QmlDesigner: Fix crash on asset library refresh

Asset library refresh will crash if done while there is a modal dialog
open, so postpone it a bit in that case. The timer used for this
will also reduce unnecessary refreshes, improving overall performance.

Change-Id: Ib2ff29f5f79428c6543a20f611c708ba80e88ded
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Miikka Heikkinen
2021-09-03 16:35:59 +03:00
parent c7061af61f
commit 8004909f79
2 changed files with 24 additions and 11 deletions

View File

@@ -161,6 +161,8 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
{
m_compressionTimer.setInterval(200);
m_compressionTimer.setSingleShot(true);
m_assetCompressionTimer.setInterval(200);
m_assetCompressionTimer.setSingleShot(true);
ItemLibraryModel::registerQmlTypes();
setWindowTitle(tr("Library", "Title of library view"));
@@ -234,17 +236,7 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
// reconstruct the model to update the icons
connect(m_fileSystemWatcher, &Utils::FileSystemWatcher::directoryChanged, [this](const QString & changedDirPath) {
Q_UNUSED(changedDirPath)
// TODO: find a clever way to only refresh the changed directory part of the model
m_assetsModel->refresh();
if (!QApplication::activeModalWidget()) {
// reload assets qml so that an overridden file's image shows the new image
QTimer::singleShot(100, this, [this] {
const QString assetsQmlPath = qmlSourcesPath() + "/Assets.qml";
m_assetsWidget->engine()->clearComponentCache();
m_assetsWidget->setSource(QUrl::fromLocalFile(assetsQmlPath));
});
}
m_assetCompressionTimer.start();
});
m_stackedWidget = new QStackedWidget(this);
@@ -270,6 +262,26 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
connect(m_qmlSourceUpdateShortcut, &QShortcut::activated, this, &ItemLibraryWidget::reloadQmlSource);
connect(&m_compressionTimer, &QTimer::timeout, this, &ItemLibraryWidget::updateModel);
connect(&m_assetCompressionTimer, &QTimer::timeout, this, [this]() {
// TODO: find a clever way to only refresh the changed directory part of the model
// Don't bother with asset updates after model has detached, project is probably closing
if (!m_model.isNull()) {
if (QApplication::activeModalWidget()) {
// Retry later, as updating file system watchers can crash when there is an active
// modal widget
m_assetCompressionTimer.start();
} else {
m_assetsModel->refresh();
// reload assets qml so that an overridden file's image shows the new image
QTimer::singleShot(100, this, [this] {
const QString assetsQmlPath = qmlSourcesPath() + "/Assets.qml";
m_assetsWidget->engine()->clearComponentCache();
m_assetsWidget->setSource(QUrl::fromLocalFile(assetsQmlPath));
});
}
}
});
m_itemViewQuickWidget->engine()->addImageProvider("itemlibrary_preview",
new ItemLibraryIconImageProvider{m_imageCache});

View File

@@ -119,6 +119,7 @@ private:
void handlePriorityImportsChanged();
QTimer m_compressionTimer;
QTimer m_assetCompressionTimer;
QSize m_itemIconSize;
SynchronousImageCache &m_fontImageCache;