diff --git a/.gitignore b/.gitignore index 1c265ad3125125b91201dd852fd10f276d74d27e..7c2ec273988850aadbf90243e1621f8c50716247 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 @@ -111,7 +110,8 @@ qtc-debugging-helper # linux shared libraries *.so* -# windows shared libraries +# windows binaries +*.exe *.dll # osx shared libraries diff --git a/examples/quick/controls/controls.pro b/examples/quick/controls/controls.pro index 134a25e357cdbe4dcb2d67d0585e807652d1a163..f6696bc5322f550d28bbea10e32b654b88892082 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/splitview.pro b/examples/quick/controls/splitview/splitview.pro deleted file mode 100644 index 40adf3d119508a699c3f38762d4e67cdce3f41a0..0000000000000000000000000000000000000000 --- 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 e5a8bf02ca789d31c0265da83b2cb6f09e10ba15..0000000000000000000000000000000000000000 --- 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/tableview/images/header.png b/examples/quick/controls/tableview/images/header.png deleted file mode 100644 index dba6646092ce4f4f6dcc52f05c3fa96535eab660..0000000000000000000000000000000000000000 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 71192ea4e2b72d820f7afa745d50275fa8a1fb82..0000000000000000000000000000000000000000 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 27fcb19153992dbc4003103460fd74004e6778e8..0000000000000000000000000000000000000000 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 b85f2d1d98ea0d3e3354afbc8b2116a7ac8c7fc2..49386289da0684744c1caff910e326e35c3a1019 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 83d3f6a76c31f2ec3b0d1a8be27f540093b5a6f0..0000000000000000000000000000000000000000 --- a/examples/quick/controls/tableview/resources.qrc +++ /dev/null @@ -1,8 +0,0 @@ -<!DOCTYPE RCC><RCC version="1.0"> -<qresource prefix="/"> - <file>main.qml</file> - <file>images/selectedrow.png</file> - <file>images/header.png</file> - <file>images/sort-up.png</file> -</qresource> -</RCC> diff --git a/examples/quick/controls/tableview/src/main.cpp b/examples/quick/controls/tableview/src/main.cpp index a757f4853bfbf9bcd6469529cfbc00854b38de47..1406b84cec5d0799a5691bea174af49b955aa3bd 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 <QtQml/QQmlApplicationEngine> +#include "sortfilterproxymodel.h" +#include <QtQml/qqmlapplicationengine.h> +#include <QtGui/qsurfaceformat.h> +#include <QtQml/qqml.h> 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<SortFilterProxyModel>("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 0000000000000000000000000000000000000000..7b999470f37e96ec71a31b6df747d26bcbeeb80d --- /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 <QtDebug> +#include <QtQml> + +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<QAbstractItemModel *>(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<QRegExp::PatternSyntax>(filterSyntax()))); +} + +SortFilterProxyModel::FilterSyntax SortFilterProxyModel::filterSyntax() const +{ + return static_cast<FilterSyntax>(filterRegExp().patternSyntax()); +} + +void SortFilterProxyModel::setFilterSyntax(SortFilterProxyModel::FilterSyntax syntax) +{ + setFilterRegExp(QRegExp(filterString(), filterCaseSensitivity(), static_cast<QRegExp::PatternSyntax>(syntax))); +} + +QJSValue SortFilterProxyModel::get(int idx) const +{ + QJSEngine *engine = qmlEngine(this); + QJSValue value = engine->newObject(); + if (idx >= 0 && idx < count()) { + QHash<int, QByteArray> roles = roleNames(); + QHashIterator<int, QByteArray> 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<int, QByteArray> roles = roleNames(); + QHashIterator<int, QByteArray> it(roles); + while (it.hasNext()) { + it.next(); + if (it.value() == role) + return it.key(); + } + return -1; +} + +QHash<int, QByteArray> SortFilterProxyModel::roleNames() const +{ + if (QAbstractItemModel *source = sourceModel()) + return source->roleNames(); + return QHash<int, QByteArray>(); +} + +bool SortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + QRegExp rx = filterRegExp(); + if (rx.isEmpty()) + return true; + QAbstractItemModel *model = sourceModel(); + if (filterRole().isEmpty()) { + QHash<int, QByteArray> roles = roleNames(); + QHashIterator<int, QByteArray> 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 0000000000000000000000000000000000000000..026b5d124bc7997f88710fe7f1bc0d70654daae5 --- /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 <QtCore/qsortfilterproxymodel.h> +#include <QtQml/qqmlparserstatus.h> +#include <QtQml/qjsvalue.h> + +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<int, QByteArray> 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 66d903eacf02b2c8c3cf57b9c10fc4835937357a..491f851c916c23f86cae2a84a24368c93cd149e2 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 c982ac2038c1e1b55eb8564117bda3c8589a1cce..c0ed1a2f99e3d20865968642202b95907663ef6a 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 e5a8bf02ca789d31c0265da83b2cb6f09e10ba15..0000000000000000000000000000000000000000 --- 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/splitview/resources.qrc b/examples/quick/controls/tableview/tableview.qrc similarity index 100% rename from examples/quick/controls/splitview/resources.qrc rename to examples/quick/controls/tableview/tableview.qrc diff --git a/src/controls/Private/TextHandle.qml b/src/controls/Private/TextHandle.qml index 19fc19a6d74523ec7f168402b7820320ef5afc54..8656dcfd86f4e301052e253d9e6db5376e95c521 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 d19dda31da94b873c6ea8264e10763fd90fdc466..75ca947f7619eaa04e23534aa03944806588f639 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/Private/qquickstyleitem.cpp b/src/controls/Private/qquickstyleitem.cpp index edb33212ea64a9df2d4a216482a3420870badd75..fb49e6e3f812368c1bcc02c9446ab145230c6477 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/Slider.qml b/src/controls/Slider.qml index 459fe54ccad671f6b170f2cecfd9d60cbc68ea0e..d0644b4ccb6c03068ccd8332b9c239676a16a2ca 100644 --- a/src/controls/Slider.qml +++ b/src/controls/Slider.qml @@ -239,28 +239,28 @@ 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 } } 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)) @@ -276,10 +276,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) diff --git a/src/controls/Styles/Android/ComboBoxStyle.qml b/src/controls/Styles/Android/ComboBoxStyle.qml index b6ff1c3078858a04fd3a1484efddfd1261f302ed..366deed56e5031ebf82d17be9f89895b2f12ae27 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/CursorHandleStyle.qml b/src/controls/Styles/Android/CursorHandleStyle.qml index 97b9fe857799919ecc1f538d8780b2a84c9e37e5..e9d08f8e6b3bff3debc97b17019d5b70e96e7feb 100644 --- a/src/controls/Styles/Android/CursorHandleStyle.qml +++ b/src/controls/Styles/Android/CursorHandleStyle.qml @@ -45,66 +45,51 @@ import "drawables" DrawableLoader { id: delegate - property bool active: false + + property bool hasText: !!editor.text || !!editor.displayText + styleDef: styleData.hasSelection ? AndroidStyle.styleDef.textViewStyle.TextView_textSelectHandleRight : AndroidStyle.styleDef.textViewStyle.TextView_textSelectHandle x: styleData.hasSelection ? -width / 4 : -width / 2 y: styleData.lineHeight - opacity: 1.0 pressed: styleData.pressed focused: control.activeFocus window_focused: focused && control.Window.active - Connections { - target: editor - ignoreUnknownSignals: true - onDisplayTextChanged: { - delegate.state = "hidden" - } + opacity: hasText && (styleData.hasSelection || styleData.pressed || idle.running) ? 1.0 : 0.0 + + Timer { + id: idle + repeat: false + interval: 4000 } Connections { target: styleData - onActivated: { - if (editor.text) { - delegate.active = true - delegate.opacity = 1.0 - delegate.state = "" - if (!styleData.hasSelection) - delegate.state = "idle" - } + onActivated: idle.restart() + onPressedChanged: { + if (!styleData.pressed) + idle.restart() } } - state: "hidden" - - states: [ - State { - name: "hidden" - when: editor.inputMethodComposing && !delegate.active && !editor.text - }, - State { - name: "idle" - when: !styleData.hasSelection && !styleData.pressed - } - ] + // Hide the cursor handle on textual changes, unless the signals are + // indirectly triggered by activating/tapping/moving the handle. When + // text prediction is enabled, the textual content may change when the + // cursor moves and the predicted text is committed. + Connections { + target: editor + ignoreUnknownSignals: true + onTextChanged: if (!ignore.running) idle.stop() + onDisplayTextChanged: if (!ignore.running) idle.stop() + onInputMethodComposing: if (!ignore.running) idle.stop() + } - transitions: [ - Transition { - to: "hidden" - SequentialAnimation { - PauseAnimation { duration: 100 } - PropertyAction { target: delegate; property: "opacity"; value: 0.0 } - } - }, - Transition { - to: "idle" - SequentialAnimation { - PauseAnimation { duration: 4000 } - NumberAnimation { target: delegate; property: "opacity"; to: 0.0 } - PropertyAction { target: delegate; property: "active"; value: false } - } - } - ] + Timer { + id: ignore + repeat: false + interval: 250 + running: idle.running + } } diff --git a/src/controls/Styles/Android/SpinBoxStyle.qml b/src/controls/Styles/Android/SpinBoxStyle.qml index 5c05774fa658ed5d89ad26746a85ae9a61a24d5d..0e5df3fd0b833c6222b677b116e918643f2137be 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 67cd3b7869f5112b61a13da116e6d42af5d85975..0edc5c90b0aaf9b193ff948a2eba3893f7cbac81 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 diff --git a/src/controls/Styles/Desktop/ComboBoxStyle.qml b/src/controls/Styles/Desktop/ComboBoxStyle.qml index d897a2a4556109b3491f32e8336e9da18ae875c6..758518edcd77011cd7a0a0dfc43476fe3773028d 100644 --- a/src/controls/Styles/Desktop/ComboBoxStyle.qml +++ b/src/controls/Styles/Desktop/ComboBoxStyle.qml @@ -109,8 +109,8 @@ Style { elementType: "itemrow" selected: styleData.selected - implicitWidth: textItem.contentWidth - implicitHeight: textItem.contentHeight + implicitWidth: textItem.implicitWidth + implicitHeight: textItem.implicitHeight StyleItem { id: textItem diff --git a/src/controls/Styles/iOS/CursorHandleStyle.qml b/src/controls/Styles/iOS/CursorHandleStyle.qml index 26ab972823b886e2a105a1b53a18cd91286fd7b3..408a7bf462e5fd00694bd37d24f72de9168bf9ff 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 b8ed0ba2c6c5faeefb5f54f739636d860fc7dc07..1c19a300f83b2151f967e5bdcb60f8a6895444d9 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 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 a82017b49b52f615a1d8177564ac3551fb7e7a01..0000000000000000000000000000000000000000 Binary files a/src/controls/doc/images/qtquickcontrols-example-splitview.png and /dev/null differ diff --git a/src/controls/doc/images/qtquickcontrols-example-tableview.png b/src/controls/doc/images/qtquickcontrols-example-tableview.png index b9dc67c317a8f071841bbc5a6ffa78b997854723..c4ab8d9973ca1a9de080446f33e19c142e48d34a 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 5ff2b27be609b34cf8aa10ca2c895dd50fa8ad8a..29c8d2b55241eedaec8a5e1dc46473e3ec031b71 100644 --- a/src/controls/doc/src/qtquickcontrols-examples.qdoc +++ b/src/controls/doc/src/qtquickcontrols-examples.qdoc @@ -77,20 +77,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 @@ -98,10 +84,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 <QtQml/qqml.h> + ... + qmlRegisterType<SortFilterProxyModel>("org.qtproject.example", 1, 0, "SortFilterProxyModel"); + ... + \endcode + + QML namespace import: + + \qml + import org.qtproject.example 1.0 + \endqml + + For more information about registering C++ classses as QML types, see + \l {Defining QML Types from C++}. \include examples-run.qdocinc */ diff --git a/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc b/src/controls/doc/src/qtquickcontrols-platformnotes.qdoc index 092dc45d2fbbb7d377951f63347a1929f1bf7b8a..2d8524454c7d28c5ca24e6affc46ef5afc3c7e1d 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 */ diff --git a/tests/auto/controls/data/tst_slider.qml b/tests/auto/controls/data/tst_slider.qml index 2b3a00a53ffff783b89eceafdd776d94a0bc9afa..2541b1c583cc8f7cd98a2e6e9ee1d853da0e03fd 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() + } } } diff --git a/tests/manual/workshop/content/AboutDialog.qml b/tests/manual/workshop/content/AboutDialog.qml new file mode 100644 index 0000000000000000000000000000000000000000..c4d87ee03e5b6dda9c50599482bda12eb5ab218b --- /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 0000000000000000000000000000000000000000..1abd57e4cbf9c00f96fff9eb64985f211b1facfb --- /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/examples/quick/controls/splitview/main.qml b/tests/manual/workshop/content/ImageViewer.qml similarity index 71% rename from examples/quick/controls/splitview/main.qml rename to tests/manual/workshop/content/ImageViewer.qml index 8707b6cc868144e9452180cca97afd60c591ce22..26d2da173cf5506944647302f596650816115634 100644 --- a/examples/quick/controls/splitview/main.qml +++ b/tests/manual/workshop/content/ImageViewer.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,45 +38,22 @@ ** ****************************************************************************/ - - - - 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" - } - } +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 0000000000000000000000000000000000000000..eb9f720d384f294fba35641771c3280793b4f2d4 --- /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 0000000000000000000000000000000000000000..d490e2b5e589df5182ba7646511047b44c99d07a --- /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 0000000000000000000000000000000000000000..62aa1efe54c76991fdaea3a103d362bcc635e5c6 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 0000000000000000000000000000000000000000..d64cdaa7876296e8ff5fe0953c5f364a0a6be118 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 0000000000000000000000000000000000000000..8ab41cc804991d9da9d2c0dd2140579b8a405cf7 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 0000000000000000000000000000000000000000..f35f2583540678b7a544d9175245096082f302af 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 0000000000000000000000000000000000000000..9fdbb6657744a38310d3fa4ab8b7558e5966987e 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 0000000000000000000000000000000000000000..5c9f6b343bdff4e1295342362486b2cc37387ecb 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 0000000000000000000000000000000000000000..a15e34c924abc6f343e2a3ff35368035930488d6 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 0000000000000000000000000000000000000000..8d8bb9bd768d8e8ab785d95483ead02ae6800dc5 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 0000000000000000000000000000000000000000..a68e2db77531cb15a2cddd62f567f030513b60fa 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 0000000000000000000000000000000000000000..c37bc0414c24b6e4f34096d0c0f20fbe0bf84045 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 0000000000000000000000000000000000000000..6e52db7cfd482e228dae640a7717ea1dcaf523e8 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 0000000000000000000000000000000000000000..e7a8d1722f328be5fa649f774e2fa6bcf049ebef 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 0000000000000000000000000000000000000000..55a069dfce0cba716f426a78c04346cadb60cfad 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 0000000000000000000000000000000000000000..b588c9586d9c9ba0d07966f448c19e23320bf6e3 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 0000000000000000000000000000000000000000..ac4d4a0d981cf7257756d5ecd7951154b70b87d5 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 0000000000000000000000000000000000000000..74fefab78a719e4883756d2bcc1b968835dd4fa0 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 0000000000000000000000000000000000000000..665400ccfd2da9264fa4cf0e653e2573a8f7daf7 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 0000000000000000000000000000000000000000..1d4a38ab38bea53d34f71c84e4f88669b99f3447 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 0000000000000000000000000000000000000000..4dc6a8cee217d45990972ff43f27d06c6a851b61 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 0000000000000000000000000000000000000000..606ea9eba46b82eea04678e64369b97e595f9da5 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 0000000000000000000000000000000000000000..36503018ef4157fa20f6cfdaf9fb851137384c53 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 0000000000000000000000000000000000000000..723a8886b1eea48a4644b89b7d3496cff0b10e2f --- /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/examples/quick/controls/splitview/src/main.cpp b/tests/manual/workshop/src/main.cpp similarity index 82% rename from examples/quick/controls/splitview/src/main.cpp rename to tests/manual/workshop/src/main.cpp index a757f4853bfbf9bcd6469529cfbc00854b38de47..d8b3665ca4eb5eb1f2687d57b37b7171ccc1566f 100644 --- a/examples/quick/controls/splitview/src/main.cpp +++ b/tests/manual/workshop/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. @@ -38,12 +38,20 @@ ** ****************************************************************************/ -#include "qtquickcontrolsapplication.h" +#include "qt_quick_controls_testapp.h" #include <QtQml/QQmlApplicationEngine> +#include <QtGui/QSurfaceFormat> +#include <QtQuick/QQuickWindow> int main(int argc, char *argv[]) { - QtQuickControlsApplication app(argc, 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/examples/quick/controls/splitview/src/src.pri b/tests/manual/workshop/src/src.pri similarity index 100% rename from examples/quick/controls/splitview/src/src.pri rename to tests/manual/workshop/src/src.pri diff --git a/tests/manual/workshop/workshop.pro b/tests/manual/workshop/workshop.pro new file mode 100644 index 0000000000000000000000000000000000000000..c3abc14ce6cde1eb980f62df140955446f23cf1e --- /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 0000000000000000000000000000000000000000..57d803b228cbc26d75cd031e184cad5481025899 --- /dev/null +++ b/tests/manual/workshop/workshop.qrc @@ -0,0 +1,24 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + <file>content/AboutDialog.qml</file> + <file>content/Controls.qml</file> + <file>content/ImageViewer.qml</file> + <file>content/ModelView.qml</file> + <file>content/Styles.qml</file> + <file>images/document-open.png</file> + <file>images/document-open@2x.png</file> + <file>images/document-save-as.png</file> + <file>images/document-save-as@2x.png</file> + <file>images/folder_new.png</file> + <file>images/tab.png</file> + <file>images/tab_selected.png</file> + <file>images/bubble.png</file> + <file>images/button-pressed.png</file> + <file>images/button.png</file> + <file>images/progress-background.png</file> + <file>images/progress-fill.png</file> + <file>images/textfield.png</file> + <file>images/slider-handle.png</file> + </qresource> +</RCC> diff --git a/tests/shared/qt_quick_controls_quicktest.h b/tests/shared/qt_quick_controls_quicktest.h index 67dffa92a1c739a57de31d96c37be46a97836fec..cbbd5a25898e6ff769af11aa01c07b2ec1447d5a 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 <QtQuickTest/quicktestglobal.h> -#ifdef QT_WIDGETS_LIB -#include <QtWidgets/QApplication> -#else -#include <QtGui/QGuiApplication> -#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 0000000000000000000000000000000000000000..a57a4c5be6c9c2a2b3dd1189fa891c2985f6f0cc --- /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 <QtWidgets/QApplication> +#else +#include <QtGui/QGuiApplication> +#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