forked from qt-creator/qt-creator
QmlDesigner: Add image for broken preview
Task-number: QDS-9048 Change-Id: Ic2ce8bf4d51f72c3ddae588709820728fc7c76b5 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Tim Jenssen <tim.jenssen@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -37,6 +37,7 @@ QQuickImageResponse *ItemLibraryIconImageProvider::requestImageResponse(const QS
|
|||||||
[response, abortReason] {
|
[response, abortReason] {
|
||||||
switch (abortReason) {
|
switch (abortReason) {
|
||||||
case ImageCache::AbortReason::Failed:
|
case ImageCache::AbortReason::Failed:
|
||||||
|
case ImageCache::AbortReason::NoEntry:
|
||||||
if (response)
|
if (response)
|
||||||
response->abort();
|
response->abort();
|
||||||
break;
|
break;
|
||||||
|
@@ -60,10 +60,14 @@ void AsynchronousExplicitImageCache::request(Utils::SmallStringView name,
|
|||||||
};
|
};
|
||||||
const auto entry = requestImageFromStorage(requestType);
|
const auto entry = requestImageFromStorage(requestType);
|
||||||
|
|
||||||
if (entry && !entry->isNull())
|
if (entry) {
|
||||||
captureCallback(*entry);
|
if (entry->isNull())
|
||||||
else
|
abortCallback(ImageCache::AbortReason::Failed);
|
||||||
abortCallback(ImageCache::AbortReason::Failed);
|
else
|
||||||
|
captureCallback(*entry);
|
||||||
|
} else {
|
||||||
|
abortCallback(ImageCache::AbortReason::NoEntry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsynchronousExplicitImageCache::wait()
|
void AsynchronousExplicitImageCache::wait()
|
||||||
|
@@ -27,16 +27,20 @@ QQuickImageResponse *ExplicitImageCacheImageProvider::requestImageResponse(const
|
|||||||
},
|
},
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
},
|
},
|
||||||
[response = QPointer<ImageCacheImageResponse>(response.get())](
|
[response = QPointer<ImageCacheImageResponse>(response.get()),
|
||||||
ImageCache::AbortReason abortReason) {
|
failedImage = m_failedImage](ImageCache::AbortReason abortReason) {
|
||||||
QMetaObject::invokeMethod(
|
QMetaObject::invokeMethod(
|
||||||
response,
|
response,
|
||||||
[response, abortReason] {
|
[response, abortReason, failedImage] {
|
||||||
switch (abortReason) {
|
switch (abortReason) {
|
||||||
case ImageCache::AbortReason::Failed:
|
case ImageCache::AbortReason::NoEntry:
|
||||||
if (response)
|
if (response)
|
||||||
response->abort();
|
response->abort();
|
||||||
break;
|
break;
|
||||||
|
case ImageCache::AbortReason::Failed:
|
||||||
|
if (response)
|
||||||
|
response->setImage(failedImage);
|
||||||
|
break;
|
||||||
case ImageCache::AbortReason::Abort:
|
case ImageCache::AbortReason::Abort:
|
||||||
response->cancel();
|
response->cancel();
|
||||||
break;
|
break;
|
||||||
|
@@ -14,9 +14,11 @@ class ExplicitImageCacheImageProvider : public QQuickAsyncImageProvider
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ExplicitImageCacheImageProvider(AsynchronousExplicitImageCache &imageCache,
|
ExplicitImageCacheImageProvider(AsynchronousExplicitImageCache &imageCache,
|
||||||
const QImage &defaultImage)
|
const QImage &defaultImage,
|
||||||
|
const QImage &failedImage)
|
||||||
: m_cache(imageCache)
|
: m_cache(imageCache)
|
||||||
, m_defaultImage(defaultImage)
|
, m_defaultImage(defaultImage)
|
||||||
|
, m_failedImage(failedImage)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override;
|
QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override;
|
||||||
@@ -24,6 +26,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
AsynchronousExplicitImageCache &m_cache;
|
AsynchronousExplicitImageCache &m_cache;
|
||||||
QImage m_defaultImage;
|
QImage m_defaultImage;
|
||||||
|
QImage m_failedImage;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -32,6 +32,7 @@ QQuickImageResponse *MidSizeImageCacheProvider::requestImageResponse(const QStri
|
|||||||
[response, abortReason] {
|
[response, abortReason] {
|
||||||
switch (abortReason) {
|
switch (abortReason) {
|
||||||
case ImageCache::AbortReason::Failed:
|
case ImageCache::AbortReason::Failed:
|
||||||
|
case ImageCache::AbortReason::NoEntry:
|
||||||
if (response)
|
if (response)
|
||||||
response->abort();
|
response->abort();
|
||||||
break;
|
break;
|
||||||
|
@@ -33,6 +33,7 @@ QQuickImageResponse *SmallImageCacheProvider::requestImageResponse(const QString
|
|||||||
[response, abortReason] {
|
[response, abortReason] {
|
||||||
switch (abortReason) {
|
switch (abortReason) {
|
||||||
case ImageCache::AbortReason::Failed:
|
case ImageCache::AbortReason::Failed:
|
||||||
|
case ImageCache::AbortReason::NoEntry:
|
||||||
if (response)
|
if (response)
|
||||||
response->abort();
|
response->abort();
|
||||||
break;
|
break;
|
||||||
|
@@ -43,7 +43,7 @@ using AuxiliaryData = std::variant<std::monostate,
|
|||||||
FontCollectorSizeAuxiliaryData,
|
FontCollectorSizeAuxiliaryData,
|
||||||
FontCollectorSizesAuxiliaryData>;
|
FontCollectorSizesAuxiliaryData>;
|
||||||
|
|
||||||
enum class AbortReason : char { Abort, Failed };
|
enum class AbortReason : char { Abort, Failed, NoEntry };
|
||||||
|
|
||||||
using CaptureImageCallback = std::function<void(const QImage &)>;
|
using CaptureImageCallback = std::function<void(const QImage &)>;
|
||||||
using CaptureImageWithScaledImagesCallback = std::function<
|
using CaptureImageWithScaledImagesCallback = std::function<
|
||||||
|
@@ -54,11 +54,16 @@ ProjectExplorer::Target *activeTarget(ProjectExplorer::Project *project)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QString defaultImagePath()
|
QString previewDefaultImagePath()
|
||||||
{
|
{
|
||||||
return Core::ICore::resourcePath("qmldesigner/welcomepage/images/newThumbnail.png").toString();
|
return Core::ICore::resourcePath("qmldesigner/welcomepage/images/newThumbnail.png").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString previewBrokenImagePath()
|
||||||
|
{
|
||||||
|
return Core::ICore::resourcePath("qmldesigner/welcomepage/images/newPreview.png").toString();
|
||||||
|
}
|
||||||
|
|
||||||
::QmlProjectManager::QmlBuildSystem *getQmlBuildSystem(::ProjectExplorer::Target *target)
|
::QmlProjectManager::QmlBuildSystem *getQmlBuildSystem(::ProjectExplorer::Target *target)
|
||||||
{
|
{
|
||||||
return qobject_cast<::QmlProjectManager::QmlBuildSystem *>(target->buildSystem());
|
return qobject_cast<::QmlProjectManager::QmlBuildSystem *>(target->buildSystem());
|
||||||
@@ -147,7 +152,7 @@ public:
|
|||||||
QSize{300, 300},
|
QSize{300, 300},
|
||||||
QSize{1000, 1000},
|
QSize{1000, 1000},
|
||||||
externalDependencies,
|
externalDependencies,
|
||||||
ImageCacheCollectorNullImageHandling::DontCaptureNullImage}
|
ImageCacheCollectorNullImageHandling::CaptureNullImage}
|
||||||
{
|
{
|
||||||
timer.setSingleShot(true);
|
timer.setSingleShot(true);
|
||||||
}
|
}
|
||||||
@@ -260,8 +265,10 @@ QmlDesignerProjectManager::~QmlDesignerProjectManager() = default;
|
|||||||
|
|
||||||
void QmlDesignerProjectManager::registerPreviewImageProvider(QQmlEngine *engine) const
|
void QmlDesignerProjectManager::registerPreviewImageProvider(QQmlEngine *engine) const
|
||||||
{
|
{
|
||||||
auto imageProvider = std::make_unique<ExplicitImageCacheImageProvider>(m_previewImageCacheData->cache,
|
auto imageProvider = std::make_unique<ExplicitImageCacheImageProvider>(
|
||||||
QImage{defaultImagePath()});
|
m_previewImageCacheData->cache,
|
||||||
|
QImage{previewDefaultImagePath()},
|
||||||
|
QImage{previewBrokenImagePath()});
|
||||||
|
|
||||||
engine->addImageProvider("project_preview", imageProvider.release());
|
engine->addImageProvider("project_preview", imageProvider.release());
|
||||||
}
|
}
|
||||||
|
@@ -74,7 +74,7 @@ TEST_F(AsynchronousExplicitImageCache, RequestImageCallsAbortCallbackWithoutEntr
|
|||||||
ON_CALL(mockStorage, fetchImage(Eq("/path/to/Component.qml"), _))
|
ON_CALL(mockStorage, fetchImage(Eq("/path/to/Component.qml"), _))
|
||||||
.WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::ImageEntry{}));
|
.WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::ImageEntry{}));
|
||||||
|
|
||||||
EXPECT_CALL(mockAbortCallback, Call(Eq(QmlDesigner::ImageCache::AbortReason::Failed)))
|
EXPECT_CALL(mockAbortCallback, Call(Eq(QmlDesigner::ImageCache::AbortReason::NoEntry)))
|
||||||
.WillRepeatedly([&](auto) { notification.notify(); });
|
.WillRepeatedly([&](auto) { notification.notify(); });
|
||||||
|
|
||||||
cache.requestImage("/path/to/Component.qml",
|
cache.requestImage("/path/to/Component.qml",
|
||||||
@@ -131,7 +131,7 @@ TEST_F(AsynchronousExplicitImageCache, RequestMidSizeImageCallsAbortCallbackWith
|
|||||||
ON_CALL(mockStorage, fetchMidSizeImage(Eq("/path/to/Component.qml"), _))
|
ON_CALL(mockStorage, fetchMidSizeImage(Eq("/path/to/Component.qml"), _))
|
||||||
.WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::ImageEntry{}));
|
.WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::ImageEntry{}));
|
||||||
|
|
||||||
EXPECT_CALL(mockAbortCallback, Call(Eq(QmlDesigner::ImageCache::AbortReason::Failed)))
|
EXPECT_CALL(mockAbortCallback, Call(Eq(QmlDesigner::ImageCache::AbortReason::NoEntry)))
|
||||||
.WillRepeatedly([&](auto) { notification.notify(); });
|
.WillRepeatedly([&](auto) { notification.notify(); });
|
||||||
|
|
||||||
cache.requestMidSizeImage("/path/to/Component.qml",
|
cache.requestMidSizeImage("/path/to/Component.qml",
|
||||||
@@ -188,7 +188,7 @@ TEST_F(AsynchronousExplicitImageCache, RequestSmallImageCallsAbortCallbackWithou
|
|||||||
ON_CALL(mockStorage, fetchSmallImage(Eq("/path/to/Component.qml"), _))
|
ON_CALL(mockStorage, fetchSmallImage(Eq("/path/to/Component.qml"), _))
|
||||||
.WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::ImageEntry{}));
|
.WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::ImageEntry{}));
|
||||||
|
|
||||||
EXPECT_CALL(mockAbortCallback, Call(Eq(QmlDesigner::ImageCache::AbortReason::Failed)))
|
EXPECT_CALL(mockAbortCallback, Call(Eq(QmlDesigner::ImageCache::AbortReason::NoEntry)))
|
||||||
.WillRepeatedly([&](auto) { notification.notify(); });
|
.WillRepeatedly([&](auto) { notification.notify(); });
|
||||||
|
|
||||||
cache.requestSmallImage("/path/to/Component.qml",
|
cache.requestSmallImage("/path/to/Component.qml",
|
||||||
|
Reference in New Issue
Block a user