aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@qt.io>2018-10-17 14:48:59 +0200
committerRichard Moe Gustavsen <richard.gustavsen@qt.io>2019-02-21 10:55:13 +0000
commit2c16e0c30c6c5ed12af52ecac2cda128487cb379 (patch)
tree2aeb8f1bf4a140c782674329f62e1058b706684a
parent99e2356a734fa3eb55ffc2e983658d17ab4c3e9f (diff)
QQmlDelegateModel: guard new row/column properties with revision 12
Tag the new 'row' and 'column' properties with revision 12. This will make sure that they cannot be accessed by the delegate unless the QQmlAdaptorModel has the correct minorVersion set. Fixes: QTBUG-70031 Change-Id: I49e67c37ab5b7925c7bca313bbb99f04d1387cc4 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h10
-rw-r--r--src/qml/types/qqmltableinstancemodel.cpp5
-rw-r--r--src/qml/types/qqmltableinstancemodel_p.h2
-rw-r--r--src/qml/util/qqmladaptormodel.cpp5
-rw-r--r--src/qml/util/qqmladaptormodel_p.h2
-rw-r--r--src/quick/items/qquicktableview.cpp12
-rw-r--r--src/quick/items/qquicktableview_p_p.h1
-rw-r--r--tests/auto/quick/qquicktableview/data/checkmodelpropertyrevision.qml87
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp12
9 files changed, 132 insertions, 4 deletions
diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h
index 0cd772ede0..0028849828 100644
--- a/src/qml/types/qqmldelegatemodel_p_p.h
+++ b/src/qml/types/qqmldelegatemodel_p_p.h
@@ -96,8 +96,8 @@ class QQmlDelegateModelItem : public QObject
{
Q_OBJECT
Q_PROPERTY(int index READ modelIndex NOTIFY modelIndexChanged)
- Q_PROPERTY(int row MEMBER row NOTIFY rowChanged)
- Q_PROPERTY(int column MEMBER column NOTIFY columnChanged)
+ Q_PROPERTY(int row READ modelRow NOTIFY rowChanged REVISION 12)
+ Q_PROPERTY(int column READ modelColumn NOTIFY columnChanged REVISION 12)
Q_PROPERTY(QObject *model READ modelObject CONSTANT)
public:
QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *metaType,
@@ -126,6 +126,8 @@ public:
int groupIndex(Compositor::Group group);
+ int modelRow() const { return row; }
+ int modelColumn() const { return column; }
int modelIndex() const { return index; }
virtual void setModelIndex(int idx, int newRow, int newColumn);
@@ -156,8 +158,8 @@ public:
Q_SIGNALS:
void modelIndexChanged();
- void rowChanged();
- void columnChanged();
+ Q_REVISION(12) void rowChanged();
+ Q_REVISION(12) void columnChanged();
protected:
void objectDestroyed(QObject *);
diff --git a/src/qml/types/qqmltableinstancemodel.cpp b/src/qml/types/qqmltableinstancemodel.cpp
index 1054158dc8..2170e2daec 100644
--- a/src/qml/types/qqmltableinstancemodel.cpp
+++ b/src/qml/types/qqmltableinstancemodel.cpp
@@ -82,6 +82,11 @@ QQmlTableInstanceModel::QQmlTableInstanceModel(QQmlContext *qmlContext, QObject
{
}
+void QQmlTableInstanceModel::useImportVersion(int minorVersion)
+{
+ m_adaptorModel.useImportVersion(minorVersion);
+}
+
QQmlTableInstanceModel::~QQmlTableInstanceModel()
{
for (const auto modelItem : m_modelItems) {
diff --git a/src/qml/types/qqmltableinstancemodel_p.h b/src/qml/types/qqmltableinstancemodel_p.h
index 03761af326..3dd5c4e4ce 100644
--- a/src/qml/types/qqmltableinstancemodel_p.h
+++ b/src/qml/types/qqmltableinstancemodel_p.h
@@ -93,6 +93,8 @@ public:
QQmlTableInstanceModel(QQmlContext *qmlContext, QObject *parent = nullptr);
~QQmlTableInstanceModel() override;
+ void useImportVersion(int minorVersion);
+
int count() const override { return m_adaptorModel.count(); }
int rows() const { return m_adaptorModel.rowCount(); }
int columns() const { return m_adaptorModel.columnCount(); }
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp
index 8743e9ea7c..d9cb6506b8 100644
--- a/src/qml/util/qqmladaptormodel.cpp
+++ b/src/qml/util/qqmladaptormodel.cpp
@@ -1008,6 +1008,11 @@ int QQmlAdaptorModel::indexAt(int row, int column) const
return column * rowCount() + row;
}
+void QQmlAdaptorModel::useImportVersion(int minorVersion)
+{
+ modelItemRevision = minorVersion;
+}
+
void QQmlAdaptorModel::objectDestroyed(QObject *)
{
setModel(QVariant(), nullptr, nullptr);
diff --git a/src/qml/util/qqmladaptormodel_p.h b/src/qml/util/qqmladaptormodel_p.h
index 4ce3b0703a..8c18466ab5 100644
--- a/src/qml/util/qqmladaptormodel_p.h
+++ b/src/qml/util/qqmladaptormodel_p.h
@@ -130,6 +130,8 @@ public:
int columnAt(int index) const;
int indexAt(int row, int column) const;
+ void useImportVersion(int minorVersion);
+
inline bool adaptsAim() const { return qobject_cast<QAbstractItemModel *>(object()); }
inline QAbstractItemModel *aim() { return static_cast<QAbstractItemModel *>(object()); }
inline const QAbstractItemModel *aim() const { return static_cast<const QAbstractItemModel *>(object()); }
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index eaf0e4cf89..9949f083b1 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -1515,6 +1515,17 @@ void QQuickTableViewPrivate::fixup(QQuickFlickablePrivate::AxisData &data, qreal
QQuickFlickablePrivate::fixup(data, minExtent, maxExtent);
}
+int QQuickTableViewPrivate::resolveImportVersion()
+{
+ const auto data = QQmlData::get(q_func());
+ if (!data || !data->propertyCache)
+ return 0;
+
+ const auto cppMetaObject = data->propertyCache->firstCppMetaObject();
+ const auto qmlTypeView = QQmlMetaType::qmlType(cppMetaObject);
+ return qmlTypeView.minorVersion();
+}
+
void QQuickTableViewPrivate::createWrapperModel()
{
Q_Q(QQuickTableView);
@@ -1524,6 +1535,7 @@ void QQuickTableViewPrivate::createWrapperModel()
// common interface to any kind of model (js arrays, QAIM, number etc), and
// help us create delegate instances.
tableModel = new QQmlTableInstanceModel(qmlContext(q));
+ tableModel->useImportVersion(resolveImportVersion());
model = tableModel;
}
diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h
index 2ed04f8d29..8a02d23694 100644
--- a/src/quick/items/qquicktableview_p_p.h
+++ b/src/quick/items/qquicktableview_p_p.h
@@ -334,6 +334,7 @@ public:
void scheduleRebuildTable(QQuickTableViewPrivate::RebuildOptions options);
void invalidateColumnRowPositions();
+ int resolveImportVersion();
void createWrapperModel();
void initItemCallback(int modelIndex, QObject *item);
diff --git a/tests/auto/quick/qquicktableview/data/checkmodelpropertyrevision.qml b/tests/auto/quick/qquicktableview/data/checkmodelpropertyrevision.qml
new file mode 100644
index 0000000000..0550f20bac
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/data/checkmodelpropertyrevision.qml
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Window 2.12
+
+Item {
+ id: root
+ width: 640
+ height: 480
+
+ property alias tableView: tableView
+
+ property int row: 42
+ property int column: 42
+
+ property int resolvedDelegateRow: 0
+ property int resolvedDelegateColumn: 0
+
+ TableView {
+ id: tableView
+ // Dummy tableView, to let the auto test follow the
+ // same pattern for loading qml files as other tests.
+ }
+
+ Item {
+ width: 100
+ height: parent.height;
+ Repeater {
+ model: 1
+ delegate: Component {
+ Rectangle {
+ color: "blue"
+ height: 100
+ width: 100
+ Component.onCompleted: {
+ // row and column should be resolved to be the ones
+ // found in the root item, and not in the delegate
+ // items context. The context properties are revisioned,
+ // and require that the QQmlDelegateModel has an import
+ // version set (which is not the case when using a
+ // Repeater, only when using a TableView).
+ resolvedDelegateRow = row
+ resolvedDelegateColumn = column
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
index d475ef9c4d..22f6e5d654 100644
--- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -156,6 +156,7 @@ private slots:
void checkRebuildViewportOnly();
void useDelegateChooserWithoutDefault();
void checkTableviewInsideAsyncLoader();
+ void checkThatRevisionedPropertiesCannotBeUsedInOldImports();
};
tst_QQuickTableView::tst_QQuickTableView()
@@ -2003,6 +2004,17 @@ void tst_QQuickTableView::checkTableviewInsideAsyncLoader()
QVERIFY(height > 0);
};
+void tst_QQuickTableView::checkThatRevisionedPropertiesCannotBeUsedInOldImports()
+{
+ // Check that if you use a QQmlAdaptorModel together with a Repeater, the
+ // revisioned context properties 'row' and 'column' are not accessible.
+ LOAD_TABLEVIEW("checkmodelpropertyrevision.qml");
+ const int resolvedRow = view->rootObject()->property("resolvedDelegateRow").toInt();
+ const int resolvedColumn = view->rootObject()->property("resolvedDelegateColumn").toInt();
+ QCOMPARE(resolvedRow, 42);
+ QCOMPARE(resolvedColumn, 42);
+}
+
QTEST_MAIN(tst_QQuickTableView)
#include "tst_qquicktableview.moc"