diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2019-10-14 18:46:38 +0200 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2019-10-14 19:02:37 +0200 |
commit | c2f8b9535d34da6948ccf45b7d5fd90de2f1bc9e (patch) | |
tree | c6f7e058a985d7c18b51cadc76283caf555071c9 /src/qmlmodels | |
parent | 9e633bbda7608ac0231809e2a6a97ae8f2d849d6 (diff) | |
parent | 803f18f02e5609a1ca00a5b78ea6d3613d44e1a0 (diff) |
Merge remote-tracking branch 'origin/dev' into wip/cmake
Removed dependencies.yaml because we don't use it yet in wip/cmake.
Fixed conflict in qmlcachegen.cpp.
Change-Id: Ie1060c737bee1daa85779903598e5b6d5020d922
Diffstat (limited to 'src/qmlmodels')
38 files changed, 1643 insertions, 63 deletions
diff --git a/src/qmlmodels/doc/qtqmlmodels.qdocconf b/src/qmlmodels/doc/qtqmlmodels.qdocconf new file mode 100644 index 0000000000..a4153f4a53 --- /dev/null +++ b/src/qmlmodels/doc/qtqmlmodels.qdocconf @@ -0,0 +1,37 @@ +include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) +include($QT_INSTALL_DOCS/config/exampleurl-qtdeclarative.qdocconf) + +project = QtQmlModels +description = Qt Qml Models Reference Documentation +version = $QT_VERSION +moduleheader = QtQmlModels +qhp.projects = QtQmlModels + +qhp.QtQmlModels.file = qtqmlmodels.qhp +qhp.QtQmlModels.namespace = org.qt-project.qtqmlmodels.$QT_VERSION_TAG +qhp.QtQmlModels.virtualFolder = qtqmlmodels +qhp.QtQmlModels.indexRoot = + +qhp.QtQmlModels.filterAttributes = qtqmlmodels $QT_VERSION qtrefdoc +qhp.QtQmlModels.customFilters.Qt.name = QtQmlModels $QT_VERSION +qhp.QtQmlModels.customFilters.Qt.filterAttributes = qtqmlmodels $QT_VERSION + +qhp.QtQmlModels.title = QML Types +qhp.QtQmlModels.indexTitle = Qt QML Models QML Types +qhp.QtQmlModels.selectors = qmlclass +qhp.QtQmlModels.sortPages = true + +tagfile = qtqmlmodels.tags + +depends += qtcore qtqml qtdoc + +headerdirs += .. + +sourcedirs += .. \ + ../../imports/models + +exampledirs += ../../../examples/qml \ + ../ \ + snippets + +navigation.qmltypespage = "Qt Qml Models QML Types" diff --git a/src/qmlmodels/doc/snippets/delegatemodel/delegatemodel.qml b/src/qmlmodels/doc/snippets/delegatemodel/delegatemodel.qml new file mode 100644 index 0000000000..1a7baa6b1e --- /dev/null +++ b/src/qmlmodels/doc/snippets/delegatemodel/delegatemodel.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick 2.0 +import QtQml.Models 2.2 + +Rectangle { + width: 200; height: 100 + + DelegateModel { + id: visualModel + model: ListModel { + ListElement { name: "Apple" } + ListElement { name: "Orange" } + } + delegate: Rectangle { + height: 25 + width: 100 + Text { text: "Name: " + name} + } + } + + ListView { + anchors.fill: parent + model: visualModel + } +} +//![0] diff --git a/src/qmlmodels/doc/snippets/delegatemodel/delegatemodel_rootindex/main.cpp b/src/qmlmodels/doc/snippets/delegatemodel/delegatemodel_rootindex/main.cpp new file mode 100644 index 0000000000..a56eb69616 --- /dev/null +++ b/src/qmlmodels/doc/snippets/delegatemodel/delegatemodel_rootindex/main.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QQuickView> +#include <QQmlContext> + +#include <QApplication> +#include <QDirModel> + +//![0] +int main(int argc, char ** argv) +{ + QApplication app(argc, argv); + + QQuickView view; + + QDirModel model; + view.rootContext()->setContextProperty("dirModel", &model); + + view.setSource(QUrl::fromLocalFile("view.qml")); + view.show(); + + return app.exec(); +} +//![0] + diff --git a/src/qmlmodels/doc/snippets/delegatemodel/delegatemodel_rootindex/view.qml b/src/qmlmodels/doc/snippets/delegatemodel/delegatemodel_rootindex/view.qml new file mode 100644 index 0000000000..2e17eed8f0 --- /dev/null +++ b/src/qmlmodels/doc/snippets/delegatemodel/delegatemodel_rootindex/view.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick 2.0 +import QtQml.Models 2.2 + +ListView { + id: view + width: 300 + height: 400 + + model: DelegateModel { + model: dirModel + + delegate: Rectangle { + width: 200; height: 25 + Text { text: filePath } + + MouseArea { + anchors.fill: parent + onClicked: { + if (model.hasModelChildren) + view.model.rootIndex = view.model.modelIndex(index) + } + } + } + } +} +//![0] diff --git a/src/qmlmodels/doc/snippets/delegatemodel/delegatemodelgroup.qml b/src/qmlmodels/doc/snippets/delegatemodel/delegatemodelgroup.qml new file mode 100644 index 0000000000..8562deeeda --- /dev/null +++ b/src/qmlmodels/doc/snippets/delegatemodel/delegatemodelgroup.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick 2.0 +import QtQml.Models 2.2 + +Rectangle { + width: 200; height: 100 + + DelegateModel { + id: visualModel + model: ListModel { + ListElement { name: "Apple" } + ListElement { name: "Orange" } + } + + groups: [ + DelegateModelGroup { name: "selected" } + ] + + delegate: Rectangle { + id: item + height: 25 + width: 200 + Text { + text: { + var text = "Name: " + name + if (item.DelegateModel.inSelected) + text += " (" + item.DelegateModel.selectedIndex + ")" + return text; + } + } + MouseArea { + anchors.fill: parent + onClicked: item.DelegateModel.inSelected = !item.DelegateModel.inSelected + } + } + } + + ListView { + anchors.fill: parent + model: visualModel + } +} +//![0] diff --git a/src/qmlmodels/doc/snippets/package/Delegate.qml b/src/qmlmodels/doc/snippets/package/Delegate.qml new file mode 100644 index 0000000000..7c73f35c3d --- /dev/null +++ b/src/qmlmodels/doc/snippets/package/Delegate.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +//! [0] +Package { + Text { id: listDelegate; width: parent.width; height: 25; text: 'Empty'; Package.name: 'list' } + Text { id: gridDelegate; width: parent.width / 2; height: 50; text: 'Empty'; Package.name: 'grid' } + + Rectangle { + id: wrapper + width: parent.width; height: 25 + color: 'lightsteelblue' + + Text { text: display; anchors.centerIn: parent } + state: root.upTo > index ? 'inGrid' : 'inList' + states: [ + State { + name: 'inList' + ParentChange { target: wrapper; parent: listDelegate } + }, + State { + name: 'inGrid' + ParentChange { + target: wrapper; parent: gridDelegate + x: 0; y: 0; width: gridDelegate.width; height: gridDelegate.height + } + } + ] + + transitions: [ + Transition { + ParentAnimation { + NumberAnimation { properties: 'x,y,width,height'; duration: 300 } + } + } + ] + } +} +//! [0] diff --git a/src/qmlmodels/doc/snippets/package/view.qml b/src/qmlmodels/doc/snippets/package/view.qml new file mode 100644 index 0000000000..311cc3be8e --- /dev/null +++ b/src/qmlmodels/doc/snippets/package/view.qml @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQml.Models 2.1 + +Rectangle { + id: root + color: "white" + width: 320 + height: 480 + property int upTo: 0 + SequentialAnimation on upTo { + loops: -1 + NumberAnimation { to: 8; duration: 3500 } + NumberAnimation { to: 0; duration: 3500 } + } + + ListModel { + id: myModel + ListElement { display: "One" } + ListElement { display: "Two" } + ListElement { display: "Three" } + ListElement { display: "Four" } + ListElement { display: "Five" } + ListElement { display: "Six" } + ListElement { display: "Seven" } + ListElement { display: "Eight" } + } + //![0] + DelegateModel { + id: visualModel + delegate: Delegate {} + model: myModel + } + + ListView { + id: lv + height: parent.height/2 + width: parent.width + + model: visualModel.parts.list + } + GridView { + y: parent.height/2 + height: parent.height/2 + width: parent.width + cellWidth: width / 2 + cellHeight: 50 + model: visualModel.parts.grid + } + //![0] + Text { + anchors.bottom: parent.bottom + } +} diff --git a/src/qmlmodels/doc/snippets/qml/listmodel/listelements.qml b/src/qmlmodels/doc/snippets/qml/listmodel/listelements.qml new file mode 100644 index 0000000000..12146c1420 --- /dev/null +++ b/src/qmlmodels/doc/snippets/qml/listmodel/listelements.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [document] +import QtQuick 2.0 + +Item { + width: 200; height: 250 + + //! [model] + ListModel { + id: fruitModel + + ListElement { + name: "Apple" + cost: 2.45 + } + ListElement { + name: "Orange" + cost: 3.25 + } + ListElement { + name: "Banana" + cost: 1.95 + } + } + //! [model] + + //! [view] + ListView { + anchors.fill: parent + model: fruitModel + delegate: Row { + Text { text: "Fruit: " + name } + Text { text: "Cost: $" + cost } + } + } + //! [view] +} +//! [document] diff --git a/src/qmlmodels/doc/snippets/qml/listmodel/listmodel-modify.qml b/src/qmlmodels/doc/snippets/qml/listmodel/listmodel-modify.qml new file mode 100644 index 0000000000..f293eff8ec --- /dev/null +++ b/src/qmlmodels/doc/snippets/qml/listmodel/listmodel-modify.qml @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.0 + +Rectangle { + width: 200; height: 200 + +ListModel { + id: fruitModel + + ListElement { + name: "Apple" + cost: 2.45 + attributes: [ + ListElement { description: "Core" }, + ListElement { description: "Deciduous" } + ] + } + ListElement { + name: "Orange" + cost: 3.25 + attributes: [ + ListElement { description: "Citrus" } + ] + } + ListElement { + name: "Banana" + cost: 1.95 + attributes: [ + ListElement { description: "Tropical" }, + ListElement { description: "Seedless" } + ] + } +} + +//![delegate] + Component { + id: fruitDelegate + Item { + width: 200; height: 50 + Text { text: name } + Text { text: '$' + cost; anchors.right: parent.right } + + // Double the price when clicked. + MouseArea { + anchors.fill: parent + onClicked: fruitModel.setProperty(index, "cost", cost * 2) + } + } + } +//![delegate] + +ListView { + width: 200; height: 200 + model: fruitModel + delegate: fruitDelegate +} + +} diff --git a/src/qmlmodels/doc/snippets/qml/listmodel/listmodel-nested.qml b/src/qmlmodels/doc/snippets/qml/listmodel/listmodel-nested.qml new file mode 100644 index 0000000000..8c193d6a5e --- /dev/null +++ b/src/qmlmodels/doc/snippets/qml/listmodel/listmodel-nested.qml @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.0 + +Rectangle { + width: 200; height: 200 + + +//![model] +ListModel { + id: fruitModel + + ListElement { + name: "Apple" + cost: 2.45 + attributes: [ + ListElement { description: "Core" }, + ListElement { description: "Deciduous" } + ] + } + ListElement { + name: "Orange" + cost: 3.25 + attributes: [ + ListElement { description: "Citrus" } + ] + } + ListElement { + name: "Banana" + cost: 1.95 + attributes: [ + ListElement { description: "Tropical" }, + ListElement { description: "Seedless" } + ] + } +} +//![model] + +//![delegate] +Component { + id: fruitDelegate + Item { + width: 200; height: 50 + Text { id: nameField; text: name } + Text { text: '$' + cost; anchors.left: nameField.right } + Row { + anchors.top: nameField.bottom + spacing: 5 + Text { text: "Attributes:" } + Repeater { + model: attributes + Text { text: description } + } + } + } +} +//![delegate] + +ListView { + width: 200; height: 200 + model: fruitModel + delegate: fruitDelegate +} + +} diff --git a/src/qmlmodels/doc/snippets/qml/listmodel/listmodel-simple.qml b/src/qmlmodels/doc/snippets/qml/listmodel/listmodel-simple.qml new file mode 100644 index 0000000000..d07f868476 --- /dev/null +++ b/src/qmlmodels/doc/snippets/qml/listmodel/listmodel-simple.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick 2.0 + +Rectangle { + width: 200; height: 200 + + ListModel { + id: fruitModel +//![0] + ListElement { + name: "Apple" + cost: 2.45 + } + ListElement { + name: "Orange" + cost: 3.25 + } + ListElement { + name: "Banana" + cost: 1.95 + } +//![1] + } + + Component { + id: fruitDelegate + Row { + spacing: 10 + Text { text: name } + Text { text: '$' + cost } + } + } + + ListView { + anchors.fill: parent + model: fruitModel + delegate: fruitDelegate + } +} +//![1] diff --git a/src/qmlmodels/doc/snippets/qml/listmodel/listmodel.qml b/src/qmlmodels/doc/snippets/qml/listmodel/listmodel.qml new file mode 100644 index 0000000000..c2a69d6e8f --- /dev/null +++ b/src/qmlmodels/doc/snippets/qml/listmodel/listmodel.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick 2.0 + +ListModel { + id: fruitModel + + ListElement { + name: "Apple" + cost: 2.45 + } + ListElement { + name: "Orange" + cost: 3.25 + } + ListElement { + name: "Banana" + cost: 1.95 + } +} +//![0] diff --git a/src/qmlmodels/doc/snippets/qml/tablemodel/fruit-example-complex.qml b/src/qmlmodels/doc/snippets/qml/tablemodel/fruit-example-complex.qml new file mode 100644 index 0000000000..104a2209d7 --- /dev/null +++ b/src/qmlmodels/doc/snippets/qml/tablemodel/fruit-example-complex.qml @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![file] +import QtQuick 2.12 +import QtQuick.Window 2.12 +import Qt.labs.qmlmodels 1.0 + +Window { + width: 400 + height: 400 + visible: true + + TableView { + anchors.fill: parent + columnSpacing: 1 + rowSpacing: 1 + boundsBehavior: Flickable.StopAtBounds + + model: TableModel { + TableModelColumn { + display: function(modelIndex) { return rows[modelIndex.row][0].checked } + setDisplay: function(modelIndex, cellData) { rows[modelIndex.row][0].checked = cellData } + } + TableModelColumn { + display: function(modelIndex) { return rows[modelIndex.row][1].amount } + setDisplay: function(modelIndex, cellData) { rows[modelIndex.row][1].amount = cellData } + } + TableModelColumn { + display: function(modelIndex) { return rows[modelIndex.row][2].fruitType } + setDisplay: function(modelIndex, cellData) { rows[modelIndex.row][2].fruitType = cellData } + } + TableModelColumn { + display: function(modelIndex) { return rows[modelIndex.row][3].fruitName } + setDisplay: function(modelIndex, cellData) { rows[modelIndex.row][3].fruitName = cellData } + } + TableModelColumn { + display: function(modelIndex) { return rows[modelIndex.row][4].fruitPrice } + setDisplay: function(modelIndex, cellData) { rows[modelIndex.row][4].fruitPrice = cellData } + } + + // Each row is one type of fruit that can be ordered +//![rows] + rows: [ + [ + // Each object (line) is one cell/column. + { checked: false, checkable: true }, + { amount: 1 }, + { fruitType: "Apple" }, + { fruitName: "Granny Smith" }, + { fruitPrice: 1.50 } + ], + [ + { checked: true, checkable: true }, + { amount: 4 }, + { fruitType: "Orange" }, + { fruitName: "Navel" }, + { fruitPrice: 2.50 } + ], + [ + { checked: false, checkable: false }, + { amount: 1 }, + { fruitType: "Banana" }, + { fruitName: "Cavendish" }, + { fruitPrice: 3.50 } + ] + ] +//![rows] + } +//![delegate] + delegate: TextInput { + text: model.display + padding: 12 + selectByMouse: true + + onAccepted: model.display = text + + Rectangle { + anchors.fill: parent + color: "#efefef" + z: -1 + } + } +//![delegate] + } +} +//![file] diff --git a/src/qmlmodels/doc/snippets/qml/tablemodel/fruit-example-delegatechooser.qml b/src/qmlmodels/doc/snippets/qml/tablemodel/fruit-example-delegatechooser.qml new file mode 100644 index 0000000000..d3f6176c70 --- /dev/null +++ b/src/qmlmodels/doc/snippets/qml/tablemodel/fruit-example-delegatechooser.qml @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![file] +import QtQuick 2.12 +import QtQuick.Controls 2.5 +import Qt.labs.qmlmodels 1.0 + +ApplicationWindow { + width: 400 + height: 400 + visible: true + + TableView { + anchors.fill: parent + columnSpacing: 1 + rowSpacing: 1 + boundsBehavior: Flickable.StopAtBounds + + model: TableModel { + TableModelColumn { display: "checked" } + TableModelColumn { display: "amount" } + TableModelColumn { display: "fruitType" } + TableModelColumn { display: "fruitName" } + TableModelColumn { display: "fruitPrice" } + + // Each row is one type of fruit that can be ordered +//![rows] + rows: [ + { + // Each property is one cell/column. + checked: false, + amount: 1, + fruitType: "Apple", + fruitName: "Granny Smith", + fruitPrice: 1.50 + }, + { + checked: true, + amount: 4, + fruitType: "Orange", + fruitName: "Navel", + fruitPrice: 2.50 + }, + { + checked: false, + amount: 1, + fruitType: "Banana", + fruitName: "Cavendish", + fruitPrice: 3.50 + } + ] +//![rows] + } +//![delegate] + delegate: DelegateChooser { + DelegateChoice { + column: 0 + delegate: CheckBox { + checked: model.display + onToggled: model.display = checked + } + } + DelegateChoice { + column: 1 + delegate: SpinBox { + value: model.display + onValueModified: model.display = value + } + } + DelegateChoice { + delegate: TextField { + text: model.display + selectByMouse: true + implicitWidth: 140 + onAccepted: model.display = text + } + } + } +//![delegate] + } +} +//![file] diff --git a/src/qmlmodels/doc/snippets/qml/tablemodel/fruit-example-simpledelegate.qml b/src/qmlmodels/doc/snippets/qml/tablemodel/fruit-example-simpledelegate.qml new file mode 100644 index 0000000000..f51c1818c3 --- /dev/null +++ b/src/qmlmodels/doc/snippets/qml/tablemodel/fruit-example-simpledelegate.qml @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![file] +import QtQuick 2.12 +import QtQuick.Window 2.12 +import Qt.labs.qmlmodels 1.0 + +Window { + width: 400 + height: 400 + visible: true + + TableView { + anchors.fill: parent + columnSpacing: 1 + rowSpacing: 1 + boundsBehavior: Flickable.StopAtBounds + + model: TableModel { + TableModelColumn { display: "checked" } + TableModelColumn { display: "amount" } + TableModelColumn { display: "fruitType" } + TableModelColumn { display: "fruitName" } + TableModelColumn { display: "fruitPrice" } + + // Each row is one type of fruit that can be ordered +//![rows] + rows: [ + { + // Each property is one cell/column. + checked: false, + amount: 1, + fruitType: "Apple", + fruitName: "Granny Smith", + fruitPrice: 1.50 + }, + { + checked: true, + amount: 4, + fruitType: "Orange", + fruitName: "Navel", + fruitPrice: 2.50 + }, + { + checked: false, + amount: 1, + fruitType: "Banana", + fruitName: "Cavendish", + fruitPrice: 3.50 + } + ] +//![rows] + } +//![delegate] + delegate: TextInput { + text: model.display + padding: 12 + selectByMouse: true + + onAccepted: model.display = text + + Rectangle { + anchors.fill: parent + color: "#efefef" + z: -1 + } + } +//![delegate] + } +} +//![file] diff --git a/src/qmlmodels/qmlmodels.pro b/src/qmlmodels/qmlmodels.pro index 7d1d9bdf67..1d733f5bdb 100644 --- a/src/qmlmodels/qmlmodels.pro +++ b/src/qmlmodels/qmlmodels.pro @@ -1,6 +1,8 @@ TARGET = QtQmlModels QT = core-private qml-private +QMAKE_DOCS = $$PWD/doc/qtqmlmodels.qdocconf + DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES QT_NO_FOREACH HEADERS += \ diff --git a/src/qmlmodels/qqmldelegatecomponent.cpp b/src/qmlmodels/qqmldelegatecomponent.cpp index ccb0d60053..cc3b38ec93 100644 --- a/src/qmlmodels/qqmldelegatecomponent.cpp +++ b/src/qmlmodels/qqmldelegatecomponent.cpp @@ -59,19 +59,6 @@ QVariant QQmlAbstractDelegateComponent::value(QQmlAdaptorModel *adaptorModel, in } /*! - \qmlmodule Qt.labs.qmlmodels 1.0 - \title Qt Labs QML Models - QML Types - \ingroup qmlmodules - \brief The Qt Labs QML Models module provides various model-related types for use with views. - - To use this module, import the module with the following line: - - \qml - import Qt.labs.qmlmodels 1.0 - \endqml -*/ - -/*! \qmltype DelegateChoice \instantiates QQmlDelegateChoice \inqmlmodule Qt.labs.qmlmodels diff --git a/src/qmlmodels/qqmldelegatecomponent_p.h b/src/qmlmodels/qqmldelegatecomponent_p.h index 1d20f0327b..86ad04d2e3 100644 --- a/src/qmlmodels/qqmldelegatecomponent_p.h +++ b/src/qmlmodels/qqmldelegatecomponent_p.h @@ -64,6 +64,9 @@ class QQmlAdaptorModel; class Q_QMLMODELS_PRIVATE_EXPORT QQmlAbstractDelegateComponent : public QQmlComponent { Q_OBJECT + QML_NAMED_ELEMENT(AbstractDelegateComponent) + QML_UNCREATABLE("Cannot create instance of abstract class AbstractDelegateComponent.") + public: QQmlAbstractDelegateComponent(QObject *parent = nullptr); ~QQmlAbstractDelegateComponent() override; @@ -90,6 +93,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateChoice : public QObject Q_PROPERTY(int column READ column WRITE setColumn NOTIFY columnChanged) Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) Q_CLASSINFO("DefaultProperty", "delegate") + QML_NAMED_ELEMENT(DelegateChoice) public: QVariant roleValue() const; void setRoleValue(const QVariant &roleValue); @@ -126,6 +130,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateChooser : public QQmlAbstractDelega Q_PROPERTY(QString role READ role WRITE setRole NOTIFY roleChanged) Q_PROPERTY(QQmlListProperty<QQmlDelegateChoice> choices READ choices CONSTANT) Q_CLASSINFO("DefaultProperty", "choices") + QML_NAMED_ELEMENT(DelegateChooser) public: QString role() const { return m_role; } diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp index 6c80f4a3e5..2c3382c643 100644 --- a/src/qmlmodels/qqmldelegatemodel.cpp +++ b/src/qmlmodels/qqmldelegatemodel.cpp @@ -48,7 +48,6 @@ #include <private/qqmlchangeset_p.h> #include <private/qqmlengine_p.h> #include <private/qqmlcomponent_p.h> -#include <private/qqmlincubator_p.h> #include <private/qv4value_p.h> #include <private/qv4functionobject_p.h> @@ -454,7 +453,8 @@ void QQmlDelegateModel::setDelegate(QQmlComponent *delegate) } if (d->m_delegate == delegate) return; - bool wasValid = d->m_delegate != nullptr; + if (d->m_complete) + _q_itemsRemoved(0, d->m_count); d->m_delegate.setObject(delegate, this); d->m_delegateValidated = false; if (d->m_delegateChooser) @@ -470,7 +470,11 @@ void QQmlDelegateModel::setDelegate(QQmlComponent *delegate) [d](){ d->delegateChanged(); }); } } - d->delegateChanged(d->m_delegate, wasValid); + if (d->m_complete) { + _q_itemsInserted(0, d->adaptorModelCount()); + d->requestMoreIfNecessary(); + } + emit delegateChanged(); } /*! @@ -540,10 +544,10 @@ void QQmlDelegateModel::setRootIndex(const QVariant &root) \qmlmethod QModelIndex QtQml.Models::DelegateModel::modelIndex(int index) QAbstractItemModel provides a hierarchical tree of data, whereas - QML only operates on list data. This function assists in using + QML only operates on list data. This function assists in using tree models in QML. - Returns a QModelIndex for the specified index. + Returns a QModelIndex for the specified \a index. This value can be assigned to rootIndex. \sa rootIndex @@ -887,6 +891,117 @@ static bool isDoneIncubating(QQmlIncubator::Status status) return status == QQmlIncubator::Ready || status == QQmlIncubator::Error; } +PropertyUpdater::PropertyUpdater(QObject *parent) : + QObject(parent) {} + +void PropertyUpdater::doUpdate() +{ + auto sender = QObject::sender(); + auto mo = sender->metaObject(); + auto signalIndex = QObject::senderSignalIndex(); + ++updateCount; + // start at 0 instead of propertyOffset to handle properties from parent hierarchy + for (auto i = 0; i < mo->propertyCount() + mo->propertyOffset(); ++i) { + auto property = mo->property(i); + if (property.notifySignal().methodIndex() == signalIndex) { + // we synchronize between required properties and model rolenames by name + // that's why the QQmlProperty and the metaobject property must have the same name + QQmlProperty qmlProp(parent(), QString::fromLatin1(property.name())); + qmlProp.write(property.read(QObject::sender())); + return; + } + } +} + +void PropertyUpdater::breakBinding() +{ + auto it = senderToConnection.find(QObject::senderSignalIndex()); + if (it == senderToConnection.end()) + return; + if (updateCount == 0) { + QObject::disconnect(*it); + QQmlError warning; + warning.setUrl(qmlContext(QObject::sender())->baseUrl()); + auto signalName = QString::fromLatin1(QObject::sender()->metaObject()->method(QObject::senderSignalIndex()).name()); + signalName.chop(sizeof("changed")-1); + QString propName = signalName; + propName[0] = propName[0].toLower(); + warning.setDescription(QString::fromUtf8("Writing to \"%1\" broke the binding to the underlying model").arg(propName)); + qmlWarning(this, warning); + senderToConnection.erase(it); + } else { + --updateCount; + } +} + +void QQDMIncubationTask::initializeRequiredProperties(QQmlDelegateModelItem *modelItemToIncubate, QObject *object) +{ + auto incubatorPriv = QQmlIncubatorPrivate::get(this); + QQmlData *d = QQmlData::get(object); + auto contextData = d ? d->context : nullptr; + if (contextData) { + contextData->hasExtraObject = true; + contextData->extraObject = modelItemToIncubate; + } + if (incubatorPriv->hadRequiredProperties()) { + if (incubatorPriv->requiredProperties().empty()) + return; + RequiredProperties &requiredProperties = incubatorPriv->requiredProperties(); + + auto qmlMetaObject = modelItemToIncubate->metaObject(); + // if a required property was not in the model, it might still be a static property of the + // QQmlDelegateModelItem or one of its derived classes this is the case for index, row, + // column, model and more + // the most derived subclass of QQmlDelegateModelItem is QQmlDMAbstractModelData at depth 2, + // so 4 should be plenty + QVarLengthArray<const QMetaObject *, 4> mos; + // we first check the dynamic meta object for properties originating from the model + mos.push_back(qmlMetaObject); // contains abstractitemmodelproperties + auto delegateModelItemSubclassMO = qmlMetaObject->superClass(); + mos.push_back(delegateModelItemSubclassMO); + + while (strcmp(delegateModelItemSubclassMO->className(), modelItemToIncubate->staticMetaObject.className())) { + delegateModelItemSubclassMO = delegateModelItemSubclassMO->superClass(); + mos.push_back(delegateModelItemSubclassMO); + } + if (proxiedObject) + mos.push_back(proxiedObject->metaObject()); + + auto updater = new PropertyUpdater(object); + for (const QMetaObject *mo : mos) { + for (int i = mo->propertyOffset(); i < mo->propertyCount() + mo->propertyOffset(); ++i) { + auto prop = mo->property(i); + if (!prop.name()) + continue; + auto propName = QString::fromUtf8(prop.name()); + bool wasInRequired = false; + QQmlProperty componentProp = QQmlComponentPrivate::removePropertyFromRequired( + object, propName, requiredProperties, &wasInRequired); + // only write to property if it was actually requested by the component + if (wasInRequired && prop.hasNotifySignal()) { + QMetaMethod changeSignal = prop.notifySignal(); + static QMetaMethod updateSlot = PropertyUpdater::staticMetaObject.method(PropertyUpdater::staticMetaObject.indexOfSlot("doUpdate()")); + QMetaObject::Connection conn = QObject::connect(modelItemToIncubate, changeSignal, updater, updateSlot); + auto propIdx = object->metaObject()->indexOfProperty(propName.toUtf8()); + QMetaMethod writeToPropSignal = object->metaObject()->property(propIdx).notifySignal(); + updater->senderToConnection[writeToPropSignal.methodIndex()] = conn; + static QMetaMethod breakBinding = PropertyUpdater::staticMetaObject.method(PropertyUpdater::staticMetaObject.indexOfSlot("breakBinding()")); + componentProp.write(prop.read(modelItemToIncubate)); + // the connection needs to established after the write, + // else the signal gets triggered by it and breakBinding will remove the connection + QObject::connect(object, writeToPropSignal, updater, breakBinding); + } + else if (wasInRequired) // we still have to write, even if there is no change signal + componentProp.write(prop.read(modelItemToIncubate)); + } + } + } else { + modelItemToIncubate->contextData->contextObject = modelItemToIncubate; + if (proxiedObject) + proxyContext->contextObject = proxiedObject; + } +} + void QQDMIncubationTask::statusChanged(Status status) { if (vdm) { @@ -987,6 +1102,7 @@ void QQDMIncubationTask::setInitialState(QObject *o) void QQmlDelegateModelPrivate::setInitialState(QQDMIncubationTask *incubationTask, QObject *o) { QQmlDelegateModelItem *cacheItem = incubationTask->incubating; + incubationTask->initializeRequiredProperties(incubationTask->incubating, o); cacheItem->object = o; if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(cacheItem->object)) @@ -1053,7 +1169,6 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ QQmlContextData *ctxt = new QQmlContextData; ctxt->setParent(QQmlContextData::get(creationContext ? creationContext : m_context.data())); - ctxt->contextObject = cacheItem; cacheItem->contextData = ctxt; if (m_adaptorModel.hasProxyObject()) { @@ -1062,7 +1177,8 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ ctxt = new QQmlContextData; ctxt->setParent(cacheItem->contextData, /*stronglyReferencedByParent*/true); QObject *proxied = proxy->proxiedObject(); - ctxt->contextObject = proxied; + cacheItem->incubationTask->proxiedObject = proxied; + cacheItem->incubationTask->proxyContext = ctxt; // We don't own the proxied object. We need to clear it if it goes away. QObject::connect(proxied, &QObject::destroyed, cacheItem, &QQmlDelegateModelItem::childContextObjectDestroyed); @@ -2166,6 +2282,8 @@ QQmlDelegateModelItem *QQmlDelegateModelItem::dataForObject(QObject *object) { QQmlData *d = QQmlData::get(object); QQmlContextData *context = d ? d->context : nullptr; + if (context && context->hasExtraObject) + return qobject_cast<QQmlDelegateModelItem *>(context->extraObject); for (context = context ? context->parent : nullptr; context; context = context->parent) { if (QQmlDelegateModelItem *cacheItem = qobject_cast<QQmlDelegateModelItem *>( context->contextObject)) { diff --git a/src/qmlmodels/qqmldelegatemodel_p.h b/src/qmlmodels/qqmldelegatemodel_p.h index 21eaef02e0..02904a71d7 100644 --- a/src/qmlmodels/qqmldelegatemodel_p.h +++ b/src/qmlmodels/qqmldelegatemodel_p.h @@ -77,7 +77,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateModel : public QQmlInstanceModel, p Q_DECLARE_PRIVATE(QQmlDelegateModel) Q_PROPERTY(QVariant model READ model WRITE setModel) - Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate) + Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup) Q_PROPERTY(QQmlDelegateModelGroup *items READ items CONSTANT) //TODO : worth renaming? Q_PROPERTY(QQmlDelegateModelGroup *persistedItems READ persistedItems CONSTANT) @@ -85,7 +85,11 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateModel : public QQmlInstanceModel, p Q_PROPERTY(QObject *parts READ parts CONSTANT) Q_PROPERTY(QVariant rootIndex READ rootIndex WRITE setRootIndex NOTIFY rootIndexChanged) Q_CLASSINFO("DefaultProperty", "delegate") + QML_NAMED_ELEMENT(DelegateModel) + QML_ADDED_IN_MINOR_VERSION(1) + QML_ATTACHED(QQmlDelegateModelAttached) Q_INTERFACES(QQmlParserStatus) + public: QQmlDelegateModel(); QQmlDelegateModel(QQmlContext *, QObject *parent=nullptr); @@ -136,6 +140,7 @@ Q_SIGNALS: void filterGroupChanged(); void defaultGroupsChanged(); void rootIndexChanged(); + void delegateChanged(); private Q_SLOTS: void _q_itemsChanged(int index, int count, const QVector<int> &roles); @@ -163,6 +168,8 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateModelGroup : public QObject Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(bool includeByDefault READ defaultInclude WRITE setDefaultInclude NOTIFY defaultIncludeChanged) + QML_NAMED_ELEMENT(DelegateModelGroup) + QML_ADDED_IN_MINOR_VERSION(1) public: QQmlDelegateModelGroup(QObject *parent = nullptr); QQmlDelegateModelGroup(const QString &name, QQmlDelegateModel *model, int compositorType, QObject *parent = nullptr); @@ -240,7 +247,6 @@ public: QT_END_NAMESPACE QML_DECLARE_TYPE(QQmlDelegateModel) -QML_DECLARE_TYPEINFO(QQmlDelegateModel, QML_HAS_ATTACHED_PROPERTIES) QML_DECLARE_TYPE(QQmlDelegateModelGroup) #endif // QQMLDATAMODEL_P_H diff --git a/src/qmlmodels/qqmldelegatemodel_p_p.h b/src/qmlmodels/qqmldelegatemodel_p_p.h index 92362b8876..06365a212f 100644 --- a/src/qmlmodels/qqmldelegatemodel_p_p.h +++ b/src/qmlmodels/qqmldelegatemodel_p_p.h @@ -201,11 +201,14 @@ public: , incubating(nullptr) , vdm(l) {} + void initializeRequiredProperties(QQmlDelegateModelItem *modelItemToIncubate, QObject* object); void statusChanged(Status) override; void setInitialState(QObject *) override; QQmlDelegateModelItem *incubating = nullptr; QQmlDelegateModelPrivate *vdm = nullptr; + QQmlContextData *proxyContext = nullptr; + QPointer<QObject> proxiedObject = nullptr; // the proxied object might disapear, so we use a QPointer instead of a raw one int index[QQmlListCompositor::MaximumGroupCount]; }; @@ -445,6 +448,19 @@ private: const int indexPropertyOffset; }; +class PropertyUpdater : public QObject +{ + Q_OBJECT + +public: + PropertyUpdater(QObject *parent); + QHash<int, QMetaObject::Connection> senderToConnection; + int updateCount = 0; +public Q_SLOTS: + void doUpdate(); + void breakBinding(); +}; + QT_END_NAMESPACE #endif diff --git a/src/qmlmodels/qqmlinstantiator.cpp b/src/qmlmodels/qqmlinstantiator.cpp index af1b526e1d..f9d5762f6e 100644 --- a/src/qmlmodels/qqmlinstantiator.cpp +++ b/src/qmlmodels/qqmlinstantiator.cpp @@ -220,7 +220,8 @@ void QQmlInstantiatorPrivate::makeModel() /*! \qmltype Instantiator \instantiates QQmlInstantiator - \inqmlmodule QtQml + \inqmlmodule QtQml.Models + \ingroup qtquick-models \brief Dynamically creates objects. A Instantiator can be used to control the dynamic creation of objects, or to dynamically @@ -231,6 +232,8 @@ void QQmlInstantiatorPrivate::makeModel() can also be destroyed dynamically through other means, and the Instantiator will not recreate them unless the properties of the Instantiator change. + \note Instantiator is part of QtQml.Models since version 2.14 and part of QtQml since + version 2.1. Importing Instantiator via QtQml is deprecated since Qt 5.14. */ QQmlInstantiator::QQmlInstantiator(QObject *parent) : QObject(*(new QQmlInstantiatorPrivate), parent) diff --git a/src/qmlmodels/qqmlinstantiator_p.h b/src/qmlmodels/qqmlinstantiator_p.h index 87accc304f..9f6d816d18 100644 --- a/src/qmlmodels/qqmlinstantiator_p.h +++ b/src/qmlmodels/qqmlinstantiator_p.h @@ -72,6 +72,8 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlInstantiator : public QObject, public QQmlP Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) Q_PROPERTY(QObject *object READ object NOTIFY objectChanged) Q_CLASSINFO("DefaultProperty", "delegate") + QML_NAMED_ELEMENT(Instantiator) + QML_ADDED_IN_MINOR_VERSION(1) public: QQmlInstantiator(QObject *parent = nullptr); diff --git a/src/qmlmodels/qqmlitemmodels.qdoc b/src/qmlmodels/qqmlitemmodels.qdoc index f6e1b0b1b9..2e12dbf656 100644 --- a/src/qmlmodels/qqmlitemmodels.qdoc +++ b/src/qmlmodels/qqmlitemmodels.qdoc @@ -62,7 +62,7 @@ \section1 QModelIndexList Type - \l QModelIndexList is exposed in QML as a JavaScript array. Conversions are + QModelIndexList is exposed in QML as a JavaScript array. Conversions are automatically made from and to C++. In fact, any JavaScript array can be converted back to QModelIndexList, with non-QModelIndex objects replaced by invalid \l{QModelIndex}es. diff --git a/src/qmlmodels/qqmllistmodel.cpp b/src/qmlmodels/qqmllistmodel.cpp index 1cd089f454..e0a66e7170 100644 --- a/src/qmlmodels/qqmllistmodel.cpp +++ b/src/qmlmodels/qqmllistmodel.cpp @@ -634,7 +634,7 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles) mo->updateValues(*roles); } -void ListModel::set(int elementIndex, QV4::Object *object) +void ListModel::set(int elementIndex, QV4::Object *object, ListModel::SetElement reason) { if (!object) return; @@ -684,7 +684,7 @@ void ListModel::set(int elementIndex, QV4::Object *object) } else if (QV4::DateObject *date = propertyValue->as<QV4::DateObject>()) { const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime); if (r.type == ListLayout::Role::DateTime) { - QDateTime dt = date->toQDateTime();; + QDateTime dt = date->toQDateTime(); e->setDateTimePropertyFast(r, dt); } } else if (QV4::Object *o = propertyValue->as<QV4::Object>()) { @@ -699,9 +699,16 @@ void ListModel::set(int elementIndex, QV4::Object *object) e->setVariantMapFast(role, o); } } else if (propertyValue->isNullOrUndefined()) { - const ListLayout::Role *r = m_layout->getExistingRole(propertyName); - if (r) - e->clearProperty(*r); + if (reason == SetElement::WasJustInserted) { + QQmlError err; + auto memberName = propertyName->toString(m_modelCache->engine())->toQString(); + err.setDescription(QString::fromLatin1("%1 is %2. Adding an object with a %2 member does not create a role for it.").arg(memberName, propertyValue->isNull() ? QLatin1String("null") : QLatin1String("undefined"))); + qmlWarning(nullptr, err); + } else { + const ListLayout::Role *r = m_layout->getExistingRole(propertyName); + if (r) + e->clearProperty(*r); + } } } } @@ -725,13 +732,13 @@ QVector<std::function<void()>> ListModel::remove(int index, int count) void ListModel::insert(int elementIndex, QV4::Object *object) { insertElement(elementIndex); - set(elementIndex, object); + set(elementIndex, object, SetElement::WasJustInserted); } int ListModel::append(QV4::Object *object) { int elementIndex = appendElement(); - set(elementIndex, object); + set(elementIndex, object, SetElement::WasJustInserted); return elementIndex; } @@ -1641,8 +1648,18 @@ PropertyKey ModelObjectOwnPropertyKeyIterator::next(const Object *o, Property *p if (attrs) *attrs = QV4::Attr_Data; if (pd) { + QVariant value = that->d()->m_model->data(that->d()->elementIndex(), role.index); - pd->value = v4->fromVariant(value); + if (auto recursiveListModel = qvariant_cast<QQmlListModel*>(value)) { + auto size = recursiveListModel->count(); + auto array = ScopedArrayObject{scope, v4->newArrayObject(size)}; + for (auto i = 0; i < size; i++) { + array->arrayPut(i, QJSValuePrivate::convertedToValue(v4, recursiveListModel->get(i))); + } + pd->value = array; + } else { + pd->value = v4->fromVariant(value); + } } return roleName->toPropertyKey(); } diff --git a/src/qmlmodels/qqmllistmodel_p.h b/src/qmlmodels/qqmllistmodel_p.h index 10d67c1c6f..dc5063eb97 100644 --- a/src/qmlmodels/qqmllistmodel_p.h +++ b/src/qmlmodels/qqmllistmodel_p.h @@ -83,6 +83,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlListModel : public QAbstractListModel Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(bool dynamicRoles READ dynamicRoles WRITE setDynamicRoles) Q_PROPERTY(QObject *agent READ agent CONSTANT REVISION(14)) + QML_NAMED_ELEMENT(ListModel) public: QQmlListModel(QObject *parent=nullptr); @@ -171,7 +172,8 @@ private: // ### FIXME class QQmlListElement : public QObject { -Q_OBJECT + Q_OBJECT + QML_NAMED_ELEMENT(ListElement) }; class QQmlListModelParser : public QQmlCustomParser @@ -201,6 +203,12 @@ private: QString listElementTypeName; }; +template<> +inline QQmlCustomParser *qmlCreateCustomParser<QQmlListModel>() +{ + return new QQmlListModelParser; +} + QT_END_NAMESPACE QML_DECLARE_TYPE(QQmlListModel) diff --git a/src/qmlmodels/qqmllistmodel_p_p.h b/src/qmlmodels/qqmllistmodel_p_p.h index a0d0e9ad89..2ad5158050 100644 --- a/src/qmlmodels/qqmllistmodel_p_p.h +++ b/src/qmlmodels/qqmllistmodel_p_p.h @@ -381,8 +381,10 @@ public: return elements.count(); } + enum class SetElement {WasJustInserted, IsCurrentlyUpdated}; + void set(int elementIndex, QV4::Object *object, QVector<int> *roles); - void set(int elementIndex, QV4::Object *object); + void set(int elementIndex, QV4::Object *object, SetElement reason = SetElement::IsCurrentlyUpdated); int append(QV4::Object *object); void insert(int elementIndex, QV4::Object *object); diff --git a/src/qmlmodels/qqmllistmodelworkeragent_p.h b/src/qmlmodels/qqmllistmodelworkeragent_p.h index 1ef27cea3f..f65909dcec 100644 --- a/src/qmlmodels/qqmllistmodelworkeragent_p.h +++ b/src/qmlmodels/qqmllistmodelworkeragent_p.h @@ -56,6 +56,7 @@ #include <QEvent> #include <QMutex> #include <QWaitCondition> +#include <QtQml/qqml.h> #include <private/qv4engine_p.h> @@ -71,6 +72,7 @@ class QQmlListModelWorkerAgent : public QObject Q_OBJECT Q_PROPERTY(int count READ count) Q_PROPERTY(QV4::ExecutionEngine *engine READ engine WRITE setEngine NOTIFY engineChanged) + QML_ANONYMOUS public: QQmlListModelWorkerAgent(QQmlListModel *); diff --git a/src/qmlmodels/qqmlmodelsmodule.cpp b/src/qmlmodels/qqmlmodelsmodule.cpp index 4b753fe49a..7ed8561558 100644 --- a/src/qmlmodels/qqmlmodelsmodule.cpp +++ b/src/qmlmodels/qqmlmodelsmodule.cpp @@ -40,16 +40,15 @@ #include "qqmlmodelsmodule_p.h" #include <private/qtqmlmodelsglobal_p.h> -#if QT_CONFIG(itemmodel) -#include <QtCore/qitemselectionmodel.h> -#endif #if QT_CONFIG(qml_list_model) #include <private/qqmllistmodel_p.h> +#include <private/qqmllistmodelworkeragent_p.h> #endif #if QT_CONFIG(qml_delegate_model) #include <private/qqmldelegatemodel_p.h> #include <private/qqmldelegatecomponent_p.h> #include <private/qquickpackage_p.h> +#include <private/qqmlcomponentattached_p.h> #endif #if QT_CONFIG(qml_object_model) #include <private/qqmlobjectmodel_p.h> @@ -67,24 +66,20 @@ void QQmlModelsModule::defineModule() const char uri[] = "QtQml.Models"; #if QT_CONFIG(qml_list_model) - qmlRegisterType<QQmlListElement>(uri, 2, 0, "ListElement"); - qmlRegisterCustomType<QQmlListModel>(uri, 2, 0, "ListModel", new QQmlListModelParser); + qmlRegisterTypesAndRevisions<QQmlListElement, QQmlListModel, QQmlListModelWorkerAgent>(uri, 2); #endif #if QT_CONFIG(qml_delegate_model) + // TODO: Get rid of these. It's called DelegateModel and DelegateModelGroup these days. qmlRegisterType<QQmlDelegateModel>(uri, 2, 0, "VisualDataModel"); qmlRegisterType<QQmlDelegateModelGroup>(uri, 2, 0, "VisualDataGroup"); - qmlRegisterType<QQmlDelegateModel>(uri, 2, 1, "DelegateModel"); - qmlRegisterType<QQmlDelegateModelGroup>(uri, 2, 1, "DelegateModelGroup"); - qmlRegisterType<QQuickPackage>(uri, 2, 0, "Package"); + + qmlRegisterTypesAndRevisions<QQmlDelegateModel, QQmlDelegateModelGroup, QQuickPackage>(uri, 2); #endif #if QT_CONFIG(qml_object_model) - qmlRegisterType<QQmlObjectModel>(uri, 2, 1, "ObjectModel"); - qmlRegisterType<QQmlObjectModel,3>(uri, 2, 3, "ObjectModel"); - qmlRegisterType<QQmlInstantiator>(uri, 2, 1, "Instantiator"); - qmlRegisterAnonymousType<QQmlInstanceModel>(uri, 2); + qmlRegisterTypesAndRevisions<QQmlObjectModel, QQmlInstantiator, QQmlInstanceModel>(uri, 2); #endif #if QT_CONFIG(itemmodel) - qmlRegisterType<QItemSelectionModel>(uri, 2, 2, "ItemSelectionModel"); + qmlRegisterTypesAndRevisions<QItemSelectionModelForeign>(uri, 2); #endif } @@ -93,13 +88,11 @@ void QQmlModelsModule::defineLabsModule() const char uri[] = "Qt.labs.qmlmodels"; #if QT_CONFIG(qml_delegate_model) - qmlRegisterUncreatableType<QQmlAbstractDelegateComponent>(uri, 1, 0, "AbstractDelegateComponent", QQmlAbstractDelegateComponent::tr("Cannot create instance of abstract class AbstractDelegateComponent.")); - qmlRegisterType<QQmlDelegateChooser>(uri, 1, 0, "DelegateChooser"); - qmlRegisterType<QQmlDelegateChoice>(uri, 1, 0, "DelegateChoice"); + qmlRegisterTypesAndRevisions< + QQmlAbstractDelegateComponent, QQmlDelegateChooser, QQmlDelegateChoice>(uri, 1); #endif #if QT_CONFIG(qml_table_model) - qmlRegisterType<QQmlTableModel>(uri, 1, 0, "TableModel"); - qmlRegisterType<QQmlTableModelColumn>(uri, 1, 0, "TableModelColumn"); + qmlRegisterTypesAndRevisions<QQmlTableModel, QQmlTableModelColumn>(uri, 1); #endif } diff --git a/src/qmlmodels/qqmlmodelsmodule_p.h b/src/qmlmodels/qqmlmodelsmodule_p.h index f63052b682..c697b08bf7 100644 --- a/src/qmlmodels/qqmlmodelsmodule_p.h +++ b/src/qmlmodels/qqmlmodelsmodule_p.h @@ -51,6 +51,12 @@ // We mean it. // +#include <QtQml/qqml.h> + +#if QT_CONFIG(itemmodel) +#include <QtCore/qitemselectionmodel.h> +#endif + #include <private/qtqmlmodelsglobal_p.h> QT_BEGIN_NAMESPACE @@ -62,6 +68,16 @@ public: static void defineLabsModule(); }; +#if QT_CONFIG(itemmodel) +struct QItemSelectionModelForeign +{ + Q_GADGET + QML_FOREIGN(QItemSelectionModel) + QML_NAMED_ELEMENT(ItemSelectionModel) + QML_ADDED_IN_MINOR_VERSION(2) +}; +#endif + QT_END_NAMESPACE #endif diff --git a/src/qmlmodels/qqmlobjectmodel.cpp b/src/qmlmodels/qqmlobjectmodel.cpp index b6330b4295..7409178616 100644 --- a/src/qmlmodels/qqmlobjectmodel.cpp +++ b/src/qmlmodels/qqmlobjectmodel.cpp @@ -328,7 +328,7 @@ QObject *QQmlObjectModel::get(int index) const \qmlmethod QtQml.Models::ObjectModel::append(object item) \since 5.6 - Appends a new item to the end of the model. + Appends a new \a item to the end of the model. \code objectModel.append(objectComponent.createObject()) @@ -346,7 +346,7 @@ void QQmlObjectModel::append(QObject *object) \qmlmethod QtQml.Models::ObjectModel::insert(int index, object item) \since 5.6 - Inserts a new item to the model at position \a index. + Inserts a new \a item to the model at position \a index. \code objectModel.insert(2, objectComponent.createObject()) @@ -371,7 +371,7 @@ void QQmlObjectModel::insert(int index, QObject *object) \qmlmethod QtQml.Models::ObjectModel::move(int from, int to, int n = 1) \since 5.6 - Moves \a n items \a from one position \a to another. + Moves \e n items \a from one position \a to another. The from and to ranges must exist; for example, to move the first 3 items to the end of the model: @@ -398,7 +398,7 @@ void QQmlObjectModel::move(int from, int to, int n) \qmlmethod QtQml.Models::ObjectModel::remove(int index, int n = 1) \since 5.6 - Removes the items at \a index from the model. + Removes \e n items at \a index from the model. \sa clear() */ diff --git a/src/qmlmodels/qqmlobjectmodel_p.h b/src/qmlmodels/qqmlobjectmodel_p.h index 78a5615ae2..0aa818d724 100644 --- a/src/qmlmodels/qqmlobjectmodel_p.h +++ b/src/qmlmodels/qqmlobjectmodel_p.h @@ -69,6 +69,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlInstanceModel : public QObject Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) + QML_ANONYMOUS public: virtual ~QQmlInstanceModel() {} @@ -113,6 +114,9 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlObjectModel : public QQmlInstanceModel Q_PROPERTY(QQmlListProperty<QObject> children READ children NOTIFY childrenChanged DESIGNABLE false) Q_CLASSINFO("DefaultProperty", "children") + QML_NAMED_ELEMENT(ObjectModel) + QML_ADDED_IN_MINOR_VERSION(1) + QML_ATTACHED(QQmlObjectModelAttached) public: QQmlObjectModel(QObject *parent=nullptr); @@ -191,6 +195,5 @@ QT_END_NAMESPACE QML_DECLARE_TYPE(QQmlInstanceModel) QML_DECLARE_TYPE(QQmlObjectModel) -QML_DECLARE_TYPEINFO(QQmlObjectModel, QML_HAS_ATTACHED_PROPERTIES) #endif // QQMLINSTANCEMODEL_P_H diff --git a/src/qmlmodels/qqmltableinstancemodel.cpp b/src/qmlmodels/qqmltableinstancemodel.cpp index b244a007e5..9b79df3441 100644 --- a/src/qmlmodels/qqmltableinstancemodel.cpp +++ b/src/qmlmodels/qqmltableinstancemodel.cpp @@ -525,8 +525,13 @@ const QAbstractItemModel *QQmlTableInstanceModel::abstractItemModel() const void QQmlTableInstanceModelIncubationTask::setInitialState(QObject *object) { - modelItemToIncubate->object = object; - emit tableInstanceModel->initItem(modelItemToIncubate->index, object); + initializeRequiredProperties(modelItemToIncubate, object); + if (QQmlIncubatorPrivate::get(this)->requiredProperties().empty()) { + modelItemToIncubate->object = object; + emit tableInstanceModel->initItem(modelItemToIncubate->index, object); + } else { + object->deleteLater(); + } } void QQmlTableInstanceModelIncubationTask::statusChanged(QQmlIncubator::Status status) diff --git a/src/qmlmodels/qqmltablemodel.cpp b/src/qmlmodels/qqmltablemodel.cpp index 4a96e7a46b..f190ad86b1 100644 --- a/src/qmlmodels/qqmltablemodel.cpp +++ b/src/qmlmodels/qqmltablemodel.cpp @@ -64,7 +64,7 @@ Q_LOGGING_CATEGORY(lcTableModel, "qt.qml.tablemodel") The model's initial row data is set with either the \l rows property or by calling \l appendRow(). Each column in the model is specified by declaring a \l TableModelColumn instance, where the order of each instance determines - its column index. Once the model's \l Component.completed() signal has been + its column index. Once the model's \l Component::completed() signal has been emitted, the columns and roles will have been established and are then fixed for the lifetime of the model. diff --git a/src/qmlmodels/qqmltablemodel_p.h b/src/qmlmodels/qqmltablemodel_p.h index b3c0cc2848..4b667e1073 100644 --- a/src/qmlmodels/qqmltablemodel_p.h +++ b/src/qmlmodels/qqmltablemodel_p.h @@ -72,6 +72,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlTableModel : public QAbstractTableModel, pu Q_PROPERTY(QQmlListProperty<QQmlTableModelColumn> columns READ columns CONSTANT FINAL) Q_INTERFACES(QQmlParserStatus) Q_CLASSINFO("DefaultProperty", "columns") + QML_NAMED_ELEMENT(TableModel) public: QQmlTableModel(QObject *parent = nullptr); diff --git a/src/qmlmodels/qqmltablemodelcolumn_p.h b/src/qmlmodels/qqmltablemodelcolumn_p.h index 0b6478ce38..33f32ccb68 100644 --- a/src/qmlmodels/qqmltablemodelcolumn_p.h +++ b/src/qmlmodels/qqmltablemodelcolumn_p.h @@ -96,6 +96,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlTableModelColumn : public QObject Q_PROPERTY(QJSValue sizeHint READ sizeHint WRITE setSizeHint NOTIFY sizeHintChanged FINAL) Q_PROPERTY(QJSValue setSizeHint READ getSetSizeHint WRITE setSetSizeHint NOTIFY setSizeHintChanged FINAL) + QML_NAMED_ELEMENT(TableModelColumn) public: QQmlTableModelColumn(QObject *parent = nullptr); diff --git a/src/qmlmodels/qquickpackage.cpp b/src/qmlmodels/qquickpackage.cpp index 03539d8737..567381e5ab 100644 --- a/src/qmlmodels/qquickpackage.cpp +++ b/src/qmlmodels/qquickpackage.cpp @@ -47,8 +47,8 @@ QT_BEGIN_NAMESPACE /*! \qmltype Package \instantiates QQuickPackage - \inqmlmodule QtQuick - \ingroup qtquick-views + \inqmlmodule QtQml.Models + \ingroup qtquick-models \brief Specifies a collection of named items. The Package type is used in conjunction with @@ -71,6 +71,9 @@ QT_BEGIN_NAMESPACE \snippet package/view.qml 0 + \note Package is part of QtQml.Models since version 2.14 and part of QtQuick since version 2.0. + Importing Package via QtQuick is deprecated since Qt 5.14. + \sa {Qt Quick Examples - Views}, {Qt Quick Demo - Photo Viewer}, {Qt QML} */ diff --git a/src/qmlmodels/qquickpackage_p.h b/src/qmlmodels/qquickpackage_p.h index 97f7818fee..801b8d8409 100644 --- a/src/qmlmodels/qquickpackage_p.h +++ b/src/qmlmodels/qquickpackage_p.h @@ -66,6 +66,8 @@ class Q_AUTOTEST_EXPORT QQuickPackage : public QObject Q_DECLARE_PRIVATE(QQuickPackage) Q_CLASSINFO("DefaultProperty", "data") + QML_NAMED_ELEMENT(Package) + QML_ATTACHED(QQuickPackageAttached) Q_PROPERTY(QQmlListProperty<QObject> data READ data) public: @@ -99,6 +101,5 @@ private: QT_END_NAMESPACE QML_DECLARE_TYPE(QQuickPackage) -QML_DECLARE_TYPEINFO(QQuickPackage, QML_HAS_ATTACHED_PROPERTIES) #endif // QQUICKPACKAGE_H |