diff --git a/wallpapers/image/CMakeLists.txt b/wallpapers/image/CMakeLists.txt --- a/wallpapers/image/CMakeLists.txt +++ b/wallpapers/image/CMakeLists.txt @@ -5,6 +5,7 @@ imageplugin.cpp backgroundlistmodel.cpp slidemodel.cpp + slidefiltermodel.cpp ) ecm_qt_declare_logging_category(image_SRCS HEADER debug.h diff --git a/wallpapers/image/backgroundlistmodel.h b/wallpapers/image/backgroundlistmodel.h --- a/wallpapers/image/backgroundlistmodel.h +++ b/wallpapers/image/backgroundlistmodel.h @@ -84,6 +84,7 @@ void reload(); void reload(const QStringList &selected); void addBackground(const QString &path); + void removeBackground(const QString &path); Q_INVOKABLE int indexOf(const QString &path) const; virtual bool contains(const QString &bg) const; @@ -97,7 +98,6 @@ void countChanged(); protected Q_SLOTS: - void removeBackground(const QString &path); void showPreview(const KFileItem &item, const QPixmap &preview); void previewFailed(const KFileItem &item); void sizeFound(const QString &path, const QSize &s); diff --git a/wallpapers/image/image.h b/wallpapers/image/image.h --- a/wallpapers/image/image.h +++ b/wallpapers/image/image.h @@ -3,6 +3,7 @@ * Copyright 2008 by Petri Damsten * * Copyright 2014 Sebastian Kügler * * Copyright 2015 Kai Uwe Broulik * + * Copyright 2019 David Redondo * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -24,6 +25,7 @@ #ifndef IMAGE_HEADER #define IMAGE_HEADER + #include #include #include @@ -48,16 +50,18 @@ class BackgroundListModel; class SlideModel; +class SlideFilterModel; class Image : public QObject, public QQmlParserStatus { Q_OBJECT Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(RenderingMode renderingMode READ renderingMode WRITE setRenderingMode NOTIFY renderingModeChanged) + Q_PROPERTY(SlideshowMode slideshowMode READ slideshowMode WRITE setSlideshowMode NOTIFY slideshowModeChanged) Q_PROPERTY(QUrl wallpaperPath READ wallpaperPath NOTIFY wallpaperPathChanged) Q_PROPERTY(QAbstractItemModel *wallpaperModel READ wallpaperModel CONSTANT) - Q_PROPERTY(QAbstractItemModel *slideshowModel READ slideshowModel CONSTANT) + Q_PROPERTY(QAbstractItemModel *slideFilterModel READ slideFilterModel CONSTANT) Q_PROPERTY(int slideTimer READ slideTimer WRITE setSlideTimer NOTIFY slideTimerChanged) Q_PROPERTY(QStringList usersWallpapers READ usersWallpapers WRITE setUsersWallpapers NOTIFY usersWallpapersChanged) Q_PROPERTY(QStringList slidePaths READ slidePaths WRITE setSlidePaths NOTIFY slidePathsChanged) @@ -73,6 +77,15 @@ }; Q_ENUM(RenderingMode) + enum SlideshowMode { + Random, + Alphabetical, + AlphabeticalReversed, + Modified, + ModifiedReversed + }; + Q_ENUM(SlideshowMode) + explicit Image(QObject* parent = nullptr); ~Image() override; @@ -97,13 +110,16 @@ RenderingMode renderingMode() const; void setRenderingMode(RenderingMode mode); + SlideshowMode slideshowMode() const; + void setSlideshowMode(SlideshowMode mode); + QSize targetSize() const; void setTargetSize(const QSize &size); KPackage::Package *package(); QAbstractItemModel* wallpaperModel(); - QAbstractItemModel* slideshowModel(); + QAbstractItemModel* slideFilterModel(); int slideTimer() const; void setSlideTimer(int time); @@ -133,6 +149,7 @@ void settingsChanged(bool); void wallpaperPathChanged(); void renderingModeChanged(); + void slideshowModeChanged(); void targetSizeChanged(); void slideTimerChanged(); void usersWallpapersChanged(); @@ -161,15 +178,14 @@ void pathCreated(const QString &path); void pathDeleted(const QString &path); void pathDirty(const QString &path); - void backgroundsFound(const QStringList &paths, const QString &token); + void backgroundsFound(); protected: void syncWallpaperPackage(); void setSingleImage(); void useSingleImageDefaults(); private: - bool m_ready; int m_delay; QStringList m_dirs; @@ -181,15 +197,16 @@ QSize m_targetSize; RenderingMode m_mode; + SlideshowMode m_slideshowMode; + KPackage::Package m_wallpaperPackage; - QStringList m_slideshowBackgrounds; - QStringList m_unseenSlideshowBackgrounds; QStringList m_slidePaths; QStringList m_uncheckedSlides; QTimer m_timer; int m_currentSlide; BackgroundListModel *m_model; SlideModel* m_slideshowModel; + SlideFilterModel* m_slideFilterModel; QFileDialog *m_dialog; QString m_img; QDateTime m_previousModified; diff --git a/wallpapers/image/image.cpp b/wallpapers/image/image.cpp --- a/wallpapers/image/image.cpp +++ b/wallpapers/image/image.cpp @@ -5,6 +5,7 @@ * Copyright 2008 Alexis Ménard * * Copyright 2014 Sebastian Kügler * * Copyright 2015 Kai Uwe Broulik * + * Copyright 2019 David Redondo * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -54,6 +55,7 @@ #include #include "backgroundlistmodel.h" #include "slidemodel.h" +#include "slidefiltermodel.h" #include @@ -63,9 +65,11 @@ m_delay(10), m_dirWatch(new KDirWatch(this)), m_mode(SingleImage), + m_slideshowMode(Random), m_currentSlide(-1), m_model(nullptr), - m_slideshowModel(nullptr), + m_slideshowModel(new SlideModel(this, this)), + m_slideFilterModel(new SlideFilterModel(this)), m_dialog(nullptr) { m_wallpaperPackage = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Wallpaper/Images")); @@ -77,7 +81,11 @@ connect(m_dirWatch, &KDirWatch::deleted, this, &Image::pathDeleted); m_dirWatch->startScan(); + m_slideFilterModel->setSourceModel(m_slideshowModel); + connect(this, &Image::uncheckedSlidesChanged, m_slideFilterModel, &SlideFilterModel::invalidateFilter); + useSingleImageDefaults(); + } Image::~Image() @@ -156,6 +164,25 @@ } } +Image::SlideshowMode Image::slideshowMode() const +{ + return m_slideshowMode; +} + +void Image::setSlideshowMode(Image::SlideshowMode mode) +{ + if (mode == m_slideshowMode) { + return; + } + m_slideshowMode = mode; + m_slideFilterModel->setSortingMode(mode); + m_slideFilterModel->sort(0); + if (m_mode == SlideShow) { + startSlideshow(); + } + emit slideshowModeChanged(); +} + float distance(const QSize& size, const QSize& desired) { // compute difference of areas @@ -277,15 +304,9 @@ return m_model; } -QAbstractItemModel* Image::slideshowModel() -{ - if (!m_slideshowModel) { - m_slideshowModel = new SlideModel(this, this); - m_slideshowModel->reload(m_slidePaths); - } - return m_slideshowModel; +QAbstractItemModel * Image::slideFilterModel() { + return m_slideFilterModel; } - int Image::slideTimer() const { return m_delay; @@ -546,8 +567,7 @@ } else { if (m_mode != SingleImage) { // it's a slide show, add it to the slide show - m_slideshowBackgrounds.append(path); - m_unseenSlideshowBackgrounds.append(path); + m_slideshowModel->addBackground(path); } // always add it to the user papers, though addUsersWallpaper(path); @@ -576,61 +596,49 @@ m_wallpaper = path; setSingleImage(); } else { - m_slideshowBackgrounds.append(path); - m_unseenSlideshowBackgrounds.clear(); - m_currentSlide = m_slideshowBackgrounds.size() - 2; + m_wallpaper = path; + m_slideshowModel->addBackground(path); + m_currentSlide = m_slideFilterModel->indexOf(path) - 1; nextSlide(); } //addUsersWallpaper(path); } void Image::startSlideshow() { - if (!m_ready) { + if (!m_ready || m_slideFilterModel->property("usedInConfig").toBool()) { return; } - - if(m_findToken.isEmpty()) { - // populate background list - m_timer.stop(); - m_slideshowBackgrounds.clear(); - m_unseenSlideshowBackgrounds.clear(); - BackgroundFinder *finder = new BackgroundFinder(this, m_dirs); - m_findToken = finder->token(); - connect(finder, &BackgroundFinder::backgroundsFound, this, &Image::backgroundsFound); - finder->start(); - //TODO: what would be cool: paint on the wallpaper itself a busy widget and perhaps some text - //about loading wallpaper slideshow while the thread runs - } else { - m_scanDirty = true; - } + // populate background list + m_timer.stop(); + m_slideshowModel->reload(m_slidePaths); + connect(m_slideshowModel, &SlideModel::done, this, &Image::backgroundsFound); + //TODO: what would be cool: paint on the wallpaper itself a busy widget and perhaps some text + //about loading wallpaper slideshow while the thread runs } -void Image::backgroundsFound(const QStringList &paths, const QString &token) +void Image::backgroundsFound() { - if (token != m_findToken) { - return; - } - - m_findToken.clear(); + disconnect(m_slideshowModel, &SlideModel::done, this, 0); if(m_scanDirty) { m_scanDirty = false; startSlideshow(); return; } - m_slideshowBackgrounds = paths; - for(const QString &slide : qAsConst(m_uncheckedSlides)) { - m_slideshowBackgrounds.removeAll(QUrl(slide).path()); - } - m_unseenSlideshowBackgrounds.clear(); + // start slideshow - if (m_slideshowBackgrounds.isEmpty()) { + if (m_slideFilterModel->rowCount() == 0) { // no image has been found, which is quite weird... try again later (this is useful for events which // are not detected by KDirWatch, like a NFS directory being mounted) QTimer::singleShot(1000, this, &Image::startSlideshow); } else { - m_currentSlide = -1; + if (m_currentSlide == -1 && m_slideshowMode != Random) { + m_currentSlide = m_slideFilterModel->indexOf(m_wallpaper) - 1; + } else { + m_currentSlide = -1; + } + m_slideFilterModel->sort(0); nextSlide(); m_timer.start(m_delay * 1000); } @@ -759,46 +767,33 @@ void Image::nextSlide() { - if (!m_ready || m_slideshowBackgrounds.isEmpty()) { + if (!m_ready || m_slideFilterModel->rowCount() == 0) { return; } - - QString previousPath; - if (m_currentSlide > -1 && m_currentSlide < m_unseenSlideshowBackgrounds.size()) { - previousPath = m_unseenSlideshowBackgrounds.takeAt(m_currentSlide); + int previousSlide = m_currentSlide; + QUrl previousPath = m_slideFilterModel->index(m_currentSlide, 0).data(BackgroundListModel::PathRole).toUrl(); + if (m_currentSlide == m_slideFilterModel->rowCount() - 1 || m_currentSlide < 0) { + m_currentSlide = 0; + } else { + m_currentSlide += 1; } - - if (m_unseenSlideshowBackgrounds.isEmpty()) { - m_unseenSlideshowBackgrounds = m_slideshowBackgrounds; - - // We're filling the queue again, make sure we can't pick up again - // the last one picked from the previous set - if (!previousPath.isEmpty()) { - m_unseenSlideshowBackgrounds.removeAll(previousPath); - - // prevent empty list - if (m_unseenSlideshowBackgrounds.isEmpty()) { - m_unseenSlideshowBackgrounds = m_slideshowBackgrounds; - } - } + //We are starting again - avoid having the same random order when we restart the slideshow + if (m_slideshowMode == Random && previousSlide == m_slideFilterModel->rowCount() - 1) { + m_slideFilterModel->invalidate(); + } + QUrl next = m_slideFilterModel->index(m_currentSlide, 0).data(BackgroundListModel::PathRole).toUrl(); + // And avoid showing the same picture twice + if (previousSlide == m_slideFilterModel->rowCount() - 1 && previousPath == next && m_slideFilterModel->rowCount() > 1) { + m_currentSlide += 1; + next = m_slideFilterModel->index(m_currentSlide, 0).data(BackgroundListModel::PathRole).toUrl(); } - - m_currentSlide = KRandom::random() % m_unseenSlideshowBackgrounds.size(); - const QString currentPath = m_unseenSlideshowBackgrounds.at(m_currentSlide); - - m_wallpaperPackage.setPath(currentPath); - findPreferedImageInPackage(m_wallpaperPackage); - m_timer.stop(); m_timer.start(m_delay * 1000); - - QString current = m_wallpaperPackage.filePath("preferred"); - if (current.isEmpty()) { - m_wallpaperPath = currentPath; + if (next.isEmpty()) { + m_wallpaperPath = previousPath.toLocalFile(); } else { - m_wallpaperPath = current; + m_wallpaperPath = next.toLocalFile(); } - Q_EMIT wallpaperPathChanged(); } @@ -816,22 +811,21 @@ void Image::pathCreated(const QString &path) { - if(!m_slideshowBackgrounds.contains(path)) { + if(m_slideshowModel->indexOf(path) == -1) { QFileInfo fileInfo(path); if(fileInfo.isFile() && BackgroundFinder::isAcceptableSuffix(fileInfo.suffix())) { - m_slideshowBackgrounds.append(path); - m_unseenSlideshowBackgrounds.append(path); - if(m_slideshowBackgrounds.count() == 1) { + m_slideshowModel->addBackground(path); + if(m_slideFilterModel->rowCount() == 1) { nextSlide(); } } } } void Image::pathDeleted(const QString &path) { - if(m_slideshowBackgrounds.removeAll(path)) { - m_unseenSlideshowBackgrounds.removeAll(path); + if(m_slideshowModel->indexOf(path) != -1) { + m_slideshowModel->removeBackground(path); if(path == m_img) { nextSlide(); } diff --git a/wallpapers/image/imagepackage/contents/ui/WallpaperDelegate.qml b/wallpapers/image/imagepackage/contents/ui/WallpaperDelegate.qml --- a/wallpapers/image/imagepackage/contents/ui/WallpaperDelegate.qml +++ b/wallpapers/image/imagepackage/contents/ui/WallpaperDelegate.qml @@ -58,7 +58,7 @@ onTriggered: { imageModel.setPendingDeletion(index, true); if (wallpapersGrid.currentIndex === index) { - wallpapersGrid.currentIndex = (index + 1) % wallpapersGrid.count; + wallpapersGrid.currentIndex = (index + 1) % wallpapersGrid.rowCount(); } } } @@ -126,7 +126,9 @@ } onClicked: { - cfg_Image = model.path; - wallpapersGrid.forceActiveFocus(); + if (configDialog.currentWallpaper == "org.kde.image") { + cfg_Image = model.path; + } + view.currentIndex = index; } } diff --git a/wallpapers/image/imagepackage/contents/ui/config.qml b/wallpapers/image/imagepackage/contents/ui/config.qml --- a/wallpapers/image/imagepackage/contents/ui/config.qml +++ b/wallpapers/image/imagepackage/contents/ui/config.qml @@ -1,6 +1,7 @@ /* * Copyright 2013 Marco Martin * Copyright 2014 Kai Uwe Broulik + * Copyright 2019 David Redondo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,6 +35,7 @@ property alias cfg_Color: colorButton.color property string cfg_Image property int cfg_FillMode + property int cfg_SlideshowMode property alias cfg_Blur: blurRadioButton.checked property var cfg_SlidePaths: "" property int cfg_SlideInterval: 0 @@ -58,6 +60,7 @@ } onSlidePathsChanged: cfg_SlidePaths = slidePaths onUncheckedSlidesChanged: cfg_UncheckedSlides = uncheckedSlides + onSlideshowModeChanged: cfg_SlideshowMode = slideshowMode } onCfg_SlidePathsChanged: { @@ -67,6 +70,10 @@ imageWallpaper.uncheckedSlides = cfg_UncheckedSlides } + onCfg_SlideshowModeChanged: { + imageWallpaper.slideshowMode = cfg_SlideshowMode + } + property int hoursIntervalValue: Math.floor(cfg_SlideInterval / 3600) property int minutesIntervalValue: Math.floor(cfg_SlideInterval % 3600) / 60 property int secondsIntervalValue: cfg_SlideInterval % 3600 % 60 @@ -116,6 +123,46 @@ } } + QtControls2.ComboBox { + id: slideshowComboBox + visible: configDialog.currentWallpaper == "org.kde.slideshow" + Kirigami.FormData.label: i18nd("plasma_wallpaper_org.kde.image", "Order:") + model: [ + { + 'label': i18nd("plasma_wallpaper_org.kde.image", "Random"), + 'slideshowMode': Wallpaper.Image.Random + }, + { + 'label': i18nd("plasma_wallpaper_org.kde.image", "A to Z"), + 'slideshowMode': Wallpaper.Image.Alphabetical + }, + { + 'label': i18nd("plasma_wallpaper_org.kde.image", "Z to A"), + 'slideshowMode': Wallpaper.Image.AlphabeticalReversed + }, + { + 'label': i18nd("plasma_wallpaper_org.kde.image", "Date modified (newest first)"), + 'slideshowMode': Wallpaper.Image.ModifiedReversed + }, + { + 'label': i18nd("plasma_wallpaper_org.kde.image", "Date modified (oldest first)"), + 'slideshowMode': Wallpaper.Image.Modified + } + ] + textRole: "label" + onCurrentIndexChanged: { + cfg_SlideshowMode = model[currentIndex]["slideshowMode"]; + } + Component.onCompleted: setMethod(); + function setMethod() { + for (var i = 0; i < model.length; i++) { + if (model[i]["slideshowMode"] === wallpaper.configuration.SlideshowMode) { + slideshowComboBox.currentIndex = i; + } + } + } + } + QtControls2.ButtonGroup { id: backgroundGroup } QtControls2.RadioButton { @@ -264,12 +311,15 @@ KCM.GridView { id: wallpapersGrid anchors.fill: parent - property var imageModel: (configDialog.currentWallpaper == "org.kde.image")? imageWallpaper.wallpaperModel : imageWallpaper.slideshowModel + property var imageModel: (configDialog.currentWallpaper == "org.kde.image")? imageWallpaper.wallpaperModel : imageWallpaper.slideFilterModel //that min is needed as the module will be populated in an async way //and only on demand so we can't ensure it already exists - view.currentIndex: Math.min(imageModel.indexOf(cfg_Image), imageModel.count-1) + view.currentIndex: Math.min(imageModel.indexOf(cfg_Image), imageModel.rowCount()-1) //kill the space for label under thumbnails view.model: imageModel + Component.onCompleted: { + imageModel.usedInConfig = true; + } view.delegate: WallpaperDelegate { color: cfg_Color } diff --git a/wallpapers/image/imagepackage/contents/ui/main.qml b/wallpapers/image/imagepackage/contents/ui/main.qml --- a/wallpapers/image/imagepackage/contents/ui/main.qml +++ b/wallpapers/image/imagepackage/contents/ui/main.qml @@ -52,7 +52,9 @@ //private onConfiguredImageChanged: { - imageWallpaper.addUrl(configuredImage) + if (modelImage != configuredImage && configuredImage != "") { + imageWallpaper.addUrl(configuredImage); + } } Component.onCompleted: { if (wallpaper.pluginName === "org.kde.slideshow") { @@ -68,11 +70,15 @@ targetSize: root.sourceSize slidePaths: wallpaper.configuration.SlidePaths slideTimer: wallpaper.configuration.SlideInterval + slideshowMode: wallpaper.configuration.SlideshowMode uncheckedSlides: wallpaper.configuration.UncheckedSlides } onFillModeChanged: Qt.callLater(loadImage); - onModelImageChanged: Qt.callLater(loadImage); + onModelImageChanged:{ + Qt.callLater(loadImage); + wallpaper.configuration.Image = modelImage; + } onConfigColorChanged: Qt.callLater(loadImage); onBlurChanged: Qt.callLater(loadImage); onWidthChanged: Qt.callLater(loadImage); diff --git a/wallpapers/image/slidefiltermodel.h b/wallpapers/image/slidefiltermodel.h new file mode 100644 --- /dev/null +++ b/wallpapers/image/slidefiltermodel.h @@ -0,0 +1,50 @@ +/* + * Copyright 2019 David Redondo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA. + */ + +#ifndef SLIDEFILTERMODEL_H +#define SLIDEFILTERMODEL_H + +#include + +#include + + +class SlideFilterModel : public QSortFilterProxyModel { + + Q_OBJECT + + Q_PROPERTY(bool usedInConfig MEMBER m_usedInConfig NOTIFY usedInConfigChanged); + +public: + 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 setSortingMode(Image::SlideshowMode mode); + void invalidateFilter(); + + Q_INVOKABLE int indexOf(const QString& path); + Q_INVOKABLE void openContainingFolder(int rowIndex); + +Q_SIGNALS: + void usedInConfigChanged(); + +private: + Image::SlideshowMode m_SortingMode; + bool m_usedInConfig; +}; +#endif diff --git a/wallpapers/image/slidefiltermodel.cpp b/wallpapers/image/slidefiltermodel.cpp new file mode 100644 --- /dev/null +++ b/wallpapers/image/slidefiltermodel.cpp @@ -0,0 +1,90 @@ +/* + * Copyright 2019 David Redondo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA. + */ + +#include "slidefiltermodel.h" + +#include "backgroundlistmodel.h" +#include "slidemodel.h" + +#include +#include + +SlideFilterModel::SlideFilterModel(QObject* parent) + : QSortFilterProxyModel{parent} + , m_SortingMode{Image::Random} + , m_usedInConfig{false} +{ + setSortCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive); + connect(this, &SlideFilterModel::usedInConfigChanged, this, &SlideFilterModel::invalidateFilter); +} + +bool SlideFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const +{ + auto index = sourceModel()->index(source_row, 0, source_parent); + return m_usedInConfig || index.data(BackgroundListModel::ToggleRole).toBool(); +} + +bool SlideFilterModel::lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const +{ + switch (m_SortingMode) { + case Image::Random: + return (*QRandomGenerator::system())() % 2 == 0; + case Image::Alphabetical: + return QSortFilterProxyModel::lessThan(source_left, source_right); + case Image::AlphabeticalReversed: + return !QSortFilterProxyModel::lessThan(source_left, source_right); + case Image::Modified: // oldest first + { + QFileInfo f1(source_left.data(BackgroundListModel::PathRole).toUrl().toLocalFile()); + QFileInfo f2(source_right.data(BackgroundListModel::PathRole).toUrl().toLocalFile()); + return f1.lastModified() < f2.lastModified(); + } + case Image::ModifiedReversed: // newest first + { + QFileInfo f1(source_left.data(BackgroundListModel::PathRole).toUrl().toLocalFile()); + QFileInfo f2(source_right.data(BackgroundListModel::PathRole).toUrl().toLocalFile()); + return !(f1.lastModified() < f2.lastModified()); + } + } + Q_UNREACHABLE(); +} + +void SlideFilterModel::setSortingMode(Image::SlideshowMode mode) +{ + m_SortingMode = mode; + if (!(m_usedInConfig && mode == Image::Random)) { + QSortFilterProxyModel::invalidate(); + } +} + +void SlideFilterModel::invalidateFilter() +{ + QSortFilterProxyModel::invalidateFilter(); +} + +int SlideFilterModel::indexOf(const QString& path) +{ + auto sourceIndex = sourceModel()->index(static_cast(sourceModel())->indexOf(path), 0); + return mapFromSource(sourceIndex).row(); +} + +void SlideFilterModel::openContainingFolder(int rowIndex) +{ + auto sourceIndex = mapToSource(index(rowIndex, 0)); + static_cast(sourceModel())->openContainingFolder(sourceIndex.row()); +} diff --git a/wallpapers/image/slidemodel.h b/wallpapers/image/slidemodel.h --- a/wallpapers/image/slidemodel.h +++ b/wallpapers/image/slidemodel.h @@ -1,3 +1,21 @@ +/* + * Copyright 2019 David Redondo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA. + */ + #ifndef SLIDEMODEL_H #define SLIDEMODEL_H @@ -13,6 +31,10 @@ void removeDir(const QString &selected); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QHash roleNames() const override; + +Q_SIGNALS: + void done(); + private Q_SLOTS: void removeBackgrounds(const QStringList &paths, const QString &token); void backgroundsFound(const QStringList &paths, const QString &token); diff --git a/wallpapers/image/slidemodel.cpp b/wallpapers/image/slidemodel.cpp --- a/wallpapers/image/slidemodel.cpp +++ b/wallpapers/image/slidemodel.cpp @@ -1,3 +1,21 @@ +/* + * Copyright 2019 David Redondo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA. + */ + #include "slidemodel.h" void SlideModel::reload(const QStringList &selected) @@ -26,6 +44,7 @@ return; } processPaths(paths); + emit done(); } diff --git a/wallpapers/image/slideshowpackage/contents/config/main.xml b/wallpapers/image/slideshowpackage/contents/config/main.xml --- a/wallpapers/image/slideshowpackage/contents/config/main.xml +++ b/wallpapers/image/slideshowpackage/contents/config/main.xml @@ -38,6 +38,9 @@ + + + 0 + -