QmlDesignerProjectManager: prevent crash at destruction

found in https://the-qt-company-00.sentry.io/issues/5315357110

Pick-to: qds/4.5
Change-Id: Ie8d7358c246799c5883e52fbdadb6f3a5e2a4359
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
Marco Bubke
2024-05-07 21:57:23 +02:00
committed by Tim Jenssen
parent 11802e70d3
commit a7fd0a78d1
2 changed files with 40 additions and 37 deletions

View File

@@ -210,10 +210,10 @@ std::unique_ptr<ProjectStorageData> createProjectStorageData(::ProjectExplorer::
} }
} // namespace } // namespace
class QmlDesignerProjectManager::QmlDesignerProjectManagerDirectoryInfo class QmlDesignerProjectManager::QmlDesignerProjectManagerProjectData
{ {
public: public:
QmlDesignerProjectManagerDirectoryInfo(ImageCacheStorage<Sqlite::Database> &storage, QmlDesignerProjectManagerProjectData(ImageCacheStorage<Sqlite::Database> &storage,
::ProjectExplorer::Project *project, ::ProjectExplorer::Project *project,
ExternalDependenciesInterface &externalDependencies) ExternalDependenciesInterface &externalDependencies)
: collector{connectionManager, : collector{connectionManager,
@@ -238,30 +238,34 @@ QmlDesignerProjectManager::QmlDesignerProjectManager(ExternalDependenciesInterfa
, m_externalDependencies{externalDependencies} , m_externalDependencies{externalDependencies}
{ {
auto editorManager = ::Core::EditorManager::instance(); auto editorManager = ::Core::EditorManager::instance();
QObject::connect(editorManager, &::Core::EditorManager::editorOpened, [&](auto *editor) { QObject::connect(editorManager, &::Core::EditorManager::editorOpened, &dummy, [&](auto *editor) {
editorOpened(editor); editorOpened(editor);
}); });
QObject::connect(editorManager, &::Core::EditorManager::currentEditorChanged, [&](auto *editor) { QObject::connect(editorManager,
currentEditorChanged(editor); &::Core::EditorManager::currentEditorChanged,
}); &dummy,
QObject::connect(editorManager, &::Core::EditorManager::editorsClosed, [&](const auto &editors) { [&](auto *editor) { currentEditorChanged(editor); });
editorsClosed(editors); QObject::connect(editorManager,
}); &::Core::EditorManager::editorsClosed,
&dummy,
[&](const auto &editors) { editorsClosed(editors); });
auto sessionManager = ::ProjectExplorer::ProjectManager::instance(); auto sessionManager = ::ProjectExplorer::ProjectManager::instance();
QObject::connect(sessionManager, QObject::connect(sessionManager,
&::ProjectExplorer::ProjectManager::projectAdded, &::ProjectExplorer::ProjectManager::projectAdded,
&dummy,
[&](auto *project) { projectAdded(project); }); [&](auto *project) { projectAdded(project); });
QObject::connect(sessionManager, QObject::connect(sessionManager,
&::ProjectExplorer::ProjectManager::aboutToRemoveProject, &::ProjectExplorer::ProjectManager::aboutToRemoveProject,
&dummy,
[&](auto *project) { aboutToRemoveProject(project); }); [&](auto *project) { aboutToRemoveProject(project); });
QObject::connect(sessionManager, QObject::connect(sessionManager,
&::ProjectExplorer::ProjectManager::projectRemoved, &::ProjectExplorer::ProjectManager::projectRemoved,
&dummy,
[&](auto *project) { projectRemoved(project); }); [&](auto *project) { projectRemoved(project); });
QObject::connect(&m_previewImageCacheData->timer, QObject::connect(&m_previewImageCacheData->timer, &QTimer::timeout, &dummy, [&]() {
&QTimer::timeout, generatePreview();
this, });
&QmlDesignerProjectManager::generatePreview);
} }
QmlDesignerProjectManager::~QmlDesignerProjectManager() = default; QmlDesignerProjectManager::~QmlDesignerProjectManager() = default;
@@ -297,8 +301,8 @@ namespace {
ProjectStorageDependencies QmlDesignerProjectManager::projectStorageDependencies() ProjectStorageDependencies QmlDesignerProjectManager::projectStorageDependencies()
{ {
if constexpr (useProjectStorage()) { if constexpr (useProjectStorage()) {
return {m_directoryInfo->projectStorageData->storage, return {m_projectData->projectStorageData->storage,
m_directoryInfo->projectStorageData->pathCache}; m_projectData->projectStorageData->pathCache};
} else { } else {
return {*dummyProjectStorage(), *dummyPathCache()}; return {*dummyProjectStorage(), *dummyPathCache()};
} }
@@ -499,10 +503,10 @@ QString qtCreatorItemLibraryPath()
void QmlDesignerProjectManager::projectAdded(::ProjectExplorer::Project *project) void QmlDesignerProjectManager::projectAdded(::ProjectExplorer::Project *project)
{ {
m_directoryInfo = std::make_unique<QmlDesignerProjectManagerDirectoryInfo>(m_previewImageCacheData->storage, m_projectData = std::make_unique<QmlDesignerProjectManagerProjectData>(m_previewImageCacheData->storage,
project, project,
m_externalDependencies); m_externalDependencies);
m_directoryInfo->activeTarget = project->activeTarget(); m_projectData->activeTarget = project->activeTarget();
QObject::connect(project, &::ProjectExplorer::Project::fileListChanged, [&]() { QObject::connect(project, &::ProjectExplorer::Project::fileListChanged, [&]() {
fileListChanged(); fileListChanged();
@@ -522,9 +526,9 @@ void QmlDesignerProjectManager::projectAdded(::ProjectExplorer::Project *project
void QmlDesignerProjectManager::aboutToRemoveProject(::ProjectExplorer::Project *) void QmlDesignerProjectManager::aboutToRemoveProject(::ProjectExplorer::Project *)
{ {
if (m_directoryInfo) { if (m_projectData) {
m_previewImageCacheData->collector.setTarget(m_directoryInfo->activeTarget); m_previewImageCacheData->collector.setTarget(m_projectData->activeTarget);
m_directoryInfo.reset(); m_projectData.reset();
} }
} }
@@ -532,14 +536,14 @@ void QmlDesignerProjectManager::projectRemoved(::ProjectExplorer::Project *) {}
void QmlDesignerProjectManager::generatePreview() void QmlDesignerProjectManager::generatePreview()
{ {
if (!m_directoryInfo || !m_directoryInfo->activeTarget) if (!m_projectData || !m_projectData->activeTarget)
return; return;
::QmlProjectManager::QmlBuildSystem *qmlBuildSystem = getQmlBuildSystem( ::QmlProjectManager::QmlBuildSystem *qmlBuildSystem = getQmlBuildSystem(
m_directoryInfo->activeTarget); m_projectData->activeTarget);
if (qmlBuildSystem) { if (qmlBuildSystem) {
m_previewImageCacheData->collector.setTarget(m_directoryInfo->activeTarget); m_previewImageCacheData->collector.setTarget(m_projectData->activeTarget);
m_previewImageCacheData->factory.generate(qmlBuildSystem->mainFilePath().toString().toUtf8()); m_previewImageCacheData->factory.generate(qmlBuildSystem->mainFilePath().toString().toUtf8());
} }
} }
@@ -567,12 +571,12 @@ QmlDesignerProjectManager::ImageCacheData *QmlDesignerProjectManager::imageCache
m_imageCacheData->nodeInstanceCollector.setTarget(project->activeTarget()); m_imageCacheData->nodeInstanceCollector.setTarget(project->activeTarget());
QObject::connect(project, QObject::connect(project,
&ProjectExplorer::Project::activeTargetChanged, &ProjectExplorer::Project::activeTargetChanged,
this, &dummy,
setTargetInImageCache); setTargetInImageCache);
} }
QObject::connect(ProjectExplorer::ProjectManager::instance(), QObject::connect(ProjectExplorer::ProjectManager::instance(),
&ProjectExplorer::ProjectManager::startupProjectChanged, &ProjectExplorer::ProjectManager::startupProjectChanged,
this, &dummy,
[=](ProjectExplorer::Project *project) { [=](ProjectExplorer::Project *project) {
setTargetInImageCache(activeTarget(project)); setTargetInImageCache(activeTarget(project));
}); });
@@ -587,12 +591,12 @@ void QmlDesignerProjectManager::fileListChanged()
void QmlDesignerProjectManager::activeTargetChanged(ProjectExplorer::Target *target) void QmlDesignerProjectManager::activeTargetChanged(ProjectExplorer::Target *target)
{ {
if (!m_directoryInfo || !m_directoryInfo->projectStorageData) if (!m_projectData || !m_projectData->projectStorageData)
return; return;
QObject::disconnect(m_directoryInfo->activeTarget, nullptr, nullptr, nullptr); QObject::disconnect(m_projectData->activeTarget, nullptr, nullptr, nullptr);
m_directoryInfo->activeTarget = target; m_projectData->activeTarget = target;
if (target) { if (target) {
QObject::connect(target, &::ProjectExplorer::Target::kitChanged, [&]() { kitChanged(); }); QObject::connect(target, &::ProjectExplorer::Target::kitChanged, [&]() { kitChanged(); });
@@ -625,17 +629,17 @@ void QmlDesignerProjectManager::projectChanged()
void QmlDesignerProjectManager::update() void QmlDesignerProjectManager::update()
{ {
if (!m_directoryInfo || !m_directoryInfo->projectStorageData) if (!m_projectData || !m_projectData->projectStorageData)
return; return;
if constexpr (isUsingQmlDesignerLite()) { if constexpr (isUsingQmlDesignerLite()) {
m_directoryInfo->projectStorageData->updater.update(directoriesForLiteDesigner(), m_projectData->projectStorageData->updater.update(directoriesForLiteDesigner(),
qmlTypesForLiteDesigner(), qmlTypesForLiteDesigner(),
propertyEditorResourcesPath(), propertyEditorResourcesPath(),
{qtCreatorItemLibraryPath()}); {qtCreatorItemLibraryPath()});
} else { } else {
m_directoryInfo->projectStorageData->updater.update(directories(m_directoryInfo->activeTarget), m_projectData->projectStorageData->updater.update(directories(m_projectData->activeTarget),
qmlTypes(m_directoryInfo->activeTarget), qmlTypes(m_projectData->activeTarget),
propertyEditorResourcesPath(), propertyEditorResourcesPath(),
{qtCreatorItemLibraryPath()}); {qtCreatorItemLibraryPath()});
} }

View File

@@ -28,11 +28,9 @@ namespace QmlDesigner {
class ExternalDependenciesInterface; class ExternalDependenciesInterface;
class QmlDesignerProjectManager : public QObject class QmlDesignerProjectManager
{ {
Q_OBJECT class QmlDesignerProjectManagerProjectData;
class QmlDesignerProjectManagerDirectoryInfo;
class PreviewImageCacheData; class PreviewImageCacheData;
class ImageCacheData; class ImageCacheData;
@@ -68,7 +66,8 @@ private:
std::once_flag imageCacheFlag; std::once_flag imageCacheFlag;
std::unique_ptr<ImageCacheData> m_imageCacheData; std::unique_ptr<ImageCacheData> m_imageCacheData;
std::unique_ptr<PreviewImageCacheData> m_previewImageCacheData; std::unique_ptr<PreviewImageCacheData> m_previewImageCacheData;
std::unique_ptr<QmlDesignerProjectManagerDirectoryInfo> m_directoryInfo; std::unique_ptr<QmlDesignerProjectManagerProjectData> m_projectData;
ExternalDependenciesInterface &m_externalDependencies; ExternalDependenciesInterface &m_externalDependencies;
QObject dummy;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner