diff --git a/wallpapers/image/CMakeLists.txt b/wallpapers/image/CMakeLists.txt --- a/wallpapers/image/CMakeLists.txt +++ b/wallpapers/image/CMakeLists.txt @@ -4,6 +4,7 @@ image.cpp imageplugin.cpp backgroundlistmodel.cpp + slidemodel.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 @@ -105,18 +105,20 @@ void backgroundsFound(const QStringList &paths, const QString &token); void processPaths(const QStringList &paths); +protected: + QPointer m_wallpaper; + QString m_findToken; + private: QSize bestSize(const KPackage::Package &package) const; - QPointer m_wallpaper; QList m_packages; QSet m_removableWallpapers; QHash m_sizeCache; QHash m_previewJobs; KDirWatch m_dirwatch; QCache m_imageCache; - QString m_findToken; int m_screenshotSize; QHash m_pendingDeletion; }; diff --git a/wallpapers/image/image.h b/wallpapers/image/image.h --- a/wallpapers/image/image.h +++ b/wallpapers/image/image.h @@ -48,6 +48,7 @@ } class BackgroundListModel; +class SlideModel; class Image : public QObject, public QQmlParserStatus { @@ -57,6 +58,7 @@ Q_PROPERTY(RenderingMode renderingMode READ renderingMode WRITE setRenderingMode NOTIFY renderingModeChanged) Q_PROPERTY(QUrl wallpaperPath READ wallpaperPath NOTIFY wallpaperPathChanged) Q_PROPERTY(QAbstractItemModel *wallpaperModel READ wallpaperModel CONSTANT) + Q_PROPERTY(QAbstractItemModel *slideshowModel READ slideshowModel 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) @@ -82,6 +84,7 @@ Q_INVOKABLE void addSlidePath(const QString &path); Q_INVOKABLE void removeSlidePath(const QString &path); + Q_INVOKABLE void openFolder(const QString& path); Q_INVOKABLE void getNewWallpaper(QQuickItem *ctx = nullptr); Q_INVOKABLE void showFileDialog(); @@ -98,6 +101,7 @@ KPackage::Package *package(); QAbstractItemModel* wallpaperModel(); + QAbstractItemModel* slideshowModel(); int slideTimer() const; void setSlideTimer(int time); @@ -116,7 +120,7 @@ QString photosPath() const; - public Q_SLOTS: + public Q_SLOTS: void nextSlide(); void removeWallpaper(QString name); @@ -178,6 +182,7 @@ QTimer m_timer; int m_currentSlide; BackgroundListModel *m_model; + SlideModel* m_slideshowModel; 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 @@ -53,6 +53,7 @@ #include #include #include "backgroundlistmodel.h" +#include "slidemodel.h" #include @@ -64,6 +65,7 @@ m_mode(SingleImage), m_currentSlide(-1), m_model(nullptr), + m_slideshowModel(nullptr), m_dialog(nullptr) { m_wallpaperPackage = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Wallpaper/Images")); @@ -275,6 +277,15 @@ return m_model; } +QAbstractItemModel* Image::slideshowModel() +{ + if (!m_slideshowModel) { + m_slideshowModel = new SlideModel(this, this); + m_slideshowModel->reload(m_slidePaths); + } + return m_slideshowModel; +} + int Image::slideTimer() const { return m_delay; @@ -336,7 +347,9 @@ updateDirWatch(m_slidePaths); startSlideshow(); } - + if (m_slideshowModel) { + m_slideshowModel->reload(m_slidePaths); + } emit slidePathsChanged(); } @@ -357,7 +370,9 @@ if (m_mode == SlideShow) { updateDirWatch(m_slidePaths); } - + if (m_slideshowModel) { + m_slideshowModel->reload(m_slidePaths); + } emit slidePathsChanged(); startSlideshow(); } @@ -370,7 +385,9 @@ if (m_mode == SlideShow) { updateDirWatch(m_slidePaths); } - + if (m_slideshowModel) { + m_slideshowModel->removeDir(path); + } emit slidePathsChanged(); startSlideshow(); } @@ -582,7 +599,6 @@ startSlideshow(); return; } - m_slideshowBackgrounds = paths; m_unseenSlideshowBackgrounds.clear(); // start slideshow @@ -856,3 +872,7 @@ } } +void Image::openFolder(const QString& path) +{ + new KRun(QUrl::fromLocalFile(path), nullptr); +} 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 @@ -19,6 +19,7 @@ import QtQuick 2.0 import QtQuick.Controls.Private 1.0 +import QtQuick.Controls 2.3 as QtControls2 import QtGraphicalEffects 1.0 import org.kde.kquickcontrolsaddons 2.0 import org.kde.plasma.components 2.0 as PlasmaComponents @@ -28,7 +29,6 @@ KCM.GridDelegate { id: wallpaperDelegate - property alias color: backgroundRect.color property bool selected: (wallpapersGrid.currentIndex == index) opacity: model.pendingDeletion ? 0.5 : 1 @@ -43,20 +43,20 @@ Kirigami.Action { icon.name: "document-open-folder" tooltip: i18nd("plasma_wallpaper_org.kde.image", "Open Containing Folder") - onTriggered: imageWallpaper.wallpaperModel.openContainingFolder(index) + onTriggered: imageModel.openContainingFolder(index) }, Kirigami.Action { icon.name: "edit-undo" visible: model.pendingDeletion tooltip: i18nd("plasma_wallpaper_org.kde.image", "Restore wallpaper") - onTriggered: imageWallpaper.wallpaperModel.setPendingDeletion(index, !model.pendingDeletion) + onTriggered: imageModel.setPendingDeletion(index, !model.pendingDeletion) }, Kirigami.Action { icon.name: "edit-delete" tooltip: i18nd("plasma_wallpaper_org.kde.image", "Remove Wallpaper") - visible: model.removable && !model.pendingDeletion + visible: model.removable && !model.pendingDeletion && configDialog.currentWallpaper == "org.kde.image" onTriggered: { - imageWallpaper.wallpaperModel.setPendingDeletion(index, true); + imageModel.setPendingDeletion(index, true); if (wallpapersGrid.currentIndex === index) { wallpapersGrid.currentIndex = (index + 1) % wallpapersGrid.count; } 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 @@ -238,30 +238,70 @@ text: i18nd("plasma_wallpaper_org.kde.image","Seconds") } } - QtControls2.ScrollView { - id: foldersScroll - Layout.fillHeight: true; + Kirigami.Heading { + text: "Folders" + level: 2 + } + GridLayout { + columns: 2 Layout.fillWidth: true - Component.onCompleted: foldersScroll.background.visible = true; - ListView { - id: slidePathsView - anchors.margins: 4 - model: imageWallpaper.slidePaths - delegate: QtControls2.Label { - text: modelData - width: slidePathsView.width - height: Math.max(paintedHeight, removeButton.height); - QtControls2.ToolButton { - id: removeButton - anchors { - verticalCenter: parent.verticalCenter - right: parent.right + Layout.fillHeight: true + columnSpacing: Kirigami.Units.largeSpacing + QtControls2.ScrollView { + id: foldersScroll + Layout.fillHeight: true + Layout.preferredWidth: 0.25 * parent.width + Component.onCompleted: foldersScroll.background.visible = true; + ListView { + id: slidePathsView + anchors.margins: 4 + model: imageWallpaper.slidePaths + delegate: Kirigami.SwipeListItem { + id: folderDelegate + actions: [ + Kirigami.Action { + iconName: "list-remove" + tooltip: i18nd("plasma_wallpaper_org.kde.image", "Remove Folder") + onTriggered: imageWallpaper.removeSlidePath(modelData) + }, + Kirigami.Action { + icon.name: "document-open-folder" + tooltip: i18nd("plasma_wallpaper_org.kde.image", "Open Folder") + onTriggered: imageWallpaper.openFolder(modelData) + } + ] + QtControls2.Label { + text: modelData.endsWith("/") ? modelData.split('/').reverse()[1] : modelData.split('/').pop() + Layout.fillWidth: true + QtControls2.ToolTip.text: modelData + QtControls2.ToolTip.visible: folderDelegate.hovered + QtControls2.ToolTip.delay: 1000 + QtControls2.ToolTip.timeout: 5000 } - icon.name: "list-remove" - onClicked: imageWallpaper.removeSlidePath(modelData); + width: slidePathsView.width + height: paintedHeight; } } } + Loader { + sourceComponent: thumbnailsComponent + Layout.fillWidth: true + Layout.fillHeight: true + anchors.fill: undefined + } + QtControls2.Button { + Layout.alignment: Qt.AlignRight + icon.name: "list-add" + text: i18nd("plasma_wallpaper_org.kde.image","Add Folder...") + onClicked: imageWallpaper.showAddSlidePathsDialog() + } + QtControls2.Button { + Layout.alignment: Qt.AlignRight + icon.name: "get-hot-new-stuff" + text: i18nd("plasma_wallpaper_org.kde.image","Get New Wallpapers...") + visible: KAuthorized.authorize("ghns") + onClicked: imageWallpaper.getNewWallpaper(this); + } } } } @@ -271,12 +311,12 @@ KCM.GridView { id: wallpapersGrid anchors.fill: parent - + property var imageModel: (configDialog.currentWallpaper == "org.kde.image")? imageWallpaper.wallpaperModel : imageWallpaper.slideshowModel //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(imageWallpaper.wallpaperModel.indexOf(cfg_Image), imageWallpaper.wallpaperModel.count-1) + view.currentIndex: Math.min(imageModel.indexOf(cfg_Image), imageModel.count-1) //kill the space for label under thumbnails - view.model: imageWallpaper.wallpaperModel + view.model: imageModel view.delegate: WallpaperDelegate { color: cfg_Color } @@ -314,14 +354,8 @@ RowLayout { id: buttonsRow Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + visible: configDialog.currentWallpaper == "org.kde.image" QtControls2.Button { - visible: (configDialog.currentWallpaper == "org.kde.slideshow") - icon.name: "list-add" - text: i18nd("plasma_wallpaper_org.kde.image","Add Folder...") - onClicked: imageWallpaper.showAddSlidePathsDialog() - } - QtControls2.Button { - visible: (configDialog.currentWallpaper == "org.kde.image") icon.name: "list-add" text: i18nd("plasma_wallpaper_org.kde.image","Add Image...") onClicked: imageWallpaper.showFileDialog(); diff --git a/wallpapers/image/slidemodel.h b/wallpapers/image/slidemodel.h new file mode 100644 --- /dev/null +++ b/wallpapers/image/slidemodel.h @@ -0,0 +1,19 @@ +#ifndef SLIDEMODEL_H +#define SLIDEMODEL_H + +#endif + +#include "backgroundlistmodel.h" + +class SlideModel : public BackgroundListModel +{ + Q_OBJECT +public: + using BackgroundListModel::BackgroundListModel; + + void reload(const QStringList &selected); + void removeDir(const QString &selected); +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 new file mode 100644 --- /dev/null +++ b/wallpapers/image/slidemodel.cpp @@ -0,0 +1,36 @@ +#include "slidemodel.h" + +void SlideModel::reload(const QStringList &selected) +{ + BackgroundFinder *finder = new BackgroundFinder(m_wallpaper.data(), selected); + connect(finder, &BackgroundFinder::backgroundsFound, this, &SlideModel::backgroundsFound); + m_findToken = finder->token(); + finder->start(); +} + +void SlideModel::backgroundsFound(const QStringList& paths, const QString& token) +{ + if (token != m_findToken) { + return; + } + processPaths(paths); +} + + +void SlideModel::removeDir(const QString &path) +{ + BackgroundFinder *finder = new BackgroundFinder(m_wallpaper.data(), QStringList{path}); + connect(finder, &BackgroundFinder::backgroundsFound, this, &SlideModel::removeBackgrounds); + m_findToken = finder->token(); + finder->start(); +} + +void SlideModel::removeBackgrounds(const QStringList &paths, const QString &token) +{ + if (token != m_findToken) { + return; + } + Q_FOREACH (QString file, paths) { + removeBackground(file); + } +}