File indexing completed on 2024-06-23 05:32:17

0001 /*
0002     SPDX-FileCopyrightText: 2007 Paolo Capriotti <p.capriotti@gmail.com>
0003     SPDX-FileCopyrightText: 2008 Petri Damsten <damu@iki.fi>
0004     SPDX-FileCopyrightText: 2014 Sebastian Kügler <sebas@kde.org>
0005     SPDX-FileCopyrightText: 2015 Kai Uwe Broulik <kde@privat.broulik.de>
0006     SPDX-FileCopyrightText: 2019 David Redondo <kde@david-redondo.de>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #pragma once
0012 
0013 #include <optional>
0014 
0015 #include <QAbstractItemModel>
0016 #include <QBindable>
0017 #include <QPointer>
0018 #include <QQmlParserStatus>
0019 #include <QQmlPropertyMap>
0020 #include <QSize>
0021 #include <QTimer>
0022 #include <QUrl>
0023 
0024 #include "sortingmode.h"
0025 
0026 class ImageProxyModel;
0027 class SlideModel;
0028 class SlideFilterModel;
0029 
0030 /**
0031  * @brief An image wallpaper backend that handles slideshow progress and data from
0032  * wallpaper models.
0033  *
0034  * It's used in the configuration dialog and the wallpaper front-end.
0035  *
0036  * When used in the configuration dialog, it summons the wallpaper models to list
0037  * all available images in either:
0038  * - the default wallpaper location (image wallpaper plugin)
0039  * - the specified folders (slideshow wallpaper plugin)
0040  *
0041  * When used in the front-end, it will only be activated when the current wallpaper
0042  * plugin is the sildeshow plugin.
0043  * It provides wallpaper paths for \MediaProxy and will update the current wallpaper
0044  * path periodically following the slideshow settings, and \MediaProxy will convert
0045  * the wallpaper path to an url that \QQuickImage can understand.
0046  *
0047  * @warning The API is unstable. Do not use the backend in your wallpaper plugin.
0048  */
0049 class ImageBackend : public QObject, public QQmlParserStatus
0050 {
0051     Q_OBJECT
0052     Q_INTERFACES(QQmlParserStatus)
0053 
0054     /**
0055      * Used to save the current wallpaper in slideshow mode
0056      */
0057     Q_PROPERTY(QQmlPropertyMap *configMap READ configMap WRITE setConfigMap NOTIFY configMapChanged)
0058 
0059     Q_PROPERTY(bool usedInConfig MEMBER m_usedInConfig)
0060     Q_PROPERTY(RenderingMode renderingMode READ renderingMode WRITE setRenderingMode NOTIFY renderingModeChanged)
0061     Q_PROPERTY(SortingMode::Mode slideshowMode READ slideshowMode WRITE setSlideshowMode NOTIFY slideshowModeChanged)
0062     Q_PROPERTY(bool slideshowFoldersFirst READ slideshowFoldersFirst WRITE setSlideshowFoldersFirst NOTIFY slideshowFoldersFirstChanged)
0063 
0064     /**
0065      * Provides source url for \MediaProxy
0066      */
0067     Q_PROPERTY(QString image READ image WRITE setImage NOTIFY imageChanged)
0068 
0069     Q_PROPERTY(QAbstractItemModel *wallpaperModel READ wallpaperModel NOTIFY wallpaperModelChanged)
0070     Q_PROPERTY(QAbstractItemModel *slideFilterModel READ slideFilterModel NOTIFY slideFilterModelChanged)
0071     Q_PROPERTY(int slideTimer READ slideTimer WRITE setSlideTimer NOTIFY slideTimerChanged)
0072     Q_PROPERTY(QStringList slidePaths READ slidePaths WRITE setSlidePaths NOTIFY slidePathsChanged)
0073     Q_PROPERTY(QSize targetSize READ targetSize WRITE setTargetSize NOTIFY targetSizeChanged)
0074     Q_PROPERTY(QStringList uncheckedSlides READ uncheckedSlides WRITE setUncheckedSlides NOTIFY uncheckedSlidesChanged)
0075 
0076     /**
0077      * Pauses slideshow when certain conditions are met
0078      */
0079     Q_PROPERTY(bool pauseSlideshow READ pauseSlideshow WRITE setPauseSlideshow NOTIFY pauseSlideshowChanged)
0080 
0081     /**
0082      * @return @c true if the image list is loaded, @c false otherwise
0083      */
0084     Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)
0085 
0086 public:
0087     enum RenderingMode {
0088         SingleImage,
0089         SlideShow,
0090     };
0091     Q_ENUM(RenderingMode)
0092 
0093     explicit ImageBackend(QObject *parent = nullptr);
0094     ~ImageBackend() override;
0095 
0096     QString image() const;
0097     void setImage(const QString &url);
0098 
0099     // this is for QML use
0100     Q_INVOKABLE bool addSlidePath(const QUrl &url);
0101     Q_INVOKABLE void removeSlidePath(const QString &path);
0102 
0103     Q_INVOKABLE QString nameFilters() const;
0104 
0105     Q_INVOKABLE QString addUsersWallpaper(const QUrl &url);
0106 
0107     QQmlPropertyMap *configMap() const;
0108     void setConfigMap(QQmlPropertyMap *configMap);
0109 
0110     RenderingMode renderingMode() const;
0111     void setRenderingMode(RenderingMode mode);
0112 
0113     SortingMode::Mode slideshowMode() const;
0114     void setSlideshowMode(SortingMode::Mode slideshowMode);
0115 
0116     bool slideshowFoldersFirst() const;
0117     void setSlideshowFoldersFirst(bool slideshowFoldersFirst);
0118 
0119     QSize targetSize() const;
0120     void setTargetSize(const QSize &size);
0121 
0122     QAbstractItemModel *wallpaperModel() const;
0123     QAbstractItemModel *slideFilterModel() const;
0124 
0125     int slideTimer() const;
0126     void setSlideTimer(int time);
0127 
0128     QStringList slidePaths() const;
0129     void setSlidePaths(const QStringList &slidePaths);
0130 
0131     void classBegin() override;
0132     void componentComplete() override;
0133 
0134     QStringList uncheckedSlides() const;
0135     void setUncheckedSlides(const QStringList &uncheckedSlides);
0136 
0137     bool pauseSlideshow() const;
0138     void setPauseSlideshow(bool pauseSlideshow);
0139 
0140     bool loading() const;
0141 
0142 public Q_SLOTS:
0143     void nextSlide();
0144     void slotSlideModelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList<int> &roles);
0145 
0146 Q_SIGNALS:
0147     void settingsChanged();
0148     void imageChanged();
0149     void wallpaperModelChanged();
0150     void slideFilterModelChanged();
0151     void renderingModeChanged();
0152     void slideshowModeChanged();
0153     void slideshowFoldersFirstChanged();
0154     void targetSizeChanged();
0155     void slideTimerChanged();
0156     void slidePathsChanged();
0157     void uncheckedSlidesChanged();
0158     void pauseSlideshowChanged();
0159     void configMapChanged();
0160     void loadingChanged(bool loading);
0161 
0162 protected Q_SLOTS:
0163     void startSlideshow();
0164     void backgroundsFound();
0165 
0166 private:
0167     void ensureWallpaperModel();
0168     void ensureSlideshowModel();
0169 
0170     void saveCurrentWallpaper();
0171 
0172     bool m_ready = false;
0173     int m_delay = 10;
0174     QUrl m_image;
0175     Q_OBJECT_BINDABLE_PROPERTY(ImageBackend, QSize, m_targetSize, &ImageBackend::targetSizeChanged)
0176 
0177     Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(ImageBackend, bool, m_usedInConfig, true)
0178     QPointer<QQmlPropertyMap> m_configMap;
0179     Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(ImageBackend, bool, m_loading, false, &ImageBackend::loadingChanged)
0180 
0181     RenderingMode m_mode = SingleImage;
0182     Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(ImageBackend, SortingMode::Mode, m_slideshowMode, SortingMode::Random, &ImageBackend::slideshowModeChanged)
0183     Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(ImageBackend, bool, m_slideshowFoldersFirst, false, &ImageBackend::slideshowFoldersFirstChanged)
0184 
0185     QTimer m_timer;
0186     bool m_pauseSlideshow = false;
0187     std::optional<decltype(std::declval<QTimer>().remainingTimeAsDuration())> m_remainingTime;
0188 
0189     QStringList m_slidePaths;
0190     QStringList m_uncheckedSlides;
0191     int m_currentSlide = -1;
0192     ImageProxyModel *m_model = nullptr;
0193     SlideModel *m_slideshowModel = nullptr;
0194     SlideFilterModel *m_slideFilterModel = nullptr;
0195 };