fix: many issues with RoleCombineModel#1189
Conversation
修正 RoleCombineModel 的若干问题,包括索引映射错误,minor 模型变化处理不完整,QAbstractItemModelTester运行失败等. Log:
Reviewer's GuideThis PR overhauls RoleCombineModel’s change-listeners and mapping logic to correctly handle rows/columns inserted or removed from both major and minor models, fixes role-to-key assignments, adds safety checks for data access and flat-list behavior, and introduces comprehensive unit tests (including QAbstractItemModelTester) to validate these fixes. Sequence diagram for row removal in minor model and mapping updatesequenceDiagram
participant MinorModel as QAbstractItemModel (minor)
participant RoleCombineModel
participant MajorModel as QAbstractItemModel (major)
MinorModel->>RoleCombineModel: rowsRemoved(parent, first, last)
loop For each mapping in m_indexMap
alt Mapping points to removed minor row
RoleCombineModel->>RoleCombineModel: Try to rebind mapping using func
alt New mapping valid
RoleCombineModel->>RoleCombineModel: Update mapping
else New mapping invalid
RoleCombineModel->>RoleCombineModel: Remove mapping
end
else Mapping points to row after last
RoleCombineModel->>RoleCombineModel: Adjust mapping row index
end
end
loop For each affected major index
RoleCombineModel-->>MajorModel: dataChanged(majorIndex, majorIndex, roles)
end
Class diagram for updated RoleCombineModel structureclassDiagram
class QAbstractProxyModel
class RoleCombineModel {
+QHash<int, QByteArray> roleNames() const
+bool hasIndex(int row, int column, const QModelIndex &parent = QModelIndex()) const
+bool hasChildren(const QModelIndex &parent = QModelIndex()) const
+QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const
+QModelIndex parent(const QModelIndex &child) const
+int rowCount(const QModelIndex &parent) const
+int columnCount(const QModelIndex &parent) const
+QVariant data(const QModelIndex &index, int role) const
-QMap<QPair<int, int>, QPair<int, int>> m_indexMap
-QHash<int, int> m_minorRolesMap
-QHash<int, QByteArray> m_roleNames
-QAbstractItemModel* m_minor
}
QAbstractProxyModel <|-- RoleCombineModel
class QAbstractItemModel
RoleCombineModel o-- QAbstractItemModel : sourceModel
RoleCombineModel o-- QAbstractItemModel : m_minor
Class diagram for m_indexMap and role mapping logic in RoleCombineModelclassDiagram
class RoleCombineModel {
-QMap<QPair<int, int>, QPair<int, int>> m_indexMap
-QHash<int, int> m_minorRolesMap
}
class QPair_int_int {
+int first
+int second
}
class QMap_QPair_int_int__QPair_int_int {
}
class QHash_int_int {
}
RoleCombineModel o-- QMap_QPair_int_int__QPair_int_int : m_indexMap
QMap_QPair_int_int__QPair_int_int o-- QPair_int_int
RoleCombineModel o-- QHash_int_int : m_minorRolesMap
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
deepin pr auto review代码审查意见:
总体来说,代码的改进主要集中在减少重复代码、增强错误处理、提高代码可读性和性能优化等方面。 |
There was a problem hiding this comment.
Hey @BLumia - I've reviewed your changes and they look great!
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `panels/dock/taskmanager/rolecombinemodel.cpp:244` </location>
<code_context>
+ }
+ });
+
+ connect(m_minor, &QAbstractItemModel::columnsRemoved, this, [this, majorRoles, func](const QModelIndex &parent, int first, int last) {
+ // 当minor模型删除列时,需要更新映射
+ for (auto it = m_indexMap.begin(); it != m_indexMap.end(); ++it) {
+ int minorRow = it.value().first;
+ int minorCol = it.value().second;
+
+ if (minorCol > last) {
+ // 调整后续列的索引
+ int newMinorCol = minorCol - (last - first + 1);
+ it.value().second = newMinorCol;
+ }
+ }
+ });
</code_context>
<issue_to_address>
No handling for mappings that become invalid after minor column removal.
Mappings referencing removed columns are not updated, which may leave invalid entries. Please ensure such mappings are removed or invalidated.
</issue_to_address>
### Comment 2
<location> `panels/dock/taskmanager/rolecombinemodel.cpp:285` </location>
<code_context>
+ // 修复角色映射逻辑:应该映射到新创建的minor角色,而不是major角色
+ auto majorRoleNames = sourceModel()->roleNames();
+
+ std::for_each(minorRolenames.constBegin(), minorRolenames.constEnd(), [&minorRolenames, &majorRoleNames, this](auto &roleName) {
+ int minorRoleKey = minorRolenames.key(roleName);
+
+ // 在组合角色中找到对应的key,但排除major模型已有的key
+ int combinedRoleKey = -1;
+ for (auto it = m_roleNames.constBegin(); it != m_roleNames.constEnd(); ++it) {
+ if (it.value() == roleName && !majorRoleNames.contains(it.key())) {
+ combinedRoleKey = it.key();
+ break;
+ }
+ }
+
+ if (combinedRoleKey != -1) {
+ m_minorRolesMap.insert(combinedRoleKey, minorRoleKey);
+ }
</code_context>
<issue_to_address>
Role mapping logic may not handle duplicate role names across major and minor models.
If major and minor models share a role name but have different keys, the logic skips mapping for keys already in the major model, potentially omitting roles from the combined model. Please confirm if this is intentional.
</issue_to_address>
### Comment 3
<location> `tests/panels/dock/taskmanager/rolecombinemodeltests.cpp:183` </location>
<code_context>
+ EXPECT_EQ(model.index(2, 0).data(bDataRole).toString(), "dataB3");
+}
+
+// 新增测试用例:检测parent参数处理问题
+TEST(RoleCombineModel, InvalidParentHandlingBug)
+{
+ TestModelA modelA;
+ TestModelB modelB;
+
+ RoleCombineModel model(&modelA, &modelB, TestModelA::idRole, [](QVariant data, QAbstractItemModel *model) -> QModelIndex {
+ return QModelIndex();
+ });
+
+ modelA.addData(new DataA(0, "dataA0", &modelA));
</code_context>
<issue_to_address>
Test for invalid parent handling is present but could be more explicit.
Please add assertions to confirm that rowCount and data access remain correct after attempting to add data with an invalid parent.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| @@ -24,42 +24,133 @@ RoleCombineModel::RoleCombineModel(QAbstractItemModel* major, QAbstractItemModel | |||
| } | |||
There was a problem hiding this comment.
issue (bug_risk): No handling for mappings that become invalid after minor column removal.
Mappings referencing removed columns are not updated, which may leave invalid entries. Please ensure such mappings are removed or invalidated.
| std::for_each(minorRolenames.constBegin(), minorRolenames.constEnd(), [&minorRolenames, &majorRoleNames, this](auto &roleName) { | ||
| int minorRoleKey = minorRolenames.key(roleName); | ||
|
|
||
| // 在组合角色中找到对应的key,但排除major模型已有的key | ||
| int combinedRoleKey = -1; | ||
| for (auto it = m_roleNames.constBegin(); it != m_roleNames.constEnd(); ++it) { | ||
| if (it.value() == roleName && !majorRoleNames.contains(it.key())) { | ||
| combinedRoleKey = it.key(); | ||
| break; | ||
| } |
There was a problem hiding this comment.
question: Role mapping logic may not handle duplicate role names across major and minor models.
If major and minor models share a role name but have different keys, the logic skips mapping for keys already in the major model, potentially omitting roles from the combined model. Please confirm if this is intentional.
| }); | ||
|
|
||
| auto tester = new QAbstractItemModelTester(&model, QAbstractItemModelTester::FailureReportingMode::Fatal); | ||
| } |
There was a problem hiding this comment.
suggestion (testing): Test for invalid parent handling is present but could be more explicit.
Please add assertions to confirm that rowCount and data access remain correct after attempting to add data with an invalid parent.
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: BLumia, tsic404 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
修正 RoleCombineModel 的若干问题,包括索引映射错误,minor
模型变化处理不完整,QAbstractItemModelTester运行失败等.
Summary by Sourcery
Fix various indexing and mapping issues in RoleCombineModel by properly handling rows/columns insertion and removal for both major and minor models, strengthen data access safety and parent handling, and correct combined role mapping logic.
New Features:
Bug Fixes:
Enhancements:
Tests: