From 04ec29f8b3abea2297a1f5c033bef49ba0405c34 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 27 Oct 2014 17:24:11 +0100 Subject: Correct sizing of combobox items The qstyle can set as preferred size for itemview items a different size than the text height depending from the result of sizeFromContents( CT_ItemViewItem, .. Examples of styles that do this, are Oxygen and Breeze, in order to have a bit more spacing. This makes the combobox render incorrectly. This patch makes use of the size hint of the qstyle instead of the text height. Since the height can be more than the font height, the text (and optional icon) are now drawn vertically centered in the delegate. Change-Id: I898d85c994d5760979750c2f3a5dafd83f1e3cbd Reviewed-by: J-P Nurmi --- src/controls/Private/qquickstyleitem.cpp | 2 ++ src/controls/Styles/Desktop/ComboBoxStyle.qml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/controls/Private/qquickstyleitem.cpp b/src/controls/Private/qquickstyleitem.cpp index edb33212..fb49e6e3 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/Styles/Desktop/ComboBoxStyle.qml b/src/controls/Styles/Desktop/ComboBoxStyle.qml index d897a2a4..758518ed 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 -- cgit v1.2.1 From 9c6a5d4757810f5993316015778fa63c22465287 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 4 Nov 2014 15:24:47 +0100 Subject: Share QtQuickControlsTestApp used by auto tests also for manual tests Change-Id: I5853c6c4c315aebdc378af1f3c0e6d34a2b19115 Reviewed-by: Mitch Curtis Reviewed-by: Caroline Chao --- tests/shared/qt_quick_controls_quicktest.h | 17 ++-------- tests/shared/qt_quick_controls_testapp.h | 53 ++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 tests/shared/qt_quick_controls_testapp.h diff --git a/tests/shared/qt_quick_controls_quicktest.h b/tests/shared/qt_quick_controls_quicktest.h index 67dffa92..cbbd5a25 100644 --- a/tests/shared/qt_quick_controls_quicktest.h +++ b/tests/shared/qt_quick_controls_quicktest.h @@ -34,14 +34,9 @@ #ifndef QT_QUICK_CONTROLS_QUICKTEST_H #define QT_QUICK_CONTROLS_QUICKTEST_H +#include "qt_quick_controls_testapp.h" #include -#ifdef QT_WIDGETS_LIB -#include -#else -#include -#endif - QT_BEGIN_NAMESPACE #ifdef QUICK_TEST_SOURCE_DIR @@ -50,18 +45,12 @@ QT_BEGIN_NAMESPACE #define QT_QUICK_CONTROLS_TEST_MAIN_VAR 0 #endif -#ifdef QT_WIDGETS_LIB -#define Application QApplication -#else -#define Application QGuiApplication -#endif - #define QT_QUICK_CONTROLS_TEST_MAIN(name) \ int main(int argc, char **argv) \ { \ - Application* app = 0; \ + QtQuickControlsTestApp* app = 0; \ if (!QCoreApplication::instance()) \ - app = new Application(argc, argv); \ + app = new QtQuickControlsTestApp(argc, argv); \ int i = quick_test_main(argc, argv, #name, QT_QUICK_CONTROLS_TEST_MAIN_VAR); \ delete app; \ return i; \ diff --git a/tests/shared/qt_quick_controls_testapp.h b/tests/shared/qt_quick_controls_testapp.h new file mode 100644 index 00000000..a57a4c5b --- /dev/null +++ b/tests/shared/qt_quick_controls_testapp.h @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** 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. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT_QUICK_CONTROLS_TESTAPP_H +#define QT_QUICK_CONTROLS_TESTAPP_H + +#ifdef QT_WIDGETS_LIB +#include +#else +#include +#endif + +QT_BEGIN_NAMESPACE + +#ifdef QT_WIDGETS_LIB +#define QtQuickControlsTestApp QApplication +#else +#define QtQuickControlsTestApp QGuiApplication +#endif + +QT_END_NAMESPACE + +#endif // QT_QUICK_CONTROLS_TESTAPP_H -- cgit v1.2.1 From 389d091ea25f123cecc7d63379ce8fb2ce16ebd9 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 4 Nov 2014 15:32:27 +0100 Subject: Workshop manual test (the former Gallery example) Change-Id: Ib62be83b1652777e7603a262a8a89c132d3766e7 Reviewed-by: Mitch Curtis Reviewed-by: Caroline Chao --- tests/manual/workshop/content/AboutDialog.qml | 49 +++ tests/manual/workshop/content/Controls.qml | 280 +++++++++++++++ tests/manual/workshop/content/ImageViewer.qml | 59 ++++ tests/manual/workshop/content/ModelView.qml | 88 +++++ tests/manual/workshop/content/Styles.qml | 382 +++++++++++++++++++++ tests/manual/workshop/images/bubble.png | Bin 0 -> 214 bytes tests/manual/workshop/images/button-pressed.png | Bin 0 -> 3094 bytes tests/manual/workshop/images/button.png | Bin 0 -> 3164 bytes tests/manual/workshop/images/document-open.png | Bin 0 -> 1550 bytes tests/manual/workshop/images/document-open@2x.png | Bin 0 -> 3355 bytes tests/manual/workshop/images/document-save-as.png | Bin 0 -> 1837 bytes .../manual/workshop/images/document-save-as@2x.png | Bin 0 -> 4500 bytes tests/manual/workshop/images/folder_new.png | Bin 0 -> 1199 bytes tests/manual/workshop/images/go-next.png | Bin 0 -> 1219 bytes tests/manual/workshop/images/go-previous.png | Bin 0 -> 1200 bytes .../manual/workshop/images/preferences-system.png | Bin 0 -> 2129 bytes tests/manual/workshop/images/process-stop.png | Bin 0 -> 1927 bytes .../manual/workshop/images/progress-background.png | Bin 0 -> 456 bytes tests/manual/workshop/images/progress-fill.png | Bin 0 -> 507 bytes tests/manual/workshop/images/slider-handle.png | Bin 0 -> 3523 bytes tests/manual/workshop/images/tab.png | Bin 0 -> 9877 bytes tests/manual/workshop/images/tab_selected.png | Bin 0 -> 10184 bytes tests/manual/workshop/images/textfield.png | Bin 0 -> 3023 bytes tests/manual/workshop/images/toplevel_window.png | Bin 0 -> 3690 bytes tests/manual/workshop/images/view-refresh.png | Bin 0 -> 2024 bytes tests/manual/workshop/images/window-new@2x.png | Bin 0 -> 1900 bytes tests/manual/workshop/main.qml | 169 +++++++++ tests/manual/workshop/src/main.cpp | 57 +++ tests/manual/workshop/src/src.pri | 2 + tests/manual/workshop/workshop.pro | 18 + tests/manual/workshop/workshop.qrc | 24 ++ 31 files changed, 1128 insertions(+) create mode 100644 tests/manual/workshop/content/AboutDialog.qml create mode 100644 tests/manual/workshop/content/Controls.qml create mode 100644 tests/manual/workshop/content/ImageViewer.qml create mode 100644 tests/manual/workshop/content/ModelView.qml create mode 100644 tests/manual/workshop/content/Styles.qml create mode 100644 tests/manual/workshop/images/bubble.png create mode 100644 tests/manual/workshop/images/button-pressed.png create mode 100644 tests/manual/workshop/images/button.png create mode 100644 tests/manual/workshop/images/document-open.png create mode 100644 tests/manual/workshop/images/document-open@2x.png create mode 100644 tests/manual/workshop/images/document-save-as.png create mode 100644 tests/manual/workshop/images/document-save-as@2x.png create mode 100644 tests/manual/workshop/images/folder_new.png create mode 100644 tests/manual/workshop/images/go-next.png create mode 100644 tests/manual/workshop/images/go-previous.png create mode 100644 tests/manual/workshop/images/preferences-system.png create mode 100644 tests/manual/workshop/images/process-stop.png create mode 100644 tests/manual/workshop/images/progress-background.png create mode 100644 tests/manual/workshop/images/progress-fill.png create mode 100644 tests/manual/workshop/images/slider-handle.png create mode 100644 tests/manual/workshop/images/tab.png create mode 100644 tests/manual/workshop/images/tab_selected.png create mode 100644 tests/manual/workshop/images/textfield.png create mode 100644 tests/manual/workshop/images/toplevel_window.png create mode 100644 tests/manual/workshop/images/view-refresh.png create mode 100644 tests/manual/workshop/images/window-new@2x.png create mode 100644 tests/manual/workshop/main.qml create mode 100644 tests/manual/workshop/src/main.cpp create mode 100644 tests/manual/workshop/src/src.pri create mode 100644 tests/manual/workshop/workshop.pro create mode 100644 tests/manual/workshop/workshop.qrc diff --git a/tests/manual/workshop/content/AboutDialog.qml b/tests/manual/workshop/content/AboutDialog.qml new file mode 100644 index 00000000..c4d87ee0 --- /dev/null +++ b/tests/manual/workshop/content/AboutDialog.qml @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** 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. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 + +MessageDialog { + icon: StandardIcon.Information + title: "Qt Quick Controls Workshop" + text: "Qt Quick Controls Workshop" + detailedText: "A manual test for most of the available Qt Quick Controls" +} diff --git a/tests/manual/workshop/content/Controls.qml b/tests/manual/workshop/content/Controls.qml new file mode 100644 index 00000000..1abd57e4 --- /dev/null +++ b/tests/manual/workshop/content/Controls.qml @@ -0,0 +1,280 @@ +/**************************************************************************** +** +** 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. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Layouts 1.1 +import QtQuick.Controls.Styles 1.1 + +Item { + id: flickable + anchors.fill: parent + enabled: enabledCheck.checked + + property int tabPosition: tabPositionGroup.current === r2 ? Qt.BottomEdge : Qt.TopEdge + + property string loremIpsum: + "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor "+ + "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor "+ + "incididunt ut labore et dolore magna aliqua.\n Ut enim ad minim veniam, quis nostrud "+ + "exercitation ullamco laboris nisi ut aliquip ex ea commodo cosnsequat. "; + + ListModel { + id: choices + ListElement { text: "Banana" } + ListElement { text: "Orange" } + ListElement { text: "Apple" } + ListElement { text: "Coconut" } + } + + RowLayout { + id: contentRow + anchors.fill:parent + anchors.margins: 8 + spacing: 16 + ColumnLayout { + id: firstColumn + Layout.minimumWidth: implicitWidth + Layout.fillWidth: false + RowLayout { + id: buttonrow + Button { + id: button1 + text: "Button 1" + tooltip:"This is an interesting tool tip" + Layout.fillWidth: true + } + Button { + id:button2 + text:"Button 2" + Layout.fillWidth: true + menu: Menu { + MenuItem { text: "This Button" } + MenuItem { text: "Happens To Have" } + MenuItem { text: "A Menu Assigned" } + } + } + } + ComboBox { + id: combo + model: choices + currentIndex: 2 + Layout.fillWidth: true + } + ComboBox { + model: Qt.fontFamilies() + Layout.fillWidth: true + currentIndex: 47 + } + ComboBox { + id: editableCombo + editable: true + model: choices + Layout.fillWidth: true + currentIndex: 2 + onAccepted: { + if (editableCombo.find(currentText) === -1) { + choices.append({text: editText}) + currentIndex = editableCombo.find(editText) + } + } + } + RowLayout { + SpinBox { + id: t1 + Layout.fillWidth: true + minimumValue: -50 + value: -20 + } + SpinBox { + id: t2 + Layout.fillWidth: true + } + } + TextField { + id: t3 + placeholderText: "This is a placeholder for a TextField" + Layout.fillWidth: true + } + ProgressBar { + // normalize value [0.0 .. 1.0] + value: (slider.value - slider.minimumValue) / (slider.maximumValue - slider.minimumValue) + Layout.fillWidth: true + } + ProgressBar { + indeterminate: true + Layout.fillWidth: true + } + Slider { + id: slider + value: 0.5 + Layout.fillWidth: true + tickmarksEnabled: tickmarkCheck.checked + stepSize: tickmarksEnabled ? 0.1 : 0 + } + MouseArea { + id: busyCheck + Layout.fillWidth: true + Layout.fillHeight: true + hoverEnabled:true + Layout.preferredHeight: busyIndicator.height + BusyIndicator { + id: busyIndicator + running: busyCheck.containsMouse + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + ColumnLayout { + id: rightcol + Layout.fillWidth: true + anchors { + top: parent.top + bottom: parent.bottom + } + + GroupBox { + id: group1 + title: "CheckBox" + Layout.fillWidth: true + RowLayout { + Layout.fillWidth: true + CheckBox { + id: frameCheckbox + text: "Text frame" + checked: true + Layout.minimumWidth: 100 + } + CheckBox { + id: tickmarkCheck + text: "Tickmarks" + checked: false + Layout.minimumWidth: 100 + } + CheckBox { + id: wrapCheck + text: "Word wrap" + checked: true + Layout.minimumWidth: 100 + } + } + } + GroupBox { + id: group2 + title:"Tab Position" + Layout.fillWidth: true + RowLayout { + ExclusiveGroup { id: tabPositionGroup } + RadioButton { + id: r1 + text: "Top" + checked: true + exclusiveGroup: tabPositionGroup + Layout.minimumWidth: 100 + } + RadioButton { + id: r2 + text: "Bottom" + exclusiveGroup: tabPositionGroup + Layout.minimumWidth: 100 + } + } + } + + TextArea { + id: area + frameVisible: frameCheckbox.checked + text: loremIpsum + loremIpsum + textFormat: Qt.RichText + wrapMode: wrapCheck.checked ? TextEdit.WordWrap : TextEdit.NoWrap + Layout.fillWidth: true + Layout.fillHeight: true + menu: editmenu + } + } + } + + ExclusiveGroup { + id: textFormatGroup + + Action { + id: a1 + text: "Align &Left" + checkable: true + Component.onCompleted: checked = true + } + + Action { + id: a2 + text: "&Center" + checkable: true + } + + Action { + id: a3 + text: "Align &Right" + checkable: true + } + } + + Component { + id: editmenu + Menu { + MenuItem { action: cutAction } + MenuItem { action: copyAction } + MenuItem { action: pasteAction } + MenuSeparator {} + Menu { + title: "Text &Format" + MenuItem { action: a1 } + MenuItem { action: a2 } + MenuItem { action: a3 } + MenuSeparator { } + MenuItem { text: "Allow &Hyphenation"; checkable: true } + } + Menu { + title: "Font &Style" + MenuItem { text: "&Bold"; checkable: true } + MenuItem { text: "&Italic"; checkable: true } + MenuItem { text: "&Underline"; checkable: true } + } + } + } +} diff --git a/tests/manual/workshop/content/ImageViewer.qml b/tests/manual/workshop/content/ImageViewer.qml new file mode 100644 index 00000000..26d2da17 --- /dev/null +++ b/tests/manual/workshop/content/ImageViewer.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** 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. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Window 2.1 + +Window { + id: imageViewer + minimumWidth: viewerImage.width + minimumHeight: viewerImage.height + function open(source) { + viewerImage.source = source + width = viewerImage.implicitWidth + 20 + height = viewerImage.implicitHeight + 20 + title = source + visible = true + } + Image { + id: viewerImage + anchors.centerIn: parent + } +} diff --git a/tests/manual/workshop/content/ModelView.qml b/tests/manual/workshop/content/ModelView.qml new file mode 100644 index 00000000..eb9f720d --- /dev/null +++ b/tests/manual/workshop/content/ModelView.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** 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. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 + +Item { + id: root + width: 600 + height: 300 + anchors.fill: parent + anchors.margins: Qt.platform.os === "osx" ? 12 : 6 + + ListModel { + id: dummyModel + Component.onCompleted: { + for (var i = 0 ; i < 100 ; ++i) { + append({"index": i, "title": "A title " + i, "imagesource" :"http://someurl.com", "credit" : "N/A"}) + } + } + } + + TableView{ + model: dummyModel + anchors.fill: parent + + TableViewColumn { + role: "index" + title: "#" + width: 36 + resizable: false + movable: false + } + TableViewColumn { + role: "title" + title: "Title" + width: 120 + } + TableViewColumn { + role: "credit" + title: "Credit" + width: 120 + } + TableViewColumn { + role: "imagesource" + title: "Image source" + width: 200 + visible: true + } + } +} diff --git a/tests/manual/workshop/content/Styles.qml b/tests/manual/workshop/content/Styles.qml new file mode 100644 index 00000000..d490e2b5 --- /dev/null +++ b/tests/manual/workshop/content/Styles.qml @@ -0,0 +1,382 @@ +/**************************************************************************** +** +** 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. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Particles 2.0 +import QtQuick.Layouts 1.0 + +Item { + id: root + width: 300 + height: 200 + + property int columnWidth: 120 + GridLayout { + rowSpacing: 12 + columnSpacing: 30 + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: 30 + + Button { + text: "Push me" + style: ButtonStyle { } + implicitWidth: columnWidth + } + Button { + text: "Push me" + style: ButtonStyle { + background: BorderImage { + source: control.pressed ? "../images/button-pressed.png" : "../images/button.png" + border.left: 4 ; border.right: 4 ; border.top: 4 ; border.bottom: 4 + } + } + implicitWidth: columnWidth + } + Button { + text: "Push me" + style: buttonStyle + implicitWidth: columnWidth + } + + TextField { + Layout.row: 1 + style: TextFieldStyle { } + implicitWidth: columnWidth + } + TextField { + style: TextFieldStyle { + background: BorderImage { + source: "../images/textfield.png" + border.left: 4 ; border.right: 4 ; border.top: 4 ; border.bottom: 4 + } + } + implicitWidth: columnWidth + } + TextField { + style: textfieldStyle + implicitWidth: columnWidth + } + + Slider { + id: slider1 + Layout.row: 2 + value: 0.5 + implicitWidth: columnWidth + style: SliderStyle { } + } + Slider { + id: slider2 + value: 0.5 + implicitWidth: columnWidth + style: SliderStyle { + groove: BorderImage { + height: 6 + border.top: 1 + border.bottom: 1 + source: "../images/progress-background.png" + border.left: 6 + border.right: 6 + BorderImage { + anchors.verticalCenter: parent.verticalCenter + source: "../images/progress-fill.png" + border.left: 5 ; border.top: 1 + border.right: 5 ; border.bottom: 1 + width: styleData.handlePosition + height: parent.height + } + } + handle: Item { + width: 13 + height: 13 + Image { + anchors.centerIn: parent + source: "../images/slider-handle.png" + } + } + } + } + Slider { + id: slider3 + value: 0.5 + implicitWidth: columnWidth + style: sliderStyle + } + + ProgressBar { + Layout.row: 3 + value: slider1.value + implicitWidth: columnWidth + style: ProgressBarStyle{ } + } + ProgressBar { + value: slider2.value + implicitWidth: columnWidth + style: progressBarStyle + } + ProgressBar { + value: slider3.value + implicitWidth: columnWidth + style: progressBarStyle2 + } + + CheckBox { + text: "CheckBox" + style: CheckBoxStyle{} + Layout.row: 4 + implicitWidth: columnWidth + } + RadioButton { + style: RadioButtonStyle{} + text: "RadioButton" + implicitWidth: columnWidth + } + + ComboBox { + model: ["Paris", "Oslo", "New York"] + style: ComboBoxStyle{} + implicitWidth: columnWidth + } + + TabView { + Layout.row: 5 + Layout.columnSpan: 3 + Layout.fillWidth: true + implicitHeight: 30 + Tab { title: "One" ; Item {}} + Tab { title: "Two" ; Item {}} + Tab { title: "Three" ; Item {}} + Tab { title: "Four" ; Item {}} + style: TabViewStyle {} + } + + TabView { + Layout.row: 6 + Layout.columnSpan: 3 + Layout.fillWidth: true + implicitHeight: 30 + Tab { title: "One" ; Item {}} + Tab { title: "Two" ; Item {}} + Tab { title: "Three" ; Item {}} + Tab { title: "Four" ; Item {}} + style: tabViewStyle + } + } + + // Style delegates: + + property Component buttonStyle: ButtonStyle { + background: Rectangle { + implicitHeight: 22 + implicitWidth: columnWidth + color: control.pressed ? "darkGray" : control.activeFocus ? "#cdd" : "#ccc" + antialiasing: true + border.color: "gray" + radius: height/2 + Rectangle { + anchors.fill: parent + anchors.margins: 1 + color: "transparent" + antialiasing: true + visible: !control.pressed + border.color: "#aaffffff" + radius: height/2 + } + } + } + + property Component textfieldStyle: TextFieldStyle { + background: Rectangle { + implicitWidth: columnWidth + implicitHeight: 22 + color: "#f0f0f0" + antialiasing: true + border.color: "gray" + radius: height/2 + Rectangle { + anchors.fill: parent + anchors.margins: 1 + color: "transparent" + antialiasing: true + border.color: "#aaffffff" + radius: height/2 + } + } + } + + property Component sliderStyle: SliderStyle { + handle: Rectangle { + width: 18 + height: 18 + color: control.pressed ? "darkGray" : "lightGray" + border.color: "gray" + antialiasing: true + radius: height/2 + Rectangle { + anchors.fill: parent + anchors.margins: 1 + color: "transparent" + antialiasing: true + border.color: "#eee" + radius: height/2 + } + } + + groove: Rectangle { + height: 8 + implicitWidth: columnWidth + implicitHeight: 22 + + antialiasing: true + color: "#ccc" + border.color: "#777" + radius: height/2 + Rectangle { + anchors.fill: parent + anchors.margins: 1 + color: "transparent" + antialiasing: true + border.color: "#66ffffff" + radius: height/2 + } + } + } + + property Component progressBarStyle: ProgressBarStyle { + background: BorderImage { + source: "../images/progress-background.png" + border.left: 2 ; border.right: 2 ; border.top: 2 ; border.bottom: 2 + } + progress: Item { + clip: true + BorderImage { + anchors.fill: parent + anchors.rightMargin: (control.value < control.maximumValue) ? -4 : 0 + source: "../images/progress-fill.png" + border.left: 10 ; border.right: 10 + Rectangle { + width: 1 + color: "#a70" + opacity: 0.8 + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.bottomMargin: 1 + anchors.right: parent.right + visible: control.value < control.maximumValue + anchors.rightMargin: -parent.anchors.rightMargin + } + } + ParticleSystem{ id: bubbles; running: visible } + ImageParticle{ + id: fireball + system: bubbles + source: "../images/bubble.png" + opacity: 0.7 + } + Emitter{ + system: bubbles + anchors.bottom: parent.bottom + anchors.margins: 4 + anchors.bottomMargin: -4 + anchors.left: parent.left + anchors.right: parent.right + size: 4 + sizeVariation: 4 + acceleration: PointDirection{ y: -6; xVariation: 3 } + emitRate: 6 * control.value + lifeSpan: 3000 + } + } + } + + property Component progressBarStyle2: ProgressBarStyle { + background: Rectangle { + implicitWidth: columnWidth + implicitHeight: 24 + color: "#f0f0f0" + border.color: "gray" + } + progress: Rectangle { + color: "#ccc" + border.color: "gray" + Rectangle { + color: "transparent" + border.color: "#44ffffff" + anchors.fill: parent + anchors.margins: 1 + } + } + } + + property Component tabViewStyle: TabViewStyle { + tabOverlap: 16 + frameOverlap: 4 + tabsMovable: true + + frame: Rectangle { + gradient: Gradient{ + GradientStop { color: "#e5e5e5" ; position: 0 } + GradientStop { color: "#e0e0e0" ; position: 1 } + } + border.color: "#898989" + Rectangle { anchors.fill: parent ; anchors.margins: 1 ; border.color: "white" ; color: "transparent" } + } + tab: Item { + property int totalOverlap: tabOverlap * (control.count - 1) + implicitWidth: Math.min ((styleData.availableWidth + totalOverlap)/control.count - 4, image.sourceSize.width) + implicitHeight: image.sourceSize.height + BorderImage { + id: image + anchors.fill: parent + source: styleData.selected ? "../images/tab_selected.png" : "../images/tab.png" + border.left: 30 + smooth: false + border.right: 30 + } + Text { + text: styleData.title + anchors.centerIn: parent + } + } + leftCorner: Item { implicitWidth: 12 } + } +} diff --git a/tests/manual/workshop/images/bubble.png b/tests/manual/workshop/images/bubble.png new file mode 100644 index 00000000..62aa1efe Binary files /dev/null and b/tests/manual/workshop/images/bubble.png differ diff --git a/tests/manual/workshop/images/button-pressed.png b/tests/manual/workshop/images/button-pressed.png new file mode 100644 index 00000000..d64cdaa7 Binary files /dev/null and b/tests/manual/workshop/images/button-pressed.png differ diff --git a/tests/manual/workshop/images/button.png b/tests/manual/workshop/images/button.png new file mode 100644 index 00000000..8ab41cc8 Binary files /dev/null and b/tests/manual/workshop/images/button.png differ diff --git a/tests/manual/workshop/images/document-open.png b/tests/manual/workshop/images/document-open.png new file mode 100644 index 00000000..f35f2583 Binary files /dev/null and b/tests/manual/workshop/images/document-open.png differ diff --git a/tests/manual/workshop/images/document-open@2x.png b/tests/manual/workshop/images/document-open@2x.png new file mode 100644 index 00000000..9fdbb665 Binary files /dev/null and b/tests/manual/workshop/images/document-open@2x.png differ diff --git a/tests/manual/workshop/images/document-save-as.png b/tests/manual/workshop/images/document-save-as.png new file mode 100644 index 00000000..5c9f6b34 Binary files /dev/null and b/tests/manual/workshop/images/document-save-as.png differ diff --git a/tests/manual/workshop/images/document-save-as@2x.png b/tests/manual/workshop/images/document-save-as@2x.png new file mode 100644 index 00000000..a15e34c9 Binary files /dev/null and b/tests/manual/workshop/images/document-save-as@2x.png differ diff --git a/tests/manual/workshop/images/folder_new.png b/tests/manual/workshop/images/folder_new.png new file mode 100644 index 00000000..8d8bb9bd Binary files /dev/null and b/tests/manual/workshop/images/folder_new.png differ diff --git a/tests/manual/workshop/images/go-next.png b/tests/manual/workshop/images/go-next.png new file mode 100644 index 00000000..a68e2db7 Binary files /dev/null and b/tests/manual/workshop/images/go-next.png differ diff --git a/tests/manual/workshop/images/go-previous.png b/tests/manual/workshop/images/go-previous.png new file mode 100644 index 00000000..c37bc041 Binary files /dev/null and b/tests/manual/workshop/images/go-previous.png differ diff --git a/tests/manual/workshop/images/preferences-system.png b/tests/manual/workshop/images/preferences-system.png new file mode 100644 index 00000000..6e52db7c Binary files /dev/null and b/tests/manual/workshop/images/preferences-system.png differ diff --git a/tests/manual/workshop/images/process-stop.png b/tests/manual/workshop/images/process-stop.png new file mode 100644 index 00000000..e7a8d172 Binary files /dev/null and b/tests/manual/workshop/images/process-stop.png differ diff --git a/tests/manual/workshop/images/progress-background.png b/tests/manual/workshop/images/progress-background.png new file mode 100644 index 00000000..55a069df Binary files /dev/null and b/tests/manual/workshop/images/progress-background.png differ diff --git a/tests/manual/workshop/images/progress-fill.png b/tests/manual/workshop/images/progress-fill.png new file mode 100644 index 00000000..b588c958 Binary files /dev/null and b/tests/manual/workshop/images/progress-fill.png differ diff --git a/tests/manual/workshop/images/slider-handle.png b/tests/manual/workshop/images/slider-handle.png new file mode 100644 index 00000000..ac4d4a0d Binary files /dev/null and b/tests/manual/workshop/images/slider-handle.png differ diff --git a/tests/manual/workshop/images/tab.png b/tests/manual/workshop/images/tab.png new file mode 100644 index 00000000..74fefab7 Binary files /dev/null and b/tests/manual/workshop/images/tab.png differ diff --git a/tests/manual/workshop/images/tab_selected.png b/tests/manual/workshop/images/tab_selected.png new file mode 100644 index 00000000..665400cc Binary files /dev/null and b/tests/manual/workshop/images/tab_selected.png differ diff --git a/tests/manual/workshop/images/textfield.png b/tests/manual/workshop/images/textfield.png new file mode 100644 index 00000000..1d4a38ab Binary files /dev/null and b/tests/manual/workshop/images/textfield.png differ diff --git a/tests/manual/workshop/images/toplevel_window.png b/tests/manual/workshop/images/toplevel_window.png new file mode 100644 index 00000000..4dc6a8ce Binary files /dev/null and b/tests/manual/workshop/images/toplevel_window.png differ diff --git a/tests/manual/workshop/images/view-refresh.png b/tests/manual/workshop/images/view-refresh.png new file mode 100644 index 00000000..606ea9eb Binary files /dev/null and b/tests/manual/workshop/images/view-refresh.png differ diff --git a/tests/manual/workshop/images/window-new@2x.png b/tests/manual/workshop/images/window-new@2x.png new file mode 100644 index 00000000..36503018 Binary files /dev/null and b/tests/manual/workshop/images/window-new@2x.png differ diff --git a/tests/manual/workshop/main.qml b/tests/manual/workshop/main.qml new file mode 100644 index 00000000..723a8886 --- /dev/null +++ b/tests/manual/workshop/main.qml @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** 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. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Layouts 1.0 +import QtQuick.Dialogs 1.0 +import "content" + +ApplicationWindow { + visible: true + title: "Qt Quick Controls Workshop" + + width: 640 + height: 420 + minimumHeight: 400 + minimumWidth: 600 + + ImageViewer { id: imageViewer } + + FileDialog { + id: fileDialog + nameFilters: [ "Image files (*.png *.jpg)" ] + onAccepted: imageViewer.open(fileUrl) + } + + AboutDialog { id: aboutDialog } + + Action { + id: openAction + text: "&Open" + shortcut: StandardKey.Open + iconSource: "images/document-open.png" + onTriggered: fileDialog.open() + tooltip: "Open an image" + } + + Action { + id: copyAction + text: "&Copy" + shortcut: StandardKey.Copy + iconName: "edit-copy" + enabled: (!!activeFocusItem && !!activeFocusItem["copy"]) + onTriggered: activeFocusItem.copy() + } + + Action { + id: cutAction + text: "Cu&t" + shortcut: StandardKey.Cut + iconName: "edit-cut" + enabled: (!!activeFocusItem && !!activeFocusItem["cut"]) + onTriggered: activeFocusItem.cut() + } + + Action { + id: pasteAction + text: "&Paste" + shortcut: StandardKey.Paste + iconName: "edit-paste" + enabled: (!!activeFocusItem && !!activeFocusItem["paste"]) + onTriggered: activeFocusItem.paste() + } + + toolBar: ToolBar { + id: toolbar + RowLayout { + id: toolbarLayout + spacing: 0 + anchors.fill: parent + ToolButton { action: openAction } + ToolButton { + Accessible.name: "Save as" + iconSource: "images/document-save-as.png" + tooltip: "(Pretend to) Save as..." + } + Item { Layout.fillWidth: true } + CheckBox { + id: enabledCheck + text: "Enabled" + checked: true + } + } + } + + menuBar: MenuBar { + Menu { + title: "&File" + MenuItem { action: openAction } + MenuItem { + text: "E&xit" + shortcut: StandardKey.Quit + onTriggered: Qt.quit() + } + } + Menu { + title: "&Edit" + MenuItem { action: cutAction } + MenuItem { action: copyAction } + MenuItem { action: pasteAction } + } + Menu { + title: "&Help" + MenuItem { + text: "About..." + onTriggered: aboutDialog.open() + } + } + } + + TabView { + id:frame + enabled: enabledCheck.checked + tabPosition: controlPage.item ? controlPage.item.tabPosition : Qt.TopEdge + anchors.fill: parent + anchors.margins: Qt.platform.os === "osx" ? 12 : 2 + + Tab { + id: controlPage + title: "Controls" + Controls { } + } + Tab { + title: "Itemviews" + ModelView { } + } + Tab { + title: "Styles" + Styles { anchors.fill: parent } + } + } +} diff --git a/tests/manual/workshop/src/main.cpp b/tests/manual/workshop/src/main.cpp new file mode 100644 index 00000000..d8b3665c --- /dev/null +++ b/tests/manual/workshop/src/main.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** 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. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qt_quick_controls_testapp.h" +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QtQuickControlsTestApp app(argc, argv); + if (QCoreApplication::arguments().contains(QLatin1String("--coreprofile"))) { + QSurfaceFormat fmt; + fmt.setVersion(4, 4); + fmt.setProfile(QSurfaceFormat::CoreProfile); + QSurfaceFormat::setDefaultFormat(fmt); + } + QQmlApplicationEngine engine(QUrl("qrc:/main.qml")); + return app.exec(); +} diff --git a/tests/manual/workshop/src/src.pri b/tests/manual/workshop/src/src.pri new file mode 100644 index 00000000..66d903ea --- /dev/null +++ b/tests/manual/workshop/src/src.pri @@ -0,0 +1,2 @@ +SOURCES += \ + $$PWD/main.cpp diff --git a/tests/manual/workshop/workshop.pro b/tests/manual/workshop/workshop.pro new file mode 100644 index 00000000..c3abc14c --- /dev/null +++ b/tests/manual/workshop/workshop.pro @@ -0,0 +1,18 @@ +QT += qml quick +TARGET = workshop +!no_desktop: QT += widgets + +include(src/src.pri) + +INCLUDEPATH += ../../shared + +OTHER_FILES += \ + main.qml \ + content/AboutDialog.qml \ + content/Controls.qml \ + content/ImageViewer.qml \ + content/ModelView.qml \ + content/Styles.qml + +RESOURCES += \ + workshop.qrc diff --git a/tests/manual/workshop/workshop.qrc b/tests/manual/workshop/workshop.qrc new file mode 100644 index 00000000..57d803b2 --- /dev/null +++ b/tests/manual/workshop/workshop.qrc @@ -0,0 +1,24 @@ + + + main.qml + content/AboutDialog.qml + content/Controls.qml + content/ImageViewer.qml + content/ModelView.qml + content/Styles.qml + images/document-open.png + images/document-open@2x.png + images/document-save-as.png + images/document-save-as@2x.png + images/folder_new.png + images/tab.png + images/tab_selected.png + images/bubble.png + images/button-pressed.png + images/button.png + images/progress-background.png + images/progress-fill.png + images/textfield.png + images/slider-handle.png + + -- cgit v1.2.1 From 1f6041cb73cfa0fe8415ba713026b1aa1d018cc9 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 3 Nov 2014 15:54:17 +0100 Subject: Update .gitignore Change-Id: I76598cb827c97ed80561d78680db0bf13e75f5ca Reviewed-by: J-P Nurmi --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1c265ad3..86a342d1 100644 --- a/.gitignore +++ b/.gitignore @@ -111,7 +111,8 @@ qtc-debugging-helper # linux shared libraries *.so* -# windows shared libraries +# windows binaries +*.exe *.dll # osx shared libraries -- cgit v1.2.1 From 74b05b5c86637dcbdcd42320e8f27794fff9f93f Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 4 Nov 2014 15:57:43 +0100 Subject: Android: text entry implicit size fits 20 characters A native unlayouted EditText control fits 20 characters by default. Let Qt Quick Controls Android Style use the same metrics instead of adjusting to the textual contents. This gives empty TextField, SpinBox and ComboBox sensible implicit sizes instead of shrinking them down to something unusable. Change-Id: I3cd3948aa3d64daada9d0b7d773cebb6627263f6 Reviewed-by: Mitch Curtis --- src/controls/Styles/Android/ComboBoxStyle.qml | 9 +++++++-- src/controls/Styles/Android/SpinBoxStyle.qml | 9 +++++++-- src/controls/Styles/Android/TextFieldStyle.qml | 11 ++++++++--- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/controls/Styles/Android/ComboBoxStyle.qml b/src/controls/Styles/Android/ComboBoxStyle.qml index b6ff1c30..366deed5 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 diff --git a/src/controls/Styles/Android/SpinBoxStyle.qml b/src/controls/Styles/Android/SpinBoxStyle.qml index 5c05774f..0e5df3fd 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 diff --git a/src/controls/Styles/Android/TextFieldStyle.qml b/src/controls/Styles/Android/TextFieldStyle.qml index 67cd3b78..0edc5c90 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,10 +81,15 @@ 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 -- cgit v1.2.1 From aa510d9ac0bd1ecab6baa260d3ff5f2a64eb3acf Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 4 Nov 2014 17:27:28 +0100 Subject: Slider: fix tap-to-set-value on touch screens Change-Id: I7784b3a8266f889bc2079da4c64096eb9d50d6f5 Task-number: QTBUG-42252 Reviewed-by: Caroline Chao --- src/controls/Slider.qml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/controls/Slider.qml b/src/controls/Slider.qml index b06fcf3a..d43923c1 100644 --- a/src/controls/Slider.qml +++ b/src/controls/Slider.qml @@ -237,21 +237,21 @@ Control { return Math.max(range.positionAtMinimum, Math.min(range.positionAtMaximum, val)) } - function updateHandlePosition(mouse) { + 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 } 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 } } @@ -274,10 +274,11 @@ Control { } pressX = mouse.x pressY = mouse.y - updateHandlePosition(mouse) + 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) -- cgit v1.2.1 From d2439bede98e0f1eb42e8c44b997b1e5d29454e4 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 4 Nov 2014 17:43:49 +0100 Subject: Remove the SplitView example This example served no purpose. A similar snippet can be found in SplitView docs, in the detailed description. Change-Id: Ic53e5bbe8c0c46c7cf9a0002f12ad6c229028388 Reviewed-by: Caroline Chao --- .gitignore | 1 - examples/quick/controls/controls.pro | 1 - examples/quick/controls/splitview/main.qml | 82 --------------------- examples/quick/controls/splitview/resources.qrc | 5 -- examples/quick/controls/splitview/splitview.pro | 12 --- .../quick/controls/splitview/splitview.qmlproject | 16 ---- examples/quick/controls/splitview/src/main.cpp | 49 ------------ examples/quick/controls/splitview/src/src.pri | 2 - .../images/qtquickcontrols-example-splitview.png | Bin 398 -> 0 bytes src/controls/doc/src/qtquickcontrols-examples.qdoc | 14 ---- 10 files changed, 182 deletions(-) delete mode 100644 examples/quick/controls/splitview/main.qml delete mode 100644 examples/quick/controls/splitview/resources.qrc delete mode 100644 examples/quick/controls/splitview/splitview.pro delete mode 100644 examples/quick/controls/splitview/splitview.qmlproject delete mode 100644 examples/quick/controls/splitview/src/main.cpp delete mode 100644 examples/quick/controls/splitview/src/src.pri delete mode 100644 src/controls/doc/images/qtquickcontrols-example-splitview.png diff --git a/.gitignore b/.gitignore index 86a342d1..7c2ec273 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ /examples/quick/controls/basiclayouts/basiclayouts /examples/quick/controls/calendar/calendar /examples/quick/controls/gallery/gallery -/examples/quick/controls/splitview/splitview /examples/quick/controls/styles/styles /examples/quick/controls/tableview/tableview /examples/quick/controls/touch/touch diff --git a/examples/quick/controls/controls.pro b/examples/quick/controls/controls.pro index 134a25e3..f6696bc5 100644 --- a/examples/quick/controls/controls.pro +++ b/examples/quick/controls/controls.pro @@ -2,7 +2,6 @@ TEMPLATE = subdirs SUBDIRS += \ gallery \ - splitview \ tableview \ touch \ basiclayouts \ diff --git a/examples/quick/controls/splitview/main.qml b/examples/quick/controls/splitview/main.qml deleted file mode 100644 index 8707b6cc..00000000 --- a/examples/quick/controls/splitview/main.qml +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - - - - -import QtQuick 2.2 -import QtQuick.Controls 1.2 -import QtQuick.Layouts 1.0 - -ApplicationWindow { - visible: true - width: 600 - height: 400 - - SplitView { - anchors.fill: parent - - Rectangle { - id: column - width: 200 - Layout.minimumWidth: 100 - Layout.maximumWidth: 300 - color: "lightsteelblue" - } - - SplitView { - orientation: Qt.Vertical - Layout.fillWidth: true - - Rectangle { - id: row1 - height: 200 - color: "lightblue" - Layout.minimumHeight: 1 - } - - Rectangle { - id: row2 - color: "lightgray" - } - } - } -} diff --git a/examples/quick/controls/splitview/resources.qrc b/examples/quick/controls/splitview/resources.qrc deleted file mode 100644 index 3b111a90..00000000 --- a/examples/quick/controls/splitview/resources.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - main.qml - - diff --git a/examples/quick/controls/splitview/splitview.pro b/examples/quick/controls/splitview/splitview.pro deleted file mode 100644 index 40adf3d1..00000000 --- a/examples/quick/controls/splitview/splitview.pro +++ /dev/null @@ -1,12 +0,0 @@ -QT += qml quick -TARGET = splitview -!no_desktop: QT += widgets - -include(src/src.pri) -include(../shared/shared.pri) - -OTHER_FILES += \ - main.qml - -RESOURCES += \ - resources.qrc diff --git a/examples/quick/controls/splitview/splitview.qmlproject b/examples/quick/controls/splitview/splitview.qmlproject deleted file mode 100644 index e5a8bf02..00000000 --- a/examples/quick/controls/splitview/splitview.qmlproject +++ /dev/null @@ -1,16 +0,0 @@ -import QmlProject 1.1 - -Project { - mainFile: "main.qml" - - /* Include .qml, .js, and image files from current directory and subdirectories */ - QmlFiles { - directory: "." - } - JavaScriptFiles { - directory: "." - } - ImageFiles { - directory: "." - } -} diff --git a/examples/quick/controls/splitview/src/main.cpp b/examples/quick/controls/splitview/src/main.cpp deleted file mode 100644 index a757f485..00000000 --- a/examples/quick/controls/splitview/src/main.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qtquickcontrolsapplication.h" -#include - -int main(int argc, char *argv[]) -{ - QtQuickControlsApplication app(argc, argv); - QQmlApplicationEngine engine(QUrl("qrc:/main.qml")); - return app.exec(); -} diff --git a/examples/quick/controls/splitview/src/src.pri b/examples/quick/controls/splitview/src/src.pri deleted file mode 100644 index 66d903ea..00000000 --- a/examples/quick/controls/splitview/src/src.pri +++ /dev/null @@ -1,2 +0,0 @@ -SOURCES += \ - $$PWD/main.cpp diff --git a/src/controls/doc/images/qtquickcontrols-example-splitview.png b/src/controls/doc/images/qtquickcontrols-example-splitview.png deleted file mode 100644 index a82017b4..00000000 Binary files a/src/controls/doc/images/qtquickcontrols-example-splitview.png and /dev/null differ diff --git a/src/controls/doc/src/qtquickcontrols-examples.qdoc b/src/controls/doc/src/qtquickcontrols-examples.qdoc index 8b8c1469..ca293df0 100644 --- a/src/controls/doc/src/qtquickcontrols-examples.qdoc +++ b/src/controls/doc/src/qtquickcontrols-examples.qdoc @@ -62,20 +62,6 @@ \include examples-run.qdocinc */ -/*! - \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 -- cgit v1.2.1 From cf26937de2910da16cb3299db5550ae16b926159 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 4 Nov 2014 14:38:54 +0100 Subject: Revise the Table View example A simple sortable and searchable table view example that also fits a mobile screen. The old "example" is demoted as a manual test app. Task-number: QTBUG-41253 Change-Id: I746c8e5871c35a184748abbb4427ca3d160ffc8e Reviewed-by: Venugopal Shivashankar Reviewed-by: Caroline Chao --- .../quick/controls/tableview/images/header.png | Bin 356 -> 0 bytes .../controls/tableview/images/selectedrow.png | Bin 303 -> 0 bytes .../quick/controls/tableview/images/sort-up.png | Bin 205 -> 0 bytes examples/quick/controls/tableview/main.qml | 469 +++++---------------- examples/quick/controls/tableview/resources.qrc | 8 - examples/quick/controls/tableview/src/main.cpp | 14 +- .../tableview/src/sortfilterproxymodel.cpp | 189 +++++++++ .../controls/tableview/src/sortfilterproxymodel.h | 111 +++++ examples/quick/controls/tableview/src/src.pri | 8 +- examples/quick/controls/tableview/tableview.pro | 11 +- .../quick/controls/tableview/tableview.qmlproject | 16 - examples/quick/controls/tableview/tableview.qrc | 5 + .../images/qtquickcontrols-example-tableview.png | Bin 38463 -> 36290 bytes src/controls/doc/src/qtquickcontrols-examples.qdoc | 32 +- 14 files changed, 474 insertions(+), 389 deletions(-) delete mode 100644 examples/quick/controls/tableview/images/header.png delete mode 100644 examples/quick/controls/tableview/images/selectedrow.png delete mode 100644 examples/quick/controls/tableview/images/sort-up.png delete mode 100644 examples/quick/controls/tableview/resources.qrc create mode 100644 examples/quick/controls/tableview/src/sortfilterproxymodel.cpp create mode 100644 examples/quick/controls/tableview/src/sortfilterproxymodel.h delete mode 100644 examples/quick/controls/tableview/tableview.qmlproject create mode 100644 examples/quick/controls/tableview/tableview.qrc diff --git a/examples/quick/controls/tableview/images/header.png b/examples/quick/controls/tableview/images/header.png deleted file mode 100644 index dba66460..00000000 Binary files a/examples/quick/controls/tableview/images/header.png and /dev/null differ diff --git a/examples/quick/controls/tableview/images/selectedrow.png b/examples/quick/controls/tableview/images/selectedrow.png deleted file mode 100644 index 71192ea4..00000000 Binary files a/examples/quick/controls/tableview/images/selectedrow.png and /dev/null differ diff --git a/examples/quick/controls/tableview/images/sort-up.png b/examples/quick/controls/tableview/images/sort-up.png deleted file mode 100644 index 27fcb191..00000000 Binary files a/examples/quick/controls/tableview/images/sort-up.png and /dev/null differ diff --git a/examples/quick/controls/tableview/main.qml b/examples/quick/controls/tableview/main.qml index b85f2d1d..49386289 100644 --- a/examples/quick/controls/tableview/main.qml +++ b/examples/quick/controls/tableview/main.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. @@ -38,385 +38,150 @@ ** ****************************************************************************/ - - - - import QtQuick 2.2 -import QtQuick.Window 2.1 +import QtQuick.Layouts 1.1 import QtQuick.Controls 1.2 -import QtQuick.XmlListModel 2.0 +import org.qtproject.example 1.0 -Window { +ApplicationWindow { + id: window visible: true - width: 538 + frame.margins * 2 - height: 360 + frame.margins * 2 - - ToolBar { - id: toolbar - width: parent.width + title: "Table View Example" - ListModel { - id: delegatemenu - ListElement { text: "Shiny delegate" } - ListElement { text: "Scale selected" } - ListElement { text: "Editable items" } - } + toolBar: ToolBar { + TextField { + id: searchBox - ComboBox { - id: delegateChooser - enabled: frame.currentIndex === 3 ? 1 : 0 - model: delegatemenu - width: 150 - anchors.left: parent.left - anchors.leftMargin: 8 - anchors.verticalCenter: parent.verticalCenter - } + placeholderText: "Search..." + inputMethodHints: Qt.ImhNoPredictiveText - CheckBox { - id: enabledCheck - text: "Enabled" - checked: true + width: window.width / 5 * 2 anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter } } - SystemPalette {id: syspal} - color: syspal.window - - XmlListModel { - id: flickerModel - source: "http://api.flickr.com/services/feeds/photos_public.gne?format=rss2&tags=" + "Qt" - query: "/rss/channel/item" - namespaceDeclarations: "declare namespace media=\"http://search.yahoo.com/mrss/\";" - XmlRole { name: "title"; query: "title/string()" } - XmlRole { name: "imagesource"; query: "media:thumbnail/@url/string()" } - XmlRole { name: "credit"; query: "media:credit/string()" } - } - - ListModel { - id: nestedModel - ListElement{content: ListElement { description: "Core" ; color:"#ffaacc"}} - ListElement{content: ListElement { description: "Second" ; color:"#ffccaa"}} - ListElement{content: ListElement { description: "Third" ; color:"#ffffaa"}} - } + TableView { + id: tableView - ListModel { - id: largeModel - Component.onCompleted: { - for (var i=0 ; i< 500 ; ++i) - largeModel.append({"name":"Person "+i , "age": Math.round(Math.random()*100), "gender": Math.random()>0.5 ? "Male" : "Female"}) - } - } + frameVisible: false + sortIndicatorVisible: true - Column { - anchors.top: toolbar.bottom - anchors.right: parent.right - anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.margins: 8 + anchors.fill: parent - TabView { - id:frame - focus:true - enabled: enabledCheck.checked + Layout.minimumWidth: 400 + Layout.minimumHeight: 240 + Layout.preferredWidth: 600 + Layout.preferredHeight: 400 - property int margins: Qt.platform.os === "osx" ? 16 : 0 + TableViewColumn { + id: titleColumn + title: "Title" + role: "title" + movable: false + resizable: false + width: tableView.viewport.width - authorColumn.width + } - height: parent.height - 34 - anchors.right: parent.right - anchors.left: parent.left - anchors.margins: margins + TableViewColumn { + id: authorColumn + title: "Author" + role: "author" + movable: false + resizable: false + width: tableView.viewport.width / 3 + } - Tab { - title: "XmlListModel" + model: SortFilterProxyModel { + id: proxyModel + source: sourceModel.count > 0 ? sourceModel : null - TableView { - model: flickerModel - anchors.fill: parent - anchors.margins: 12 + sortOrder: tableView.sortIndicatorOrder + sortCaseSensitivity: Qt.CaseInsensitive + sortRole: sourceModel.count > 0 ? tableView.getColumn(tableView.sortIndicatorColumn).role : "" - TableViewColumn { - role: "title" - title: "Title" - width: 120 - } - TableViewColumn { - role: "credit" - title: "Credit" - width: 120 - } - TableViewColumn { - role: "imagesource" - title: "Image source" - width: 200 - visible: true - } + filterString: "*" + searchBox.text + "*" + filterSyntax: SortFilterProxyModel.Wildcard + filterCaseSensitivity: Qt.CaseInsensitive + } - frameVisible: frameCheckbox.checked - headerVisible: headerCheckbox.checked - sortIndicatorVisible: sortableCheckbox.checked - alternatingRowColors: alternateCheckbox.checked - } + ListModel { + id: sourceModel + ListElement { + title: "Moby-Dick" + author: "Herman Melville" } - Tab { - title: "Multivalue" - - TableView { - model: nestedModel - anchors.fill: parent - anchors.margins: 12 - - TableViewColumn { - role: "content" - title: "Text and Color" - width: 220 - } - - itemDelegate: Item { - Rectangle{ - color: styleData.value.get(0).color - anchors.top:parent.top - anchors.right:parent.right - anchors.bottom:parent.bottom - anchors.margins: 4 - width:32 - border.color:"#666" - } - Text { - width: parent.width - anchors.margins: 4 - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - elide: styleData.elideMode - text: styleData.value.get(0).description - color: styleData.textColor - } - } - - frameVisible: frameCheckbox.checked - headerVisible: headerCheckbox.checked - sortIndicatorVisible: sortableCheckbox.checked - alternatingRowColors: alternateCheckbox.checked - } + ListElement { + title: "The Adventures of Tom Sawyer" + author: "Mark Twain" } - Tab { - title: "Generated" - - TableView { - model: largeModel - anchors.margins: 12 - anchors.fill: parent - TableViewColumn { - role: "name" - title: "Name" - width: 120 - } - TableViewColumn { - role: "age" - title: "Age" - width: 120 - } - TableViewColumn { - role: "gender" - title: "Gender" - width: 120 - } - frameVisible: frameCheckbox.checked - headerVisible: headerCheckbox.checked - sortIndicatorVisible: sortableCheckbox.checked - alternatingRowColors: alternateCheckbox.checked - } + ListElement { + title: "Cat’s Cradle" + author: "Kurt Vonnegut" } - - Tab { - title: "Delegates" - Item { - anchors.fill: parent - - Component { - id: delegate1 - Item { - clip: true - Text { - width: parent.width - anchors.margins: 4 - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - elide: styleData.elideMode - text: styleData.value !== undefined ? styleData.value : "" - color: styleData.textColor - } - } - } - - Component { - id: delegate2 - Text { - width: parent.width - anchors.margins: 4 - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - elide: styleData.elideMode - text: styleData.value !== undefined ? styleData.value : "" - color: styleData.textColor - } - } - - Component { - id: editableDelegate - Item { - - Text { - width: parent.width - anchors.margins: 4 - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - elide: styleData.elideMode - text: styleData.value !== undefined ? styleData.value : "" - color: styleData.textColor - visible: !styleData.selected - } - Loader { // Initialize text editor lazily to improve performance - id: loaderEditor - anchors.fill: parent - anchors.margins: 4 - Connections { - target: loaderEditor.item - onAccepted: { - if (typeof styleData.value === 'number') - largeModel.setProperty(styleData.row, styleData.role, Number(parseFloat(loaderEditor.item.text).toFixed(0))) - else - largeModel.setProperty(styleData.row, styleData.role, loaderEditor.item.text) - } - } - sourceComponent: styleData.selected ? editor : null - Component { - id: editor - TextInput { - id: textinput - color: styleData.textColor - text: styleData.value - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - onClicked: textinput.forceActiveFocus() - } - } - } - } - } - } - TableView { - id: delegatesView - model: largeModel - anchors.margins: 12 - anchors.fill:parent - frameVisible: frameCheckbox.checked - headerVisible: headerCheckbox.checked - sortIndicatorVisible: sortableCheckbox.checked - alternatingRowColors: alternateCheckbox.checked - - TableViewColumn { - role: "name" - title: "Name" - width: 120 - } - TableViewColumn { - role: "age" - title: "Age" - width: 120 - } - TableViewColumn { - role: "gender" - title: "Gender" - width: 120 - } - - headerDelegate: BorderImage{ - source: "images/header.png" - border{left:2;right:2;top:2;bottom:2} - Text { - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.right: indicator.visible ? indicator.left : parent.right - anchors.margins: 6 - text: styleData.value - elide: Text.ElideRight - color:"#333" - } - // Sort indicator - Image { - id: indicator - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: 6 - source: "images/sort-up.png" - visible: delegatesView.sortIndicatorVisible && - styleData.column === delegatesView.sortIndicatorColumn - rotation: delegatesView.sortIndicatorOrder === Qt.AscendingOrder ? 180 : 0 - Behavior on rotation { NumberAnimation { } } - } - - } - - rowDelegate: Rectangle { - height: (delegateChooser.currentIndex == 1 && styleData.selected) ? 30 : 20 - Behavior on height{ NumberAnimation{} } - - color: styleData.selected ? "#448" : (styleData.alternate? "#eee" : "#fff") - BorderImage{ - id: selected - anchors.fill: parent - source: "images/selectedrow.png" - visible: styleData.selected - border{left:2; right:2; top:2; bottom:2} - SequentialAnimation { - running: true; loops: Animation.Infinite - NumberAnimation { target:selected; property: "opacity"; to: 1.0; duration: 900} - NumberAnimation { target:selected; property: "opacity"; to: 0.5; duration: 900} - } - } - } - - itemDelegate: { - if (delegateChooser.currentIndex == 2) - return editableDelegate; - else - return delegate1; - } - } - } + ListElement { + title: "Farenheit 451" + author: "Ray Bradbury" } - } - Row{ - x: 12 - height: 34 - CheckBox{ - id: alternateCheckbox - checked: true - text: "Alternate" - anchors.verticalCenter: parent.verticalCenter + ListElement { + title: "It" + author: "Stephen King" + } + ListElement { + title: "On the Road" + author: "Jack Kerouac" + } + ListElement { + title: "Of Mice and Men" + author: "John Steinbeck" + } + ListElement { + title: "Do Androids Dream of Electric Sheep?" + author: "Philip K. Dick" + } + ListElement { + title: "Uncle Tom’s Cabin" + author: "Harriet Beecher Stowe" + } + ListElement { + title: "The Call of the Wild" + author: "Jack London" + } + ListElement { + title: "The Old Man and the Sea" + author: "Ernest Hemingway" + } + ListElement { + title: "A Streetcar Named Desire" + author: "Tennessee Williams" + } + ListElement { + title: "Catch-22" + author: "Joseph Heller" + } + ListElement { + title: "One Flew Over the Cuckoo’s Nest" + author: "Ken Kesey" + } + ListElement { + title: "The Murders in the Rue Morgue" + author: "Edgar Allan Poe" + } + ListElement { + title: "Breakfast at Tiffany’s" + author: "Truman Capote" } - CheckBox{ - id: sortableCheckbox - checked: false - text: "Sort indicator" - anchors.verticalCenter: parent.verticalCenter + ListElement { + title: "Death of a Salesman" + author: "Arthur Miller" } - CheckBox{ - id: frameCheckbox - checked: true - text: "Frame" - anchors.verticalCenter: parent.verticalCenter + ListElement { + title: "Post Office" + author: "Charles Bukowski" } - CheckBox{ - id: headerCheckbox - checked: true - text: "Headers" - anchors.verticalCenter: parent.verticalCenter + ListElement { + title: "Herbert West—Reanimator" + author: "H. P. Lovecraft" } } } diff --git a/examples/quick/controls/tableview/resources.qrc b/examples/quick/controls/tableview/resources.qrc deleted file mode 100644 index 83d3f6a7..00000000 --- a/examples/quick/controls/tableview/resources.qrc +++ /dev/null @@ -1,8 +0,0 @@ - - - main.qml - images/selectedrow.png - images/header.png - images/sort-up.png - - diff --git a/examples/quick/controls/tableview/src/main.cpp b/examples/quick/controls/tableview/src/main.cpp index a757f485..1406b84c 100644 --- a/examples/quick/controls/tableview/src/main.cpp +++ b/examples/quick/controls/tableview/src/main.cpp @@ -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. @@ -39,11 +39,21 @@ ****************************************************************************/ #include "qtquickcontrolsapplication.h" -#include +#include "sortfilterproxymodel.h" +#include +#include +#include int main(int argc, char *argv[]) { QtQuickControlsApplication app(argc, argv); + if (QCoreApplication::arguments().contains(QLatin1String("--coreprofile"))) { + QSurfaceFormat fmt; + fmt.setVersion(4, 4); + fmt.setProfile(QSurfaceFormat::CoreProfile); + QSurfaceFormat::setDefaultFormat(fmt); + } + qmlRegisterType("org.qtproject.example", 1, 0, "SortFilterProxyModel"); QQmlApplicationEngine engine(QUrl("qrc:/main.qml")); return app.exec(); } diff --git a/examples/quick/controls/tableview/src/sortfilterproxymodel.cpp b/examples/quick/controls/tableview/src/sortfilterproxymodel.cpp new file mode 100644 index 00000000..7b999470 --- /dev/null +++ b/examples/quick/controls/tableview/src/sortfilterproxymodel.cpp @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** 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. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "sortfilterproxymodel.h" +#include +#include + +SortFilterProxyModel::SortFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent), m_complete(false) +{ + connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(countChanged())); + connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(countChanged())); +} + +int SortFilterProxyModel::count() const +{ + return rowCount(); +} + +QObject *SortFilterProxyModel::source() const +{ + return sourceModel(); +} + +void SortFilterProxyModel::setSource(QObject *source) +{ + setSourceModel(qobject_cast(source)); +} + +QByteArray SortFilterProxyModel::sortRole() const +{ + return m_sortRole; +} + +void SortFilterProxyModel::setSortRole(const QByteArray &role) +{ + if (m_sortRole != role) { + m_sortRole = role; + if (m_complete) + QSortFilterProxyModel::setSortRole(roleKey(role)); + } +} + +void SortFilterProxyModel::setSortOrder(Qt::SortOrder order) +{ + QSortFilterProxyModel::sort(0, order); +} + +QByteArray SortFilterProxyModel::filterRole() const +{ + return m_filterRole; +} + +void SortFilterProxyModel::setFilterRole(const QByteArray &role) +{ + if (m_filterRole != role) { + m_filterRole = role; + if (m_complete) + QSortFilterProxyModel::setFilterRole(roleKey(role)); + } +} + +QString SortFilterProxyModel::filterString() const +{ + return filterRegExp().pattern(); +} + +void SortFilterProxyModel::setFilterString(const QString &filter) +{ + setFilterRegExp(QRegExp(filter, filterCaseSensitivity(), static_cast(filterSyntax()))); +} + +SortFilterProxyModel::FilterSyntax SortFilterProxyModel::filterSyntax() const +{ + return static_cast(filterRegExp().patternSyntax()); +} + +void SortFilterProxyModel::setFilterSyntax(SortFilterProxyModel::FilterSyntax syntax) +{ + setFilterRegExp(QRegExp(filterString(), filterCaseSensitivity(), static_cast(syntax))); +} + +QJSValue SortFilterProxyModel::get(int idx) const +{ + QJSEngine *engine = qmlEngine(this); + QJSValue value = engine->newObject(); + if (idx >= 0 && idx < count()) { + QHash roles = roleNames(); + QHashIterator it(roles); + while (it.hasNext()) { + it.next(); + value.setProperty(QString::fromUtf8(it.value()), data(index(idx, 0), it.key()).toString()); + } + } + return value; +} + +void SortFilterProxyModel::classBegin() +{ +} + +void SortFilterProxyModel::componentComplete() +{ + m_complete = true; + if (!m_sortRole.isEmpty()) + QSortFilterProxyModel::setSortRole(roleKey(m_sortRole)); + if (!m_filterRole.isEmpty()) + QSortFilterProxyModel::setFilterRole(roleKey(m_filterRole)); +} + +int SortFilterProxyModel::roleKey(const QByteArray &role) const +{ + QHash roles = roleNames(); + QHashIterator it(roles); + while (it.hasNext()) { + it.next(); + if (it.value() == role) + return it.key(); + } + return -1; +} + +QHash SortFilterProxyModel::roleNames() const +{ + if (QAbstractItemModel *source = sourceModel()) + return source->roleNames(); + return QHash(); +} + +bool SortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + QRegExp rx = filterRegExp(); + if (rx.isEmpty()) + return true; + QAbstractItemModel *model = sourceModel(); + if (filterRole().isEmpty()) { + QHash roles = roleNames(); + QHashIterator it(roles); + while (it.hasNext()) { + it.next(); + QModelIndex sourceIndex = model->index(sourceRow, 0, sourceParent); + QString key = model->data(sourceIndex, it.key()).toString(); + if (key.contains(rx)) + return true; + } + return false; + } + QModelIndex sourceIndex = model->index(sourceRow, 0, sourceParent); + if (!sourceIndex.isValid()) + return true; + QString key = model->data(sourceIndex, roleKey(filterRole())).toString(); + return key.contains(rx); +} diff --git a/examples/quick/controls/tableview/src/sortfilterproxymodel.h b/examples/quick/controls/tableview/src/sortfilterproxymodel.h new file mode 100644 index 00000000..026b5d12 --- /dev/null +++ b/examples/quick/controls/tableview/src/sortfilterproxymodel.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** 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. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SORTFILTERPROXYMODEL_H +#define SORTFILTERPROXYMODEL_H + +#include +#include +#include + +class SortFilterProxyModel : public QSortFilterProxyModel, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + + Q_PROPERTY(int count READ count NOTIFY countChanged) + Q_PROPERTY(QObject *source READ source WRITE setSource) + + Q_PROPERTY(QByteArray sortRole READ sortRole WRITE setSortRole) + Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder) + + Q_PROPERTY(QByteArray filterRole READ filterRole WRITE setFilterRole) + Q_PROPERTY(QString filterString READ filterString WRITE setFilterString) + Q_PROPERTY(FilterSyntax filterSyntax READ filterSyntax WRITE setFilterSyntax) + + Q_ENUMS(FilterSyntax) + +public: + explicit SortFilterProxyModel(QObject *parent = 0); + + QObject *source() const; + void setSource(QObject *source); + + QByteArray sortRole() const; + void setSortRole(const QByteArray &role); + + void setSortOrder(Qt::SortOrder order); + + QByteArray filterRole() const; + void setFilterRole(const QByteArray &role); + + QString filterString() const; + void setFilterString(const QString &filter); + + enum FilterSyntax { + RegExp, + Wildcard, + FixedString + }; + + FilterSyntax filterSyntax() const; + void setFilterSyntax(FilterSyntax syntax); + + int count() const; + Q_INVOKABLE QJSValue get(int index) const; + + void classBegin(); + void componentComplete(); + +signals: + void countChanged(); + +protected: + int roleKey(const QByteArray &role) const; + QHash roleNames() const; + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; + +private: + bool m_complete; + QByteArray m_sortRole; + QByteArray m_filterRole; +}; + +#endif // SORTFILTERPROXYMODEL_H diff --git a/examples/quick/controls/tableview/src/src.pri b/examples/quick/controls/tableview/src/src.pri index 66d903ea..491f851c 100644 --- a/examples/quick/controls/tableview/src/src.pri +++ b/examples/quick/controls/tableview/src/src.pri @@ -1,2 +1,8 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/sortfilterproxymodel.h + SOURCES += \ - $$PWD/main.cpp + $$PWD/main.cpp \ + $$PWD/sortfilterproxymodel.cpp diff --git a/examples/quick/controls/tableview/tableview.pro b/examples/quick/controls/tableview/tableview.pro index c982ac20..c0ed1a2f 100644 --- a/examples/quick/controls/tableview/tableview.pro +++ b/examples/quick/controls/tableview/tableview.pro @@ -1,12 +1,11 @@ -QT += qml quick +TEMPLATE = app TARGET = tableview -!no_desktop: QT += widgets -include(src/src.pri) -include(../shared/shared.pri) +RESOURCES += \ + tableview.qrc OTHER_FILES += \ main.qml -RESOURCES += \ - resources.qrc +include(src/src.pri) +include(../shared/shared.pri) diff --git a/examples/quick/controls/tableview/tableview.qmlproject b/examples/quick/controls/tableview/tableview.qmlproject deleted file mode 100644 index e5a8bf02..00000000 --- a/examples/quick/controls/tableview/tableview.qmlproject +++ /dev/null @@ -1,16 +0,0 @@ -import QmlProject 1.1 - -Project { - mainFile: "main.qml" - - /* Include .qml, .js, and image files from current directory and subdirectories */ - QmlFiles { - directory: "." - } - JavaScriptFiles { - directory: "." - } - ImageFiles { - directory: "." - } -} diff --git a/examples/quick/controls/tableview/tableview.qrc b/examples/quick/controls/tableview/tableview.qrc new file mode 100644 index 00000000..3b111a90 --- /dev/null +++ b/examples/quick/controls/tableview/tableview.qrc @@ -0,0 +1,5 @@ + + + main.qml + + diff --git a/src/controls/doc/images/qtquickcontrols-example-tableview.png b/src/controls/doc/images/qtquickcontrols-example-tableview.png index b9dc67c3..c4ab8d99 100644 Binary files a/src/controls/doc/images/qtquickcontrols-example-tableview.png and b/src/controls/doc/images/qtquickcontrols-example-tableview.png differ diff --git a/src/controls/doc/src/qtquickcontrols-examples.qdoc b/src/controls/doc/src/qtquickcontrols-examples.qdoc index ca293df0..4e6fccb0 100644 --- a/src/controls/doc/src/qtquickcontrols-examples.qdoc +++ b/src/controls/doc/src/qtquickcontrols-examples.qdoc @@ -69,10 +69,34 @@ \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 + ... + qmlRegisterType("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 */ -- cgit v1.2.1 From 9f4ff8ce499dd0d50d0b04cb88ffa981dddd006e Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 6 Nov 2014 15:35:49 +0100 Subject: Let the cursor handle be visible regardless of selection The cursor handle is visible on Android even when there's no selection. Let the style decide when to show/hide the handles, but make sure to disable the corresponding MouseArea when a handle is hidden. Change-Id: I211c122998223ad25279bee2841c5b5e14d4c48e Reviewed-by: Mitch Curtis Reviewed-by: Richard Moe Gustavsen --- src/controls/Private/TextHandle.qml | 2 +- src/controls/Private/TextInputWithHandles.qml | 2 +- src/controls/Styles/iOS/CursorHandleStyle.qml | 1 + src/controls/TextArea.qml | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/controls/Private/TextHandle.qml b/src/controls/Private/TextHandle.qml index 19fc19a6..8656dcfd 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 ceb63084..726b6863 100644 --- a/src/controls/Private/TextInputWithHandles.qml +++ b/src/controls/Private/TextInputWithHandles.qml @@ -170,7 +170,7 @@ TextInput { 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/Styles/iOS/CursorHandleStyle.qml b/src/controls/Styles/iOS/CursorHandleStyle.qml index 26ab9728..408a7bf4 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/TextArea.qml b/src/controls/TextArea.qml index 8cfb6dfd..691bf13e 100644 --- a/src/controls/TextArea.qml +++ b/src/controls/TextArea.qml @@ -933,7 +933,7 @@ ScrollView { property var posInViewport: flickableItem.contentX !== flickableItem.contentY !== Number.MAX_VALUE ? parent.mapToItem(viewport, handleX, handleY) : -1 - visible: pressed || (edit.hasSelection + visible: pressed || ((edit.cursorVisible || edit.hasSelection) && posInViewport.y + handleHeight >= -1 && posInViewport.y <= viewport.height + 1 && posInViewport.x + handleWidth >= -1 -- cgit v1.2.1 From e2b8964c56a71950b274eebb9aec70dc532ea875 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 6 Nov 2014 17:28:55 +0100 Subject: Android: fix missing cursor handle Change-Id: Iefd5ed9b662423c25d5dcad011d93b2336da794a Reviewed-by: Mitch Curtis --- src/controls/Styles/Android/CursorHandleStyle.qml | 75 +++++++++-------------- 1 file changed, 30 insertions(+), 45 deletions(-) diff --git a/src/controls/Styles/Android/CursorHandleStyle.qml b/src/controls/Styles/Android/CursorHandleStyle.qml index 97b9fe85..e9d08f8e 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 + } } -- cgit v1.2.1 From a8532793ffac763b8345fd42fe0bccb312e4c94c Mon Sep 17 00:00:00 2001 From: Venu Date: Fri, 7 Nov 2014 13:35:28 +0100 Subject: Doc: Language edits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed the section title and removed a redundant sentence. Change-Id: I16ac77e2df61f488f1feda60d043f6ed95af7f6c Reviewed-by: Topi Reiniö --- src/controls/doc/src/qtquickcontrols-platformnotes.qdoc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc b/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc index 70f1a1bb..fdf64cf5 100644 --- a/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc +++ b/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc @@ -33,7 +33,7 @@ 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. @@ -41,8 +41,7 @@ \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 + It 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. @@ -62,8 +61,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 */ -- cgit v1.2.1 From 8e8b0dbaec1868944e0a699a4474304b0cae65e9 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 7 Nov 2014 12:25:29 +0100 Subject: Slider: don't clamp to the initial press point Change-Id: I5115bbab670f534dae44eb19c2208aff21293889 Reviewed-by: Mitch Curtis --- src/controls/Slider.qml | 2 +- tests/auto/controls/data/tst_slider.qml | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/controls/Slider.qml b/src/controls/Slider.qml index d43923c1..89c1e723 100644 --- a/src/controls/Slider.qml +++ b/src/controls/Slider.qml @@ -258,7 +258,7 @@ Control { onPositionChanged: { if (pressed) - updateHandlePosition(mouse) + updateHandlePosition(mouse, preventStealing) var point = mouseArea.mapToItem(fakeHandle, mouse.x, mouse.y) handleHovered = fakeHandle.contains(Qt.point(point.x, point.y)) diff --git a/tests/auto/controls/data/tst_slider.qml b/tests/auto/controls/data/tst_slider.qml index 2b3a00a5..2541b1c5 100644 --- a/tests/auto/controls/data/tst_slider.qml +++ b/tests/auto/controls/data/tst_slider.qml @@ -41,6 +41,8 @@ import QtQuick 2.2 import QtTest 1.0 import QtQuickControlsTests 1.0 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Private 1.0 Item { id: container @@ -305,5 +307,28 @@ Item { compare(slider.__handlePos, 50) slider.destroy() } + + function test_dragThreshold() { + var control = Qt.createQmlObject('import QtQuick.Controls 1.2; Slider {x: 20; y: 20; width: 100; height: 50}', container, '') + + var pt = { x: control.width/2, y: control.height/2 } + + mousePress(control, pt.x, pt.y) + compare(control.value, 0.5) + + // drag less than the threshold distance + mouseMove(control, pt.x + Settings.dragThreshold - 1, pt.y) + compare(control.value, 0.5) + + // drag over the threshold + mouseMove(control, pt.x + Settings.dragThreshold + 1, pt.y) + verify(control.value > 0.5) + + // move back close to the original press point, less than the threshold distance away + mouseMove(control, pt.x - Settings.dragThreshold / 2, pt.y) + verify(control.value < 0.5) + + control.destroy() + } } } -- cgit v1.2.1