diff options
Diffstat (limited to 'src')
96 files changed, 759 insertions, 396 deletions
diff --git a/src/controls/ApplicationWindow.qml b/src/controls/ApplicationWindow.qml index c13fdb6e1..888b0aec2 100644 --- a/src/controls/ApplicationWindow.qml +++ b/src/controls/ApplicationWindow.qml @@ -125,7 +125,7 @@ Window { property Item statusBar // The below documentation was supposed to be written as a grouped property, but qdoc would - // not render it correctly due to a bug (https://bugreports.qt-project.org/browse/QTBUG-34206) + // not render it correctly due to a bug (QTBUG-34206) /*! \qmlproperty ContentItem ApplicationWindow::contentItem diff --git a/src/controls/ComboBox.qml b/src/controls/ComboBox.qml index 68429483c..f2f37a0a5 100644 --- a/src/controls/ComboBox.qml +++ b/src/controls/ComboBox.qml @@ -401,8 +401,8 @@ Control { clip: contentWidth > width control: comboBox - cursorHandle: __style ? __style.cursorHandle : undefined - selectionHandle: __style ? __style.selectionHandle : undefined + cursorHandle: __style ? __style.__cursorHandle : undefined + selectionHandle: __style ? __style.__selectionHandle : undefined anchors.fill: parent anchors.leftMargin: __style ? __style.padding.left : 0 diff --git a/src/controls/Private/AbstractCheckable.qml b/src/controls/Private/AbstractCheckable.qml index 1909e05c2..f1dbe9621 100644 --- a/src/controls/Private/AbstractCheckable.qml +++ b/src/controls/Private/AbstractCheckable.qml @@ -148,4 +148,14 @@ Control { clicked(); } } + + Action { + // handle mnemonic + text: abstractCheckable.text + onTriggered: { + if (!abstractCheckable.exclusiveGroup || !abstractCheckable.checked) + abstractCheckable.__cycleStatesHandler(); + abstractCheckable.clicked(); + } + } } diff --git a/src/controls/Private/BasicButton.qml b/src/controls/Private/BasicButton.qml index f482ad72f..f0c9c63ea 100644 --- a/src/controls/Private/BasicButton.qml +++ b/src/controls/Private/BasicButton.qml @@ -152,6 +152,10 @@ Control { id: ownAction iconSource: !button.action || __iconOverriden ? button.iconSource : "" iconName: !button.action || __iconOverriden ? button.iconName : "" + + // let ownAction handle mnemonic if and only if the button does + // not already have an action assigned to avoid ambiguous shortcuts + text: button.action ? "" : button.text } Connections { diff --git a/src/controls/Private/EditMenu.qml b/src/controls/Private/EditMenu.qml index f4d80bd5f..70b6b9b24 100644 --- a/src/controls/Private/EditMenu.qml +++ b/src/controls/Private/EditMenu.qml @@ -49,6 +49,7 @@ Loader { property Flickable flickable property Component defaultMenu: item && item.defaultMenu ? item.defaultMenu : null property Menu menuInstance: null + property MouseArea mouseArea Connections { target: control @@ -69,5 +70,6 @@ Loader { return menuInstance; } - source: Qt.resolvedUrl("EditMenu_" + (Qt.platform.os === "ios" ? "ios" : "base") + ".qml") + source: Qt.resolvedUrl(Qt.platform.os === "ios" ? "EditMenu_ios.qml" + : Qt.platform.os === "android" ? "" : "EditMenu_base.qml") } diff --git a/src/controls/Private/EditMenu_base.qml b/src/controls/Private/EditMenu_base.qml index 597541bc2..3745d9f48 100644 --- a/src/controls/Private/EditMenu_base.qml +++ b/src/controls/Private/EditMenu_base.qml @@ -90,10 +90,8 @@ Item { MenuItem { action: pasteAction.createObject(editMenuBase) } } - MouseArea { - id: mouseArea - anchors.fill: parent - acceptedButtons: Qt.RightButton + Connections { + target: mouseArea onClicked: { if (input.selectionStart === input.selectionEnd) { diff --git a/src/controls/Private/EditMenu_ios.qml b/src/controls/Private/EditMenu_ios.qml index aeb21b03f..44ff7709f 100644 --- a/src/controls/Private/EditMenu_ios.qml +++ b/src/controls/Private/EditMenu_ios.qml @@ -75,7 +75,7 @@ Item { } MenuItem { text: "select" - visible: selectionStart === selectionEnd + visible: selectionStart === selectionEnd && input.length > 0 onTriggered: selectWord(); } MenuItem { @@ -85,9 +85,8 @@ Item { } } - MouseArea { - id: mouseArea - anchors.fill: parent + Connections { + target: mouseArea function clearFocusFromOtherItems() { @@ -115,7 +114,8 @@ Item { onPressAndHold: { var pos = input.positionAt(mouseArea.mouseX, mouseArea.mouseY); input.select(pos, pos); - if (!control.menu || !input.activeFocus || (selectionStart != selectionEnd)) { + var hasSelection = selectionStart != selectionEnd; + if (!control.menu || (input.length > 0 && (!input.activeFocus || hasSelection))) { selectWord(); } else { // We don't select anything at this point, the @@ -170,6 +170,7 @@ Item { return; if ((__showMenuFromTouchAndHold || selectionStart !== selectionEnd) + && control.activeFocus && (!cursorHandle.pressed && !selectionHandle.pressed) && (!flickable || !flickable.moving) && (cursorHandle.delegate)) { diff --git a/src/controls/Private/ScrollBar.qml b/src/controls/Private/ScrollBar.qml index 827504121..3bd0a1640 100644 --- a/src/controls/Private/ScrollBar.qml +++ b/src/controls/Private/ScrollBar.qml @@ -102,7 +102,7 @@ Item { onExited: if (!pressed) __panel.activeControl = "none" onMouseXChanged: if (!pressed) __panel.activeControl = __panel.hitTest(mouseX, mouseY) hoverEnabled: !Settings.hasTouchScreen - enabled: !Settings.hasTouchScreen // TODO: touch on desktop? + enabled: !Settings.isMobile || !Settings.hasTouchScreen // ### Not ideal, but will usually behave as expected... preventStealing: true property var pressedX property var pressedY diff --git a/src/controls/Private/TextHandle.qml b/src/controls/Private/TextHandle.qml index 19fc19a6d..8656dcfd8 100644 --- a/src/controls/Private/TextHandle.qml +++ b/src/controls/Private/TextHandle.qml @@ -75,7 +75,7 @@ Loader { MouseArea { id: mouse anchors.fill: item - enabled: handle.active + enabled: item && item.visible preventStealing: true property real pressX property point offset diff --git a/src/controls/Private/TextInputWithHandles.qml b/src/controls/Private/TextInputWithHandles.qml index f33487743..75ca947f7 100644 --- a/src/controls/Private/TextInputWithHandles.qml +++ b/src/controls/Private/TextInputWithHandles.qml @@ -52,9 +52,9 @@ TextInput { readonly property int selectionPosition: selectionStart !== cursorPosition ? selectionStart : selectionEnd readonly property alias containsMouse: mouseArea.containsMouse property alias editMenu: editMenu - cursorDelegate: __style && __style.cursorDelegate ? __style.cursorDelegate : null + cursorDelegate: __style && __style.__cursorDelegate ? __style.__cursorDelegate : null - selectByMouse: control.selectByMouse && (!cursorHandle.delegate || !selectionHandle.delegate) + selectByMouse: control.selectByMouse && (!Settings.isMobile || !cursorHandle.delegate || !selectionHandle.delegate) // force re-evaluation when selection moves: // - cursorRectangle changes => content scrolled @@ -104,13 +104,17 @@ TextInput { anchors.fill: parent hoverEnabled: true cursorShape: Qt.IBeamCursor - acceptedButtons: input.selectByMouse ? Qt.NoButton : Qt.LeftButton + acceptedButtons: (input.selectByMouse ? Qt.NoButton : Qt.LeftButton) | (control.menu ? Qt.RightButton : Qt.NoButton) onClicked: { + if (editMenu.item) + return; var pos = input.positionAt(mouse.x, mouse.y) input.moveHandles(pos, pos) input.activate() } onPressAndHold: { + if (editMenu.item) + return; var pos = input.positionAt(mouse.x, mouse.y) input.moveHandles(pos, control.selectByMouse ? -1 : pos) input.activate() @@ -120,6 +124,7 @@ TextInput { EditMenu { id: editMenu input: parent + mouseArea: mouseArea control: parent.control cursorHandle: cursorHandle selectionHandle: selectionHandle @@ -132,7 +137,7 @@ TextInput { editor: input parent: control control: input.control - active: control.selectByMouse + active: control.selectByMouse && Settings.isMobile maximum: cursorHandle.position - 1 property var mappedPos: parent.mapFromItem(editor, editor.selectionRectangle.x, editor.selectionRectangle.y) @@ -158,15 +163,14 @@ TextInput { editor: input parent: control control: input.control - active: control.selectByMouse - delegate: style.cursorHandle + active: control.selectByMouse && Settings.isMobile minimum: input.hasSelection ? selectionHandle.position + 1 : -1 property var mappedPos: parent.mapFromItem(editor, editor.cursorRectangle.x, editor.cursorRectangle.y) x: mappedPos.x y: mappedPos.y - visible: pressed || (input.hasSelection && handleX + handleWidth >= -1 && handleX <= control.width + 1) + visible: pressed || ((input.cursorVisible || input.hasSelection) && handleX + handleWidth >= -1 && handleX <= control.width + 1) onPositionChanged: { if (!input.blockRecursion) { diff --git a/src/controls/Private/qquickcontrolsettings.cpp b/src/controls/Private/qquickcontrolsettings.cpp index bd02b87d8..b73a7d43a 100644 --- a/src/controls/Private/qquickcontrolsettings.cpp +++ b/src/controls/Private/qquickcontrolsettings.cpp @@ -35,10 +35,14 @@ #include <qquickitem.h> #include <qcoreapplication.h> #include <qqmlengine.h> +#include <qlibrary.h> #include <qdir.h> #include <QTouchDevice> #include <QGuiApplication> #include <QStyleHints> +#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK) +#include <private/qjnihelpers_p.h> +#endif QT_BEGIN_NAMESPACE @@ -49,7 +53,8 @@ static QString defaultStyleName() if (QCoreApplication::instance()->inherits("QApplication")) return QLatin1String("Desktop"); #elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK) - return QLatin1String("Android"); + if (QtAndroidPrivate::androidSdkVersion() >= 11) + return QLatin1String("Android"); #elif defined(Q_OS_IOS) return QLatin1String("iOS"); #elif defined(Q_OS_WINRT) @@ -126,11 +131,29 @@ QQuickControlSettings::QQuickControlSettings(QQmlEngine *engine) QString path = styleFilePath(); - if (!QDir(path).exists()) { + QDir dir(path); + if (!dir.exists()) { QString unknownStyle = m_name; m_name = defaultStyleName(); m_path = styleImportPath(engine, m_name); qWarning() << "WARNING: Cannot find style" << unknownStyle << "- fallback:" << styleFilePath(); + } else { + typedef bool (*StyleInitFunc)(); + typedef const char *(*StylePathFunc)(); + + foreach (const QString &fileName, dir.entryList()) { + if (QLibrary::isLibrary(fileName)) { + QLibrary lib(dir.absoluteFilePath(fileName)); + StyleInitFunc initFunc = (StyleInitFunc) lib.resolve("qt_quick_controls_style_init"); + if (initFunc) + initFunc(); + StylePathFunc pathFunc = (StylePathFunc) lib.resolve("qt_quick_controls_style_path"); + if (pathFunc) + m_path = QString::fromLocal8Bit(pathFunc()); + if (initFunc || pathFunc) + break; + } + } } connect(this, SIGNAL(styleNameChanged()), SIGNAL(styleChanged())); diff --git a/src/controls/Private/qquickspinboxvalidator.cpp b/src/controls/Private/qquickspinboxvalidator.cpp index afbc866c8..2fec79e82 100644 --- a/src/controls/Private/qquickspinboxvalidator.cpp +++ b/src/controls/Private/qquickspinboxvalidator.cpp @@ -200,7 +200,9 @@ QValidator::State QQuickSpinBoxValidator::validate(QString &input, int &pos) con bool ok = false; qreal val = locale().toDouble(value, &ok); if (ok) { - if (state == QValidator::Acceptable) { + if (state == QValidator::Acceptable || + (state == QValidator::Intermediate && val >= 0 && val <= m_validator.top()) || + (state == QValidator::Intermediate && val < 0 && val >= m_validator.bottom())) { const_cast<QQuickSpinBoxValidator *>(this)->setValue(val); if (input != textFromValue(val)) state = QValidator::Intermediate; diff --git a/src/controls/Private/qquickstyleitem.cpp b/src/controls/Private/qquickstyleitem.cpp index edb33212e..fb49e6e3f 100644 --- a/src/controls/Private/qquickstyleitem.cpp +++ b/src/controls/Private/qquickstyleitem.cpp @@ -354,6 +354,8 @@ void QQuickStyleItem::initStyleOption() opt->features = QStyleOptionViewItem::HasDisplay; opt->text = text(); opt->textElideMode = Qt::ElideRight; + opt->displayAlignment = Qt::AlignLeft | Qt::AlignVCenter; + opt->decorationAlignment = Qt::AlignCenter; resolvePalette(); needsResolvePalette = false; QPalette pal = m_styleoption->palette; diff --git a/src/controls/Private/qquicktooltip.cpp b/src/controls/Private/qquicktooltip.cpp index b93b4a534..6f81b5b82 100644 --- a/src/controls/Private/qquicktooltip.cpp +++ b/src/controls/Private/qquicktooltip.cpp @@ -36,7 +36,7 @@ #include <qquickitem.h> #include <private/qguiapplication_p.h> #include <qpa/qplatformintegration.h> -#include <QtQuick/private/qquickrendercontrol_p.h> +#include <QtQuick/QQuickRenderControl> #ifdef QT_WIDGETS_LIB #include <qtooltip.h> diff --git a/src/controls/Slider.qml b/src/controls/Slider.qml index 94653bf82..d0644b4cc 100644 --- a/src/controls/Slider.qml +++ b/src/controls/Slider.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Quick Controls module of the Qt Toolkit. @@ -61,7 +61,7 @@ import QtQuick.Controls.Private 1.0 } \endcode - The Slider value is by default in the range [0, 1]. If integer values are + The slider value is by default in the range [0, 1]. If integer values are needed, you can set the \l stepSize. You can create a custom appearance for a Slider by @@ -82,7 +82,7 @@ Control { /*! \qmlproperty real Slider::minimumValue - This property holds the minimum value of the Slider. + This property holds the minimum value of the slider. The default value is \c{0.0}. */ property alias minimumValue: range.minimumValue @@ -90,7 +90,7 @@ Control { /*! \qmlproperty real Slider::maximumValue - This property holds the maximum value of the Slider + This property holds the maximum value of the slider. The default value is \c{1.0}. */ property alias maximumValue: range.maximumValue @@ -117,9 +117,9 @@ Control { /*! \qmlproperty bool Slider::hovered - This property indicates whether the control is being hovered. + This property indicates whether the slider handle is being hovered. */ - readonly property alias hovered: mouseArea.containsMouse + readonly property alias hovered: mouseArea.handleHovered /*! \qmlproperty real Slider::stepSize @@ -146,7 +146,7 @@ Control { /*! \qmlproperty real Slider::value - This property holds the current value of the Slider. + This property holds the current value of the slider. The default value is \c{0.0}. */ property alias value: range.value @@ -154,7 +154,7 @@ Control { /*! \qmlproperty bool Slider::activeFocusOnPress - This property indicates whether the Slider should receive active focus when + This property indicates whether the slider should receive active focus when pressed. */ property bool activeFocusOnPress: false @@ -162,11 +162,13 @@ Control { /*! \qmlproperty bool Slider::tickmarksEnabled - This property indicates whether the Slider should display tickmarks + This property indicates whether the slider should display tickmarks at step intervals. Tick mark spacing is calculated based on the \l stepSize property. The default value is \c false. + + \note This property may be ignored on some platforms when using the native style (e.g. Android). */ property bool tickmarksEnabled: false @@ -231,46 +233,54 @@ Control { property int clickOffset: 0 property real pressX: 0 property real pressY: 0 + property bool handleHovered: false function clamp ( val ) { return Math.max(range.positionAtMinimum, Math.min(range.positionAtMaximum, val)) } - onMouseXChanged: { - if (pressed && __horizontal) { - var pos = clamp (mouse.x + clickOffset - fakeHandle.width/2) - var overThreshold = Math.abs(mouse.x - pressX) >= Settings.dragThreshold + function updateHandlePosition(mouse, force) { + var pos, overThreshold + if (__horizontal) { + pos = clamp (mouse.x + clickOffset - fakeHandle.width/2) + overThreshold = Math.abs(mouse.x - pressX) >= Settings.dragThreshold if (overThreshold) preventStealing = true - if (overThreshold || !Settings.hasTouchScreen) + if (overThreshold || force) fakeHandle.x = pos - } - } - - onMouseYChanged: { - if (pressed && !__horizontal) { - var pos = clamp (mouse.y + clickOffset- fakeHandle.height/2) - var overThreshold = Math.abs(mouse.y - pressY) >= Settings.dragThreshold + } else if (!__horizontal) { + pos = clamp (mouse.y + clickOffset- fakeHandle.height/2) + overThreshold = Math.abs(mouse.y - pressY) >= Settings.dragThreshold if (overThreshold) preventStealing = true - if (overThreshold || !Settings.hasTouchScreen) + if (overThreshold || force) fakeHandle.y = pos } } + onPositionChanged: { + if (pressed) + updateHandlePosition(mouse, preventStealing) + + var point = mouseArea.mapToItem(fakeHandle, mouse.x, mouse.y) + handleHovered = fakeHandle.contains(Qt.point(point.x, point.y)) + } + onPressed: { if (slider.activeFocusOnPress) slider.forceActiveFocus(); - var point = mouseArea.mapToItem(fakeHandle, mouse.x, mouse.y) - if (fakeHandle.contains(Qt.point(point.x, point.y))) { + if (handleHovered) { + var point = mouseArea.mapToItem(fakeHandle, mouse.x, mouse.y) clickOffset = __horizontal ? fakeHandle.width/2 - point.x : fakeHandle.height/2 - point.y } pressX = mouse.x pressY = mouse.y + updateHandlePosition(mouse, !Settings.hasTouchScreen) } onReleased: { + updateHandlePosition(mouse, Settings.hasTouchScreen) // If we don't update while dragging, this is the only // moment that the range is updated. if (!slider.updateValueWhileDragging) @@ -278,6 +288,8 @@ Control { clickOffset = 0 preventStealing = false } + + onExited: handleHovered = false } diff --git a/src/controls/SpinBox.qml b/src/controls/SpinBox.qml index f13e81dc4..66a210274 100644 --- a/src/controls/SpinBox.qml +++ b/src/controls/SpinBox.qml @@ -291,8 +291,8 @@ Control { anchors.bottomMargin: __style ? __style.padding.bottom: 0 control: spinbox - cursorHandle: __style ? __style.cursorHandle : undefined - selectionHandle: __style ? __style.selectionHandle : undefined + cursorHandle: __style ? __style.__cursorHandle : undefined + selectionHandle: __style ? __style.__selectionHandle : undefined focus: true activeFocusOnPress: spinbox.activeFocusOnPress diff --git a/src/controls/StackView.qml b/src/controls/StackView.qml index 4423a02ff..f6608ecaa 100644 --- a/src/controls/StackView.qml +++ b/src/controls/StackView.qml @@ -473,7 +473,7 @@ import QtQuick.Controls.Private 1.0 \endlist */ -Item { +FocusScope { id: root /*! \qmlproperty int StackView::depth diff --git a/src/controls/Styles/Android/ButtonStyle.qml b/src/controls/Styles/Android/ButtonStyle.qml index 2a1080513..7157affe0 100644 --- a/src/controls/Styles/Android/ButtonStyle.qml +++ b/src/controls/Styles/Android/ButtonStyle.qml @@ -93,7 +93,7 @@ Style { LabelStyle { id: label visible: !!text - text: control.text + text: StyleHelpers.removeMnemonics(control.text) pressed: control.pressed focused: control.activeFocus selected: control.checked diff --git a/src/controls/Styles/Android/CheckBoxStyle.qml b/src/controls/Styles/Android/CheckBoxStyle.qml index 908665d01..3983a868e 100644 --- a/src/controls/Styles/Android/CheckBoxStyle.qml +++ b/src/controls/Styles/Android/CheckBoxStyle.qml @@ -70,7 +70,7 @@ Style { LabelStyle { id: label - text: control.text + text: StyleHelpers.removeMnemonics(control.text) pressed: control.pressed focused: control.activeFocus selected: control.checked diff --git a/src/controls/Styles/Android/ComboBoxStyle.qml b/src/controls/Styles/Android/ComboBoxStyle.qml index 715dd9f69..366deed56 100644 --- a/src/controls/Styles/Android/ComboBoxStyle.qml +++ b/src/controls/Styles/Android/ComboBoxStyle.qml @@ -37,7 +37,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -import QtQuick 2.2 +import QtQuick 2.4 import QtQuick.Window 2.2 import QtQuick.Controls 1.2 import QtQuick.Controls.Private 1.0 @@ -70,7 +70,7 @@ Style { readonly property real minWidth: styleDef.View_minWidth || 0 readonly property real minHeight: styleDef.View_minHeight || 0 - readonly property real labelWidth: label.implicitWidth + paddingStart + paddingEnd + readonly property real labelWidth: Math.max(label.implicitWidth, metrics.width) + paddingStart + paddingEnd readonly property real labelHeight: label.implicitHeight + bg.padding.top + bg.padding.bottom implicitWidth: Math.max(minWidth, Math.max(bg.implicitWidth, labelWidth)) @@ -85,6 +85,11 @@ Style { styleDef: panel.styleDef.View_background } + TextMetrics { + id: metrics + text: "12345678901234567890" + } + LabelStyle { id: label text: control.currentText @@ -105,11 +110,11 @@ Style { property Component __popupStyle: null property Component __dropDownStyle: null - property Component selectionHandle: DrawableLoader { + property Component __selectionHandle: DrawableLoader { styleDef: AndroidStyle.styleDef.textViewStyle.TextView_textSelectHandleLeft x: -width / 4 * 3 y: styleData.lineHeight } - property Component cursorHandle: CursorHandleStyle { } + property Component __cursorHandle: CursorHandleStyle { } } diff --git a/src/controls/Styles/Android/CursorHandleStyle.qml b/src/controls/Styles/Android/CursorHandleStyle.qml index 97b9fe857..e9d08f8e6 100644 --- a/src/controls/Styles/Android/CursorHandleStyle.qml +++ b/src/controls/Styles/Android/CursorHandleStyle.qml @@ -45,66 +45,51 @@ import "drawables" DrawableLoader { id: delegate - property bool active: false + + property bool hasText: !!editor.text || !!editor.displayText + styleDef: styleData.hasSelection ? AndroidStyle.styleDef.textViewStyle.TextView_textSelectHandleRight : AndroidStyle.styleDef.textViewStyle.TextView_textSelectHandle x: styleData.hasSelection ? -width / 4 : -width / 2 y: styleData.lineHeight - opacity: 1.0 pressed: styleData.pressed focused: control.activeFocus window_focused: focused && control.Window.active - Connections { - target: editor - ignoreUnknownSignals: true - onDisplayTextChanged: { - delegate.state = "hidden" - } + opacity: hasText && (styleData.hasSelection || styleData.pressed || idle.running) ? 1.0 : 0.0 + + Timer { + id: idle + repeat: false + interval: 4000 } Connections { target: styleData - onActivated: { - if (editor.text) { - delegate.active = true - delegate.opacity = 1.0 - delegate.state = "" - if (!styleData.hasSelection) - delegate.state = "idle" - } + onActivated: idle.restart() + onPressedChanged: { + if (!styleData.pressed) + idle.restart() } } - state: "hidden" - - states: [ - State { - name: "hidden" - when: editor.inputMethodComposing && !delegate.active && !editor.text - }, - State { - name: "idle" - when: !styleData.hasSelection && !styleData.pressed - } - ] + // Hide the cursor handle on textual changes, unless the signals are + // indirectly triggered by activating/tapping/moving the handle. When + // text prediction is enabled, the textual content may change when the + // cursor moves and the predicted text is committed. + Connections { + target: editor + ignoreUnknownSignals: true + onTextChanged: if (!ignore.running) idle.stop() + onDisplayTextChanged: if (!ignore.running) idle.stop() + onInputMethodComposing: if (!ignore.running) idle.stop() + } - transitions: [ - Transition { - to: "hidden" - SequentialAnimation { - PauseAnimation { duration: 100 } - PropertyAction { target: delegate; property: "opacity"; value: 0.0 } - } - }, - Transition { - to: "idle" - SequentialAnimation { - PauseAnimation { duration: 4000 } - NumberAnimation { target: delegate; property: "opacity"; to: 0.0 } - PropertyAction { target: delegate; property: "active"; value: false } - } - } - ] + Timer { + id: ignore + repeat: false + interval: 250 + running: idle.running + } } diff --git a/src/controls/Styles/Android/GroupBoxStyle.qml b/src/controls/Styles/Android/GroupBoxStyle.qml index b7346ea43..d8f1127b6 100644 --- a/src/controls/Styles/Android/GroupBoxStyle.qml +++ b/src/controls/Styles/Android/GroupBoxStyle.qml @@ -53,7 +53,7 @@ GroupBoxStyle { readonly property var styleDef: AndroidStyle.styleDef.checkboxStyle readonly property real contentMargin: label.implicitHeight / 3 - readonly property real topMargin: indicator.height + readonly property real topMargin: control.checkable ? indicator.height : label.height Binding { target: root; property: "padding.top"; value: topMargin + contentMargin } Binding { target: root; property: "padding.left"; value: contentMargin } Binding { target: root; property: "padding.right"; value: contentMargin } @@ -95,14 +95,15 @@ GroupBoxStyle { DrawableLoader { id: indicator - visible: control.checkable + active: control.checkable checked: control.checked pressed: check.pressed focused: check.activeFocus window_focused: control.Window.active styleDef: AndroidStyle.styleDef.checkboxStyle.CompoundButton_button - anchors.verticalCenter: label.verticalCenter width: control.checkable ? item.implicitWidth : 0 + anchors.verticalCenter: parent.top + anchors.verticalCenterOffset: topMargin / 2 } LabelStyle { @@ -114,9 +115,10 @@ GroupBoxStyle { window_focused: control.Window.active styleDef: AndroidStyle.styleDef.checkboxStyle - anchors.top: parent.top anchors.left: indicator.right anchors.right: parent.right + anchors.verticalCenter: parent.top + anchors.verticalCenterOffset: topMargin / 2 } } } diff --git a/src/controls/Styles/Android/RadioButtonStyle.qml b/src/controls/Styles/Android/RadioButtonStyle.qml index 76b2c9b7c..678fcdc3d 100644 --- a/src/controls/Styles/Android/RadioButtonStyle.qml +++ b/src/controls/Styles/Android/RadioButtonStyle.qml @@ -70,7 +70,7 @@ Style { LabelStyle { id: label - text: control.text + text: StyleHelpers.removeMnemonics(control.text) pressed: control.pressed focused: control.activeFocus selected: control.checked diff --git a/src/controls/Styles/Android/SpinBoxStyle.qml b/src/controls/Styles/Android/SpinBoxStyle.qml index 86fce0349..0e5df3fd0 100644 --- a/src/controls/Styles/Android/SpinBoxStyle.qml +++ b/src/controls/Styles/Android/SpinBoxStyle.qml @@ -37,7 +37,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -import QtQuick 2.2 +import QtQuick 2.4 import QtQuick.Window 2.2 import QtQuick.Controls 1.2 import QtQuick.Controls.Private 1.0 @@ -58,7 +58,7 @@ Style { readonly property real contentWidth: Math.max(styleDef.View_minWidth || 0, styleData.contentWidth) readonly property real contentHeight: Math.max(styleDef.View_minHeight || 0, styleData.contentHeight) - readonly property real labelWidth: label.implicitWidth + bg.padding.left + bg.padding.right + readonly property real labelWidth: Math.max(label.implicitWidth, metrics.width) + bg.padding.left + bg.padding.right readonly property real labelHeight: label.implicitHeight + bg.padding.top + bg.padding.bottom implicitWidth: Math.max(contentWidth, Math.max(bg.implicitWidth, labelWidth)) @@ -88,6 +88,11 @@ Style { readonly property int horizontalAlignment: Qt.AlignLeft readonly property int verticalAlignment: Qt.AlignVCenter + TextMetrics { + id: metrics + text: "12345678901234567890" + } + LabelStyle { id: label visible: false @@ -98,11 +103,11 @@ Style { } } - property Component selectionHandle: DrawableLoader { + property Component __selectionHandle: DrawableLoader { styleDef: AndroidStyle.styleDef.textViewStyle.TextView_textSelectHandleLeft x: -width / 4 * 3 y: styleData.lineHeight } - property Component cursorHandle: CursorHandleStyle { } + property Component __cursorHandle: CursorHandleStyle { } } diff --git a/src/controls/Styles/Android/SwitchStyle.qml b/src/controls/Styles/Android/SwitchStyle.qml index 4c36c918e..6e9260c35 100644 --- a/src/controls/Styles/Android/SwitchStyle.qml +++ b/src/controls/Styles/Android/SwitchStyle.qml @@ -79,18 +79,26 @@ SwitchStyle { Item { id: thumb + readonly property bool hideText: AndroidStyle.styleDef.switchStyle.Switch_showText === false + x: control.checked ? max : min - FontMetrics { - id: metrics + TextMetrics { + id: onMetrics + font: label.font + text: panel.styleDef.Switch_textOn + } + + TextMetrics { + id: offMetrics font: label.font + text: panel.styleDef.Switch_textOff } - readonly property real maxTextWidth: Math.max(metrics.boundingRect(panel.styleDef.Switch_textOn).width, - metrics.boundingRect(panel.styleDef.Switch_textOff).width) + readonly property real maxTextWidth: Math.max(onMetrics.width, offMetrics.width) implicitWidth: Math.max(loader.implicitWidth, maxTextWidth + 2 * panel.styleDef.Switch_thumbTextPadding) - implicitHeight: Math.max(loader.implicitHeight, metrics.height) + implicitHeight: Math.max(loader.implicitHeight, onMetrics.height, offMetrics.height) anchors.top: parent.top anchors.bottom: parent.bottom @@ -120,6 +128,7 @@ SwitchStyle { LabelStyle { id: label + visible: !thumb.hideText text: control.checked ? panel.styleDef.Switch_textOn : panel.styleDef.Switch_textOff pressed: control.pressed diff --git a/src/controls/Styles/Android/TextAreaStyle.qml b/src/controls/Styles/Android/TextAreaStyle.qml index 61ea9fb85..85950efa0 100644 --- a/src/controls/Styles/Android/TextAreaStyle.qml +++ b/src/controls/Styles/Android/TextAreaStyle.qml @@ -72,11 +72,11 @@ ScrollViewStyle { styleDef: style.styleDef } - property Component selectionHandle: DrawableLoader { + property Component __selectionHandle: DrawableLoader { styleDef: AndroidStyle.styleDef.textViewStyle.TextView_textSelectHandleLeft x: -width / 4 * 3 y: styleData.lineHeight } - property Component cursorHandle: CursorHandleStyle { } + property Component __cursorHandle: CursorHandleStyle { } } diff --git a/src/controls/Styles/Android/TextFieldStyle.qml b/src/controls/Styles/Android/TextFieldStyle.qml index e7eec32c6..0edc5c90b 100644 --- a/src/controls/Styles/Android/TextFieldStyle.qml +++ b/src/controls/Styles/Android/TextFieldStyle.qml @@ -37,7 +37,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -import QtQuick 2.2 +import QtQuick 2.4 import QtQuick.Window 2.2 import QtQuick.Controls 1.2 import QtQuick.Controls.Private 1.0 @@ -56,7 +56,7 @@ Style { readonly property real minWidth: styleDef.View_minWidth || 0 readonly property real minHeight: styleDef.View_minHeight || 0 - readonly property real labelWidth: label.implicitWidth + bg.padding.left + bg.padding.right + readonly property real labelWidth: Math.max(label.implicitWidth, metrics.width) + bg.padding.left + bg.padding.right readonly property real labelHeight: label.implicitHeight + bg.padding.top + bg.padding.bottom implicitWidth: Math.max(minWidth, Math.max(bg.implicitWidth, labelWidth)) @@ -81,21 +81,26 @@ Style { readonly property alias selectionColor: label.selectionColor readonly property color selectedTextColor: label.selectedTextColor + TextMetrics { + id: metrics + text: "12345678901234567890" + } + LabelStyle { id: label visible: false - text: control.text + text: control.text || control.placeholderText focused: control.activeFocus window_focused: focused && control.Window.active styleDef: panel.styleDef } } - property Component selectionHandle: DrawableLoader { + property Component __selectionHandle: DrawableLoader { styleDef: AndroidStyle.styleDef.textViewStyle.TextView_textSelectHandleLeft x: -width / 4 * 3 y: styleData.lineHeight } - property Component cursorHandle: CursorHandleStyle { } + property Component __cursorHandle: CursorHandleStyle { } } diff --git a/src/controls/Styles/Android/ToolButtonStyle.qml b/src/controls/Styles/Android/ToolButtonStyle.qml index 33d922207..9dbe60f77 100644 --- a/src/controls/Styles/Android/ToolButtonStyle.qml +++ b/src/controls/Styles/Android/ToolButtonStyle.qml @@ -95,7 +95,7 @@ Style { LabelStyle { id: label visible: !!text - text: control.text + text: StyleHelpers.removeMnemonics(control.text) pressed: control.pressed focused: control.activeFocus selected: control.checked diff --git a/src/controls/Styles/Android/drawables/AnimationDrawable.qml b/src/controls/Styles/Android/drawables/AnimationDrawable.qml index a522bfa7c..12d576ff4 100644 --- a/src/controls/Styles/Android/drawables/AnimationDrawable.qml +++ b/src/controls/Styles/Android/drawables/AnimationDrawable.qml @@ -49,14 +49,17 @@ Drawable { property int currentFrame: 0 readonly property int frameCount: styleDef.frames ? styleDef.frames.length : 0 readonly property var frameDef: styleDef.frames ? styleDef.frames[currentFrame] : undefined + readonly property alias running: timer.running + property bool oneshot: styleDef.oneshot Timer { + id: timer repeat: true running: root.frameCount && root.visible && Qt.application.active interval: root.frameDef ? root.frameDef.duration : 0 onTriggered: { var frame = root.currentFrame + 1 - repeat = !root.styleDef.oneshot || frame < root.frameCount - 1 + repeat = !root.oneshot || frame < root.frameCount - 1 root.currentFrame = frame % root.frameCount } } diff --git a/src/controls/Styles/Android/drawables/ImageDrawable.qml b/src/controls/Styles/Android/drawables/ImageDrawable.qml index 1e71a389a..4b41b2f21 100644 --- a/src/controls/Styles/Android/drawables/ImageDrawable.qml +++ b/src/controls/Styles/Android/drawables/ImageDrawable.qml @@ -52,5 +52,33 @@ Drawable { anchors.fill: parent fillMode: Image.TileHorizontally source: AndroidStyle.filePath(styleDef.path) + + layer.enabled: !!styleDef && !!styleDef.tintList + layer.effect: ShaderEffect { + property variant source: image + property color color: AndroidStyle.colorValue(styleDef.tintList[state]) + state: { + var states = [] + if (pressed) states.push("PRESSED") + if (enabled) states.push("ENABLED") + if (focused) states.push("FOCUSED") + if (selected) states.push("SELECTED") + if (window_focused) states.push("WINDOW_FOCUSED") + if (!states.length) + states.push("EMPTY") + return states.join("_") + "_STATE_SET" + } + // QtGraphicalEffects/ColorOverlay: + fragmentShader: " + varying mediump vec2 qt_TexCoord0; + uniform highp float qt_Opacity; + uniform lowp sampler2D source; + uniform highp vec4 color; + void main() { + highp vec4 pixelColor = texture2D(source, qt_TexCoord0); + gl_FragColor = vec4(mix(pixelColor.rgb/max(pixelColor.a, 0.00390625), color.rgb/max(color.a, 0.00390625), color.a) * pixelColor.a, pixelColor.a) * qt_Opacity; + } + " + } } } diff --git a/src/controls/Styles/Android/drawables/StateDrawable.qml b/src/controls/Styles/Android/drawables/StateDrawable.qml index d446542d9..862ab9ae6 100644 --- a/src/controls/Styles/Android/drawables/StateDrawable.qml +++ b/src/controls/Styles/Android/drawables/StateDrawable.qml @@ -46,10 +46,12 @@ Drawable { implicitWidth: Math.max(loader.implicitWidth, styleDef.width || 0) implicitHeight: Math.max(loader.implicitHeight, styleDef.height || 0) + property int prevMatch: 0 + DrawableLoader { id: loader anchors.fill: parent - styleDef: bestStateMatch() + visible: !animation.active focused: root.focused pressed: root.pressed checked: root.checked @@ -65,17 +67,70 @@ Drawable { clippables: root.clippables } - function bestStateMatch () { + Loader { + id: animation + property var animDef + active: false + anchors.fill: parent + sourceComponent: AnimationDrawable { + anchors.fill: parent + styleDef: animDef + focused: root.focused + pressed: root.pressed + checked: root.checked + selected: root.selected + accelerated: root.accelerated + window_focused: root.window_focused + index: root.index + level: root.level + levelId: root.levelId + orientations: root.orientations + duration: root.duration + excludes: root.excludes + clippables: root.clippables + + oneshot: true + onRunningChanged: if (!running) animation.active = false + } + } + + onStyleDefChanged: resolveState() + Component.onCompleted: resolveState() + + // In order to be able to find appropriate transition paths between + // various states, the following states must be allowed to change in + // batches. For example, button-like controls could have a transition + // path from pressed+checked to unpressed+unchecked. We must let both + // properties change before we try to find the transition path. + onEnabledChanged: resolver.start() + onFocusedChanged: resolver.start() + onPressedChanged: resolver.start() + onCheckedChanged: resolver.start() + onSelectedChanged: resolver.start() + onAcceleratedChanged: resolver.start() + onWindow_focusedChanged: resolver.start() + + Timer { + id: resolver + interval: 15 + onTriggered: resolveState() + } + + function resolveState () { if (styleDef && styleDef.stateslist) { var bestMatch = 0 var highestScore = -1 var stateslist = styleDef.stateslist + var transitions = [] for (var i = 0; i < stateslist.length; ++i) { var score = 0 var state = stateslist[i] + if (state.transition) + transitions.push(i) + for (var s in state.states) { if (s === "pressed") score += (pressed === state.states[s]) ? 1 : -10 @@ -98,8 +153,21 @@ Drawable { highestScore = score } } - return stateslist[bestMatch].drawable + + if (prevMatch != bestMatch) { + for (var t = 0; t < transitions.length; ++t) { + var transition = stateslist[transitions[t]].transition + if ((transition.from == prevMatch && transition.to == bestMatch) || + (transition.reverse && transition.from == bestMatch && transition.to == prevMatch)) { + animation.animDef = stateslist[transitions[t]].drawable + animation.active = true + break + } + } + prevMatch = bestMatch + } + + loader.styleDef = stateslist[bestMatch].drawable } - return undefined } } diff --git a/src/controls/Styles/Base/ButtonStyle.qml b/src/controls/Styles/Base/ButtonStyle.qml index 54576b7fd..9b55d26d7 100644 --- a/src/controls/Styles/Base/ButtonStyle.qml +++ b/src/controls/Styles/Base/ButtonStyle.qml @@ -143,7 +143,7 @@ Style { id: text renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering anchors.verticalCenter: parent.verticalCenter - text: control.text + text: StyleHelpers.stylizeMnemonics(control.text) color: SystemPaletteSingleton.buttonText(control.enabled) } } diff --git a/src/controls/Styles/Base/CheckBoxStyle.qml b/src/controls/Styles/Base/CheckBoxStyle.qml index a23c77210..6fbdaede6 100644 --- a/src/controls/Styles/Base/CheckBoxStyle.qml +++ b/src/controls/Styles/Base/CheckBoxStyle.qml @@ -98,7 +98,7 @@ Style { } Text { id: text - text: control.text + text: StyleHelpers.stylizeMnemonics(control.text) anchors.centerIn: parent color: SystemPaletteSingleton.text(control.enabled) renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering diff --git a/src/controls/Styles/Base/ComboBoxStyle.qml b/src/controls/Styles/Base/ComboBoxStyle.qml index 77d2e91e1..1a810772a 100644 --- a/src/controls/Styles/Base/ComboBoxStyle.qml +++ b/src/controls/Styles/Base/ComboBoxStyle.qml @@ -280,7 +280,8 @@ Style { property Component __scrollerStyle: null } - /*! The cursor handle. + /*! \internal + The cursor handle. \since QtQuick.Controls.Styles 1.3 The parent of the handle is positioned to the top left corner of @@ -297,9 +298,10 @@ Style { \row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text. \endtable */ - property Component cursorHandle + property Component __cursorHandle - /*! The selection handle. + /*! \internal + The selection handle. \since QtQuick.Controls.Styles 1.3 The parent of the handle is positioned to the top left corner of @@ -316,10 +318,11 @@ Style { \row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text. \endtable */ - property Component selectionHandle + property Component __selectionHandle - /*! The cursor delegate. + /*! \internal + The cursor delegate. \since QtQuick.Controls.Styles 1.3 */ - property Component cursorDelegate + property Component __cursorDelegate } diff --git a/src/controls/Styles/Base/RadioButtonStyle.qml b/src/controls/Styles/Base/RadioButtonStyle.qml index 8f70d854c..7975de701 100644 --- a/src/controls/Styles/Base/RadioButtonStyle.qml +++ b/src/controls/Styles/Base/RadioButtonStyle.qml @@ -97,7 +97,7 @@ Style { } Text { id: text - text: control.text + text: StyleHelpers.stylizeMnemonics(control.text) anchors.centerIn: parent color: SystemPaletteSingleton.text(control.enabled) renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering diff --git a/src/controls/Styles/Base/SpinBoxStyle.qml b/src/controls/Styles/Base/SpinBoxStyle.qml index 1bcb6b5cf..d821940a5 100644 --- a/src/controls/Styles/Base/SpinBoxStyle.qml +++ b/src/controls/Styles/Base/SpinBoxStyle.qml @@ -210,7 +210,8 @@ Style { } } - /*! The cursor handle. + /*! \internal + The cursor handle. \since QtQuick.Controls.Styles 1.3 The parent of the handle is positioned to the top left corner of @@ -227,9 +228,10 @@ Style { \row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text. \endtable */ - property Component cursorHandle + property Component __cursorHandle - /*! The selection handle. + /*! \internal + The selection handle. \since QtQuick.Controls.Styles 1.3 The parent of the handle is positioned to the top left corner of @@ -246,10 +248,11 @@ Style { \row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text. \endtable */ - property Component selectionHandle + property Component __selectionHandle - /*! The cursor delegate. + /*! \internal + The cursor delegate. \since QtQuick.Controls.Styles 1.3 */ - property Component cursorDelegate + property Component __cursorDelegate } diff --git a/src/controls/Styles/Base/TableViewStyle.qml b/src/controls/Styles/Base/TableViewStyle.qml index ca4cc4288..e5e6db2fd 100644 --- a/src/controls/Styles/Base/TableViewStyle.qml +++ b/src/controls/Styles/Base/TableViewStyle.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Quick Controls module of the Qt Toolkit. @@ -110,7 +110,7 @@ ScrollViewStyle { */ property Component rowDelegate: Rectangle { height: Math.round(TextSingleton.implicitHeight * 1.2) - property color selectedColor: styleData.hasActiveFocus ? "#07c" : "#999" + property color selectedColor: control.activeFocus ? "#07c" : "#999" color: styleData.selected ? selectedColor : !styleData.alternate ? alternateBackgroundColor : backgroundColor } diff --git a/src/controls/Styles/Base/TextAreaStyle.qml b/src/controls/Styles/Base/TextAreaStyle.qml index bd3ed31ea..56a1ec58f 100644 --- a/src/controls/Styles/Base/TextAreaStyle.qml +++ b/src/controls/Styles/Base/TextAreaStyle.qml @@ -104,7 +104,8 @@ ScrollViewStyle { \sa TextArea::textMargin */ property real textMargin: 4 - /*! The cursor handle. + /*! \internal + The cursor handle. \since QtQuick.Controls.Styles 1.3 The parent of the handle is positioned to the top left corner of @@ -121,9 +122,10 @@ ScrollViewStyle { \row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text. \endtable */ - property Component cursorHandle + property Component __cursorHandle - /*! The selection handle. + /*! \internal + The selection handle. \since QtQuick.Controls.Styles 1.3 The parent of the handle is positioned to the top left corner of @@ -140,10 +142,11 @@ ScrollViewStyle { \row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text. \endtable */ - property Component selectionHandle + property Component __selectionHandle - /*! The cursor delegate. + /*! \internal + The cursor delegate. \since QtQuick.Controls.Styles 1.3 */ - property Component cursorDelegate + property Component __cursorDelegate } diff --git a/src/controls/Styles/Base/TextFieldStyle.qml b/src/controls/Styles/Base/TextFieldStyle.qml index c1e7a69f6..4d0a66eba 100644 --- a/src/controls/Styles/Base/TextFieldStyle.qml +++ b/src/controls/Styles/Base/TextFieldStyle.qml @@ -157,7 +157,8 @@ Style { } } - /*! The cursor handle. + /*! \internal + The cursor handle. \since QtQuick.Controls.Styles 1.3 The parent of the handle is positioned to the top left corner of @@ -174,9 +175,10 @@ Style { \row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text. \endtable */ - property Component cursorHandle + property Component __cursorHandle - /*! The selection handle. + /*! \internal + The selection handle. \since QtQuick.Controls.Styles 1.3 The parent of the handle is positioned to the top left corner of @@ -193,10 +195,11 @@ Style { \row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text. \endtable */ - property Component selectionHandle + property Component __selectionHandle - /*! The cursor delegate. + /*! \internal + The cursor delegate. \since QtQuick.Controls.Styles 1.3 */ - property Component cursorDelegate + property Component __cursorDelegate } diff --git a/src/controls/Styles/Base/ToolButtonStyle.qml b/src/controls/Styles/Base/ToolButtonStyle.qml index 364b1b31e..7183623fd 100644 --- a/src/controls/Styles/Base/ToolButtonStyle.qml +++ b/src/controls/Styles/Base/ToolButtonStyle.qml @@ -74,7 +74,7 @@ Style { id: label visible: !hasIcon anchors.centerIn: parent - text: control.text + text: StyleHelpers.stylizeMnemonics(control.text) renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering } Image { diff --git a/src/controls/Styles/Desktop/ComboBoxStyle.qml b/src/controls/Styles/Desktop/ComboBoxStyle.qml index d897a2a45..758518edc 100644 --- a/src/controls/Styles/Desktop/ComboBoxStyle.qml +++ b/src/controls/Styles/Desktop/ComboBoxStyle.qml @@ -109,8 +109,8 @@ Style { elementType: "itemrow" selected: styleData.selected - implicitWidth: textItem.contentWidth - implicitHeight: textItem.contentHeight + implicitWidth: textItem.implicitWidth + implicitHeight: textItem.implicitHeight StyleItem { id: textItem diff --git a/src/controls/Styles/Desktop/MenuStyle.qml b/src/controls/Styles/Desktop/MenuStyle.qml index ecd898cfc..1c21f8c41 100644 --- a/src/controls/Styles/Desktop/MenuStyle.qml +++ b/src/controls/Styles/Desktop/MenuStyle.qml @@ -100,7 +100,7 @@ Style { selected: styleData.selected on: styleData.checkable && styleData.checked - hints: { "showUnderlined": styleData.underlineMnemonics } + hints: { "showUnderlined": styleData.underlineMnemonic } properties: { "checkable": styleData.checkable, diff --git a/src/controls/Styles/Desktop/TableViewStyle.qml b/src/controls/Styles/Desktop/TableViewStyle.qml index 605c62d63..11f8ed54c 100644 --- a/src/controls/Styles/Desktop/TableViewStyle.qml +++ b/src/controls/Styles/Desktop/TableViewStyle.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Quick Controls module of the Qt Toolkit. @@ -82,7 +82,7 @@ ScrollViewStyle { visible: styleData.selected || styleData.alternate source: "image://__tablerow/" + (styleData.alternate ? "alternate_" : "") + (styleData.selected ? "selected_" : "") - + (styleData.hasActiveFocus ? "active" : "") + + (control.activeFocus ? "active" : "") height: Math.max(16, RowItemSingleton.implicitHeight) border.left: 4 ; border.right: 4 } diff --git a/src/controls/Styles/iOS/ComboBoxStyle.qml b/src/controls/Styles/iOS/ComboBoxStyle.qml index 147fd7fdb..ba657298e 100644 --- a/src/controls/Styles/iOS/ComboBoxStyle.qml +++ b/src/controls/Styles/iOS/ComboBoxStyle.qml @@ -42,7 +42,7 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.3 ComboBoxStyle { - selectionHandle: SelectionHandleStyle{} - cursorHandle: CursorHandleStyle{} - cursorDelegate: CursorDelegate{} + __selectionHandle: SelectionHandleStyle{} + __cursorHandle: CursorHandleStyle{} + __cursorDelegate: CursorDelegate{} } diff --git a/src/controls/Styles/iOS/CursorHandleStyle.qml b/src/controls/Styles/iOS/CursorHandleStyle.qml index 26ab97282..408a7bf46 100644 --- a/src/controls/Styles/iOS/CursorHandleStyle.qml +++ b/src/controls/Styles/iOS/CursorHandleStyle.qml @@ -45,6 +45,7 @@ Item { y: -20 width: 80 height: knob.height + knobLine.height + 60 + visible: styleData.hasSelection Rectangle { id: knob diff --git a/src/controls/Styles/iOS/SpinBoxStyle.qml b/src/controls/Styles/iOS/SpinBoxStyle.qml index a764cb79d..c898e5e9f 100644 --- a/src/controls/Styles/iOS/SpinBoxStyle.qml +++ b/src/controls/Styles/iOS/SpinBoxStyle.qml @@ -42,7 +42,7 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.3 SpinBoxStyle { - selectionHandle: SelectionHandleStyle{} - cursorHandle: CursorHandleStyle{} - cursorDelegate: CursorDelegate{} + __selectionHandle: SelectionHandleStyle{} + __cursorHandle: CursorHandleStyle{} + __cursorDelegate: CursorDelegate{} } diff --git a/src/controls/Styles/iOS/TextAreaStyle.qml b/src/controls/Styles/iOS/TextAreaStyle.qml index 6b8a18003..6be12be68 100644 --- a/src/controls/Styles/iOS/TextAreaStyle.qml +++ b/src/controls/Styles/iOS/TextAreaStyle.qml @@ -51,7 +51,7 @@ ScrollViewStyle { property color selectedTextColor: SystemPaletteSingleton.highlightedText(control.enabled) property color backgroundColor: control.backgroundVisible ? SystemPaletteSingleton.base(control.enabled) : "transparent" property int renderType: Text.QtRendering - property Component selectionHandle: SelectionHandleStyle{} - property Component cursorHandle: CursorHandleStyle{} - property Component cursorDelegate: CursorDelegate{} + property Component __selectionHandle: SelectionHandleStyle{} + property Component __cursorHandle: CursorHandleStyle{} + property Component __cursorDelegate: CursorDelegate{} } diff --git a/src/controls/Styles/iOS/TextFieldStyle.qml b/src/controls/Styles/iOS/TextFieldStyle.qml index 28ad692ff..ca237a0a2 100644 --- a/src/controls/Styles/iOS/TextFieldStyle.qml +++ b/src/controls/Styles/iOS/TextFieldStyle.qml @@ -42,7 +42,7 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.3 TextFieldStyle { - selectionHandle: SelectionHandleStyle{} - cursorHandle: CursorHandleStyle{} - cursorDelegate: CursorDelegate{} + __selectionHandle: SelectionHandleStyle{} + __cursorHandle: CursorHandleStyle{} + __cursorDelegate: CursorDelegate{} } diff --git a/src/controls/Styles/iOS/ToolButtonStyle.qml b/src/controls/Styles/iOS/ToolButtonStyle.qml index c2d2db9c3..3e4cbd2e5 100644 --- a/src/controls/Styles/iOS/ToolButtonStyle.qml +++ b/src/controls/Styles/iOS/ToolButtonStyle.qml @@ -38,5 +38,6 @@ ** ****************************************************************************/ import QtQuick.Controls.Styles 1.3 +import QtQuick.Controls.Private 1.0 ToolButtonStyle { } diff --git a/src/controls/TableView.qml b/src/controls/TableView.qml index 11b0662aa..fb940c444 100644 --- a/src/controls/TableView.qml +++ b/src/controls/TableView.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Quick Controls module of the Qt Toolkit. @@ -56,25 +56,42 @@ import QtQuick.Window 2.1 A TableView is similar to \l ListView, and adds scroll bars, selection, and resizable header sections. As with \l ListView, data for each row is provided through a \l model: - \code - ListModel { - id: libraryModel - ListElement{ title: "A Masterpiece" ; author: "Gabriel" } - ListElement{ title: "Brilliance" ; author: "Jens" } - ListElement{ title: "Outstanding" ; author: "Frederik" } - } - \endcode + \code + ListModel { + id: libraryModel + ListElement { + title: "A Masterpiece" + author: "Gabriel" + } + ListElement { + title: "Brilliance" + author: "Jens" + } + ListElement { + title: "Outstanding" + author: "Frederik" + } + } + \endcode You provide title and size of a column header by adding a \l TableViewColumn as demonstrated below. - \code - TableView { - TableViewColumn{ role: "title" ; title: "Title" ; width: 100 } - TableViewColumn{ role: "author" ; title: "Author" ; width: 200 } - model: libraryModel - } - \endcode + \code + TableView { + TableViewColumn { + role: "title" + title: "Title" + width: 100 + } + TableViewColumn { + role: "author" + title: "Author" + width: 200 + } + model: libraryModel + } + \endcode The header sections are attached to values in the \l model by defining the model role they attach to. Each property in the model will @@ -149,6 +166,7 @@ ScrollView { \li styleData.elideMode - the elide mode of the column \li styleData.textAlignment - the horizontal text alignment of the column \li styleData.pressed - true when the item is pressed (since QtQuick.Controls 1.3) + \li styleData.hasActiveFocus - true when the row has focus (since QtQuick.Controls 1.3) \endlist Example: @@ -165,9 +183,9 @@ ScrollView { \note For performance reasons, created delegates can be recycled across multiple table rows. This implies that when you make use of implicit - properties such as \c styledata.row or \c model, these values can change also - after the delegate has been constructed. In practice this means you should not assume - that content is fixed when \c Component.onCompleted happens, but instead rely on + properties such as \c styleData.row or \c model, these values can change + after the delegate has been constructed. This means that you should not assume + that content is fixed when \c Component.onCompleted is called, but instead rely on bindings to such properties. */ property Component itemDelegate: __style ? __style.itemDelegate : null @@ -179,14 +197,15 @@ ScrollView { \li styleData.alternate - true when the row uses the alternate background color \li styleData.selected - true when the row is currently selected \li styleData.row - the index of the row + \li styleData.hasActiveFocus - true when the row has focus \li styleData.pressed - true when the row is pressed (since QtQuick.Controls 1.3) \endlist \note For performance reasons, created delegates can be recycled across multiple table rows. This implies that when you make use of implicit - properties such as \c styledata.row or \c model, these values can change also - after the delegate has been constructed. In practice this means you should not assume - that content is fixed when \c Component.onCompleted happens, but instead rely on + properties such as \c styleData.row or \c model, these values can change + after the delegate has been constructed. This means that you should not assume + that content is fixed when \c Component.onCompleted is called, but instead rely on bindings to such properties. */ property Component rowDelegate: __style ? __style.rowDelegate : null @@ -761,7 +780,7 @@ ScrollView { property QtObject styleData: QtObject { readonly property bool alternate: (index + rowCount) % 2 === 1 readonly property bool selected: false - readonly property bool hasActiveFocus: root.activeFocus + readonly property bool hasActiveFocus: false readonly property bool pressed: false } readonly property var model: listView.model @@ -790,19 +809,23 @@ ScrollView { Keys.forwardTo: root Keys.onUpPressed: { - event.accepted = false + var oldIndex = listView.currentIndex __scroller.blockUpdates = true; listView.decrementCurrentIndex(); __scroller.blockUpdates = false; + if (oldIndex === listView.currentIndex) + event.accepted = false if (selectionMode) keySelect(event.modifiers & Qt.ShiftModifier, currentRow) } Keys.onDownPressed: { - event.accepted = false + var oldIndex = listView.currentIndex __scroller.blockUpdates = true; listView.incrementCurrentIndex(); __scroller.blockUpdates = false; + if (oldIndex === listView.currentIndex) + event.accepted = false if (selectionMode) keySelect(event.modifiers & Qt.ShiftModifier, currentRow) } @@ -829,15 +852,17 @@ ScrollView { } Keys.onReturnPressed: { - event.accepted = false if (currentRow > -1) root.activated(currentRow); + else + event.accepted = false } delegate: FocusScope { id: rowItemContainer activeFocusOnTab: false + z: rowItem.activeFocus ? 0.7 : rowItem.itemSelected ? 0.5 : 0 property Item rowItem // We recycle instantiated row items to speed up list scrolling @@ -918,7 +943,7 @@ ScrollView { readonly property int row: rowitem.rowIndex readonly property bool alternate: rowitem.alternate readonly property bool selected: rowitem.itemSelected - readonly property bool hasActiveFocus: root.activeFocus + readonly property bool hasActiveFocus: rowitem.activeFocus readonly property bool pressed: rowitem.rowIndex === mousearea.pressedRow } readonly property var model: listView.model @@ -949,6 +974,7 @@ ScrollView { readonly property int elideMode: columnItem.elideMode readonly property int textAlignment: columnItem.horizontalAlignment readonly property bool selected: rowitem.itemSelected + readonly property bool hasActiveFocus: rowitem.activeFocus readonly property bool pressed: row === mousearea.pressedRow && column === mousearea.pressedColumn readonly property color textColor: rowitem.itemTextColor readonly property string role: columnItem.role diff --git a/src/controls/TextArea.qml b/src/controls/TextArea.qml index 5e8387db6..1c19a300f 100644 --- a/src/controls/TextArea.qml +++ b/src/controls/TextArea.qml @@ -718,7 +718,8 @@ ScrollView { TextEdit { id: edit focus: true - cursorDelegate: __style && __style.cursorDelegate ? __style.cursorDelegate : null + cursorDelegate: __style && __style.__cursorDelegate ? __style.__cursorDelegate : null + persistentSelection: true Rectangle { id: colorRect @@ -769,7 +770,7 @@ ScrollView { wrapMode: TextEdit.WordWrap textMargin: __style && __style.textMargin !== undefined ? __style.textMargin : 4 - selectByMouse: area.selectByMouse && (!cursorHandle.delegate || !selectionHandle.delegate) + selectByMouse: area.selectByMouse && (!Settings.isMobile || !cursorHandle.delegate || !selectionHandle.delegate) readOnly: false Keys.forwardTo: area @@ -846,15 +847,20 @@ ScrollView { } MouseArea { + id: mouseArea anchors.fill: parent cursorShape: edit.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor - acceptedButtons: edit.selectByMouse ? Qt.NoButton : Qt.LeftButton + acceptedButtons: (edit.selectByMouse ? Qt.NoButton : Qt.LeftButton) | (area.menu ? Qt.RightButton : Qt.NoButton) onClicked: { + if (editMenu.item) + return; var pos = edit.positionAt(mouse.x, mouse.y) edit.moveHandles(pos, pos) edit.activate() } onPressAndHold: { + if (editMenu.item) + return; var pos = edit.positionAt(mouse.x, mouse.y) edit.moveHandles(pos, area.selectByMouse ? -1 : pos) edit.activate() @@ -865,6 +871,7 @@ ScrollView { id: editMenu control: area input: edit + mouseArea: mouseArea cursorHandle: cursorHandle selectionHandle: selectionHandle flickable: flickable @@ -878,8 +885,8 @@ ScrollView { control: area z: 1 // above scrollbars parent: Qt.platform.os === "ios" ? editor : __scroller // no clip - active: area.selectByMouse - delegate: __style.selectionHandle + active: area.selectByMouse && Settings.isMobile + delegate: __style.__selectionHandle maximum: cursorHandle.position - 1 // Mention contentX and contentY in the mappedPos binding to force re-evaluation if they change @@ -888,8 +895,13 @@ ScrollView { x: mappedPos.x y: mappedPos.y - visible: pressed || (edit.hasSelection && handleY + handleHeight >= -1 && handleY <= viewport.height + 1 - && handleX + handleWidth >= -1 && handleX <= viewport.width + 1) + property var posInViewport: flickableItem.contentX !== flickableItem.contentY !== Number.MAX_VALUE ? + parent.mapToItem(viewport, handleX, handleY) : -1 + visible: pressed || (edit.hasSelection + && posInViewport.y + handleHeight >= -1 + && posInViewport.y <= viewport.height + 1 + && posInViewport.x + handleWidth >= -1 + && posInViewport.x <= viewport.width + 1) onPositionChanged: { if (!edit.blockRecursion) { @@ -909,8 +921,8 @@ ScrollView { control: area z: 1 // above scrollbars parent: Qt.platform.os === "ios" ? editor : __scroller // no clip - active: area.selectByMouse - delegate: __style.cursorHandle + active: area.selectByMouse && Settings.isMobile + delegate: __style.__cursorHandle minimum: edit.hasSelection ? selectionHandle.position + 1 : -1 // Mention contentX and contentY in the mappedPos binding to force re-evaluation if they change @@ -919,8 +931,13 @@ ScrollView { x: mappedPos.x y: mappedPos.y - visible: pressed || (edit.hasSelection && handleY + handleHeight >= -1 && handleY <= viewport.height + 1 - && handleX + handleWidth >= -1 && handleX <= viewport.width + 1) + property var posInViewport: flickableItem.contentX !== flickableItem.contentY !== Number.MAX_VALUE ? + parent.mapToItem(viewport, handleX, handleY) : -1 + visible: pressed || ((edit.cursorVisible || edit.hasSelection) + && posInViewport.y + handleHeight >= -1 + && posInViewport.y <= viewport.height + 1 + && posInViewport.x + handleWidth >= -1 + && posInViewport.x <= viewport.width + 1) onPositionChanged: { if (!edit.blockRecursion) { diff --git a/src/controls/TextField.qml b/src/controls/TextField.qml index 2e940bdb1..8a544a694 100644 --- a/src/controls/TextField.qml +++ b/src/controls/TextField.qml @@ -629,7 +629,7 @@ Control { font: textInput.font horizontalAlignment: textInput.horizontalAlignment verticalAlignment: textInput.verticalAlignment - opacity: !textInput.text.length && !textInput.inputMethodComposing ? 1 : 0 + opacity: textInput.displayText.length ? 0.0 : 1.0 color: __panel ? __panel.placeholderTextColor : "darkgray" clip: contentWidth > width; elide: Text.ElideRight @@ -643,8 +643,8 @@ Control { selectedTextColor: __panel ? __panel.selectedTextColor : "white" control: textfield - cursorHandle: __style ? __style.cursorHandle : undefined - selectionHandle: __style ? __style.selectionHandle : undefined + cursorHandle: __style ? __style.__cursorHandle : undefined + selectionHandle: __style ? __style.__selectionHandle : undefined font: __panel ? __panel.font : TextSingleton.font anchors.leftMargin: __panel ? __panel.leftMargin : 0 @@ -662,12 +662,7 @@ Control { Keys.forwardTo: textfield - onAccepted: { - Qt.inputMethod.commit() - if (!(textInput.inputMethodHints & Qt.ImhMultiLine)) - Qt.inputMethod.hide() - textfield.accepted() - } + onAccepted: textfield.accepted() onEditingFinished: textfield.editingFinished() } diff --git a/src/controls/ToolBar.qml b/src/controls/ToolBar.qml index cc07fd5cb..b79e0ade8 100644 --- a/src/controls/ToolBar.qml +++ b/src/controls/ToolBar.qml @@ -151,7 +151,7 @@ FocusScope { anchors.topMargin: topMargin anchors.leftMargin: leftMargin - anchors.rightMargin: rightMargin + (buttonLoader.active ? buttonLoader.width : 0) + anchors.rightMargin: rightMargin + (buttonLoader.active ? buttonLoader.width + rightMargin : 0) anchors.bottomMargin: bottomMargin property int topMargin: __style ? __style.padding.top : 0 diff --git a/src/controls/doc/images/qtquickcontrols-android.png b/src/controls/doc/images/qtquickcontrols-android.png Binary files differdeleted file mode 100644 index 8877c09cd..000000000 --- a/src/controls/doc/images/qtquickcontrols-android.png +++ /dev/null diff --git a/src/controls/doc/images/qtquickcontrols-example-gallery-android-dark.png b/src/controls/doc/images/qtquickcontrols-example-gallery-android-dark.png Binary files differnew file mode 100644 index 000000000..7e27b466b --- /dev/null +++ b/src/controls/doc/images/qtquickcontrols-example-gallery-android-dark.png diff --git a/src/controls/doc/images/qtquickcontrols-example-gallery-android.png b/src/controls/doc/images/qtquickcontrols-example-gallery-android.png Binary files differnew file mode 100644 index 000000000..11ba2cc0c --- /dev/null +++ b/src/controls/doc/images/qtquickcontrols-example-gallery-android.png diff --git a/src/controls/doc/images/qtquickcontrols-example-gallery-osx.png b/src/controls/doc/images/qtquickcontrols-example-gallery-osx.png Binary files differnew file mode 100644 index 000000000..492dc36e5 --- /dev/null +++ b/src/controls/doc/images/qtquickcontrols-example-gallery-osx.png diff --git a/src/controls/doc/images/qtquickcontrols-example-gallery.png b/src/controls/doc/images/qtquickcontrols-example-gallery.png Binary files differdeleted file mode 100644 index a88eab793..000000000 --- a/src/controls/doc/images/qtquickcontrols-example-gallery.png +++ /dev/null diff --git a/src/controls/doc/images/qtquickcontrols-example-splitview.png b/src/controls/doc/images/qtquickcontrols-example-splitview.png Binary files differdeleted file mode 100644 index a82017b49..000000000 --- a/src/controls/doc/images/qtquickcontrols-example-splitview.png +++ /dev/null diff --git a/src/controls/doc/images/qtquickcontrols-example-tableview.png b/src/controls/doc/images/qtquickcontrols-example-tableview.png Binary files differindex b9dc67c31..c4ab8d997 100644 --- a/src/controls/doc/images/qtquickcontrols-example-tableview.png +++ b/src/controls/doc/images/qtquickcontrols-example-tableview.png diff --git a/src/controls/doc/src/applicationwindow.qdoc b/src/controls/doc/src/applicationwindow.qdoc index f9e2d97fe..45b66e30b 100644 --- a/src/controls/doc/src/applicationwindow.qdoc +++ b/src/controls/doc/src/applicationwindow.qdoc @@ -27,5 +27,6 @@ /*! \group applicationwindow + \brief A window adding convenience for positioning items. \title Application Window */ diff --git a/src/controls/doc/src/controls.qdoc b/src/controls/doc/src/controls.qdoc index d1e4d0524..fa2a800ca 100644 --- a/src/controls/doc/src/controls.qdoc +++ b/src/controls/doc/src/controls.qdoc @@ -27,5 +27,6 @@ /*! \group controls + \brief Buttons and UI Controls. \title Buttons and Controls */ diff --git a/src/controls/doc/src/menus.qdoc b/src/controls/doc/src/menus.qdoc index 75f5ba2c6..8a6a8032c 100644 --- a/src/controls/doc/src/menus.qdoc +++ b/src/controls/doc/src/menus.qdoc @@ -27,5 +27,6 @@ /*! \group menus + \brief How to create a menu bar. \title Menus */ diff --git a/src/controls/doc/src/qtquickcontrols-examples.qdoc b/src/controls/doc/src/qtquickcontrols-examples.qdoc index 8b8c14699..29c8d2b55 100644 --- a/src/controls/doc/src/qtquickcontrols-examples.qdoc +++ b/src/controls/doc/src/qtquickcontrols-examples.qdoc @@ -40,7 +40,22 @@ \title Qt Quick Controls - Gallery \ingroup qtquickcontrols_examples \brief A collection of components for a classic desktop-style UI. - \image qtquickcontrols-example-gallery.png + + \raw HTML + <div class="table"><table style="background:transparent; border:0px"> + <tr><td style="border:0px"> + \endraw + \image qtquickcontrols-example-gallery-osx.png + \caption OS X + \raw HTML + </td><td style="border:0px"> + \endraw + \image qtquickcontrols-example-gallery-android.png + \caption Android - Nexus 5 + \raw HTML + </td></tr> + </table></div> + \endraw This example project demonstrates the various UI components provided by \l{Qt Quick Controls}. @@ -63,30 +78,40 @@ */ /*! - \example splitview - \title Qt Quick Controls - Split View Example - \ingroup qtquickcontrols_examples - \brief An example for the SplitView UI control. - \image qtquickcontrols-example-splitview.png - - This example project demonstrates the usage of \l {SplitView} from - \l{Qt Quick Controls} - a control that lays out items horizontally or - vertically with a draggable splitter between each item. - - \include examples-run.qdocinc -*/ - -/*! \example tableview \title Qt Quick Controls - Table View Example \ingroup qtquickcontrols_examples \brief An example for the TableView control. \image qtquickcontrols-example-tableview.png - This example shows how a \l{TableView} from \l{Qt Quick Controls} - can be used together with different types of data models to display - lists of information with support for scroll bars, selections and - resizable header sections. + This example project demonstrates the usage of \l {TableView} from + \l{Qt Quick Controls} - 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. + + The C++ class, SortFilterProxyModel, is registered as a QML type + under the namespace, "\c{org.qtproject.example 1.0}". + + The following snippets show how the type is registered under + a namespace and later imported by \e main.qml. + + QML type registration: + + \code + #include <QtQml/qqml.h> + ... + qmlRegisterType<SortFilterProxyModel>("org.qtproject.example", 1, 0, "SortFilterProxyModel"); + ... + \endcode + + QML namespace import: + + \qml + import org.qtproject.example 1.0 + \endqml + + For more information about registering C++ classses as QML types, see + \l {Defining QML Types from C++}. \include examples-run.qdocinc */ diff --git a/src/controls/doc/src/qtquickcontrols-overview.qdoc b/src/controls/doc/src/qtquickcontrols-overview.qdoc index 09f5318d0..651edc66d 100644 --- a/src/controls/doc/src/qtquickcontrols-overview.qdoc +++ b/src/controls/doc/src/qtquickcontrols-overview.qdoc @@ -61,7 +61,7 @@ For an overview of the controls provided by \l{Qt Quick Controls}, you can look at the \l{Qt Quick Controls - Gallery}{Gallery} example. - \image qtquickcontrols-example-gallery.png + \image qtquickcontrols-example-gallery-osx.png \section1 Setting Up Controls from C++ diff --git a/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc b/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc index 70f1a1bb5..8c6c5c198 100644 --- a/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc +++ b/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc @@ -33,19 +33,37 @@ This page contains platform specific notes for creating applications that use \l{Qt Quick Controls}. - \section1 Android + \section1 Android Style Qt 5.4 introduced a native Android style for Qt Quick Controls. - \image qtquickcontrols-android.png + \image qtquickcontrols-example-gallery-android.png \note The Android style requires Android 3.0 (API level 11) or later. - No special actions are required to use the Android style. It is - automatically selected and deployed on Android. See \l{Getting Started + The style is automatically selected and deployed on Android. See \l{Getting Started with Qt for Android} and \l{Deploying an Application on Android} for more details on the Android essentials. + \section2 Android Themes + + Applications may choose a specific \l{http://developer.android.com/design/style/themes.html} + {Android theme} by specifying it in \l{AndroidManifest.xml}. + + \image qtquickcontrols-example-gallery-android-dark.png + + The following example sets a dark Holo theme, and the result can be + seen in the screenshot above. + + \code + <manifest ...> + <application ... android:theme="@android:style/Theme.Holo"> + ... + </application> + ... + </manifest> + \endcode + \section2 Action Bar The \l{http://developer.android.com/guide/topics/ui/actionbar.html} @@ -62,8 +80,8 @@ items declared in QML. Just to name a few possibilities: \list \li ToolButton actions, - \li A TextField as a search field, - \li A ComboBox for navigation, and - \li A ProgressBar for displaying progress. + \li a TextField as a search field, + \li a ComboBox for navigation, and + \li a ProgressBar for displaying progress. \endlist */ diff --git a/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc b/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc index 74c750a5a..7548d7429 100644 --- a/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc +++ b/src/controls/doc/src/qtquickcontrolsstyles-index.qdoc @@ -40,6 +40,7 @@ /*! \group controlsstyling + \brief Provides custom styling for Buttons and UI Controls. \title Styling Controls */ diff --git a/src/controls/qquickmenu.cpp b/src/controls/qquickmenu.cpp index faa9b1d1d..1a125135c 100644 --- a/src/controls/qquickmenu.cpp +++ b/src/controls/qquickmenu.cpp @@ -43,7 +43,7 @@ #include <QtGui/qpa/qplatformtheme.h> #include <QtGui/qpa/qplatformmenu.h> #include <qquickitem.h> -#include <QtQuick/private/qquickrendercontrol_p.h> +#include <QtQuick/QQuickRenderControl> QT_BEGIN_NAMESPACE @@ -367,7 +367,10 @@ QQuickWindow *QQuickMenu::findParentWindow() void QQuickMenu::popup() { - QQuickWindow *parentWindow = findParentWindow(); + QQuickWindow *quickWindow = findParentWindow(); + QPoint renderOffset; + QWindow *renderWindow = QQuickRenderControl::renderWindowFor(quickWindow, &renderOffset); + QWindow *parentWindow = renderWindow ? renderWindow : quickWindow; QScreen *screen = parentWindow ? parentWindow->screen() : qGuiApp->primaryScreen(); QPoint mousePos = QCursor::pos(screen); @@ -379,7 +382,7 @@ void QQuickMenu::popup() if (parentWindow) mousePos = parentWindow->mapFromGlobal(mousePos); - __popup(QRectF(mousePos.x(), mousePos.y(), 0, 0)); + __popup(QRectF(mousePos.x() - renderOffset.x(), mousePos.y() - renderOffset.y(), 0, 0)); } void QQuickMenu::__popup(const QRectF &targetRect, int atItemIndex, MenuType menuType) @@ -397,10 +400,10 @@ void QQuickMenu::__popup(const QRectF &targetRect, int atItemIndex, MenuType men QQuickMenuBase *atItem = menuItemAtIndex(atItemIndex); QQuickWindow *quickWindow = findParentWindow(); - QWindow *parentWindow = quickWindow; - QWindow *renderWindow = QQuickRenderControl::renderWindowFor(static_cast<QQuickWindow *>(parentWindow)); - if (renderWindow) - parentWindow = renderWindow; // may not be a QQuickWindow anymore (happens when using QQuickWidget) + QPoint renderOffset; + QWindow *renderWindow = QQuickRenderControl::renderWindowFor(quickWindow, &renderOffset); + QWindow *parentWindow = renderWindow ? renderWindow : quickWindow; + // parentWindow may not be a QQuickWindow (happens when using QQuickWidget) if (m_platformMenu) { QRectF globalTargetRect = targetRect.translated(m_xOffset, m_yOffset); @@ -411,6 +414,7 @@ void QQuickMenu::__popup(const QRectF &targetRect, int atItemIndex, MenuType men } globalTargetRect = visualItem()->mapRectToScene(globalTargetRect); } + globalTargetRect.translate(renderOffset); m_platformMenu->setMenuType(QPlatformMenu::MenuType(menuType)); m_platformMenu->showPopup(parentWindow, globalTargetRect.toRect(), atItem ? atItem->platformItem() : 0); } else { @@ -425,7 +429,8 @@ void QQuickMenu::__popup(const QRectF &targetRect, int atItemIndex, MenuType men connect(m_popupWindow, SIGNAL(visibleChanged(bool)), this, SLOT(windowVisibleChanged(bool))); connect(m_popupWindow, SIGNAL(geometryChanged()), this, SIGNAL(__popupGeometryChanged())); - m_popupWindow->setPosition(targetRect.x() + m_xOffset, targetRect.y() + targetRect.height() + m_yOffset); + m_popupWindow->setPosition(targetRect.x() + m_xOffset + renderOffset.x(), + targetRect.y() + targetRect.height() + m_yOffset + renderOffset.y()); m_popupWindow->show(); } } diff --git a/src/controls/qquickmenupopupwindow.cpp b/src/controls/qquickmenupopupwindow.cpp index 52ce72195..787896d8d 100644 --- a/src/controls/qquickmenupopupwindow.cpp +++ b/src/controls/qquickmenupopupwindow.cpp @@ -37,7 +37,7 @@ #include <qpa/qwindowsysteminterface.h> #include <qquickitem.h> #include <QtGui/QScreen> -#include <QtQuick/private/qquickrendercontrol_p.h> +#include <QtQuick/QQuickRenderControl> QT_BEGIN_NAMESPACE diff --git a/src/controls/qquickpopupwindow.cpp b/src/controls/qquickpopupwindow.cpp index e10e6ae04..fa7ebee1e 100644 --- a/src/controls/qquickpopupwindow.cpp +++ b/src/controls/qquickpopupwindow.cpp @@ -36,7 +36,7 @@ #include <qguiapplication.h> #include <qpa/qwindowsysteminterface.h> #include <QtQuick/qquickitem.h> -#include <QtQuick/private/qquickrendercontrol_p.h> +#include <QtQuick/QQuickRenderControl> QT_BEGIN_NAMESPACE @@ -180,7 +180,8 @@ void QQuickPopupWindow::forwardEventToTransientParent(QMouseEvent *e) || e->type() == QEvent::MouseButtonPress)) { // Clicked outside any popup dismissPopup(); - } else if (transientParent()) { + } + if (transientParent()) { QPoint parentPos = transientParent()->mapFromGlobal(mapToGlobal(e->pos())); QMouseEvent pe = QMouseEvent(e->type(), parentPos, e->button(), e->buttons(), e->modifiers()); QGuiApplication::sendEvent(transientParent(), &pe); @@ -191,11 +192,11 @@ void QQuickPopupWindow::exposeEvent(QExposeEvent *e) { if (isExposed() && m_needsActivatedEvent) { m_needsActivatedEvent = false; - QWindowSystemInterface::handleWindowActivated(this, Qt::PopupFocusReason); + QWindowSystemInterface::handleWindowActivated(this); } else if (!isExposed() && !m_needsActivatedEvent) { m_needsActivatedEvent = true; if (QWindow *tp = transientParent()) - QWindowSystemInterface::handleWindowActivated(tp, Qt::PopupFocusReason); + QWindowSystemInterface::handleWindowActivated(tp); } QQuickWindow::exposeEvent(e); } @@ -204,7 +205,7 @@ void QQuickPopupWindow::hideEvent(QHideEvent *e) { if (QWindow *tp = !m_needsActivatedEvent ? transientParent() : 0) { m_needsActivatedEvent = true; - QWindowSystemInterface::handleWindowActivated(tp, Qt::PopupFocusReason); + QWindowSystemInterface::handleWindowActivated(tp); } QQuickWindow::hideEvent(e); diff --git a/src/dialogs/DefaultColorDialog.qml b/src/dialogs/DefaultColorDialog.qml index 6cd1eda9f..7188010ea 100644 --- a/src/dialogs/DefaultColorDialog.qml +++ b/src/dialogs/DefaultColorDialog.qml @@ -40,6 +40,7 @@ import QtQuick 2.4 import QtQuick.Controls 1.2 +import QtQuick.Controls.Private 1.0 import QtQuick.Dialogs 1.0 import QtQuick.Window 2.1 import "qml" @@ -61,9 +62,8 @@ AbstractColorDialog { Rectangle { id: content - property int maxSize: 0.9 * Math.min(Screen.desktopAvailableWidth, Screen.desktopAvailableHeight) - implicitHeight: Math.min(maxSize, Screen.pixelDensity * (usePaletteMap ? 100 : 50)) - implicitWidth: usePaletteMap ? implicitHeight - bottomMinHeight : implicitHeight * 1.5 + implicitHeight: Math.min(root.__maximumDimension, Screen.pixelDensity * (usePaletteMap ? 120 : 50)) + implicitWidth: Math.min(root.__maximumDimension, usePaletteMap ? Screen.pixelDensity * (usePaletteMap ? 100 : 50) : implicitHeight * 1.5) color: palette.window focus: root.visible property real bottomMinHeight: sliders.height + buttonRow.height + outerSpacing * 3 @@ -99,9 +99,6 @@ AbstractColorDialog { } } - // set the preferred width based on height, to avoid "letterboxing" the paletteMap - onHeightChanged: implicitHeight = Math.max((usePaletteMap ? 480 : bottomMinHeight), height) - SystemPalette { id: palette } Item { @@ -276,7 +273,6 @@ AbstractColorDialog { right: parent.right margins: content.outerSpacing } - spacing: content.spacing ColorSlider { id: hueSlider @@ -371,7 +367,8 @@ AbstractColorDialog { } Row { spacing: content.spacing - height: parent.height + height: visible ? parent.height : 0 + visible: !Settings.isMobile TextField { id: colorField text: root.currentColor.toString() diff --git a/src/dialogs/DefaultDialogWrapper.qml b/src/dialogs/DefaultDialogWrapper.qml index a10249001..014c38a7b 100644 --- a/src/dialogs/DefaultDialogWrapper.qml +++ b/src/dialogs/DefaultDialogWrapper.qml @@ -48,6 +48,7 @@ import "qml" AbstractDialog { id: root default property alias data: defaultContentItem.data + onVisibilityChanged: if (visible && contentItem) contentItem.forceActiveFocus() Rectangle { id: content @@ -58,10 +59,9 @@ AbstractDialog { property real minimumHeight: implicitHeight property real minimumWidth: Screen.pixelDensity * 50 implicitHeight: defaultContentItem.implicitHeight + spacing + outerSpacing * 2 + buttonsRight.implicitHeight - implicitWidth: Math.min(Screen.desktopAvailableWidth * 0.9, Math.max( + implicitWidth: Math.min(root.__maximumDimension, Math.max( defaultContentItem.implicitWidth, buttonsRowImplicitWidth, Screen.pixelDensity * 50) + outerSpacing * 2); color: palette.window - focus: root.visible Keys.onPressed: { event.accepted = true switch (event.key) { diff --git a/src/dialogs/DefaultFileDialog.qml b/src/dialogs/DefaultFileDialog.qml index feb31c4df..7cd87bc99 100644 --- a/src/dialogs/DefaultFileDialog.qml +++ b/src/dialogs/DefaultFileDialog.qml @@ -120,10 +120,9 @@ AbstractFileDialog { } Rectangle { - property int maxSize: Math.min(Screen.desktopAvailableWidth, Screen.desktopAvailableHeight) - implicitWidth: Math.min(maxSize, Math.max(Screen.pixelDensity * 100, splitter.implicitWidth)) - implicitHeight: Math.min(maxSize, Screen.pixelDensity * 80) id: window + implicitWidth: Math.min(root.__maximumDimension, Math.max(Screen.pixelDensity * 100, splitter.implicitWidth)) + implicitHeight: Math.min(root.__maximumDimension, Screen.pixelDensity * 80) color: root.palette.window Binding { @@ -317,13 +316,14 @@ AbstractFileDialog { sortReversed: view.sortIndicatorOrder === Qt.DescendingOrder } - onActivated: { - if (view.model.isFolder(row)) { + onActivated: if (view.focus) { + if (view.selection.count > 0 && view.model.isFolder(row)) { dirDown(view.model.get(row, "filePath")) } else { root.acceptSelection() } } + onClicked: currentPathField.text = view.model.get(row, "filePath") TableViewColumn { @@ -399,13 +399,14 @@ AbstractFileDialog { TextField { id: currentPathField Layout.fillWidth: true - onAccepted: { + function doAccept() { root.clearSelection() if (root.addSelection(root.pathToUrl(text))) root.accept() else root.folder = root.pathFolder(text) } + onAccepted: doAccept() } } } @@ -455,6 +456,8 @@ AbstractFileDialog { onClicked: { if (view.model.isFolder(view.currentIndex) && !selectFolder) dirDown(view.model.get(view.currentIndex, "filePath")) + else if (!(root.selectExisting)) + currentPathField.doAccept() else root.acceptSelection() } diff --git a/src/dialogs/DefaultFontDialog.qml b/src/dialogs/DefaultFontDialog.qml index 4bd4a1bef..d5c4570ac 100644 --- a/src/dialogs/DefaultFontDialog.qml +++ b/src/dialogs/DefaultFontDialog.qml @@ -58,9 +58,8 @@ AbstractFontDialog { id: content SystemPalette { id: palette } - property int maxSize: Math.min(Screen.desktopAvailableWidth, Screen.desktopAvailableHeight) - implicitWidth: Math.min(maxSize, Math.max(Screen.pixelDensity * 60, mainLayout.implicitWidth + outerSpacing * 2)) - implicitHeight: Math.min(maxSize, Math.max(Screen.pixelDensity * 40, mainLayout.implicitHeight + outerSpacing * 2)) + implicitWidth: Math.min(root.__maximumDimension, Math.max(Screen.pixelDensity * 100, mainLayout.implicitWidth + outerSpacing * 2)) + implicitHeight: Math.min(root.__maximumDimension, Math.max(Screen.pixelDensity * 60, mainLayout.implicitHeight + outerSpacing * 2)) property real spacing: 6 property real outerSpacing: 12 color: palette.window @@ -127,7 +126,7 @@ AbstractFontDialog { focus: true Layout.fillWidth: true Layout.fillHeight: true - Layout.minimumWidth: fontColumn.width + Layout.preferredWidth: fontColumn.width headerVisible: false function reset() { fontModel.findIndex() @@ -201,7 +200,7 @@ AbstractFontDialog { function reset() { weightModel.findIndex() } - TableViewColumn{ id: weightColumn; role: "name"; title: qsTr("Weight") } + TableViewColumn { id: weightColumn; role: "name"; title: qsTr("Weight") } model: ListModel { id: weightModel ListElement { @@ -340,28 +339,6 @@ AbstractFontDialog { } Item { Layout.fillHeight: true; } //spacer Label { id: writingSystemLabel; text: qsTr("Writing System"); font.bold: true } - ComboBox { - id: wsComboBox - function reset() { - if (wsModel.count > 0) { - currentIndex = 0 - } - } - textRole: "name" - model: WritingSystemListModel { - id: wsModel - Component.onCompleted: wsComboBox.reset() - } - onCurrentIndexChanged: { - if (currentIndex == -1) - return - - content.writingSystem = wsModel.get(currentIndex).name - fontModel.writingSystem = content.writingSystem - content.writingSystemSample = wsModel.get(currentIndex).sample - fontListView.reset() - } - } } ColumnLayout { @@ -398,6 +375,28 @@ AbstractFontDialog { id: buttonRow Layout.columnSpan: 3 spacing: content.spacing + ComboBox { + id: wsComboBox + function reset() { + if (wsModel.count > 0) { + currentIndex = 0 + } + } + textRole: "name" + model: WritingSystemListModel { + id: wsModel + Component.onCompleted: wsComboBox.reset() + } + onCurrentIndexChanged: { + if (currentIndex == -1) + return + + content.writingSystem = wsModel.get(currentIndex).name + fontModel.writingSystem = content.writingSystem + content.writingSystemSample = wsModel.get(currentIndex).sample + fontListView.reset() + } + } Item { Layout.fillWidth: true; } //spacer Button { text: qsTr("Cancel") diff --git a/src/dialogs/DefaultMessageDialog.qml b/src/dialogs/DefaultMessageDialog.qml index 609d060c5..0e6e3a6af 100644 --- a/src/dialogs/DefaultMessageDialog.qml +++ b/src/dialogs/DefaultMessageDialog.qml @@ -55,7 +55,7 @@ AbstractMessageDialog { property real buttonsRowImplicitWidth: Screen.pixelDensity * 50 implicitHeight: contentColumn.implicitHeight + outerSpacing * 2 onImplicitHeightChanged: root.height = implicitHeight - implicitWidth: Math.min(Screen.desktopAvailableWidth * 0.9, Math.max( + implicitWidth: Math.min(root.__maximumDimension, Math.max( mainText.implicitWidth, buttonsRowImplicitWidth) + outerSpacing * 2); onImplicitWidthChanged: root.width = implicitWidth color: palette.window @@ -89,12 +89,9 @@ AbstractMessageDialog { Column { id: contentColumn spacing: content.spacing - anchors { - top: parent.top - left: parent.left - right: parent.right - margins: content.outerSpacing - } + x: content.outerSpacing + y: content.outerSpacing + width: content.width - content.outerSpacing * 2 SystemPalette { id: palette } diff --git a/src/dialogs/dialogs.pro b/src/dialogs/dialogs.pro index fd85dcba9..93db78f40 100644 --- a/src/dialogs/dialogs.pro +++ b/src/dialogs/dialogs.pro @@ -39,15 +39,17 @@ HEADERS += \ qquickabstractdialog_p.h \ qquickdialog_p.h +WIDGET_DIALOGS_QML_FILES = \ + WidgetMessageDialog.qml \ + WidgetFileDialog.qml \ + WidgetColorDialog.qml \ + WidgetFontDialog.qml + DIALOGS_QML_FILES += \ DefaultMessageDialog.qml \ - WidgetMessageDialog.qml \ DefaultFileDialog.qml \ - WidgetFileDialog.qml \ DefaultColorDialog.qml \ - WidgetColorDialog.qml \ DefaultFontDialog.qml \ - WidgetFontDialog.qml \ DefaultDialogWrapper.qml \ qml/ColorSlider.qml \ qml/DefaultWindowDecoration.qml \ @@ -65,7 +67,12 @@ DIALOGS_QML_FILES += \ images/crosshairs.png \ images/slider_handle.png \ images/sunken_frame.png \ - images/window_border.png + images/window_border.png \ + $$WIDGET_DIALOGS_QML_FILES + +ios|android|blackberry|winrt { + DIALOGS_QML_FILES -= $$WIDGET_DIALOGS_QML_FILES +} QT += quick-private gui gui-private core core-private qml qml-private diff --git a/src/dialogs/doc/src/qtquickdialogs-index.qdoc b/src/dialogs/doc/src/qtquickdialogs-index.qdoc index 5a1223b04..ab0bc31a1 100644 --- a/src/dialogs/doc/src/qtquickdialogs-index.qdoc +++ b/src/dialogs/doc/src/qtquickdialogs-index.qdoc @@ -27,6 +27,7 @@ /*! \group dialogs + \brief Dialog components \title Dialogs */ diff --git a/src/dialogs/plugin.cpp b/src/dialogs/plugin.cpp index b8ddf35b9..be71ffe89 100644 --- a/src/dialogs/plugin.cpp +++ b/src/dialogs/plugin.cpp @@ -50,9 +50,11 @@ #include "qquickdialog_p.h" #include <private/qguiapplication_p.h> #include <qpa/qplatformintegration.h> +#include <QTouchDevice> //#define PURE_QML_ONLY -//#define DEBUG_REGISTRATION + +Q_LOGGING_CATEGORY(lcRegistration, "qt.quick.dialogs.registration") static void initResources() { @@ -85,11 +87,7 @@ public: QtQuick2DialogsPlugin() : QQmlExtensionPlugin(), m_useResources(true) { } virtual void initializeEngine(QQmlEngine *engine, const char * uri) { -#ifdef DEBUG_REGISTRATION - qDebug() << Q_FUNC_INFO << uri << m_decorationComponentUrl; -#else - Q_UNUSED(uri) -#endif + qCDebug(lcRegistration) << uri << m_decorationComponentUrl; QQuickAbstractDialog::m_decorationComponent = new QQmlComponent(engine, m_decorationComponentUrl, QQmlComponent::Asynchronous); } @@ -97,12 +95,10 @@ public: virtual void registerTypes(const char *uri) { initResources(); -#ifdef DEBUG_REGISTRATION - qDebug() << Q_FUNC_INFO << uri; -#endif Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Dialogs")); bool hasTopLevelWindows = QGuiApplicationPrivate::platformIntegration()-> hasCapability(QPlatformIntegration::MultipleWindows); + qCDebug(lcRegistration) << uri << "can use top-level windows?" << hasTopLevelWindows; QDir qmlDir(baseUrl().toLocalFile()); QDir widgetsDir(baseUrl().toLocalFile()); widgetsDir.cd("../PrivateWidgets"); @@ -164,9 +160,7 @@ public: QUrl dialogQmlPath = m_useResources ? QUrl("qrc:/QtQuick/Dialogs/DefaultDialogWrapper.qml") : QUrl::fromLocalFile(qmlDir.filePath("DefaultDialogWrapper.qml")); -#ifdef DEBUG_REGISTRATION - qDebug() << " registering DefaultDialogWrapper.qml as Dialog; success?" << -#endif + qCDebug(lcRegistration) << " registering" << dialogQmlPath << "as Dialog"; qmlRegisterType(dialogQmlPath, uri, 1, 2, "Dialog"); } } @@ -175,29 +169,35 @@ protected: template <class WrapperType> void registerWidgetOrQmlImplementation(QDir widgetsDir, QDir qmlDir, const char *qmlName, const char *uri, bool hasTopLevelWindows, int versionMajor, int versionMinor) { - // qDebug() << "QtQuick2DialogsPlugin::registerWidgetOrQmlImplementation" << uri << qmlName << ": QML in" << qmlDir.absolutePath() - // << "using resources?" << m_useResources << "; widgets in" << widgetsDir.absolutePath(); -#ifdef DEBUG_REGISTRATION - qDebug() << Q_FUNC_INFO << qmlDir << qmlName << uri; -#endif + qCDebug(lcRegistration) << qmlName << uri << ": QML in" << qmlDir.absolutePath() + << "using resources?" << m_useResources << "; widgets in" << widgetsDir.absolutePath(); bool needQmlImplementation = true; #ifdef PURE_QML_ONLY Q_UNUSED(widgetsDir) Q_UNUSED(hasTopLevelWindows) #else + bool mobileTouchPlatform = false; +#if defined(Q_OS_IOS) + mobileTouchPlatform = true; +#elif defined(Q_OS_ANDROID) || defined(Q_OS_BLACKBERRY) || defined(Q_OS_QNX) || defined(Q_OS_WINRT) + foreach (const QTouchDevice *dev, QTouchDevice::devices()) + if (dev->type() == QTouchDevice::TouchScreen) + mobileTouchPlatform = true; +#endif // If there is a qmldir and we have a QApplication instance (as opposed to a - // widget-free QGuiApplication), assume that the widget-based dialog will work. - if (hasTopLevelWindows && widgetsDir.exists("qmldir") && + // widget-free QGuiApplication), and this isn't a mobile touch-based platform, + // assume that the widget-based dialog will work. Otherwise an application developer + // can ensure that widgets are omitted from the deployment to ensure that the widget + // dialogs won't be used. + if (!mobileTouchPlatform && hasTopLevelWindows && widgetsDir.exists("qmldir") && QCoreApplication::instance()->inherits("QApplication")) { QUrl dialogQmlPath = m_useResources ? QUrl(QString("qrc:/QtQuick/Dialogs/Widget%1.qml").arg(qmlName)) : QUrl::fromLocalFile(qmlDir.filePath(QString("Widget%1.qml").arg(qmlName))); if (qmlRegisterType(dialogQmlPath, uri, versionMajor, versionMinor, qmlName) >= 0) { needQmlImplementation = false; -#ifdef DEBUG_REGISTRATION - qDebug() << " registering" << qmlName << " as " << dialogQmlPath << "success?" << !needQmlImplementation; -#endif + qCDebug(lcRegistration) << " registering" << qmlName << " as " << dialogQmlPath << "success?" << !needQmlImplementation; } } #endif @@ -207,9 +207,7 @@ protected: QUrl dialogQmlPath = m_useResources ? QUrl(QString("qrc:/QtQuick/Dialogs/Default%1.qml").arg(qmlName)) : QUrl::fromLocalFile(qmlDir.filePath(QString("Default%1.qml").arg(qmlName))); -#ifdef DEBUG_REGISTRATION - qDebug() << " registering" << qmlName << " as " << dialogQmlPath << "success?" << -#endif + qCDebug(lcRegistration) << " registering" << qmlName << " as " << dialogQmlPath; qmlRegisterType(dialogQmlPath, uri, versionMajor, versionMinor, qmlName); } } diff --git a/src/dialogs/qml/DefaultWindowDecoration.qml b/src/dialogs/qml/DefaultWindowDecoration.qml index 9b0066980..15512669d 100644 --- a/src/dialogs/qml/DefaultWindowDecoration.qml +++ b/src/dialogs/qml/DefaultWindowDecoration.qml @@ -58,8 +58,8 @@ Rectangle { width: content ? content.width + 15 : 0 height: content ? content.height + 15 : 0 - onWidthChanged: content.x = 5 - onHeightChanged: content.y = 5 + onWidthChanged: if (content) content.x = 5 + onHeightChanged: if (content) content.y = 5 border { left: 10; top: 10; right: 10; bottom: 10 } clip: true source: "../images/window_border.png" diff --git a/src/dialogs/qmldir b/src/dialogs/qmldir index 37e1efff7..df0d402be 100644 --- a/src/dialogs/qmldir +++ b/src/dialogs/qmldir @@ -4,3 +4,4 @@ classname QtQuick2DialogsPlugin typeinfo plugins.qmltypes depends Qt.labs.folderlistmodel 1.0 depends Qt.labs.settings 1.0 +depends QtQuick.Dialogs.Private 1.0 diff --git a/src/dialogs/qquickabstractdialog.cpp b/src/dialogs/qquickabstractdialog.cpp index 41aa1bdcc..92fd04f4e 100644 --- a/src/dialogs/qquickabstractdialog.cpp +++ b/src/dialogs/qquickabstractdialog.cpp @@ -35,6 +35,8 @@ #include "qquickitem.h" #include <private/qguiapplication_p.h> +#include <private/qqmlglobal_p.h> +#include <QLoggingCategory> #include <QWindow> #include <QQmlComponent> #include <QQuickWindow> @@ -42,6 +44,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcWindow, "qt.quick.dialogs.window") + QQmlComponent *QQuickAbstractDialog::m_decorationComponent(0); QQuickAbstractDialog::QQuickAbstractDialog(QObject *parent) @@ -70,6 +74,7 @@ void QQuickAbstractDialog::setVisible(bool v) if (m_visible == v) return; m_visible = v; if (helper()) { + qCDebug(lcWindow) << "via helper" << helper(); if (v) { Qt::WindowFlags flags = Qt::Dialog; if (!title().isEmpty()) @@ -88,6 +93,7 @@ void QQuickAbstractDialog::setVisible(bool v) if (!m_dialogWindow && m_hasNativeWindows) { QQuickWindow *win = new QQuickWindow; ((QObject *)win)->setParent(this); // memory management only + win->setFlags(Qt::Dialog); m_dialogWindow = win; m_contentItem->setParentItem(win->contentItem()); QSize minSize = QSize(m_contentItem->implicitWidth(), m_contentItem->implicitHeight()); @@ -106,33 +112,43 @@ void QQuickAbstractDialog::setVisible(bool v) m_dialogWindow->setMinimumSize(minSize); connect(win, SIGNAL(widthChanged(int)), this, SLOT(windowGeometryChanged())); connect(win, SIGNAL(heightChanged(int)), this, SLOT(windowGeometryChanged())); + qCDebug(lcWindow) << "created window" << win; } - QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent()); - - // If the platform does not support multiple windows, but the dialog is - // implemented as an Item, then try to decorate it as a fake window and make it visible. - if (parentItem && !m_dialogWindow && !m_windowDecoration) { - if (m_decorationComponent) { - if (m_decorationComponent->isLoading()) - connect(m_decorationComponent, SIGNAL(statusChanged(QQmlComponent::Status)), - this, SLOT(decorationLoaded())); - else - decorationLoaded(); + if (!m_dialogWindow) { + if (Q_UNLIKELY(!parentWindow())) { + qWarning("cannot set dialog visible: no window"); + return; } - // Window decoration wasn't possible, so just reparent it into the scene - else { - m_contentItem->setParentItem(parentItem); - m_contentItem->setZ(10000); + m_dialogWindow = parentWindow(); + + // If the platform does not support multiple windows, but the dialog is + // implemented as an Item, then try to decorate it as a fake window and make it visible. + if (!m_windowDecoration) { + if (m_decorationComponent) { + if (m_decorationComponent->isLoading()) + connect(m_decorationComponent, SIGNAL(statusChanged(QQmlComponent::Status)), + this, SLOT(decorationLoaded())); + else + decorationLoaded(); // do the reparenting of contentItem on top of it + } + // Window decoration wasn't possible, so just reparent it into the scene + else { + qCDebug(lcWindow) << "no window and no decoration"; + m_contentItem->setParentItem(parentWindow()->contentItem()); + m_contentItem->setZ(10000); + } } } } if (m_dialogWindow) { // "grow up" to the size and position expected to achieve if (!m_sizeAspiration.isNull()) { - if (m_hasAspiredPosition) + if (m_hasAspiredPosition) { + qCDebug(lcWindow) << "geometry aspiration" << m_sizeAspiration; m_dialogWindow->setGeometry(m_sizeAspiration); - else { + } else { + qCDebug(lcWindow) << "size aspiration" << m_sizeAspiration.size(); if (m_sizeAspiration.width() > 0) m_dialogWindow->setWidth(m_sizeAspiration.width()); if (m_sizeAspiration.height() > 0) @@ -142,6 +158,7 @@ void QQuickAbstractDialog::setVisible(bool v) connect(m_dialogWindow, SIGNAL(yChanged(int)), this, SLOT(setY(int))); connect(m_dialogWindow, SIGNAL(widthChanged(int)), this, SLOT(setWidth(int))); connect(m_dialogWindow, SIGNAL(heightChanged(int)), this, SLOT(setHeight(int))); + connect(m_contentItem, SIGNAL(implicitHeightChanged()), this, SLOT(implicitHeightChanged())); } if (!m_visibleChangedConnected) { connect(m_dialogWindow, SIGNAL(visibleChanged(bool)), this, SLOT(visibleChanged(bool))); @@ -166,9 +183,9 @@ void QQuickAbstractDialog::setVisible(bool v) void QQuickAbstractDialog::decorationLoaded() { bool ok = false; - QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent()); - while (parentItem->parentItem() && !parentItem->parentItem()->inherits("QQuickRootItem")) - parentItem = parentItem->parentItem(); + Q_ASSERT(parentWindow()); + QQuickItem *parentItem = parentWindow()->contentItem(); + Q_ASSERT(parentItem); if (m_decorationComponent->isError()) { qWarning() << m_decorationComponent->errors(); } else { @@ -182,6 +199,7 @@ void QQuickAbstractDialog::decorationLoaded() m_windowDecoration->setProperty("content", contentVariant); connect(m_windowDecoration, SIGNAL(dismissed()), this, SLOT(reject())); ok = true; + qCDebug(lcWindow) << "using synthetic window decoration" << m_windowDecoration; } else { qWarning() << m_decorationComponent->url() << "cannot be used as a window decoration because it's not an Item"; @@ -194,12 +212,14 @@ void QQuickAbstractDialog::decorationLoaded() if (!ok) { m_contentItem->setParentItem(parentItem); m_contentItem->setZ(10000); + qCDebug(lcWindow) << "no decoration"; } } void QQuickAbstractDialog::setModality(Qt::WindowModality m) { if (m_modality == m) return; + qCDebug(lcWindow) << "modality" << m; m_modality = m; emit modalityChanged(); } @@ -219,12 +239,14 @@ void QQuickAbstractDialog::reject() void QQuickAbstractDialog::visibleChanged(bool v) { m_visible = v; + qCDebug(lcWindow) << "visible" << v; emit visibilityChanged(); } void QQuickAbstractDialog::windowGeometryChanged() { if (m_dialogWindow && m_contentItem) { + qCDebug(lcWindow) << m_dialogWindow->geometry(); m_contentItem->setWidth(m_dialogWindow->width()); m_contentItem->setHeight(m_dialogWindow->height()); } @@ -232,27 +254,42 @@ void QQuickAbstractDialog::windowGeometryChanged() void QQuickAbstractDialog::minimumWidthChanged() { - m_dialogWindow->setMinimumWidth(qMax(m_contentItem->implicitWidth(), - m_contentItem->property("minimumWidth").toReal())); + qreal min = m_contentItem->property("minimumWidth").toReal(); + qCDebug(lcWindow) << "content implicitWidth" << m_contentItem->implicitWidth() << "minimumWidth" << min; + m_dialogWindow->setMinimumWidth(qMax(m_contentItem->implicitWidth(), min)); } void QQuickAbstractDialog::minimumHeightChanged() { + qreal min = m_contentItem->property("minimumHeight").toReal(); + qCDebug(lcWindow) << "content implicitHeight" << m_contentItem->implicitHeight() << "minimumHeight" << min; m_dialogWindow->setMinimumHeight(qMax(m_contentItem->implicitHeight(), m_contentItem->property("minimumHeight").toReal())); } +void QQuickAbstractDialog::implicitHeightChanged() +{ + qCDebug(lcWindow) << "content implicitHeight" << m_contentItem->implicitHeight() + << "window minimumHeight" << m_dialogWindow->minimumHeight(); + if (m_contentItem->implicitHeight() < m_dialogWindow->minimumHeight()) + m_dialogWindow->setMinimumHeight(m_contentItem->implicitHeight()); +} + QQuickWindow *QQuickAbstractDialog::parentWindow() { - QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent()); - if (parentItem) - m_parentWindow = parentItem->window(); + if (!m_parentWindow) { + // Usually a dialog is declared inside an Item; but if its QObject parent + // is a Window, that's the window we are interested in. (QTBUG-38578) + QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent()); + m_parentWindow = (parentItem ? parentItem->window() : qmlobject_cast<QQuickWindow *>(parent())); + } return m_parentWindow; } void QQuickAbstractDialog::setContentItem(QQuickItem *obj) { m_contentItem = obj; + qCDebug(lcWindow) << obj; if (m_dialogWindow) { disconnect(this, SLOT(visibleChanged(bool))); // Can't necessarily delete because m_dialogWindow might have been provided by the QML. @@ -288,6 +325,25 @@ int QQuickAbstractDialog::height() const return m_sizeAspiration.height(); } +/* + A non-fullscreen dialog is not allowed to be too large + to fit on the screen in either orientation (portrait or landscape). + That way on platforms which can do rotation, the dialog does not + change its size when the screen is rotated. So the value returned + here is the maximum for both width and height. We need to know + at init time, not wait until the dialog's content item is shown in + a window so that the desktopAvailableWidth and Height will be valid + in the Screen attached property. And to allow space for window borders, + the max is further reduced by 10%. +*/ +int QQuickAbstractDialog::__maximumDimension() const +{ + QScreen *screen = QGuiApplication::primaryScreen(); + return (screen ? + qMin(screen->availableVirtualGeometry().width(), screen->availableVirtualGeometry().height()) : + 480) * 9 / 10; +} + void QQuickAbstractDialog::setX(int arg) { m_hasAspiredPosition = true; @@ -300,6 +356,7 @@ void QQuickAbstractDialog::setX(int arg) } else if (m_contentItem) { m_contentItem->setX(arg); } + qCDebug(lcWindow) << arg; emit geometryChanged(); } @@ -315,6 +372,7 @@ void QQuickAbstractDialog::setY(int arg) } else if (m_contentItem) { m_contentItem->setY(arg); } + qCDebug(lcWindow) << arg; emit geometryChanged(); } @@ -329,6 +387,7 @@ void QQuickAbstractDialog::setWidth(int arg) } else if (m_contentItem) { m_contentItem->setWidth(arg); } + qCDebug(lcWindow) << arg; emit geometryChanged(); } @@ -343,6 +402,7 @@ void QQuickAbstractDialog::setHeight(int arg) } else if (m_contentItem) { m_contentItem->setHeight(arg); } + qCDebug(lcWindow) << arg; emit geometryChanged(); } diff --git a/src/dialogs/qquickabstractdialog_p.h b/src/dialogs/qquickabstractdialog_p.h index a74c539ba..164168fe0 100644 --- a/src/dialogs/qquickabstractdialog_p.h +++ b/src/dialogs/qquickabstractdialog_p.h @@ -66,6 +66,7 @@ class QQuickAbstractDialog : public QObject Q_PROPERTY(int y READ y WRITE setY NOTIFY geometryChanged) Q_PROPERTY(int width READ width WRITE setWidth NOTIFY geometryChanged) Q_PROPERTY(int height READ height WRITE setHeight NOTIFY geometryChanged) + Q_PROPERTY(int __maximumDimension READ __maximumDimension CONSTANT) public: QQuickAbstractDialog(QObject *parent = 0); @@ -80,6 +81,7 @@ public: int y() const; int width() const; int height() const; + int __maximumDimension() const; virtual void setVisible(bool v); virtual void setModality(Qt::WindowModality m); @@ -135,6 +137,7 @@ protected Q_SLOTS: void windowGeometryChanged(); void minimumWidthChanged(); void minimumHeightChanged(); + void implicitHeightChanged(); protected: virtual QPlatformDialogHelper *helper() = 0; diff --git a/src/dialogs/qquickcolordialog.cpp b/src/dialogs/qquickcolordialog.cpp index 514b275e0..d4f41f2bd 100644 --- a/src/dialogs/qquickcolordialog.cpp +++ b/src/dialogs/qquickcolordialog.cpp @@ -40,7 +40,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype AbstractColorDialog \instantiates QQuickColorDialog - \inqmlmodule QtQuick.Dialogs 1 + \inqmlmodule QtQuick.Dialogs \ingroup qtquick-visual \brief API wrapper for QML file dialog implementations \since 5.1 diff --git a/src/dialogs/qquickfiledialog.cpp b/src/dialogs/qquickfiledialog.cpp index 576778e10..132131bcb 100644 --- a/src/dialogs/qquickfiledialog.cpp +++ b/src/dialogs/qquickfiledialog.cpp @@ -44,7 +44,7 @@ using namespace QV4; /*! \qmltype AbstractFileDialog \instantiates QQuickFileDialog - \inqmlmodule QtQuick.Dialogs 1 + \inqmlmodule QtQuick.Dialogs \ingroup qtquick-visual \brief API wrapper for QML file dialog implementations \since 5.1 @@ -176,14 +176,15 @@ void QQuickFileDialog::clearSelection() bool QQuickFileDialog::addSelection(const QUrl &path) { QFileInfo info(path.toLocalFile()); - if (info.exists() && ((info.isDir() && m_selectFolder) || !info.isDir())) { - if (m_selectFolder) - m_selections.append(pathFolder(path.toLocalFile())); - else - m_selections.append(path); - return true; - } - return false; + if (selectExisting() && !info.exists()) + return false; + if (selectFolder() != info.isDir()) + return false; + if (selectFolder()) + m_selections.append(pathFolder(path.toLocalFile())); + else + m_selections.append(path); + return true; } /*! diff --git a/src/dialogs/qquickfontdialog.cpp b/src/dialogs/qquickfontdialog.cpp index 9e8ee28ec..260ad710f 100644 --- a/src/dialogs/qquickfontdialog.cpp +++ b/src/dialogs/qquickfontdialog.cpp @@ -41,7 +41,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype AbstractFontDialog \instantiates QQuickFontDialog - \inqmlmodule QtQuick.Dialogs 1 + \inqmlmodule QtQuick.Dialogs \ingroup qtquick-visual \brief API wrapper for QML font dialog implementations \since 5.2 diff --git a/src/dialogs/qquickmessagedialog.cpp b/src/dialogs/qquickmessagedialog.cpp index 55caad6aa..1a6ee470a 100644 --- a/src/dialogs/qquickmessagedialog.cpp +++ b/src/dialogs/qquickmessagedialog.cpp @@ -40,7 +40,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype AbstractMessageDialog \instantiates QQuickMessageDialog - \inqmlmodule QtQuick.Dialogs 1 + \inqmlmodule QtQuick.Dialogs \ingroup qtquick-visual \brief API wrapper for QML message dialog implementations \since 5.2 diff --git a/src/dialogs/qquickplatformcolordialog.cpp b/src/dialogs/qquickplatformcolordialog.cpp index f48c4ab75..59ad97057 100644 --- a/src/dialogs/qquickplatformcolordialog.cpp +++ b/src/dialogs/qquickplatformcolordialog.cpp @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype ColorDialog \instantiates QQuickPlatformColorDialog - \inqmlmodule QtQuick.Dialogs 1 + \inqmlmodule QtQuick.Dialogs \ingroup dialogs \brief Dialog component for choosing a color. \since 5.1 diff --git a/src/dialogs/qquickplatformfiledialog.cpp b/src/dialogs/qquickplatformfiledialog.cpp index 7ed4e3fbc..b8f75ddc9 100644 --- a/src/dialogs/qquickplatformfiledialog.cpp +++ b/src/dialogs/qquickplatformfiledialog.cpp @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype FileDialog \instantiates QQuickPlatformFileDialog - \inqmlmodule QtQuick.Dialogs 1 + \inqmlmodule QtQuick.Dialogs \ingroup dialogs \brief Dialog component for choosing files from a local filesystem. \since 5.1 @@ -172,6 +172,21 @@ QQuickPlatformFileDialog::~QQuickPlatformFileDialog() delete m_dlgHelper; } +void QQuickPlatformFileDialog::setModality(Qt::WindowModality m) +{ +#ifdef Q_OS_WIN + // A non-modal native file dialog is not possible on Windows, so + // be stubborn about it. Emit modalityChanged() whether it changed + // or not, to ensure that anything which depends on the property + // will re-read the actual current value. + if (m != Qt::ApplicationModal) + m = Qt::ApplicationModal; + if (m == m_modality) + emit modalityChanged(); +#endif + QQuickAbstractFileDialog::setModality(m); +} + QPlatformFileDialogHelper *QQuickPlatformFileDialog::helper() { QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent()); diff --git a/src/dialogs/qquickplatformfiledialog_p.h b/src/dialogs/qquickplatformfiledialog_p.h index 411a78242..f21d01406 100644 --- a/src/dialogs/qquickplatformfiledialog_p.h +++ b/src/dialogs/qquickplatformfiledialog_p.h @@ -56,6 +56,7 @@ class QQuickPlatformFileDialog : public QQuickAbstractFileDialog public: QQuickPlatformFileDialog(QObject *parent = 0); virtual ~QQuickPlatformFileDialog(); + virtual void setModality(Qt::WindowModality m) Q_DECL_OVERRIDE; protected: QPlatformFileDialogHelper *helper(); diff --git a/src/dialogs/qquickplatformfontdialog.cpp b/src/dialogs/qquickplatformfontdialog.cpp index 1744cb846..37a1dad3f 100644 --- a/src/dialogs/qquickplatformfontdialog.cpp +++ b/src/dialogs/qquickplatformfontdialog.cpp @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype FontDialog \instantiates QQuickPlatformFontDialog - \inqmlmodule QtQuick.Dialogs 1 + \inqmlmodule QtQuick.Dialogs \ingroup qtquick-visual \ingroup dialogs \brief Dialog component for choosing a font. diff --git a/src/dialogs/qquickplatformmessagedialog.cpp b/src/dialogs/qquickplatformmessagedialog.cpp index c7b13c7ce..e27c5eba7 100644 --- a/src/dialogs/qquickplatformmessagedialog.cpp +++ b/src/dialogs/qquickplatformmessagedialog.cpp @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype MessageDialog \instantiates QQuickPlatformMessageDialog - \inqmlmodule QtQuick.Dialogs 1 + \inqmlmodule QtQuick.Dialogs \ingroup dialogs \brief Dialog component for displaying popup messages. \since 5.2 diff --git a/src/layouts/qquicklayoutstyleinfo.cpp b/src/layouts/qquicklayoutstyleinfo.cpp index 1b9f2f577..144b14f00 100644 --- a/src/layouts/qquicklayoutstyleinfo.cpp +++ b/src/layouts/qquicklayoutstyleinfo.cpp @@ -44,11 +44,18 @@ QQuickLayoutStyleInfo::QQuickLayoutStyleInfo() qreal QQuickLayoutStyleInfo::spacing(Qt::Orientation /*orientation*/) const { +#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_BLACKBERRY) || defined(Q_OS_QNX) || defined(Q_OS_WINRT) + // On Android and iOS the default spacing between each UI element is 8dp + qreal spacing = 8.0; +#else qreal spacing = 5.0; -#ifndef Q_OS_MAC - // On mac the DPI is always 72 so we should not scale it +#endif + +#ifndef Q_OS_OSX + // On OS X the DPI is always 72 so we should not scale it spacing = qRound(spacing * (qreal(qt_defaultDpiX()) / 96.0)); #endif + return spacing; } diff --git a/src/widgets/qquickqcolordialog.cpp b/src/widgets/qquickqcolordialog.cpp index 79ae51428..e72975c26 100644 --- a/src/widgets/qquickqcolordialog.cpp +++ b/src/widgets/qquickqcolordialog.cpp @@ -81,7 +81,7 @@ private: /*! \qmltype QtColorDialog \instantiates QQuickQColorDialog - \inqmlmodule QtQuick.PrivateWidgets 1 + \inqmlmodule QtQuick.PrivateWidgets \ingroup qtquick-visual \brief Dialog component for choosing a color. \since 5.1 diff --git a/src/widgets/qquickqfiledialog.cpp b/src/widgets/qquickqfiledialog.cpp index cae23622c..81e8aa531 100644 --- a/src/widgets/qquickqfiledialog.cpp +++ b/src/widgets/qquickqfiledialog.cpp @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype QtFileDialog \instantiates QQuickQFileDialog - \inqmlmodule QtQuick.PrivateWidgets 1 + \inqmlmodule QtQuick.PrivateWidgets \ingroup qtquick-visual \brief Dialog component for choosing files from a local filesystem. \since 5.1 diff --git a/src/widgets/qquickqfontdialog.cpp b/src/widgets/qquickqfontdialog.cpp index 635c80dcb..8fb93b3e3 100644 --- a/src/widgets/qquickqfontdialog.cpp +++ b/src/widgets/qquickqfontdialog.cpp @@ -83,7 +83,7 @@ private: /*! \qmltype QtFontDialog \instantiates QQuickQFontDialog - \inqmlmodule QtQuick.PrivateWidgets 1 + \inqmlmodule QtQuick.PrivateWidgets \ingroup qtquick-visual \brief Dialog component for choosing files from a local filesystem. \since 5.2 diff --git a/src/widgets/qquickqmessagebox.cpp b/src/widgets/qquickqmessagebox.cpp index 0b267158d..261239e94 100644 --- a/src/widgets/qquickqmessagebox.cpp +++ b/src/widgets/qquickqmessagebox.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype QtMessageDialog \instantiates QQuickQMessageBox - \inqmlmodule QtQuick.PrivateWidgets 1 + \inqmlmodule QtQuick.PrivateWidgets \ingroup qtquick-visual \brief Dialog component for choosing a color. \since 5.2 |
