From 0a84ef4b2c4d0d044e6ebc99d8a1c4328b7b290c Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Wed, 25 May 2022 17:04:20 +0200 Subject: [PATCH] QmlDesigner: Refactor ImageCache Move the ImageCache from the ItemLibraryView to a more centralized location. Change-Id: Ic0721976650dad8af26c29b50fed8aec0fffbf75 Reviewed-by: Reviewed-by: Qt CI Bot Reviewed-by: Miikka Heikkinen Reviewed-by: Marco Bubke --- .../itemlibrary/itemlibraryview.cpp | 86 ++----------------- .../components/itemlibrary/itemlibraryview.h | 13 +-- .../itemlibrary/itemlibrarywidget.cpp | 7 +- .../itemlibrary/itemlibrarywidget.h | 6 +- .../designercore/include/viewmanager.h | 5 +- .../designercore/model/viewmanager.cpp | 16 ++-- src/plugins/qmldesigner/qmldesignerplugin.cpp | 4 +- .../qmldesigner/qmldesignerprojectmanager.cpp | 71 +++++++++++++-- .../qmldesigner/qmldesignerprojectmanager.h | 20 +++-- 9 files changed, 101 insertions(+), 127 deletions(-) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp index 9267e367935..21928ea06ae 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp @@ -30,12 +30,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #include #include @@ -44,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -52,38 +45,9 @@ namespace QmlDesigner { -namespace { -ProjectExplorer::Target *activeTarget(ProjectExplorer::Project *project) -{ - if (project) - return project->activeTarget(); - - return {}; -} -} // namespace - -class ItemLibraryView::ImageCacheData -{ -public: - Sqlite::Database database{Utils::PathString{ - Core::ICore::cacheResourcePath("imagecache-v2.db").toString()}, - Sqlite::JournalMode::Wal, - Sqlite::LockingMode::Normal}; - ImageCacheStorage storage{database}; - ImageCacheConnectionManager connectionManager; - ImageCacheCollector collector{connectionManager, QSize{300, 300}, QSize{600, 600}}; - ImageCacheFontCollector fontCollector; - ImageCacheGenerator generator{collector, storage}; - ImageCacheGenerator fontGenerator{fontCollector, storage}; - TimeStampProvider timeStampProvider; - AsynchronousImageCache cache{storage, generator, timeStampProvider}; - AsynchronousImageCache asynchronousFontImageCache{storage, fontGenerator, timeStampProvider}; - SynchronousImageCache synchronousFontImageCache{storage, timeStampProvider, fontCollector}; -}; - -ItemLibraryView::ItemLibraryView(QObject* parent) - : AbstractView(parent) - +ItemLibraryView::ItemLibraryView(AsynchronousImageCache &imageCache) + : AbstractView() + , m_imageCache(imageCache) {} ItemLibraryView::~ItemLibraryView() @@ -97,11 +61,8 @@ bool ItemLibraryView::hasWidget() const WidgetInfo ItemLibraryView::widgetInfo() { - if (m_widget.isNull()) { - m_widget = new ItemLibraryWidget{imageCacheData()->cache, - imageCacheData()->asynchronousFontImageCache, - imageCacheData()->synchronousFontImageCache}; - } + if (m_widget.isNull()) + m_widget = new ItemLibraryWidget{m_imageCache}; return createWidgetInfo(m_widget.data(), new WidgetInfo::ToolBarWidgetDefaultFactory(m_widget.data()), @@ -182,43 +143,6 @@ void ItemLibraryView::usedImportsChanged(const QList &usedImports) m_widget->updateUsedImports(usedImports); } -ItemLibraryView::ImageCacheData *ItemLibraryView::imageCacheData() -{ - std::call_once(imageCacheFlag, [this]() { - m_imageCacheData = std::make_unique(); - auto setTargetInImageCache = - [imageCacheData = m_imageCacheData.get()](ProjectExplorer::Target *target) { - if (target == imageCacheData->collector.target()) - return; - - if (target) - imageCacheData->cache.clean(); - - imageCacheData->collector.setTarget(target); - }; - - if (auto project = ProjectExplorer::SessionManager::startupProject(); project) { - m_imageCacheData->collector.setTarget(project->activeTarget()); - connect(project, - &ProjectExplorer::Project::activeTargetChanged, - this, - setTargetInImageCache); - } - connect(ProjectExplorer::SessionManager::instance(), - &ProjectExplorer::SessionManager::startupProjectChanged, - this, - [=](ProjectExplorer::Project *project) { - setTargetInImageCache(activeTarget(project)); - }); - }); - return m_imageCacheData.get(); -} - -AsynchronousImageCache &ItemLibraryView::imageCache() -{ - return imageCacheData()->cache; -} - void ItemLibraryView::documentMessagesChanged(const QList &errors, const QList &) { if (m_hasErrors && errors.isEmpty()) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h index b7b91eaf3f8..4a0925064fb 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h @@ -29,19 +29,16 @@ #include -#include - namespace QmlDesigner { class ItemLibraryWidget; -class AsynchronousImageCache; class ItemLibraryView : public AbstractView { Q_OBJECT public: - ItemLibraryView(QObject* parent = nullptr); + ItemLibraryView(class AsynchronousImageCache &imageCache); ~ItemLibraryView() override; bool hasWidget() const override; @@ -58,17 +55,11 @@ public: void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data) override; - AsynchronousImageCache &imageCache(); - protected: void updateImports(); private: - class ImageCacheData; - ImageCacheData *imageCacheData(); - - std::once_flag imageCacheFlag; - std::unique_ptr m_imageCacheData; + AsynchronousImageCache &m_imageCache; QPointer m_widget; bool m_hasErrors = false; QVariantMap m_importableExtensions3DMap; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 511ef37f196..75a564d7384 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -140,18 +140,13 @@ void ItemLibraryWidget::resizeEvent(QResizeEvent *event) isHorizontalLayout = event->size().width() >= HORIZONTAL_LAYOUT_WIDTH_LIMIT; } -ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache, - AsynchronousImageCache &asynchronousFontImageCache, - SynchronousImageCache &synchronousFontImageCache) +ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache) : m_itemIconSize(24, 24) - , m_fontImageCache(synchronousFontImageCache) , m_itemLibraryModel(new ItemLibraryModel(this)) , m_addModuleModel(new ItemLibraryAddImportModel(this)) , m_itemsWidget(new QQuickWidget(this)) , m_imageCache{imageCache} { - Q_UNUSED(asynchronousFontImageCache) - m_compressionTimer.setInterval(200); m_compressionTimer.setSingleShot(true); ItemLibraryModel::registerQmlTypes(); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h index a7f23180730..be905f181ae 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -56,7 +56,6 @@ class Model; class ItemLibraryModel; class ItemLibraryAddImportModel; class ItemLibraryResourceView; -class SynchronousImageCache; class AsynchronousImageCache; class ImageCacheCollector; @@ -67,9 +66,7 @@ class ItemLibraryWidget : public QFrame public: Q_PROPERTY(bool subCompEditMode READ subCompEditMode NOTIFY subCompEditModeChanged) - ItemLibraryWidget(AsynchronousImageCache &imageCache, - AsynchronousImageCache &asynchronousFontImageCache, - SynchronousImageCache &synchronousFontImageCache); + ItemLibraryWidget(AsynchronousImageCache &imageCache); ~ItemLibraryWidget(); void setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo); @@ -115,7 +112,6 @@ private: QTimer m_compressionTimer; QSize m_itemIconSize; - SynchronousImageCache &m_fontImageCache; QPointer m_itemLibraryInfo; QPointer m_itemLibraryModel; diff --git a/src/plugins/qmldesigner/designercore/include/viewmanager.h b/src/plugins/qmldesigner/designercore/include/viewmanager.h index 04f25b84f81..dd77c07f459 100644 --- a/src/plugins/qmldesigner/designercore/include/viewmanager.h +++ b/src/plugins/qmldesigner/designercore/include/viewmanager.h @@ -47,12 +47,11 @@ class Edit3DView; namespace Internal { class DesignModeWidget; } class ViewManagerData; -class AsynchronousImageCache; class QMLDESIGNERCORE_EXPORT ViewManager { public: - ViewManager(); + ViewManager(class AsynchronousImageCache &imageCache); ~ViewManager(); void attachRewriterView(); @@ -107,8 +106,6 @@ public: void disableStandardViews(); void enableStandardViews(); - AsynchronousImageCache &imageCache(); - private: // functions Q_DISABLE_COPY(ViewManager) diff --git a/src/plugins/qmldesigner/designercore/model/viewmanager.cpp b/src/plugins/qmldesigner/designercore/model/viewmanager.cpp index 8ad61d320cf..8e96507cd53 100644 --- a/src/plugins/qmldesigner/designercore/model/viewmanager.cpp +++ b/src/plugins/qmldesigner/designercore/model/viewmanager.cpp @@ -62,6 +62,10 @@ static Q_LOGGING_CATEGORY(viewBenchmark, "qtc.viewmanager.attach", QtWarningMsg) class ViewManagerData { public: + ViewManagerData(AsynchronousImageCache &imageCache) + : itemLibraryView(imageCache) + {} + InteractiveConnectionManager connectionManager; CapturingConnectionManager capturingConnectionManager; QmlModelState savedState; @@ -90,12 +94,13 @@ static CrumbleBar *crumbleBar() { return QmlDesignerPlugin::instance()->mainWidget()->crumbleBar(); } -ViewManager::ViewManager() - : d(std::make_unique()) +ViewManager::ViewManager(AsynchronousImageCache &imageCache) + : d(std::make_unique(imageCache)) { d->formEditorView.setGotoErrorCallback([this](int line, int column) { d->textEditorView.gotoCursorPosition(line, column); - if (Internal::DesignModeWidget *designModeWidget = QmlDesignerPlugin::instance()->mainWidget()) + if (Internal::DesignModeWidget *designModeWidget = QmlDesignerPlugin::instance() + ->mainWidget()) designModeWidget->showDockWidget("TextEditor"); }); } @@ -438,11 +443,6 @@ void ViewManager::enableStandardViews() attachViewsExceptRewriterAndComponetView(); } -AsynchronousImageCache &ViewManager::imageCache() -{ - return d->itemLibraryView.imageCache(); -} - void ViewManager::addView(std::unique_ptr &&view) { d->additionalViews.push_back(std::move(view)); diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index ae596bb9001..e6f40d14fc6 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -137,7 +137,7 @@ class QmlDesignerPluginPrivate { public: QmlDesignerProjectManager projectManager; - ViewManager viewManager; + ViewManager viewManager{projectManager.asynchronousImageCache()}; DocumentManager documentManager; ShortCutManager shortCutManager; SettingsPage settingsPage; @@ -670,7 +670,7 @@ void QmlDesignerPlugin::emitUsageStatisticsHelpRequested(const QString &identifi AsynchronousImageCache &QmlDesignerPlugin::imageCache() { - return m_instance->d->viewManager.imageCache(); + return m_instance->d->projectManager.asynchronousImageCache(); } void QmlDesignerPlugin::registerPreviewImageProvider(QQmlEngine *engine) diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp index 538c3939f2f..43070221bcf 100644 --- a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp +++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -60,6 +61,14 @@ namespace QmlDesigner { namespace { +ProjectExplorer::Target *activeTarget(ProjectExplorer::Project *project) +{ + if (project) + return project->activeTarget(); + + return {}; +} + QString defaultImagePath() { return Core::ICore::resourcePath("qmldesigner/welcomepage/images/newThumbnail.png").toString(); @@ -89,7 +98,22 @@ public: } // namespace -class PreviewImageCacheData +class QmlDesignerProjectManager::ImageCacheData +{ +public: + Sqlite::Database database{Utils::PathString{ + Core::ICore::cacheResourcePath("imagecache-v2.db").toString()}, + Sqlite::JournalMode::Wal, + Sqlite::LockingMode::Normal}; + ImageCacheStorage storage{database}; + ImageCacheConnectionManager connectionManager; + ImageCacheCollector collector{connectionManager, QSize{300, 300}, QSize{600, 600}}; + ImageCacheGenerator generator{collector, storage}; + TimeStampProvider timeStampProvider; + AsynchronousImageCache asynchronousImageCache{storage, generator, timeStampProvider}; +}; + +class QmlDesignerProjectManager::PreviewImageCacheData { public: Sqlite::Database database{Utils::PathString{ @@ -100,7 +124,7 @@ public: AsynchronousExplicitImageCache cache{storage}; }; -class QmlDesignerProjectManagerProjectData +class QmlDesignerProjectManager::QmlDesignerProjectManagerProjectData { public: QmlDesignerProjectManagerProjectData(ImageCacheStorage &storage) @@ -117,7 +141,7 @@ public: }; QmlDesignerProjectManager::QmlDesignerProjectManager() - : m_imageCacheData{std::make_unique()} + : m_previewImageCacheData{std::make_unique()} { auto editorManager = ::Core::EditorManager::instance(); QObject::connect(editorManager, &::Core::EditorManager::editorOpened, [&](auto *editor) { @@ -145,12 +169,17 @@ QmlDesignerProjectManager::~QmlDesignerProjectManager() = default; void QmlDesignerProjectManager::registerPreviewImageProvider(QQmlEngine *engine) const { - auto imageProvider = std::make_unique(m_imageCacheData->cache, + auto imageProvider = std::make_unique(m_previewImageCacheData->cache, QImage{defaultImagePath()}); engine->addImageProvider("project_preview", imageProvider.release()); } +AsynchronousImageCache &QmlDesignerProjectManager::asynchronousImageCache() +{ + return imageCacheData()->asynchronousImageCache; +} + void QmlDesignerProjectManager::editorOpened(::Core::IEditor *) {} void QmlDesignerProjectManager::currentEditorChanged(::Core::IEditor *) @@ -171,7 +200,7 @@ void QmlDesignerProjectManager::editorsClosed(const QList<::Core::IEditor *> &) void QmlDesignerProjectManager::projectAdded(::ProjectExplorer::Project *project) { - m_projectData = std::make_unique(m_imageCacheData->storage); + m_projectData = std::make_unique(m_previewImageCacheData->storage); m_projectData->activeTarget = project->activeTarget(); } @@ -183,4 +212,36 @@ void QmlDesignerProjectManager::aboutToRemoveProject(::ProjectExplorer::Project void QmlDesignerProjectManager::projectRemoved(::ProjectExplorer::Project *) {} +QmlDesignerProjectManager::ImageCacheData *QmlDesignerProjectManager::imageCacheData() +{ + std::call_once(imageCacheFlag, [this]() { + m_imageCacheData = std::make_unique(); + auto setTargetInImageCache = + [imageCacheData = m_imageCacheData.get()](ProjectExplorer::Target *target) { + if (target == imageCacheData->collector.target()) + return; + + if (target) + imageCacheData->asynchronousImageCache.clean(); + + imageCacheData->collector.setTarget(target); + }; + + if (auto project = ProjectExplorer::SessionManager::startupProject(); project) { + m_imageCacheData->collector.setTarget(project->activeTarget()); + QObject::connect(project, + &ProjectExplorer::Project::activeTargetChanged, + this, + setTargetInImageCache); + } + QObject::connect(ProjectExplorer::SessionManager::instance(), + &ProjectExplorer::SessionManager::startupProjectChanged, + this, + [=](ProjectExplorer::Project *project) { + setTargetInImageCache(activeTarget(project)); + }); + }); + return m_imageCacheData.get(); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.h b/src/plugins/qmldesigner/qmldesignerprojectmanager.h index 4b993ba74d2..6b94fa9e6f4 100644 --- a/src/plugins/qmldesigner/qmldesignerprojectmanager.h +++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.h @@ -26,8 +26,10 @@ #pragma once #include +#include #include +#include QT_FORWARD_DECLARE_CLASS(QQmlEngine) @@ -42,17 +44,22 @@ class Target; namespace QmlDesigner { -class QmlDesignerProjectManagerProjectData; -class PreviewImageCacheData; - -class QmlDesignerProjectManager +class QmlDesignerProjectManager : public QObject { + Q_OBJECT + + class QmlDesignerProjectManagerProjectData; + class PreviewImageCacheData; + class ImageCacheData; + public: QmlDesignerProjectManager(); ~QmlDesignerProjectManager(); void registerPreviewImageProvider(QQmlEngine *engine) const; + class AsynchronousImageCache &asynchronousImageCache(); + private: void editorOpened(::Core::IEditor *editor); void currentEditorChanged(::Core::IEditor *); @@ -60,9 +67,12 @@ private: void projectAdded(::ProjectExplorer::Project *project); void aboutToRemoveProject(::ProjectExplorer::Project *project); void projectRemoved(::ProjectExplorer::Project *project); + ImageCacheData *imageCacheData(); private: - std::unique_ptr m_imageCacheData; + std::once_flag imageCacheFlag; + std::unique_ptr m_imageCacheData; + std::unique_ptr m_previewImageCacheData; std::unique_ptr m_projectData; }; } // namespace QmlDesigner