summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVolker Hilsheimer <[email protected]>2025-12-04 08:12:42 +0100
committerVolker Hilsheimer <[email protected]>2025-12-04 14:29:20 +0100
commiteecc41edcaa85a39c5981e9813a33fc8392f7cd3 (patch)
treedb202ca112d856ee4c43683dd7d8bb2497bb737b /src
parente22cd01076e795ed853b0536605d3bb205587d78 (diff)
QRMA: hook inserted objects up to auto-connect
Auto-connecting properties is enabled in models where all item data is backed by the same QObject subclass. When assigning a new row, an entire branch of rows in a tree, or assigning a fresh range as the children of a row, then the new items need to be connected. Some of these items might be nullptr, in which case we have so far stopped the connection loop early (by returning false from the helpers). Fix that to only stop early if a connection failed (i.e. if role names and properties in the objects are not aligned), but continue if we encounter a nullptr entry in the item data. Change-Id: I2c4b5e5beedc7b38c40ee459c2e0437568b9b087 Reviewed-by: Artem Dyomin <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/itemmodels/qrangemodel.cpp6
-rw-r--r--src/corelib/itemmodels/qrangemodel_impl.h18
-rw-r--r--src/corelib/itemmodels/qrangemodeladapter.h19
3 files changed, 35 insertions, 8 deletions
diff --git a/src/corelib/itemmodels/qrangemodel.cpp b/src/corelib/itemmodels/qrangemodel.cpp
index b4ffea4d87d..d72722f063d 100644
--- a/src/corelib/itemmodels/qrangemodel.cpp
+++ b/src/corelib/itemmodels/qrangemodel.cpp
@@ -154,7 +154,7 @@ static bool connectPropertiesHelper(const QModelIndex &index, QObject *item, QOb
const QHash<int, QMetaProperty> &properties)
{
if (!item)
- return false;
+ return true;
for (auto &&[role, property] : properties.asKeyValueRange()) {
if (property.hasNotifySignal()) {
if (!Handler(index, item, context, role, property))
@@ -171,7 +171,7 @@ bool QRangeModelImplBase::connectProperty(const QModelIndex &index, QObject *ite
int role, const QMetaProperty &property)
{
if (!item)
- return false;
+ return true; // nothing to do, continue
PropertyChangedHandler handler{index, role};
auto connection = property.enclosingMetaObject()->connect(item, property.notifySignal(),
context, std::move(handler));
@@ -199,7 +199,7 @@ bool QRangeModelImplBase::connectPropertyConst(const QModelIndex &index, QObject
int role, const QMetaProperty &property)
{
if (!item)
- return false;
+ return true; // nothing to do, continue
ConstPropertyChangedHandler handler{index, role};
if (!property.enclosingMetaObject()->connect(item, property.notifySignal(),
context, std::move(handler))) {
diff --git a/src/corelib/itemmodels/qrangemodel_impl.h b/src/corelib/itemmodels/qrangemodel_impl.h
index 7864992633d..3e35ad3981c 100644
--- a/src/corelib/itemmodels/qrangemodel_impl.h
+++ b/src/corelib/itemmodels/qrangemodel_impl.h
@@ -1715,7 +1715,7 @@ public:
bool autoConnectPropertiesInRow(const row_type &row, int rowIndex, const QModelIndex &parent) const
{
if (!QRangeModelDetails::isValid(row))
- return false;
+ return true; // nothing to do
return forEachColumn(row, rowIndex, parent, [this](const QModelIndex &index, QObject *item) {
if constexpr (isMutable())
return Self::connectProperties(index, item, m_data.context, m_data.properties);
@@ -2450,6 +2450,14 @@ public:
deleteRemovedRows(QRangeModelDetails::begin(range), QRangeModelDetails::end(range));
}
+ bool autoConnectProperties(const QModelIndex &parent) const
+ {
+ auto *children = this->childRange(parent);
+ if (!children)
+ return true;
+ return autoConnectPropertiesRange(QRangeModelDetails::refTo(children), parent);
+ }
+
protected:
QModelIndex indexImpl(int row, int column, const QModelIndex &parent) const
{
@@ -2682,9 +2690,11 @@ protected:
return false;
Q_ASSERT(QRangeModelDetails::isValid(row));
const auto &children = this->protocol().childRows(QRangeModelDetails::refTo(row));
- if (!autoConnectPropertiesRange(QRangeModelDetails::refTo(children),
- this->itemModel().index(rowIndex, 0, parent))) {
- return false;
+ if (QRangeModelDetails::isValid(children)) {
+ if (!autoConnectPropertiesRange(QRangeModelDetails::refTo(children),
+ this->itemModel().index(rowIndex, 0, parent))) {
+ return false;
+ }
}
++rowIndex;
}
diff --git a/src/corelib/itemmodels/qrangemodeladapter.h b/src/corelib/itemmodels/qrangemodeladapter.h
index df74a26663e..bd3342e6185 100644
--- a/src/corelib/itemmodels/qrangemodeladapter.h
+++ b/src/corelib/itemmodels/qrangemodeladapter.h
@@ -757,10 +757,18 @@ public:
}
}
} else {
- oldRow = other;
+ oldRow = std::forward<R>(other);
}
this->m_adapter->emitDataChanged(this->m_index,
this->m_index.siblingAtColumn(this->m_adapter->columnCount() - 1));
+ if constexpr (Impl::itemsAreQObjects) {
+ if (this->m_adapter->model()->autoConnectPolicy() == QRangeModel::AutoConnectPolicy::Full) {
+ impl->autoConnectPropertiesInRow(oldRow, this->m_index.row(), this->m_index.parent());
+ if constexpr (is_tree<Impl>)
+ impl->autoConnectProperties(this->m_index);
+ }
+
+ }
}
#ifndef QT_NO_DATASTREAM
@@ -1048,6 +1056,15 @@ public:
impl->endInsertRows();
}
}
+ if constexpr (Impl::itemsAreQObjects) {
+ if (model()->autoConnectPolicy() == QRangeModel::AutoConnectPolicy::Full) {
+ const auto begin = QRangeModelDetails::begin(refTo(oldRange));
+ const auto end = QRangeModelDetails::end(refTo(oldRange));
+ int rowIndex = 0;
+ for (auto it = begin; it != end; ++it, ++rowIndex)
+ impl->autoConnectPropertiesInRow(*it, rowIndex, root);
+ }
+ }
}
template <typename NewRange = range_type, if_assignable_range<NewRange> = true>