diff options
| author | Volker Hilsheimer <[email protected]> | 2025-12-04 08:12:42 +0100 |
|---|---|---|
| committer | Volker Hilsheimer <[email protected]> | 2025-12-04 14:29:20 +0100 |
| commit | eecc41edcaa85a39c5981e9813a33fc8392f7cd3 (patch) | |
| tree | db202ca112d856ee4c43683dd7d8bb2497bb737b /src | |
| parent | e22cd01076e795ed853b0536605d3bb205587d78 (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.cpp | 6 | ||||
| -rw-r--r-- | src/corelib/itemmodels/qrangemodel_impl.h | 18 | ||||
| -rw-r--r-- | src/corelib/itemmodels/qrangemodeladapter.h | 19 |
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> |
