aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/imports/controls/ComboBox.qml2
-rw-r--r--src/imports/controls/DialogButtonBox.qml1
-rw-r--r--src/imports/controls/designer/AbstractButtonSection.qml4
-rw-r--r--src/imports/controls/designer/ButtonSection.qml12
-rw-r--r--src/imports/controls/designer/ControlSection.qml4
-rw-r--r--src/imports/controls/designer/DialSpecifics.qml14
-rw-r--r--src/imports/controls/designer/InsetSection.qml119
-rw-r--r--src/imports/controls/designer/LabelSpecifics.qml4
-rw-r--r--src/imports/controls/designer/PageIndicatorSpecifics.qml16
-rw-r--r--src/imports/controls/designer/RangeSliderSpecifics.qml16
-rw-r--r--src/imports/controls/designer/RoundButtonSpecifics.qml5
-rw-r--r--src/imports/controls/designer/SliderSpecifics.qml14
-rw-r--r--src/imports/controls/designer/SpinBoxSpecifics.qml12
-rw-r--r--src/imports/controls/designer/TextAreaSpecifics.qml27
-rw-r--r--src/imports/controls/designer/TextFieldSpecifics.qml27
-rw-r--r--src/imports/controls/designer/designer.pri1
-rw-r--r--src/imports/controls/doc/src/includes/qquickicon.qdocinc2
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-icons.qdoc1
-rw-r--r--src/imports/controls/fusion/ComboBox.qml2
-rw-r--r--src/imports/controls/fusion/DialogButtonBox.qml1
-rw-r--r--src/imports/controls/fusion/plugins.qmltypes2
-rw-r--r--src/imports/controls/imagine/ComboBox.qml2
-rw-r--r--src/imports/controls/imagine/DialogButtonBox.qml1
-rw-r--r--src/imports/controls/imagine/GroupBox.qml3
-rw-r--r--src/imports/controls/imagine/plugins.qmltypes14
-rw-r--r--src/imports/controls/imagine/qquickninepatchimage.cpp16
-rw-r--r--src/imports/controls/material/ComboBox.qml12
-rw-r--r--src/imports/controls/material/DialogButtonBox.qml1
-rw-r--r--src/imports/controls/material/material.pro2
-rw-r--r--src/imports/controls/material/plugins.qmltypes3
-rw-r--r--src/imports/controls/material/qmldir2
-rw-r--r--src/imports/controls/material/qquickmaterialstyle.cpp92
-rw-r--r--src/imports/controls/material/qquickmaterialstyle_p.h80
-rw-r--r--src/imports/controls/plugins.qmltypes18
-rw-r--r--src/imports/controls/universal/ComboBox.qml2
-rw-r--r--src/imports/controls/universal/DialogButtonBox.qml1
-rw-r--r--src/imports/controls/universal/plugins.qmltypes2
-rw-r--r--src/imports/platform/platform.pro4
-rw-r--r--src/imports/platform/plugins.qmltypes9
-rw-r--r--src/imports/platform/qquickplatformfiledialog.cpp9
-rw-r--r--src/imports/platform/qquickplatformmenu.cpp7
-rw-r--r--src/imports/platform/qquickplatformmenubar.cpp1
-rw-r--r--src/imports/platform/qquickplatformmenuitem.cpp58
-rw-r--r--src/imports/platform/qquickplatformmenuitem_p.h2
-rw-r--r--src/imports/platform/qquickplatformsystemtrayicon.cpp1
-rw-r--r--src/imports/platform/qtlabsplatformplugin.cpp1
-rw-r--r--src/imports/templates/plugins.qmltypes80
-rw-r--r--src/imports/templates/qmldir1
-rw-r--r--src/imports/templates/qtquicktemplates2plugin.cpp2
-rw-r--r--src/quickcontrols2/qquickiconimage.cpp7
-rw-r--r--src/quickcontrols2/qquickiconimage_p_p.h1
-rw-r--r--src/quicktemplates2/accessible/accessible.pri5
-rw-r--r--src/quicktemplates2/accessible/qaccessiblequickpage.cpp81
-rw-r--r--src/quicktemplates2/accessible/qaccessiblequickpage_p.h70
-rw-r--r--src/quicktemplates2/qquickabstractbutton.cpp41
-rw-r--r--src/quicktemplates2/qquickabstractbutton_p_p.h2
-rw-r--r--src/quicktemplates2/qquickaction.cpp4
-rw-r--r--src/quicktemplates2/qquickapplicationwindow.cpp7
-rw-r--r--src/quicktemplates2/qquickcombobox.cpp71
-rw-r--r--src/quicktemplates2/qquickcontrol.cpp56
-rw-r--r--src/quicktemplates2/qquickcontrol_p_p.h3
-rw-r--r--src/quicktemplates2/qquickdial.cpp36
-rw-r--r--src/quicktemplates2/qquickdialogbuttonbox.cpp27
-rw-r--r--src/quicktemplates2/qquickdialogbuttonbox_p.h1
-rw-r--r--src/quicktemplates2/qquickdrawer.cpp2
-rw-r--r--src/quicktemplates2/qquickheaderview.cpp20
-rw-r--r--src/quicktemplates2/qquickmenu.cpp29
-rw-r--r--src/quicktemplates2/qquickmenu_p.h1
-rw-r--r--src/quicktemplates2/qquickmenu_p_p.h2
-rw-r--r--src/quicktemplates2/qquickoverlay.cpp12
-rw-r--r--src/quicktemplates2/qquickpage.cpp3
-rw-r--r--src/quicktemplates2/qquickpageindicator.cpp6
-rw-r--r--src/quicktemplates2/qquickpopup.cpp53
-rw-r--r--src/quicktemplates2/qquickpopup_p_p.h2
-rw-r--r--src/quicktemplates2/qquickpopupanchors.cpp26
-rw-r--r--src/quicktemplates2/qquickpopupanchors_p.h6
-rw-r--r--src/quicktemplates2/qquickpopupitem.cpp3
-rw-r--r--src/quicktemplates2/qquickpopuppositioner.cpp18
-rw-r--r--src/quicktemplates2/qquickpopuppositioner_p_p.h1
-rw-r--r--src/quicktemplates2/qquickrangeslider.cpp13
-rw-r--r--src/quicktemplates2/qquickscrollbar.cpp44
-rw-r--r--src/quicktemplates2/qquickscrollbar_p_p.h2
-rw-r--r--src/quicktemplates2/qquickscrollview.cpp14
-rw-r--r--src/quicktemplates2/qquickslider.cpp3
-rw-r--r--src/quicktemplates2/qquickspinbox.cpp41
-rw-r--r--src/quicktemplates2/qquicksplitview.cpp2
-rw-r--r--src/quicktemplates2/qquickstackview.cpp40
-rw-r--r--src/quicktemplates2/qquickstackview_p.cpp6
-rw-r--r--src/quicktemplates2/qquickstackview_p_p.h5
-rw-r--r--src/quicktemplates2/qquickswipedelegate.cpp46
-rw-r--r--src/quicktemplates2/qquickswipedelegate_p_p.h1
-rw-r--r--src/quicktemplates2/qquickswipeview.cpp1
-rw-r--r--src/quicktemplates2/qquicktextarea.cpp23
-rw-r--r--src/quicktemplates2/qquicktumbler.cpp5
-rw-r--r--src/quicktemplates2/qtquicktemplates2global.cpp63
-rw-r--r--src/quicktemplates2/qtquicktemplates2global_p.h2
-rw-r--r--src/quicktemplates2/quicktemplates2.pro6
97 files changed, 1353 insertions, 272 deletions
diff --git a/src/imports/controls/ComboBox.qml b/src/imports/controls/ComboBox.qml
index b30293f5..e9f93d66 100644
--- a/src/imports/controls/ComboBox.qml
+++ b/src/imports/controls/ComboBox.qml
@@ -53,7 +53,7 @@ T.ComboBox {
rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
delegate: ItemDelegate {
- width: parent.width
+ width: ListView.view.width
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
palette.text: control.palette.text
palette.highlightedText: control.palette.highlightedText
diff --git a/src/imports/controls/DialogButtonBox.qml b/src/imports/controls/DialogButtonBox.qml
index 3c9d5b48..cc148ac4 100644
--- a/src/imports/controls/DialogButtonBox.qml
+++ b/src/imports/controls/DialogButtonBox.qml
@@ -55,6 +55,7 @@ T.DialogButtonBox {
}
contentItem: ListView {
+ implicitWidth: contentWidth
model: control.contentModel
spacing: control.spacing
orientation: ListView.Horizontal
diff --git a/src/imports/controls/designer/AbstractButtonSection.qml b/src/imports/controls/designer/AbstractButtonSection.qml
index e8aa39c2..35fad2ab 100644
--- a/src/imports/controls/designer/AbstractButtonSection.qml
+++ b/src/imports/controls/designer/AbstractButtonSection.qml
@@ -104,8 +104,8 @@ Section {
}
Label {
- text: qsTr("Repeat")
- tooltip: qsTr("Whether the button repeats while pressed and held down.")
+ text: qsTr("Auto-Repeat")
+ tooltip: qsTr("Whether the button repeats pressed(), released() and clicked() signals while the button is pressed and held down.")
}
SecondColumnLayout {
CheckBox {
diff --git a/src/imports/controls/designer/ButtonSection.qml b/src/imports/controls/designer/ButtonSection.qml
index fef46071..951c8cf4 100644
--- a/src/imports/controls/designer/ButtonSection.qml
+++ b/src/imports/controls/designer/ButtonSection.qml
@@ -43,17 +43,7 @@ Section {
caption: qsTr("Button")
SectionLayout {
- Label {
- text: qsTr("AutoRepeat")
- tooltip: qsTr("Whether the button repeats pressed(), released() and clicked() signals while the button is pressed and held down.")
- }
- SecondColumnLayout {
- CheckBox {
- text: backendValues.autoRepeat.valueToString
- backendValue: backendValues.autoRepeat
- Layout.fillWidth: true
- }
- }
+
Label {
text: qsTr("Flat")
tooltip: qsTr("Whether the button is flat.")
diff --git a/src/imports/controls/designer/ControlSection.qml b/src/imports/controls/designer/ControlSection.qml
index 7c53ac73..3446c08f 100644
--- a/src/imports/controls/designer/ControlSection.qml
+++ b/src/imports/controls/designer/ControlSection.qml
@@ -69,7 +69,7 @@ Section {
Label {
text: qsTr("Hover")
- tooltip: qsTr("Whether control accepts hover evets.")
+ tooltip: qsTr("Whether control accepts hover events.")
}
SecondColumnLayout {
CheckBox {
@@ -95,7 +95,7 @@ Section {
Label {
text: qsTr("Wheel")
- tooltip: qsTr("Whether control accepts wheel evets.")
+ tooltip: qsTr("Whether control accepts wheel events.")
}
SecondColumnLayout {
CheckBox {
diff --git a/src/imports/controls/designer/DialSpecifics.qml b/src/imports/controls/designer/DialSpecifics.qml
index fc5b5e83..a0df81ef 100644
--- a/src/imports/controls/designer/DialSpecifics.qml
+++ b/src/imports/controls/designer/DialSpecifics.qml
@@ -112,7 +112,7 @@ Column {
}
SecondColumnLayout {
ComboBox {
- backendValue: backendValues.orientation
+ backendValue: backendValues.snapMode
model: [ "NoSnap", "SnapOnRelease", "SnapAlways" ]
scope: "Dial"
Layout.fillWidth: true
@@ -143,6 +143,18 @@ Column {
Layout.fillWidth: true
}
}
+
+ Label {
+ text: qsTr("Wrap")
+ tooltip: qsTr("Whether the dial wraps when dragged.")
+ }
+ SecondColumnLayout {
+ CheckBox {
+ text: backendValues.wrap.valueToString
+ backendValue: backendValues.wrap
+ Layout.fillWidth: true
+ }
+ }
}
}
diff --git a/src/imports/controls/designer/InsetSection.qml b/src/imports/controls/designer/InsetSection.qml
new file mode 100644
index 00000000..4253b170
--- /dev/null
+++ b/src/imports/controls/designer/InsetSection.qml
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** 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.12
+import HelperWidgets 2.0
+import QtQuick.Layouts 1.12
+
+Section {
+ caption: qsTr("Inset")
+
+ SectionLayout {
+ Label {
+ text: qsTr("Vertical")
+ }
+ SecondColumnLayout {
+ Label {
+ text: qsTr("Top")
+ tooltip: qsTr("Top inset for the background.")
+ width: 42
+ }
+ SpinBox {
+ maximumValue: 10000
+ minimumValue: -10000
+ realDragRange: 5000
+ decimals: 0
+ backendValue: backendValues.topInset
+ Layout.fillWidth: true
+ }
+ Item {
+ width: 4
+ height: 4
+ }
+
+ Label {
+ text: qsTr("Bottom")
+ tooltip: qsTr("Bottom inset for the background.")
+ width: 42
+ }
+ SpinBox {
+ maximumValue: 10000
+ minimumValue: -10000
+ realDragRange: 5000
+ decimals: 0
+ backendValue: backendValues.bottomInset
+ Layout.fillWidth: true
+ }
+ }
+
+ Label {
+ text: qsTr("Horizontal")
+ }
+ SecondColumnLayout {
+ Label {
+ text: qsTr("Left")
+ tooltip: qsTr("Left inset for the background.")
+ width: 42
+ }
+ SpinBox {
+ maximumValue: 10000
+ minimumValue: -10000
+ realDragRange: 5000
+ decimals: 0
+ backendValue: backendValues.leftInset
+ Layout.fillWidth: true
+ }
+ Item {
+ width: 4
+ height: 4
+ }
+
+ Label {
+ text: qsTr("Right")
+ tooltip: qsTr("Right inset for the background.")
+ width: 42
+ }
+ SpinBox {
+ maximumValue: 10000
+ minimumValue: -10000
+ realDragRange: 5000
+ decimals: 0
+ backendValue: backendValues.rightInset
+ Layout.fillWidth: true
+ }
+ }
+ }
+}
diff --git a/src/imports/controls/designer/LabelSpecifics.qml b/src/imports/controls/designer/LabelSpecifics.qml
index c832f894..e5d5e04f 100644
--- a/src/imports/controls/designer/LabelSpecifics.qml
+++ b/src/imports/controls/designer/LabelSpecifics.qml
@@ -79,4 +79,8 @@ Column {
PaddingSection {
width: parent.width
}
+
+ InsetSection {
+ width: parent.width
+ }
}
diff --git a/src/imports/controls/designer/PageIndicatorSpecifics.qml b/src/imports/controls/designer/PageIndicatorSpecifics.qml
index 042672a9..20aa8577 100644
--- a/src/imports/controls/designer/PageIndicatorSpecifics.qml
+++ b/src/imports/controls/designer/PageIndicatorSpecifics.qml
@@ -73,6 +73,18 @@ Column {
Layout.fillWidth: true
}
}
+
+ Label {
+ text: qsTr("Interactive")
+ tooltip: qsTr("Whether the control is interactive.")
+ }
+ SecondColumnLayout {
+ CheckBox {
+ text: backendValues.interactive.valueToString
+ backendValue: backendValues.interactive
+ Layout.fillWidth: true
+ }
+ }
}
}
@@ -80,10 +92,6 @@ Column {
width: parent.width
}
- FontSection {
- width: parent.width
- }
-
PaddingSection {
width: parent.width
}
diff --git a/src/imports/controls/designer/RangeSliderSpecifics.qml b/src/imports/controls/designer/RangeSliderSpecifics.qml
index 79d2404f..9372a4ff 100644
--- a/src/imports/controls/designer/RangeSliderSpecifics.qml
+++ b/src/imports/controls/designer/RangeSliderSpecifics.qml
@@ -127,7 +127,7 @@ Column {
}
SecondColumnLayout {
ComboBox {
- backendValue: backendValues.orientation
+ backendValue: backendValues.snapMode
model: [ "NoSnap", "SnapOnRelease", "SnapAlways" ]
scope: "RangeSlider"
Layout.fillWidth: true
@@ -158,6 +158,20 @@ Column {
Layout.fillWidth: true
}
}
+
+ Label {
+ text: qsTr("Touch drag threshold")
+ tooltip: qsTr("The threshold (in logical pixels) at which a touch drag event will be initiated.")
+ }
+ SecondColumnLayout {
+ SpinBox {
+ minimumValue: 0
+ maximumValue: 10000
+ decimals: 0
+ backendValue: backendValues.touchDragThreshold
+ Layout.fillWidth: true
+ }
+ }
}
}
diff --git a/src/imports/controls/designer/RoundButtonSpecifics.qml b/src/imports/controls/designer/RoundButtonSpecifics.qml
index 2da4cda6..af4ab5d0 100644
--- a/src/imports/controls/designer/RoundButtonSpecifics.qml
+++ b/src/imports/controls/designer/RoundButtonSpecifics.qml
@@ -42,6 +42,7 @@ Column {
width: parent.width
Section {
+ width: parent.width
caption: qsTr("RoundButton")
SectionLayout {
@@ -51,8 +52,8 @@ Column {
}
SecondColumnLayout {
SpinBox {
- maximumValue: 9999999
- minimumValue: -9999999
+ minimumValue: 0
+ maximumValue: 10000
decimals: 0
backendValue: backendValues.radius
Layout.fillWidth: true
diff --git a/src/imports/controls/designer/SliderSpecifics.qml b/src/imports/controls/designer/SliderSpecifics.qml
index 076d8a1c..d126dd06 100644
--- a/src/imports/controls/designer/SliderSpecifics.qml
+++ b/src/imports/controls/designer/SliderSpecifics.qml
@@ -143,6 +143,20 @@ Column {
Layout.fillWidth: true
}
}
+
+ Label {
+ text: qsTr("Touch drag threshold")
+ tooltip: qsTr("The threshold (in logical pixels) at which a touch drag event will be initiated.")
+ }
+ SecondColumnLayout {
+ SpinBox {
+ minimumValue: 0
+ maximumValue: 10000
+ decimals: 0
+ backendValue: backendValues.touchDragThreshold
+ Layout.fillWidth: true
+ }
+ }
}
}
diff --git a/src/imports/controls/designer/SpinBoxSpecifics.qml b/src/imports/controls/designer/SpinBoxSpecifics.qml
index d6375d7c..db59f074 100644
--- a/src/imports/controls/designer/SpinBoxSpecifics.qml
+++ b/src/imports/controls/designer/SpinBoxSpecifics.qml
@@ -113,6 +113,18 @@ Column {
Layout.fillWidth: true
}
}
+
+ Label {
+ text: qsTr("Wrap")
+ tooltip: qsTr("Whether the spinbox wraps.")
+ }
+ SecondColumnLayout {
+ CheckBox {
+ text: backendValues.wrap.valueToString
+ backendValue: backendValues.wrap
+ Layout.fillWidth: true
+ }
+ }
}
}
diff --git a/src/imports/controls/designer/TextAreaSpecifics.qml b/src/imports/controls/designer/TextAreaSpecifics.qml
index a14584e7..f8cf92e8 100644
--- a/src/imports/controls/designer/TextAreaSpecifics.qml
+++ b/src/imports/controls/designer/TextAreaSpecifics.qml
@@ -57,6 +57,29 @@ Column {
}
}
+
+ Label {
+ text: qsTr("Hover")
+ tooltip: qsTr("Whether text area accepts hover events.")
+ }
+ SecondColumnLayout {
+ CheckBox {
+ text: backendValues.hoverEnabled.valueToString
+ backendValue: backendValues.hoverEnabled
+ Layout.fillWidth: true
+ }
+ }
+ }
+ }
+
+ Section {
+ width: parent.width
+ caption: qsTr("Placeholder Text Color")
+
+ ColorEditor {
+ caption: qsTr("Placeholder Text Color")
+ backendValue: backendValues.placeholderTextColor
+ supportGradient: false
}
}
@@ -74,4 +97,8 @@ Column {
PaddingSection {
width: parent.width
}
+
+ InsetSection {
+ width: parent.width
+ }
}
diff --git a/src/imports/controls/designer/TextFieldSpecifics.qml b/src/imports/controls/designer/TextFieldSpecifics.qml
index 67a63ec4..f95f282c 100644
--- a/src/imports/controls/designer/TextFieldSpecifics.qml
+++ b/src/imports/controls/designer/TextFieldSpecifics.qml
@@ -57,6 +57,29 @@ Column {
}
}
+
+ Label {
+ text: qsTr("Hover")
+ tooltip: qsTr("Whether text field accepts hover events.")
+ }
+ SecondColumnLayout {
+ CheckBox {
+ text: backendValues.hoverEnabled.valueToString
+ backendValue: backendValues.hoverEnabled
+ Layout.fillWidth: true
+ }
+ }
+ }
+ }
+
+ Section {
+ width: parent.width
+ caption: qsTr("Placeholder Text Color")
+
+ ColorEditor {
+ caption: qsTr("Placeholder Text Color")
+ backendValue: backendValues.placeholderTextColor
+ supportGradient: false
}
}
@@ -71,4 +94,8 @@ Column {
PaddingSection {
width: parent.width
}
+
+ InsetSection {
+ width: parent.width
+ }
}
diff --git a/src/imports/controls/designer/designer.pri b/src/imports/controls/designer/designer.pri
index 3ad99df7..6692b203 100644
--- a/src/imports/controls/designer/designer.pri
+++ b/src/imports/controls/designer/designer.pri
@@ -17,6 +17,7 @@ AUX_QML_FILES += \
$$PWD/DialSpecifics.qml \
$$PWD/FrameSpecifics.qml \
$$PWD/GroupBoxSpecifics.qml \
+ $$PWD/InsetSection.qml \
$$PWD/ItemDelegateSection.qml \
$$PWD/ItemDelegateSpecifics.qml \
$$PWD/LabelSpecifics.qml \
diff --git a/src/imports/controls/doc/src/includes/qquickicon.qdocinc b/src/imports/controls/doc/src/includes/qquickicon.qdocinc
index ba7cede9..beef5624 100644
--- a/src/imports/controls/doc/src/includes/qquickicon.qdocinc
+++ b/src/imports/controls/doc/src/includes/qquickicon.qdocinc
@@ -44,5 +44,7 @@
\li This property specifies whether the icon should be cached.
The default value is true.
+
+ This property was introduced in QtQuick.Controls 2.13.
\endtable
//! [grouped-properties]
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-icons.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-icons.qdoc
index f8cb1f52..190aafd9 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-icons.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-icons.qdoc
@@ -44,6 +44,7 @@
\li \c icon.width
\li \c icon.height
\li \c icon.color
+ \li \c icon.cache
\endlist
Theme icons are referenced by a name, and regular icons by a source URL. Both
diff --git a/src/imports/controls/fusion/ComboBox.qml b/src/imports/controls/fusion/ComboBox.qml
index d8ef1888..5e26f90e 100644
--- a/src/imports/controls/fusion/ComboBox.qml
+++ b/src/imports/controls/fusion/ComboBox.qml
@@ -55,7 +55,7 @@ T.ComboBox {
rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
delegate: MenuItem {
- width: parent.width
+ width: ListView.view.width
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal
highlighted: control.highlightedIndex === index
diff --git a/src/imports/controls/fusion/DialogButtonBox.qml b/src/imports/controls/fusion/DialogButtonBox.qml
index a0b0f243..4673e421 100644
--- a/src/imports/controls/fusion/DialogButtonBox.qml
+++ b/src/imports/controls/fusion/DialogButtonBox.qml
@@ -56,6 +56,7 @@ T.DialogButtonBox {
delegate: Button { }
contentItem: ListView {
+ implicitWidth: contentWidth
model: control.contentModel
spacing: control.spacing
orientation: ListView.Horizontal
diff --git a/src/imports/controls/fusion/plugins.qmltypes b/src/imports/controls/fusion/plugins.qmltypes
index 5140d1e8..681b8b90 100644
--- a/src/imports/controls/fusion/plugins.qmltypes
+++ b/src/imports/controls/fusion/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls.Fusion 2.14'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls.Fusion 2.15'
Module {
dependencies: ["QtQuick.Controls 2.0"]
diff --git a/src/imports/controls/imagine/ComboBox.qml b/src/imports/controls/imagine/ComboBox.qml
index 92937826..d657e734 100644
--- a/src/imports/controls/imagine/ComboBox.qml
+++ b/src/imports/controls/imagine/ComboBox.qml
@@ -59,7 +59,7 @@ T.ComboBox {
bottomInset: background ? -background.bottomInset || 0 : 0
delegate: ItemDelegate {
- width: parent.width
+ width: ListView.view.width
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal
highlighted: control.highlightedIndex === index
diff --git a/src/imports/controls/imagine/DialogButtonBox.qml b/src/imports/controls/imagine/DialogButtonBox.qml
index c24b29fc..fd27a876 100644
--- a/src/imports/controls/imagine/DialogButtonBox.qml
+++ b/src/imports/controls/imagine/DialogButtonBox.qml
@@ -66,6 +66,7 @@ T.DialogButtonBox {
}
contentItem: ListView {
+ implicitWidth: contentWidth
model: control.contentModel
spacing: control.spacing
orientation: ListView.Horizontal
diff --git a/src/imports/controls/imagine/GroupBox.qml b/src/imports/controls/imagine/GroupBox.qml
index 7abdb6f0..46f9c98a 100644
--- a/src/imports/controls/imagine/GroupBox.qml
+++ b/src/imports/controls/imagine/GroupBox.qml
@@ -53,7 +53,6 @@ T.GroupBox {
leftPadding: background ? background.leftPadding : 0
rightPadding: background ? background.rightPadding : 0
bottomPadding: background ? background.bottomPadding : 0
- padding: 12
label: Label {
width: control.width
@@ -88,7 +87,7 @@ T.GroupBox {
x: -leftInset
y: control.topPadding - control.bottomPadding - topInset
width: control.width + leftInset + rightInset
- height: control.height + topInset + bottomInset - control.topPadding + control.padding
+ height: control.height + topInset + bottomInset - control.topPadding + control.bottomPadding
source: Imagine.url + "groupbox-background"
NinePatchImageSelector on source {
diff --git a/src/imports/controls/imagine/plugins.qmltypes b/src/imports/controls/imagine/plugins.qmltypes
index 191807ae..785b6dba 100644
--- a/src/imports/controls/imagine/plugins.qmltypes
+++ b/src/imports/controls/imagine/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls.Imagine 2.14'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls.Imagine 2.15'
Module {
dependencies: ["QtQuick.Controls 2.0"]
@@ -54,6 +54,7 @@ Module {
Property { name: "verticalAlignment"; type: "VAlignment" }
Property { name: "mipmap"; revision: 3; type: "bool" }
Property { name: "autoTransform"; revision: 5; type: "bool" }
+ Property { name: "sourceClipRect"; revision: 15; type: "QRectF" }
Signal { name: "paintedGeometryChanged" }
Signal {
name: "horizontalAlignmentChanged"
@@ -75,6 +76,14 @@ Module {
defaultProperty: "data"
prototype: "QQuickImplicitSizeItem"
Enum {
+ name: "LoadPixmapOptions"
+ values: {
+ "NoOption": 0,
+ "HandleDPR": 1,
+ "UseProviderOptions": 2
+ }
+ }
+ Enum {
name: "Status"
values: {
"Null": 0,
@@ -92,6 +101,7 @@ Module {
Property { name: "mirror"; type: "bool" }
Property { name: "currentFrame"; revision: 14; type: "int" }
Property { name: "frameCount"; revision: 14; type: "int"; isReadonly: true }
+ Property { name: "colorSpace"; revision: 15; type: "QColorSpace" }
Signal {
name: "sourceChanged"
Parameter { type: "QUrl" }
@@ -106,6 +116,8 @@ Module {
}
Signal { name: "currentFrameChanged"; revision: 14 }
Signal { name: "frameCountChanged"; revision: 14 }
+ Signal { name: "sourceClipRectChanged"; revision: 15 }
+ Signal { name: "colorSpaceChanged"; revision: 15 }
}
Component {
name: "QQuickImageSelector"
diff --git a/src/imports/controls/imagine/qquickninepatchimage.cpp b/src/imports/controls/imagine/qquickninepatchimage.cpp
index 7d5e4f71..ed388ec1 100644
--- a/src/imports/controls/imagine/qquickninepatchimage.cpp
+++ b/src/imports/controls/imagine/qquickninepatchimage.cpp
@@ -386,7 +386,12 @@ void QQuickNinePatchImage::pixmapChange()
{
Q_D(QQuickNinePatchImage);
if (QFileInfo(d->url.fileName()).completeSuffix().toLower() == QLatin1String("9.png")) {
- d->resetNode = d->ninePatch.isNull();
+ // Keep resetNode if it is already set, we do not want to miss an
+ // ImageNode->NinePatchNode change. Without this there's a chance one gets
+ // an incorrect cast on oldNode every once in a while with source changes.
+ if (!d->resetNode)
+ d->resetNode = d->ninePatch.isNull();
+
d->ninePatch = d->pix.image();
if (d->ninePatch.depth() != 32)
d->ninePatch = d->ninePatch.convertToFormat(QImage::Format_ARGB32);
@@ -434,6 +439,8 @@ QSGNode *QQuickNinePatchImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNode
QSizeF sz = size();
QImage image = d->pix.image();
if (!sz.isValid() || image.isNull()) {
+ if (d->provider)
+ d->provider->updateTexture(nullptr);
delete oldNode;
return nullptr;
}
@@ -449,6 +456,13 @@ QSGNode *QQuickNinePatchImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNode
qsgnode_set_description(patchNode, QString::fromLatin1("QQuickNinePatchImage: '%1'").arg(d->url.toString()));
#endif
+ // The image may wrap non-owned data (due to pixmapChange). Ensure we never
+ // pass such an image to the scenegraph, because with a separate render
+ // thread the data may become invalid (in a subsequent pixmapChange on the
+ // gui thread) by the time the renderer gets to do something with the QImage
+ // passed in here.
+ image.detach();
+
QSGTexture *texture = window()->createTextureFromImage(image);
patchNode->initialize(texture, sz * d->devicePixelRatio, image.size(), d->xDivs, d->yDivs, d->devicePixelRatio);
return patchNode;
diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml
index e4ee332b..6aada8c5 100644
--- a/src/imports/controls/material/ComboBox.qml
+++ b/src/imports/controls/material/ComboBox.qml
@@ -63,9 +63,9 @@ T.ComboBox {
Material.foreground: flat ? undefined : Material.primaryTextColor
delegate: MenuItem {
- width: parent.width
+ width: ListView.view.width
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
- Material.foreground: control.currentIndex === index ? parent.Material.accent : parent.Material.foreground
+ Material.foreground: control.currentIndex === index ? ListView.view.contentItem.Material.accent : ListView.view.contentItem.Material.foreground
highlighted: control.highlightedIndex === index
hoverEnabled: control.hoverEnabled
}
@@ -147,14 +147,14 @@ T.ComboBox {
enter: Transition {
// grow_fade_in
- NumberAnimation { property: "scale"; from: 0.9; to: 1.0; easing.type: Easing.OutQuint; duration: 220 }
- NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; easing.type: Easing.OutCubic; duration: 150 }
+ NumberAnimation { property: "scale"; from: 0.9; easing.type: Easing.OutQuint; duration: 220 }
+ NumberAnimation { property: "opacity"; from: 0.0; easing.type: Easing.OutCubic; duration: 150 }
}
exit: Transition {
// shrink_fade_out
- NumberAnimation { property: "scale"; from: 1.0; to: 0.9; easing.type: Easing.OutQuint; duration: 220 }
- NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; easing.type: Easing.OutCubic; duration: 150 }
+ NumberAnimation { property: "scale"; to: 0.9; easing.type: Easing.OutQuint; duration: 220 }
+ NumberAnimation { property: "opacity"; to: 0.0; easing.type: Easing.OutCubic; duration: 150 }
}
contentItem: ListView {
diff --git a/src/imports/controls/material/DialogButtonBox.qml b/src/imports/controls/material/DialogButtonBox.qml
index c53b8210..d148fb24 100644
--- a/src/imports/controls/material/DialogButtonBox.qml
+++ b/src/imports/controls/material/DialogButtonBox.qml
@@ -60,6 +60,7 @@ T.DialogButtonBox {
delegate: Button { flat: true }
contentItem: ListView {
+ implicitWidth: contentWidth
model: control.contentModel
spacing: control.spacing
orientation: ListView.Horizontal
diff --git a/src/imports/controls/material/material.pro b/src/imports/controls/material/material.pro
index cf08b925..ea74d277 100644
--- a/src/imports/controls/material/material.pro
+++ b/src/imports/controls/material/material.pro
@@ -1,4 +1,4 @@
-TARGET = qtquickcontrols2materialstyleplugin
+TARGET = qqc2materialstyleplugin
TARGETPATH = QtQuick/Controls.2/Material
IMPORT_NAME = QtQuick.Controls.Material
diff --git a/src/imports/controls/material/plugins.qmltypes b/src/imports/controls/material/plugins.qmltypes
index 7546a7b0..e290e0ea 100644
--- a/src/imports/controls/material/plugins.qmltypes
+++ b/src/imports/controls/material/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls.Material 2.14'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls.Material 2.15'
Module {
dependencies: ["QtQuick.Controls 2.0"]
@@ -328,6 +328,7 @@ Module {
Property { name: "toolBarColor"; type: "QColor"; isReadonly: true }
Property { name: "toolTextColor"; type: "QColor"; isReadonly: true }
Property { name: "spinBoxDisabledIconColor"; type: "QColor"; isReadonly: true }
+ Property { name: "sliderDisabledColor"; revision: 15; type: "QColor"; isReadonly: true }
Property { name: "touchTarget"; type: "int"; isReadonly: true }
Property { name: "buttonHeight"; type: "int"; isReadonly: true }
Property { name: "delegateHeight"; type: "int"; isReadonly: true }
diff --git a/src/imports/controls/material/qmldir b/src/imports/controls/material/qmldir
index 870a0382..d48b7b12 100644
--- a/src/imports/controls/material/qmldir
+++ b/src/imports/controls/material/qmldir
@@ -1,4 +1,4 @@
module QtQuick.Controls.Material
-plugin qtquickcontrols2materialstyleplugin
+plugin qqc2materialstyleplugin
classname QtQuickControls2MaterialStylePlugin
depends QtQuick.Controls 2.5
diff --git a/src/imports/controls/material/qquickmaterialstyle.cpp b/src/imports/controls/material/qquickmaterialstyle.cpp
index 35afeb00..d343f2f5 100644
--- a/src/imports/controls/material/qquickmaterialstyle.cpp
+++ b/src/imports/controls/material/qquickmaterialstyle.cpp
@@ -469,14 +469,13 @@ void QQuickMaterialStyle::setTheme(Theme theme)
m_theme = theme;
propagateTheme();
- emit themeChanged();
- emit paletteChanged();
+ themeChange();
if (!m_customAccent)
- emit accentChanged();
+ accentChange();
if (!m_hasBackground)
- emit backgroundChanged();
+ backgroundChange();
if (!m_hasForeground)
- emit foregroundChanged();
+ foregroundChange();
}
void QQuickMaterialStyle::inheritTheme(Theme theme)
@@ -486,14 +485,13 @@ void QQuickMaterialStyle::inheritTheme(Theme theme)
m_theme = theme;
propagateTheme();
- emit themeChanged();
- emit paletteChanged();
+ themeChange();
if (!m_customAccent)
- emit accentChanged();
+ accentChange();
if (!m_hasBackground)
- emit backgroundChanged();
+ backgroundChange();
if (!m_hasForeground)
- emit foregroundChanged();
+ foregroundChange();
}
void QQuickMaterialStyle::propagateTheme()
@@ -516,6 +514,19 @@ void QQuickMaterialStyle::resetTheme()
inheritTheme(material ? material->theme() : globalTheme);
}
+void QQuickMaterialStyle::themeChange()
+{
+ emit themeChanged();
+ emit themeOrAccentChanged();
+ emit primaryHighlightedTextColor();
+ emit buttonColorChanged();
+ emit buttonDisabledColorChanged();
+ emit dialogColorChanged();
+ emit tooltipColorChanged();
+ emit toolBarColorChanged();
+ emit toolTextColorChanged();
+}
+
QVariant QQuickMaterialStyle::primary() const
{
return primaryColor();
@@ -535,8 +546,7 @@ void QQuickMaterialStyle::setPrimary(const QVariant &var)
m_customPrimary = custom;
m_primary = primary;
propagatePrimary();
- emit primaryChanged();
- emit paletteChanged();
+ primaryChange();
}
void QQuickMaterialStyle::inheritPrimary(uint primary, bool custom)
@@ -547,8 +557,7 @@ void QQuickMaterialStyle::inheritPrimary(uint primary, bool custom)
m_customPrimary = custom;
m_primary = primary;
propagatePrimary();
- emit primaryChanged();
- emit paletteChanged();
+ primaryChange();
}
void QQuickMaterialStyle::propagatePrimary()
@@ -575,6 +584,13 @@ void QQuickMaterialStyle::resetPrimary()
inheritPrimary(globalPrimary, false);
}
+void QQuickMaterialStyle::primaryChange()
+{
+ emit primaryChanged();
+ emit toolBarColorChanged();
+ emit toolTextColorChanged();
+}
+
QVariant QQuickMaterialStyle::accent() const
{
return accentColor();
@@ -594,8 +610,7 @@ void QQuickMaterialStyle::setAccent(const QVariant &var)
m_customAccent = custom;
m_accent = accent;
propagateAccent();
- emit accentChanged();
- emit paletteChanged();
+ accentChange();
}
void QQuickMaterialStyle::inheritAccent(uint accent, bool custom)
@@ -606,8 +621,7 @@ void QQuickMaterialStyle::inheritAccent(uint accent, bool custom)
m_customAccent = custom;
m_accent = accent;
propagateAccent();
- emit accentChanged();
- emit paletteChanged();
+ accentChange();
}
void QQuickMaterialStyle::propagateAccent()
@@ -634,6 +648,13 @@ void QQuickMaterialStyle::resetAccent()
inheritAccent(globalAccent, false);
}
+void QQuickMaterialStyle::accentChange()
+{
+ emit accentChanged();
+ emit themeOrAccentChanged();
+ emit buttonColorChanged();
+}
+
QVariant QQuickMaterialStyle::foreground() const
{
if (!m_hasForeground)
@@ -660,7 +681,7 @@ void QQuickMaterialStyle::setForeground(const QVariant &var)
m_customForeground = custom;
m_foreground = foreground;
propagateForeground();
- emit foregroundChanged();
+ foregroundChange();
}
void QQuickMaterialStyle::inheritForeground(uint foreground, bool custom, bool has)
@@ -672,7 +693,7 @@ void QQuickMaterialStyle::inheritForeground(uint foreground, bool custom, bool h
m_customForeground = custom;
m_foreground = foreground;
propagateForeground();
- emit foregroundChanged();
+ foregroundChange();
}
void QQuickMaterialStyle::propagateForeground()
@@ -697,6 +718,14 @@ void QQuickMaterialStyle::resetForeground()
inheritForeground(material ? material->m_foreground : globalForeground, true, material ? material->m_hasForeground : false);
}
+void QQuickMaterialStyle::foregroundChange()
+{
+ emit foregroundChanged();
+ emit primaryHighlightedTextColorChanged();
+ // TODO: This causes a binding loop: see QTBUG-85699 and the comments on its fix
+// emit toolTextColorChanged();
+}
+
QVariant QQuickMaterialStyle::background() const
{
return backgroundColor();
@@ -717,8 +746,7 @@ void QQuickMaterialStyle::setBackground(const QVariant &var)
m_customBackground = custom;
m_background = background;
propagateBackground();
- emit backgroundChanged();
- emit paletteChanged();
+ backgroundChange();
}
void QQuickMaterialStyle::inheritBackground(uint background, bool custom, bool has)
@@ -730,8 +758,7 @@ void QQuickMaterialStyle::inheritBackground(uint background, bool custom, bool h
m_customBackground = custom;
m_background = background;
propagateBackground();
- emit backgroundChanged();
- emit paletteChanged();
+ backgroundChange();
}
void QQuickMaterialStyle::propagateBackground()
@@ -756,6 +783,15 @@ void QQuickMaterialStyle::resetBackground()
inheritBackground(material ? material->m_background : globalBackground, true, material ? material->m_hasBackground : false);
}
+void QQuickMaterialStyle::backgroundChange()
+{
+ emit backgroundChanged();
+ emit buttonColorChanged();
+ emit dialogColorChanged();
+ emit tooltipColorChanged();
+ emit toolBarColorChanged();
+}
+
int QQuickMaterialStyle::elevation() const
{
return m_elevation;
@@ -767,7 +803,7 @@ void QQuickMaterialStyle::setElevation(int elevation)
return;
m_elevation = elevation;
- emit elevationChanged();
+ elevationChange();
}
void QQuickMaterialStyle::resetElevation()
@@ -775,6 +811,12 @@ void QQuickMaterialStyle::resetElevation()
setElevation(0);
}
+void QQuickMaterialStyle::elevationChange()
+{
+ emit elevationChanged();
+ emit buttonDisabledColorChanged();
+}
+
QColor QQuickMaterialStyle::primaryColor() const
{
if (m_customPrimary)
diff --git a/src/imports/controls/material/qquickmaterialstyle_p.h b/src/imports/controls/material/qquickmaterialstyle_p.h
index d2a89761..1207e9cc 100644
--- a/src/imports/controls/material/qquickmaterialstyle_p.h
+++ b/src/imports/controls/material/qquickmaterialstyle_p.h
@@ -66,38 +66,38 @@ class QQuickMaterialStyle : public QQuickAttachedObject
Q_PROPERTY(QColor primaryColor READ primaryColor NOTIFY primaryChanged FINAL) // TODO: remove?
Q_PROPERTY(QColor accentColor READ accentColor NOTIFY accentChanged FINAL) // TODO: remove?
Q_PROPERTY(QColor backgroundColor READ backgroundColor NOTIFY backgroundChanged FINAL)
- Q_PROPERTY(QColor primaryTextColor READ primaryTextColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor primaryHighlightedTextColor READ primaryHighlightedTextColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor secondaryTextColor READ secondaryTextColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor hintTextColor READ hintTextColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor textSelectionColor READ textSelectionColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor dropShadowColor READ dropShadowColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor dividerColor READ dividerColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor iconColor READ iconColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor iconDisabledColor READ iconDisabledColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor buttonColor READ buttonColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor buttonDisabledColor READ buttonDisabledColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor highlightedButtonColor READ highlightedButtonColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor frameColor READ frameColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor rippleColor READ rippleColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor highlightedRippleColor READ highlightedRippleColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor switchUncheckedTrackColor READ switchUncheckedTrackColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor switchCheckedTrackColor READ switchCheckedTrackColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor switchUncheckedHandleColor READ switchUncheckedHandleColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor switchCheckedHandleColor READ switchCheckedHandleColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor switchDisabledTrackColor READ switchDisabledTrackColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor switchDisabledHandleColor READ switchDisabledHandleColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor scrollBarColor READ scrollBarColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor scrollBarHoveredColor READ scrollBarHoveredColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor scrollBarPressedColor READ scrollBarPressedColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor dialogColor READ dialogColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor backgroundDimColor READ backgroundDimColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor listHighlightColor READ listHighlightColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor tooltipColor READ tooltipColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor toolBarColor READ toolBarColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor toolTextColor READ toolTextColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor spinBoxDisabledIconColor READ spinBoxDisabledIconColor NOTIFY paletteChanged FINAL)
- Q_PROPERTY(QColor sliderDisabledColor READ sliderDisabledColor NOTIFY paletteChanged FINAL)
+ Q_PROPERTY(QColor primaryTextColor READ primaryTextColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor primaryHighlightedTextColor READ primaryHighlightedTextColor NOTIFY primaryHighlightedTextColorChanged FINAL)
+ Q_PROPERTY(QColor secondaryTextColor READ secondaryTextColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor hintTextColor READ hintTextColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor textSelectionColor READ textSelectionColor NOTIFY themeOrAccentChanged FINAL)
+ Q_PROPERTY(QColor dropShadowColor READ dropShadowColor CONSTANT FINAL)
+ Q_PROPERTY(QColor dividerColor READ dividerColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor iconColor READ iconColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor iconDisabledColor READ iconDisabledColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor buttonColor READ buttonColor NOTIFY buttonColorChanged FINAL)
+ Q_PROPERTY(QColor buttonDisabledColor READ buttonDisabledColor NOTIFY buttonDisabledColorChanged FINAL)
+ Q_PROPERTY(QColor highlightedButtonColor READ highlightedButtonColor NOTIFY buttonColorChanged FINAL)
+ Q_PROPERTY(QColor frameColor READ frameColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor rippleColor READ rippleColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor highlightedRippleColor READ highlightedRippleColor NOTIFY themeOrAccentChanged FINAL)
+ Q_PROPERTY(QColor switchUncheckedTrackColor READ switchUncheckedTrackColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor switchCheckedTrackColor READ switchCheckedTrackColor NOTIFY themeOrAccentChanged FINAL)
+ Q_PROPERTY(QColor switchUncheckedHandleColor READ switchUncheckedHandleColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor switchCheckedHandleColor READ switchCheckedHandleColor NOTIFY themeOrAccentChanged FINAL)
+ Q_PROPERTY(QColor switchDisabledTrackColor READ switchDisabledTrackColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor switchDisabledHandleColor READ switchDisabledHandleColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor scrollBarColor READ scrollBarColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor scrollBarHoveredColor READ scrollBarHoveredColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor scrollBarPressedColor READ scrollBarPressedColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor dialogColor READ dialogColor NOTIFY dialogColorChanged FINAL)
+ Q_PROPERTY(QColor backgroundDimColor READ backgroundDimColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor listHighlightColor READ listHighlightColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor tooltipColor READ tooltipColor NOTIFY tooltipColorChanged FINAL)
+ Q_PROPERTY(QColor toolBarColor READ toolBarColor NOTIFY toolBarColorChanged FINAL)
+ Q_PROPERTY(QColor toolTextColor READ toolTextColor NOTIFY toolTextColorChanged FINAL)
+ Q_PROPERTY(QColor spinBoxDisabledIconColor READ spinBoxDisabledIconColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor sliderDisabledColor READ sliderDisabledColor NOTIFY themeChanged FINAL REVISION 15)
Q_PROPERTY(int touchTarget READ touchTarget CONSTANT FINAL)
Q_PROPERTY(int buttonHeight READ buttonHeight CONSTANT FINAL)
@@ -174,34 +174,40 @@ public:
void inheritTheme(Theme theme);
void propagateTheme();
void resetTheme();
+ void themeChange();
QVariant primary() const;
void setPrimary(const QVariant &accent);
void inheritPrimary(uint primary, bool custom);
void propagatePrimary();
void resetPrimary();
+ void primaryChange();
QVariant accent() const;
void setAccent(const QVariant &accent);
void inheritAccent(uint accent, bool custom);
void propagateAccent();
void resetAccent();
+ void accentChange();
QVariant foreground() const;
void setForeground(const QVariant &foreground);
void inheritForeground(uint foreground, bool custom, bool has);
void propagateForeground();
void resetForeground();
+ void foregroundChange();
QVariant background() const;
void setBackground(const QVariant &background);
void inheritBackground(uint background, bool custom, bool has);
void propagateBackground();
void resetBackground();
+ void backgroundChange();
int elevation() const;
void setElevation(int elevation);
void resetElevation();
+ void elevationChange();
QColor primaryColor() const;
QColor accentColor() const;
@@ -265,7 +271,15 @@ Q_SIGNALS:
void backgroundChanged();
void elevationChanged();
- void paletteChanged();
+ void themeOrAccentChanged();
+
+ void primaryHighlightedTextColorChanged();
+ void buttonColorChanged();
+ void buttonDisabledColorChanged();
+ void dialogColorChanged();
+ void tooltipColorChanged();
+ void toolBarColorChanged();
+ void toolTextColorChanged();
protected:
void attachedParentChange(QQuickAttachedObject *newParent, QQuickAttachedObject *oldParent) override;
diff --git a/src/imports/controls/plugins.qmltypes b/src/imports/controls/plugins.qmltypes
index c3e53431..e8212c55 100644
--- a/src/imports/controls/plugins.qmltypes
+++ b/src/imports/controls/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls 2.14'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls 2.15'
Module {
dependencies: [
@@ -589,6 +589,14 @@ Module {
defaultProperty: "contentData"
}
Component {
+ prototype: "QQuickHorizontalHeaderView"
+ name: "QtQuick.Controls/HorizontalHeaderView 2.15"
+ exports: ["QtQuick.Controls/HorizontalHeaderView 2.15"]
+ exportMetaObjectRevisions: [15]
+ isComposite: true
+ defaultProperty: "flickableData"
+ }
+ Component {
prototype: "QQuickItemDelegate"
name: "QtQuick.Controls/ItemDelegate 2.0"
exports: ["QtQuick.Controls/ItemDelegate 2.0"]
@@ -876,4 +884,12 @@ Module {
isComposite: true
defaultProperty: "data"
}
+ Component {
+ prototype: "QQuickVerticalHeaderView"
+ name: "QtQuick.Controls/VerticalHeaderView 2.15"
+ exports: ["QtQuick.Controls/VerticalHeaderView 2.15"]
+ exportMetaObjectRevisions: [15]
+ isComposite: true
+ defaultProperty: "flickableData"
+ }
}
diff --git a/src/imports/controls/universal/ComboBox.qml b/src/imports/controls/universal/ComboBox.qml
index fd2d8935..9b88ccf9 100644
--- a/src/imports/controls/universal/ComboBox.qml
+++ b/src/imports/controls/universal/ComboBox.qml
@@ -56,7 +56,7 @@ T.ComboBox {
Universal.theme: editable && activeFocus ? Universal.Light : undefined
delegate: ItemDelegate {
- width: parent.width
+ width: ListView.view.width
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal
highlighted: control.highlightedIndex === index
diff --git a/src/imports/controls/universal/DialogButtonBox.qml b/src/imports/controls/universal/DialogButtonBox.qml
index 0458c39d..103b46c2 100644
--- a/src/imports/controls/universal/DialogButtonBox.qml
+++ b/src/imports/controls/universal/DialogButtonBox.qml
@@ -59,6 +59,7 @@ T.DialogButtonBox {
}
contentItem: ListView {
+ implicitWidth: contentWidth
model: control.contentModel
spacing: control.spacing
orientation: ListView.Horizontal
diff --git a/src/imports/controls/universal/plugins.qmltypes b/src/imports/controls/universal/plugins.qmltypes
index 1734c01b..c38e39e1 100644
--- a/src/imports/controls/universal/plugins.qmltypes
+++ b/src/imports/controls/universal/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls.Universal 2.14'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls.Universal 2.15'
Module {
dependencies: ["QtQuick.Controls 2.0"]
diff --git a/src/imports/platform/platform.pro b/src/imports/platform/platform.pro
index 043b0172..d9bcfcb8 100644
--- a/src/imports/platform/platform.pro
+++ b/src/imports/platform/platform.pro
@@ -1,9 +1,9 @@
TARGET = qtlabsplatformplugin
TARGETPATH = Qt/labs/platform
-IMPORT_VERSION = 1.0
+IMPORT_VERSION = 1.1
QT += qml quick
-QT_PRIVATE += core-private gui-private qml-private quick-private
+QT_PRIVATE += core-private gui-private qml-private quick-private quicktemplates2-private
DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
diff --git a/src/imports/platform/plugins.qmltypes b/src/imports/platform/plugins.qmltypes
index 7b165ef3..e9312047 100644
--- a/src/imports/platform/plugins.qmltypes
+++ b/src/imports/platform/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt.labs.platform 1.0'
+// 'qmlplugindump -nonrelocatable Qt.labs.platform 1.1'
Module {
dependencies: ["QtQuick 2.0"]
@@ -288,8 +288,11 @@ Module {
Component {
name: "QQuickPlatformMenuItem"
prototype: "QObject"
- exports: ["Qt.labs.platform/MenuItem 1.0"]
- exportMetaObjectRevisions: [0]
+ exports: [
+ "Qt.labs.platform/MenuItem 1.0",
+ "Qt.labs.platform/MenuItem 1.1"
+ ]
+ exportMetaObjectRevisions: [0, 1]
Property { name: "menu"; type: "QQuickPlatformMenu"; isReadonly: true; isPointer: true }
Property { name: "subMenu"; type: "QQuickPlatformMenu"; isReadonly: true; isPointer: true }
Property { name: "group"; type: "QQuickPlatformMenuItemGroup"; isPointer: true }
diff --git a/src/imports/platform/qquickplatformfiledialog.cpp b/src/imports/platform/qquickplatformfiledialog.cpp
index 2ef08ef6..af5475fa 100644
--- a/src/imports/platform/qquickplatformfiledialog.cpp
+++ b/src/imports/platform/qquickplatformfiledialog.cpp
@@ -353,7 +353,6 @@ void QQuickPlatformFileDialog::resetNameFilters()
}
/*!
- \qmlpropertygroup Qt.labs.platform::FileDialog::selectedNameFilter
\qmlproperty int Qt.labs.platform::FileDialog::selectedNameFilter.index
\qmlproperty string Qt.labs.platform::FileDialog::selectedNameFilter.name
\qmlproperty list<string> Qt.labs.platform::FileDialog::selectedNameFilter.extensions
@@ -553,8 +552,14 @@ QUrl QQuickPlatformFileDialog::addDefaultSuffix(const QUrl &file) const
QUrl url = file;
const QString path = url.path();
const QString suffix = m_options->defaultSuffix();
- if (!suffix.isEmpty() && !path.endsWith(QLatin1Char('/')) && path.lastIndexOf(QLatin1Char('.')) == -1)
+ // Urls with "content" scheme do not require suffixes. Such schemes are
+ // used on Android.
+ const bool isContentScheme = url.scheme() == QStringLiteral("content");
+ if (!isContentScheme && !suffix.isEmpty() && !path.endsWith(QLatin1Char('/'))
+ && path.lastIndexOf(QLatin1Char('.')) == -1) {
url.setPath(path + QLatin1Char('.') + suffix);
+ }
+
return url;
}
diff --git a/src/imports/platform/qquickplatformmenu.cpp b/src/imports/platform/qquickplatformmenu.cpp
index 1f5f52d7..b5289f33 100644
--- a/src/imports/platform/qquickplatformmenu.cpp
+++ b/src/imports/platform/qquickplatformmenu.cpp
@@ -610,10 +610,9 @@ void QQuickPlatformMenu::setFont(const QFont& font)
/*!
\since Qt.labs.platform 1.1 (Qt 5.12)
- \qmlpropertygroup Qt.labs.platform::MenuItem::icon
- \qmlproperty url Qt.labs.platform::MenuItem::icon.source
- \qmlproperty string Qt.labs.platform::MenuItem::icon.name
- \qmlproperty bool Qt.labs.platform::MenuItem::icon.mask
+ \qmlproperty url Qt.labs.platform::Menu::icon.source
+ \qmlproperty string Qt.labs.platform::Menu::icon.name
+ \qmlproperty bool Qt.labs.platform::Menu::icon.mask
This property holds the menu item's icon.
*/
diff --git a/src/imports/platform/qquickplatformmenubar.cpp b/src/imports/platform/qquickplatformmenubar.cpp
index 99757829..f7199083 100644
--- a/src/imports/platform/qquickplatformmenubar.cpp
+++ b/src/imports/platform/qquickplatformmenubar.cpp
@@ -205,6 +205,7 @@ void QQuickPlatformMenuBar::insertMenu(int index, QQuickPlatformMenu *menu)
menu->setMenuBar(this);
if (m_handle)
m_handle->insertMenu(menu->create(), before ? before->handle() : nullptr);
+ menu->sync();
emit menusChanged();
}
diff --git a/src/imports/platform/qquickplatformmenuitem.cpp b/src/imports/platform/qquickplatformmenuitem.cpp
index fa3fdafb..5a8b3798 100644
--- a/src/imports/platform/qquickplatformmenuitem.cpp
+++ b/src/imports/platform/qquickplatformmenuitem.cpp
@@ -43,6 +43,7 @@
#include <QtGui/qkeysequence.h>
#include <QtGui/qpa/qplatformtheme.h>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtQuickTemplates2/private/qquickshortcutcontext_p_p.h>
#include "widgets/qwidgetplatform_p.h"
@@ -120,6 +121,16 @@ QQuickPlatformMenuItem::~QQuickPlatformMenuItem()
m_menu->removeItem(this);
if (m_group)
m_group->removeItem(this);
+#if QT_CONFIG(shortcut)
+ if (m_shortcutId != -1) {
+ QKeySequence sequence;
+ if (m_shortcut.type() == QVariant::Int)
+ sequence = QKeySequence(static_cast<QKeySequence::StandardKey>(m_shortcut.toInt()));
+ else
+ sequence = QKeySequence::fromString(m_shortcut.toString());
+ QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(m_shortcutId, this, sequence);
+ }
+#endif
delete m_iconLoader;
m_iconLoader = nullptr;
delete m_handle;
@@ -165,8 +176,13 @@ void QQuickPlatformMenuItem::sync()
m_handle->setText(m_text);
m_handle->setFont(m_font);
m_handle->setHasExclusiveGroup(m_group && m_group->isExclusive());
- if (m_subMenu && m_subMenu->handle())
- m_handle->setMenu(m_subMenu->handle());
+ if (m_subMenu) {
+ // Sync first as dynamically created menus may need to get the
+ // handle recreated
+ m_subMenu->sync();
+ if (m_subMenu->handle())
+ m_handle->setMenu(m_subMenu->handle());
+ }
#if QT_CONFIG(shortcut)
QKeySequence sequence;
@@ -505,13 +521,50 @@ QVariant QQuickPlatformMenuItem::shortcut() const
return m_shortcut;
}
+bool QQuickPlatformMenuItem::event(QEvent *e)
+{
+#if QT_CONFIG(shortcut)
+ if (e->type() == QEvent::Shortcut) {
+ QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
+ if (se->shortcutId() == m_shortcutId) {
+ activate();
+ return true;
+ }
+ }
+#endif
+ return QObject::event(e);
+}
+
void QQuickPlatformMenuItem::setShortcut(const QVariant& shortcut)
{
if (m_shortcut == shortcut)
return;
+#if QT_CONFIG(shortcut)
+ if (m_shortcutId != -1) {
+ QKeySequence sequence;
+ if (m_shortcut.type() == QVariant::Int)
+ sequence = QKeySequence(static_cast<QKeySequence::StandardKey>(m_shortcut.toInt()));
+ else
+ sequence = QKeySequence::fromString(m_shortcut.toString());
+ QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(m_shortcutId, this, sequence);
+ }
+#endif
m_shortcut = shortcut;
sync();
+#if QT_CONFIG(shortcut)
+ QKeySequence sequence;
+ if (m_shortcut.type() == QVariant::Int)
+ sequence = QKeySequence(static_cast<QKeySequence::StandardKey>(m_shortcut.toInt()));
+ else
+ sequence = QKeySequence::fromString(m_shortcut.toString());
+ if (!sequence.isEmpty()) {
+ m_shortcutId = QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(this, sequence,
+ Qt::WindowShortcut, QQuickShortcutContext::matcher);
+ } else {
+ m_shortcutId = -1;
+ }
+#endif
emit shortcutChanged();
}
@@ -539,7 +592,6 @@ void QQuickPlatformMenuItem::setFont(const QFont& font)
/*!
\since Qt.labs.platform 1.1 (Qt 5.12)
- \qmlpropertygroup Qt.labs.platform::MenuItem::icon
\qmlproperty url Qt.labs.platform::MenuItem::icon.source
\qmlproperty string Qt.labs.platform::MenuItem::icon.name
\qmlproperty bool Qt.labs.platform::MenuItem::icon.mask
diff --git a/src/imports/platform/qquickplatformmenuitem_p.h b/src/imports/platform/qquickplatformmenuitem_p.h
index f1143e64..e3d5258a 100644
--- a/src/imports/platform/qquickplatformmenuitem_p.h
+++ b/src/imports/platform/qquickplatformmenuitem_p.h
@@ -167,6 +167,7 @@ protected:
QQuickPlatformIconLoader *iconLoader() const;
+ bool event(QEvent *e) override;
private Q_SLOTS:
void activate();
void updateIcon();
@@ -187,6 +188,7 @@ private:
QQuickPlatformMenuItemGroup *m_group;
mutable QQuickPlatformIconLoader *m_iconLoader;
QPlatformMenuItem *m_handle;
+ int m_shortcutId = -1;
friend class QQuickPlatformMenu;
friend class QQuickPlatformMenuItemGroup;
diff --git a/src/imports/platform/qquickplatformsystemtrayicon.cpp b/src/imports/platform/qquickplatformsystemtrayicon.cpp
index da483822..442da037 100644
--- a/src/imports/platform/qquickplatformsystemtrayicon.cpp
+++ b/src/imports/platform/qquickplatformsystemtrayicon.cpp
@@ -356,7 +356,6 @@ QRect QQuickPlatformSystemTrayIcon::geometry() const
/*!
\since Qt.labs.platform 1.1 (Qt 5.12)
- \qmlpropertygroup Qt.labs.platform::SystemTrayIcon::icon
\qmlproperty url Qt.labs.platform::SystemTrayIcon::icon.source
\qmlproperty string Qt.labs.platform::SystemTrayIcon::icon.name
\qmlproperty bool Qt.labs.platform::SystemTrayIcon::icon.mask
diff --git a/src/imports/platform/qtlabsplatformplugin.cpp b/src/imports/platform/qtlabsplatformplugin.cpp
index 98d5dcc4..90bdb121 100644
--- a/src/imports/platform/qtlabsplatformplugin.cpp
+++ b/src/imports/platform/qtlabsplatformplugin.cpp
@@ -91,6 +91,7 @@ void QtLabsPlatformPlugin::registerTypes(const char *uri)
qmlRegisterType<QQuickPlatformMenu>(uri, 1, 0, "Menu");
qmlRegisterType<QQuickPlatformMenuBar>(uri, 1, 0, "MenuBar");
qmlRegisterType<QQuickPlatformMenuItem>(uri, 1, 0, "MenuItem");
+ qmlRegisterType<QQuickPlatformMenuItem, 1>(uri, 1, 1, "MenuItem");
qmlRegisterType<QQuickPlatformMenuItemGroup>(uri, 1, 0, "MenuItemGroup");
qmlRegisterType<QQuickPlatformMenuSeparator>(uri, 1, 0, "MenuSeparator");
qRegisterMetaType<QPlatformMenu::MenuType>();
diff --git a/src/imports/templates/plugins.qmltypes b/src/imports/templates/plugins.qmltypes
index da81e095..42c04c80 100644
--- a/src/imports/templates/plugins.qmltypes
+++ b/src/imports/templates/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Templates 2.14'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Templates 2.15'
Module {
dependencies: ["QtQuick 2.9", "QtQuick.Window 2.2"]
@@ -273,10 +273,11 @@ Module {
"QtQuick.Templates/ComboBox 2.0",
"QtQuick.Templates/ComboBox 2.1",
"QtQuick.Templates/ComboBox 2.14",
+ "QtQuick.Templates/ComboBox 2.15",
"QtQuick.Templates/ComboBox 2.2",
"QtQuick.Templates/ComboBox 2.5"
]
- exportMetaObjectRevisions: [0, 1, 14, 2, 5]
+ exportMetaObjectRevisions: [0, 1, 14, 15, 2, 5]
Property { name: "count"; type: "int"; isReadonly: true }
Property { name: "model"; type: "QVariant" }
Property { name: "delegateModel"; type: "QQmlInstanceModel"; isReadonly: true; isPointer: true }
@@ -301,6 +302,7 @@ Module {
Property { name: "implicitIndicatorHeight"; revision: 5; type: "double"; isReadonly: true }
Property { name: "currentValue"; revision: 14; type: "QVariant"; isReadonly: true }
Property { name: "valueRole"; revision: 14; type: "string" }
+ Property { name: "selectTextByMouse"; revision: 15; type: "bool" }
Signal {
name: "activated"
Parameter { name: "index"; type: "int" }
@@ -322,6 +324,7 @@ Module {
Signal { name: "implicitIndicatorHeightChanged"; revision: 5 }
Signal { name: "valueRoleChanged"; revision: 14 }
Signal { name: "currentValueChanged"; revision: 14 }
+ Signal { name: "selectTextByMouseChanged"; revision: 15 }
Method { name: "incrementCurrentIndex" }
Method { name: "decrementCurrentIndex" }
Method { name: "selectAll"; revision: 2 }
@@ -651,6 +654,20 @@ Module {
Signal { name: "implicitLabelHeightChanged"; revision: 5 }
}
Component {
+ name: "QQuickHeaderViewBase"
+ defaultProperty: "flickableData"
+ prototype: "QQuickTableView"
+ Property { name: "textRole"; type: "string" }
+ }
+ Component {
+ name: "QQuickHorizontalHeaderView"
+ defaultProperty: "flickableData"
+ prototype: "QQuickHeaderViewBase"
+ exports: ["QtQuick.Templates/HorizontalHeaderView 2.15"]
+ exportMetaObjectRevisions: [0]
+ attachedType: "QQuickTableViewAttached"
+ }
+ Component {
name: "QQuickIcon"
Property { name: "name"; type: "string" }
Property { name: "source"; type: "QUrl" }
@@ -1265,7 +1282,6 @@ Module {
prototype: "QObject"
Property { name: "centerIn"; type: "QQuickItem"; isPointer: true }
}
- Component { name: "QQuickPopupItem"; defaultProperty: "contentData"; prototype: "QQuickPage" }
Component {
name: "QQuickProgressBar"
defaultProperty: "data"
@@ -1355,19 +1371,6 @@ Module {
Method { name: "decrease" }
}
Component {
- name: "QQuickRootItem"
- defaultProperty: "data"
- prototype: "QQuickItem"
- Method {
- name: "setWidth"
- Parameter { name: "w"; type: "int" }
- }
- Method {
- name: "setHeight"
- Parameter { name: "h"; type: "int" }
- }
- }
- Component {
name: "QQuickRoundButton"
defaultProperty: "data"
prototype: "QQuickButton"
@@ -1852,6 +1855,37 @@ Module {
exportMetaObjectRevisions: [0]
}
Component {
+ name: "QQuickTableView"
+ defaultProperty: "flickableData"
+ prototype: "QQuickFlickable"
+ exports: ["QtQuick.Templates/__TableView__ 2.15"]
+ exportMetaObjectRevisions: [15]
+ attachedType: "QQuickTableViewAttached"
+ Property { name: "rows"; type: "int"; isReadonly: true }
+ Property { name: "columns"; type: "int"; isReadonly: true }
+ Property { name: "rowSpacing"; type: "double" }
+ Property { name: "columnSpacing"; type: "double" }
+ Property { name: "rowHeightProvider"; type: "QJSValue" }
+ Property { name: "columnWidthProvider"; type: "QJSValue" }
+ Property { name: "model"; type: "QVariant" }
+ Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "reuseItems"; type: "bool" }
+ Property { name: "contentWidth"; type: "double" }
+ Property { name: "contentHeight"; type: "double" }
+ Property { name: "syncView"; revision: 14; type: "QQuickTableView"; isPointer: true }
+ Property { name: "syncDirection"; revision: 14; type: "Qt::Orientations" }
+ Signal { name: "syncViewChanged"; revision: 14 }
+ Signal { name: "syncDirectionChanged"; revision: 14 }
+ Method { name: "forceLayout" }
+ }
+ Component {
+ name: "QQuickTableViewAttached"
+ prototype: "QObject"
+ Property { name: "view"; type: "QQuickTableView"; isReadonly: true; isPointer: true }
+ Signal { name: "pooled" }
+ Signal { name: "reused" }
+ }
+ Component {
name: "QQuickText"
defaultProperty: "data"
prototype: "QQuickImplicitSizeItem"
@@ -2794,6 +2828,14 @@ Module {
Property { name: "displacement"; type: "double"; isReadonly: true }
}
Component {
+ name: "QQuickVerticalHeaderView"
+ defaultProperty: "flickableData"
+ prototype: "QQuickHeaderViewBase"
+ exports: ["QtQuick.Templates/VerticalHeaderView 2.15"]
+ exportMetaObjectRevisions: [0]
+ attachedType: "QQuickTableViewAttached"
+ }
+ Component {
name: "QQuickWindow"
defaultProperty: "data"
prototype: "QWindow"
@@ -3018,6 +3060,12 @@ Module {
Method { name: "raise" }
Method { name: "lower" }
Method {
+ name: "startSystemResize"
+ type: "bool"
+ Parameter { name: "edges"; type: "Qt::Edges" }
+ }
+ Method { name: "startSystemMove"; type: "bool" }
+ Method {
name: "setTitle"
Parameter { type: "string" }
}
diff --git a/src/imports/templates/qmldir b/src/imports/templates/qmldir
index afb94818..9f3773a8 100644
--- a/src/imports/templates/qmldir
+++ b/src/imports/templates/qmldir
@@ -2,3 +2,4 @@ module QtQuick.Templates
plugin qtquicktemplates2plugin
classname QtQuickTemplates2Plugin
depends QtQuick.Window 2.2
+depends QtQuick 2.9
diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp
index 3b085c56..cee8e53d 100644
--- a/src/imports/templates/qtquicktemplates2plugin.cpp
+++ b/src/imports/templates/qtquicktemplates2plugin.cpp
@@ -142,6 +142,8 @@ private:
QtQuickTemplates2Plugin::QtQuickTemplates2Plugin(QObject *parent)
: QQmlExtensionPlugin(parent), registered(false)
{
+ volatile auto initialization = &QQuickTemplates_initializeModule;
+ Q_UNUSED(initialization)
#if QT_CONFIG(shortcut)
originalContextMatcher = qt_quick_shortcut_context_matcher();
qt_quick_set_shortcut_context_matcher(QQuickShortcutContext::matcher);
diff --git a/src/quickcontrols2/qquickiconimage.cpp b/src/quickcontrols2/qquickiconimage.cpp
index d86afd7f..11bb3bca 100644
--- a/src/quickcontrols2/qquickiconimage.cpp
+++ b/src/quickcontrols2/qquickiconimage.cpp
@@ -42,6 +42,12 @@
QT_BEGIN_NAMESPACE
+QQuickIconImagePrivate::~QQuickIconImagePrivate()
+{
+ qDeleteAll(icon.entries);
+ icon.entries.clear();
+}
+
bool QQuickIconImagePrivate::updateDevicePixelRatio(qreal targetDevicePixelRatio)
{
if (isThemeIcon) {
@@ -132,6 +138,7 @@ void QQuickIconImage::setName(const QString &name)
if (d->icon.iconName == name)
return;
+ qDeleteAll(d->icon.entries);
d->icon = QIconLoader::instance()->loadIcon(name);
if (isComponentComplete())
d->updateIcon();
diff --git a/src/quickcontrols2/qquickiconimage_p_p.h b/src/quickcontrols2/qquickiconimage_p_p.h
index 0c755ff6..11bf5e92 100644
--- a/src/quickcontrols2/qquickiconimage_p_p.h
+++ b/src/quickcontrols2/qquickiconimage_p_p.h
@@ -59,6 +59,7 @@ class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickIconImagePrivate : public QQuickImag
Q_DECLARE_PUBLIC(QQuickIconImage)
public:
+ ~QQuickIconImagePrivate() override;
void updateIcon();
void updateFillMode();
qreal calculateDevicePixelRatio() const;
diff --git a/src/quicktemplates2/accessible/accessible.pri b/src/quicktemplates2/accessible/accessible.pri
new file mode 100644
index 00000000..93660b9f
--- /dev/null
+++ b/src/quicktemplates2/accessible/accessible.pri
@@ -0,0 +1,5 @@
+HEADERS += \
+ $$PWD/qaccessiblequickpage_p.h
+
+SOURCES += \
+ $$PWD/qaccessiblequickpage.cpp
diff --git a/src/quicktemplates2/accessible/qaccessiblequickpage.cpp b/src/quicktemplates2/accessible/qaccessiblequickpage.cpp
new file mode 100644
index 00000000..90ac49f9
--- /dev/null
+++ b/src/quicktemplates2/accessible/qaccessiblequickpage.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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$
+**
+****************************************************************************/
+
+#include "qaccessiblequickpage_p.h"
+#include "qquickpage_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QAccessibleQuickPage::QAccessibleQuickPage(QQuickPage *page)
+ : QAccessibleQuickItem(page)
+{
+}
+
+QAccessibleInterface *QAccessibleQuickPage::child(int index) const
+{
+ const QList<QQuickItem*> kids = orderedChildItems();
+ if (QQuickItem *item = kids.value(index))
+ return QAccessible::queryAccessibleInterface(item);
+ return nullptr;
+}
+
+int QAccessibleQuickPage::indexOfChild(const QAccessibleInterface *iface) const
+{
+ const QList<QQuickItem*> kids = orderedChildItems();
+ return (int)kids.indexOf(static_cast<QQuickItem*>(iface->object()));
+}
+
+QList<QQuickItem *> QAccessibleQuickPage::orderedChildItems() const
+{
+ // Just ensures that the header is first, and footer is last. Other existing order is kept.
+ const QQuickPage *p = page();
+ QList<QQuickItem*> kids = childItems();
+ const qsizetype hidx = kids.indexOf(p->header());
+ if (hidx != -1)
+ kids.move(hidx, 0);
+ const qsizetype fidx = kids.indexOf(p->footer());
+ if (fidx != -1)
+ kids.move(fidx, kids.count() - 1);
+ return kids;
+}
+
+QQuickPage *QAccessibleQuickPage::page() const
+{
+ return static_cast<QQuickPage*>(object());
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/quicktemplates2/accessible/qaccessiblequickpage_p.h b/src/quicktemplates2/accessible/qaccessiblequickpage_p.h
new file mode 100644
index 00000000..9b208c14
--- /dev/null
+++ b/src/quicktemplates2/accessible/qaccessiblequickpage_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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 QACCESSIBLEQUICKPAGE_H
+#define QACCESSIBLEQUICKPAGE_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 <QtQuick/private/qaccessiblequickitem_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPage;
+
+class QAccessibleQuickPage : public QAccessibleQuickItem
+{
+public:
+ QAccessibleQuickPage(QQuickPage *page);
+ QAccessibleInterface *child(int index) const override;
+ int indexOfChild(const QAccessibleInterface *iface) const override;
+private:
+ QQuickPage *page() const;
+ QList<QQuickItem *> orderedChildItems() const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QACCESSIBLEQUICKPAGE_H
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp
index 8632e14c..20cf59c1 100644
--- a/src/quicktemplates2/qquickabstractbutton.cpp
+++ b/src/quicktemplates2/qquickabstractbutton.cpp
@@ -215,8 +215,20 @@ bool QQuickAbstractButtonPrivate::acceptKeyClick(Qt::Key key) const
bool QQuickAbstractButtonPrivate::isPressAndHoldConnected()
{
Q_Q(QQuickAbstractButton);
- const auto signal = &QQuickAbstractButton::pressAndHold;
- const QMetaMethod method = QMetaMethod::fromSignal(signal);
+ static const QMetaMethod method = [&]() {
+ const auto signal = &QQuickAbstractButton::pressAndHold;
+ return QMetaMethod::fromSignal(signal);
+ }();
+ return q->isSignalConnected(method);
+}
+
+bool QQuickAbstractButtonPrivate::isDoubleClickConnected()
+{
+ Q_Q(QQuickAbstractButton);
+ static const QMetaMethod method = [&]() {
+ const auto signal = &QQuickAbstractButton::doubleClicked;
+ return QMetaMethod::fromSignal(signal);
+ }();
return q->isSignalConnected(method);
}
@@ -387,6 +399,17 @@ void QQuickAbstractButtonPrivate::itemImplicitHeightChanged(QQuickItem *item)
emit q->implicitIndicatorHeightChanged();
}
+void QQuickAbstractButtonPrivate::itemDestroyed(QQuickItem *item)
+{
+ Q_Q(QQuickAbstractButton);
+ QQuickControlPrivate::itemDestroyed(item);
+ if (item == indicator) {
+ indicator = nullptr;
+ emit q->implicitIndicatorWidthChanged();
+ emit q->implicitIndicatorHeightChanged();
+ }
+}
+
QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const
{
Q_Q(const QQuickAbstractButton);
@@ -438,6 +461,7 @@ QQuickAbstractButton::QQuickAbstractButton(QQuickItem *parent)
setActiveFocusOnTab(true);
setFocusPolicy(Qt::StrongFocus);
setAcceptedMouseButtons(Qt::LeftButton);
+ setAcceptTouchEvents(true);
#if QT_CONFIG(cursor)
setCursor(Qt::ArrowCursor);
#endif
@@ -449,6 +473,7 @@ QQuickAbstractButton::QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQui
setActiveFocusOnTab(true);
setFocusPolicy(Qt::StrongFocus);
setAcceptedMouseButtons(Qt::LeftButton);
+ setAcceptTouchEvents(true);
#if QT_CONFIG(cursor)
setCursor(Qt::ArrowCursor);
#endif
@@ -734,12 +759,12 @@ void QQuickAbstractButton::setIndicator(QQuickItem *indicator)
}
/*!
- \qmlpropertygroup QtQuick.Controls::AbstractButton::icon
\qmlproperty string QtQuick.Controls::AbstractButton::icon.name
\qmlproperty url QtQuick.Controls::AbstractButton::icon.source
\qmlproperty int QtQuick.Controls::AbstractButton::icon.width
\qmlproperty int QtQuick.Controls::AbstractButton::icon.height
\qmlproperty color QtQuick.Controls::AbstractButton::icon.color
+ \qmlproperty bool QtQuick.Controls::AbstractButton::icon.cache
This property group was added in QtQuick.Controls 2.3.
@@ -1061,7 +1086,7 @@ void QQuickAbstractButton::keyReleaseEvent(QKeyEvent *event)
{
Q_D(QQuickAbstractButton);
QQuickControl::keyReleaseEvent(event);
- if (d->acceptKeyClick(static_cast<Qt::Key>(event->key()))) {
+ if (d->pressed && d->acceptKeyClick(static_cast<Qt::Key>(event->key()))) {
setPressed(false);
nextCheckState();
@@ -1084,9 +1109,11 @@ void QQuickAbstractButton::mousePressEvent(QMouseEvent *event)
void QQuickAbstractButton::mouseDoubleClickEvent(QMouseEvent *event)
{
Q_D(QQuickAbstractButton);
- QQuickControl::mouseDoubleClickEvent(event);
- emit doubleClicked();
- d->wasDoubleClick = true;
+ if (d->isDoubleClickConnected()) {
+ QQuickControl::mouseDoubleClickEvent(event);
+ emit doubleClicked();
+ d->wasDoubleClick = true;
+ }
}
void QQuickAbstractButton::timerEvent(QTimerEvent *event)
diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h
index 9291c1a8..907790dc 100644
--- a/src/quicktemplates2/qquickabstractbutton_p_p.h
+++ b/src/quicktemplates2/qquickabstractbutton_p_p.h
@@ -80,6 +80,7 @@ public:
virtual bool acceptKeyClick(Qt::Key key) const;
bool isPressAndHoldConnected();
+ bool isDoubleClickConnected();
void startPressAndHold();
void stopPressAndHold();
@@ -109,6 +110,7 @@ public:
void itemImplicitWidthChanged(QQuickItem *item) override;
void itemImplicitHeightChanged(QQuickItem *item) override;
+ void itemDestroyed(QQuickItem *item) override;
// copied from qabstractbutton.cpp
static const int AUTO_REPEAT_DELAY = 300;
diff --git a/src/quicktemplates2/qquickaction.cpp b/src/quicktemplates2/qquickaction.cpp
index 0b083339..8610cdfa 100644
--- a/src/quicktemplates2/qquickaction.cpp
+++ b/src/quicktemplates2/qquickaction.cpp
@@ -145,7 +145,7 @@ int QQuickActionPrivate::ShortcutEntry::shortcutId() const
void QQuickActionPrivate::ShortcutEntry::grab(const QKeySequence &shortcut, bool enabled)
{
- if (shortcut.isEmpty())
+ if (shortcut.isEmpty() || m_shortcutId)
return;
Qt::ShortcutContext context = Qt::WindowShortcut; // TODO
@@ -381,12 +381,12 @@ void QQuickAction::setText(const QString &text)
}
/*!
- \qmlpropertygroup QtQuick.Controls::Action::icon
\qmlproperty string QtQuick.Controls::Action::icon.name
\qmlproperty url QtQuick.Controls::Action::icon.source
\qmlproperty int QtQuick.Controls::Action::icon.width
\qmlproperty int QtQuick.Controls::Action::icon.height
\qmlproperty color QtQuick.Controls::Action::icon.color
+ \qmlproperty bool QtQuick.Controls::Action::icon.cache
\include qquickicon.qdocinc grouped-properties
*/
diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp
index 903de676..a9a4ad72 100644
--- a/src/quicktemplates2/qquickapplicationwindow.cpp
+++ b/src/quicktemplates2/qquickapplicationwindow.cpp
@@ -48,6 +48,7 @@
#include "qquickdeferredpointer_p_p.h"
#include <QtCore/private/qobject_p.h>
+#include <QtCore/qscopedvaluerollback.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/private/qquickitemchangelistener_p.h>
@@ -174,6 +175,7 @@ public:
QPalette palette;
QQuickItem *activeFocusControl = nullptr;
QQuickApplicationWindow *q_ptr = nullptr;
+ bool insideRelayout = false;
};
static void layoutItem(QQuickItem *item, qreal y, qreal width)
@@ -192,9 +194,10 @@ static void layoutItem(QQuickItem *item, qreal y, qreal width)
void QQuickApplicationWindowPrivate::relayout()
{
Q_Q(QQuickApplicationWindow);
- if (!complete)
+ if (!complete || insideRelayout)
return;
+ QScopedValueRollback<bool> guard(insideRelayout, true);
QQuickItem *content = q->contentItem();
qreal hh = header && header->isVisible() ? header->height() : 0;
qreal fh = footer && footer->isVisible() ? footer->height() : 0;
@@ -650,6 +653,8 @@ QQuickOverlay *QQuickApplicationWindow::overlay() const
if (!d->overlay) {
d->overlay = new QQuickOverlay(QQuickWindow::contentItem());
+ // make the overlay discoverable by the virtual keyboard
+ d->q_ptr->setProperty("_q_QQuickOverlay", QVariant::fromValue<QQuickItem*>(d->overlay));
d->overlay->stackAfter(QQuickApplicationWindow::contentItem());
}
return d->overlay;
diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp
index d9bbd2bd..e7d99a5d 100644
--- a/src/quicktemplates2/qquickcombobox.cpp
+++ b/src/quicktemplates2/qquickcombobox.cpp
@@ -234,6 +234,7 @@ public:
void updateCurrentText();
void updateCurrentValue();
void updateCurrentTextAndValue();
+ void updateAcceptableInput();
bool isValidIndex(int index) const;
@@ -265,6 +266,8 @@ public:
void itemImplicitWidthChanged(QQuickItem *item) override;
void itemImplicitHeightChanged(QQuickItem *item) override;
+ void setInputMethodHints(Qt::InputMethodHints hints, bool force = false);
+
static void hideOldPopup(QQuickPopup *popup);
bool flat = false;
@@ -288,6 +291,7 @@ public:
QQmlComponent *delegate = nullptr;
QQuickDeferredPointer<QQuickItem> indicator;
QQuickDeferredPointer<QQuickPopup> popup;
+ bool m_acceptableInput = true;
struct ExtraData {
bool editable = false;
@@ -404,13 +408,13 @@ void QQuickComboBoxPrivate::createdItem(int index, QObject *object)
}
if (index == currentIndex && !q->isEditable())
- updateCurrentText();
+ updateCurrentTextAndValue();
}
void QQuickComboBoxPrivate::modelUpdated()
{
if (!extra.isAllocated() || !extra->accepting)
- updateCurrentText();
+ updateCurrentTextAndValue();
}
void QQuickComboBoxPrivate::countChanged()
@@ -476,6 +480,26 @@ void QQuickComboBoxPrivate::updateCurrentTextAndValue()
updateCurrentValue();
}
+void QQuickComboBoxPrivate::updateAcceptableInput()
+{
+ Q_Q(QQuickComboBox);
+
+ if (!contentItem)
+ return;
+
+ const QQuickTextInput *textInputContentItem = qobject_cast<QQuickTextInput *>(contentItem);
+
+ if (!textInputContentItem)
+ return;
+
+ const bool newValue = textInputContentItem->hasAcceptableInput();
+
+ if (m_acceptableInput != newValue) {
+ m_acceptableInput = newValue;
+ emit q->acceptableInputChanged();
+ }
+}
+
bool QQuickComboBoxPrivate::isValidIndex(int index) const
{
return delegateModel && index >= 0 && index < delegateModel->count();
@@ -770,6 +794,16 @@ void QQuickComboBoxPrivate::itemImplicitWidthChanged(QQuickItem *item)
emit q->implicitIndicatorWidthChanged();
}
+void QQuickComboBoxPrivate::setInputMethodHints(Qt::InputMethodHints hints, bool force)
+{
+ Q_Q(QQuickComboBox);
+ if (!force && hints == q->inputMethodHints())
+ return;
+
+ extra.value().inputMethodHints = hints;
+ emit q->inputMethodHintsChanged();
+}
+
void QQuickComboBoxPrivate::itemImplicitHeightChanged(QQuickItem *item)
{
Q_Q(QQuickComboBox);
@@ -787,10 +821,12 @@ void QQuickComboBoxPrivate::hideOldPopup(QQuickPopup *popup)
popup->setVisible(false);
popup->setParentItem(nullptr);
+#if QT_CONFIG(accessibility)
// Remove the item from the accessibility tree.
QQuickAccessibleAttached *accessible = accessibleAttached(popup);
if (accessible)
accessible->setIgnored(true);
+#endif
}
QQuickComboBox::QQuickComboBox(QQuickItem *parent)
@@ -802,7 +838,8 @@ QQuickComboBox::QQuickComboBox(QQuickItem *parent)
#if QT_CONFIG(cursor)
setCursor(Qt::ArrowCursor);
#endif
- setInputMethodHints(Qt::ImhNoPredictiveText);
+ Q_D(QQuickComboBox);
+ d->setInputMethodHints(Qt::ImhNoPredictiveText, true);
}
QQuickComboBox::~QQuickComboBox()
@@ -866,11 +903,11 @@ void QQuickComboBox::setModel(const QVariant& m)
if (QAbstractItemModel* aim = qvariant_cast<QAbstractItemModel *>(d->model)) {
QObjectPrivate::disconnect(aim, &QAbstractItemModel::dataChanged,
- d, QOverload<>::of(&QQuickComboBoxPrivate::updateCurrentText));
+ d, QOverload<>::of(&QQuickComboBoxPrivate::updateCurrentTextAndValue));
}
if (QAbstractItemModel* aim = qvariant_cast<QAbstractItemModel *>(model)) {
QObjectPrivate::connect(aim, &QAbstractItemModel::dataChanged,
- d, QOverload<>::of(&QQuickComboBoxPrivate::updateCurrentText));
+ d, QOverload<>::of(&QQuickComboBoxPrivate::updateCurrentTextAndValue));
}
d->model = model;
@@ -878,7 +915,7 @@ void QQuickComboBox::setModel(const QVariant& m)
emit countChanged();
if (isComponentComplete()) {
setCurrentIndex(count() > 0 ? 0 : -1);
- d->updateCurrentText();
+ d->updateCurrentTextAndValue();
}
emit modelChanged();
}
@@ -1435,11 +1472,7 @@ Qt::InputMethodHints QQuickComboBox::inputMethodHints() const
void QQuickComboBox::setInputMethodHints(Qt::InputMethodHints hints)
{
Q_D(QQuickComboBox);
- if (hints == inputMethodHints())
- return;
-
- d->extra.value().inputMethodHints = hints;
- emit inputMethodHintsChanged();
+ d->setInputMethodHints(hints);
}
/*!
@@ -1474,7 +1507,7 @@ bool QQuickComboBox::isInputMethodComposing() const
bool QQuickComboBox::hasAcceptableInput() const
{
Q_D(const QQuickComboBox);
- return d->contentItem && d->contentItem->property("acceptableInput").toBool();
+ return d->m_acceptableInput;
}
/*!
@@ -1729,7 +1762,11 @@ void QQuickComboBox::focusInEvent(QFocusEvent *event)
{
Q_D(QQuickComboBox);
QQuickControl::focusInEvent(event);
- if (d->contentItem && isEditable())
+ // Setting focus on TextField should not be done when drop down indicator was clicked
+ // That is why, if focus is not set with key reason, it should not be passed to textEdit by default.
+ // Focus on Edit Text should be set only intentionally by user.
+ if ((event->reason() == Qt::TabFocusReason || event->reason() == Qt::BacktabFocusReason ||
+ event->reason() == Qt::ShortcutFocusReason) && d->contentItem && isEditable())
d->contentItem->forceActiveFocus(event->reason());
}
@@ -1869,7 +1906,7 @@ bool QQuickComboBox::event(QEvent *e)
{
Q_D(QQuickComboBox);
if (e->type() == QEvent::LanguageChange)
- d->updateCurrentText();
+ d->updateCurrentTextAndValue();
return QQuickControl::event(e);
}
@@ -1911,7 +1948,7 @@ void QQuickComboBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
QObjectPrivate::disconnect(oldInput, &QQuickTextInput::accepted, d, &QQuickComboBoxPrivate::acceptInput);
QObjectPrivate::disconnect(oldInput, &QQuickTextInput::textChanged, d, &QQuickComboBoxPrivate::updateEditText);
disconnect(oldInput, &QQuickTextInput::inputMethodComposingChanged, this, &QQuickComboBox::inputMethodComposingChanged);
- disconnect(oldInput, &QQuickTextInput::acceptableInputChanged, this, &QQuickComboBox::acceptableInputChanged);
+ QObjectPrivate::disconnect(oldInput, &QQuickTextInput::acceptableInputChanged, d, &QQuickComboBoxPrivate::updateAcceptableInput);
}
}
if (newItem && isEditable()) {
@@ -1920,12 +1957,14 @@ void QQuickComboBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
QObjectPrivate::connect(newInput, &QQuickTextInput::accepted, d, &QQuickComboBoxPrivate::acceptInput);
QObjectPrivate::connect(newInput, &QQuickTextInput::textChanged, d, &QQuickComboBoxPrivate::updateEditText);
connect(newInput, &QQuickTextInput::inputMethodComposingChanged, this, &QQuickComboBox::inputMethodComposingChanged);
- connect(newInput, &QQuickTextInput::acceptableInputChanged, this, &QQuickComboBox::acceptableInputChanged);
+ QObjectPrivate::connect(newInput, &QQuickTextInput::acceptableInputChanged, d, &QQuickComboBoxPrivate::updateAcceptableInput);
}
#if QT_CONFIG(cursor)
newItem->setCursor(Qt::IBeamCursor);
#endif
}
+
+ d->updateAcceptableInput();
}
void QQuickComboBox::localeChange(const QLocale &newLocale, const QLocale &oldLocale)
diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp
index 4eb411c2..a719efd3 100644
--- a/src/quicktemplates2/qquickcontrol.cpp
+++ b/src/quicktemplates2/qquickcontrol.cpp
@@ -158,9 +158,6 @@ QQuickControlPrivate::QQuickControlPrivate()
QQuickControlPrivate::~QQuickControlPrivate()
{
-#if QT_CONFIG(accessibility)
- QAccessible::removeActivationObserver(this);
-#endif
}
void QQuickControlPrivate::init()
@@ -180,11 +177,19 @@ 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;
+ // If the control is on a Flickable that has a pressDelay, the press is sent
+ // as a mouse event rather than touch; so it detect and deal with it.
+ if (touchId == -1 && pressWasTouch) {
+ const auto delta = QVector2D(point.pos() - previousPressPos);
+ const bool overThreshold = QQuickWindowPrivate::dragOverThreshold(delta);
+ if (point.state() == Qt::TouchPointReleased && !overThreshold) {
+ // touchpoint was released near the press position: don't expect any more events, but just handle the release
+ return true;
+ } else if (point.state() == Qt::TouchPointMoved && overThreshold) {
+ // touchpoint was dragged over the drag threshold: accept it, and remember to handle all moves from now on
+ touchId = point.id();
+ return true;
+ }
}
return false;
}
@@ -848,6 +853,13 @@ void QQuickControlPrivate::executeBackground(bool complete)
quickCompleteDeferred(q, backgroundName(), background);
}
+/*
+ \internal
+
+ Hides an item that was replaced by a newer one, rather than
+ deleting it, as the item is typically created in QML and hence
+ we don't own it.
+*/
void QQuickControlPrivate::hideOldItem(QQuickItem *item)
{
if (!item)
@@ -858,10 +870,35 @@ void QQuickControlPrivate::hideOldItem(QQuickItem *item)
item->setVisible(false);
item->setParentItem(nullptr);
+#if QT_CONFIG(accessibility)
// Remove the item from the accessibility tree.
QQuickAccessibleAttached *accessible = accessibleAttached(item);
if (accessible)
accessible->setIgnored(true);
+#endif
+}
+
+/*
+ \internal
+
+ Named "unhide" because it's used for cases where an item
+ that was previously hidden by \l hideOldItem() wants to be
+ shown by a control again, such as a ScrollBar in ScrollView.
+*/
+void QQuickControlPrivate::unhideOldItem(QQuickControl *control, QQuickItem *item)
+{
+ Q_ASSERT(item);
+ qCDebug(lcItemManagement) << "unhiding old item" << item;
+
+ item->setVisible(true);
+ item->setParentItem(control);
+
+#if QT_CONFIG(accessibility)
+ // Add the item back in to the accessibility tree.
+ QQuickAccessibleAttached *accessible = accessibleAttached(item);
+ if (accessible)
+ accessible->setIgnored(false);
+#endif
}
void QQuickControlPrivate::updateBaselineOffset()
@@ -966,6 +1003,9 @@ QQuickControl::~QQuickControl()
Q_D(QQuickControl);
d->removeImplicitSizeListener(d->background, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
d->removeImplicitSizeListener(d->contentItem);
+#if QT_CONFIG(accessibility)
+ QAccessible::removeActivationObserver(d);
+#endif
}
void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h
index fa06c97f..a6e624c9 100644
--- a/src/quicktemplates2/qquickcontrol_p_p.h
+++ b/src/quicktemplates2/qquickcontrol_p_p.h
@@ -122,7 +122,7 @@ public:
void setRightInset(qreal value, bool reset = false);
void setBottomInset(qreal value, bool reset = false);
- void resizeBackground();
+ virtual void resizeBackground();
virtual void resizeContent();
virtual QQuickItem *getContentItem();
@@ -173,6 +173,7 @@ public:
virtual void executeBackground(bool complete = false);
static void hideOldItem(QQuickItem *item);
+ static void unhideOldItem(QQuickControl *control, QQuickItem *item);
void updateBaselineOffset();
diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp
index 99bd0e98..906f952a 100644
--- a/src/quicktemplates2/qquickdial.cpp
+++ b/src/quicktemplates2/qquickdial.cpp
@@ -41,6 +41,8 @@
#include <QtQuick/private/qquickflickable_p.h>
#include <QtQuickTemplates2/private/qquickcontrol_p_p.h>
+#include <cmath>
+
QT_BEGIN_NAMESPACE
/*!
@@ -116,25 +118,37 @@ public:
void cancelHandle();
void executeHandle(bool complete = false);
+ void updateAllValuesAreInteger();
+
qreal from = 0;
qreal to = 1;
qreal value = 0;
qreal position = 0;
qreal angle = startAngle;
qreal stepSize = 0;
- bool pressed = false;
QPointF pressPoint;
qreal positionBeforePress = 0;
QQuickDial::SnapMode snapMode = QQuickDial::NoSnap;
QQuickDial::InputMode inputMode = QQuickDial::Circular;
+ QQuickDeferredPointer<QQuickItem> handle;
bool wrap = false;
bool live = true;
- QQuickDeferredPointer<QQuickItem> handle;
+ bool pressed = false;
+ bool allValuesAreInteger = false;
};
qreal QQuickDialPrivate::valueAt(qreal position) const
{
- return from + (to - from) * position;
+ qreal value = from + (to - from) * position;
+
+ /* play nice with users expecting that integer from, to and stepSize leads to
+ integer values - given that we are using floating point internally (and in
+ the API of value), this does not hold, but it is easy enough to handle
+ */
+ if (allValuesAreInteger)
+ value = qRound(value);
+
+ return value;
}
qreal QQuickDialPrivate::snapPosition(qreal position) const
@@ -308,11 +322,24 @@ void QQuickDialPrivate::executeHandle(bool complete)
quickCompleteDeferred(q, handleName(), handle);
}
+static bool areRepresentableAsInteger(qreal num1, qreal num2, qreal num3) {
+ auto check = [](qreal number) -> bool { return std::nearbyint(number) == number; };
+ return check(num1) && check(num2) && check(num3);
+}
+
+void QQuickDialPrivate::updateAllValuesAreInteger()
+{
+ allValuesAreInteger = areRepresentableAsInteger(to, from, stepSize) && stepSize != 0.0;
+}
+
QQuickDial::QQuickDial(QQuickItem *parent)
: QQuickControl(*(new QQuickDialPrivate), parent)
{
setActiveFocusOnTab(true);
setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(quicktemplates2_multitouch)
+ setAcceptTouchEvents(true);
+#endif
#if QT_CONFIG(cursor)
setCursor(Qt::ArrowCursor);
#endif
@@ -339,6 +366,7 @@ void QQuickDial::setFrom(qreal from)
d->from = from;
emit fromChanged();
+ d->updateAllValuesAreInteger();
if (isComponentComplete()) {
setValue(d->value);
d->updatePosition();
@@ -366,6 +394,7 @@ void QQuickDial::setTo(qreal to)
return;
d->to = to;
+ d->updateAllValuesAreInteger();
emit toChanged();
if (isComponentComplete()) {
setValue(d->value);
@@ -465,6 +494,7 @@ void QQuickDial::setStepSize(qreal step)
return;
d->stepSize = step;
+ d->updateAllValuesAreInteger();
emit stepSizeChanged();
}
diff --git a/src/quicktemplates2/qquickdialogbuttonbox.cpp b/src/quicktemplates2/qquickdialogbuttonbox.cpp
index f3dd2da1..e6db14eb 100644
--- a/src/quicktemplates2/qquickdialogbuttonbox.cpp
+++ b/src/quicktemplates2/qquickdialogbuttonbox.cpp
@@ -706,34 +706,19 @@ void QQuickDialogButtonBox::updatePolish()
d->updateLayout();
}
-class LanguageEventFilter : public QObject
+bool QQuickDialogButtonBox::event(QEvent *e)
{
-public:
- LanguageEventFilter(QQuickDialogButtonBoxPrivate *box)
- : QObject(box->q_ptr)
- , boxPrivate(box)
- {
- }
-
-protected:
- bool eventFilter(QObject *, QEvent *event)
- {
- if (event->type() == QEvent::LanguageChange)
- boxPrivate->updateLanguage();
- return false;
- }
-
-private:
- QQuickDialogButtonBoxPrivate *boxPrivate;
-};
+ Q_D(QQuickDialogButtonBox);
+ if (e->type() == QEvent::LanguageChange)
+ d->updateLanguage();
+ return QQuickContainer::event(e);
+}
void QQuickDialogButtonBox::componentComplete()
{
Q_D(QQuickDialogButtonBox);
QQuickContainer::componentComplete();
d->updateLayout();
- // TODO: use the solution in QTBUG-78141 instead, when it's implemented.
- qApp->installEventFilter(new LanguageEventFilter(d));
}
void QQuickDialogButtonBox::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
diff --git a/src/quicktemplates2/qquickdialogbuttonbox_p.h b/src/quicktemplates2/qquickdialogbuttonbox_p.h
index 51ae473f..75c05afb 100644
--- a/src/quicktemplates2/qquickdialogbuttonbox_p.h
+++ b/src/quicktemplates2/qquickdialogbuttonbox_p.h
@@ -131,6 +131,7 @@ protected:
#if QT_CONFIG(accessibility)
QAccessible::Role accessibleRole() const override;
#endif
+ bool event(QEvent *e) override;
private:
Q_DISABLE_COPY(QQuickDialogButtonBox)
diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp
index cf2f7558..6f804546 100644
--- a/src/quicktemplates2/qquickdrawer.cpp
+++ b/src/quicktemplates2/qquickdrawer.cpp
@@ -482,6 +482,8 @@ bool QQuickDrawerPrivate::handleMove(QQuickItem *item, const QPointF &point, ulo
bool QQuickDrawerPrivate::handleRelease(QQuickItem *item, const QPointF &point, ulong timestamp)
{
+ if (pressPoint.isNull())
+ return false;
if (!popupItem->keepMouseGrab() && !popupItem->keepTouchGrab()) {
velocityCalculator.reset();
return QQuickPopupPrivate::handleRelease(item, point, timestamp);
diff --git a/src/quicktemplates2/qquickheaderview.cpp b/src/quicktemplates2/qquickheaderview.cpp
index 5c465cc7..d99c09eb 100644
--- a/src/quicktemplates2/qquickheaderview.cpp
+++ b/src/quicktemplates2/qquickheaderview.cpp
@@ -236,16 +236,11 @@ void QQuickHeaderViewBasePrivate::setModelImpl(const QVariant &newModel)
void QQuickHeaderViewBasePrivate::syncModel()
{
Q_Q(QQuickHeaderViewBase);
+
if (assignedSyncView && !m_modelExplicitlySetByUser) {
auto newModel = assignedSyncView->model();
- if (auto m = newModel.value<QAbstractTableModel *>()) {
+ if (auto m = newModel.value<QAbstractItemModel *>())
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();
@@ -369,18 +364,22 @@ QModelIndex QHeaderDataProxyModel::parent(const QModelIndex &child) const
return QModelIndex();
}
-QModelIndex QHeaderDataProxyModel::sibling(int row, int column, const QModelIndex &idx) const
+QModelIndex QHeaderDataProxyModel::sibling(int row, int column, const QModelIndex &) const
{
- return index(row, column, idx);
+ return index(row, column);
}
int QHeaderDataProxyModel::rowCount(const QModelIndex &parent) const
{
+ if (parent.isValid())
+ return 0;
return m_model.isNull() ? -1 : (m_orientation == Qt::Horizontal ? 1 : m_model->rowCount(parent));
}
int QHeaderDataProxyModel::columnCount(const QModelIndex &parent) const
{
+ if (parent.isValid())
+ return 0;
return m_model.isNull() ? -1 : (m_orientation == Qt::Vertical ? 1 : m_model->columnCount(parent));
}
@@ -406,7 +405,8 @@ bool QHeaderDataProxyModel::setData(const QModelIndex &index, const QVariant &va
bool QHeaderDataProxyModel::hasChildren(const QModelIndex &parent) const
{
- Q_UNUSED(parent)
+ if (!parent.isValid())
+ return rowCount(parent) > 0 && columnCount(parent) > 0;
return false;
}
diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp
index c3d80aa0..0043dddd 100644
--- a/src/quicktemplates2/qquickmenu.cpp
+++ b/src/quicktemplates2/qquickmenu.cpp
@@ -170,6 +170,14 @@ static const int SUBMENU_DELAY = 225;
Although \l {MenuItem}{MenuItems} are most commonly used with Menu, it can
contain any type of item.
+ \section1 Margins
+
+ As it is inherited from Popup, Menu supports \l {Popup::}{margins}. By
+ default, all of the built-in styles specify \c 0 for Menu's margins to
+ ensure that the menu is kept within the bounds of the window. To allow a
+ menu to go outside of the window (to animate it moving into view, for
+ example), set the margins property to \c -1.
+
\sa {Customizing Menu}, MenuItem, {Menu Controls}, {Popup Controls}
*/
@@ -208,8 +216,12 @@ public:
QQuickMenuPrivate::QQuickMenuPrivate()
{
- Q_Q(QQuickMenu);
cascade = shouldCascade();
+}
+
+void QQuickMenuPrivate::init()
+{
+ Q_Q(QQuickMenu);
contentModel = new QQmlObjectModel(q);
}
@@ -283,8 +295,8 @@ QQuickItem *QQuickMenuPrivate::beginCreateItem()
QQuickItem *item = qobject_cast<QQuickItem *>(object);
if (!item)
delete object;
-
- QQml_setParent_noEvent(item, q);
+ else
+ QQml_setParent_noEvent(item, q);
return item;
}
@@ -713,9 +725,20 @@ QQuickMenu::QQuickMenu(QObject *parent)
{
Q_D(QQuickMenu);
setFocus(true);
+ d->init();
connect(d->contentModel, &QQmlObjectModel::countChanged, this, &QQuickMenu::countChanged);
}
+QQuickMenu::~QQuickMenu()
+{
+ Q_D(QQuickMenu);
+ // We have to do this to ensure that the change listeners are removed.
+ // It's too late to do this in ~QQuickMenuPrivate, as contentModel has already
+ // been destroyed before that is called.
+ while (d->contentModel->count() > 0)
+ d->removeItem(0, d->itemAt(0));
+}
+
/*!
\qmlmethod Item QtQuick.Controls::Menu::itemAt(int index)
diff --git a/src/quicktemplates2/qquickmenu_p.h b/src/quicktemplates2/qquickmenu_p.h
index 01b970f8..ae653d80 100644
--- a/src/quicktemplates2/qquickmenu_p.h
+++ b/src/quicktemplates2/qquickmenu_p.h
@@ -76,6 +76,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenu : public QQuickPopup
public:
explicit QQuickMenu(QObject *parent = nullptr);
+ ~QQuickMenu();
Q_INVOKABLE QQuickItem *itemAt(int index) const;
Q_INVOKABLE void addItem(QQuickItem *item);
diff --git a/src/quicktemplates2/qquickmenu_p_p.h b/src/quicktemplates2/qquickmenu_p_p.h
index ec48c919..63553f8a 100644
--- a/src/quicktemplates2/qquickmenu_p_p.h
+++ b/src/quicktemplates2/qquickmenu_p_p.h
@@ -73,6 +73,8 @@ public:
return menu->d_func();
}
+ void init();
+
QQuickItem *itemAt(int index) const;
void insertItem(int index, QQuickItem *item);
void moveItem(int from, int to);
diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp
index e9f8801d..91bd5918 100644
--- a/src/quicktemplates2/qquickoverlay.cpp
+++ b/src/quicktemplates2/qquickoverlay.cpp
@@ -311,6 +311,9 @@ QQuickOverlay::QQuickOverlay(QQuickItem *parent)
Q_D(QQuickOverlay);
setZ(1000001); // DefaultWindowDecoration+1
setAcceptedMouseButtons(Qt::AllButtons);
+#if QT_CONFIG(quicktemplates2_multitouch)
+ setAcceptTouchEvents(true);
+#endif
setFiltersChildMouseEvents(true);
setVisible(false);
@@ -468,22 +471,27 @@ bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event)
// background dimming OR over another popup underneath, in case the popup
// does not have background dimming.
if (item == p->dimmer || !p->popupItem->isAncestorOf(item)) {
+ bool handled = false;
switch (event->type()) {
#if QT_CONFIG(quicktemplates2_multitouch)
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
- return d->handleTouchEvent(item, static_cast<QTouchEvent *>(event), popup);
+ handled = d->handleTouchEvent(item, static_cast<QTouchEvent *>(event), popup);
+ break;
#endif
case QEvent::MouseButtonPress:
case QEvent::MouseMove:
case QEvent::MouseButtonRelease:
- return d->handleMouseEvent(item, static_cast<QMouseEvent *>(event), popup);
+ handled = d->handleMouseEvent(item, static_cast<QMouseEvent *>(event), popup);
+ break;
default:
break;
}
+ if (handled)
+ return true;
}
}
return false;
diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp
index 0a72bad7..bc27740b 100644
--- a/src/quicktemplates2/qquickpage.cpp
+++ b/src/quicktemplates2/qquickpage.cpp
@@ -244,6 +244,9 @@ QQuickPage::~QQuickPage()
The title is often displayed at the top of a page to give
the user context about the page they are viewing.
+ Page does not render the title itself, but instead relies
+ on the application to do so. For example:
+
\code
ApplicationWindow {
visible: true
diff --git a/src/quicktemplates2/qquickpageindicator.cpp b/src/quicktemplates2/qquickpageindicator.cpp
index a06884cb..4a2b7f14 100644
--- a/src/quicktemplates2/qquickpageindicator.cpp
+++ b/src/quicktemplates2/qquickpageindicator.cpp
@@ -276,11 +276,17 @@ void QQuickPageIndicator::setInteractive(bool interactive)
d->interactive = interactive;
if (interactive) {
setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(quicktemplates2_multitouch)
+ setAcceptTouchEvents(true);
+#endif
#if QT_CONFIG(cursor)
setCursor(Qt::ArrowCursor);
#endif
} else {
setAcceptedMouseButtons(Qt::NoButton);
+#if QT_CONFIG(quicktemplates2_multitouch)
+ setAcceptTouchEvents(true);
+#endif
#if QT_CONFIG(cursor)
unsetCursor();
#endif
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index b5a6e992..7df80a04 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -51,6 +51,8 @@
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcDimmer, "qt.quick.controls.popup.dimmer")
+
/*!
\qmltype Popup
\inherits QtObject
@@ -215,6 +217,19 @@ QT_BEGIN_NAMESPACE
To ensure that the popup is positioned within the bounds of the enclosing
window, the \l margins property can be set to a non-negative value.
+ \section1 Popup Transitions
+
+ Since Qt 5.15.3 the following properties are restored to their original values from before
+ the enter transition after the exit transition is completed.
+
+ \list
+ \li \l opacity
+ \li \l scale
+ \endlist
+
+ This allows the built-in styles to animate on these properties without losing any explicitly
+ defined value.
+
\sa {Popup Controls}, {Customizing Popup}, ApplicationWindow
*/
@@ -441,6 +456,9 @@ bool QQuickPopupPrivate::prepareEnterTransition()
popupItem->setVisible(true);
getPositioner()->setParentItem(parentItem);
emit q->visibleChanged();
+
+ if (focus)
+ popupItem->setFocus(true);
}
return true;
}
@@ -451,10 +469,16 @@ bool QQuickPopupPrivate::prepareExitTransition()
if (transitionState == ExitTransition && transitionManager.isRunning())
return false;
+ // We need to cache the original scale and opacity values so we can reset it after
+ // the exit transition is done so they have the original values again
+ prevScale = popupItem->scale();
+ prevOpacity = popupItem->opacity();
+
if (transitionState != ExitTransition) {
// The setFocus(false) call below removes any active focus before we're
// able to check it in finalizeExitTransition.
- hadActiveFocusBeforeExitTransition = popupItem->hasActiveFocus();
+ if (!hadActiveFocusBeforeExitTransition)
+ hadActiveFocusBeforeExitTransition = popupItem->hasActiveFocus();
if (focus)
popupItem->setFocus(false);
transitionState = ExitTransition;
@@ -468,8 +492,6 @@ bool QQuickPopupPrivate::prepareExitTransition()
void QQuickPopupPrivate::finalizeEnterTransition()
{
Q_Q(QQuickPopup);
- if (focus)
- popupItem->setFocus(true);
transitionState = NoTransition;
getPositioner()->reposition();
emit q->openedChanged();
@@ -480,8 +502,10 @@ void QQuickPopupPrivate::finalizeExitTransition()
{
Q_Q(QQuickPopup);
getPositioner()->setParentItem(nullptr);
- popupItem->setParentItem(nullptr);
- popupItem->setVisible(false);
+ if (popupItem) {
+ popupItem->setParentItem(nullptr);
+ popupItem->setVisible(false);
+ }
destroyOverlay();
if (hadActiveFocusBeforeExitTransition && window) {
@@ -490,13 +514,14 @@ void QQuickPopupPrivate::finalizeExitTransition()
if (QQuickOverlay *overlay = QQuickOverlay::overlay(window)) {
const auto stackingOrderPopups = QQuickOverlayPrivate::get(overlay)->stackingOrderPopups();
for (auto popup : stackingOrderPopups) {
- if (QQuickPopupPrivate::get(popup)->transitionState != ExitTransition) {
+ if (QQuickPopupPrivate::get(popup)->transitionState != ExitTransition
+ && popup->hasFocus()) {
nextFocusPopup = popup;
break;
}
}
}
- if (nextFocusPopup && nextFocusPopup->hasFocus()) {
+ if (nextFocusPopup) {
nextFocusPopup->forceActiveFocus();
} else {
QQuickApplicationWindow *applicationWindow = qobject_cast<QQuickApplicationWindow*>(window);
@@ -512,6 +537,10 @@ void QQuickPopupPrivate::finalizeExitTransition()
hadActiveFocusBeforeExitTransition = false;
emit q->visibleChanged();
emit q->closed();
+ if (popupItem) {
+ popupItem->setScale(prevScale);
+ popupItem->setOpacity(prevOpacity);
+ }
}
QMarginsF QQuickPopupPrivate::getMargins() const
@@ -574,7 +603,6 @@ void QQuickPopupPrivate::setBottomMargin(qreal value, bool reset)
/*!
\since QtQuick.Controls 2.5 (Qt 5.12)
- \qmlpropertygroup QtQuick.Controls::Popup::anchors
\qmlproperty Object QtQuick.Controls::Popup::anchors.centerIn
Anchors provide a way to position an item by specifying its
@@ -702,6 +730,8 @@ static QQuickItem *createDimmer(QQmlComponent *component, QQuickPopup *popup, QQ
if (component)
component->completeCreate();
}
+ qCDebug(lcDimmer) << "finished creating dimmer from component" << component
+ << "for popup" << popup << "with parent" << parent << "- item is:" << item;
return item;
}
@@ -728,6 +758,7 @@ void QQuickPopupPrivate::createOverlay()
void QQuickPopupPrivate::destroyOverlay()
{
if (dimmer) {
+ qCDebug(lcDimmer) << "destroying dimmer" << dimmer;
dimmer->setParentItem(nullptr);
dimmer->deleteLater();
dimmer = nullptr;
@@ -826,6 +857,12 @@ QQuickPopup::~QQuickPopup()
d->popupItem = nullptr;
delete d->positioner;
d->positioner = nullptr;
+
+ // If the popup is destroyed before the exit transition finishes,
+ // the necessary cleanup (removing modal dimmers that block mouse events,
+ // emitting closed signal, etc.) won't happen. That's why we do it manually here.
+ if (d->transitionState == QQuickPopupPrivate::ExitTransition && d->transitionManager.isRunning())
+ d->finalizeExitTransition();
}
/*!
diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h
index 8a85f914..ef4b112e 100644
--- a/src/quicktemplates2/qquickpopup_p_p.h
+++ b/src/quicktemplates2/qquickpopup_p_p.h
@@ -196,6 +196,8 @@ public:
QList<QQuickStateAction> exitActions;
QQuickPopupTransitionManager transitionManager;
QQuickPopupAnchors *anchors = nullptr;
+ qreal prevOpacity = 0;
+ qreal prevScale = 0;
friend class QQuickPopupTransitionManager;
};
diff --git a/src/quicktemplates2/qquickpopupanchors.cpp b/src/quicktemplates2/qquickpopupanchors.cpp
index 5acc2934..c7ac038d 100644
--- a/src/quicktemplates2/qquickpopupanchors.cpp
+++ b/src/quicktemplates2/qquickpopupanchors.cpp
@@ -47,6 +47,15 @@ QQuickPopupAnchors::QQuickPopupAnchors(QQuickPopup *popup)
d->popup = popup;
}
+QQuickPopupAnchors::~QQuickPopupAnchors()
+{
+ Q_D(const QQuickPopupAnchors);
+ if (d->centerIn) {
+ auto centerInPrivate = QQuickItemPrivate::get(d->centerIn);
+ centerInPrivate->removeItemChangeListener(this, QQuickItemPrivate::Destroyed);
+ }
+}
+
QQuickItem *QQuickPopupAnchors::centerIn() const
{
Q_D(const QQuickPopupAnchors);
@@ -59,8 +68,20 @@ void QQuickPopupAnchors::setCenterIn(QQuickItem *item)
if (item == d->centerIn)
return;
+ if (d->centerIn) {
+ auto centerInPrivate = QQuickItemPrivate::get(d->centerIn);
+ centerInPrivate->removeItemChangeListener(this, QQuickItemPrivate::Destroyed);
+ }
+
d->centerIn = item;
+
+ if (d->centerIn) {
+ auto centerInPrivate = QQuickItemPrivate::get(d->centerIn);
+ centerInPrivate->addItemChangeListener(this, QQuickItemPrivate::Destroyed);
+ }
+
QQuickPopupPrivate::get(d->popup)->reposition();
+
emit centerInChanged();
}
@@ -69,4 +90,9 @@ void QQuickPopupAnchors::resetCenterIn()
setCenterIn(nullptr);
}
+void QQuickPopupAnchors::itemDestroyed(QQuickItem *)
+{
+ resetCenterIn();
+}
+
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickpopupanchors_p.h b/src/quicktemplates2/qquickpopupanchors_p.h
index 531c494e..eff4e23d 100644
--- a/src/quicktemplates2/qquickpopupanchors_p.h
+++ b/src/quicktemplates2/qquickpopupanchors_p.h
@@ -50,6 +50,7 @@
#include <QtCore/qobject.h>
#include <QtQml/qqml.h>
+#include <QtQuick/private/qquickitem_p.h>
#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h>
QT_BEGIN_NAMESPACE
@@ -58,13 +59,14 @@ class QQuickItem;
class QQuickPopupAnchorsPrivate;
class QQuickPopup;
-class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopupAnchors : public QObject
+class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopupAnchors : public QObject, public QQuickItemChangeListener
{
Q_OBJECT
Q_PROPERTY(QQuickItem *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged)
public:
explicit QQuickPopupAnchors(QQuickPopup *popup);
+ ~QQuickPopupAnchors();
QQuickItem *centerIn() const;
void setCenterIn(QQuickItem *item);
@@ -74,6 +76,8 @@ Q_SIGNALS:
void centerInChanged();
private:
+ void itemDestroyed(QQuickItem *item) override;
+
Q_DISABLE_COPY(QQuickPopupAnchors)
Q_DECLARE_PRIVATE(QQuickPopupAnchors)
};
diff --git a/src/quicktemplates2/qquickpopupitem.cpp b/src/quicktemplates2/qquickpopupitem.cpp
index 8e169b0b..0069b9fc 100644
--- a/src/quicktemplates2/qquickpopupitem.cpp
+++ b/src/quicktemplates2/qquickpopupitem.cpp
@@ -164,6 +164,9 @@ QQuickPopupItem::QQuickPopupItem(QQuickPopup *popup)
setParent(popup);
setFlag(ItemIsFocusScope);
setAcceptedMouseButtons(Qt::AllButtons);
+#if QT_CONFIG(quicktemplates2_multitouch)
+ setAcceptTouchEvents(true);
+#endif
#if QT_CONFIG(cursor)
setCursor(Qt::ArrowCursor);
#endif
diff --git a/src/quicktemplates2/qquickpopuppositioner.cpp b/src/quicktemplates2/qquickpopuppositioner.cpp
index dbe8ac1d..1bfaafbe 100644
--- a/src/quicktemplates2/qquickpopuppositioner.cpp
+++ b/src/quicktemplates2/qquickpopuppositioner.cpp
@@ -92,7 +92,10 @@ void QQuickPopupPositioner::setParentItem(QQuickItem *parent)
QQuickItemPrivate::get(parent)->addItemChangeListener(this, ItemChangeTypes);
addAncestorListeners(parent->parentItem());
-
+ // Store the scale property so the end result of any transition that could effect the scale
+ // does not influence the top left of the final popup, so it doesn't appear to flip from one
+ // position to another as a result
+ m_popupScale = m_popup->popupItem()->scale();
if (m_popup->popupItem()->isVisible())
QQuickPopupPrivate::get(m_popup)->reposition();
}
@@ -108,11 +111,10 @@ void QQuickPopupPositioner::reposition()
return;
}
- const qreal scale = popupItem->scale();
- const qreal w = popupItem->width() * scale;
- const qreal h = popupItem->height() * scale;
- const qreal iw = popupItem->implicitWidth() * scale;
- const qreal ih = popupItem->implicitHeight() * scale;
+ const qreal w = popupItem->width() * m_popupScale;
+ const qreal h = popupItem->height() * m_popupScale;
+ const qreal iw = popupItem->implicitWidth() * m_popupScale;
+ const qreal ih = popupItem->implicitHeight() * m_popupScale;
bool widthAdjusted = false;
bool heightAdjusted = false;
@@ -258,9 +260,9 @@ void QQuickPopupPositioner::reposition()
}
if (!p->hasWidth && widthAdjusted && rect.width() > 0)
- popupItem->setWidth(rect.width() / scale);
+ popupItem->setWidth(rect.width() / m_popupScale);
if (!p->hasHeight && heightAdjusted && rect.height() > 0)
- popupItem->setHeight(rect.height() / scale);
+ popupItem->setHeight(rect.height() / m_popupScale);
m_positioning = false;
}
diff --git a/src/quicktemplates2/qquickpopuppositioner_p_p.h b/src/quicktemplates2/qquickpopuppositioner_p_p.h
index 64f57a3f..03a2e2fe 100644
--- a/src/quicktemplates2/qquickpopuppositioner_p_p.h
+++ b/src/quicktemplates2/qquickpopuppositioner_p_p.h
@@ -79,6 +79,7 @@ protected:
bool m_positioning = false;
QQuickItem *m_parentItem = nullptr;
QQuickPopup *m_popup = nullptr;
+ qreal m_popupScale = 1.0;
};
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp
index 9ad12102..f1e5c805 100644
--- a/src/quicktemplates2/qquickrangeslider.cpp
+++ b/src/quicktemplates2/qquickrangeslider.cpp
@@ -625,6 +625,9 @@ QQuickRangeSlider::QQuickRangeSlider(QQuickItem *parent)
setFlag(QQuickItem::ItemIsFocusScope);
setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(quicktemplates2_multitouch)
+ setAcceptTouchEvents(true);
+#endif
#if QT_CONFIG(cursor)
setCursor(Qt::ArrowCursor);
#endif
@@ -662,6 +665,10 @@ void QQuickRangeSlider::setFrom(qreal from)
if (isComponentComplete()) {
d->first->setValue(d->first->value());
d->second->setValue(d->second->value());
+ auto *firstPrivate = QQuickRangeSliderNodePrivate::get(d->first);
+ auto *secondPrivate = QQuickRangeSliderNodePrivate::get(d->second);
+ firstPrivate->updatePosition(true);
+ secondPrivate->updatePosition();
}
}
@@ -690,6 +697,10 @@ void QQuickRangeSlider::setTo(qreal to)
if (isComponentComplete()) {
d->first->setValue(d->first->value());
d->second->setValue(d->second->value());
+ auto *firstPrivate = QQuickRangeSliderNodePrivate::get(d->first);
+ auto *secondPrivate = QQuickRangeSliderNodePrivate::get(d->second);
+ firstPrivate->updatePosition(true);
+ secondPrivate->updatePosition();
}
}
@@ -743,7 +754,6 @@ qreal QQuickRangeSlider::valueAt(qreal position) const
}
/*!
- \qmlpropertygroup QtQuick.Controls::RangeSlider::first
\qmlproperty real QtQuick.Controls::RangeSlider::first.value
\qmlproperty real QtQuick.Controls::RangeSlider::first.position
\qmlproperty real QtQuick.Controls::RangeSlider::first.visualPosition
@@ -822,7 +832,6 @@ QQuickRangeSliderNode *QQuickRangeSlider::first() const
*/
/*!
- \qmlpropertygroup QtQuick.Controls::RangeSlider::second
\qmlproperty real QtQuick.Controls::RangeSlider::second.value
\qmlproperty real QtQuick.Controls::RangeSlider::second.position
\qmlproperty real QtQuick.Controls::RangeSlider::second.visualPosition
diff --git a/src/quicktemplates2/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp
index 678b7942..f0783708 100644
--- a/src/quicktemplates2/qquickscrollbar.cpp
+++ b/src/quicktemplates2/qquickscrollbar.cpp
@@ -77,7 +77,7 @@ QT_BEGIN_NAMESPACE
\list
\li \l orientation
\li \l position
- \li \l size
+ \li \l {ScrollBar::} {size}
\li \l active
\endlist
@@ -205,11 +205,17 @@ void QQuickScrollBarPrivate::setInteractive(bool enabled)
interactive = enabled;
if (interactive) {
q->setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(quicktemplates2_multitouch)
+ q->setAcceptTouchEvents(true);
+#endif
#if QT_CONFIG(cursor)
q->setCursor(Qt::ArrowCursor);
#endif
} else {
q->setAcceptedMouseButtons(Qt::NoButton);
+#if QT_CONFIG(quicktemplates2_multitouch)
+ q->setAcceptTouchEvents(false);
+#endif
#if QT_CONFIG(cursor)
q->unsetCursor();
#endif
@@ -303,6 +309,9 @@ QQuickScrollBar::QQuickScrollBar(QQuickItem *parent)
{
setKeepMouseGrab(true);
setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(quicktemplates2_multitouch)
+ setAcceptTouchEvents(true);
+#endif
#if QT_CONFIG(cursor)
setCursor(Qt::ArrowCursor);
#endif
@@ -788,6 +797,14 @@ void QQuickScrollBarAttachedPrivate::initHorizontal()
if (parent && parent == flickable->parentItem())
horizontal->stackAfter(flickable);
+ // If a scroll bar was previously hidden (due to e.g. setting a new contentItem
+ // on a ScrollView), we need to make sure that we un-hide it.
+ // We don't bother checking if the item is actually the old one, because
+ // if it's not, all of the things the function does (setting parent, visibility, etc.)
+ // should be no-ops anyway.
+ if (auto control = qobject_cast<QQuickControl*>(q_func()->parent()))
+ QQuickControlPrivate::unhideOldItem(control, horizontal);
+
layoutHorizontal();
horizontal->setSize(area->property("widthRatio").toReal());
horizontal->setPosition(area->property("xPosition").toReal());
@@ -809,6 +826,9 @@ void QQuickScrollBarAttachedPrivate::initVertical()
if (parent && parent == flickable->parentItem())
vertical->stackAfter(flickable);
+ if (auto control = qobject_cast<QQuickControl*>(q_func()->parent()))
+ QQuickControlPrivate::unhideOldItem(control, vertical);
+
layoutVertical();
vertical->setSize(area->property("heightRatio").toReal());
vertical->setPosition(area->property("yPosition").toReal());
@@ -818,6 +838,16 @@ void QQuickScrollBarAttachedPrivate::cleanupHorizontal()
{
Q_ASSERT(flickable && horizontal);
+ QQuickControlPrivate::hideOldItem(horizontal);
+ // ScrollBar.qml has a binding to visible and ScrollView.qml has a binding to parent.
+ // If we just set visible to false and parent to null, these bindings will overwrite
+ // them upon component completion as part of the binding evaluation.
+ // That's why we remove the binding completely.
+ const QQmlProperty visibleProperty(horizontal, QStringLiteral("visible"));
+ const QQmlProperty parentProperty(horizontal, QStringLiteral("parent"));
+ QQmlPropertyPrivate::removeBinding(visibleProperty);
+ QQmlPropertyPrivate::removeBinding(parentProperty);
+
disconnect(flickable, &QQuickFlickable::movingHorizontallyChanged, this, &QQuickScrollBarAttachedPrivate::activateHorizontal);
// TODO: export QQuickFlickableVisibleArea
@@ -830,6 +860,12 @@ void QQuickScrollBarAttachedPrivate::cleanupVertical()
{
Q_ASSERT(flickable && vertical);
+ QQuickControlPrivate::hideOldItem(vertical);
+ const QQmlProperty visibleProperty(vertical, QStringLiteral("visible"));
+ const QQmlProperty parentProperty(vertical, QStringLiteral("parent"));
+ QQmlPropertyPrivate::removeBinding(visibleProperty);
+ QQmlPropertyPrivate::removeBinding(parentProperty);
+
disconnect(flickable, &QQuickFlickable::movingVerticallyChanged, this, &QQuickScrollBarAttachedPrivate::activateVertical);
// TODO: export QQuickFlickableVisibleArea
@@ -860,6 +896,9 @@ class QQuickFriendlyFlickable : public QQuickFlickable
void QQuickScrollBarAttachedPrivate::scrollHorizontal()
{
+ if (!flickable)
+ return;
+
QQuickFriendlyFlickable *f = reinterpret_cast<QQuickFriendlyFlickable *>(flickable);
const qreal viewwidth = f->width();
@@ -872,6 +911,9 @@ void QQuickScrollBarAttachedPrivate::scrollHorizontal()
void QQuickScrollBarAttachedPrivate::scrollVertical()
{
+ if (!flickable)
+ return;
+
QQuickFriendlyFlickable *f = reinterpret_cast<QQuickFriendlyFlickable *>(flickable);
const qreal viewheight = f->height();
diff --git a/src/quicktemplates2/qquickscrollbar_p_p.h b/src/quicktemplates2/qquickscrollbar_p_p.h
index 5c7628b9..c58c2ed1 100644
--- a/src/quicktemplates2/qquickscrollbar_p_p.h
+++ b/src/quicktemplates2/qquickscrollbar_p_p.h
@@ -107,6 +107,8 @@ public:
class QQuickScrollBarAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener
{
+ Q_DECLARE_PUBLIC(QQuickScrollBar)
+
public:
static QQuickScrollBarAttachedPrivate *get(QQuickScrollBarAttached *attached)
{
diff --git a/src/quicktemplates2/qquickscrollview.cpp b/src/quicktemplates2/qquickscrollview.cpp
index f9f4c9f8..01e19b16 100644
--- a/src/quicktemplates2/qquickscrollview.cpp
+++ b/src/quicktemplates2/qquickscrollview.cpp
@@ -38,6 +38,7 @@
#include "qquickpane_p_p.h"
#include "qquickscrollbar_p_p.h"
+#include <QtQml/qqmlinfo.h>
#include <QtQuick/private/qquickflickable_p.h>
QT_BEGIN_NAMESPACE
@@ -82,7 +83,13 @@ QT_BEGIN_NAMESPACE
\l {QtQuick.Controls::Pane::}{contentHeight} properties must
be set to the combined size of its contained items.
\li If the content size is less than or equal to the size of the ScrollView,
- it will not be flickable.
+ it will not be scrollable.
+ \li If you want the ScrollView to only scroll vertically, you can bind
+ \l {QtQuick.Controls::Pane::}{contentWidth} to
+ \l {QtQuick.Controls::Control::}{availableWidth}
+ (and vice versa for contentHeight). This will let the contents fill
+ out all the available space horizontally inside the ScrollView, taking
+ any padding or scroll bars into account.
\endlist
\section2 Scroll Bars
@@ -569,7 +576,10 @@ void QQuickScrollView::contentItemChange(QQuickItem *newItem, QQuickItem *oldIte
// assume/require that it has an explicit content size assigned.
d->flickableHasExplicitContentWidth = true;
d->flickableHasExplicitContentHeight = true;
- d->setFlickable(qobject_cast<QQuickFlickable *>(newItem), false);
+ auto newItemAsFlickable = qobject_cast<QQuickFlickable *>(newItem);
+ if (newItem && !newItemAsFlickable)
+ qmlWarning(this) << "ScrollView only supports Flickable types as its contentItem";
+ d->setFlickable(newItemAsFlickable, false);
}
QQuickPane::contentItemChange(newItem, oldItem);
}
diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp
index f4a459fa..ddb4c434 100644
--- a/src/quicktemplates2/qquickslider.cpp
+++ b/src/quicktemplates2/qquickslider.cpp
@@ -274,6 +274,9 @@ QQuickSlider::QQuickSlider(QQuickItem *parent)
setActiveFocusOnTab(true);
setFocusPolicy(Qt::StrongFocus);
setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_CONFIG(quicktemplates2_multitouch)
+ setAcceptTouchEvents(true);
+#endif
#if QT_CONFIG(cursor)
setCursor(Qt::ArrowCursor);
#endif
diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp
index 3482af8c..a3a73472 100644
--- a/src/quicktemplates2/qquickspinbox.cpp
+++ b/src/quicktemplates2/qquickspinbox.cpp
@@ -117,8 +117,8 @@ public:
int effectiveStepSize() const;
- void updateDisplayText();
- void setDisplayText(const QString &displayText);
+ void updateDisplayText(bool modified = false);
+ void setDisplayText(const QString &displayText, bool modified = false);
bool upEnabled() const;
void updateUpEnabled();
@@ -209,24 +209,34 @@ void QQuickSpinBoxPrivate::updateValue()
}
}
+// modified indicates if the value was modified by the user and not programatically
+// this is then passed on to updateDisplayText to indicate that the user has modified
+// the value so it may need to trigger an update of the contentItem's text too
+
bool QQuickSpinBoxPrivate::setValue(int newValue, bool allowWrap, bool modified)
{
Q_Q(QQuickSpinBox);
+ int correctedValue = newValue;
if (q->isComponentComplete())
- newValue = boundValue(newValue, allowWrap);
+ correctedValue = boundValue(newValue, allowWrap);
- if (value == newValue)
+ if (!modified && newValue == correctedValue && newValue == value)
return false;
- value = newValue;
+ const bool emitSignals = (value != correctedValue);
+ value = correctedValue;
- updateDisplayText();
+ updateDisplayText(modified);
updateUpEnabled();
updateDownEnabled();
- emit q->valueChanged();
- if (modified)
- emit q->valueModified();
+ // Only emit the signals if the corrected value is not the same as the
+ // original value to avoid unnecessary updates
+ if (emitSignals) {
+ emit q->valueChanged();
+ if (modified)
+ emit q->valueModified();
+ }
return true;
}
@@ -250,7 +260,7 @@ int QQuickSpinBoxPrivate::effectiveStepSize() const
return from > to ? -1 * stepSize : stepSize;
}
-void QQuickSpinBoxPrivate::updateDisplayText()
+void QQuickSpinBoxPrivate::updateDisplayText(bool modified)
{
Q_Q(QQuickSpinBox);
QString text;
@@ -262,13 +272,14 @@ void QQuickSpinBoxPrivate::updateDisplayText()
} else {
text = locale.toString(value);
}
- setDisplayText(text);
+ setDisplayText(text, modified);
}
-void QQuickSpinBoxPrivate::setDisplayText(const QString &text)
+void QQuickSpinBoxPrivate::setDisplayText(const QString &text, bool modified)
{
Q_Q(QQuickSpinBox);
- if (displayText == text)
+
+ if (!modified && displayText == text)
return;
displayText = text;
@@ -698,7 +709,7 @@ QJSValue QQuickSpinBox::valueFromText() const
if (!d->valueFromText.isCallable()) {
QQmlEngine *engine = qmlEngine(this);
if (engine)
- d->valueFromText = engine->evaluate(QStringLiteral("function(text, locale) { return Number.fromLocaleString(locale, text); }"));
+ d->valueFromText = engine->evaluate(QStringLiteral("(function(text, locale) { return Number.fromLocaleString(locale, text); })"));
}
return d->valueFromText;
}
@@ -715,7 +726,6 @@ void QQuickSpinBox::setValueFromText(const QJSValue &callback)
}
/*!
- \qmlpropertygroup QtQuick.Controls::SpinBox::up
\qmlproperty bool QtQuick.Controls::SpinBox::up.pressed
\qmlproperty Item QtQuick.Controls::SpinBox::up.indicator
\qmlproperty bool QtQuick.Controls::SpinBox::up.hovered
@@ -736,7 +746,6 @@ QQuickSpinButton *QQuickSpinBox::up() const
}
/*!
- \qmlpropertygroup QtQuick.Controls::SpinBox::down
\qmlproperty bool QtQuick.Controls::SpinBox::down.pressed
\qmlproperty Item QtQuick.Controls::SpinBox::down.indicator
\qmlproperty bool QtQuick.Controls::SpinBox::down.hovered
diff --git a/src/quicktemplates2/qquicksplitview.cpp b/src/quicktemplates2/qquicksplitview.cpp
index a3566c56..a06c8d31 100644
--- a/src/quicktemplates2/qquicksplitview.cpp
+++ b/src/quicktemplates2/qquicksplitview.cpp
@@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE
/*!
\qmltype SplitView
- \inherits Control
+ \inherits Container
//! \instantiates QQuickSplitView
\inqmlmodule QtQuick.Controls
\since 5.13
diff --git a/src/quicktemplates2/qquickstackview.cpp b/src/quicktemplates2/qquickstackview.cpp
index 4c314904..135107ea 100644
--- a/src/quicktemplates2/qquickstackview.cpp
+++ b/src/quicktemplates2/qquickstackview.cpp
@@ -558,7 +558,14 @@ QQuickItem *QQuickStackView::find(const QJSValue &callback, LoadBehavior behavio
void QQuickStackView::push(QQmlV4Function *args)
{
Q_D(QQuickStackView);
- QScopedValueRollback<QString> rollback(d->operation, QStringLiteral("push"));
+ const QString operationName = QStringLiteral("push");
+ if (d->modifyingElements) {
+ d->warnOfInterruption(operationName);
+ return;
+ }
+
+ QScopedValueRollback<bool> modifyingElements(d->modifyingElements, true);
+ QScopedValueRollback<QString> operationNameRollback(d->operation, operationName);
if (args->length() <= 0) {
d->warn(QStringLiteral("missing arguments"));
args->setReturnValue(QV4::Encode::null());
@@ -627,6 +634,9 @@ void QQuickStackView::push(QQmlV4Function *args)
items down to (but not including) the first item is popped.
If not specified, only the current item is popped.
+ \note A pop() operation on a stack with depth 1 or 0 does nothing. In such
+ cases, the stack can be emptied using the \l clear() method.
+
\include qquickstackview.qdocinc pop-ownership
An \a operation can be optionally specified as the last argument. Supported
@@ -651,14 +661,15 @@ void QQuickStackView::push(QQmlV4Function *args)
void QQuickStackView::pop(QQmlV4Function *args)
{
Q_D(QQuickStackView);
- if (d->removingElements) {
- d->warn(QStringLiteral("cannot pop while already in the process of removing elements"));
+ const QString operationName = QStringLiteral("pop");
+ if (d->modifyingElements) {
+ d->warnOfInterruption(operationName);
args->setReturnValue(QV4::Encode::null());
return;
}
- QScopedValueRollback<bool> removingElements(d->removingElements, true);
- QScopedValueRollback<QString> rollback(d->operation, QStringLiteral("pop"));
+ QScopedValueRollback<bool> modifyingElements(d->modifyingElements, true);
+ QScopedValueRollback<QString> operationNameRollback(d->operation, operationName);
int argc = args->length();
if (d->elements.count() <= 1 || argc > 2) {
if (argc > 2)
@@ -813,14 +824,15 @@ void QQuickStackView::pop(QQmlV4Function *args)
void QQuickStackView::replace(QQmlV4Function *args)
{
Q_D(QQuickStackView);
- if (d->removingElements) {
- d->warn(QStringLiteral("cannot replace while already in the process of removing elements"));
+ const QString operationName = QStringLiteral("replace");
+ if (d->modifyingElements) {
+ d->warnOfInterruption(operationName);
args->setReturnValue(QV4::Encode::null());
return;
}
- QScopedValueRollback<bool> removingElements(d->removingElements, true);
- QScopedValueRollback<QString> rollback(d->operation, QStringLiteral("replace"));
+ QScopedValueRollback<bool> modifyingElements(d->modifyingElements, true);
+ QScopedValueRollback<QString> operationNameRollback(d->operation, operationName);
if (args->length() <= 0) {
d->warn(QStringLiteral("missing arguments"));
args->setReturnValue(QV4::Encode::null());
@@ -916,12 +928,14 @@ void QQuickStackView::clear(Operation operation)
if (d->elements.isEmpty())
return;
- if (d->removingElements) {
- d->warn(QStringLiteral("cannot clear while already in the process of removing elements"));
+ const QString operationName = QStringLiteral("clear");
+ if (d->modifyingElements) {
+ d->warnOfInterruption(operationName);
return;
}
- QScopedValueRollback<bool> removingElements(d->removingElements, true);
+ QScopedValueRollback<bool> modifyingElements(d->modifyingElements, true);
+ QScopedValueRollback<QString> operationNameRollback(d->operation, operationName);
if (operation != Immediate) {
QQuickStackElement *exit = d->elements.pop();
exit->removal = true;
@@ -1128,7 +1142,7 @@ void QQuickStackView::componentComplete()
QQuickControl::componentComplete();
Q_D(QQuickStackView);
- QScopedValueRollback<QString> rollback(d->operation, QStringLiteral("initialItem"));
+ QScopedValueRollback<QString> operationNameRollback(d->operation, QStringLiteral("initialItem"));
QQuickStackElement *element = nullptr;
QString error;
int oldDepth = d->elements.count();
diff --git a/src/quicktemplates2/qquickstackview_p.cpp b/src/quicktemplates2/qquickstackview_p.cpp
index a280e31d..e9dc5f35 100644
--- a/src/quicktemplates2/qquickstackview_p.cpp
+++ b/src/quicktemplates2/qquickstackview_p.cpp
@@ -56,6 +56,12 @@ void QQuickStackViewPrivate::warn(const QString &error)
qmlWarning(q) << operation << ": " << error;
}
+void QQuickStackViewPrivate::warnOfInterruption(const QString &attemptedOperation)
+{
+ Q_Q(QQuickStackView);
+ qmlWarning(q) << "cannot " << attemptedOperation << " while already in the process of completing a " << operation;
+}
+
void QQuickStackViewPrivate::setCurrentItem(QQuickStackElement *element)
{
Q_Q(QQuickStackView);
diff --git a/src/quicktemplates2/qquickstackview_p_p.h b/src/quicktemplates2/qquickstackview_p_p.h
index b8c4b817..98f9cb98 100644
--- a/src/quicktemplates2/qquickstackview_p_p.h
+++ b/src/quicktemplates2/qquickstackview_p_p.h
@@ -73,6 +73,7 @@ public:
}
void warn(const QString &error);
+ void warnOfInterruption(const QString &attemptedOperation);
void setCurrentItem(QQuickStackElement *element);
@@ -94,7 +95,7 @@ public:
void depthChange(int newDepth, int oldDepth);
bool busy = false;
- bool removingElements = false;
+ bool modifyingElements = false;
QString operation;
QJSValue initialItem;
QQuickItem *currentItem = nullptr;
@@ -114,7 +115,7 @@ public:
return attached->d_func();
}
- void itemParentChanged(QQuickItem *item, QQuickItem *parent);
+ void itemParentChanged(QQuickItem *item, QQuickItem *parent) override;
bool explicitVisible = false;
QQuickStackElement *element = nullptr;
diff --git a/src/quicktemplates2/qquickswipedelegate.cpp b/src/quicktemplates2/qquickswipedelegate.cpp
index 30616f7a..629bf23d 100644
--- a/src/quicktemplates2/qquickswipedelegate.cpp
+++ b/src/quicktemplates2/qquickswipedelegate.cpp
@@ -697,6 +697,11 @@ void QQuickSwipe::close()
if (qFuzzyIsNull(d->position))
return;
+ if (d->control->isPressed()) {
+ // We don't support closing when we're pressed; release() or clicked() should be used instead.
+ return;
+ }
+
d->beginTransition(0.0);
d->wasComplete = false;
d->positionBeforePress = 0.0;
@@ -708,6 +713,29 @@ QQuickSwipeDelegatePrivate::QQuickSwipeDelegatePrivate(QQuickSwipeDelegate *cont
{
}
+void QQuickSwipeDelegatePrivate::resizeBackground()
+{
+ if (!background)
+ return;
+
+ resizingBackground = true;
+
+ QQuickItemPrivate *p = QQuickItemPrivate::get(background);
+ const bool extraAllocated = extra.isAllocated();
+ // Don't check for or set the x here since it will just be overwritten by reposition().
+ if (((!p->widthValid || !extraAllocated || !extra->hasBackgroundWidth))
+ || (extraAllocated && (extra->hasLeftInset || extra->hasRightInset))) {
+ background->setWidth(width - getLeftInset() - getRightInset());
+ }
+ if (((!p->heightValid || !extraAllocated || !extra->hasBackgroundHeight) && qFuzzyIsNull(background->y()))
+ || (extraAllocated && (extra->hasTopInset || extra->hasBottomInset))) {
+ background->setY(getTopInset());
+ background->setHeight(height - getTopInset() - getBottomInset());
+ }
+
+ resizingBackground = false;
+}
+
bool QQuickSwipeDelegatePrivate::handleMousePressEvent(QQuickItem *item, QMouseEvent *event)
{
Q_Q(QQuickSwipeDelegate);
@@ -773,9 +801,10 @@ bool QQuickSwipeDelegatePrivate::handleMouseMoveEvent(QQuickItem *item, QMouseEv
const QPointF mappedEventPos = item->mapToItem(q, event->pos());
const qreal distance = (mappedEventPos - pressPoint).x();
if (!q->keepMouseGrab()) {
- // Taken from QQuickDrawerPrivate::grabMouse; see comments there.
- int threshold = qMax(20, QGuiApplication::styleHints()->startDragDistance() + 5);
- const bool overThreshold = QQuickWindowPrivate::dragOverThreshold(distance, Qt::XAxis, event, threshold);
+ // We used to use the custom threshold that QQuickDrawerPrivate::grabMouse used,
+ // but since it's larger than what Flickable uses, it results in Flickable
+ // stealing events from us (QTBUG-50045), so now we use the default.
+ const bool overThreshold = QQuickWindowPrivate::dragOverThreshold(distance, Qt::XAxis, event);
if (window && overThreshold) {
QQuickItem *grabber = q->window()->mouseGrabberItem();
if (!grabber || !grabber->keepMouseGrab()) {
@@ -889,7 +918,11 @@ bool QQuickSwipeDelegatePrivate::handleMouseReleaseEvent(QQuickItem *item, QMous
swipePrivate->beginTransition(-1.0);
swipePrivate->wasComplete = true;
} else if (!swipePrivate->isTransitioning()) {
- swipePrivate->beginTransition(0.0);
+ // The position is either <= 0.5 or >= -0.5, so the position should go to 0.
+ // However, if the position was already 0 or close to it, we were just clicked,
+ // and we don't need to start a transition.
+ if (!qFuzzyIsNull(swipePrivate->position))
+ swipePrivate->beginTransition(0.0);
swipePrivate->wasComplete = false;
}
@@ -926,13 +959,15 @@ void QQuickSwipeDelegatePrivate::resizeContent()
// If the background and contentItem are repositioned due to a swipe,
// we don't want to call QQuickControlPrivate's implementation of this function,
// as it repositions the contentItem to be visible.
- // However, we still want to resize the control vertically.
+ // However, we still want to position the contentItem vertically
+ // and resize it (in case the control was resized while open).
QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&swipe);
if (!swipePrivate->complete) {
QQuickItemDelegatePrivate::resizeContent();
} else if (contentItem) {
Q_Q(QQuickSwipeDelegate);
contentItem->setY(q->topPadding());
+ contentItem->setWidth(q->availableWidth());
contentItem->setHeight(q->availableHeight());
}
}
@@ -1016,7 +1051,6 @@ QQuickSwipeDelegate::QQuickSwipeDelegate(QQuickItem *parent)
*/
/*!
- \qmlpropertygroup QtQuick.Controls::SwipeDelegate::swipe
\qmlproperty real QtQuick.Controls::SwipeDelegate::swipe.position
\qmlproperty bool QtQuick.Controls::SwipeDelegate::swipe.complete
\qmlproperty bool QtQuick.Controls::SwipeDelegate::swipe.enabled
diff --git a/src/quicktemplates2/qquickswipedelegate_p_p.h b/src/quicktemplates2/qquickswipedelegate_p_p.h
index 78c72ec8..95a999a0 100644
--- a/src/quicktemplates2/qquickswipedelegate_p_p.h
+++ b/src/quicktemplates2/qquickswipedelegate_p_p.h
@@ -67,6 +67,7 @@ public:
bool handleMouseReleaseEvent(QQuickItem *item, QMouseEvent *event);
void resizeContent() override;
+ void resizeBackground() override;
QQuickSwipe swipe;
};
diff --git a/src/quicktemplates2/qquickswipeview.cpp b/src/quicktemplates2/qquickswipeview.cpp
index dab20b93..98d4d22b 100644
--- a/src/quicktemplates2/qquickswipeview.cpp
+++ b/src/quicktemplates2/qquickswipeview.cpp
@@ -310,7 +310,6 @@ void QQuickSwipeView::geometryChanged(const QRectF &newGeometry, const QRectF &o
void QQuickSwipeView::itemAdded(int index, QQuickItem *item)
{
Q_D(QQuickSwipeView);
- QQuickItemPrivate::get(item)->setCulled(true); // QTBUG-51078, QTBUG-51669
if (isComponentComplete())
item->setSize(QSizeF(d->contentItem->width(), d->contentItem->height()));
QQuickSwipeViewAttached *attached = qobject_cast<QQuickSwipeViewAttached *>(qmlAttachedPropertiesObject<QQuickSwipeView>(item));
diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp
index 56dc946d..64fc631d 100644
--- a/src/quicktemplates2/qquicktextarea.cpp
+++ b/src/quicktemplates2/qquicktextarea.cpp
@@ -219,16 +219,25 @@ void QQuickTextAreaPrivate::resizeBackground()
resizingBackground = true;
+ // When using the attached property TextArea.flickable, we reparent the background out
+ // of TextArea and into the Flickable since we don't want the background to move while
+ // flicking. This means that the size of the background should also follow the size of
+ // the Flickable rather than the size of the TextArea.
+ const auto flickable = qobject_cast<QQuickFlickable *>(background->parentItem());
+
QQuickItemPrivate *p = QQuickItemPrivate::get(background);
if (((!p->widthValid || !extra.isAllocated() || !extra->hasBackgroundWidth) && qFuzzyIsNull(background->x()))
|| (extra.isAllocated() && (extra->hasLeftInset || extra->hasRightInset))) {
+ const qreal bgWidth = flickable ? flickable->width() : width;
background->setX(getLeftInset());
- background->setWidth(width - getLeftInset() - getRightInset());
+ background->setWidth(bgWidth - getLeftInset() - getRightInset());
}
+
if (((!p->heightValid || !extra.isAllocated() || !extra->hasBackgroundHeight) && qFuzzyIsNull(background->y()))
|| (extra.isAllocated() && (extra->hasTopInset || extra->hasBottomInset))) {
+ const qreal bgHeight = flickable ? flickable->height() : height;
background->setY(getTopInset());
- background->setHeight(height - getTopInset() - getBottomInset());
+ background->setHeight(bgHeight - getTopInset() - getBottomInset());
}
resizingBackground = false;
@@ -349,6 +358,7 @@ void QQuickTextAreaPrivate::attachFlickable(QQuickFlickable *item)
QObject::connect(flickable, &QQuickFlickable::contentYChanged, q, &QQuickItem::update);
QQuickItemPrivate::get(flickable)->updateOrAddGeometryChangeListener(this, QQuickGeometryChange::Size);
+ QQuickItemPrivate::get(flickable)->addItemChangeListener(this, QQuickItemPrivate::Destroyed);
QObjectPrivate::connect(flickable, &QQuickFlickable::contentWidthChanged, this, &QQuickTextAreaPrivate::resizeFlickableControl);
QObjectPrivate::connect(flickable, &QQuickFlickable::contentHeightChanged, this, &QQuickTextAreaPrivate::resizeFlickableControl);
@@ -369,6 +379,7 @@ void QQuickTextAreaPrivate::detachFlickable()
QObject::disconnect(flickable, &QQuickFlickable::contentYChanged, q, &QQuickItem::update);
QQuickItemPrivate::get(flickable)->updateOrRemoveGeometryChangeListener(this, QQuickGeometryChange::Nothing);
+ QQuickItemPrivate::get(flickable)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed);
QObjectPrivate::disconnect(flickable, &QQuickFlickable::contentWidthChanged, this, &QQuickTextAreaPrivate::resizeFlickableControl);
QObjectPrivate::disconnect(flickable, &QQuickFlickable::contentHeightChanged, this, &QQuickTextAreaPrivate::resizeFlickableControl);
@@ -553,6 +564,8 @@ void QQuickTextAreaPrivate::itemDestroyed(QQuickItem *item)
background = nullptr;
emit q->implicitBackgroundWidthChanged();
emit q->implicitBackgroundHeightChanged();
+ } else if (item == flickable) {
+ detachFlickable();
}
}
@@ -1073,7 +1086,11 @@ QSGNode *QQuickTextArea::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
if (d->flickable)
clipper = d->flickable;
- const QRectF cr = clipper->clipRect().adjusted(leftPadding(), topPadding(), -rightPadding(), -bottomPadding());
+ const QRectF cr = clipper->clipRect().adjusted(
+ leftPadding(), topPadding(),
+ (!d->cursorItem && effectiveHAlign() == HAlignment::AlignRight ? 1 : 0) - rightPadding(),
+ -bottomPadding());
+
clipNode->setRect(!d->flickable ? cr : cr.translated(d->flickable->contentX(), d->flickable->contentY()));
clipNode->update();
diff --git a/src/quicktemplates2/qquicktumbler.cpp b/src/quicktemplates2/qquicktumbler.cpp
index c1d1c00f..35ed9680 100644
--- a/src/quicktemplates2/qquicktumbler.cpp
+++ b/src/quicktemplates2/qquicktumbler.cpp
@@ -662,8 +662,9 @@ void QQuickTumblerPrivate::syncCurrentIndex()
return;
}
- // PathView likes to use 0 as currentIndex for empty models, but we use -1 for that.
- if (q->count() == 0 && actualViewIndex == 0)
+ // actualViewIndex might be 0 or -1 for PathView and ListView respectively,
+ // but we always use -1 for that.
+ if (q->count() == 0 && actualViewIndex <= 0)
return;
ignoreCurrentIndexChanges = true;
diff --git a/src/quicktemplates2/qtquicktemplates2global.cpp b/src/quicktemplates2/qtquicktemplates2global.cpp
new file mode 100644
index 00000000..5d7816b4
--- /dev/null
+++ b/src/quicktemplates2/qtquicktemplates2global.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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 "qquickpage_p.h"
+#include "accessible/qaccessiblequickpage_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#if QT_CONFIG(accessibility)
+static QAccessibleInterface *qQuickAccessibleFactory(const QString &classname, QObject *object)
+{
+ if (classname == u"QQuickPage") {
+ return new QAccessibleQuickPage(qobject_cast<QQuickPage *>(object));
+ }
+ return nullptr;
+}
+#endif
+
+void QQuickTemplates_initializeModule()
+{
+#if QT_CONFIG(accessibility)
+ QAccessible::installFactory(&qQuickAccessibleFactory);
+#endif
+}
+
+Q_CONSTRUCTOR_FUNCTION(QQuickTemplates_initializeModule)
+
+QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qtquicktemplates2global_p.h b/src/quicktemplates2/qtquicktemplates2global_p.h
index e5ee3f2e..9b6610dd 100644
--- a/src/quicktemplates2/qtquicktemplates2global_p.h
+++ b/src/quicktemplates2/qtquicktemplates2global_p.h
@@ -64,6 +64,8 @@ QT_BEGIN_NAMESPACE
# define Q_QUICKTEMPLATES2_PRIVATE_EXPORT
#endif
+Q_QUICKTEMPLATES2_PRIVATE_EXPORT void QQuickTemplates_initializeModule();
+
QT_END_NAMESPACE
#endif // QTQUICKTEMPLATES2GLOBAL_P_H
diff --git a/src/quicktemplates2/quicktemplates2.pro b/src/quicktemplates2/quicktemplates2.pro
index 8ed0151a..a3f778b2 100644
--- a/src/quicktemplates2/quicktemplates2.pro
+++ b/src/quicktemplates2/quicktemplates2.pro
@@ -10,5 +10,11 @@ DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
HEADERS += \
$$PWD/qtquicktemplates2global_p.h
+SOURCES += \
+ $$PWD/qtquicktemplates2global.cpp
+
include(quicktemplates2.pri)
+qtConfig(accessibility) {
+ include(accessible/accessible.pri)
+}
load(qt_module)