diff options
46 files changed, 795 insertions, 281 deletions
diff --git a/.qmake.conf b/.qmake.conf index 36da0899..600fb8ae 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -2,4 +2,4 @@ load(qt_build_config) CONFIG += warning_clean android|ios|qnx|isEmpty(QT.widgets.name): CONFIG += no_desktop -MODULE_VERSION = 5.11.3 +MODULE_VERSION = 5.12.0 diff --git a/dist/changes-5.12.0 b/dist/changes-5.12.0 new file mode 100644 index 00000000..0453ff44 --- /dev/null +++ b/dist/changes-5.12.0 @@ -0,0 +1,25 @@ +Qt 5.12 introduces many new features and improvements as well as bugfixes +over the 5.11.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Dialogs * +**************************************************************************** + + - [QTBUG-69095] Add a signal to the Dialog class to allow the client to + intercept the button presses and optionally prevent further processing + of the event. This allows performing some validation on the fields + before dismissing the dialog. diff --git a/src/controls/ApplicationWindow.qml b/src/controls/ApplicationWindow.qml index fb9cdacd..b739ecae 100644 --- a/src/controls/ApplicationWindow.qml +++ b/src/controls/ApplicationWindow.qml @@ -84,7 +84,7 @@ import QtQuick.Controls.Private 1.0 \note By default, an ApplicationWindow is not visible. - The \l{Qt Quick Controls - Gallery} example is a good starting + The \l{Qt Quick Controls 1 - Gallery} example is a good starting point to explore this type. */ @@ -147,7 +147,7 @@ Window { property alias contentItem : contentArea /*! The style Component for the window. - \sa {Qt Quick Controls Styles QML Types} + \sa {Qt Quick Controls 1 Styles QML Types} */ property Component style: Settings.styleComponent(Settings.style, "ApplicationWindowStyle.qml", root) diff --git a/src/controls/ComboBox.qml b/src/controls/ComboBox.qml index bd42f76b..7c6f93a7 100644 --- a/src/controls/ComboBox.qml +++ b/src/controls/ComboBox.qml @@ -570,11 +570,16 @@ Control { onSelectedTextChanged: popup.currentText = selectedText property string selectedText + property int triggeredIndex: -1 on__SelectedIndexChanged: { if (__selectedIndex === -1) popup.currentText = "" else updateSelectedText() + if (triggeredIndex >= 0 && triggeredIndex == __selectedIndex) { + activated(currentIndex) + triggeredIndex = -1 + } } property string textRole: "" @@ -611,8 +616,7 @@ Control { modelData : ((popup.modelIsArray ? modelData[popup.textRole] : model[popup.textRole]) || '') onTriggered: { - if (index !== currentIndex) - activated(index) + popup.triggeredIndex = index comboBox.editText = text } onTextChanged: if (index === currentIndex) popup.updateSelectedText(); diff --git a/src/controls/Private/BasicTableView.qml b/src/controls/Private/BasicTableView.qml index 2557dca7..1f846b57 100644 --- a/src/controls/Private/BasicTableView.qml +++ b/src/controls/Private/BasicTableView.qml @@ -260,6 +260,17 @@ ScrollView { if (index >= 0 && index <= columnCount && object.Accessible.role === Accessible.ColumnHeader) { object.__view = root columnModel.insert(index, {columnItem: object}) + if (root.__columns[index] !== object) { + // The new column needs to be put into __columns at the specified index + // so the list needs to be recreated to be correct + var arr = [] + for (var i = 0; i < index; ++i) + arr.push(root.__columns[i]) + arr.push(object) + for (i = index; i < root.__columns.length; ++i) + arr.push(root.__columns[i]) + root.__columns = arr + } return object } diff --git a/src/controls/Private/ScrollViewHelper.qml b/src/controls/Private/ScrollViewHelper.qml index 810de91d..53050108 100644 --- a/src/controls/Private/ScrollViewHelper.qml +++ b/src/controls/Private/ScrollViewHelper.qml @@ -68,31 +68,29 @@ Item { anchors.fill: parent - property bool recursionGuard: false - - function doLayout() { - if (!recursionGuard) { - recursionGuard = true + Timer { + id: layoutTimer + interval: 0; + onTriggered: { blockUpdates = true; scrollHelper.contentWidth = flickableItem !== null ? flickableItem.contentWidth : 0 scrollHelper.contentHeight = flickableItem !== null ? flickableItem.contentHeight : 0 scrollHelper.availableWidth = viewport.width scrollHelper.availableHeight = viewport.height blockUpdates = false; - recursionGuard = false } } Connections { target: viewport - onWidthChanged: doLayout() - onHeightChanged: doLayout() + onWidthChanged: layoutTimer.running = true + onHeightChanged: layoutTimer.running = true } Connections { target: flickableItem - onContentWidthChanged: doLayout() - onContentHeightChanged: doLayout() + onContentWidthChanged: layoutTimer.running = true + onContentHeightChanged: layoutTimer.running = true onContentXChanged: { hscrollbar.flash() vscrollbar.flash() diff --git a/src/controls/Private/StackViewSlideDelegate.qml b/src/controls/Private/StackViewSlideDelegate.qml index e64bc38b..dcc14448 100644 --- a/src/controls/Private/StackViewSlideDelegate.qml +++ b/src/controls/Private/StackViewSlideDelegate.qml @@ -135,7 +135,7 @@ StackViewDelegate { to: target.height duration: 300 } - property Component replaceTransition: pushTransition } + property Component replaceTransition: pushTransition } } diff --git a/src/controls/Private/qquickcontrolsettings.cpp b/src/controls/Private/qquickcontrolsettings.cpp index 95c656b2..d06f931a 100644 --- a/src/controls/Private/qquickcontrolsettings.cpp +++ b/src/controls/Private/qquickcontrolsettings.cpp @@ -161,7 +161,7 @@ QQmlComponent *QQuickControlSettings1::styleComponent(const QUrl &styleDirUrl, c styleFileUrl = makeStyleComponentUrl(controlStyleName, m_styleMap.value(QStringLiteral("Base")).m_styleDirPath); } - return new QQmlComponent(qmlEngine(control), styleFileUrl); + return new QQmlComponent(qmlEngine(control), styleFileUrl, this); } static QString relativeStyleImportPath(QQmlEngine *engine, const QString &styleName) diff --git a/src/controls/Private/qquicktreemodeladaptor.cpp b/src/controls/Private/qquicktreemodeladaptor.cpp index 495abc9c..287b388f 100644 --- a/src/controls/Private/qquicktreemodeladaptor.cpp +++ b/src/controls/Private/qquicktreemodeladaptor.cpp @@ -283,6 +283,8 @@ QItemSelection QQuickTreeModelAdaptor1::selectionForRowRange(const QModelIndex return QItemSelection(); return QItemSelection(toIndex, toIndex); } + + to = qMax(to, 0); if (from > to) qSwap(from, to); @@ -360,8 +362,15 @@ void QQuickTreeModelAdaptor1::showModelChildItems(const TreeItem &parentItem, in if (start == 0) { startIdx = rowIdx; } else { - const QModelIndex &prevSiblingIdx = m_model->index(start - 1, 0, parentIndex); - startIdx = lastChildIndex(prevSiblingIdx) + 1; + // Prefer to insert before next sibling instead of after last child of previous, as + // the latter is potentially buggy, see QTBUG-66062 + const QModelIndex &nextSiblingIdx = m_model->index(end + 1, 0, parentIndex); + if (nextSiblingIdx.isValid()) { + startIdx = itemIndex(nextSiblingIdx); + } else { + const QModelIndex &prevSiblingIdx = m_model->index(start - 1, 0, parentIndex); + startIdx = lastChildIndex(prevSiblingIdx) + 1; + } } int rowDepth = rowIdx == 0 ? 0 : parentItem.depth + 1; diff --git a/src/controls/ScrollView.qml b/src/controls/ScrollView.qml index 65ed54d7..b0df615e 100644 --- a/src/controls/ScrollView.qml +++ b/src/controls/ScrollView.qml @@ -183,7 +183,7 @@ FocusScope { /*! \qmlproperty Component ScrollView::style The style Component for this control. - \sa {Qt Quick Controls Styles QML Types} + \sa {Qt Quick Controls 1 Styles QML Types} */ property Component style: Settings.styleComponent(Settings.style, "ScrollViewStyle.qml", root) diff --git a/src/controls/StackView.qml b/src/controls/StackView.qml index 3c8b4e25..aa3596f3 100644 --- a/src/controls/StackView.qml +++ b/src/controls/StackView.qml @@ -58,7 +58,7 @@ import QtQuick.Controls.Private 1.0 as the user navigates deeper into the material, and popped off again when he chooses to go back. - The \l{Qt Quick Controls - Touch Gallery}{touch gallery} example is a good + The \l{Qt Quick Controls 1 - Touch Gallery}{touch gallery} example is a good starting point to understand how StackView works. The following snippet from the example shows how it can be used: diff --git a/src/controls/Styles/Android/plugin.cpp b/src/controls/Styles/Android/plugin.cpp index 646fff36..7a09bb9c 100644 --- a/src/controls/Styles/Android/plugin.cpp +++ b/src/controls/Styles/Android/plugin.cpp @@ -44,13 +44,6 @@ #include "qquickandroidstyle_p.h" #include "qquickandroid9patch_p.h" -static void initResources() -{ -#ifdef QT_STATIC - Q_INIT_RESOURCE(qmake_QtQuick_Controls_Styles_Android); -#endif -} - QT_BEGIN_NAMESPACE class QtQuickControls1AndroidStylePlugin: public QQmlExtensionPlugin @@ -59,7 +52,7 @@ class QtQuickControls1AndroidStylePlugin: public QQmlExtensionPlugin Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: - QtQuickControls1AndroidStylePlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } + QtQuickControls1AndroidStylePlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { } void registerTypes(const char *uri); }; diff --git a/src/controls/Styles/WinRT/plugin.cpp b/src/controls/Styles/WinRT/plugin.cpp index e6d0adfe..b205d75e 100644 --- a/src/controls/Styles/WinRT/plugin.cpp +++ b/src/controls/Styles/WinRT/plugin.cpp @@ -39,15 +39,9 @@ #include <QtCore/qglobal.h> -static void initResources() -{ - Q_INIT_RESOURCE(WinRT); -} - extern "C" { Q_DECL_EXPORT bool qt_quick_controls_style_init() { - initResources(); return true; } diff --git a/src/controls/Styles/styles.pri b/src/controls/Styles/styles.pri index 67c1ab76..c29cebfd 100644 --- a/src/controls/Styles/styles.pri +++ b/src/controls/Styles/styles.pri @@ -108,6 +108,7 @@ STYLES_QML_FILES += \ $$PWD/Base/images/knob.png \ $$PWD/Base/images/needle.png -STYLES_QML_FILES += $$PWD/qmldir +AUX_QML_FILES += $$PWD/qmldir +static: QML_FILES += $$AUX_QML_FILES ios:static: include(iOS/iOS.pri) !qtquickcompiler|static: QML_FILES += $$STYLES_QML_FILES diff --git a/src/controls/controls.pro b/src/controls/controls.pro index 07e8e002..3119d33d 100644 --- a/src/controls/controls.pro +++ b/src/controls/controls.pro @@ -6,7 +6,7 @@ IMPORT_VERSION = 1.5 QT += qml quick quick-private qml-private gui-private core-private -QMAKE_DOCS = $$PWD/doc/qtquickcontrols.qdocconf +QMAKE_DOCS = $$PWD/doc/qtquickcontrols1.qdocconf CONTROLS_QML_FILES = \ ApplicationWindow.qml \ @@ -45,6 +45,7 @@ qtquickcompiler { } else { QML_FILES += $$CONTROLS_QML_FILES !static: CONFIG += qmlcache + else: CONTROLS_QML_FILES += qmldir } SOURCES += $$PWD/plugin.cpp diff --git a/src/controls/doc/qtquickcontrols.qdocconf b/src/controls/doc/qtquickcontrols.qdocconf deleted file mode 100644 index e81777e0..00000000 --- a/src/controls/doc/qtquickcontrols.qdocconf +++ /dev/null @@ -1,77 +0,0 @@ -include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) - -project = QtQuickControls -description = Qt Quick Controls Reference Documentation -version = $QT_VERSION - -qhp.projects = QtQuickControls - -qhp.QtQuickControls.file = qtquickcontrols.qhp -qhp.QtQuickControls.namespace = org.qt-project.qtquickcontrols.$QT_VERSION_TAG -qhp.QtQuickControls.virtualFolder = qtquickcontrols -qhp.QtQuickControls.indexTitle = Qt Quick Controls -qhp.QtQuickControls.indexRoot = -#qhp.QtQuickControls.extraFiles = style/qtquickcontrols.css - -qhp.QtQuickControls.filterAttributes = qtquickcontrols $QT_VERSION qtrefdoc -qhp.QtQuickControls.customFilters.Qt.name = QtQuickControls $QT_VERSION -qhp.QtQuickControls.customFilters.Qt.filterAttributes = qtquickcontrols $QT_VERSION - -qhp.QtQuickControls.subprojects = qqcqmltypes qqcstylesqmltypes qqcexamples - -qhp.QtQuickControls.subprojects.qqcqmltypes.title = Controls QML Types -qhp.QtQuickControls.subprojects.qqcqmltypes.indexTitle = Qt Quick Controls QML Types -qhp.QtQuickControls.subprojects.qqcqmltypes.selectors = group:controls -qhp.QtQuickControls.subprojects.qqcqmltypes.sortPages = true - -qhp.QtQuickControls.subprojects.qqcstylesqmltypes.title = Controls Styles QML Types -qhp.QtQuickControls.subprojects.qqcstylesqmltypes.indexTitle = Qt Quick Controls Styles QML Types -qhp.QtQuickControls.subprojects.qqcstylesqmltypes.selectors = group:controlsstyling -qhp.QtQuickControls.subprojects.qqcstylesqmltypes.sortPages = true - -qhp.QtQuickControls.subprojects.qqcexamples.title = Examples and Tutorials -qhp.QtQuickControls.subprojects.qqcexamples.indexTitle = Qt Quick Controls Examples -qhp.QtQuickControls.subprojects.qqcexamples.selectors = doc:example group:stylingtutorials -qhp.QtQuickControls.subprojects.qqcexamples.sortpages = true - -depends = qtcore qtdoc qtgui qtwidgets qtqml qtquick qtquicklayouts qtquickdialogs qtquickextras qtgraphicaleffects - -# Specify the install path under QT_INSTALL_EXAMPLES -# Examples will be installed under quick/controls - 'controls' subdirectory -# is given as part of \example commands -exampledirs += ../../../examples/quickcontrols/controls \ - snippets -examplesinstallpath = quickcontrols/controls - -headerdirs += .. - -sourcedirs += .. - -sources += ../Private/AbstractCheckable.qml \ - ../Private/BasicButton.qml \ - ../Private/FocusFrame.qml \ - ../Private/ModalPopupBehavior.qml \ - ../Private/ScrollBar.qml \ - ../Private/TabBar.qml \ - ../Private/Control.qml \ - ../Private/qquickstyleitem.cpp \ - ../Private/Style.qml \ - ../Private/qquickabstractstyle_p.h \ - ../Private/qquickabstractstyle.cpp - -excludefiles += ../TableView.qml \ - ../TreeView.qml \ - ../Styles/Base/TableViewStyle.qml \ - ../Styles/Base/TreeViewStyle.qml - -excludedirs += ../Styles/Desktop \ - ../Styles/Android \ - ../Styles/iOS - -imagedirs += images \ - ../../extras/doc/images - -navigation.landingpage = "Qt Quick Controls" -navigation.qmltypespage = "Qt Quick Controls QML Types" - -tagfile = qtquickcontrols.tags diff --git a/src/controls/doc/qtquickcontrols1.qdocconf b/src/controls/doc/qtquickcontrols1.qdocconf new file mode 100644 index 00000000..d2ea0c47 --- /dev/null +++ b/src/controls/doc/qtquickcontrols1.qdocconf @@ -0,0 +1,82 @@ +include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) + +project = QtQuickControls1 +description = Qt Quick Controls 1 Reference Documentation +version = $QT_VERSION + +qhp.projects = QtQuickControls1 + +qhp.QtQuickControls1.file = qtquickcontrols1.qhp +qhp.QtQuickControls1.namespace = org.qt-project.qtquickcontrols1.$QT_VERSION_TAG +qhp.QtQuickControls1.virtualFolder = qtquickcontrols1 +qhp.QtQuickControls1.indexTitle = Qt Quick Controls 1 +qhp.QtQuickControls1.indexRoot = +#qhp.QtQuickControls1.extraFiles = style/qtquickcontrols1.css + +qhp.QtQuickControls1.filterAttributes = qtquickcontrols1 $QT_VERSION qtrefdoc +qhp.QtQuickControls1.customFilters.Qt.name = QtQuickControls1 $QT_VERSION +qhp.QtQuickControls1.customFilters.Qt.filterAttributes = qtquickcontrols1 $QT_VERSION + +qhp.QtQuickControls1.subprojects = qqcqmltypes qqcstylesqmltypes qqcexamples + +qhp.QtQuickControls1.subprojects.qqcqmltypes.title = Controls 1 QML Types +qhp.QtQuickControls1.subprojects.qqcqmltypes.indexTitle = Qt Quick Controls 1 QML Types +qhp.QtQuickControls1.subprojects.qqcqmltypes.selectors = group:controls1 +qhp.QtQuickControls1.subprojects.qqcqmltypes.sortPages = true + +qhp.QtQuickControls1.subprojects.qqcstylesqmltypes.title = Controls 1 Styles QML Types +qhp.QtQuickControls1.subprojects.qqcstylesqmltypes.indexTitle = Qt Quick Controls 1 Styles QML Types +qhp.QtQuickControls1.subprojects.qqcstylesqmltypes.selectors = group:controlsstyling +qhp.QtQuickControls1.subprojects.qqcstylesqmltypes.sortPages = true + +qhp.QtQuickControls1.subprojects.qqcexamples.title = Examples and Tutorials +qhp.QtQuickControls1.subprojects.qqcexamples.indexTitle = Qt Quick Controls 1 Examples +qhp.QtQuickControls1.subprojects.qqcexamples.selectors = doc:example group:stylingtutorials +qhp.QtQuickControls1.subprojects.qqcexamples.sortpages = true + +depends = qtcore qtdoc qtgui qtwidgets qtqml qtquick qtquickdialogs qtquickextras qtgraphicaleffects + +# Specify the install path under QT_INSTALL_EXAMPLES +# Examples will be installed under quick/controls - 'controls' subdirectory +# is given as part of \example commands +exampledirs += ../../../examples/quickcontrols/controls \ + snippets +examplesinstallpath = quickcontrols/controls + +# This module has no documented C++ types, clear the module header +moduleheader = + +headerdirs += .. + +sourcedirs += .. + +sources += ../Private/AbstractCheckable.qml \ + ../Private/BasicButton.qml \ + ../Private/FocusFrame.qml \ + ../Private/ModalPopupBehavior.qml \ + ../Private/ScrollBar.qml \ + ../Private/TabBar.qml \ + ../Private/Control.qml \ + ../Private/qquickstyleitem.cpp \ + ../Private/Style.qml \ + ../Private/qquickabstractstyle_p.h \ + ../Private/qquickabstractstyle.cpp + +excludefiles += ../TableView.qml \ + ../TreeView.qml \ + ../Styles/Base/TableViewStyle.qml \ + ../Styles/Base/TreeViewStyle.qml + +excludedirs += ../Styles/Desktop \ + ../Styles/Android \ + ../Styles/iOS \ + ../Styles/WinRT + + +imagedirs += images \ + ../../extras/doc/images + +navigation.landingpage = "Qt Quick Controls 1" +navigation.qmltypespage = "Qt Quick Controls 1 QML Types" + +tagfile = qtquickcontrols1.tags diff --git a/src/controls/doc/src/qtquickcontrols-examples.qdoc b/src/controls/doc/src/qtquickcontrols-examples.qdoc index fff6103e..b6f2dca0 100644 --- a/src/controls/doc/src/qtquickcontrols-examples.qdoc +++ b/src/controls/doc/src/qtquickcontrols-examples.qdoc @@ -28,16 +28,16 @@ /*! \group qtquickcontrols_examples \ingroup all-examples - \title Qt Quick Controls Examples - \brief A Collection of examples for \l{Qt Quick Controls}, written in QML. + \title Qt Quick Controls 1 Examples + \brief A Collection of examples for \l{Qt Quick Controls 1}, written in QML. These examples show how to create user interfaces using - \l{Qt Quick Controls}. + \l{Qt Quick Controls 1}. */ /*! \example gallery - \title Qt Quick Controls - Gallery + \title Qt Quick Controls 1 - Gallery \ingroup qtquickcontrols_examples \brief A collection of components for a classic desktop-style UI. @@ -58,14 +58,14 @@ \endraw This example project demonstrates the various UI components provided by - \l{Qt Quick Controls}. + \l{Qt Quick Controls 1}. \include examples-run.qdocinc */ /*! \example uiforms - \title Qt Quick Controls - UI Forms + \title Qt Quick Controls 1 - UI Forms \ingroup qtquickcontrols_examples \brief Demonstrates how to separate the application logic from the UI. @@ -126,13 +126,13 @@ /*! \example tableview - \title Qt Quick Controls - Table View Example + \title Qt Quick Controls 1 - Table View Example \ingroup qtquickcontrols_examples \brief An example for the TableView control. \image qtquickcontrols-example-tableview.png This example project demonstrates the usage of \l {TableView} from - \l{Qt Quick Controls} - a control to display one or more columns of + \l{Qt Quick Controls 1} - a control to display one or more columns of information from a data list model. The example includes a model that supports sorting and filtering. @@ -165,7 +165,7 @@ /*! \example texteditor - \title Qt Quick Controls - Text Editor Example + \title Qt Quick Controls 1 - Text Editor Example \ingroup qtquickcontrols_examples \brief A QML app using Qt Quick Controls and a C++ class to provide a fully-functional rich-text editor application. @@ -206,13 +206,13 @@ /*! \example touch - \title Qt Quick Controls - Touch Gallery + \title Qt Quick Controls 1 - Touch Gallery \ingroup qtquickcontrols_examples \brief Demonstrates UI controls for a touch interface. \image qtquickcontrols-example-touch.png \e {Touch Gallery} demonstrates how to implement a UI suitable for touch - input using the following \l{Qt Quick Controls}: + input using the following \l{Qt Quick Controls 1}: \list \li \l ApplicationWindow @@ -228,7 +228,7 @@ \endlist The appearance of the controls is customized by using - \l {Qt Quick Controls Styles}. + \l {Qt Quick Controls 1 Styles}. \include examples-run.qdocinc @@ -452,7 +452,7 @@ /*! \example calendar - \title Qt Quick Controls - Calendar Example + \title Qt Quick Controls 1 - Calendar Example \ingroup qtquickcontrols_examples \brief Demonstrates the use of Calendar control. \image qtquickcontrols-example-calendar.png @@ -540,25 +540,25 @@ /*! \example styles - \title Qt Quick Controls - Styles Example + \title Qt Quick Controls 1 - Styles Example \ingroup qtquickcontrols_examples \brief Demonstrates custom styles. \image qtquickcontrols-example-styles.png - This example shows how to create custom styles for \l{Qt Quick Controls}. + This example shows how to create custom styles for \l{Qt Quick Controls 1}. \include examples-run.qdocinc */ /*! \example filesystembrowser - \title Qt Quick Controls - File System Browser Example + \title Qt Quick Controls 1 - File System Browser Example \ingroup qtquickcontrols_examples \brief An example for the TreeView control. \image qtquickcontrols-example-filesystembrowser.png This example project demonstrates the usage of \l {TreeView} from - \l{Qt Quick Controls} - a control to display a tree representation of items + \l{Qt Quick Controls 1} - a control to display a tree representation of items from a model derived from the QAbstractItemModel class. The example displays the home path data given by the QFileSystemModel model. diff --git a/src/controls/doc/src/qtquickcontrols-index.qdoc b/src/controls/doc/src/qtquickcontrols-index.qdoc index 28bc3644..727be41e 100644 --- a/src/controls/doc/src/qtquickcontrols-index.qdoc +++ b/src/controls/doc/src/qtquickcontrols-index.qdoc @@ -26,8 +26,8 @@ ****************************************************************************/ /*! - \page qtquickcontrols-index.html - \title Qt Quick Controls + \page qtquickcontrols1-index.html + \title Qt Quick Controls 1 \brief The Qt Quick Controls module provides a set of UI controls for Qt Quick. @@ -36,7 +36,7 @@ The module was introduced in Qt 5.1. - Visit the \l{Qt Quick Controls Overview} page to get started. + Visit the \l{Qt Quick Controls 1 Overview} page to get started. \section1 Application Window Components used to describe the basic window properties of an application. @@ -67,11 +67,11 @@ \list \li \l{Qt Quick} - \li \l{Qt Quick Controls Overview} - \li \l{Qt Quick Controls QML Types}{Qt Quick Controls QML Types} - \li \l{Qt Quick Controls Platform Notes} - \li \l{Qt Quick Controls Examples} - \li \l{Qt Quick Controls Styles} + \li \l{Qt Quick Controls 1 Overview} + \li \l{Qt Quick Controls 1 QML Types} + \li \l{Qt Quick Controls 1 Platform Notes} + \li \l{Qt Quick Controls 1 Examples} + \li \l{Qt Quick Controls 1 Styles} \li \l{Qt Quick Layouts} \li \l{Qt Quick Dialogs} \endlist diff --git a/src/controls/doc/src/qtquickcontrols-overview.qdoc b/src/controls/doc/src/qtquickcontrols-overview.qdoc index 5b7b1c07..dddec50b 100644 --- a/src/controls/doc/src/qtquickcontrols-overview.qdoc +++ b/src/controls/doc/src/qtquickcontrols-overview.qdoc @@ -27,7 +27,7 @@ /*! \page qtquickcontrols-overview.html - \title Qt Quick Controls Overview + \title Qt Quick Controls 1 Overview \brief A set of UI controls to create user interfaces in Qt Quick The Qt Quick Controls provide a set of UI controls to create user interfaces @@ -61,8 +61,8 @@ } \endcode - For an overview of the controls provided by \l{Qt Quick Controls}, you can look at - the \l{Qt Quick Controls - Gallery}{Gallery} example. + For an overview of the controls provided by \l{Qt Quick Controls 1}, you can look at + the \l{Qt Quick Controls 1 - Gallery}{Gallery} example. \image qtquickcontrols-example-gallery-osx.png @@ -134,7 +134,7 @@ \list \li \l{Qt Quick} - \li \l{Qt Quick Controls} - \li \l{Qt Quick Controls Examples} + \li \l{Qt Quick Controls 1} + \li \l{Qt Quick Controls 1 Examples} \endlist */ diff --git a/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc b/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc index 92010562..60d5e797 100644 --- a/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc +++ b/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc @@ -27,11 +27,11 @@ /*! \page qtquickcontrols-platformnotes.html - \title Qt Quick Controls Platform Notes + \title Qt Quick Controls 1 Platform Notes \brief Platform specific notes for Qt Quick Controls. This page contains platform specific notes for creating applications - that use \l{Qt Quick Controls}. + that use \l{Qt Quick Controls 1}. \section1 Android Style @@ -71,7 +71,7 @@ including various navigation modes, actions, an options menu, a back button, and also displays the application icon and title. - Unlike \l{Qt Widgets}, Qt Quick Controls do not use the native action + Unlike \l{Qt Widgets}, Qt Quick Controls 1 do not use the native action bar on Android. ToolBar and MenuBar are offered as a cross-platform replacement. They are unified to a single "action bar" when assigned to the appropriate ApplicationWindow properties. diff --git a/src/controls/doc/src/qtquickcontrols.qdoc b/src/controls/doc/src/qtquickcontrols.qdoc index 974345f5..a57521d1 100644 --- a/src/controls/doc/src/qtquickcontrols.qdoc +++ b/src/controls/doc/src/qtquickcontrols.qdoc @@ -27,15 +27,15 @@ /*! \qmlmodule QtQuick.Controls 1.4 - \title Qt Quick Controls QML Types + \title Qt Quick Controls 1 QML Types \ingroup qmlmodules \brief Provides QML types for user interfaces. - The \l{Qt Quick Controls} module provides QML types for creating user + The \l{Qt Quick Controls 1} module provides QML types for creating user interfaces. These QML types work in conjunction with \l{Qt Quick} and \l{Qt Quick Layouts}. - Controls can be styled using the \l{Qt Quick Controls Styles QML Types}{Styles QML Types}. + Controls can be styled using the \l{Qt Quick Controls 1 Styles QML Types}{Styles QML Types}. The QML types can be imported into your application using the following import statement in your .qml file. diff --git a/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc b/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc index 100868a9..dfe8f4d0 100644 --- a/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc +++ b/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc @@ -57,10 +57,10 @@ /*! \page qtquickcontrolsstyles-index.html - \title Qt Quick Controls Styles + \title Qt Quick Controls 1 Styles \brief The Qt Quick Controls Styles submodule provides custom styles for Qt Quick Controls. - The Qt Quick Controls Styles submodule allows custom styling for \l {Qt Quick Controls}. + The Qt Quick Controls Styles submodule allows custom styling for \l {Qt Quick Controls 1}. The submodule was introduced in Qt 5.1. @@ -118,19 +118,19 @@ \list \li \l{Qt Quick} - \li \l{Qt Quick Controls} - \li \l{Qt Quick Controls Styles QML Types} + \li \l{Qt Quick Controls 1} + \li \l{Qt Quick Controls 1 Styles QML Types} \endlist */ /*! \qmlmodule QtQuick.Controls.Styles 1.4 - \title Qt Quick Controls Styles QML Types + \title Qt Quick Controls 1 Styles QML Types \ingroup qmlmodules \brief Provides QML types for Qt Quick Controls styles. - The \l{Qt Quick Controls} module provides a set of QML types for handling + The \l{Qt Quick Controls 1} module provides a set of QML types for handling styles. Some of the controls allow custom styling similar to widget style sheets. diff --git a/src/controls/plugin.cpp b/src/controls/plugin.cpp index 4eb6c466..82eef800 100644 --- a/src/controls/plugin.cpp +++ b/src/controls/plugin.cpp @@ -71,20 +71,14 @@ #include <QtCore/qlocale.h> #endif -static void initResources() -{ -#ifdef QT_STATIC - Q_INIT_RESOURCE(qmake_QtQuick_Controls); - Q_INIT_RESOURCE(qmake_controls); -#endif -} - QT_BEGIN_NAMESPACE -static const struct { +struct QmldirStruct { const char *type; int major, minor; -} qmldir [] = { +}; + +static const QmldirStruct qmldir [] = { { "ApplicationWindow", 1, 0 }, { "Button", 1, 0 }, { "Calendar", 1, 2 }, @@ -127,9 +121,45 @@ static const struct { { "Slider", 1, 6 } }; +static const QmldirStruct stylesQmldir [] = { + { "ApplicationWindowStyle", 1, 3 }, + { "ButtonStyle", 1, 0 }, + { "BusyIndicatorStyle", 1, 1 }, + { "CalendarStyle", 1, 1 }, + { "CheckBoxStyle", 1, 0 }, + { "ComboBoxStyle", 1, 0 }, + { "MenuStyle", 1, 2 }, + { "MenuBarStyle", 1, 2 }, + { "ProgressBarStyle", 1, 0 }, + { "RadioButtonStyle", 1, 0 }, + { "ScrollViewStyle", 1, 0 }, + { "SliderStyle", 1, 0 }, + { "SpinBoxStyle", 1, 1 }, + { "SwitchStyle", 1, 1 }, + { "TabViewStyle", 1, 0 }, + { "TableViewStyle", 1, 0 }, + { "TreeViewStyle", 1, 4 }, + { "TextAreaStyle", 1, 1 }, + { "TextFieldStyle", 1, 0 }, + { "ToolBarStyle", 1, 0 }, + { "StatusBarStyle", 1, 0 }, + { "CircularGaugeStyle", 1, 0 }, + { "CircularButtonStyle", 1, 0 }, + { "CircularTickmarkLabelStyle", 1, 0 }, + { "CommonStyleHelper", 1, 0 }, + { "DelayButtonStyle", 1, 0 }, + { "DialStyle", 1, 1 }, + { "GaugeStyle", 1, 0 }, + { "HandleStyle", 1, 0 }, + { "HandleStyleHelper", 1, 0 }, + { "PieMenuStyle", 1, 3 }, + { "StatusIndicatorStyle", 1, 1 }, + { "ToggleButtonStyle", 1, 0 }, + { "TumblerStyle", 1, 2 } +}; + QtQuickControls1Plugin::QtQuickControls1Plugin(QObject *parent) : QQmlExtensionPlugin(parent) { - initResources(); } void QtQuickControls1Plugin::registerTypes(const char *uri) @@ -181,6 +211,12 @@ void QtQuickControls1Plugin::registerTypes(const char *uri) #ifdef QT_WIDGETS_LIB qmlRegisterType<QQuickStyleItem1>(private_uri, 1, 0, "StyleItem"); #endif + + const char *styles_uri = "QtQuick.Controls.Styles"; + const QString baseStyleLocation = filesLocation + "/Styles/Base"; + for (int i = 0; i < int(sizeof(stylesQmldir)/sizeof(stylesQmldir[0])); i++) + qmlRegisterType(QUrl(baseStyleLocation + "/" + stylesQmldir[i].type + ".qml"), styles_uri, + stylesQmldir[i].major, stylesQmldir[i].minor, stylesQmldir[i].type); } void QtQuickControls1Plugin::initializeEngine(QQmlEngine *engine, const char *uri) diff --git a/src/controls/qquickmenu.cpp b/src/controls/qquickmenu.cpp index 3c6d91ef..bfa0f673 100644 --- a/src/controls/qquickmenu.cpp +++ b/src/controls/qquickmenu.cpp @@ -789,33 +789,41 @@ void QQuickMenu1::insertItem(int index, QQuickMenuBase1 *menuItem) void QQuickMenu1::removeItem(QQuickMenuBase1 *menuItem) { - if (!menuItem) - return; - menuItem->setParentMenu(0); - - QQuickMenuItemContainer1 *container = menuItem->parent() != this ? m_containers[menuItem->parent()] : 0; - if (container) - container->removeItem(menuItem); - else - m_menuItems.removeOne(menuItem); - - --m_itemsCount; - emit itemsChanged(); + // Removes the item, but if it's a container, the container is kept + if (menuItem) { + unparentItem(menuItem); + emit itemsChanged(); + } } void QQuickMenu1::clear() { - m_containers.clear(); - m_containersCount = 0; + if (m_itemsCount > 0) { + while (m_itemsCount > 0) + unparentItem(menuItemAtIndex(0)); - // QTBUG-48927: a proxy menu (ApplicationWindowStyle.qml) must not - // delete its items, because they are owned by the menubar - if (m_proxy) + // We can delete the containers now, as there cannot be any further items in them. + qDeleteAll(m_containers); + m_containers.clear(); + m_containersCount = 0; + + // The containers are also kept in m_menuItems, so we have to clear explicitly. m_menuItems.clear(); - while (!m_menuItems.empty()) - delete m_menuItems.takeFirst(); - m_itemsCount = 0; + emit itemsChanged(); + } +} + +void QQuickMenu1::unparentItem(QQuickMenuBase1 *menuItem) +{ + menuItem->setParentMenu(nullptr); + QQuickMenuItemContainer1 *container = (menuItem->parent() != this) + ? m_containers[menuItem->parent()] : nullptr; + if (container) + container->removeItem(menuItem); + else + m_menuItems.removeOne(menuItem); + --m_itemsCount; } void QQuickMenu1::setupMenuItem(QQuickMenuBase1 *item, int platformIndex) @@ -871,8 +879,31 @@ QObject *QQuickMenu1::at_menuItems(QQuickMenuItems *list, int index) void QQuickMenu1::clear_menuItems(QQuickMenuItems *list) { - if (QQuickMenu1 *menu = qobject_cast<QQuickMenu1 *>(list->object)) - menu->clear(); + if (QQuickMenu1 *menu = qobject_cast<QQuickMenu1 *>(list->object)) { + // There may be stray containers that don't appear in m_menuItems. This is because we may + // remove a container with removeItem(), which will only remove it from m_menuItems. + // Therefore, make sure that all containers are removed from m_menuItems first. + for (QQuickMenuItemContainer1 *container : menu->m_containers) + menu->m_menuItems.removeOne(container); + + // Delete or unparent the items first. They may have references to the containers. + // QTBUG-48927: a proxy menu (ApplicationWindowStyle.qml) must not + // delete its items, because they are owned by the menubar + // We still do own the containers, though. We create them on append_menuItems, after all. + while (!menu->m_menuItems.empty()) { + if (menu->m_proxy) + menu->unparentItem(menu->m_menuItems[0]); + else + delete menu->m_menuItems.takeFirst(); + } + menu->m_menuItems.clear(); + + qDeleteAll(menu->m_containers); + menu->m_containers.clear(); + menu->m_containersCount = 0; + + menu->m_itemsCount = 0; + } } QT_END_NAMESPACE diff --git a/src/controls/qquickmenu_p.h b/src/controls/qquickmenu_p.h index 800981dd..0594f391 100644 --- a/src/controls/qquickmenu_p.h +++ b/src/controls/qquickmenu_p.h @@ -190,6 +190,8 @@ private: static int count_menuItems(QQuickMenuItems *list); static QObject *at_menuItems(QQuickMenuItems *list, int index); static void clear_menuItems(QQuickMenuItems *list); + + void unparentItem(QQuickMenuBase1 *menuItem); void setupMenuItem(QQuickMenuBase1 *item, int platformIndex = -1); QPlatformMenu *m_platformMenu; diff --git a/src/dialogs/DefaultDialogWrapper.qml b/src/dialogs/DefaultDialogWrapper.qml index b446c316..3ca030c4 100644 --- a/src/dialogs/DefaultDialogWrapper.qml +++ b/src/dialogs/DefaultDialogWrapper.qml @@ -47,6 +47,9 @@ import "qml" AbstractDialog { id: root default property alias data: defaultContentItem.data + + signal actionChosen(var action) + onVisibilityChanged: if (visible && contentItem) contentItem.forceActiveFocus() Rectangle { @@ -63,19 +66,7 @@ AbstractDialog { defaultContentItem.implicitWidth, buttonsRowImplicitWidth, Screen.pixelDensity * 50) + outerSpacing * 2) color: palette.window Keys.onPressed: { - event.accepted = true - switch (event.key) { - case Qt.Key_Escape: - case Qt.Key_Back: - reject() - break - case Qt.Key_Enter: - case Qt.Key_Return: - accept() - break - default: - event.accepted = false - } + event.accepted = handleKey(event.key) } SystemPalette { id: palette } @@ -109,7 +100,7 @@ AbstractDialog { id: buttonsLeftRepeater Button { text: (buttonsLeftRepeater.model && buttonsLeftRepeater.model[index] ? buttonsLeftRepeater.model[index].text : index) - onClicked: root.click(buttonsLeftRepeater.model[index].standardButton) + onClicked: content.handleButton(buttonsLeftRepeater.model[index].standardButton) } } @@ -136,9 +127,54 @@ AbstractDialog { // TODO maybe: insert gaps if the button requires it (destructive buttons only) Button { text: (buttonsRightRepeater.model && buttonsRightRepeater.model[index] ? buttonsRightRepeater.model[index].text : index) - onClicked: root.click(buttonsRightRepeater.model[index].standardButton) + onClicked: content.handleButton(buttonsRightRepeater.model[index].standardButton) + } + } + } + + function handleButton(button) { + var action = { + "button": button, + "key": 0, + "accepted": true, + } + root.actionChosen(action) + if (action.accepted) { + click(button) + } + } + + function handleKey(key) { + var button = 0 + switch (key) { + case Qt.Key_Escape: + case Qt.Key_Back: + button = StandardButton.Cancel + break + case Qt.Key_Enter: + case Qt.Key_Return: + button = StandardButton.Ok + break + default: + return false + } + var action = { + "button": button, + "key": key, + "accepted": true, + } + root.actionChosen(action) + if (action.accepted) { + switch (button) { + case StandardButton.Cancel: + reject() + break + case StandardButton.Ok: + accept() + break } } + return true } } function setupButtons() { diff --git a/src/dialogs/Private/dialogsprivateplugin.cpp b/src/dialogs/Private/dialogsprivateplugin.cpp index ba8aabe3..a785f388 100644 --- a/src/dialogs/Private/dialogsprivateplugin.cpp +++ b/src/dialogs/Private/dialogsprivateplugin.cpp @@ -42,13 +42,6 @@ #include "qquickwritingsystemlistmodel_p.h" #include "qquickfontlistmodel_p.h" -static void initResources() -{ -#ifdef QT_STATIC - Q_INIT_RESOURCE(qmake_QtQuick_Dialogs_Private); -#endif -} - QT_BEGIN_NAMESPACE class QtQuick2DialogsPrivatePlugin : public QQmlExtensionPlugin @@ -57,7 +50,7 @@ class QtQuick2DialogsPrivatePlugin : public QQmlExtensionPlugin Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: - QtQuick2DialogsPrivatePlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } + QtQuick2DialogsPrivatePlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { } virtual void registerTypes(const char *uri) { Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Dialogs.Private")); diff --git a/src/dialogs/plugin.cpp b/src/dialogs/plugin.cpp index 1e6740d5..8c10786f 100644 --- a/src/dialogs/plugin.cpp +++ b/src/dialogs/plugin.cpp @@ -62,13 +62,6 @@ Q_LOGGING_CATEGORY(lcRegistration, "qt.quick.dialogs.registration") -static void initResources() -{ -#ifdef QT_STATIC - Q_INIT_RESOURCE(qmake_QtQuick_Dialogs); -#endif -} - QT_BEGIN_NAMESPACE /*! @@ -92,7 +85,7 @@ class QtQuick2DialogsPlugin : public QQmlExtensionPlugin Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: - QtQuick2DialogsPlugin() : QQmlExtensionPlugin(), m_useResources(true) { initResources(); } + QtQuick2DialogsPlugin() : QQmlExtensionPlugin(), m_useResources(true) { } virtual void initializeEngine(QQmlEngine *engine, const char * uri) { qCDebug(lcRegistration) << uri << m_decorationComponentUrl; diff --git a/src/dialogs/qquickdialog.cpp b/src/dialogs/qquickdialog.cpp index 485eeb43..ef6a9a1f 100644 --- a/src/dialogs/qquickdialog.cpp +++ b/src/dialogs/qquickdialog.cpp @@ -154,6 +154,31 @@ QT_BEGIN_NAMESPACE */ /*! + \qmlsignal Dialog::actionChosen(var action) + + This signal is emitted when the user has pressed any button or a key + associated with some role (such as the Enter or Escape keys). The \a + action parameter carries information about the event: + + \list + \li StandardButton button - The role of the button which was pressed. If a + key was pressed instead, this will be \c StandardButton.Ok if accepted + and \c StandardButton.Cancel if rejected. + \li Qt.Key key - The key which was pressed, or \c 0 if none + \li bool accepted - Set this to \c false to stop the event from triggering + its predefined action + \endlist + + By handling this signal and setting the \c action.accepted field to \c + false, it's possible to implement some validation on the dialog contents + before accepting it, for example. + + The corresponding handler is \c onActionChosen. + + \since QtQuick.Controls 1.8 +*/ + +/*! \qmlproperty bool Dialog::visible This property holds whether the dialog is visible. By default this is diff --git a/src/extras/Styles/Flat/flatstyleplugin.cpp b/src/extras/Styles/Flat/flatstyleplugin.cpp index 5d88134b..7efbb16c 100644 --- a/src/extras/Styles/Flat/flatstyleplugin.cpp +++ b/src/extras/Styles/Flat/flatstyleplugin.cpp @@ -45,20 +45,10 @@ #include "qquicktexthandle.h" -static void initResources() -{ -#ifndef QT_STATIC - Q_INIT_RESOURCE(flatstyle); -#else - Q_INIT_RESOURCE(qmake_QtQuick_Controls_Styles_Flat); -#endif -} - #ifndef QT_STATIC extern "C" { Q_DECL_EXPORT bool qt_quick_controls_style_init() { - initResources(); return true; } @@ -74,7 +64,6 @@ QT_BEGIN_NAMESPACE QtQuickExtrasStylesPlugin::QtQuickExtrasStylesPlugin(QObject *parent) : QQmlExtensionPlugin(parent) { - initResources(); } void QtQuickExtrasStylesPlugin::registerTypes(const char *uri) diff --git a/src/extras/doc/qtquickextras.qdocconf b/src/extras/doc/qtquickextras.qdocconf index 4d6128db..d7a56c82 100644 --- a/src/extras/doc/qtquickextras.qdocconf +++ b/src/extras/doc/qtquickextras.qdocconf @@ -27,7 +27,7 @@ qhp.QtQuickExtras.subprojects.qtquickextrasexamples.indexTitle = Qt Quick Extras qhp.QtQuickExtras.subprojects.qtquickextrasexamples.selectors = fake:example qhp.QtQuickExtras.subprojects.qtquickextrasexamples.sortPages = true -depends = qtqml qtquick qtdoc qtquickcontrols qtgui +depends = qtqml qtquick qtdoc qtquickcontrols1 qtgui exampledirs += ../../../examples/quickcontrols/extras examplesinstallpath = quickcontrols/extras diff --git a/src/extras/doc/src/qtquickextras-index.qdoc b/src/extras/doc/src/qtquickextras-index.qdoc index 4bc2e1da..6f32d789 100644 --- a/src/extras/doc/src/qtquickextras-index.qdoc +++ b/src/extras/doc/src/qtquickextras-index.qdoc @@ -60,6 +60,6 @@ \li \l{Qt Quick Extras Overview} \li \l{Qt Quick Extras QML Types}{Qt Quick Extras QML Types} \li \l{Qt Quick Extras Examples} - \li \l{Qt Quick Controls Styles} + \li \l{Qt Quick Controls 1 Styles} \endlist */ diff --git a/src/extras/doc/src/qtquickextras.qdoc b/src/extras/doc/src/qtquickextras.qdoc index 58d6fa18..db465a5d 100644 --- a/src/extras/doc/src/qtquickextras.qdoc +++ b/src/extras/doc/src/qtquickextras.qdoc @@ -33,10 +33,10 @@ The \l{Qt Quick Extras} module provides specialized controls for creating user interfaces. These QML types work in conjunction with - \l{Qt Quick} and \l{Qt Quick Controls}. + \l{Qt Quick} and \l{Qt Quick Controls 1}. Controls can be styled using the - \l{Qt Quick Controls Styles QML Types}{Styles QML Types}. + \l{Qt Quick Controls 1 Styles QML Types}{Styles QML Types}. The QML types can be imported into your application using the following import statement in your .qml file. diff --git a/src/widgets/qquickqfiledialog_p.h b/src/widgets/qquickqfiledialog_p.h index d977e345..4988c1e0 100644 --- a/src/widgets/qquickqfiledialog_p.h +++ b/src/widgets/qquickqfiledialog_p.h @@ -51,11 +51,13 @@ // We mean it. // -#include <QFileDialog> -#include "../dialogs/qquickabstractfiledialog_p.h" +#include <QtWidgets/qtwidgetsglobal.h> #if QT_CONFIG(filedialog) +#include <QFileDialog> +#include "../dialogs/qquickabstractfiledialog_p.h" + QT_BEGIN_NAMESPACE class QQuickQFileDialog : public QQuickAbstractFileDialog diff --git a/src/widgets/widgetsplugin.cpp b/src/widgets/widgetsplugin.cpp index 65233756..3289e6fd 100644 --- a/src/widgets/widgetsplugin.cpp +++ b/src/widgets/widgetsplugin.cpp @@ -44,13 +44,6 @@ #include "qquickqcolordialog_p.h" #include "qquickqfontdialog_p.h" -static void initResources() -{ -#ifdef QT_STATIC - Q_INIT_RESOURCE(qmake_QtQuick_PrivateWidgets); -#endif -} - QT_BEGIN_NAMESPACE /*! @@ -78,7 +71,7 @@ class QtQuick2PrivateWidgetsPlugin : public QQmlExtensionPlugin Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: - QtQuick2PrivateWidgetsPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } + QtQuick2PrivateWidgetsPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { } virtual void registerTypes(const char *uri) { Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.PrivateWidgets")); diff --git a/tests/auto/controls/data/tableview/table_resizedynamiccolumns.qml b/tests/auto/controls/data/tableview/table_resizedynamiccolumns.qml new file mode 100644 index 00000000..d11bce97 --- /dev/null +++ b/tests/auto/controls/data/tableview/table_resizedynamiccolumns.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 + +TableView { + id: tableView + Component { + id: columnComponentWithDelegate + TableViewColumn { + delegate: Rectangle { + implicitWidth: 50 + height: 10 + color: "red" + } + } + } + Component { + id: columnComponent + TableViewColumn { } + } + Component.onCompleted: { + addColumn(columnComponentWithDelegate.createObject(tableView, { title: "rects", width: 20 })); + addColumn(columnComponent.createObject(tableView, { title: "numbers" })); + } + model: 10 +} diff --git a/tests/auto/controls/data/tst_combobox.qml b/tests/auto/controls/data/tst_combobox.qml index 415d3ad3..bccac8d2 100644 --- a/tests/auto/controls/data/tst_combobox.qml +++ b/tests/auto/controls/data/tst_combobox.qml @@ -418,6 +418,61 @@ TestCase { comboBox.destroy() } + function test_activated_index_QTBUG_43050(){ + if (Qt.platform.os === "osx") + skip("When the menu pops up on OS X, it does not return and the test fails after time out") + if (Qt.platform.os === "windows") + skip("Test randomly fails under Windows") + + var comboBox = Qt.createQmlObject('import QtQuick.Controls 1.2; \ + ComboBox { \ + property bool indexWasUpdated: false; \ + model: 4; \ + onActivated: indexWasUpdated = (index === currentIndex); \ + }', container, ''); + var menuIndex = getMenuIndex(comboBox) + verify(menuIndex !== -1) + comboBox.forceActiveFocus() + verify(!comboBox.data[menuIndex].__popupVisible) + keyPress(Qt.Key_Space) + verify(comboBox.data[menuIndex].__popupVisible) + + waitForRendering(comboBox) + keyPress(Qt.Key_Down) + keyPress(Qt.Key_Down) + verify(!comboBox.indexWasUpdated) + keyPress(Qt.Key_Enter) + verify(comboBox.indexWasUpdated) + + comboBox.destroy() + } + + function test_update_index_on_activated_QTBUG_51113(){ + if (Qt.platform.os === "osx") + skip("When the menu pops up on OS X, it does not return and the test fails after time out") + if (Qt.platform.os === "windows") + skip("Test randomly fails under Windows") + + var comboBox = Qt.createQmlObject('import QtQuick.Controls 1.2; \ + ComboBox { \ + model: 4; \ + onActivated: if (index == 1) currentIndex = 3; \ + }', container, ''); + var menuIndex = getMenuIndex(comboBox) + verify(menuIndex !== -1) + comboBox.forceActiveFocus() + verify(!comboBox.data[menuIndex].__popupVisible) + keyPress(Qt.Key_Space) + verify(comboBox.data[menuIndex].__popupVisible) + + waitForRendering(comboBox) + keyPress(Qt.Key_Down) + keyPress(Qt.Key_Enter) + compare(comboBox.currentIndex, 3) + + comboBox.destroy() + } + function test_activeFocusOnTab() { if (Qt.styleHints.tabFocusBehavior != Qt.TabFocusAllControls) skip("This function doesn't support NOT iterating all.") diff --git a/tests/auto/controls/data/tst_scrollview.qml b/tests/auto/controls/data/tst_scrollview.qml index 42398115..d3bfac4b 100644 --- a/tests/auto/controls/data/tst_scrollview.qml +++ b/tests/auto/controls/data/tst_scrollview.qml @@ -212,21 +212,27 @@ TestCase { bigItem.height = 100 bigItem.width = 100 - verify(!scrollView.__horizontalScrollBar.visible, "Scrollbar showing when contents already fit") - verify(!scrollView.__verticalScrollBar.visible, "Scrollbar showing when contents already fit") + tryVerify(function() { return !scrollView.__horizontalScrollBar.visible }, 50, + "Scrollbar showing when contents already fit") + tryVerify(function() { return !scrollView.__verticalScrollBar.visible }, 50, + "Scrollbar showing when contents already fit") bigItem.height = 1000 bigItem.width = 1000 - verify(scrollView.__horizontalScrollBar.visible, "Scrollbar not showing when contents are too big") - verify(scrollView.__verticalScrollBar.visible, "Scrollbar not showing when contents are too big") + tryVerify(function() { return scrollView.__horizontalScrollBar.visible }, 50, + "Scrollbar not showing when contents are too big") + tryVerify(function() { return scrollView.__verticalScrollBar.visible }, 50, + "Scrollbar not showing when contents are too big") //always off bigItem.height = 1000 scrollView.verticalScrollBarPolicy = Qt.ScrollBarAlwaysOff - verify(!scrollView.__verticalScrollBar.visible, "Scrollbar showing when disabled") + tryVerify(function() { return !scrollView.__verticalScrollBar.visible }, 50, + "Scrollbar showing when disabled") bigItem.height = 100 - verify(!scrollView.__verticalScrollBar.visible, "Scrollbar showing when disabled") + tryVerify(function() { return !scrollView.__verticalScrollBar.visible }, 50, + "Scrollbar showing when disabled") //always on scrollView.verticalScrollBarPolicy = Qt.ScrollBarAlwaysOn @@ -258,12 +264,14 @@ TestCase { verify(scrollView !== null, "view created is null") verify(scrollView.flickableItem.contentY === 0) + tryVerify(function() { return scrollView.__verticalScrollBar.visible }); + mouseClick(scrollView, scrollView.width -2, scrollView.height/2, Qt.LeftButton) - verify(Math.round(scrollView.flickableItem.contentY) === 100) + tryVerify(function() { return Math.round(scrollView.flickableItem.contentY) === 100 }); - verify(scrollView.flickableItem.contentX === 0) + tryVerify(function() { return scrollView.flickableItem.contentX === 0 }) mouseClick(scrollView, scrollView.width/2, scrollView.height - 2, Qt.LeftButton) - verify(Math.round(scrollView.flickableItem.contentX) === 100) + tryVerify(function() { return Math.round(scrollView.flickableItem.contentX) === 100 }) } function test_viewport() { diff --git a/tests/auto/controls/data/tst_tableview.qml b/tests/auto/controls/data/tst_tableview.qml index fe50f241..08bf1d9d 100644 --- a/tests/auto/controls/data/tst_tableview.qml +++ b/tests/auto/controls/data/tst_tableview.qml @@ -1131,5 +1131,20 @@ TestCase { tableView.moveColumn(0, 1); compare(tableView.sortIndicatorColumn, 1); } + + function test_resize_dynamic_columns() { + var component = Qt.createComponent("tableview/table_resizedynamiccolumns.qml") + compare(component.status, Component.Ready) + var table = createTemporaryObject(component, container); + verify(table !== null, "table created is null") + waitForRendering(table) + compare(table.getColumn(0).width, 20) + table.getColumn(0).resizeToContents() + tryCompare(table.getColumn(0), "width", 50) + table.getColumn(0).width = 20 + compare(table.getColumn(0).width, 20) + table.resizeColumnsToContents() + compare(table.getColumn(0).width, 50) + } } } diff --git a/tests/auto/controls/data/tst_treeview.qml b/tests/auto/controls/data/tst_treeview.qml index b46d4dc2..139be338 100644 --- a/tests/auto/controls/data/tst_treeview.qml +++ b/tests/auto/controls/data/tst_treeview.qml @@ -747,7 +747,6 @@ Item { } function test_indexAt() { - skip("Fails because of bug QTBUG-47523") var component = Qt.createComponent("treeview/treeview_1.qml") compare(component.status, Component.Ready) var tree = component.createObject(container); diff --git a/tests/auto/dialogs/data/DialogButtonHandler.qml b/tests/auto/dialogs/data/DialogButtonHandler.qml new file mode 100644 index 00000000..e19f88c8 --- /dev/null +++ b/tests/auto/dialogs/data/DialogButtonHandler.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtQuick.Dialogs 1.2 + +Dialog { + property bool handlerWasCalled: false + property var buttonCode + property var keyCode + property bool mustBlock: false + property string actionCalled: "" + + visible: true + title: "Blue sky dialog" + standardButtons: buttonsFromTest + + Item { + implicitWidth: 300 + implicitHeight: 200 + } + + onActionChosen: { + handlerWasCalled = true + buttonCode = action.button + keyCode = action.key + if (mustBlock) { + action.accepted = false + } + } + + onAccepted: actionCalled = "accepted" + onApply: actionCalled = "apply" + onDiscard: actionCalled = "discard" + onHelp: actionCalled = "help" + onNo: actionCalled = "no" + onRejected: actionCalled = "rejected" + onReset: actionCalled = "reset" + onYes: actionCalled = "yes" +} diff --git a/tests/auto/dialogs/tst_dialogs.cpp b/tests/auto/dialogs/tst_dialogs.cpp index 1f802113..8303ff83 100644 --- a/tests/auto/dialogs/tst_dialogs.cpp +++ b/tests/auto/dialogs/tst_dialogs.cpp @@ -51,6 +51,10 @@ private slots: void dialogImplicitWidth_data(); void dialogImplicitWidth(); void dialogContentResize(); + void dialogButtonHandler_data(); + void dialogButtonHandler(); + void dialogKeyHandler_data(); + void dialogKeyHandler(); // FileDialog void fileDialogDefaultModality(); @@ -113,6 +117,142 @@ void tst_dialogs::dialogContentResize() QVERIFY(userContent->height() > 200); } +void tst_dialogs::dialogButtonHandler_data() +{ + QTest::addColumn<int>("standardButtons"); + QTest::addColumn<bool>("mustBlock"); + QTest::addColumn<QString>("expectedAction"); + + QTest::newRow("Cancel, ignored") << + int(QQuickAbstractDialog::Cancel) << + false << + "rejected"; + QTest::newRow("Cancel, blocked") << + int(QQuickAbstractDialog::Cancel) << + true << + ""; + QTest::newRow("OK, ignored") << + int(QQuickAbstractDialog::Ok) << + false << + "accepted"; + QTest::newRow("OK, blocked") << + int(QQuickAbstractDialog::Ok) << + true << + ""; +} + +void tst_dialogs::dialogButtonHandler() +{ + QFETCH(int, standardButtons); + QFETCH(bool, mustBlock); + QFETCH(QString, expectedAction); + + QQmlEngine engine; + engine.rootContext()->setContextProperty("buttonsFromTest", standardButtons); + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("DialogButtonHandler.qml")); + QObject *root = component.create(); + QScopedPointer<QObject> cleanup(root); + QVERIFY2(root, qPrintable(component.errorString())); + + root->setProperty("visible", true); + root->setProperty("mustBlock", mustBlock); + + QQuickWindow *window = root->findChild<QQuickWindow*>(); + QTest::qWaitForWindowExposed(window); + + /* Hack to find the created buttons: since they are created by a + * QQuickRepeater, they don't appear on the hierarchy tree; therefore, we + * first need to find the repeater, and then to get its child. */ + const QList<QQuickItem*> children = root->findChildren<QQuickItem*>(); + QQuickItem *buttonWidget = nullptr; + for (QQuickItem *child: children) { + if (qstrcmp(child->metaObject()->className(), "QQuickRepeater") == 0 && + child->property("count").toInt() > 0) { + int index = 0; + QMetaObject::invokeMethod(child, + "itemAt", + Q_RETURN_ARG(QQuickItem *, buttonWidget), + Q_ARG(int, index)); + break; + } + } + QVERIFY(buttonWidget); + + const QPointF buttonCenterF(buttonWidget->width() / 2, + buttonWidget->height() / 2); + const QPoint buttonCenter = buttonWidget->mapToScene(buttonCenterF).toPoint(); + + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, buttonCenter); + QTRY_VERIFY(root->property("handlerWasCalled").toBool()); + + QCOMPARE(root->property("buttonCode").toInt(), standardButtons); + QCOMPARE(root->property("keyCode").toInt(), 0); + + QCOMPARE(root->property("actionCalled").toString(), expectedAction); +} + +void tst_dialogs::dialogKeyHandler_data() +{ + QTest::addColumn<int>("key"); + QTest::addColumn<bool>("mustBlock"); + QTest::addColumn<int>("expectedButton"); + QTest::addColumn<QString>("expectedAction"); + + QTest::newRow("Escape, ignored") << + int(Qt::Key_Escape) << + false << + int(QQuickAbstractDialog::Cancel) << + "rejected"; + QTest::newRow("Cancel, blocked") << + int(Qt::Key_Escape) << + true << + int(QQuickAbstractDialog::Cancel) << + ""; + QTest::newRow("Enter, ignored") << + int(Qt::Key_Enter) << + false << + int(QQuickAbstractDialog::Ok) << + "accepted"; + QTest::newRow("Enter, blocked") << + int(Qt::Key_Enter) << + true << + int(QQuickAbstractDialog::Ok) << + ""; +} + +void tst_dialogs::dialogKeyHandler() +{ + QFETCH(int, key); + QFETCH(bool, mustBlock); + QFETCH(int, expectedButton); + QFETCH(QString, expectedAction); + + QQmlEngine engine; + QQuickAbstractDialog::StandardButtons buttons = + QQuickAbstractDialog::Ok | QQuickAbstractDialog::Cancel; + engine.rootContext()->setContextProperty("buttonsFromTest", int(buttons)); + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("DialogButtonHandler.qml")); + QObject *root = component.create(); + QScopedPointer<QObject> cleanup(root); + QVERIFY2(root, qPrintable(component.errorString())); + + root->setProperty("visible", true); + root->setProperty("mustBlock", mustBlock); + + QQuickWindow *window = root->findChild<QQuickWindow*>(); + QTest::qWaitForWindowExposed(window); + + QTest::keyClick(window, Qt::Key(key)); + QTRY_VERIFY(root->property("handlerWasCalled").toBool()); + + QCOMPARE(root->property("buttonCode").toInt(), expectedButton); + QCOMPARE(root->property("keyCode").toInt(), key); + + QCOMPARE(root->property("actionCalled").toString(), expectedAction); +} + void tst_dialogs::fileDialogDefaultModality() { QQuickView *window = new QQuickView; diff --git a/tests/benchmarks/startup/gallery.qrc b/tests/benchmarks/startup/gallery.qrc index 2cabf889..1a84303a 100644 --- a/tests/benchmarks/startup/gallery.qrc +++ b/tests/benchmarks/startup/gallery.qrc @@ -1,6 +1,5 @@ <RCC> <qresource prefix="/"> - <file>timer.qml</file> <file alias="main.qml">../../../examples/quickcontrols/controls/gallery/main.qml</file> <file alias="qml/ButtonPage.qml">../../../examples/quickcontrols/controls/gallery/qml/ButtonPage.qml</file> <file alias="qml/InputPage.qml">../../../examples/quickcontrols/controls/gallery/qml/InputPage.qml</file> diff --git a/tests/benchmarks/startup/startup_bench.cpp b/tests/benchmarks/startup/startup_bench.cpp index cdc754ec..ea510e8c 100644 --- a/tests/benchmarks/startup/startup_bench.cpp +++ b/tests/benchmarks/startup/startup_bench.cpp @@ -50,29 +50,26 @@ #include "qtquickcontrolsapplication.h" #include <QtQml/QQmlApplicationEngine> +#include <QQuickWindow> #include <QtCore/QElapsedTimer> #include <functional> #include <stdio.h> -int runBenchmark(std::function<int()> f) { +int runBenchmark(std::function<qint64()> f) { { - QElapsedTimer t; - t.start(); - int r = f(); - if (r == 0) - printf("%d,", static_cast<int>(t.elapsed())); + auto r = f(); + if (r >= 0) + printf("%d,", static_cast<int>(r)); else - return r; + return -1; } { - QElapsedTimer t; - t.start(); - int r = f(); - if (r == 0) - printf("%d\n", static_cast<int>(t.elapsed())); + auto r = f(); + if (r >= 0) + printf("%d\n", static_cast<int>(r)); else - return r; + return -1; } return 0; @@ -83,14 +80,18 @@ int main(int argc, char *argv[]) { QtQuickControlsApplication app(argc, argv); - auto startup = [&app]() { + auto startup = [&app]() -> qint64 { + QElapsedTimer timer; + timer.start(); QQmlApplicationEngine engine(QUrl("qrc:/main.qml")); - QObject::connect(&engine, &QQmlApplicationEngine::quit, + if (engine.rootObjects().size() != 1) + return -1; + QQuickWindow *window = qobject_cast<QQuickWindow*>(engine.rootObjects().first()); + QObject::connect(window, &QQuickWindow::frameSwapped, QCoreApplication::instance(), &QCoreApplication::quit); - engine.load(QUrl("qrc:/timer.qml")); - if (engine.rootObjects().size() != 2) + if (app.exec() != 0) return -1; - return app.exec(); + return timer.elapsed(); }; return runBenchmark(startup); diff --git a/tests/benchmarks/startup/timer.qml b/tests/benchmarks/startup/timer.qml deleted file mode 100644 index a0e9f1c1..00000000 --- a/tests/benchmarks/startup/timer.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.2 - -Timer { - running: true - interval: 0 - onTriggered: Qt.quit(); -} |