From 15d92cf1e510e32f4e3e59b1311627848fb0dbcc Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 16 Jan 2023 13:55:02 +0200 Subject: [PATCH] Use imagecache for all AssetImageProvider images TextureImageCacheCollector is added to the existing async image cache to generate thumbnails for image files. Fixes: QDS-8581 Change-Id: I4a334b3241688d7a61a0560463bff32763a216a5 Reviewed-by: Thomas Hartmann Reviewed-by: Qt CI Bot Reviewed-by: --- .../materialBrowserQmlSource/TextureItem.qml | 5 +- .../imports/HelperWidgets/UrlChooser.qml | 2 - .../TextureEditorTopSection.qml | 5 +- src/plugins/qmldesigner/CMakeLists.txt | 4 +- .../materialbrowser/materialbrowserwidget.cpp | 4 +- .../materialbrowser/materialbrowserwidget.h | 4 +- .../propertyeditor/assetimageprovider.cpp | 32 +++++++++++ ...orimageprovider.h => assetimageprovider.h} | 12 ++-- .../propertyeditorimageprovider.cpp | 55 ------------------- .../quick2propertyeditorview.cpp | 4 +- .../textureeditor/textureeditorqmlbackend.cpp | 4 +- .../textureeditor/textureeditorqmlbackend.h | 5 +- .../imagecache/imagecachedispatchcollector.h | 3 +- .../imagecache/textureimagecachecollector.cpp | 54 ++++++++++++++++++ .../imagecache/textureimagecachecollector.h | 31 +++++++++++ .../qmldesigner/qmldesignerprojectmanager.cpp | 31 ++++++++--- src/plugins/qmldesigner/utils/asset.cpp | 4 +- 17 files changed, 171 insertions(+), 88 deletions(-) create mode 100644 src/plugins/qmldesigner/components/propertyeditor/assetimageprovider.cpp rename src/plugins/qmldesigner/components/propertyeditor/{propertyeditorimageprovider.h => assetimageprovider.h} (50%) delete mode 100644 src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.cpp create mode 100644 src/plugins/qmldesigner/designercore/imagecache/textureimagecachecollector.cpp create mode 100644 src/plugins/qmldesigner/designercore/imagecache/textureimagecachecollector.h diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml index a223668dc9b..b234d5981c7 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureItem.qml @@ -61,9 +61,10 @@ Rectangle { Image { source: "image://materialBrowserTex/" + textureSource asynchronous: true - sourceSize.width: root.width - 10 - sourceSize.height: root.height - 10 + width: root.width - 10 + height: root.height - 10 anchors.centerIn: parent smooth: true + fillMode: Image.PreserveAspectFit } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml index d6373f790ab..9414a744629 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml @@ -116,8 +116,6 @@ Row { Image { id: thumbnail asynchronous: true - sourceSize.height: 96 - sourceSize.width: 96 height: 96 width: 96 fillMode: Image.PreserveAspectFit diff --git a/share/qtcreator/qmldesigner/textureEditorQmlSource/TextureEditorTopSection.qml b/share/qtcreator/qmldesigner/textureEditorQmlSource/TextureEditorTopSection.qml index 016049df102..18ff2447944 100644 --- a/share/qtcreator/qmldesigner/textureEditorQmlSource/TextureEditorTopSection.qml +++ b/share/qtcreator/qmldesigner/textureEditorQmlSource/TextureEditorTopSection.qml @@ -35,8 +35,9 @@ Column { Image { id: texturePreview asynchronous: true - sourceSize.width: 150 - sourceSize.height: 150 + width: 150 + height: 150 + fillMode: Image.PreserveAspectFit anchors.centerIn: parent source: "image://qmldesigner_thumbnails/" + resolveResourcePath(backendValues.source.valueToString) } diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 811bcad4782..ec69bbc9b02 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -161,6 +161,8 @@ extend_qtc_library(QmlDesignerCore meshimagecachecollector.cpp meshimagecachecollector.h synchronousimagecache.cpp + textureimagecachecollector.cpp + textureimagecachecollector.h timestampprovider.cpp timestampprovider.h timestampproviderinterface.h @@ -774,6 +776,7 @@ extend_qtc_plugin(QmlDesigner SOURCES_PREFIX components/propertyeditor SOURCES aligndistribute.cpp aligndistribute.h + assetimageprovider.cpp assetimageprovider.h colorpalettebackend.cpp colorpalettebackend.h designerpropertymap.cpp designerpropertymap.h fileresourcesmodel.cpp fileresourcesmodel.h @@ -785,7 +788,6 @@ extend_qtc_plugin(QmlDesigner gradientpresetitem.cpp gradientpresetitem.h gradientpresetlistmodel.cpp gradientpresetlistmodel.h propertyeditorcontextobject.cpp propertyeditorcontextobject.h - propertyeditorimageprovider.cpp propertyeditorimageprovider.h propertyeditorqmlbackend.cpp propertyeditorqmlbackend.h propertyeditortransaction.cpp propertyeditortransaction.h propertyeditorvalue.cpp propertyeditorvalue.h diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index 64d285f9222..8cb3574d455 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -7,10 +7,10 @@ #include "materialbrowsertexturesmodel.h" #include "materialbrowserview.h" +#include #include #include #include -#include #include #include #include @@ -152,7 +152,7 @@ MaterialBrowserWidget::MaterialBrowserWidget(AsynchronousImageCache &imageCache, { QImage defaultImage; defaultImage.load(Utils::StyleHelper::dpiSpecificImageFile(":/textureeditor/images/texture_default.png")); - m_textureImageProvider = new PropertyEditorImageProvider(imageCache, defaultImage); + m_textureImageProvider = new AssetImageProvider(imageCache, defaultImage); setWindowTitle(tr("Material Browser", "Title of material browser widget")); setMinimumWidth(120); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h index 47930eee0ae..65f117548a2 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h @@ -24,11 +24,11 @@ QT_END_NAMESPACE namespace QmlDesigner { +class AssetImageProvider; class MaterialBrowserView; class MaterialBrowserModel; class MaterialBrowserTexturesModel; class PreviewImageProvider; -class PropertyEditorImageProvider; class MaterialBrowserWidget : public QFrame { @@ -80,7 +80,7 @@ private: QShortcut *m_qmlSourceUpdateShortcut = nullptr; PreviewImageProvider *m_previewImageProvider = nullptr; - PropertyEditorImageProvider *m_textureImageProvider = nullptr; + AssetImageProvider *m_textureImageProvider = nullptr; Core::IContext *m_context = nullptr; QString m_filterText; diff --git a/src/plugins/qmldesigner/components/propertyeditor/assetimageprovider.cpp b/src/plugins/qmldesigner/components/propertyeditor/assetimageprovider.cpp new file mode 100644 index 00000000000..a4f5a85108f --- /dev/null +++ b/src/plugins/qmldesigner/components/propertyeditor/assetimageprovider.cpp @@ -0,0 +1,32 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#include "assetimageprovider.h" + +#include +#include + +#include +#include +#include + +#include +#include + +namespace QmlDesigner { + +QQuickImageResponse *AssetImageProvider::requestImageResponse(const QString &id, + const QSize &requestedSize) +{ + Asset asset(id); + + if (asset.suffix() == "*.mesh") + return m_imageCacheProvider.requestImageResponse(id, {}); + + if (asset.suffix() == "*.builtin") + return m_imageCacheProvider.requestImageResponse("#" + id.split('.').first(), {}); + + return m_imageCacheProvider.requestImageResponse(id, requestedSize); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.h b/src/plugins/qmldesigner/components/propertyeditor/assetimageprovider.h similarity index 50% rename from src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.h rename to src/plugins/qmldesigner/components/propertyeditor/assetimageprovider.h index 23ff248277f..25d7ea61c98 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.h +++ b/src/plugins/qmldesigner/components/propertyeditor/assetimageprovider.h @@ -1,26 +1,26 @@ -// Copyright (C) 2022 The Qt Company Ltd. +// Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #pragma once -#include "imagecache/smallimagecacheprovider.h" +#include "imagecache/midsizeimagecacheprovider.h" #include namespace QmlDesigner { -class PropertyEditorImageProvider : public QQuickAsyncImageProvider +class AssetImageProvider : public QQuickAsyncImageProvider { public: - PropertyEditorImageProvider(AsynchronousImageCache &imageCache, const QImage &defaultImage = {}) - : m_smallImageCacheProvider(imageCache, defaultImage) + AssetImageProvider(AsynchronousImageCache &imageCache, const QImage &defaultImage = {}) + : m_imageCacheProvider(imageCache, defaultImage) {} QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override; private: - SmallImageCacheProvider m_smallImageCacheProvider; + MidSizeImageCacheProvider m_imageCacheProvider; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.cpp deleted file mode 100644 index caa5348bc42..00000000000 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 - -#include "propertyeditorimageprovider.h" - -#include -#include - -#include -#include -#include - -#include -#include - -namespace QmlDesigner { - -QQuickImageResponse *PropertyEditorImageProvider::requestImageResponse(const QString &id, - const QSize &requestedSize) -{ - Asset asset(id); - - if (asset.suffix() == "*.mesh") - return m_smallImageCacheProvider.requestImageResponse(id, requestedSize); - - if (asset.suffix() == "*.builtin") - return m_smallImageCacheProvider.requestImageResponse("#" + id.split('.').first(), - requestedSize); - - auto response = std::make_unique(m_smallImageCacheProvider.defaultImage()); - - QMetaObject::invokeMethod( - response.get(), - [response = QPointer(response.get()), asset, requestedSize] { - if (asset.isImage()) { - QImage image = QImage(Utils::StyleHelper::dpiSpecificImageFile(asset.id())); - if (!image.isNull()) { - response->setImage(image.scaled(requestedSize, Qt::KeepAspectRatio)); - return; - } - } else if (asset.isHdrFile()) { - HdrImage hdr{asset.id()}; - if (!hdr.image().isNull()) { - response->setImage(hdr.image().scaled(requestedSize, Qt::KeepAspectRatio)); - return; - } - } - response->setImage(response->image().scaled(requestedSize, Qt::KeepAspectRatio)); - }, - Qt::QueuedConnection); - - return response.release(); -} - -} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp index e5a21325ec2..9194bfa7150 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp @@ -4,6 +4,7 @@ #include "quick2propertyeditorview.h" #include "aligndistribute.h" +#include "assetimageprovider.h" #include "annotationeditor/annotationeditor.h" #include "bindingeditor/actioneditor.h" #include "bindingeditor/bindingeditor.h" @@ -16,7 +17,6 @@ #include "itemfiltermodel.h" #include "propertychangesmodel.h" #include "propertyeditorcontextobject.h" -#include "propertyeditorimageprovider.h" #include "propertyeditorqmlbackend.h" #include "propertyeditorvalue.h" #include "propertymodel.h" @@ -33,7 +33,7 @@ Quick2PropertyEditorView::Quick2PropertyEditorView(AsynchronousImageCache &image setResizeMode(QQuickWidget::SizeRootObjectToView); Theme::setupTheme(engine()); engine()->addImageProvider("qmldesigner_thumbnails", - new PropertyEditorImageProvider(imageCache)); + new AssetImageProvider(imageCache)); } void Quick2PropertyEditorView::registerQmlTypes() diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp index c3bcdd7d5e7..56f64eb17cb 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp @@ -3,10 +3,10 @@ #include "textureeditorqmlbackend.h" +#include "assetimageprovider.h" #include "bindingproperty.h" #include "documentmanager.h" #include "nodemetainfo.h" -#include "propertyeditorimageprovider.h" #include "propertyeditorvalue.h" #include "qmldesignerconstants.h" #include "qmlobjectnode.h" @@ -49,7 +49,7 @@ TextureEditorQmlBackend::TextureEditorQmlBackend(TextureEditorView *textureEdito { QImage defaultImage; defaultImage.load(Utils::StyleHelper::dpiSpecificImageFile(":/textureeditor/images/texture_default.png")); - m_textureEditorImageProvider = new PropertyEditorImageProvider(imageCache, defaultImage); + m_textureEditorImageProvider = new AssetImageProvider(imageCache, defaultImage); m_view->setResizeMode(QQuickWidget::SizeRootObjectToView); m_view->engine()->addImportPath(propertyEditorResourcesPath() + "/imports"); m_view->engine()->addImageProvider("qmldesigner_thumbnails", m_textureEditorImageProvider); diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h index 2d0131cc9fc..deea94e0961 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h @@ -17,9 +17,8 @@ QT_END_NAMESPACE namespace QmlDesigner { -class PropertyEditorImageProvider; +class AssetImageProvider; class TextureEditorContextObject; -class TextureEditorImageProvider; class TextureEditorTransaction; class TextureEditorView; @@ -65,7 +64,7 @@ private: DesignerPropertyMap m_backendValuesPropertyMap; QScopedPointer m_textureEditorTransaction; QScopedPointer m_contextObject; - PropertyEditorImageProvider *m_textureEditorImageProvider = nullptr; + AssetImageProvider *m_textureEditorImageProvider = nullptr; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachedispatchcollector.h b/src/plugins/qmldesigner/designercore/imagecache/imagecachedispatchcollector.h index 49678ec77fc..c5205e0c138 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/imagecachedispatchcollector.h +++ b/src/plugins/qmldesigner/designercore/imagecache/imagecachedispatchcollector.h @@ -84,9 +84,10 @@ private: Utils::SmallStringView, const ImageCache::AuxiliaryData &, CaptureCallback, - AbortCallback) + AbortCallback abortCallback) { qWarning() << "ImageCacheDispatchCollector: cannot handle file type."; + abortCallback(ImageCache::AbortReason::Failed); } template diff --git a/src/plugins/qmldesigner/designercore/imagecache/textureimagecachecollector.cpp b/src/plugins/qmldesigner/designercore/imagecache/textureimagecachecollector.cpp new file mode 100644 index 00000000000..73e2840dc1e --- /dev/null +++ b/src/plugins/qmldesigner/designercore/imagecache/textureimagecachecollector.cpp @@ -0,0 +1,54 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#include "textureimagecachecollector.h" + +#include +#include +#include +#include + +namespace QmlDesigner { + +TextureImageCacheCollector::TextureImageCacheCollector() = default; +TextureImageCacheCollector::~TextureImageCacheCollector() = default; + +void TextureImageCacheCollector::start(Utils::SmallStringView name, + Utils::SmallStringView, + const ImageCache::AuxiliaryData &auxiliaryData, + CaptureCallback captureCallback, + AbortCallback abortCallback) +{ + Asset asset {QString(name)}; + QImage image; + + if (asset.isImage()) { + image = QImage(Utils::StyleHelper::dpiSpecificImageFile(asset.id())); + } else if (asset.isHdrFile()) { + HdrImage hdr{asset.id()}; + if (!hdr.image().isNull()) + image = hdr.image().copy(); // Copy to ensure image data survives HdrImage destruction + } + + if (image.isNull()) + abortCallback(ImageCache::AbortReason::Failed); + else + image = image.scaled(QSize{300, 300}, Qt::KeepAspectRatio); + + captureCallback({}, image, {}); +} + +ImageCacheCollectorInterface::ImageTuple TextureImageCacheCollector::createImage( + Utils::SmallStringView, Utils::SmallStringView, const ImageCache::AuxiliaryData &) +{ + return {}; +} + +QIcon TextureImageCacheCollector::createIcon(Utils::SmallStringView, + Utils::SmallStringView, + const ImageCache::AuxiliaryData &) +{ + return {}; +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/imagecache/textureimagecachecollector.h b/src/plugins/qmldesigner/designercore/imagecache/textureimagecachecollector.h new file mode 100644 index 00000000000..67876d7641a --- /dev/null +++ b/src/plugins/qmldesigner/designercore/imagecache/textureimagecachecollector.h @@ -0,0 +1,31 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "imagecachecollectorinterface.h" + +namespace QmlDesigner { + +class TextureImageCacheCollector final : public ImageCacheCollectorInterface +{ +public: + TextureImageCacheCollector(); + ~TextureImageCacheCollector(); + + void start(Utils::SmallStringView filePath, + Utils::SmallStringView state, + const ImageCache::AuxiliaryData &auxiliaryData, + CaptureCallback captureCallback, + AbortCallback abortCallback) override; + + ImageTuple createImage(Utils::SmallStringView filePath, + Utils::SmallStringView state, + const ImageCache::AuxiliaryData &auxiliaryData) override; + + QIcon createIcon(Utils::SmallStringView filePath, + Utils::SmallStringView state, + const ImageCache::AuxiliaryData &auxiliaryData) override; +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp index 9e84a0de412..766b18af463 100644 --- a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp +++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp @@ -31,8 +31,11 @@ #include #include #include +#include #include +#include + #include #include @@ -76,8 +79,9 @@ public: } }; -auto makeCollecterDispatcherChain(ImageCacheCollector &nodeInstanceCollector, - MeshImageCacheCollector &meshImageCollector) +auto makeCollectorDispatcherChain(ImageCacheCollector &nodeInstanceCollector, + MeshImageCacheCollector &meshImageCollector, + TextureImageCacheCollector &textureImageCollector) { return std::make_tuple( std::make_pair([](Utils::SmallStringView filePath, @@ -91,8 +95,17 @@ auto makeCollecterDispatcherChain(ImageCacheCollector &nodeInstanceCollector, [[maybe_unused]] const QmlDesigner::ImageCache::AuxiliaryData &auxiliaryData) { return filePath.endsWith(".mesh") || filePath.startsWith("#"); }, - &meshImageCollector)); -} + &meshImageCollector), + std::make_pair( + [](Utils::SmallStringView filePath, + [[maybe_unused]] Utils::SmallStringView state, + [[maybe_unused]] const QmlDesigner::ImageCache::AuxiliaryData &auxiliaryData) { + Asset asset {QString(filePath)}; + Asset::Type type = asset.type(); + return type == Asset::Type::Image || type == Asset::Type::Texture3D; + }, + &textureImageCollector)); + } } // namespace class QmlDesignerProjectManager::ImageCacheData @@ -111,10 +124,14 @@ public: ImageCacheStorage storage{database}; ImageCacheConnectionManager connectionManager; MeshImageCacheCollector meshImageCollector; + TextureImageCacheCollector textureImageCollector; ImageCacheCollector nodeInstanceCollector; - ImageCacheDispatchCollector - dispatchCollector{makeCollecterDispatcherChain(nodeInstanceCollector, meshImageCollector)}; + ImageCacheDispatchCollector + dispatchCollector{makeCollectorDispatcherChain(nodeInstanceCollector, + meshImageCollector, + textureImageCollector)}; ImageCacheGenerator generator{dispatchCollector, storage}; TimeStampProvider timeStampProvider; AsynchronousImageCache asynchronousImageCache{storage, generator, timeStampProvider}; diff --git a/src/plugins/qmldesigner/utils/asset.cpp b/src/plugins/qmldesigner/utils/asset.cpp index 0dc66eeb3c6..31bce298b53 100644 --- a/src/plugins/qmldesigner/utils/asset.cpp +++ b/src/plugins/qmldesigner/utils/asset.cpp @@ -10,7 +10,9 @@ namespace QmlDesigner { Asset::Asset(const QString &filePath) : m_filePath(filePath) { - m_suffix = "*." + filePath.split('.').last().toLower(); + const QStringList split = filePath.split('.'); + if (split.size() > 1) + m_suffix = "*." + split.last().toLower(); }