aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2018-07-11 16:19:31 +0200
committerEike Ziller <eike.ziller@qt.io>2018-07-12 10:16:26 +0000
commit0471fc0f4685c8e2f821322fd2c56a4beafbd245 (patch)
tree806fa0161b9ae2938df08bd13e7effd346d58203
parent293e711739b7e6eb00497cce97f7cca87ba497a5 (diff)
Fix assert when filtering examples / tutorials
The examples are put throw two proxy models. The first one implements the sorting and filtering, the second one transforms the list into a grid. The grid proxy model was based on QIdentityProxyModel, which is wrong because that explicitly states that it should be used when the structure of the model stays the same. Even QAbstractProxyModel works under the assumption that all items in the proxy model correspond to an item in the source model, which is not true for a N*M grid. Just implement the proxy model "by hand", making sure that all items that cannot be mapped to the source are handles correctly as "empty" items. Task-number: QTCREATORBUG-20641 Change-Id: Id08b77bb7157b893b9d0d73dc006db98d90032b7 Reviewed-by: hjk <hjk@qt.io>
-rw-r--r--src/plugins/qtsupport/gettingstartedwelcomepage.cpp71
1 files changed, 67 insertions, 4 deletions
diff --git a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
index e0698965e2..4407de9a06 100644
--- a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
+++ b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
@@ -293,12 +293,70 @@ public:
}
};
-class GridProxyModel : public QIdentityProxyModel
+class GridProxyModel : public QAbstractItemModel
{
public:
+ using OptModelIndex = Utils::optional<QModelIndex>;
+
GridProxyModel()
{}
+ void setSourceModel(QAbstractItemModel *newModel)
+ {
+ if (m_sourceModel == newModel)
+ return;
+ if (m_sourceModel)
+ disconnect(m_sourceModel, nullptr, this, nullptr);
+ m_sourceModel = newModel;
+ if (newModel) {
+ connect(newModel, &QAbstractItemModel::layoutAboutToBeChanged, this, [this] {
+ layoutAboutToBeChanged();
+ });
+ connect(newModel, &QAbstractItemModel::layoutChanged, this, [this] { layoutChanged(); });
+ connect(newModel, &QAbstractItemModel::modelAboutToBeReset, this, [this] {
+ beginResetModel();
+ });
+ connect(newModel, &QAbstractItemModel::modelReset, this, [this] { endResetModel(); });
+ connect(newModel, &QAbstractItemModel::rowsAboutToBeInserted, this, [this] {
+ beginResetModel();
+ });
+ connect(newModel, &QAbstractItemModel::rowsInserted, this, [this] { endResetModel(); });
+ connect(newModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, [this] {
+ beginResetModel();
+ });
+ connect(newModel, &QAbstractItemModel::rowsRemoved, this, [this] { endResetModel(); });
+ }
+ }
+
+ QAbstractItemModel *sourceModel() const
+ {
+ return m_sourceModel;
+ }
+
+ QVariant data(const QModelIndex &index, int role) const final
+ {
+ const OptModelIndex sourceIndex = mapToSource(index);
+ if (sourceIndex)
+ return sourceModel()->data(*sourceIndex, role);
+ return QVariant();
+ }
+
+ Qt::ItemFlags flags(const QModelIndex &index) const final
+ {
+ const OptModelIndex sourceIndex = mapToSource(index);
+ if (sourceIndex)
+ return sourceModel()->flags(*sourceIndex);
+ return Qt::ItemFlags();
+ }
+
+ bool hasChildren(const QModelIndex &parent) const final
+ {
+ const OptModelIndex sourceParent = mapToSource(parent);
+ if (sourceParent)
+ return sourceModel()->hasChildren(*sourceParent);
+ return false;
+ }
+
void setColumnCount(int columnCount)
{
if (columnCount == m_columnCount)
@@ -333,15 +391,19 @@ public:
return QModelIndex();
}
- QModelIndex mapToSource(const QModelIndex &proxyIndex) const final
+ // The items at the lower right of the grid might not correspond to source items, if
+ // source's row count is not N*columnCount
+ OptModelIndex mapToSource(const QModelIndex &proxyIndex) const
{
if (!proxyIndex.isValid())
return QModelIndex();
int sourceRow = proxyIndex.row() * m_columnCount + proxyIndex.column();
- return sourceModel()->index(sourceRow, 0);
+ if (sourceRow < sourceModel()->rowCount())
+ return sourceModel()->index(sourceRow, 0);
+ return OptModelIndex();
}
- QModelIndex mapFromSource(const QModelIndex &sourceIndex) const final
+ QModelIndex mapFromSource(const QModelIndex &sourceIndex) const
{
if (!sourceIndex.isValid())
return QModelIndex();
@@ -352,6 +414,7 @@ public:
}
private:
+ QAbstractItemModel *m_sourceModel = nullptr;
int m_columnCount = 1;
};