[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [plasma-desktop/ivan/wallpaper-thumbnail-image-provider] /: Attempt to create an image provider for 
From:       Ivan Čukić <ivan.cukic () kde ! org>
Date:       2016-09-18 14:57:29
Message-ID: E1bldX7-0001jz-1D () code ! kde ! org
[Download RAW message or body]

Git commit 6c16aa06a01301677bd4008e6773304095c3392d by Ivan Čukić.
Committed on 18/09/2016 at 14:57.
Pushed by ivan into branch 'ivan/wallpaper-thumbnail-image-provider'.

Attempt to create an image provider for wallpaper thumbs

M  +55   -45   desktoppackage/contents/activitymanager/ActivityItem.qml
M  +2    -1    imports/activitymanager/CMakeLists.txt
M  +143  -25   imports/activitymanager/switcherbackend.cpp
M  +1    -1    imports/activitymanager/switcherbackend.h

http://commits.kde.org/plasma-desktop/6c16aa06a01301677bd4008e6773304095c3392d

diff --git a/desktoppackage/contents/activitymanager/ActivityItem.qml \
b/desktoppackage/contents/activitymanager/ActivityItem.qml index bb492b6..f55c28f \
                100644
--- a/desktoppackage/contents/activitymanager/ActivityItem.qml
+++ b/desktoppackage/contents/activitymanager/ActivityItem.qml
@@ -33,48 +33,48 @@ Item {
 
     property string background : ""
 
-    function updateBackgroundRetry(valid) {
-        // TODO: (comment by David)
-        //
-        // Registering a a QQuickImageProvider with
-        // ForceAsynchronousImageLoading (so you can just exec() in the main
-        // method without blocking) will probably be both simpler code
-        // and more robust.
-
-        if (valid) {
-            // Try to get the pixmap, if it is not available, this function
-            // will be called again when the thumbnailer finishes its job
-            // console.log("Loading background for " + root.title);
-            backgroundWallpaper.pixmap = \
                ActivitySwitcher.Backend.wallpaperThumbnail(
-                background,
-                backgroundWallpaper.width,
-                backgroundWallpaper.height,
-                updateBackgroundRetry
-                );
-
-            backgroundColor.visible = false;
-
-        } else {
-            backgroundColor.color = "#000000";
-            backgroundColor.visible = true;
-        }
-    }
-
-    function updateBackground() {
-        if (background == "") return;
-
-        updateBackgroundRetry(true);
-    }
-
-    onBackgroundChanged: if (background[0] != '#') {
-        // We have a proper wallpaper, hurroo!
-        updateBackground();
-
-    } else {
-        // We have only a color
-        backgroundColor.color = background
-        backgroundColor.visible = true
-    }
+    // function updateBackgroundRetry(valid) {
+    //     // TODO: (comment by David)
+    //     //
+    //     // Registering a a QQuickImageProvider with
+    //     // ForceAsynchronousImageLoading (so you can just exec() in the main
+    //     // method without blocking) will probably be both simpler code
+    //     // and more robust.
+    //
+    //     if (valid) {
+    //         // Try to get the pixmap, if it is not available, this function
+    //         // will be called again when the thumbnailer finishes its job
+    //         // console.log("Loading background for " + root.title);
+    //         backgroundWallpaper.pixmap = \
ActivitySwitcher.Backend.wallpaperThumbnail( +    //             background,
+    //             backgroundWallpaper.width,
+    //             backgroundWallpaper.height,
+    //             updateBackgroundRetry
+    //             );
+    //
+    //         backgroundColor.visible = false;
+    //
+    //     } else {
+    //         backgroundColor.color = "#000000";
+    //         backgroundColor.visible = true;
+    //     }
+    // }
+    //
+    // function updateBackground() {
+    //     if (background == "") return;
+    //
+    //     updateBackgroundRetry(true);
+    // }
+    //
+    // onBackgroundChanged: if (background[0] != '#') {
+    //     // We have a proper wallpaper, hurroo!
+    //     updateBackground();
+    //
+    // } else {
+    //     // We have only a color
+    //     backgroundColor.color = background
+    //     backgroundColor.visible = true
+    // }
 
     signal clicked
 
@@ -83,8 +83,8 @@ Item {
     // Marco removed displayAspectRatio
     height : width * 9.0 / 16.0
 
-    onWidthChanged  : updateBackground()
-    onHeightChanged : updateBackground()
+    // onWidthChanged  : updateBackground()
+    // onHeightChanged : updateBackground()
 
 
     Item {
@@ -104,14 +104,24 @@ Item {
             opacity: root.selected ? .8 : .5
         }
 
-        KQuickControlsAddonsComponents.QPixmapItem {
+        Image {
             id: backgroundWallpaper
 
             anchors.fill: parent
 
             visible: !backgroundColor.visible
+            source: "wallpaperthumbnail://" + background
+            // source: background
         }
 
+        // KQuickControlsAddonsComponents.QPixmapItem {
+        //     id: backgroundWallpaper
+        //
+        //     anchors.fill: parent
+        //
+        //     visible: !backgroundColor.visible
+        // }
+
 
         // Title and the icon
 
diff --git a/imports/activitymanager/CMakeLists.txt \
b/imports/activitymanager/CMakeLists.txt index 21aab9d..272187e 100644
--- a/imports/activitymanager/CMakeLists.txt
+++ b/imports/activitymanager/CMakeLists.txt
@@ -1,7 +1,7 @@
 find_package (ECM 0.0.8 REQUIRED NO_MODULE)
 set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH})
 
-find_package (Qt5 REQUIRED NO_MODULE COMPONENTS Widgets Qml X11Extras)
+find_package (Qt5 REQUIRED NO_MODULE COMPONENTS Widgets Qml X11Extras Quick)
 find_package (KF5I18n         ${KF5_DEP_VERSION} CONFIG REQUIRED)
 find_package (KF5Config       ${KF5_DEP_VERSION} CONFIG REQUIRED)
 find_package (KF5CoreAddons   ${KF5_DEP_VERSION} CONFIG REQUIRED)
@@ -32,6 +32,7 @@ target_link_libraries (
    activityswitcherextensionplugin
 
    Qt5::Core
+   Qt5::Quick
    Qt5::Qml
    Qt5::Widgets
    Qt5::X11Extras
diff --git a/imports/activitymanager/switcherbackend.cpp \
b/imports/activitymanager/switcherbackend.cpp index 8a5ada2..82f7c72 100644
--- a/imports/activitymanager/switcherbackend.cpp
+++ b/imports/activitymanager/switcherbackend.cpp
@@ -29,6 +29,10 @@
 #include <QTimer>
 #include <QDateTime>
 
+// Qml and QtQuick
+#include <QQuickImageProvider>
+#include <QQmlEngine>
+
 // KDE
 #include <kglobalaccel.h>
 #include <klocalizedstring.h>
@@ -134,6 +138,92 @@ namespace {
         }
     }
 
+    class ThumbnailImageResponse: public QQuickImageResponse {
+    public:
+        ThumbnailImageResponse(const QString &id, const QSize &requestedSize)
+            : m_id(id)
+            , m_requestedSize(requestedSize)
+            , m_texture(Q_NULLPTR)
+        {
+            qDebug() << "GREPME Getting the thumbnail for: " << m_id;
+            run();
+            // setAutoDelete(false);
+        }
+
+        QQuickTextureFactory *textureFactory() const
+        {
+            return m_texture;
+        }
+
+        void run()
+        {
+            int width = m_requestedSize.width();
+            int height = m_requestedSize.height();
+
+            if (width == 0) {
+                width = 320;
+            }
+
+            if (height == 0) {
+                height = 240;
+            }
+            qDebug() << "GREPME Getting the thumbnail for: " << m_id;
+            const auto file = QUrl::fromUserInput(m_id);
+
+            KFileItemList list;
+            list.append(KFileItem(file, QString(), 0));
+
+            auto job =
+                KIO::filePreview(list, QSize(width, height));
+            job->setScaleType(KIO::PreviewJob::Scaled);
+            job->setIgnoreMaximumSize(true);
+
+            connect(job, &KIO::PreviewJob::gotPreview,
+                    this, [this,file] (const KFileItem& item, const QPixmap& pixmap) \
{ +                        Q_UNUSED(item);
+                        qDebug() << " ----> GREPME We got a preview for: " << file \
<< pixmap; +
+                        m_texture = \
QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()); +                     \
emit finished(); +                    }, Qt::QueuedConnection);
+
+            connect(job, &KIO::PreviewJob::failed,
+                    this, [this,job] (const KFileItem& item) {
+                        Q_UNUSED(item);
+                        qWarning() << "SwitcherBackend: FAILED to get the \
thumbnail"; +                        emit finished();
+                    });
+            // QImage image(50, 50, QImage::Format_RGB32);
+            // if (m_id == "slow") {
+            //     qDebug() << "Slow, red, sleeping for 5 seconds";
+            //     QThread::sleep(5);
+            //     image.fill(Qt::red);
+            // } else {
+            //     qDebug() << "Fast, blue, sleeping for 1 second";
+            //     QThread::sleep(1);
+            //     image.fill(Qt::blue);
+            // }
+            // if (m_requestedSize.isValid())
+            //     image = image.scaled(m_requestedSize);
+            // m_texture = QQuickTextureFactory::textureFactoryForImage(image);
+            //       emit finished();
+        }
+
+        QString m_id;
+        QSize m_requestedSize;
+        QQuickTextureFactory *m_texture;
+    };
+
+    class ThumbnailImageProvider: public QQuickAsyncImageProvider {
+    public:
+        QQuickImageResponse *requestImageResponse(const QString &id,
+                                                  const QSize &requestedSize)
+        {
+            return new ThumbnailImageResponse(id, requestedSize);
+        }
+    };
+
+
 
 } // local namespace
 
@@ -193,8 +283,10 @@ SwitcherBackend::~SwitcherBackend()
 
 QObject *SwitcherBackend::instance(QQmlEngine *engine, QJSEngine *scriptEngine)
 {
-    Q_UNUSED(engine)
+    // Q_UNUSED(engine)
     Q_UNUSED(scriptEngine)
+    qDebug() << "GREPME Register thumbnailer";
+    engine->addImageProvider("wallpaperthumbnail", new ThumbnailImageProvider());
     return new SwitcherBackend();
 }
 
@@ -360,43 +452,69 @@ QPixmap SwitcherBackend::wallpaperThumbnail(const QString \
&path, int width, int  + QString::number(width) + "x"
         + QString::number(height);
 
+    qDebug() << "GREPME Pixmap key is: " << pixmapKey;
+
     if (m_wallpaperCache->findPixmap(pixmapKey, &preview)) {
+        qDebug() << " ----> GREPME pixmap is here - is it null? "
+                 << preview.isNull()
+                 << preview;
+        return preview;
+    }
+
+    const auto file = QUrl::fromUserInput(path);
+
+    // If we already have a thumbnail job for this file,
+    // just register the callback that we need to call
+    // when the job is done
+    const bool jobAlreadyRunning = m_previewJobs.contains(pixmapKey);
+    m_previewJobs.insert(pixmapKey, callback);
+
+    if (jobAlreadyRunning) {
+        qDebug() << " ... GREPME Preview already requested";
         return preview;
     }
 
-    QUrl file = QUrl::fromLocalFile(path);
+    qDebug() << " ... GREPME Creating preview for " << file;
 
-    if (!m_previewJobs.contains(file) && file.isValid()) {
-        m_previewJobs.insert(file);
+    KFileItemList list;
+    list.append(KFileItem(file, QString(), 0));
 
-        KFileItemList list;
-        list.append(KFileItem(file, QString(), 0));
+    auto job =
+        KIO::filePreview(list, QSize(width, height));
+    job->setScaleType(KIO::PreviewJob::Scaled);
+    job->setIgnoreMaximumSize(true);
 
-        KIO::PreviewJob* job =
-            KIO::filePreview(list, QSize(width, height));
-        job->setScaleType(KIO::PreviewJob::Scaled);
-        job->setIgnoreMaximumSize(true);
+    connect(job, &KIO::PreviewJob::gotPreview,
+            this, [this,pixmapKey] (const KFileItem& item, const QPixmap& pixmap) {
+                Q_UNUSED(item);
+                qDebug() << " ----> GREPME We got a preview for: " << pixmapKey << \
pixmap; +                m_wallpaperCache->insertPixmap(pixmapKey, pixmap);
 
-        connect(job, &KIO::PreviewJob::gotPreview,
-                this, [=] (const KFileItem& item, const QPixmap& pixmap) mutable {
-                    Q_UNUSED(item);
-                    m_wallpaperCache->insertPixmap(pixmapKey, pixmap);
-                    m_previewJobs.remove(file);
+                auto callbacks = m_previewJobs.values(pixmapKey);
 
+                m_previewJobs.remove(pixmapKey);
+
+                for (auto& callback: callbacks) {
+                    qDebug() << "    GREPME Calling the callback";
                     callback.call({true});
-                });
+                }
+            }, Qt::QueuedConnection);
 
-        connect(job, &KIO::PreviewJob::failed,
-                this, [=] (const KFileItem& item) mutable {
-                    Q_UNUSED(item);
-                    m_previewJobs.remove(file);
+    connect(job, &KIO::PreviewJob::failed,
+            this, [this,pixmapKey,job] (const KFileItem& item) {
+                Q_UNUSED(item);
+                auto callbacks = m_previewJobs.values(pixmapKey);
 
-                    qWarning() << "SwitcherBackend: FAILED to get the thumbnail for \
                "
-                               << path << job->detailedErrorStrings(&file);
-                    callback.call({false});
-                });
+                m_previewJobs.remove(pixmapKey);
 
-    }
+                qWarning() << "SwitcherBackend: FAILED to get the thumbnail for "
+                           << pixmapKey;// << job->detailedErrorStrings(&file);
+
+                for (auto& callback: callbacks) {
+                    qDebug() << "!!!!! GREPME Calling the callback to tell it that \
we failed"; +                    callback.call({false});
+                }
+            });
 
     return preview;
 }
diff --git a/imports/activitymanager/switcherbackend.h \
b/imports/activitymanager/switcherbackend.h index 6f9e0d7..5b52a0c 100644
--- a/imports/activitymanager/switcherbackend.h
+++ b/imports/activitymanager/switcherbackend.h
@@ -103,7 +103,7 @@ private:
     QString m_previousActivity;
 
     KImageCache *m_wallpaperCache;
-    QSet<QUrl> m_previewJobs;
+    QMultiHash<QString, QJSValue> m_previewJobs;
 
     SortedActivitiesModel *m_runningActivitiesModel;
     SortedActivitiesModel *m_stoppedActivitiesModel;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic