summaryrefslogtreecommitdiffstats
path: root/src/libs/installer
diff options
context:
space:
mode:
authorArttu Tarkiainen <arttu.tarkiainen@qt.io>2021-09-23 16:40:50 +0300
committerArttu Tarkiainen <arttu.tarkiainen@qt.io>2021-10-28 07:11:49 +0000
commitf64011e117e759754f7b4f2885f9bf335a6596ff (patch)
treef811214fcdbe6f5b666c92c7195a1c06fbffead8 /src/libs/installer
parent270c5dfd9b6c86bec8eaf34d0a2c3d3b945ed5e5 (diff)
ComponentModel: Fix segfaults on reset when used with a proxy model
Resetting the model is split into two parts - 'ComponentModel ::setRootComponents' updates the root item list and emits 'QAbstractItemModel::modelReset' which was connected to a private slot of the class that updates the component check state and then emits 'QAbstractItemModel::dataChanged' for each component index. The issue was that these could be emitted before the proxy model's private slot that catches the source model reset and performs invalidation had been invoked, causing the proxy model's slot reacting to source model data changes to refer previously retrieved source model indexes, which now had invalid information. Fix by moving the post-reset operations to non-slot function 'ComponentModel::postModelReset()' which is called after the 'QAbstractItemModel::modelReset' is emitted, so that any directly connected slots get invoked first. Task-number: QTIFW-1404 Change-Id: If4d55110c93658689787484d0e8a8eb6b6da685d Reviewed-by: Katja Marttila <katja.marttila@qt.io>
Diffstat (limited to 'src/libs/installer')
-rw-r--r--src/libs/installer/componentmodel.cpp22
-rw-r--r--src/libs/installer/componentmodel.h4
2 files changed, 13 insertions, 13 deletions
diff --git a/src/libs/installer/componentmodel.cpp b/src/libs/installer/componentmodel.cpp
index 642828ad7..aeaa0b2fc 100644
--- a/src/libs/installer/componentmodel.cpp
+++ b/src/libs/installer/componentmodel.cpp
@@ -101,7 +101,6 @@ ComponentModel::ComponentModel(int columns, PackageManagerCore *core)
, m_modelState(DefaultChecked)
{
m_headerData.insert(0, columns, QVariant());
- connect(this, &QAbstractItemModel::modelReset, this, &ComponentModel::slotModelReset);
}
/*!
@@ -417,6 +416,7 @@ void ComponentModel::setRootComponents(QList<QInstaller::Component*> rootCompone
m_rootComponentList.append(component);
}
endResetModel();
+ postModelReset();
}
/*!
@@ -459,7 +459,16 @@ void ComponentModel::setCheckedState(QInstaller::ComponentModel::ModelStateFlag
// -- private slots
-void ComponentModel::slotModelReset()
+void ComponentModel::onVirtualStateChanged()
+{
+ // If the virtual state of a component changes, force a reset of the component model.
+ setRootComponents(m_core->components(PackageManagerCore::ComponentType::Root));
+}
+
+
+// -- private
+
+void ComponentModel::postModelReset()
{
ComponentList components = m_rootComponentList;
if (!m_core->isUpdater()) {
@@ -485,15 +494,6 @@ void ComponentModel::slotModelReset()
updateAndEmitModelState(); // update the internal state
}
-void ComponentModel::onVirtualStateChanged()
-{
- // If the virtual state of a component changes, force a reset of the component model.
- setRootComponents(m_core->components(PackageManagerCore::ComponentType::Root));
-}
-
-
-// -- private
-
void ComponentModel::updateAndEmitModelState()
{
m_modelState = ComponentModel::DefaultChecked;
diff --git a/src/libs/installer/componentmodel.h b/src/libs/installer/componentmodel.h
index 8a9fbf884..e5cd2c57d 100644
--- a/src/libs/installer/componentmodel.h
+++ b/src/libs/installer/componentmodel.h
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -94,10 +94,10 @@ Q_SIGNALS:
void checkStateChanged(QInstaller::ComponentModel::ModelState state);
private Q_SLOTS:
- void slotModelReset();
void onVirtualStateChanged();
private:
+ void postModelReset();
void updateAndEmitModelState();
void collectComponents(Component *const component, const QModelIndex &parent) const;
QSet<QModelIndex> updateCheckedState(const ComponentSet &components, Qt::CheckState state);