Merge remote-tracking branch 'origin/5.15' into dev

Conflicts:
	src/imports/controls/qtquickcontrols2plugin.cpp

Change-Id: Ifc09ea9f71fdba119fe8eed99f0bdcb402444f27
This commit is contained in:
Simon Hausmann 2020-03-10 14:23:53 +01:00
commit 3f3e82fb05
98 changed files with 3117 additions and 107 deletions

29
dist/changes-5.14.1 vendored Normal file
View File

@ -0,0 +1,29 @@
Qt 5.14.1 is a bug-fix release. It maintains both forward and backward
compatibility (source and binary) with Qt 5.14.0.
For more details, refer to the online documentation included in this
distribution. The documentation is also available online:
https://doc.qt.io/qt-5/index.html
The Qt version 5.14 series is binary compatible with the 5.13.x series.
Applications compiled for 5.13 will continue to run with 5.14.
Some of the changes listed in this file include issue tracking numbers
corresponding to tasks in the Qt Bug Tracker:
https://bugreports.qt.io/
Each of these identifiers can be entered in the bug tracker to obtain more
information about a particular change.
****************************************************************************
* Controls *
****************************************************************************
- StackView:
* [QTBUG-80353] fixed crash when recursively removing items.
* [QTBUG-57267] fix an issue where the current item became hidden.
- SplitView:
* [QTBUG-79846] fixed hoverable child items breaking handle hover state.

View File

@ -62,11 +62,13 @@ ApplicationWindow {
visible: true
title: "Qt Quick Controls 2"
function help()
{
var url = "https://doc.qt.io/qt-5/"
+ (stackView.depth > 1
? "qml-qtquick-controls2-" + stackView.currentItem.control + ".html"
function help() {
let displayingControl = listView.currentIndex !== -1
let currentControlName = displayingControl
? listView.model.get(listView.currentIndex).title.toLowerCase() : ""
let url = "https://doc.qt.io/qt-5/"
+ (displayingControl
? "qml-qtquick-controls2-" + currentControlName + ".html"
: "qtquick-controls2-qmlmodule.html");
Qt.openUrlExternally(url)
}

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "busyindicator"
Column {
spacing: 40
width: parent.width

View File

@ -55,8 +55,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "button"
Column {
spacing: 40
width: parent.width

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "checkbox"
Column {
spacing: 40
width: parent.width

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "combobox"
Column {
spacing: 40
width: parent.width

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
property string control : "delaybutton"
Column {
spacing: 40
width: parent.width

View File

@ -55,8 +55,6 @@ import QtQuick.Controls 2.12
Pane {
padding: 0
property string control : "swipedelegate"
property var delegateComponentMap: {
"ItemDelegate": itemDelegateComponent,
"SwipeDelegate": swipeDelegateComponent,

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "dial"
Column {
spacing: 40
width: parent.width

View File

@ -55,8 +55,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "dialog"
readonly property int buttonWidth: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 2, page.availableWidth / 3))
Column {

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "frame"
readonly property int itemWidth: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 3, page.availableWidth / 3 * 2))
Column {

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "groupbox"
readonly property int itemWidth: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 3, page.availableWidth / 3 * 2))
Column {

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "pageindicator"
Column {
spacing: 40
width: parent.width

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "progressbar"
Column {
spacing: 40
width: parent.width

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "radiobutton"
Column {
spacing: 40
width: parent.width

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "rangeslider"
Column {
spacing: 40
width: parent.width

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
Flickable {
id: flickable
readonly property string control : "scrollbar"
contentHeight: pane.height
Pane {

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
Flickable {
id: flickable
readonly property string control : "scrollindicator"
contentHeight: pane.height
Pane {

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
Page {
id: page
readonly property string control : "flickable"
default property alias content: pane.contentItem
Flickable {

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "slider"
Column {
spacing: 40
width: parent.width

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : ""
Column {
spacing: 40
width: parent.width

View File

@ -55,8 +55,6 @@ StackView {
id: stackView
initialItem: page
readonly property string control : "stackview"
Component {
id: page

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
Pane {
id: pane
readonly property string control : "swipeview"
SwipeView {
id: view
currentIndex: 1

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "switch"
Column {
spacing: 40
width: parent.width

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
Page {
id: page
readonly property string control : "tabbar"
SwipeView {
id: swipeView
anchors.fill: parent

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "textarea"
Column {
spacing: 40
width: parent.width

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "textfield"
Column {
spacing: 40
width: parent.width

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "tooltip"
Column {
spacing: 40
width: parent.width

View File

@ -54,8 +54,6 @@ import QtQuick.Controls 2.12
ScrollablePage {
id: page
readonly property string control : "tumbler"
Column {
spacing: 40
width: parent.width

View File

@ -0,0 +1,66 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Templates 2.15 as T
T.HorizontalHeaderView {
id: control
implicitWidth: syncView ? syncView.width : 0
implicitHeight: contentHeight
delegate: Rectangle {
// Qt6: add cellPadding (and font etc) as public API in headerview
readonly property real cellPadding: 8
implicitWidth: text.implicitWidth + (cellPadding * 2)
implicitHeight: Math.max(control.height, text.implicitHeight + (cellPadding * 2))
color: "#f6f6f6"
border.color: "#e4e4e4"
Text {
id: text
text: model[control.textRole]
width: parent.width
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "#ff26282a"
}
}
}

View File

@ -0,0 +1,66 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Templates 2.15 as T
T.VerticalHeaderView {
id: control
implicitWidth: contentWidth
implicitHeight: syncView ? syncView.height : 0
delegate: Rectangle {
// Qt6: add cellPadding (and font etc) as public API in headerview
readonly property real cellPadding: 8
implicitWidth: Math.max(control.width, text.implicitWidth + (cellPadding * 2))
implicitHeight: text.implicitHeight + (cellPadding * 2)
color: "#f6f6f6"
border.color: "#e4e4e4"
Text {
id: text
text: model[control.textRole]
width: parent.width
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "#ff26282a"
}
}
}

View File

@ -32,6 +32,7 @@ QML_FILES += \
$$PWD/Drawer.qml \
$$PWD/Frame.qml \
$$PWD/GroupBox.qml \
$$PWD/HorizontalHeaderView.qml \
$$PWD/ItemDelegate.qml \
$$PWD/Label.qml \
$$PWD/Menu.qml \
@ -67,4 +68,5 @@ QML_FILES += \
$$PWD/ToolButton.qml \
$$PWD/ToolSeparator.qml \
$$PWD/ToolTip.qml \
$$PWD/Tumbler.qml
$$PWD/Tumbler.qml \
$$PWD/VerticalHeaderView.qml

View File

@ -19,7 +19,7 @@ SOURCES += \
RESOURCES += \
$$PWD/qtquickcontrols2plugin.qrc
!static: qtConfig(quick-designer): include(designer/designer.pri)
qtConfig(quick-designer): include(designer/designer.pri)
include(doc/doc.pri)
CONFIG += no_cxx_module install_qml_files builtin_resources qtquickcompiler

View File

@ -443,7 +443,7 @@ MetaInfo {
version: "2.0"
requiredImport: "QtQuick.Controls"
Property { name: "text"; type: "binding"; value: "qsTr(\"Text Area\")" }
Property { name: "placeholderText"; type: "binding"; value: "qsTr(\"Text Area\")" }
}
}
@ -458,7 +458,7 @@ MetaInfo {
version: "2.0"
requiredImport: "QtQuick.Controls"
Property { name: "text"; type: "binding"; value: "qsTr(\"Text Field\")" }
Property { name: "placeholderText"; type: "binding"; value: "qsTr(\"Text Field\")" }
}
}

View File

@ -0,0 +1,119 @@
/****************************************************************************
**
** Copyright (C) 2020 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.15
import QtQuick.Controls 2.15
import Qt.labs.qmlmodels 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
//! [horizontal]
HorizontalHeaderView {
id: horizontalHeader
syncView: tableView
anchors.left: tableView.left
}
//! [horizontal]
//! [vertical]
VerticalHeaderView {
id: verticalHeader
syncView: tableView
anchors.top: tableView.top
}
//! [vertical]
TableView {
id: tableView
anchors.fill: parent
anchors.topMargin: horizontalHeader.height
anchors.leftMargin: verticalHeader.width
columnSpacing: 1
rowSpacing: 1
clip: true
model: TableModel {
TableModelColumn { display: "name" }
TableModelColumn { display: "color" }
rows: [
{
"name": "cat",
"color": "black"
},
{
"name": "dog",
"color": "brown"
},
{
"name": "bird",
"color": "white"
}
]
}
delegate: Rectangle {
implicitWidth: 100
implicitHeight: 50
border.width: 1
Text {
text: display
anchors.centerIn: parent
}
}
}
}
//![file]

View File

@ -54,22 +54,22 @@ RangeSlider {
}
first.handle: Rectangle {
x: control.leftPadding + first.visualPosition * (control.availableWidth - width)
x: control.leftPadding + control.first.visualPosition * (control.availableWidth - width)
y: control.topPadding + control.availableHeight / 2 - height / 2
implicitWidth: 26
implicitHeight: 26
radius: 13
color: first.pressed ? "#f0f0f0" : "#f6f6f6"
color: control.first.pressed ? "#f0f0f0" : "#f6f6f6"
border.color: "#bdbebf"
}
second.handle: Rectangle {
x: control.leftPadding + second.visualPosition * (control.availableWidth - width)
x: control.leftPadding + control.second.visualPosition * (control.availableWidth - width)
y: control.topPadding + control.availableHeight / 2 - height / 2
implicitWidth: 26
implicitHeight: 26
radius: 13
color: second.pressed ? "#f0f0f0" : "#f6f6f6"
color: control.second.pressed ? "#f0f0f0" : "#f6f6f6"
border.color: "#bdbebf"
}
}

View File

@ -0,0 +1,76 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Templates 2.15 as T
T.HorizontalHeaderView {
id: control
implicitWidth: syncView ? syncView.width : 0
implicitHeight: contentHeight
delegate: Rectangle {
// Qt6: add cellPadding (and font etc) as public API in headerview
readonly property real cellPadding: 8
implicitWidth: text.implicitWidth + (cellPadding * 2)
implicitHeight: Math.max(control.height, text.implicitHeight + (cellPadding * 2))
border.color: "#cacaca"
gradient: Gradient {
GradientStop {
position: 0
color: "#fbfbfb"
}
GradientStop {
position: 1
color: "#e0dfe0"
}
}
Text {
id: text
text: model[control.textRole]
width: parent.width
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "#ff26282a"
}
}
}

View File

@ -0,0 +1,76 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Templates 2.15 as T
T.VerticalHeaderView {
id: control
implicitWidth: contentWidth
implicitHeight: syncView ? syncView.height : 0
delegate: Rectangle {
// Qt6: add cellPadding (and font etc) as public API in headerview
readonly property real cellPadding: 8
implicitWidth: Math.max(control.width, text.implicitWidth + (cellPadding * 2))
implicitHeight: text.implicitHeight + (cellPadding * 2)
border.color: "#cacaca"
gradient: Gradient {
GradientStop {
position: 0
color: "#fbfbfb"
}
GradientStop {
position: 1
color: "#e0dfe0"
}
}
Text {
id: text
text: model[control.textRole]
width: parent.width
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "#ff26282a"
}
}
}

View File

@ -28,6 +28,7 @@ QML_FILES += \
$$PWD/Drawer.qml \
$$PWD/Frame.qml \
$$PWD/GroupBox.qml \
$$PWD/HorizontalHeaderView.qml \
$$PWD/ItemDelegate.qml \
$$PWD/Label.qml \
$$PWD/Menu.qml \
@ -64,4 +65,5 @@ QML_FILES += \
$$PWD/ToolButton.qml \
$$PWD/ToolSeparator.qml \
$$PWD/ToolTip.qml \
$$PWD/Tumbler.qml
$$PWD/Tumbler.qml \
$$PWD/VerticalHeaderView.qml

View File

@ -84,7 +84,7 @@ void QQuickFusionDial::paint(QPainter *painter)
QColor buttonColor = m_palette.button().color();
const bool enabled = isEnabled();
qreal r = qMin(width, height) / 2;
qreal r = qMin(width, height) / 2.0;
r -= r/50;
const qreal penSize = r/20.0;

View File

@ -74,7 +74,7 @@ T.Dial {
transform: [
Translate {
y: -background.height * 0.4 + handle.height / 2
y: -Math.min(control.background.width, control.background.height) * 0.4 + control.handle.height / 2
},
Rotation {
angle: control.angle
@ -89,6 +89,7 @@ T.Dial {
y: control.height / 2 - height / 2
width: Math.max(64, Math.min(control.width, control.height))
height: width
fillMode: Image.PreserveAspectFit
source: Imagine.url + "dial-background"
NinePatchImageSelector on source {

View File

@ -0,0 +1,66 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Templates 2.15 as T
T.HorizontalHeaderView {
id: control
implicitWidth: syncView ? syncView.width : 0
implicitHeight: contentHeight
delegate: Rectangle {
// Qt6: add cellPadding (and font etc) as public API in headerview
readonly property real cellPadding: 8
implicitWidth: text.implicitWidth + (cellPadding * 2)
implicitHeight: Math.max(control.height, text.implicitHeight + (cellPadding * 2))
color: "#f6f6f6"
border.color: "#e4e4e4"
Text {
id: text
text: model[control.textRole]
width: parent.width
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "#ff26282a"
}
}
}

View File

@ -0,0 +1,66 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Templates 2.15 as T
T.VerticalHeaderView {
id: control
implicitWidth: contentWidth
implicitHeight: syncView ? syncView.height : 0
delegate: Rectangle {
// Qt6: add cellPadding (and font etc) as public API in headerview
readonly property real cellPadding: 8
implicitWidth: Math.max(control.width, text.implicitWidth + (cellPadding * 2))
implicitHeight: text.implicitHeight + (cellPadding * 2)
color: "#f6f6f6"
border.color: "#e4e4e4"
Text {
id: text
text: model[control.textRole]
width: parent.width
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "#ff26282a"
}
}
}

View File

@ -12,6 +12,7 @@ QML_FILES += \
$$PWD/Drawer.qml \
$$PWD/Frame.qml \
$$PWD/GroupBox.qml \
$$PWD/HorizontalHeaderView.qml \
$$PWD/ItemDelegate.qml \
$$PWD/Label.qml \
$$PWD/Menu.qml \
@ -44,7 +45,8 @@ QML_FILES += \
$$PWD/ToolButton.qml \
$$PWD/ToolSeparator.qml \
$$PWD/ToolTip.qml \
$$PWD/Tumbler.qml
$$PWD/Tumbler.qml \
$$PWD/VerticalHeaderView.qml
HEADERS += \
$$PWD/qquickimageselector_p.h \

View File

@ -0,0 +1,67 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Templates 2.15 as T
import QtQuick.Controls.Material 2.15
import QtQuick.Controls.Material.impl 2.15
T.HorizontalHeaderView {
id: control
implicitWidth: syncView ? syncView.width : 0
implicitHeight: contentHeight
delegate: Rectangle {
// Qt6: add cellPadding (and font etc) as public API in headerview
readonly property real cellPadding: 8
implicitWidth: text.implicitWidth + (cellPadding * 2)
implicitHeight: Math.max(control.height, text.implicitHeight + (cellPadding * 2))
color: control.Material.backgroundColor
Text {
id: text
text: model[control.textRole]
width: parent.width
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: enabled ? control.Material.foreground : control.Material.hintTextColor
}
}
}

View File

@ -0,0 +1,67 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Templates 2.15 as T
import QtQuick.Controls.Material 2.15
import QtQuick.Controls.Material.impl 2.15
T.VerticalHeaderView {
id: control
implicitWidth: contentWidth
implicitHeight: syncView ? syncView.height : 0
delegate: Rectangle {
// Qt6: add cellPadding (and font etc) as public API in headerview
readonly property real cellPadding: 8
implicitWidth: Math.max(control.width, text.implicitWidth + (cellPadding * 2))
implicitHeight: text.implicitHeight + (cellPadding * 2)
color: control.Material.backgroundColor
Text {
id: text
text: model[control.textRole]
width: parent.width
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: enabled ? control.Material.foreground : control.Material.hintTextColor
}
}
}

View File

@ -30,6 +30,7 @@ QML_FILES += \
$$PWD/ElevationEffect.qml \
$$PWD/Frame.qml \
$$PWD/GroupBox.qml \
$$PWD/HorizontalHeaderView.qml \
$$PWD/ItemDelegate.qml \
$$PWD/Label.qml \
$$PWD/Menu.qml \
@ -68,4 +69,5 @@ QML_FILES += \
$$PWD/ToolButton.qml \
$$PWD/ToolSeparator.qml \
$$PWD/ToolTip.qml \
$$PWD/Tumbler.qml
$$PWD/Tumbler.qml \
$$PWD/VerticalHeaderView.qml

View File

@ -124,7 +124,7 @@ void QQuickDefaultBusyIndicatorNode::sync(QQuickItem *item)
Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
QPointF pos = QPointF(sz / 2 - circleRadius, sz / 2 - circleRadius);
pos = moveCircle(pos, 360 / CircleCount * i, sz / 2 - circleRadius);
pos = moveCircle(pos, 360.0 / CircleCount * i, sz / 2 - circleRadius);
QMatrix4x4 m;
m.translate(dx + pos.x(), dy + pos.y());

View File

@ -59,7 +59,7 @@ static inline qreal blockStartX(int blockIndex)
static inline qreal blockRestX(int blockIndex, qreal availableWidth)
{
const qreal spanRightEdgePos = availableWidth / 2 + BlockSpan / 2;
const qreal spanRightEdgePos = availableWidth / 2 + BlockSpan / 2.0;
return spanRightEdgePos - (blockIndex + 1) * BlockWidth - (blockIndex * BlockRestingSpacing);
}

View File

@ -194,6 +194,10 @@ void QtQuickControls2Plugin::registerTypes(const char *uri)
qmlRegisterUncreatableType<QQuickSplitHandleAttached>(uri, 2, 13, "SplitHandle",
QStringLiteral("SplitHandle is only available as an attached property."));
// QtQuick.Controls 2.15 (new types in Qt 5.15)
qmlRegisterType(resolvedUrl(QStringLiteral("HorizontalHeaderView.qml")), uri, 2, 15, "HorizontalHeaderView");
qmlRegisterType(resolvedUrl(QStringLiteral("VerticalHeaderView.qml")), uri, 2, 15, "VerticalHeaderView");
// The minor version used to be the current Qt 5 minor. For compatibility it is the last
// Qt 5 release.
const QByteArray import = QByteArray(uri) + ".impl";

View File

@ -0,0 +1,68 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Controls.impl 2.15
import QtQuick.Templates 2.15 as T
import QtQuick.Controls.Universal 2.15
import QtQuick.Controls.Universal.impl 2.15
T.HorizontalHeaderView {
id: control
implicitWidth: syncView ? syncView.width : 0
implicitHeight: contentHeight
delegate: Rectangle {
// Qt6: add cellPadding (and font etc) as public API in headerview
readonly property real cellPadding: 8
implicitWidth: text.implicitWidth + (cellPadding * 2)
implicitHeight: Math.max(control.height, text.implicitHeight + (cellPadding * 2))
color: control.Universal.background
Text {
id: text
text: model[control.textRole]
width: parent.width
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2)
}
}
}

View File

@ -0,0 +1,68 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Controls.impl 2.15
import QtQuick.Templates 2.15 as T
import QtQuick.Controls.Universal 2.15
import QtQuick.Controls.Universal.impl 2.15
T.VerticalHeaderView {
id: control
implicitWidth: contentWidth
implicitHeight: syncView ? syncView.height : 0
delegate: Rectangle {
// Qt6: add cellPadding (and font etc) as public API in headerview
readonly property real cellPadding: 8
implicitWidth: Math.max(control.width, text.implicitWidth + (cellPadding * 2))
implicitHeight: text.implicitHeight + (cellPadding * 2)
color: control.Universal.background
Text {
id: text
text: model[control.textRole]
width: parent.width
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2)
}
}
}

View File

@ -13,6 +13,7 @@ QML_FILES += \
$$PWD/Drawer.qml \
$$PWD/Frame.qml \
$$PWD/GroupBox.qml \
$$PWD/HorizontalHeaderView.qml \
$$PWD/ItemDelegate.qml \
$$PWD/Label.qml \
$$PWD/Menu.qml \
@ -48,7 +49,8 @@ QML_FILES += \
$$PWD/ToolButton.qml \
$$PWD/ToolSeparator.qml \
$$PWD/ToolTip.qml \
$$PWD/Tumbler.qml
$$PWD/Tumbler.qml \
$$PWD/VerticalHeaderView.qml
HEADERS += \
$$PWD/qquickuniversalbusyindicator_p.h \

View File

@ -119,7 +119,7 @@ QPlatformDialogHelper *QQuickPlatformDialog::handle() const
*/
QQmlListProperty<QObject> QQuickPlatformDialog::data()
{
return QQmlListProperty<QObject>(this, m_data);
return QQmlListProperty<QObject>(this, &m_data);
}
/*!

View File

@ -623,7 +623,7 @@ static QStringList extractExtensions(const QString &filter)
const int to = filter.lastIndexOf(QLatin1Char(')')) - 1;
if (from >= 0 && from < to) {
const QStringRef ref = filter.midRef(from + 1, to - from);
const QVector<QStringRef> exts = ref.split(QLatin1Char(' '), QString::SkipEmptyParts);
const QVector<QStringRef> exts = ref.split(QLatin1Char(' '), Qt::SkipEmptyParts);
for (const QStringRef &ref : exts)
extensions += extractExtension(ref.toString());
}

View File

@ -56,6 +56,7 @@
#include <QtQuickTemplates2/private/qquickdrawer_p.h>
#include <QtQuickTemplates2/private/qquickframe_p.h>
#include <QtQuickTemplates2/private/qquickgroupbox_p.h>
#include <QtQuickTemplates2/private/qquickheaderview_p.h>
#include <QtQuickTemplates2/private/qquickicon_p.h>
#include <QtQuickTemplates2/private/qquickitemdelegate_p.h>
#include <QtQuickTemplates2/private/qquicklabel_p.h>
@ -357,6 +358,10 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri)
// QtQuick.Templates 2.15 (new types and revisions in Qt 5.15)
qmlRegisterType<QQuickComboBox, 15>(uri, 2, 15, "ComboBox");
// Register QQuickTableView here to expose headerView's base, with a irregular type name to 'hide' it.
qmlRegisterType<QQuickTableView, 15>(uri, 2, 15, "__TableView__");
qmlRegisterType<QQuickHorizontalHeaderView>(uri, 2, 15, "HorizontalHeaderView");
qmlRegisterType<QQuickVerticalHeaderView>(uri, 2, 15, "VerticalHeaderView");
}
QT_END_NAMESPACE

View File

@ -110,7 +110,7 @@ static QStringList envPathList(const QByteArray &var)
QStringList paths;
if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty(var))) {
const QByteArray value = qgetenv(var);
paths += QString::fromLocal8Bit(value).split(QDir::listSeparator(), QString::SkipEmptyParts);
paths += QString::fromLocal8Bit(value).split(QDir::listSeparator(), Qt::SkipEmptyParts);
}
return paths;
}
@ -128,6 +128,7 @@ static QStringList defaultImportPathList()
importPaths += QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
# endif
#endif
importPaths += envPathList("QML2_IMPORT_PATH");
importPaths += QStringLiteral(":/qt-project.org/imports");
importPaths += QCoreApplication::applicationDirPath();
return importPaths;
@ -346,7 +347,7 @@ QStringList QQuickStylePrivate::stylePaths(bool resolve)
} else {
// Fast/simpler path for systems where something other than : is used as
// the list separator (such as ';').
const QStringList customPaths = value.split(listSeparator, QString::SkipEmptyParts);
const QStringList customPaths = value.split(listSeparator, Qt::SkipEmptyParts);
paths += customPaths;
}
}
@ -384,7 +385,13 @@ void QQuickStylePrivate::init(const QUrl &baseUrl)
spec->resolve(baseUrl);
if (!spec->fallbackStyle.isEmpty()) {
QString fallbackStyle = spec->findStyle(QQmlFile::urlToLocalFileOrQrc(baseUrl), spec->fallbackStyle);
QString fallbackStyle;
const QStringList stylePaths = QQuickStylePrivate::stylePaths();
for (const QString &path : stylePaths) {
fallbackStyle = spec->findStyle(path, spec->fallbackStyle);
if (!fallbackStyle.isEmpty())
break;
}
if (fallbackStyle.isEmpty()) {
if (spec->fallbackStyle.compare(QStringLiteral("Default")) != 0) {
qWarning() << "ERROR: unable to locate fallback style" << spec->fallbackStyle;

View File

@ -178,7 +178,7 @@ void QQuickAbstractButtonPrivate::handleRelease(const QPointF &point)
if (wasPressed) {
emit q->released();
if (!wasHeld)
if (!wasHeld && !wasDoubleClick)
trigger();
} else {
emit q->canceled();
@ -188,6 +188,8 @@ void QQuickAbstractButtonPrivate::handleRelease(const QPointF &point)
stopPressRepeat();
else
stopPressAndHold();
wasDoubleClick = false;
}
void QQuickAbstractButtonPrivate::handleUngrab()
@ -201,6 +203,7 @@ void QQuickAbstractButtonPrivate::handleUngrab()
q->setPressed(false);
stopPressRepeat();
stopPressAndHold();
wasDoubleClick = false;
emit q->canceled();
}
@ -1080,8 +1083,10 @@ void QQuickAbstractButton::mousePressEvent(QMouseEvent *event)
void QQuickAbstractButton::mouseDoubleClickEvent(QMouseEvent *event)
{
Q_D(QQuickAbstractButton);
QQuickControl::mouseDoubleClickEvent(event);
emit doubleClicked();
d->wasDoubleClick = true;
}
void QQuickAbstractButton::timerEvent(QTimerEvent *event)

View File

@ -124,6 +124,7 @@ public:
bool autoExclusive = false;
bool autoRepeat = false;
bool wasHeld = false;
bool wasDoubleClick = false;
int holdTimer = 0;
int delayTimer = 0;
int repeatTimer = 0;

View File

@ -1865,6 +1865,14 @@ void QQuickComboBox::wheelEvent(QWheelEvent *event)
}
#endif
bool QQuickComboBox::event(QEvent *e)
{
Q_D(QQuickComboBox);
if (e->type() == QEvent::LanguageChange)
d->updateCurrentText();
return QQuickControl::event(e);
}
void QQuickComboBox::componentComplete()
{
Q_D(QQuickComboBox);

View File

@ -227,6 +227,7 @@ protected:
#if QT_CONFIG(wheelevent)
void wheelEvent(QWheelEvent *event) override;
#endif
bool event(QEvent *e) override;
void componentComplete() override;
void itemChange(ItemChange change, const ItemChangeData &value) override;

View File

@ -180,6 +180,12 @@ bool QQuickControlPrivate::acceptTouch(const QTouchEvent::TouchPoint &point)
return true;
}
// If the control is on a Flickable that has a pressDelay, then the press is never
// sent as a touch event, therefore we need to check for this case.
if (touchId == -1 && pressWasTouch && point.state() == Qt::TouchPointReleased &&
point.pos() == previousPressPos) {
return true;
}
return false;
}
#endif
@ -215,6 +221,8 @@ void QQuickControlPrivate::handleRelease(const QPointF &)
if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && QGuiApplication::styleHints()->setFocusOnTouchRelease())
setActiveFocus(q, Qt::MouseFocusReason);
touchId = -1;
pressWasTouch = false;
previousPressPos = QPointF();
}
void QQuickControlPrivate::handleUngrab()
@ -2121,6 +2129,10 @@ void QQuickControl::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickControl);
d->handlePress(event->localPos());
if (event->source() == Qt::MouseEventSynthesizedByQt) {
d->pressWasTouch = true;
d->previousPressPos = event->localPos();
}
event->accept();
}

View File

@ -230,7 +230,9 @@ public:
bool explicitHoverEnabled = false;
#endif
bool resizingBackground = false;
bool pressWasTouch = false;
int touchId = -1;
QPointF previousPressPos;
qreal padding = 0;
qreal horizontalPadding = 0;
qreal verticalPadding = 0;

View File

@ -455,8 +455,11 @@ void QQuickDialogButtonBoxPrivate::updateLanguage()
qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button, true));
const auto boxAttachedPrivate = QQuickDialogButtonBoxAttachedPrivate::get(attached);
const QPlatformDialogHelper::StandardButton standardButton = boxAttachedPrivate->standardButton;
const QString buttonText = QGuiApplicationPrivate::platformTheme()->standardButtonText(standardButton);
button->setText(QPlatformTheme::removeMnemonics(buttonText));
// The button might be a custom one with explicitly specified text, so we shouldn't change it in that case.
if (standardButton != QPlatformDialogHelper::NoButton) {
const QString buttonText = QGuiApplicationPrivate::platformTheme()->standardButtonText(standardButton);
button->setText(QPlatformTheme::removeMnemonics(buttonText));
}
}
--i;
}

View File

@ -0,0 +1,500 @@
/****************************************************************************
**
** Copyright (C) 2020 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$
**
****************************************************************************/
#include <QtQuickTemplates2/private/qquickheaderview_p_p.h>
#include <algorithm>
/*!
\qmltype HorizontalHeaderView
\inqmlmodule QtQuick.Controls
\ingroup qtquickcontrols2-containers
\inherits TableView
\brief Provides a horizontal header view to accompany a \l TableView.
A HorizontalHeaderView provides labeling of the columns of a \l TableView.
To add a horizontal header to a TableView, bind the
\l {HorizontalHeaderView::syncView} {syncView} property to the TableView:
\snippet qtquickcontrols2-headerview-simple.qml horizontal
The header displays data from the {syncView}'s model by default, but can
also have its own model. If the model is a QAbstractTableModel, then
the header will display the model's horizontal headerData(); otherwise,
the model's data().
*/
/*!
\qmltype VerticalHeaderView
\inqmlmodule QtQuick.Controls
\ingroup qtquickcontrols2-containers
\inherits TableView
\brief Provides a vertical header view to accompany a \l TableView.
A VerticalHeaderView provides labeling of the rows of a \l TableView.
To add a vertical header to a TableView, bind the
\l {VerticalHeaderView::syncView} {syncView} property to the TableView:
\snippet qtquickcontrols2-headerview-simple.qml vertical
The header displays data from the {syncView}'s model by default, but can
also have its own model. If the model is a QAbstractTableModel, then
the header will display the model's vertical headerData(); otherwise,
the model's data().
*/
/*!
\qmlproperty TableView QtQuick::HorizontalHeaderView::syncView
This property holds the TableView to synchronize with.
Once this property is bound to another TableView, both header and table
will synchronize with regard to column widths, column spacing, and flicking
horizontally.
If the \l model is not explicitly set, then the header will use the syncView's
model to label the columns.
\sa model TableView
*/
/*!
\qmlproperty TableView QtQuick::VerticalHeaderView::syncView
This property holds the TableView to synchronize with.
Once this property is bound to another TableView, both header and table
will synchronize with regard to row heights, row spacing, and flicking
vertically.
If the \l model is not explicitly set, then the header will use the syncView's
model to label the rows.
\sa model TableView
*/
/*!
\qmlproperty QVariant QtQuick::HorizontalHeaderView::model
This property holds the model providing data for the horizontal header view.
When model is not explicitly set, the header will use the syncView's
model once syncView is set.
If model is a QAbstractTableModel, its horizontal headerData() will
be accessed.
If model is a QAbstractItemModel other than QAbstractTableModel, model's data()
will be accessed.
Otherwise, the behavior is same as setting TableView::model.
\sa TableView {TableView::model} {model} QAbstractTableModel
*/
/*!
\qmlproperty QVariant QtQuick::VerticalHeaderView::model
This property holds the model providing data for the vertical header view.
When model is not explicitly set, it will be synchronized with syncView's model
once syncView is set.
If model is a QAbstractTableModel, its vertical headerData() will
be accessed.
If model is a QAbstractItemModel other than QAbstractTableModel, model's data()
will be accessed.
Otherwise, the behavior is same as setting TableView::model.
\sa TableView {TableView::model} {model} QAbstractTableModel
*/
/*!
\qmlproperty QString QtQuick::HorizontalHeaderView::textRole
This property holds the model role used to display text in each header cell.
The default value is the \c "display" role.
\sa QAbstractItemModel::roleNames()
*/
/*!
\qmlproperty QString QtQuick::VerticalHeaderView::textRole
This property holds the model role used to display text in each header cell.
The default value is the \c "display" role.
\sa QAbstractItemModel::roleNames()
*/
QT_BEGIN_NAMESPACE
QQuickHeaderViewBasePrivate::QQuickHeaderViewBasePrivate()
: QQuickTableViewPrivate()
{
}
QQuickHeaderViewBasePrivate::~QQuickHeaderViewBasePrivate()
{
}
const QPointer<QQuickItem> QQuickHeaderViewBasePrivate::delegateItemAt(int row, int col) const
{
return loadedTableItem(QPoint(col, row))->item;
}
QVariant QQuickHeaderViewBasePrivate::modelImpl() const
{
if (auto model = m_headerDataProxyModel.sourceModel())
return QVariant::fromValue(model.data());
if (auto model = m_transposeProxyModel.sourceModel())
return QVariant::fromValue(model);
return QQuickTableViewPrivate::modelImpl();
}
template <typename P, typename M>
inline bool proxyModelSetter(QQuickHeaderViewBase *const q, P &proxyModel, M *model)
{
if (model) {
if (model == proxyModel.sourceModel())
return true;
proxyModel.setSourceModel(model);
const auto &modelVariant = QVariant::fromValue(std::addressof(proxyModel));
bool isProxyModelChanged = (modelVariant != QQuickTableViewPrivate::get(q)->QQuickTableViewPrivate::modelImpl());
QQuickTableViewPrivate::get(q)->QQuickTableViewPrivate::setModelImpl(modelVariant);
//Necessary, since TableView's assigned model not changed, but proxy's source changed
if (!isProxyModelChanged)
emit q->modelChanged();
return true;
}
proxyModel.setSourceModel(nullptr);
return false;
}
void QQuickHeaderViewBasePrivate::setModelImpl(const QVariant &newModel)
{
Q_Q(QQuickHeaderViewBase);
m_modelExplicitlySetByUser = true;
// Case 1: newModel is QAbstractTableModel
if (proxyModelSetter(q, m_headerDataProxyModel, newModel.value<QAbstractTableModel *>()))
return;
// Case 2: newModel is QAbstractItemModel but not QAbstractTableModel
if (orientation() == Qt::Horizontal
&& proxyModelSetter(q, m_transposeProxyModel, newModel.value<QAbstractItemModel *>()))
return;
QQuickTableViewPrivate::setModelImpl(newModel);
}
void QQuickHeaderViewBasePrivate::syncModel()
{
Q_Q(QQuickHeaderViewBase);
if (assignedSyncView && !m_modelExplicitlySetByUser) {
auto newModel = assignedSyncView->model();
if (auto m = newModel.value<QAbstractTableModel *>()) {
proxyModelSetter(q, m_headerDataProxyModel, m);
} else if (orientation() == Qt::Horizontal) {
if (auto m = newModel.value<QAbstractItemModel *>())
proxyModelSetter(q, m_transposeProxyModel, m);
} else {
QQuickTableViewPrivate::setModelImpl(newModel);
}
}
QQuickTableViewPrivate::syncModel();
}
void QQuickHeaderViewBasePrivate::syncSyncView()
{
Q_Q(QQuickHeaderViewBase);
if (assignedSyncDirection != orientation()) {
qmlWarning(q_func()) << "Setting syncDirection other than Qt::"
<< QVariant::fromValue(orientation()).toString()
<< " is invalid.";
assignedSyncDirection = orientation();
}
if (assignedSyncView) {
QBoolBlocker fixupGuard(inUpdateContentSize, true);
if (orientation() == Qt::Horizontal) {
q->setLeftMargin(assignedSyncView->leftMargin());
q->setRightMargin(assignedSyncView->rightMargin());
} else {
q->setTopMargin(assignedSyncView->topMargin());
q->setBottomMargin(assignedSyncView->bottomMargin());
}
}
QQuickTableViewPrivate::syncSyncView();
}
QQuickHeaderViewBase::QQuickHeaderViewBase(Qt::Orientation orient, QQuickItem *parent)
: QQuickTableView(*(new QQuickHeaderViewBasePrivate), parent)
{
d_func()->setOrientation(orient);
setSyncDirection(orient);
}
QQuickHeaderViewBase::QQuickHeaderViewBase(QQuickHeaderViewBasePrivate &dd, QQuickItem *parent)
: QQuickTableView(dd, parent)
{
}
QQuickHeaderViewBase::~QQuickHeaderViewBase()
{
}
QString QQuickHeaderViewBase::textRole() const
{
Q_D(const QQuickHeaderViewBase);
return d->m_textRole;
}
void QQuickHeaderViewBase::setTextRole(const QString &role)
{
Q_D(QQuickHeaderViewBase);
if (d->m_textRole == role)
return;
d->m_textRole = role;
emit textRoleChanged();
}
Qt::Orientation QQuickHeaderViewBasePrivate::orientation() const
{
return m_headerDataProxyModel.orientation();
}
void QQuickHeaderViewBasePrivate::setOrientation(Qt::Orientation orientation)
{
if (QQuickHeaderViewBasePrivate::orientation() == orientation)
return;
m_headerDataProxyModel.setOrientation(orientation);
}
QQuickVerticalHeaderView::QQuickVerticalHeaderView(QQuickVerticalHeaderViewPrivate &dd, QQuickItem *parent)
: QQuickHeaderViewBase(dd, parent)
{
}
/*! \internal
\class QHeaderDataProxyModel
\brief
QHeaderDataProxyModel is a proxy AbstractItemModel type that maps
source model's headerData() to correspondent data()
*/
QHeaderDataProxyModel::QHeaderDataProxyModel(QObject *parent)
: QAbstractItemModel(parent)
{
}
QHeaderDataProxyModel::~QHeaderDataProxyModel() = default;
void QHeaderDataProxyModel::setSourceModel(QAbstractItemModel *newSourceModel)
{
if (m_model == newSourceModel)
return;
beginResetModel();
disconnectFromModel();
m_model = newSourceModel;
connectToModel();
endResetModel();
}
QModelIndex QHeaderDataProxyModel::index(int row, int column, const QModelIndex &parent) const
{
return hasIndex(row, column, parent) ? createIndex(row, column) : QModelIndex();
}
QModelIndex QHeaderDataProxyModel::parent(const QModelIndex &child) const
{
Q_UNUSED(child)
return QModelIndex();
}
QModelIndex QHeaderDataProxyModel::sibling(int row, int column, const QModelIndex &idx) const
{
return index(row, column, idx);
}
int QHeaderDataProxyModel::rowCount(const QModelIndex &parent) const
{
return m_model.isNull() ? -1 : (m_orientation == Qt::Horizontal ? 1 : m_model->rowCount(parent));
}
int QHeaderDataProxyModel::columnCount(const QModelIndex &parent) const
{
return m_model.isNull() ? -1 : (m_orientation == Qt::Vertical ? 1 : m_model->columnCount(parent));
}
QVariant QHeaderDataProxyModel::data(const QModelIndex &index, int role) const
{
if (m_model.isNull())
return QVariant();
if (!hasIndex(index.row(), index.column()))
return QModelIndex();
auto section = m_orientation == Qt::Vertical ? index.row() : index.column();
return m_model->headerData(section, m_orientation, role);
}
bool QHeaderDataProxyModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!hasIndex(index.row(), index.column()))
return false;
auto section = m_orientation == Qt::Vertical ? index.row() : index.column();
auto ret = m_model->setHeaderData(section, m_orientation, value, role);
emit dataChanged(index, index, { role });
return ret;
}
bool QHeaderDataProxyModel::hasChildren(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return false;
}
QVariant QHeaderDataProxyModel::variantValue() const
{
return QVariant::fromValue(static_cast<QObject *>(const_cast<QHeaderDataProxyModel *>(this)));
}
void QHeaderDataProxyModel::setOrientation(Qt::Orientation o)
{
if (o == m_orientation)
return;
beginResetModel();
m_orientation = o;
endResetModel();
}
Qt::Orientation QHeaderDataProxyModel::orientation() const
{
return m_orientation;
}
QPointer<QAbstractItemModel> QHeaderDataProxyModel::sourceModel() const
{
return m_model;
}
void QHeaderDataProxyModel::connectToModel()
{
if (m_model.isNull())
return;
connect(m_model, &QAbstractItemModel::headerDataChanged,
[this](Qt::Orientation orient, int first, int last) {
if (orient != orientation())
return;
if (orient == Qt::Horizontal) {
emit dataChanged(createIndex(0, first), createIndex(0, last));
} else {
emit dataChanged(createIndex(first, 0), createIndex(last, 0));
}
});
connect(m_model, &QAbstractItemModel::modelAboutToBeReset,
this, &QHeaderDataProxyModel::modelAboutToBeReset, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::modelReset,
this, &QHeaderDataProxyModel::modelReset, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::rowsAboutToBeMoved,
this, &QHeaderDataProxyModel::rowsAboutToBeMoved, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::rowsMoved,
this, &QHeaderDataProxyModel::rowsMoved, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::rowsAboutToBeInserted,
this, &QHeaderDataProxyModel::rowsAboutToBeInserted, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::rowsInserted,
this, &QHeaderDataProxyModel::rowsInserted, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::rowsAboutToBeRemoved,
this, &QHeaderDataProxyModel::rowsAboutToBeRemoved, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::rowsRemoved,
this, &QHeaderDataProxyModel::rowsRemoved, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::columnsAboutToBeMoved,
this, &QHeaderDataProxyModel::columnsAboutToBeMoved, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::columnsMoved,
this, &QHeaderDataProxyModel::columnsMoved, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::columnsAboutToBeInserted,
this, &QHeaderDataProxyModel::columnsAboutToBeInserted, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::columnsInserted,
this, &QHeaderDataProxyModel::columnsInserted, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::columnsAboutToBeRemoved,
this, &QHeaderDataProxyModel::columnsAboutToBeRemoved, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::columnsRemoved,
this, &QHeaderDataProxyModel::columnsRemoved, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::layoutAboutToBeChanged,
this, &QHeaderDataProxyModel::layoutAboutToBeChanged, Qt::UniqueConnection);
connect(m_model, &QAbstractItemModel::layoutChanged,
this, &QHeaderDataProxyModel::layoutChanged, Qt::UniqueConnection);
}
void QHeaderDataProxyModel::disconnectFromModel()
{
if (m_model.isNull())
return;
m_model->disconnect(this);
}
QQuickHorizontalHeaderView::QQuickHorizontalHeaderView(QQuickItem *parent)
: QQuickHeaderViewBase(Qt::Horizontal, parent)
{
setFlickableDirection(FlickableDirection::HorizontalFlick);
}
QQuickHorizontalHeaderView::~QQuickHorizontalHeaderView()
{
}
QQuickVerticalHeaderView::QQuickVerticalHeaderView(QQuickItem *parent)
: QQuickHeaderViewBase(Qt::Vertical, parent)
{
setFlickableDirection(FlickableDirection::VerticalFlick);
}
QQuickVerticalHeaderView::~QQuickVerticalHeaderView()
{
}
QQuickHorizontalHeaderViewPrivate::QQuickHorizontalHeaderViewPrivate() = default;
QQuickHorizontalHeaderViewPrivate::~QQuickHorizontalHeaderViewPrivate() = default;
QQuickVerticalHeaderViewPrivate::QQuickVerticalHeaderViewPrivate() = default;
QQuickVerticalHeaderViewPrivate::~QQuickVerticalHeaderViewPrivate() = default;
QT_END_NAMESPACE

View File

@ -0,0 +1,125 @@
/****************************************************************************
**
** Copyright (C) 2020 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$
**
****************************************************************************/
#ifndef QQUICKHEADERVIEW_P_H
#define QQUICKHEADERVIEW_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <private/qquicktableview_p.h>
#include <private/qtquicktemplates2global_p.h>
QT_BEGIN_NAMESPACE
class QQuickHeaderViewBase;
class QQuickHeaderViewBasePrivate;
class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickHeaderViewBase : public QQuickTableView
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickHeaderViewBase)
Q_PROPERTY(QString textRole READ textRole WRITE setTextRole NOTIFY textRoleChanged FINAL)
public:
explicit QQuickHeaderViewBase(Qt::Orientation orient, QQuickItem *parent = nullptr);
~QQuickHeaderViewBase();
QString textRole() const;
void setTextRole(const QString &role);
protected:
QQuickHeaderViewBase(QQuickHeaderViewBasePrivate &dd, QQuickItem *parent);
Q_SIGNALS:
void textRoleChanged();
private:
Q_DISABLE_COPY(QQuickHeaderViewBase)
friend class QQuickHorizontalHeaderView;
friend class QQuickVerticalHeaderView;
};
class QQuickHorizontalHeaderViewPrivate;
class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickHorizontalHeaderView : public QQuickHeaderViewBase
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickHorizontalHeaderView)
public:
QQuickHorizontalHeaderView(QQuickItem *parent = nullptr);
~QQuickHorizontalHeaderView() override;
protected:
QQuickHorizontalHeaderView(QQuickHorizontalHeaderViewPrivate &dd, QQuickItem *parent);
private:
Q_DISABLE_COPY(QQuickHorizontalHeaderView)
};
class QQuickVerticalHeaderViewPrivate;
class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickVerticalHeaderView : public QQuickHeaderViewBase
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickVerticalHeaderView)
public:
QQuickVerticalHeaderView(QQuickItem *parent = nullptr);
~QQuickVerticalHeaderView() override;
protected:
QQuickVerticalHeaderView(QQuickVerticalHeaderViewPrivate &dd, QQuickItem *parent);
private:
Q_DISABLE_COPY(QQuickVerticalHeaderView)
};
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickHorizontalHeaderView)
QML_DECLARE_TYPE(QQuickVerticalHeaderView)
#endif // QQUICKHEADERVIEW_P_H

View File

@ -0,0 +1,136 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QQUICKHEADERVIEW_P_P_H
#define QQUICKHEADERVIEW_P_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/QAbstractItemModel>
#include <QtCore/QPointer>
#include <QtCore/QTransposeProxyModel>
#include <QtQuick/private/qquicktableview_p_p.h>
#include <private/qquickheaderview_p.h>
QT_BEGIN_NAMESPACE
class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QHeaderDataProxyModel : public QAbstractItemModel
{
Q_OBJECT
Q_DISABLE_COPY(QHeaderDataProxyModel)
Q_PROPERTY(QAbstractItemModel *sourceModel READ sourceModel)
public:
explicit QHeaderDataProxyModel(QObject *parent = nullptr);
~QHeaderDataProxyModel();
void setSourceModel(QAbstractItemModel *newSourceModel);
QPointer<QAbstractItemModel> sourceModel() const;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &child) const override;
QModelIndex sibling(int row, int column, const QModelIndex &idx) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
inline QVariant variantValue() const;
inline Qt::Orientation orientation() const;
inline void setOrientation(Qt::Orientation o);
private:
inline void connectToModel();
inline void disconnectFromModel();
QPointer<QAbstractItemModel> m_model = nullptr;
Qt::Orientation m_orientation = Qt::Horizontal;
};
class QQuickHeaderViewBasePrivate : public QQuickTableViewPrivate
{
Q_DECLARE_PUBLIC(QQuickHeaderViewBase)
public:
QQuickHeaderViewBasePrivate();
~QQuickHeaderViewBasePrivate();
Qt::Orientation orientation() const;
void setOrientation(Qt::Orientation orientation);
const QPointer<QQuickItem> delegateItemAt(int row, int col) const;
QVariant modelImpl() const override;
void setModelImpl(const QVariant &newModel) override;
void syncModel() override;
void syncSyncView() override;
protected:
QHeaderDataProxyModel m_headerDataProxyModel;
QTransposeProxyModel m_transposeProxyModel;
struct SectionSize
{
int section;
qreal previousSize;
};
QStack<SectionSize> m_hiddenSectionSizes;
bool m_modelExplicitlySetByUser = false;
QString m_textRole = QStringLiteral("display");
};
class QQuickHorizontalHeaderViewPrivate : public QQuickHeaderViewBasePrivate
{
Q_DECLARE_PUBLIC(QQuickHorizontalHeaderView)
public:
QQuickHorizontalHeaderViewPrivate();
~QQuickHorizontalHeaderViewPrivate();
};
class QQuickVerticalHeaderViewPrivate : public QQuickHeaderViewBasePrivate
{
Q_DECLARE_PUBLIC(QQuickVerticalHeaderView)
public:
QQuickVerticalHeaderViewPrivate();
~QQuickVerticalHeaderViewPrivate();
};
QT_END_NAMESPACE
#endif // QQUICKHEADERVIEW_P_P_H

View File

@ -252,9 +252,18 @@ void QQuickToolTip::setVisible(bool visible)
{
Q_D(QQuickToolTip);
if (visible) {
if (!d->visible && d->delay > 0) {
d->startDelay();
return;
if (!d->visible) {
// We are being made visible, and we weren't before.
if (d->delay > 0) {
d->startDelay();
return;
}
} else {
// We are being made visible, even though we already were.
// We've probably been re-opened before our exit transition could finish.
// In that case, we need to manually start the timeout, as that is usually
// done in itemChange(), which won't be called in this situation.
d->startTimeout();
}
} else {
d->stopDelay();
@ -557,8 +566,9 @@ void QQuickToolTipAttached::hide()
QQuickToolTip *tip = d->instance(false);
if (!tip)
return;
tip->close();
// check the parent item to prevent unexpectedly closing tooltip by new created invisible tooltip
if (parent() == tip->parentItem())
tip->close();
}
QT_END_NAMESPACE

View File

@ -31,6 +31,8 @@ HEADERS += \
$$PWD/qquickframe_p.h \
$$PWD/qquickframe_p_p.h \
$$PWD/qquickgroupbox_p.h \
$$PWD/qquickheaderview_p.h \
$$PWD/qquickheaderview_p_p.h \
$$PWD/qquickicon_p.h \
$$PWD/qquickitemdelegate_p.h \
$$PWD/qquickitemdelegate_p_p.h \
@ -120,6 +122,7 @@ SOURCES += \
$$PWD/qquickdrawer.cpp \
$$PWD/qquickframe.cpp \
$$PWD/qquickgroupbox.cpp \
$$PWD/qquickheaderview.cpp \
$$PWD/qquickicon.cpp \
$$PWD/qquickitemdelegate.cpp \
$$PWD/qquicklabel.cpp \

View File

@ -14,6 +14,7 @@ SUBDIRS += \
qquickapplicationwindow \
qquickcolor \
qquickdrawer \
qquickheaderview \
qquickiconimage \
qquickiconlabel \
qquickimaginestyle \
@ -29,7 +30,5 @@ SUBDIRS += \
qquickuniversalstyleconf \
revisions \
sanity \
snippets
# Requires lrelease, which isn't always available in CI.
qtHaveModule(tools): translation
snippets \
translation

View File

@ -887,4 +887,27 @@ TestCase {
mouseRelease(control)
compare(clickedSpy.count, 1)
}
function test_doubleClick() {
let control = createTemporaryObject(button, testCase, { text: "Hello" })
verify(control)
let pressedSpy = signalSpy.createObject(control, { target: control, signalName: "pressed" })
verify(pressedSpy.valid)
let releasedSpy = signalSpy.createObject(control, { target: control, signalName: "released" })
verify(releasedSpy.valid)
let clickedSpy = signalSpy.createObject(control, { target: control, signalName: "clicked" })
verify(clickedSpy.valid)
let doubleClickedSpy = signalSpy.createObject(control, { target: control, signalName: "doubleClicked" })
verify(doubleClickedSpy.valid)
mouseDoubleClickSequence(control)
compare(pressedSpy.count, 2)
compare(releasedSpy.count, 2)
compare(clickedSpy.count, 1)
compare(doubleClickedSpy.count, 1)
}
}

View File

@ -152,8 +152,7 @@ TestCase {
"doubleClicked",
["pressedChanged", { "pressed": false }],
["downChanged", { "down": false }],
"released",
"clicked"]
"released"]
mouseDoubleClickSequence(control, control.width / 2, control.height / 2, Qt.LeftButton)
verify(sequenceSpy.success)
}

View File

@ -173,8 +173,7 @@ TestCase {
"doubleClicked",
["pressedChanged", { "pressed": false }],
["downChanged", { "down": false }],
"released",
"clicked"]
"released"]
mouseDoubleClickSequence(control, control.width / 2, control.height / 2, Qt.LeftButton)
verify(sequenceSpy.success)
}

View File

@ -654,8 +654,7 @@ TestCase {
"pressed",
"doubleClicked",
["pressedChanged", { "pressed": false }],
"released",
"clicked"
"released"
];
mouseDoubleClickSequence(control, control.width / 2, control.height / 2, Qt.LeftButton);
verify(mouseSignalSequenceSpy.success);

View File

@ -227,15 +227,46 @@ TestCase {
id: toolTipWithExitTransition
ToolTip {
Component.onCompleted: contentItem.objectName = "contentItem"
enter: Transition {
NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 100 }
}
exit: Transition {
NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 1000 }
NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 500 }
}
}
}
function test_openDuringExitTransitionWithTimeout() {
let control = createTemporaryObject(toolTipWithExitTransition, testCase, { timeout: 250 })
verify(control)
let openedSpy = signalSpy.createObject(control, { target: control, signalName: "opened" })
verify(openedSpy.valid)
control.open()
verify(control.visible)
// Can't be fully open yet because the enter transition has only just started.
compare(control.opened, false)
compare(control.enter.running, true)
// Wait for it to have opened. We don't check that the opened property is still true
// because it can result in hard-to-reproduce flakiness. Instead we just check that
// it was opened at some point.
tryCompare(openedSpy, "count", 1)
// Let it timeout and begin the exit transition.
tryCompare(control, "opened", false)
verify(control.visible)
tryCompare(control.exit, "running", true)
verify(control.visible)
// Quickly open it again; it should still timeout eventually.
control.open()
tryCompare(openedSpy, "count", 2)
tryCompare(control.exit, "running", true)
}
function test_makeVisibleWhileExitTransitionRunning_data() {
return [
{ tag: "imperative", imperative: true },

View File

@ -311,7 +311,7 @@ void tst_customization::creation()
QVERIFY2(qt_createdQObjects()->removeOne(controlName), qPrintable(controlName + " was not created as expected"));
for (QString delegate : qAsConst(delegates)) {
QStringList properties = delegate.split(".", QString::SkipEmptyParts);
QStringList properties = delegate.split(".", Qt::SkipEmptyParts);
// <control>-<delegate>-<style>(-<override>)
delegate.append("-" + style);
@ -412,7 +412,7 @@ void tst_customization::override()
QVERIFY2(qt_createdQObjects()->removeOne(controlName), qPrintable(controlName + " was not created as expected"));
for (QString delegate : qAsConst(delegates)) {
QStringList properties = delegate.split(".", QString::SkipEmptyParts);
QStringList properties = delegate.split(".", Qt::SkipEmptyParts);
// <control>-<delegate>-<style>(-override)
delegate.append("-" + style);

View File

@ -0,0 +1,71 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite 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.14
import QtQuick.Controls 2.14
ApplicationWindow {
width: 400
height: 400
property alias flickable: flickable
property alias button: button
Flickable {
id: flickable
width: 300
height: 400
pressDelay: 50
Button {
id: button
text: "This is a test button"
}
}
}

View File

@ -0,0 +1,14 @@
CONFIG += testcase
TARGET = tst_qquickcontrol
SOURCES += tst_qquickcontrol.cpp
macos:CONFIG -= app_bundle
QT += core-private gui-private qml-private quick-private testlib quicktemplates2-private
include (../shared/util.pri)
TESTDATA = data/*
OTHER_FILES += \
data/*.qml

View File

@ -0,0 +1,110 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/qtest.h>
#include <QtTest/qsignalspy.h>
#include "../shared/util.h"
#include "../shared/visualtestutil.h"
#include "../shared/qtest_quickcontrols.h"
#include <QtGui/qpa/qwindowsysteminterface.h>
#include <QtQuickTemplates2/private/qquickbutton_p.h>
using namespace QQuickVisualTestUtil;
class tst_QQuickControl : public QQmlDataTest
{
Q_OBJECT
private slots:
void initTestCase();
void flickable();
private:
struct TouchDeviceDeleter
{
static inline void cleanup(QTouchDevice *device)
{
QWindowSystemInterface::unregisterTouchDevice(device);
delete device;
}
};
QScopedPointer<QTouchDevice, TouchDeviceDeleter> touchDevice;
};
void tst_QQuickControl::initTestCase()
{
QQmlDataTest::initTestCase();
qputenv("QML_NO_TOUCH_COMPRESSION", "1");
touchDevice.reset(new QTouchDevice);
touchDevice->setType(QTouchDevice::TouchScreen);
QWindowSystemInterface::registerTouchDevice(touchDevice.data());
}
void tst_QQuickControl::flickable()
{
// Check that when a Button that is inside a Flickable with a pressDelay
// still gets the released and clicked signals sent due to the fact that
// Flickable sends a mouse event for the delay and not a touch event
QQuickApplicationHelper helper(this, QStringLiteral("flickable.qml"));
QQuickWindow *window = helper.window;
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window));
QQuickButton *button = window->property("button").value<QQuickButton *>();
QVERIFY(button);
QSignalSpy buttonPressedSpy(button, SIGNAL(pressed()));
QVERIFY(buttonPressedSpy.isValid());
QSignalSpy buttonReleasedSpy(button, SIGNAL(released()));
QVERIFY(buttonReleasedSpy.isValid());
QSignalSpy buttonClickedSpy(button, SIGNAL(clicked()));
QVERIFY(buttonClickedSpy.isValid());
QTest::touchEvent(window, touchDevice.data()).press(0, QPoint(button->width() / 2, button->height() / 2));
QTRY_COMPARE(buttonPressedSpy.count(), 1);
QTest::touchEvent(window, touchDevice.data()).release(0, QPoint(button->width() / 2, button->height() / 2));
QTRY_COMPARE(buttonReleasedSpy.count(), 1);
QTRY_COMPARE(buttonClickedSpy.count(), 1);
}
QTEST_QUICKCONTROLS_MAIN(tst_QQuickControl)
#include "tst_qquickcontrol.moc"

View File

@ -0,0 +1,121 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite 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.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import TestTableModel 0.1
import TestTableModelWithHeader 0.1
import HeaderDataProxyModel 0.1
Window {
objectName: "window"
width: 400
height: 400
visible: true
Component {
id: cellDelegate
Rectangle {
implicitHeight: 25
implicitWidth: 50
color: "red"
Text {
text: row + "," + column
}
}
}
HeaderDataProxyModel {
id: pm
objectName: "proxyModel"
}
TestTableModel {
id: tm
objectName: "tableModel"
rowCount: 5
columnCount: 10
}
TestTableModelWithHeader {
id: thm
objectName: "tableHeaderModel"
rowCount: 5
columnCount: 10
}
HorizontalHeaderView {
id: hhv
objectName: "horizontalHeader"
width: 200
height: 200
model: thm
delegate: cellDelegate
}
VerticalHeaderView {
id: vhv
objectName: "verticalHeader"
width: 200
height: 200
model: thm
delegate: cellDelegate
}
TableView {
id: tv
objectName: "tableView"
width: 400
height: 400
model: thm
delegate:cellDelegate
}
}

View File

@ -0,0 +1,15 @@
CONFIG += testcase
TARGET = tst_qquickheaderview
SOURCES += tst_qquickheaderview.cpp
macos:CONFIG -= app_bundle
QT += core-private gui-private qml-private quick-private testlib quickcontrols2 \
quickcontrols2-private quicktemplates2-private quicktemplates2
include (../shared/util.pri)
TESTDATA = data/*
OTHER_FILES += \
data/*.qml

View File

@ -0,0 +1,354 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "../shared/qtest_quickcontrols.h"
#include "../shared/util.h"
#include <QtTest/qsignalspy.h>
#include <QtTest/qtest.h>
#include <QAbstractItemModelTester>
#include <QtQml/QQmlEngine>
#include <QtQuick/private/qquickwindow_p.h>
#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
#include <QtQuickTemplates2/private/qquickheaderview_p.h>
#include <private/qquickheaderview_p_p.h>
class TestTableModel : public QAbstractTableModel {
Q_OBJECT
Q_PROPERTY(int rowCount READ rowCount WRITE setRowCount NOTIFY rowCountChanged)
Q_PROPERTY(int columnCount READ columnCount WRITE setColumnCount NOTIFY columnCountChanged)
public:
TestTableModel(QObject *parent = nullptr)
: QAbstractTableModel(parent)
{
}
int rowCount(const QModelIndex & = QModelIndex()) const override
{
return m_rows;
}
virtual void setRowCount(int count)
{
beginResetModel();
m_rows = count;
emit rowCountChanged();
endResetModel();
}
int columnCount(const QModelIndex & = QModelIndex()) const override
{
return m_cols;
}
virtual void setColumnCount(int count)
{
beginResetModel();
m_cols = count;
emit columnCountChanged();
endResetModel();
}
int indexValue(const QModelIndex &index) const
{
return index.row() + (index.column() * rowCount());
}
Q_INVOKABLE QModelIndex toQModelIndex(int serialIndex)
{
return createIndex(serialIndex % rowCount(), serialIndex / rowCount());
}
Q_INVOKABLE QVariant data(int row, int col)
{
return data(createIndex(row, col), Qt::DisplayRole);
}
QVariant data(const QModelIndex &index, int role) const override
{
if (!index.isValid())
return QVariant();
switch (role) {
case Qt::DisplayRole:
return QString("%1, %2, checked: %3 ")
.arg(index.row())
.arg(index.column())
.arg(m_checkedCells.contains(indexValue(index)));
case Qt::EditRole:
return m_checkedCells.contains(indexValue(index));
default:
return QVariant();
}
}
bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole) override
{
if (role != Qt::EditRole)
return false;
int i = indexValue(index);
bool checked = value.toBool();
if (checked == m_checkedCells.contains(i))
return false;
if (checked)
m_checkedCells.insert(i);
else
m_checkedCells.remove(i);
emit dataChanged(index, index, { role });
return true;
}
Q_INVOKABLE QHash<int, QByteArray> roleNames() const override
{
return {
{ Qt::DisplayRole, "display" },
{ Qt::EditRole, "edit" }
};
}
signals:
void rowCountChanged();
void columnCountChanged();
private:
int m_rows = 0;
int m_cols = 0;
QSet<int> m_checkedCells;
};
class TestTableModelWithHeader : public TestTableModel {
Q_OBJECT
public:
void setRowCount(int count) override
{
vData.resize(count);
TestTableModel::setRowCount(count);
}
void setColumnCount(int count) override
{
hData.resize(count);
TestTableModel::setColumnCount(count);
}
Q_INVOKABLE QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override
{
auto sectionCount = orientation == Qt::Horizontal ? columnCount() : rowCount();
if (section < 0 || section >= sectionCount)
return QVariant();
switch (role) {
case Qt::DisplayRole:
case Qt::EditRole: {
auto &data = orientation == Qt::Horizontal ? hData : vData;
return data[section].toString();
}
default:
return QVariant();
}
}
Q_INVOKABLE bool setHeaderData(int section, Qt::Orientation orientation,
const QVariant &value, int role = Qt::EditRole) override
{
qDebug() << Q_FUNC_INFO
<< "section:" << section
<< "orient:" << orientation
<< "value:" << value
<< "role:" << QAbstractItemModel::roleNames()[role];
auto sectionCount = orientation == Qt::Horizontal ? columnCount() : rowCount();
if (section < 0 || section >= sectionCount)
return false;
auto &data = orientation == Qt::Horizontal ? hData : vData;
data[section] = value;
emit headerDataChanged(orientation, section, section);
return true;
}
private:
QVector<QVariant> hData, vData;
};
class tst_QQuickHeaderView : public QQmlDataTest {
Q_OBJECT
private slots:
void initTestCase() override;
void cleanupTestCase();
void init();
void cleanup();
void defaults();
void testHeaderDataProxyModel();
void testOrientation();
void testModel();
private:
QQmlEngine *engine;
QString errorString;
std::unique_ptr<QObject> rootObjectFromQml(const char *file)
{
auto component = new QQmlComponent(engine);
component->loadUrl(testFileUrl(file));
auto root = component->create();
if (!root)
errorString = component->errorString();
return std::unique_ptr<QObject>(new QObject(root));
}
};
void tst_QQuickHeaderView::initTestCase()
{
QQmlDataTest::initTestCase();
qmlRegisterType<TestTableModel>("TestTableModel", 0, 1, "TestTableModel");
qmlRegisterType<TestTableModelWithHeader>("TestTableModelWithHeader", 0, 1, "TestTableModelWithHeader");
qmlRegisterType<QHeaderDataProxyModel>("HeaderDataProxyModel", 0, 1, "HeaderDataProxyModel");
}
void tst_QQuickHeaderView::cleanupTestCase()
{
}
void tst_QQuickHeaderView::init()
{
engine = new QQmlEngine(this);
}
void tst_QQuickHeaderView::cleanup()
{
if (engine) {
delete engine;
engine = nullptr;
}
}
void tst_QQuickHeaderView::defaults()
{
QQmlComponent component(engine);
component.loadUrl(testFileUrl("Window.qml"));
QScopedPointer<QObject> root(component.create());
QVERIFY2(root, qPrintable(component.errorString()));
auto hhv = root->findChild<QQuickHorizontalHeaderView *>("horizontalHeader");
QVERIFY(hhv);
auto vhv = root->findChild<QQuickVerticalHeaderView *>("verticalHeader");
QVERIFY(vhv);
auto tm = root->findChild<TestTableModel *>("tableModel");
QVERIFY(tm);
auto pm = root->findChild<QHeaderDataProxyModel *>("proxyModel");
QVERIFY(pm);
auto tv = root->findChild<QQuickTableView *>("tableView");
QVERIFY(tv);
}
void tst_QQuickHeaderView::testHeaderDataProxyModel()
{
TestTableModel model;
model.setColumnCount(10);
model.setRowCount(7);
QHeaderDataProxyModel model2;
model2.setSourceModel(&model);
QAbstractItemModelTester tester(&model2, QAbstractItemModelTester::FailureReportingMode::QtTest);
}
void tst_QQuickHeaderView::testOrientation()
{
QQmlComponent component(engine);
component.loadUrl(testFileUrl("Window.qml"));
QScopedPointer<QObject> root(component.create());
QVERIFY2(root, qPrintable(component.errorString()));
auto hhv = root->findChild<QQuickHorizontalHeaderView *>("horizontalHeader");
QVERIFY(hhv);
QCOMPARE(hhv->columns(), 10);
QCOMPARE(hhv->rows(), 1);
auto vhv = root->findChild<QQuickVerticalHeaderView *>("verticalHeader");
QVERIFY(vhv);
hhv->setSyncDirection(Qt::Vertical);
hhv->flick(10, 20);
vhv->setSyncDirection(Qt::Horizontal);
vhv->flick(20, 10);
QVERIFY(QTest::qWaitForWindowActive(qobject_cast<QWindow *>(root.data())));
// Explicitly setting a different synDirection is ignored
QCOMPARE(hhv->syncDirection(), Qt::Horizontal);
QCOMPARE(hhv->flickableDirection(), QQuickFlickable::HorizontalFlick);
QCOMPARE(vhv->syncDirection(), Qt::Vertical);
QCOMPARE(vhv->flickableDirection(), QQuickFlickable::VerticalFlick);
}
void tst_QQuickHeaderView::testModel()
{
QQmlComponent component(engine);
component.loadUrl(testFileUrl("Window.qml"));
QScopedPointer<QObject> root(component.create());
QVERIFY2(root, qPrintable(component.errorString()));
auto hhv = root->findChild<QQuickHorizontalHeaderView *>("horizontalHeader");
QVERIFY(hhv);
auto thm = root->findChild<TestTableModel *>("tableHeaderModel");
QVERIFY(thm);
auto pm = root->findChild<QHeaderDataProxyModel *>("proxyModel");
QVERIFY(pm);
QSignalSpy modelChangedSpy(hhv, SIGNAL(modelChanged()));
QVERIFY(modelChangedSpy.isValid());
hhv->setModel(QVariant::fromValue(thm));
QCOMPARE(modelChangedSpy.count(), 0);
hhv->setModel(QVariant::fromValue(pm));
QCOMPARE(modelChangedSpy.count(), 1);
TestTableModel ttm2;
ttm2.setRowCount(100);
ttm2.setColumnCount(30);
hhv->setModel(QVariant::fromValue(&ttm2));
QCOMPARE(modelChangedSpy.count(), 2);
}
QTEST_MAIN(tst_QQuickHeaderView)
#include "tst_qquickheaderview.moc"

View File

@ -0,0 +1,28 @@
import QtQuick 2.13
import QtQuick.Window 2.13
import QtQuick.Controls 2.13
Window {
width: 400
height: 400
property alias mouseArea: mouseArea
property alias loader: loader
MouseArea {
id: mouseArea
property bool isToolTipVisible: false
width: 200
height: 200
hoverEnabled: true
ToolTip.text: "static tooltip"
ToolTip.visible: containsMouse
ToolTip.onVisibleChanged: isToolTipVisible = ToolTip.visible
}
Loader {
id: loader
active: false
sourceComponent: Rectangle {
ToolTip.text: "dynamic tooltip"
ToolTip.visible: false
}
}
}

View File

@ -94,6 +94,7 @@ private slots:
void toolTipCrashOnClose();
void setOverlayParentToNull();
void tabFence();
void invisibleToolTipOpen();
};
void tst_QQuickPopup::initTestCase()
@ -1358,6 +1359,33 @@ void tst_QQuickPopup::tabFence()
QVERIFY(outsideButton1->hasActiveFocus());
}
void tst_QQuickPopup::invisibleToolTipOpen()
{
QQuickApplicationHelper helper(this, "invisibleToolTipOpen.qml");
QQuickWindow *window = helper.window;
centerOnScreen(window);
moveMouseAway(window);
window->show();
QVERIFY(QTest::qWaitForWindowActive(window));
QQuickItem *mouseArea = qvariant_cast<QQuickItem *>(window->property("mouseArea"));
QVERIFY(mouseArea);
QObject *loader = qvariant_cast<QObject *>(window->property("loader"));
QVERIFY(loader);
QTest::mouseMove(window, QPoint(mouseArea->width() / 2, mouseArea->height() / 2));
QTRY_VERIFY(mouseArea->property("isToolTipVisible").toBool());
QSignalSpy componentLoadedSpy(loader, SIGNAL(loaded()));
QVERIFY(componentLoadedSpy.isValid());
loader->setProperty("active", true);
QTRY_COMPARE(componentLoadedSpy.count(), 1);
QTRY_VERIFY(mouseArea->property("isToolTipVisible").toBool());
}
QTEST_QUICKCONTROLS_MAIN(tst_QQuickPopup)
#include "tst_qquickpopup.moc"

View File

@ -2,3 +2,23 @@
*
[attachedObjects:material/SwitchDelegate.qml]
*
[ids:controls/HorizontalHeaderView.qml]
*
[ids:controls/VerticalHeaderView.qml]
*
[ids:fusion/HorizontalHeaderView.qml]
*
[ids:fusion/VerticalHeaderView.qml]
*
[ids:imagine/HorizontalHeaderView.qml]
*
[ids:imagine/VerticalHeaderView.qml]
*
[ids:material/HorizontalHeaderView.qml]
*
[ids:material/VerticalHeaderView.qml]
*
[ids:universal/HorizontalHeaderView.qml]
*
[ids:universal/VerticalHeaderView.qml]
*

View File

@ -122,7 +122,7 @@ public:
if (!parser.parse()) {
const auto diagnosticMessages = parser.diagnosticMessages();
for (const QQmlJS::DiagnosticMessage &msg : diagnosticMessages)
#if Q_QML_PRIVATE_API_VERSION < 5
#if Q_QML_PRIVATE_API_VERSION >= 8
m_errors += QString("%s:%d : %s").arg(m_fileName).arg(msg.loc.startLine).arg(msg.message);
#else
m_errors += QString("%s:%d : %s").arg(m_fileName).arg(msg.line).arg(msg.message);

View File

@ -0,0 +1,65 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite 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.13
import QtQuick.Controls 2.13
ComboBox {
objectName: "comboBox"
textRole: "label"
model: ListModel {
ListElement {
label: qsTr("Hello")
}
ListElement {
label: qsTr("ListView")
}
}
}

View File

@ -0,0 +1,75 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite 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.14
import QtQuick.Controls 2.14
Item {
property Dialog dialog: Dialog {
width: 300
height: 300
visible: true
footer: DialogButtonBox {
Button {
objectName: "okButton"
text: qsTr("OK")
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
}
Button {
objectName: "cancelButton"
text: qsTr("Cancel")
DialogButtonBox.buttonRole: DialogButtonBox.RejectRole
}
}
}
}

Binary file not shown.

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="ja_JP">
<context>
<name>main</name>
<message>
<location filename="../main.qml" line="8"/>
<source>Hello World</source>
<translation></translation>
</message>
<message>
<location filename="../main.qml" line="12"/>
<source>Hello Text</source>
<translation></translation>
</message>
<message>
<location filename="../main.qml" line="35"/>
<source>Hello</source>
<translation></translation>
</message>
<message>
<location filename="../main.qml" line="38"/>
<source>ListView</source>
<translation></translation>
</message>
</context>
</TS>

Binary file not shown.

View File

@ -20,3 +20,4 @@
</message>
</context>
</TS>

View File

@ -13,7 +13,4 @@ TESTDATA = data/*
OTHER_FILES += \
data/*.qml
# We only want to run lrelease, which is why we use EXTRA_TRANSLATIONS.
EXTRA_TRANSLATIONS = qtbase_fr.ts
# Embed the translations in a qrc file.
CONFIG += lrelease embed_translations
RESOURCES += qml_jp.qm qtbase_fr.qm

View File

@ -42,8 +42,10 @@
#include <QtGui/qpa/qplatformtheme.h>
#include <QtQuick/qquickview.h>
#include <QtQuickTemplates2/private/qquickabstractbutton_p.h>
#include <QtQuickTemplates2/private/qquickcombobox_p.h>
#include <QtQuickTemplates2/private/qquickdialog_p.h>
#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h>
#include <QtQuickTemplates2/private/qquicktextfield_p.h>
using namespace QQuickVisualTestUtil;
@ -53,6 +55,8 @@ class tst_translation : public QQmlDataTest
private slots:
void dialogButtonBox();
void dialogButtonBoxWithCustomButtons();
void comboBox();
};
void tst_translation::dialogButtonBox()
@ -82,7 +86,7 @@ void tst_translation::dialogButtonBox()
QCOMPARE(discardButton->text(), defaultDiscardText);
QTranslator translator;
QVERIFY(translator.load(":/i18n/qtbase_fr.qm"));
QVERIFY(translator.load("qtbase_fr.qm", ":/"));
QVERIFY(qApp->installTranslator(&translator));
view.engine()->retranslate();
@ -95,6 +99,65 @@ void tst_translation::dialogButtonBox()
QCOMPARE(discardButton->text(), translatedDiscardText);
}
// Test that custom buttons with explicitly specified text
// do not have that text overwritten on language changes.
void tst_translation::dialogButtonBoxWithCustomButtons()
{
// This is just a way of simulating the translator going out of scope
// after the QML has been loaded.
QScopedPointer<QTranslator> translator(new QTranslator);
// Doesn't matter which language it is, as we won't be using it anyway.
QVERIFY(translator->load("qtbase_fr.qm", ":/"));
QVERIFY(qApp->installTranslator(translator.data()));
QQuickView view(testFileUrl("dialogButtonBoxWithCustomButtons.qml"));
if (view.status() != QQuickView::Ready)
QFAIL("Failed to load QML file");
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
QQuickDialog *dialog = view.rootObject()->property("dialog").value<QQuickDialog*>();
QVERIFY(dialog);
QQuickDialogButtonBox *dialogButtonBox = qobject_cast<QQuickDialogButtonBox*>(dialog->footer());
QVERIFY(dialogButtonBox);
auto okButton = dialogButtonBox->findChild<QQuickAbstractButton*>("okButton");
QVERIFY(okButton);
QCOMPARE(okButton->text(), QLatin1String("OK"));
QQuickAbstractButton *cancelButton = dialogButtonBox->findChild<QQuickAbstractButton*>("cancelButton");
QVERIFY(cancelButton);
QCOMPARE(cancelButton->text(), QLatin1String("Cancel"));
// Delete the translator and hence cause a LanguageChange event,
// but _without_ calling QQmlEngine::retranslate(), which would
// restore the original bindings and hence not reproduce the issue.
translator.reset();
QCOMPARE(okButton->text(), QLatin1String("OK"));
QCOMPARE(cancelButton->text(), QLatin1String("Cancel"));
}
void tst_translation::comboBox()
{
QQuickView view(testFileUrl("comboBox.qml"));
QQuickComboBox *comboBox = qobject_cast<QQuickComboBox*>(view.rootObject());
QVERIFY(comboBox);
QCOMPARE(comboBox->displayText(), QLatin1String("Hello"));
QQuickTextField *contentItem = qobject_cast<QQuickTextField*>(comboBox->contentItem());
QVERIFY(contentItem);
QCOMPARE(contentItem->text(), QLatin1String("Hello"));
QTranslator translator;
QVERIFY(translator.load("qml_jp.qm", ":/"));
QVERIFY(qApp->installTranslator(&translator));
view.engine()->retranslate();
QTRY_COMPARE(comboBox->displayText(), QString::fromUtf8("こんにちは"));
QCOMPARE(contentItem->text(), QString::fromUtf8("こんにちは"));
}
QTEST_MAIN(tst_translation)
#include "tst_translation.moc"

View File

@ -0,0 +1,10 @@
TEMPLATE = app
TARGET = headerview
QT += qml quick quick-private quickcontrols2 quickcontrols2-private \
quicktemplates2-private quicktemplates2
SOURCES += main.cpp
RESOURCES += main.qml
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

View File

@ -0,0 +1,218 @@
/****************************************************************************
**
** Copyright (C) 2020 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$
**
****************************************************************************/
#include <QAbstractTableModel>
#include <QDebug>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
class TestTableModel : public QAbstractTableModel {
Q_OBJECT
Q_PROPERTY(int rowCount READ rowCount WRITE setRowCount NOTIFY rowCountChanged)
Q_PROPERTY(int columnCount READ columnCount WRITE setColumnCount NOTIFY columnCountChanged)
public:
TestTableModel(QObject *parent = nullptr)
: QAbstractTableModel(parent)
{
}
int rowCount(const QModelIndex & = QModelIndex()) const override
{
return m_rows;
}
virtual void setRowCount(int count)
{
beginResetModel();
m_rows = count;
emit rowCountChanged();
endResetModel();
}
int columnCount(const QModelIndex & = QModelIndex()) const override
{
return m_cols;
}
virtual void setColumnCount(int count)
{
beginResetModel();
m_cols = count;
emit columnCountChanged();
endResetModel();
}
int indexValue(const QModelIndex &index) const
{
return index.row() + (index.column() * rowCount());
}
Q_INVOKABLE QModelIndex toQModelIndex(int serialIndex)
{
return createIndex(serialIndex % rowCount(), serialIndex / rowCount());
}
Q_INVOKABLE QVariant data(int row, int col)
{
return data(createIndex(row, col), Qt::DisplayRole);
}
QVariant data(const QModelIndex &index, int role) const override
{
if (!index.isValid())
return QVariant();
switch (role) {
case Qt::DisplayRole:
return QLatin1String("Foo");
case Qt::EditRole:
return m_checkedCells.contains(indexValue(index));
default:
return QVariant();
}
}
bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole) override
{
if (role != Qt::EditRole)
return false;
int i = indexValue(index);
bool checked = value.toBool();
if (checked == m_checkedCells.contains(i))
return false;
if (checked)
m_checkedCells.insert(i);
else
m_checkedCells.remove(i);
emit dataChanged(index, index, { role });
return true;
}
Q_INVOKABLE QHash<int, QByteArray> roleNames() const override
{
return {
{ Qt::DisplayRole, "display" },
{ Qt::EditRole, "edit" }
};
}
signals:
void rowCountChanged();
void columnCountChanged();
private:
int m_rows = 0;
int m_cols = 0;
QSet<int> m_checkedCells;
};
class TestTableModelWithHeader : public TestTableModel {
Q_OBJECT
public:
void setRowCount(int count) override
{
vData.resize(count);
TestTableModel::setRowCount(count);
}
void setColumnCount(int count) override
{
hData.resize(count);
TestTableModel::setColumnCount(count);
}
Q_INVOKABLE QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override
{
const bool isHorizontal = orientation == Qt::Horizontal;
auto sectionCount = isHorizontal ? columnCount() : rowCount();
if (section < 0 || section >= sectionCount)
return QVariant();
switch (role) {
case Qt::DisplayRole:
return (isHorizontal ? QString::fromLatin1("Column %1") : QString::fromLatin1("Row %1")).arg(section);
case Qt::EditRole: {
auto &data = isHorizontal ? hData : vData;
return data[section].toString();
}
default:
return QVariant();
}
}
Q_INVOKABLE bool setHeaderData(int section, Qt::Orientation orientation,
const QVariant &value, int role = Qt::EditRole) override
{
qDebug() << Q_FUNC_INFO
<< "section:" << section
<< "orient:" << orientation
<< "value:" << value
<< "role:" << QAbstractItemModel::roleNames()[role];
auto sectionCount = orientation == Qt::Horizontal ? columnCount() : rowCount();
if (section < 0 || section >= sectionCount)
return false;
auto &data = orientation == Qt::Horizontal ? hData : vData;
data[section] = value;
emit headerDataChanged(orientation, section, section);
return true;
}
private:
QVector<QVariant> hData, vData;
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<TestTableModel>("TestTableModel", 0, 1, "TestTableModel");
qmlRegisterType<TestTableModelWithHeader>("TestTableModelWithHeader", 0, 1, "TestTableModelWithHeader");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
#include "main.moc"

View File

@ -0,0 +1,126 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite 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 QtQml.Models 2.15
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Shapes 1.15
import QtQuick.Window 2.15
import Qt.labs.qmlmodels 1.0
import TestTableModelWithHeader 0.1
Window {
visible: true
width: 640
height: 480
title: qsTr("HeaderView Test")
TestTableModelWithHeader {
id: tableModel
rowCount: 50
columnCount: 80
}
TableView {
id: tableView
anchors.top: parent.top
anchors.topMargin: horizontalHeader.height + rowSpacing
anchors.left: parent.left
anchors.leftMargin: verticalHeader.width + columnSpacing
model: tableModel
rightMargin: 100
bottomMargin: 100
columnSpacing: 4
rowSpacing: 4
syncDirection: Qt.Vertical | Qt.Horizontal
implicitWidth: parent.width + columnSpacing
implicitHeight: parent.height + rowSpacing
clip: true
delegate: Rectangle {
implicitWidth: 150
implicitHeight: 50
color: "#e6ecf5"
CheckBox {
anchors.fill: parent
text: model.display
checked: model.edit
leftPadding: 12
onClicked: model.edit = checked
}
}
}
HorizontalHeaderView {
id: horizontalHeader
objectName: "horizontalHeader"
anchors.top: parent.top
anchors.left: tableView.left
syncView: tableView
clip: true
}
VerticalHeaderView {
id: verticalHeader
objectName: "verticalHeader"
anchors.top: tableView.top
syncView: tableView
clip: true
}
ToolButton {
width: verticalHeader.width
height: horizontalHeader.height
onClicked: {
horizontalHeader.contentX = 0
verticalHeader.contentY = 0
}
}
}

View File

@ -3,6 +3,7 @@ SUBDIRS += \
buttons \
gifs \
fonts \
headerview \
screenshots \
styles \
testbench