Skip to content

Commit ba91781

Browse files
committed
fix: many issues with RoleGroupModel
修正 RoleGroupModel 的若干问题,包括 hasChildren() 不正确,无法被 QTreeView支持,QAbstractItemModelTester运行失败等. Log:
1 parent 03beb42 commit ba91781

File tree

3 files changed

+388
-36
lines changed

3 files changed

+388
-36
lines changed

panels/dock/taskmanager/rolegroupmodel.cpp

Lines changed: 115 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,15 @@ void RoleGroupModel::setSourceModel(QAbstractItemModel *model)
5252
if (nullptr == list) {
5353
beginInsertRows(QModelIndex(), m_rowMap.size(), m_rowMap.size());
5454
list = new QList<int>();
55+
list->append(i);
5556
m_map.insert(data, list);
5657
m_rowMap.append(list);
5758
endInsertRows();
59+
} else {
60+
beginInsertRows(index(m_rowMap.indexOf(list), 0), list->size(), list->size());
61+
list->append(i);
62+
endInsertRows();
5863
}
59-
beginInsertRows(index(m_rowMap.indexOf(list), 0), list->size(), list->size());
60-
list->append(i);
61-
endInsertRows();
6264
}
6365
});
6466

@@ -97,8 +99,11 @@ void RoleGroupModel::setSourceModel(QAbstractItemModel *model)
9799
if (list == nullptr)
98100
continue;
99101

100-
auto index = createIndex(list->indexOf(i), 0, m_rowMap.indexOf(list));
101-
Q_EMIT dataChanged(index, index, roles);
102+
int childRow = list->indexOf(i);
103+
if (childRow >= 0) {
104+
auto index = createIndex(childRow, 0, m_rowMap.indexOf(list));
105+
Q_EMIT dataChanged(index, index, roles);
106+
}
102107
}
103108
});
104109

@@ -109,12 +114,14 @@ void RoleGroupModel::setSourceModel(QAbstractItemModel *model)
109114

110115
int RoleGroupModel::rowCount(const QModelIndex &parent) const
111116
{
112-
if (!sourceModel()) {
113-
return 0;
114-
}
115117
if (parent.isValid()) {
116-
auto list = m_rowMap.value(parent.row(), nullptr);
117-
return nullptr == list ? 0 : list->size();
118+
int parentRow = parent.row();
119+
if (parentRow < 0 || parentRow >= m_rowMap.size()) {
120+
return 0;
121+
}
122+
123+
auto list = m_rowMap.value(parentRow, nullptr);
124+
return (list != nullptr) ? list->size() : 0;
118125
}
119126

120127
return m_rowMap.size();
@@ -128,6 +135,31 @@ int RoleGroupModel::columnCount(const QModelIndex &parent) const
128135
return 0;
129136
}
130137

138+
bool RoleGroupModel::hasChildren(const QModelIndex &parent) const
139+
{
140+
if (!sourceModel()) {
141+
return false;
142+
}
143+
144+
if (!parent.isValid()) {
145+
// 根节点:如果有分组则有子节点
146+
return m_rowMap.size() > 0;
147+
}
148+
149+
auto parentPos = static_cast<int>(parent.internalId());
150+
if (parentPos == -1) {
151+
// 这是分组节点:检查是否有子项
152+
if (parent.row() < 0 || parent.row() >= m_rowMap.size()) {
153+
return false;
154+
}
155+
auto list = m_rowMap.value(parent.row(), nullptr);
156+
return list && list->size() > 0;
157+
}
158+
159+
// 这是子项:没有子节点
160+
return false;
161+
}
162+
131163
QHash<int, QByteArray> RoleGroupModel::roleNames() const
132164
{
133165
if (sourceModel()) {
@@ -138,61 +170,104 @@ QHash<int, QByteArray> RoleGroupModel::roleNames() const
138170

139171
QVariant RoleGroupModel::data(const QModelIndex &index, int role) const
140172
{
173+
if (!index.isValid()) {
174+
return QVariant();
175+
}
176+
141177
auto parentPos = static_cast<int>(index.internalId());
142-
auto list = m_rowMap.value(index.row(), nullptr);
178+
143179
if (parentPos == -1) {
144-
if (nullptr == list || list->size() == 0) {
180+
// 这是分组节点(顶级项目)
181+
auto list = m_rowMap.value(index.row(), nullptr);
182+
if (nullptr == list || list->isEmpty()) {
145183
return QVariant();
146184
}
147-
return sourceModel()->index(list->first(), 0).data(role);
148-
}
149185

150-
list = m_rowMap.value(parentPos);
151-
if (list == nullptr) {
152-
return QVariant();
153-
}
186+
// 对于分组节点,显示分组信息和数量
187+
if (role == Qt::DisplayRole) {
188+
QString groupValue = sourceModel()->index(list->first(), 0).data(m_roleForDeduplication).toString();
189+
return QString("%1 (%2)").arg(groupValue).arg(list->size());
190+
} else {
191+
// 对于其他角色,返回分组中第一个项目的数据
192+
return sourceModel()->index(list->first(), 0).data(role);
193+
}
194+
} else {
195+
// 这是子项目
196+
auto list = m_rowMap.value(parentPos);
197+
if (list == nullptr || index.row() < 0 || index.row() >= list->size()) {
198+
return QVariant();
199+
}
154200

155-
return sourceModel()->index(list->value(index.row()), 0).data(role);
201+
// 直接返回对应源项目的数据
202+
return sourceModel()->index(list->value(index.row()), 0).data(role);
203+
}
156204
}
157205

158206
QModelIndex RoleGroupModel::index(int row, int column, const QModelIndex &parent) const
159207
{
160-
auto list = m_map.value(parent.data(m_roleForDeduplication).toString(), nullptr);
161-
if (parent.isValid() && nullptr != list) {
162-
return createIndex(row, column, m_rowMap.indexOf(list));
163-
}
208+
if (parent.isValid()) {
209+
int parentRow = parent.row();
210+
if (parentRow < 0 || parentRow >= m_rowMap.size()) {
211+
return QModelIndex();
212+
}
213+
214+
auto list = m_rowMap.value(parentRow);
215+
if (nullptr == list || row < 0 || row >= list->size()) {
216+
return QModelIndex();
217+
}
218+
219+
return createIndex(row, column, parentRow);
220+
} else {
221+
if (row < 0 || row >= m_rowMap.size()) {
222+
return QModelIndex();
223+
}
164224

165-
return createIndex(row, column, -1);
225+
return createIndex(row, column, -1);
226+
}
166227
}
167228

168229
QModelIndex RoleGroupModel::parent(const QModelIndex &child) const
169230
{
231+
if (!child.isValid())
232+
return QModelIndex();
233+
170234
auto pos = static_cast<int>(child.internalId());
171235
if (pos == -1)
172236
return QModelIndex();
173237

174-
return createIndex(pos, 0);
238+
if (pos < 0 || pos >= m_rowMap.size()) {
239+
return QModelIndex();
240+
}
241+
242+
return createIndex(pos, 0, -1);
175243
}
176244

177245
QModelIndex RoleGroupModel::mapToSource(const QModelIndex &proxyIndex) const
178246
{
247+
if (!proxyIndex.isValid()) {
248+
return QModelIndex();
249+
}
250+
179251
auto parentIndex = proxyIndex.parent();
180252
QList<int> *list = nullptr;
181253

182254
if (parentIndex.isValid()) {
183-
list = m_rowMap.value(parentIndex.row());
255+
int parentRow = parentIndex.row();
256+
if (parentRow < 0 || parentRow >= m_rowMap.size()) {
257+
return QModelIndex();
258+
}
259+
list = m_rowMap.value(parentRow);
260+
if (!list || proxyIndex.row() >= list->size()) {
261+
return QModelIndex();
262+
}
263+
return sourceModel()->index(list->value(proxyIndex.row()), 0);
184264
} else {
185265
list = m_map.value(proxyIndex.data(m_roleForDeduplication).toString());
266+
if (!list || list->isEmpty()) {
267+
return QModelIndex();
268+
}
269+
return sourceModel()->index(list->value(0), 0);
186270
}
187-
188-
if (nullptr == list)
189-
return QModelIndex();
190-
191-
if (parentIndex.isValid()) {
192-
return sourceModel()->index(list->value(proxyIndex.row()), 0);
193-
}
194-
195-
return sourceModel()->index(list->value(0), 0);
196271
}
197272

198273
QModelIndex RoleGroupModel::mapFromSource(const QModelIndex &sourceIndex) const
@@ -212,7 +287,11 @@ QModelIndex RoleGroupModel::mapFromSource(const QModelIndex &sourceIndex) const
212287
}
213288

214289
auto pos = list->indexOf(sourceIndex.row());
215-
return createIndex(pos, 0, m_rowMap.indexOf(list));
290+
if (pos >= 0) {
291+
return createIndex(pos, 0, m_rowMap.indexOf(list));
292+
}
293+
294+
return QModelIndex();
216295
}
217296

218297
void RoleGroupModel::rebuildTreeSource()

panels/dock/taskmanager/rolegroupmodel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class RoleGroupModel : public QAbstractProxyModel
2222
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
2323
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
2424

25+
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
2526
bool hasIndex(int row, int column, const QModelIndex &parent = QModelIndex()) const;
2627
Q_INVOKABLE virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
2728
Q_INVOKABLE virtual QModelIndex parent(const QModelIndex &child) const override;

0 commit comments

Comments
 (0)