diff options
Diffstat (limited to 'examples')
75 files changed, 2814 insertions, 296 deletions
diff --git a/examples/quickcontrols2/chattutorial/chapter1-settingup/main.qml b/examples/quickcontrols2/chattutorial/chapter1-settingup/main.qml index ff65c53c..4fc97a49 100644 --- a/examples/quickcontrols2/chattutorial/chapter1-settingup/main.qml +++ b/examples/quickcontrols2/chattutorial/chapter1-settingup/main.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ApplicationWindow { width: 540 diff --git a/examples/quickcontrols2/chattutorial/chapter2-lists/main.qml b/examples/quickcontrols2/chattutorial/chapter2-lists/main.qml index a8d9f478..3a1d4cc9 100644 --- a/examples/quickcontrols2/chattutorial/chapter2-lists/main.qml +++ b/examples/quickcontrols2/chattutorial/chapter2-lists/main.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ApplicationWindow { width: 540 diff --git a/examples/quickcontrols2/chattutorial/chapter3-navigation/ContactPage.qml b/examples/quickcontrols2/chattutorial/chapter3-navigation/ContactPage.qml index 8beb689f..e45e5b61 100644 --- a/examples/quickcontrols2/chattutorial/chapter3-navigation/ContactPage.qml +++ b/examples/quickcontrols2/chattutorial/chapter3-navigation/ContactPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 Page { id: root diff --git a/examples/quickcontrols2/chattutorial/chapter3-navigation/ConversationPage.qml b/examples/quickcontrols2/chattutorial/chapter3-navigation/ConversationPage.qml index 9590669a..0e0e07fb 100644 --- a/examples/quickcontrols2/chattutorial/chapter3-navigation/ConversationPage.qml +++ b/examples/quickcontrols2/chattutorial/chapter3-navigation/ConversationPage.qml @@ -40,7 +40,7 @@ import QtQuick 2.6 import QtQuick.Layouts 1.3 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 Page { id: root diff --git a/examples/quickcontrols2/chattutorial/chapter3-navigation/main.qml b/examples/quickcontrols2/chattutorial/chapter3-navigation/main.qml index 5bc9e95d..25d50fb7 100644 --- a/examples/quickcontrols2/chattutorial/chapter3-navigation/main.qml +++ b/examples/quickcontrols2/chattutorial/chapter3-navigation/main.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ApplicationWindow { id: window diff --git a/examples/quickcontrols2/chattutorial/chapter4-models/ContactPage.qml b/examples/quickcontrols2/chattutorial/chapter4-models/ContactPage.qml index a6491495..4a914b32 100644 --- a/examples/quickcontrols2/chattutorial/chapter4-models/ContactPage.qml +++ b/examples/quickcontrols2/chattutorial/chapter4-models/ContactPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 import io.qt.examples.chattutorial 1.0 diff --git a/examples/quickcontrols2/chattutorial/chapter4-models/ConversationPage.qml b/examples/quickcontrols2/chattutorial/chapter4-models/ConversationPage.qml index 5c91a206..183d5a32 100644 --- a/examples/quickcontrols2/chattutorial/chapter4-models/ConversationPage.qml +++ b/examples/quickcontrols2/chattutorial/chapter4-models/ConversationPage.qml @@ -40,7 +40,7 @@ import QtQuick 2.6 import QtQuick.Layouts 1.3 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 import io.qt.examples.chattutorial 1.0 diff --git a/examples/quickcontrols2/chattutorial/chapter4-models/chapter4-models.pro b/examples/quickcontrols2/chattutorial/chapter4-models/chapter4-models.pro index d62eacc0..75d37ca3 100644 --- a/examples/quickcontrols2/chattutorial/chapter4-models/chapter4-models.pro +++ b/examples/quickcontrols2/chattutorial/chapter4-models/chapter4-models.pro @@ -3,7 +3,7 @@ TEMPLATE = app QT += qml quick sql CONFIG += c++11 -!contains(sql-drivers, sqlite): QTPLUGIN += qsqlite +!qtConfig(sql-sqlite): QTPLUGIN += qsqlite HEADERS += sqlcontactmodel.h \ sqlconversationmodel.h diff --git a/examples/quickcontrols2/chattutorial/chapter4-models/main.qml b/examples/quickcontrols2/chattutorial/chapter4-models/main.qml index 5bc9e95d..25d50fb7 100644 --- a/examples/quickcontrols2/chattutorial/chapter4-models/main.qml +++ b/examples/quickcontrols2/chattutorial/chapter4-models/main.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ApplicationWindow { id: window diff --git a/examples/quickcontrols2/chattutorial/chapter5-styling/+material/ChatToolBar.qml b/examples/quickcontrols2/chattutorial/chapter5-styling/+material/ChatToolBar.qml index b0f42969..0557de7f 100644 --- a/examples/quickcontrols2/chattutorial/chapter5-styling/+material/ChatToolBar.qml +++ b/examples/quickcontrols2/chattutorial/chapter5-styling/+material/ChatToolBar.qml @@ -38,8 +38,8 @@ ** ****************************************************************************/ -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 +import QtQuick.Controls 2.1 +import QtQuick.Controls.Material 2.1 ToolBar { Material.theme: Material.Dark diff --git a/examples/quickcontrols2/chattutorial/chapter5-styling/ChatToolBar.qml b/examples/quickcontrols2/chattutorial/chapter5-styling/ChatToolBar.qml index e400e029..072ae241 100644 --- a/examples/quickcontrols2/chattutorial/chapter5-styling/ChatToolBar.qml +++ b/examples/quickcontrols2/chattutorial/chapter5-styling/ChatToolBar.qml @@ -38,7 +38,7 @@ ** ****************************************************************************/ -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ToolBar { } diff --git a/examples/quickcontrols2/chattutorial/chapter5-styling/ContactPage.qml b/examples/quickcontrols2/chattutorial/chapter5-styling/ContactPage.qml index b94ef0b3..9afc2d8c 100644 --- a/examples/quickcontrols2/chattutorial/chapter5-styling/ContactPage.qml +++ b/examples/quickcontrols2/chattutorial/chapter5-styling/ContactPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 import io.qt.examples.chattutorial 1.0 diff --git a/examples/quickcontrols2/chattutorial/chapter5-styling/ConversationPage.qml b/examples/quickcontrols2/chattutorial/chapter5-styling/ConversationPage.qml index afe8b572..a217bc0a 100644 --- a/examples/quickcontrols2/chattutorial/chapter5-styling/ConversationPage.qml +++ b/examples/quickcontrols2/chattutorial/chapter5-styling/ConversationPage.qml @@ -40,7 +40,7 @@ import QtQuick 2.6 import QtQuick.Layouts 1.3 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 import io.qt.examples.chattutorial 1.0 diff --git a/examples/quickcontrols2/chattutorial/chapter5-styling/chapter5-styling.pro b/examples/quickcontrols2/chattutorial/chapter5-styling/chapter5-styling.pro index 2b15b72d..007d23b3 100644 --- a/examples/quickcontrols2/chattutorial/chapter5-styling/chapter5-styling.pro +++ b/examples/quickcontrols2/chattutorial/chapter5-styling/chapter5-styling.pro @@ -3,7 +3,7 @@ TEMPLATE = app QT += qml quick sql CONFIG += c++11 -!contains(sql-drivers, sqlite): QTPLUGIN += qsqlite +!qtConfig(sql-sqlite): QTPLUGIN += qsqlite HEADERS += sqlcontactmodel.h \ sqlconversationmodel.h diff --git a/examples/quickcontrols2/chattutorial/chapter5-styling/main.qml b/examples/quickcontrols2/chattutorial/chapter5-styling/main.qml index 5bc9e95d..25d50fb7 100644 --- a/examples/quickcontrols2/chattutorial/chapter5-styling/main.qml +++ b/examples/quickcontrols2/chattutorial/chapter5-styling/main.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ApplicationWindow { id: window diff --git a/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc b/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc index afdac5a3..5c80587d 100644 --- a/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc +++ b/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc @@ -82,7 +82,7 @@ Once we've set up things in C++, we can move on to the user interface in QML. \quotefromfile chattutorial/chapter1-settingup/main.qml \skipto import -\printuntil import QtQuick.Controls 2.0 +\printuntil import QtQuick.Controls 2.1 First, we import the \l {Qt Quick} module. This gives us access to graphical primitives such as \l Item, \l Rectangle, \l Text, and so @@ -727,7 +727,7 @@ their text color to something lighter. The simplest way of doing so is to import the Material style directly and use the Material attached property: \code - import QtQuick.Controls.Material 2.0 + import QtQuick.Controls.Material 2.1 // ... diff --git a/examples/quickcontrols2/contactlist/ContactDelegate.ui.qml b/examples/quickcontrols2/contactlist/ContactDelegate.ui.qml new file mode 100644 index 00000000..383bb4ec --- /dev/null +++ b/examples/quickcontrols2/contactlist/ContactDelegate.ui.qml @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Layouts 1.0 +import QtQuick.Controls 2.1 + +ItemDelegate { + id: delegate + + checkable: true + + contentItem: ColumnLayout { + spacing: 10 + + Label { + text: fullName + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + } + + GridLayout { + id: grid + visible: false + + columns: 2 + rowSpacing: 10 + columnSpacing: 10 + + Label { + text: qsTr("Address:") + Layout.leftMargin: 60 + } + + Label { + text: address + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + } + + Label { + text: qsTr("City:") + Layout.leftMargin: 60 + } + + Label { + text: city + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + } + + Label { + text: qsTr("Number:") + Layout.leftMargin: 60 + } + + Label { + text: number + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + } + } + } + + states: [ + State { + name: "expanded" + when: delegate.checked + + PropertyChanges { + target: grid + visible: true + } + } + ] +} diff --git a/examples/quickcontrols2/contactlist/ContactDialog.qml b/examples/quickcontrols2/contactlist/ContactDialog.qml new file mode 100644 index 00000000..54256e47 --- /dev/null +++ b/examples/quickcontrols2/contactlist/ContactDialog.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Controls 2.1 + +Dialog { + id: dialog + + signal finished(string fullName, string address, string city, string number) + + function createContact() { + form.fullName.clear(); + form.address.clear(); + form.city.clear(); + form.number.clear(); + + dialog.title = qsTr("Add Contact"); + dialog.open(); + } + + function editContact(contact) { + form.fullName.text = contact.fullName; + form.address.text = contact.address; + form.city.text = contact.city; + form.number.text = contact.number; + + dialog.title = qsTr("Edit Contact"); + dialog.open(); + } + + x: parent.width / 2 - width / 2 + y: parent.height / 2 - height / 2 + + focus: true + modal: true + title: qsTr("Add Contact") + standardButtons: Dialog.Ok | Dialog.Cancel + + contentItem: ContactForm { + id: form + } + + onAccepted: finished(form.fullName.text, form.address.text, form.city.text, form.number.text) +} diff --git a/examples/quickcontrols2/contactlist/ContactForm.ui.qml b/examples/quickcontrols2/contactlist/ContactForm.ui.qml new file mode 100644 index 00000000..f3397bb0 --- /dev/null +++ b/examples/quickcontrols2/contactlist/ContactForm.ui.qml @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Layouts 1.0 +import QtQuick.Controls 2.1 + +GridLayout { + id: grid + property alias fullName: fullName + property alias address: address + property alias city: city + property alias number: number + property int minimumInputSize: 120 + property string placeholderText: qsTr("<enter>") + + rows: 4 + columns: 2 + + Label { + text: qsTr("Full Name") + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + } + + TextField { + id: fullName + focus: true + Layout.fillWidth: true + Layout.minimumWidth: grid.minimumInputSize + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + placeholderText: grid.placeholderText + } + + Label { + text: qsTr("Address") + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + } + + TextField { + id: address + Layout.fillWidth: true + Layout.minimumWidth: grid.minimumInputSize + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + placeholderText: grid.placeholderText + } + + Label { + text: qsTr("City") + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + } + + TextField { + id: city + Layout.fillWidth: true + Layout.minimumWidth: grid.minimumInputSize + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + placeholderText: grid.placeholderText + } + + Label { + text: qsTr("Number") + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + } + + TextField { + id: number + Layout.fillWidth: true + Layout.minimumWidth: grid.minimumInputSize + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + placeholderText: grid.placeholderText + } +} diff --git a/examples/quickcontrols2/contactlist/ContactView.ui.qml b/examples/quickcontrols2/contactlist/ContactView.ui.qml new file mode 100644 index 00000000..2aaaa31d --- /dev/null +++ b/examples/quickcontrols2/contactlist/ContactView.ui.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Controls 2.1 +import Backend 1.0 + +ListView { + id: listView + + signal pressAndHold(int index) + + width: 320 + height: 480 + + focus: true + boundsBehavior: Flickable.StopAtBounds + + section.property: "fullName" + section.criteria: ViewSection.FirstCharacter + section.delegate: SectionDelegate { + width: listView.width + } + + delegate: ContactDelegate { + id: delegate + width: listView.width + + Connections { + target: delegate + onPressAndHold: listView.pressAndHold(index) + } + } + + model: ContactModel { + id: contactModel + } + + ScrollBar.vertical: ScrollBar { } +} diff --git a/examples/quickcontrols2/gallery/pages/MenuPage.qml b/examples/quickcontrols2/contactlist/SectionDelegate.ui.qml index 1e975bd0..fa64ffbf 100644 --- a/examples/quickcontrols2/gallery/pages/MenuPage.qml +++ b/examples/quickcontrols2/contactlist/SectionDelegate.ui.qml @@ -1,12 +1,22 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are @@ -38,30 +48,17 @@ ** ****************************************************************************/ -import QtQuick 2.6 -import QtQuick.Controls 2.0 - -ScrollablePage { - id: page - - Column { - spacing: 40 - width: parent.width - - Label { - width: parent.width - wrapMode: Label.Wrap - horizontalAlignment: Qt.AlignHCenter - text: "Menu can be used either as a context menu, or as a popup menu." - } +import QtQuick 2.7 +import QtQuick.Controls 2.1 - Button { - id: button - text: "Open" - anchors.horizontalCenter: parent.horizontalCenter - width: Math.max(implicitWidth, Math.min(implicitWidth * 2, page.availableWidth / 3)) +ToolBar { + id: background - onClicked: optionsMenu.open() - } + Label { + id: label + text: section + anchors.fill: parent + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter } } diff --git a/examples/quickcontrols2/contactlist/contactlist.pro b/examples/quickcontrols2/contactlist/contactlist.pro new file mode 100644 index 00000000..9025dbde --- /dev/null +++ b/examples/quickcontrols2/contactlist/contactlist.pro @@ -0,0 +1,22 @@ +TEMPLATE = app +TARGET = contactlist +QT += quick + +HEADERS += \ + contactmodel.h + +SOURCES += \ + main.cpp \ + contactmodel.cpp + +RESOURCES += \ + $$files(*.qml) + +# Additional import path used to resolve QML modules just for Qt Quick Designer +QML_DESIGNER_IMPORT_PATH = $$PWD/designer + +OTHER_FILES += \ + designer/Backend/*.qml + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/contactlist +INSTALLS += target diff --git a/examples/quickcontrols2/contactlist/contactlist.qml b/examples/quickcontrols2/contactlist/contactlist.qml new file mode 100644 index 00000000..13406fbe --- /dev/null +++ b/examples/quickcontrols2/contactlist/contactlist.qml @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Controls 2.1 + +ApplicationWindow { + id: window + + property int currentContact: -1 + + width: 320 + height: 480 + visible: true + title: qsTr("Contact List") + + ContactDialog { + id: contactDialog + onFinished: { + if (currentContact === -1) + contactView.model.append(fullName, address, city, number) + else + contactView.model.set(currentContact, fullName, address, city, number) + } + } + + Menu { + id: contactMenu + x: parent.width / 2 - width / 2 + y: parent.height / 2 - height / 2 + modal: true + + Label { + padding: 10 + font.bold: true + width: parent.width + horizontalAlignment: Qt.AlignHCenter + text: currentContact >= 0 ? contactView.model.get(currentContact).fullName : "" + } + MenuItem { + text: qsTr("Edit...") + onTriggered: contactDialog.editContact(contactView.model.get(currentContact)) + } + MenuItem { + text: qsTr("Remove") + onTriggered: contactView.model.remove(currentContact) + } + } + + ContactView { + id: contactView + anchors.fill: parent + onPressAndHold: { + currentContact = index + contactMenu.open() + } + } + + RoundButton { + text: qsTr("+") + highlighted: true + anchors.margins: 10 + anchors.right: parent.right + anchors.bottom: parent.bottom + onClicked: { + currentContact = -1 + contactDialog.createContact() + } + } +} diff --git a/examples/quickcontrols2/contactlist/contactmodel.cpp b/examples/quickcontrols2/contactlist/contactmodel.cpp new file mode 100644 index 00000000..308da2da --- /dev/null +++ b/examples/quickcontrols2/contactlist/contactmodel.cpp @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "contactmodel.h" + +ContactModel::ContactModel(QObject *parent ) : QAbstractListModel(parent) +{ + m_contacts.append({ "Angel Hogan", "Chapel St. 368 ", "Clearwater" , "0311 1823993" }); + m_contacts.append({ "Felicia Patton", "Annadale Lane 2", "Knoxville" , "0368 1244494" }); + m_contacts.append({ "Grant Crawford", "Windsor Drive 34", "Riverdale" , "0351 7826892" }); + m_contacts.append({ "Gretchen Little", "Sunset Drive 348", "Virginia Beach" , "0343 1234991" }); + m_contacts.append({ "Geoffrey Richards", "University Lane 54", "Trussville" , "0423 2144944" }); + m_contacts.append({ "Henrietta Chavez", "Via Volto San Luca 3", "Piobesi Torinese" , "0399 2826994" }); + m_contacts.append({ "Harvey Chandler", "North Squaw Creek 11", "Madisonville" , "0343 1244492" }); + m_contacts.append({ "Miguel Gomez", "Wild Rose Street 13", "Trussville" , "0343 9826996" }); + m_contacts.append({ "Norma Rodriguez", " Glen Eagles Street 53", "Buffalo" , "0241 5826596" }); + m_contacts.append({ "Shelia Ramirez", "East Miller Ave 68", "Pickerington" , "0346 4844556" }); + m_contacts.append({ "Stephanie Moss", "Piazza Trieste e Trento 77", "Roata Chiusani" , "0363 0510490" }); +} + +int ContactModel::rowCount(const QModelIndex &) const +{ + return m_contacts.count(); +} + +QVariant ContactModel::data(const QModelIndex &index, int role) const +{ + if (index.row() < rowCount()) + switch (role) { + case FullNameRole: return m_contacts.at(index.row()).fullName; + case AddressRole: return m_contacts.at(index.row()).address; + case CityRole: return m_contacts.at(index.row()).city; + case NumberRole: return m_contacts.at(index.row()).number; + default: return QVariant(); + } + return QVariant(); +} + +QHash<int, QByteArray> ContactModel::roleNames() const +{ + static const QHash<int, QByteArray> roles { + { FullNameRole, "fullName" }, + { AddressRole, "address" }, + { CityRole, "city" }, + { NumberRole, "number" } + }; + return roles; +} + +QVariantMap ContactModel::get(int row) const +{ + const Contact contact = m_contacts.value(row); + return { {"fullName", contact.fullName}, {"address", contact.address}, {"city", contact.city}, {"number", contact.number} }; +} + +void ContactModel::append(const QString &fullName, const QString &address, const QString &city, const QString &number) +{ + int row = 0; + while (row < m_contacts.count() && fullName > m_contacts.at(row).fullName) + ++row; + beginInsertRows(QModelIndex(), row, row); + m_contacts.insert(row, {fullName, address, city, number}); + endInsertRows(); +} + +void ContactModel::set(int row, const QString &fullName, const QString &address, const QString &city, const QString &number) +{ + if (row < 0 || row >= m_contacts.count()) + return; + + m_contacts.replace(row, { fullName, address, city, number }); + dataChanged(index(row, 0), index(row, 0), { FullNameRole, AddressRole, CityRole, NumberRole }); +} + +void ContactModel::remove(int row) +{ + if (row < 0 || row >= m_contacts.count()) + return; + + beginRemoveRows(QModelIndex(), row, row); + m_contacts.removeAt(row); + endRemoveRows(); +} diff --git a/examples/quickcontrols2/contactlist/contactmodel.h b/examples/quickcontrols2/contactlist/contactmodel.h new file mode 100644 index 00000000..d09602c4 --- /dev/null +++ b/examples/quickcontrols2/contactlist/contactmodel.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CONTACTMODEL_H +#define CONTACTMODEL_H + +#include <QAbstractListModel> + +class ContactModel : public QAbstractListModel +{ + Q_OBJECT + +public: + enum ContactRole { + FullNameRole = Qt::DisplayRole, + AddressRole = Qt::UserRole, + CityRole, + NumberRole + }; + Q_ENUM(ContactRole) + + ContactModel(QObject *parent = nullptr); + + int rowCount(const QModelIndex & = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QHash<int, QByteArray> roleNames() const; + + Q_INVOKABLE QVariantMap get(int row) const; + Q_INVOKABLE void append(const QString &fullName, const QString &address, const QString &city, const QString &number); + Q_INVOKABLE void set(int row, const QString &fullName, const QString &address, const QString &city, const QString &number); + Q_INVOKABLE void remove(int row); + +private: + struct Contact { + QString fullName; + QString address; + QString city; + QString number; + }; + + QList<Contact> m_contacts; +}; + +#endif // CONTACTMODEL_H diff --git a/examples/quickcontrols2/contactlist/designer/Backend/ContactModel.qml b/examples/quickcontrols2/contactlist/designer/Backend/ContactModel.qml new file mode 100644 index 00000000..b9570934 --- /dev/null +++ b/examples/quickcontrols2/contactlist/designer/Backend/ContactModel.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 + +ListModel { + ListElement { + address: "Chapel St. 368" + city: "Knoxville" + number: "0311 1823993" + fullName: "Angel Hogan" + } + + ListElement { + address: "Annadale Lane 2" + city: "Clearwater" + number: "0368 1244494" + fullName: "Felicia Patton" + } + + ListElement { + address: "Windsor Drive 34" + city: "Riverdale" + number: "0368 1244494" + fullName: "Grant Crawford" + } + + ListElement { + address: "Sunset Drive 348" + city: "Virginia Beach" + number: "0351 7826892" + fullName: "Gretchen Little" + } + + ListElement { + address: "University Lane 54" + city: "Trussville" + number: "0399 2826994" + fullName: "Geoffrey Richards" + } +} diff --git a/examples/quickcontrols2/contactlist/designer/Backend/qmldir b/examples/quickcontrols2/contactlist/designer/Backend/qmldir new file mode 100644 index 00000000..8e2037d4 --- /dev/null +++ b/examples/quickcontrols2/contactlist/designer/Backend/qmldir @@ -0,0 +1,2 @@ +module Backend +ContactModel 1.0 ContactModel.qml diff --git a/examples/quickcontrols2/contactlist/doc/images/qtquickcontrols2-contactlist.png b/examples/quickcontrols2/contactlist/doc/images/qtquickcontrols2-contactlist.png Binary files differnew file mode 100644 index 00000000..d7424ed3 --- /dev/null +++ b/examples/quickcontrols2/contactlist/doc/images/qtquickcontrols2-contactlist.png diff --git a/examples/quickcontrols2/contactlist/doc/src/qtquickcontrols2-contactlist.qdoc b/examples/quickcontrols2/contactlist/doc/src/qtquickcontrols2-contactlist.qdoc new file mode 100644 index 00000000..17e1aec2 --- /dev/null +++ b/examples/quickcontrols2/contactlist/doc/src/qtquickcontrols2-contactlist.qdoc @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ +/*! + \example contactlist + \title Qt Quick Controls 2 - Contact List + \ingroup qtquickcontrols2-examples + \brief A QML app using Qt Quick Controls 2 and a C++ class that implements + a simple contact list. + + The \e {Contact List Example} shows how to integrate a C++ backend in a way that + is compatible with Qt Quick Designer. + For the declarative parts of the UI, .ui.qml files are used that can be edited + visually in the Qt Quick Designer. + + \image qtquickcontrols2-contactlist.png + + \section1 C++ Backend + + The contact list application allows the user to add, edit, and remove contacts. + The actual implementation is done in C++ and exposed as a QAbstractListModel. + + The ContactModel C++ class is registered under a namespace and later + imported and instantiated by \e MainForm.ui.qml. For more information about registering C++ + classes as QML types, see \l {Defining QML Types from C++}. + + \code + #include <QtQml/qqml.h> + ... + qmlRegisterType<ContactModel>("Backend", 1, 0, "ContactModel"); + ... + \endcode + + \section1 Designer Support + + In the designer subdirectory, we create a plugin that replaces the ContactModel + in Qt Quick Designer. For this to work we add the following line to \e contactlist.pro. + + \code + QML_DESIGNER_IMPORT_PATH = $$PWD/designer + \endcode + + Because Qt Quick Designer cannot instantiate the ContactModel C++ class, we define + a mockup using a ListModel. This ensures that the ListView using the model shows something + in Qt Quick Designer. + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols2/gallery/pages/DrawerPage.qml b/examples/quickcontrols2/contactlist/main.cpp index f4a7d272..ccad6ff3 100644 --- a/examples/quickcontrols2/gallery/pages/DrawerPage.qml +++ b/examples/quickcontrols2/contactlist/main.cpp @@ -1,12 +1,22 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are @@ -38,36 +48,19 @@ ** ****************************************************************************/ -import QtQuick 2.6 -import QtQuick.Controls 2.0 - -Pane { - id: pane +#include <QGuiApplication> +#include <QQmlApplicationEngine> - Column { - spacing: 40 - width: parent.width +#include "contactmodel.h" - Label { - width: parent.width - wrapMode: Label.Wrap - horizontalAlignment: Qt.AlignHCenter - text: "Drawer provides a swipe-based side panel, similar to those often used " - + "in touch interfaces to provide a central location for navigation." - } +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); - Button { - text: "Open" - anchors.horizontalCenter: parent.horizontalCenter - width: Math.max(implicitWidth, Math.min(implicitWidth * 2, pane.availableWidth / 3)) + qmlRegisterType<ContactModel>("Backend", 1, 0, "ContactModel"); - onClicked: drawer.open() - } - } + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/contactlist.qml"))); - Image { - source: "qrc:/images/arrow.png" - anchors.left: parent.left - anchors.bottom: parent.bottom - } + return app.exec(); } diff --git a/examples/quickcontrols2/gallery/gallery.pro b/examples/quickcontrols2/gallery/gallery.pro index cb0736fd..45496a35 100644 --- a/examples/quickcontrols2/gallery/gallery.pro +++ b/examples/quickcontrols2/gallery/gallery.pro @@ -5,12 +5,12 @@ QT += quick quickcontrols2 SOURCES += \ gallery.cpp -OTHER_FILES += \ - gallery.qml \ - pages/*.qml - RESOURCES += \ - gallery.qrc + gallery.qml \ + qtquickcontrols2.conf \ + $$files(images/*.png) \ + $$files(images/+material/*.png) \ + $$files(pages/*.qml) target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/gallery INSTALLS += target diff --git a/examples/quickcontrols2/gallery/gallery.qml b/examples/quickcontrols2/gallery/gallery.qml index aadbcdec..97985a6d 100644 --- a/examples/quickcontrols2/gallery/gallery.qml +++ b/examples/quickcontrols2/gallery/gallery.qml @@ -40,9 +40,9 @@ import QtQuick 2.6 import QtQuick.Layouts 1.3 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Universal 2.0 +import QtQuick.Controls 2.1 +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Universal 2.1 import Qt.labs.settings 1.0 ApplicationWindow { @@ -105,7 +105,7 @@ ApplicationWindow { fillMode: Image.Pad horizontalAlignment: Image.AlignHCenter verticalAlignment: Image.AlignVCenter - source: "qrc:/images/menu.png" + source: "images/menu.png" } onClicked: optionsMenu.open() @@ -116,7 +116,7 @@ ApplicationWindow { MenuItem { text: "Settings" - onTriggered: settingsPopup.open() + onTriggered: settingsDialog.open() } MenuItem { text: "About" @@ -157,13 +157,11 @@ ApplicationWindow { ListElement { title: "CheckBox"; source: "qrc:/pages/CheckBoxPage.qml" } ListElement { title: "ComboBox"; source: "qrc:/pages/ComboBoxPage.qml" } ListElement { title: "Dial"; source: "qrc:/pages/DialPage.qml" } + ListElement { title: "Dialog"; source: "qrc:/pages/DialogPage.qml" } ListElement { title: "Delegates"; source: "qrc:/pages/DelegatePage.qml" } - ListElement { title: "Drawer"; source: "qrc:/pages/DrawerPage.qml" } ListElement { title: "Frame"; source: "qrc:/pages/FramePage.qml" } ListElement { title: "GroupBox"; source: "qrc:/pages/GroupBoxPage.qml" } - ListElement { title: "Menu"; source: "qrc:/pages/MenuPage.qml" } ListElement { title: "PageIndicator"; source: "qrc:/pages/PageIndicatorPage.qml" } - ListElement { title: "Popup"; source: "qrc:/pages/PopupPage.qml" } ListElement { title: "ProgressBar"; source: "qrc:/pages/ProgressBarPage.qml" } ListElement { title: "RadioButton"; source: "qrc:/pages/RadioButtonPage.qml" } ListElement { title: "RangeSlider"; source: "qrc:/pages/RangeSliderPage.qml" } @@ -199,7 +197,7 @@ ApplicationWindow { anchors.centerIn: parent anchors.verticalCenterOffset: -50 fillMode: Image.PreserveAspectFit - source: "qrc:/images/qt-logo.png" + source: "images/qt-logo.png" } Label { @@ -216,31 +214,36 @@ ApplicationWindow { Image { id: arrow - source: "qrc:/images/arrow.png" + source: "images/arrow.png" anchors.left: parent.left anchors.bottom: parent.bottom } } } - Popup { - id: settingsPopup - x: (window.width - width) / 2 - y: window.height / 6 - width: Math.min(window.width, window.height) / 3 * 2 - height: settingsColumn.implicitHeight + topPadding + bottomPadding + Dialog { + id: settingsDialog + x: Math.round((window.width - width) / 2) + y: Math.round(window.height / 6) + width: Math.round(Math.min(window.width, window.height) / 3 * 2) modal: true focus: true + title: "Settings" + + standardButtons: Dialog.Ok | Dialog.Cancel + onAccepted: { + settings.style = styleBox.displayText + settingsDialog.close() + } + onRejected: { + styleBox.currentIndex = styleBox.styleIndex + settingsDialog.close() + } contentItem: ColumnLayout { id: settingsColumn spacing: 20 - Label { - text: "Settings" - font.bold: true - } - RowLayout { spacing: 10 @@ -270,48 +273,14 @@ ApplicationWindow { Layout.fillWidth: true Layout.fillHeight: true } - - RowLayout { - spacing: 10 - - Button { - id: okButton - text: "Ok" - onClicked: { - settings.style = styleBox.displayText - settingsPopup.close() - } - - Material.foreground: Material.primary - Material.background: "transparent" - Material.elevation: 0 - - Layout.preferredWidth: 0 - Layout.fillWidth: true - } - - Button { - id: cancelButton - text: "Cancel" - onClicked: { - styleBox.currentIndex = styleBox.styleIndex - settingsPopup.close() - } - - Material.background: "transparent" - Material.elevation: 0 - - Layout.preferredWidth: 0 - Layout.fillWidth: true - } - } } } - Popup { + Dialog { id: aboutDialog modal: true focus: true + title: "About" x: (window.width - width) / 2 y: window.height / 6 width: Math.min(window.width, window.height) / 3 * 2 @@ -322,11 +291,6 @@ ApplicationWindow { spacing: 20 Label { - text: "About" - font.bold: true - } - - Label { width: aboutDialog.availableWidth text: "The Qt Quick Controls 2 module delivers the next generation user interface controls based on Qt Quick." wrapMode: Label.Wrap diff --git a/examples/quickcontrols2/gallery/gallery.qrc b/examples/quickcontrols2/gallery/gallery.qrc deleted file mode 100644 index 2dc78732..00000000 --- a/examples/quickcontrols2/gallery/gallery.qrc +++ /dev/null @@ -1,70 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>gallery.qml</file> - <file>qtquickcontrols2.conf</file> - <file>images/arrow.png</file> - <file>images/arrow@2x.png</file> - <file>images/arrow@3x.png</file> - <file>images/arrow@4x.png</file> - <file>images/arrows.png</file> - <file>images/arrows@2x.png</file> - <file>images/arrows@3x.png</file> - <file>images/arrows@4x.png</file> - <file>images/back.png</file> - <file>images/back@2x.png</file> - <file>images/back@3x.png</file> - <file>images/back@4x.png</file> - <file>images/drawer.png</file> - <file>images/drawer@2x.png</file> - <file>images/drawer@3x.png</file> - <file>images/drawer@4x.png</file> - <file>images/menu.png</file> - <file>images/menu@2x.png</file> - <file>images/menu@3x.png</file> - <file>images/menu@4x.png</file> - <file>images/+material/back.png</file> - <file>images/+material/back@2x.png</file> - <file>images/+material/back@3x.png</file> - <file>images/+material/back@4x.png</file> - <file>images/+material/drawer.png</file> - <file>images/+material/drawer@2x.png</file> - <file>images/+material/drawer@3x.png</file> - <file>images/+material/drawer@4x.png</file> - <file>images/+material/menu.png</file> - <file>images/+material/menu@2x.png</file> - <file>images/+material/menu@3x.png</file> - <file>images/+material/menu@4x.png</file> - <file>images/qt-logo.png</file> - <file>images/qt-logo@2x.png</file> - <file>images/qt-logo@3x.png</file> - <file>images/qt-logo@4x.png</file> - <file>pages/BusyIndicatorPage.qml</file> - <file>pages/ButtonPage.qml</file> - <file>pages/CheckBoxPage.qml</file> - <file>pages/ComboBoxPage.qml</file> - <file>pages/DialPage.qml</file> - <file>pages/DrawerPage.qml</file> - <file>pages/FramePage.qml</file> - <file>pages/GroupBoxPage.qml</file> - <file>pages/MenuPage.qml</file> - <file>pages/PageIndicatorPage.qml</file> - <file>pages/PopupPage.qml</file> - <file>pages/ProgressBarPage.qml</file> - <file>pages/RadioButtonPage.qml</file> - <file>pages/RangeSliderPage.qml</file> - <file>pages/ScrollablePage.qml</file> - <file>pages/ScrollBarPage.qml</file> - <file>pages/ScrollIndicatorPage.qml</file> - <file>pages/SliderPage.qml</file> - <file>pages/SpinBoxPage.qml</file> - <file>pages/StackViewPage.qml</file> - <file>pages/SwipeViewPage.qml</file> - <file>pages/SwitchPage.qml</file> - <file>pages/TabBarPage.qml</file> - <file>pages/TextAreaPage.qml</file> - <file>pages/TextFieldPage.qml</file> - <file>pages/ToolTipPage.qml</file> - <file>pages/TumblerPage.qml</file> - <file>pages/DelegatePage.qml</file> - </qresource> -</RCC> diff --git a/examples/quickcontrols2/gallery/pages/BusyIndicatorPage.qml b/examples/quickcontrols2/gallery/pages/BusyIndicatorPage.qml index 26950555..403da14e 100644 --- a/examples/quickcontrols2/gallery/pages/BusyIndicatorPage.qml +++ b/examples/quickcontrols2/gallery/pages/BusyIndicatorPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page @@ -57,9 +57,6 @@ ScrollablePage { } BusyIndicator { - readonly property int size: Math.min(page.availableWidth, page.availableHeight) / 5 - width: size - height: size anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/examples/quickcontrols2/gallery/pages/ButtonPage.qml b/examples/quickcontrols2/gallery/pages/ButtonPage.qml index add29e83..39776380 100644 --- a/examples/quickcontrols2/gallery/pages/ButtonPage.qml +++ b/examples/quickcontrols2/gallery/pages/ButtonPage.qml @@ -39,13 +39,12 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page - readonly property int itemWidth: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 2, page.availableWidth / 3)) - Column { spacing: 40 width: parent.width @@ -58,24 +57,24 @@ ScrollablePage { + "Buttons are normally used to perform an action, or to answer a question." } - Column { + ColumnLayout { spacing: 20 anchors.horizontalCenter: parent.horizontalCenter Button { text: "First" - width: itemWidth + Layout.fillWidth: true } Button { id: button text: "Second" - width: itemWidth highlighted: true + Layout.fillWidth: true } Button { text: "Third" enabled: false - width: itemWidth + Layout.fillWidth: true } } } diff --git a/examples/quickcontrols2/gallery/pages/CheckBoxPage.qml b/examples/quickcontrols2/gallery/pages/CheckBoxPage.qml index ee8b14dc..8d48d32d 100644 --- a/examples/quickcontrols2/gallery/pages/CheckBoxPage.qml +++ b/examples/quickcontrols2/gallery/pages/CheckBoxPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page diff --git a/examples/quickcontrols2/gallery/pages/ComboBoxPage.qml b/examples/quickcontrols2/gallery/pages/ComboBoxPage.qml index 66fb10dd..a52fcb67 100644 --- a/examples/quickcontrols2/gallery/pages/ComboBoxPage.qml +++ b/examples/quickcontrols2/gallery/pages/ComboBoxPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page @@ -58,7 +58,6 @@ ScrollablePage { ComboBox { model: ["First", "Second", "Third"] - width: Math.max(implicitWidth, Math.min(implicitWidth * 2, page.availableWidth / 3)) anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/examples/quickcontrols2/gallery/pages/DelegatePage.qml b/examples/quickcontrols2/gallery/pages/DelegatePage.qml index 3d175fd8..525487d1 100644 --- a/examples/quickcontrols2/gallery/pages/DelegatePage.qml +++ b/examples/quickcontrols2/gallery/pages/DelegatePage.qml @@ -40,7 +40,7 @@ import QtQuick 2.6 import QtQuick.Layouts 1.1 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 Pane { padding: 0 @@ -70,17 +70,17 @@ Pane { text: labelText width: parent.width - onClicked: if (swipe.complete) view.model.remove(ourIndex) - Component { id: removeComponent Rectangle { - color: swipeDelegate.swipe.complete && swipeDelegate.pressed ? "#333" : "#444" + color: SwipeDelegate.pressed ? "#333" : "#444" width: parent.width height: parent.height clip: true + SwipeDelegate.onClicked: view.model.remove(ourIndex) + Label { font.pixelSize: swipeDelegate.font.pixelSize text: "Remove" diff --git a/examples/quickcontrols2/gallery/pages/DialPage.qml b/examples/quickcontrols2/gallery/pages/DialPage.qml index 9f07c11e..b60fa032 100644 --- a/examples/quickcontrols2/gallery/pages/DialPage.qml +++ b/examples/quickcontrols2/gallery/pages/DialPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page diff --git a/examples/quickcontrols2/gallery/pages/DialogPage.qml b/examples/quickcontrols2/gallery/pages/DialogPage.qml new file mode 100644 index 00000000..e9a051a3 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/DialogPage.qml @@ -0,0 +1,216 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples 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 The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Layouts 1.0 +import QtQuick.Controls 2.1 + +ScrollablePage { + id: page + + readonly property int buttonWidth: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 2, page.availableWidth / 3)) + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Dialog is a popup that is mostly used for short-term tasks " + + "and brief communications with the user." + } + + Button { + text: "Message" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: messageDialog.open() + + Dialog { + id: messageDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + title: "Message" + + Label { + text: "Lorem ipsum dolor sit amet..." + } + } + } + + Button { + id: button + text: "Confirmation" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: confirmationDialog.open() + + Dialog { + id: confirmationDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + parent: ApplicationWindow.overlay + + modal: true + title: "Confirmation" + standardButtons: Dialog.Yes | Dialog.No + + Column { + spacing: 20 + anchors.fill: parent + Label { + text: "The document has been modified.\nDo you want to save your changes?" + } + CheckBox { + text: "Do not ask again" + anchors.right: parent.right + } + } + } + } + + Button { + text: "Content" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: contentDialog.open() + + Dialog { + id: contentDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: Math.min(page.width, page.height) / 3 * 2 + contentHeight: logo.height * 2 + parent: ApplicationWindow.overlay + + modal: true + title: "Content" + standardButtons: Dialog.Close + + Flickable { + id: flickable + clip: true + anchors.fill: parent + contentHeight: column.height + + Column { + id: column + spacing: 20 + width: parent.width + + Image { + id: logo + width: parent.width / 2 + anchors.horizontalCenter: parent.horizontalCenter + fillMode: Image.PreserveAspectFit + source: "../images/qt-logo.png" + } + + Label { + width: parent.width + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc finibus " + + "in est quis laoreet. Interdum et malesuada fames ac ante ipsum primis " + + "in faucibus. Curabitur eget justo sollicitudin enim faucibus bibendum. " + + "Suspendisse potenti. Vestibulum cursus consequat mauris id sollicitudin. " + + "Duis facilisis hendrerit consectetur. Curabitur sapien tortor, efficitur " + + "id auctor nec, efficitur et nisl. Ut venenatis eros in nunc placerat, " + + "eu aliquam enim suscipit." + wrapMode: Label.Wrap + } + } + + ScrollIndicator.vertical: ScrollIndicator { + parent: contentDialog.contentItem + anchors.top: flickable.top + anchors.bottom: flickable.bottom + anchors.right: parent.right + anchors.rightMargin: -contentDialog.rightPadding + 1 + } + } + } + } + + Button { + text: "Input" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: inputDialog.open() + + Dialog { + id: inputDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + parent: ApplicationWindow.overlay + + focus: true + modal: true + title: "Input" + standardButtons: Dialog.Ok | Dialog.Cancel + + ColumnLayout { + spacing: 20 + anchors.fill: parent + Label { + elide: Label.ElideRight + text: "Please enter the credentials:" + Layout.fillWidth: true + } + TextField { + focus: true + placeholderText: "Username" + Layout.fillWidth: true + } + TextField { + placeholderText: "Password" + echoMode: TextField.PasswordEchoOnEdit + Layout.fillWidth: true + } + } + } + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/FramePage.qml b/examples/quickcontrols2/gallery/pages/FramePage.qml index 51b640c1..b2d24dff 100644 --- a/examples/quickcontrols2/gallery/pages/FramePage.qml +++ b/examples/quickcontrols2/gallery/pages/FramePage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page diff --git a/examples/quickcontrols2/gallery/pages/GroupBoxPage.qml b/examples/quickcontrols2/gallery/pages/GroupBoxPage.qml index b0db5374..c4ceb45d 100644 --- a/examples/quickcontrols2/gallery/pages/GroupBoxPage.qml +++ b/examples/quickcontrols2/gallery/pages/GroupBoxPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page diff --git a/examples/quickcontrols2/gallery/pages/PageIndicatorPage.qml b/examples/quickcontrols2/gallery/pages/PageIndicatorPage.qml index e7f7e251..43982b43 100644 --- a/examples/quickcontrols2/gallery/pages/PageIndicatorPage.qml +++ b/examples/quickcontrols2/gallery/pages/PageIndicatorPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page diff --git a/examples/quickcontrols2/gallery/pages/ProgressBarPage.qml b/examples/quickcontrols2/gallery/pages/ProgressBarPage.qml index 92f26dd0..a2646fd0 100644 --- a/examples/quickcontrols2/gallery/pages/ProgressBarPage.qml +++ b/examples/quickcontrols2/gallery/pages/ProgressBarPage.qml @@ -39,13 +39,11 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page - readonly property int itemWidth: Math.max(bar.implicitWidth, page.availableWidth / 3) - Column { spacing: 40 width: parent.width @@ -61,13 +59,11 @@ ScrollablePage { ProgressBar { id: bar value: 0.5 - width: itemWidth anchors.horizontalCenter: parent.horizontalCenter } ProgressBar { indeterminate: true - width: itemWidth anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/examples/quickcontrols2/gallery/pages/RadioButtonPage.qml b/examples/quickcontrols2/gallery/pages/RadioButtonPage.qml index 0cc1f0bd..452d0425 100644 --- a/examples/quickcontrols2/gallery/pages/RadioButtonPage.qml +++ b/examples/quickcontrols2/gallery/pages/RadioButtonPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page diff --git a/examples/quickcontrols2/gallery/pages/RangeSliderPage.qml b/examples/quickcontrols2/gallery/pages/RangeSliderPage.qml index 62cbeb88..629a788b 100644 --- a/examples/quickcontrols2/gallery/pages/RangeSliderPage.qml +++ b/examples/quickcontrols2/gallery/pages/RangeSliderPage.qml @@ -39,13 +39,11 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page - readonly property int itemWidth: Math.max(slider.implicitWidth, Math.min(slider.implicitWidth * 2, page.availableWidth / 3)) - Column { spacing: 40 width: parent.width @@ -61,7 +59,6 @@ ScrollablePage { id: slider first.value: 0.25 second.value: 0.75 - width: itemWidth anchors.horizontalCenter: parent.horizontalCenter } @@ -69,7 +66,6 @@ ScrollablePage { orientation: Qt.Vertical first.value: 0.25 second.value: 0.75 - height: itemWidth anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/examples/quickcontrols2/gallery/pages/ScrollBarPage.qml b/examples/quickcontrols2/gallery/pages/ScrollBarPage.qml index f8f617d7..17be84e6 100644 --- a/examples/quickcontrols2/gallery/pages/ScrollBarPage.qml +++ b/examples/quickcontrols2/gallery/pages/ScrollBarPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 Flickable { id: flickable @@ -67,7 +67,7 @@ Flickable { Image { rotation: 90 - source: "qrc:/images/arrows.png" + source: "../images/arrows.png" anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/examples/quickcontrols2/gallery/pages/ScrollIndicatorPage.qml b/examples/quickcontrols2/gallery/pages/ScrollIndicatorPage.qml index d76d2de3..f7c23a06 100644 --- a/examples/quickcontrols2/gallery/pages/ScrollIndicatorPage.qml +++ b/examples/quickcontrols2/gallery/pages/ScrollIndicatorPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 Flickable { id: flickable @@ -67,7 +67,7 @@ Flickable { Image { rotation: 90 - source: "qrc:/images/arrows.png" + source: "../images/arrows.png" anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/examples/quickcontrols2/gallery/pages/SliderPage.qml b/examples/quickcontrols2/gallery/pages/SliderPage.qml index d9853c22..83ae32ef 100644 --- a/examples/quickcontrols2/gallery/pages/SliderPage.qml +++ b/examples/quickcontrols2/gallery/pages/SliderPage.qml @@ -39,13 +39,11 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page - readonly property int itemWidth: Math.max(slider.implicitWidth, Math.min(slider.implicitWidth * 2, page.availableWidth / 3)) - Column { spacing: 40 width: parent.width @@ -60,14 +58,12 @@ ScrollablePage { Slider { id: slider value: 0.5 - width: itemWidth anchors.horizontalCenter: parent.horizontalCenter } Slider { orientation: Qt.Vertical value: 0.5 - height: itemWidth anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/examples/quickcontrols2/gallery/pages/SpinBoxPage.qml b/examples/quickcontrols2/gallery/pages/SpinBoxPage.qml index 2b3664cf..93adc01a 100644 --- a/examples/quickcontrols2/gallery/pages/SpinBoxPage.qml +++ b/examples/quickcontrols2/gallery/pages/SpinBoxPage.qml @@ -39,13 +39,11 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page - readonly property int itemWidth: Math.max(box.implicitWidth, Math.min(box.implicitWidth * 2, pane.availableWidth / 3)) - Column { spacing: 40 width: parent.width @@ -61,7 +59,6 @@ ScrollablePage { SpinBox { id: box value: 50 - width: itemWidth anchors.horizontalCenter: parent.horizontalCenter editable: true } diff --git a/examples/quickcontrols2/gallery/pages/StackViewPage.qml b/examples/quickcontrols2/gallery/pages/StackViewPage.qml index 4e44c3c8..d99a4b93 100644 --- a/examples/quickcontrols2/gallery/pages/StackViewPage.qml +++ b/examples/quickcontrols2/gallery/pages/StackViewPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 StackView { id: stackView diff --git a/examples/quickcontrols2/gallery/pages/SwipeViewPage.qml b/examples/quickcontrols2/gallery/pages/SwipeViewPage.qml index d0b0486c..dedacac4 100644 --- a/examples/quickcontrols2/gallery/pages/SwipeViewPage.qml +++ b/examples/quickcontrols2/gallery/pages/SwipeViewPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 Pane { id: pane @@ -69,7 +69,7 @@ Pane { } Image { - source: "qrc:/images/arrows.png" + source: "../images/arrows.png" anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/examples/quickcontrols2/gallery/pages/SwitchPage.qml b/examples/quickcontrols2/gallery/pages/SwitchPage.qml index 1315268d..ccaa4e1e 100644 --- a/examples/quickcontrols2/gallery/pages/SwitchPage.qml +++ b/examples/quickcontrols2/gallery/pages/SwitchPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page diff --git a/examples/quickcontrols2/gallery/pages/TabBarPage.qml b/examples/quickcontrols2/gallery/pages/TabBarPage.qml index 1b5bdb9b..818cccef 100644 --- a/examples/quickcontrols2/gallery/pages/TabBarPage.qml +++ b/examples/quickcontrols2/gallery/pages/TabBarPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 Page { id: page @@ -69,7 +69,7 @@ Page { } Image { - source: "qrc:/images/arrows.png" + source: "../images/arrows.png" anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/examples/quickcontrols2/gallery/pages/TextAreaPage.qml b/examples/quickcontrols2/gallery/pages/TextAreaPage.qml index ca28e2b7..97669f2f 100644 --- a/examples/quickcontrols2/gallery/pages/TextAreaPage.qml +++ b/examples/quickcontrols2/gallery/pages/TextAreaPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page diff --git a/examples/quickcontrols2/gallery/pages/TextFieldPage.qml b/examples/quickcontrols2/gallery/pages/TextFieldPage.qml index 9092e10d..1b22fd08 100644 --- a/examples/quickcontrols2/gallery/pages/TextFieldPage.qml +++ b/examples/quickcontrols2/gallery/pages/TextFieldPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page @@ -58,7 +58,6 @@ ScrollablePage { TextField { id: field placeholderText: "TextField" - width: Math.max(implicitWidth, Math.min(implicitWidth * 2, pane.availableWidth / 3)) anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/examples/quickcontrols2/gallery/pages/ToolTipPage.qml b/examples/quickcontrols2/gallery/pages/ToolTipPage.qml index e0f769eb..d9bc969d 100644 --- a/examples/quickcontrols2/gallery/pages/ToolTipPage.qml +++ b/examples/quickcontrols2/gallery/pages/ToolTipPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page @@ -58,7 +58,6 @@ ScrollablePage { Button { text: "Tip" anchors.horizontalCenter: parent.horizontalCenter - width: Math.max(implicitWidth, Math.min(implicitWidth * 2, pane.availableWidth / 3)) ToolTip.timeout: 5000 ToolTip.visible: pressed diff --git a/examples/quickcontrols2/gallery/pages/TumblerPage.qml b/examples/quickcontrols2/gallery/pages/TumblerPage.qml index d12cc999..3b290dcb 100644 --- a/examples/quickcontrols2/gallery/pages/TumblerPage.qml +++ b/examples/quickcontrols2/gallery/pages/TumblerPage.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick.Controls 2.1 ScrollablePage { id: page @@ -57,7 +57,6 @@ ScrollablePage { Tumbler { model: 10 - visibleItemCount: 5 anchors.horizontalCenter: parent.horizontalCenter } } diff --git a/examples/quickcontrols2/gallery/qtquickcontrols2.conf b/examples/quickcontrols2/gallery/qtquickcontrols2.conf index ce348f2e..da1a8f41 100644 --- a/examples/quickcontrols2/gallery/qtquickcontrols2.conf +++ b/examples/quickcontrols2/gallery/qtquickcontrols2.conf @@ -1,8 +1,8 @@ [Material] Primary=#41cd52 Accent=#41cd52 -Theme=Light +Theme=System [Universal] Accent=#41cd52 -Theme=Light +Theme=System diff --git a/examples/quickcontrols2/quickcontrols2.pro b/examples/quickcontrols2/quickcontrols2.pro index 4f0f2fcc..458d10db 100644 --- a/examples/quickcontrols2/quickcontrols2.pro +++ b/examples/quickcontrols2/quickcontrols2.pro @@ -1,4 +1,6 @@ TEMPLATE = subdirs SUBDIRS += \ gallery \ - chattutorial + chattutorial \ + texteditor \ + contactlist diff --git a/examples/quickcontrols2/texteditor/+touch/texteditor.html b/examples/quickcontrols2/texteditor/+touch/texteditor.html new file mode 100644 index 00000000..b5f03f25 --- /dev/null +++ b/examples/quickcontrols2/texteditor/+touch/texteditor.html @@ -0,0 +1,19 @@ +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <meta name="qrichtext" content="1"> + <title>Text Editor Example</title> +</head> +<body> +<body> + <p align="center"> + <img src="qrc:/images/qt-logo.png" /> + </p> + <h2 align="center"> + Qt Quick Controls 2 + </h2> + <p align="center"> + This example demonstrates a modern rich text editor. + </p> +</body> +</html> diff --git a/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-desktop.jpg b/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-desktop.jpg Binary files differnew file mode 100644 index 00000000..259e0e8b --- /dev/null +++ b/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-desktop.jpg diff --git a/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-touch.jpg b/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-touch.jpg Binary files differnew file mode 100644 index 00000000..6a924cdf --- /dev/null +++ b/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-touch.jpg diff --git a/examples/quickcontrols2/texteditor/doc/src/qtquickcontrols2-texteditor.qdoc b/examples/quickcontrols2/texteditor/doc/src/qtquickcontrols2-texteditor.qdoc new file mode 100644 index 00000000..1fee54ce --- /dev/null +++ b/examples/quickcontrols2/texteditor/doc/src/qtquickcontrols2-texteditor.qdoc @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ +/*! + \example texteditor + \title Qt Quick Controls 2 - Text Editor + \ingroup qtquickcontrols2-examples + \brief A QML app using Qt Quick Controls 2 and a C++ class to + provide a fully-functional rich-text editor application. + + The \e {Text Editor Example} presents a sample HTML file using the TextArea + control, preserving the HTML formatting. The application comes with two user + interfaces; one for traditional desktop platforms with a mouse pointer, and + another simpler, touch-oriented version. + + \section1 Desktop User Interface + + \image qtquickcontrols2-texteditor-desktop.jpg + + The desktop version is a complete text editor with capabilities for formatting + text, and opening and saving HTML and plain text files. It demonstrates the + native-looking dialogs and menus using the \l{Qt Labs Platform} module. These + types are mostly suitable for desktop platforms with support for multiple + top-level windows, a mouse pointer, and moderate screen size. + + The desktop UI uses FileDialog for opening and saving files: + + \quotefromfile texteditor/qml/texteditor.qml + \skipto FileDialog + \printuntil /\bsaveAs\b/ + \printline } + + It uses FontDialog and ColorDialog for choosing fonts and colors: + + \skipto FontDialog + \printuntil /.*colorDialog$/ + \printuntil /^\s{4}\}$/ + + It also uses \l[QML QtLabsPlatform]{Menu} and + \l[QML QtLabsPlatform]{MenuItem} that provide a context menu to format text + within: + + \skipto /\bMenu\b/ + \printuntil /^\s{4}\}$/ + + \note There is also a standard menubar with more options than the + context menu. + + \section1 Touch User Interface + + \image qtquickcontrols2-texteditor-touch.jpg + + The touch user interface is a simplified version of the text editor. It is + suitable for touch devices with limited screen size. The example uses + \l{Using File Selectors with Qt Quick Controls 2}{file selectors} to load + the appropriate user interface automatically. + + Unlike the desktop version, which uses top-level dialogs, the touch version + uses the QML \l Dialog type, which is not a top-level window. This type of + dialog is fully supported on mobile and embedded platforms that do not support + multiple top-level windows. + + \quotefromfile texteditor/qml/+touch/texteditor.qml + \skipto /\bDialog\b/ + \printuntil /^\s{4}\}$/ + + \section1 C++ Backend + + Both user interfaces use the same C++ backend, which supports opening, formatting, + and editing a document. The C++ class, \c DocumentHandler, extends QObject and is + registered as a QML type under the namespace \c {io.qt.examples.texteditor 1.0}. + + The following snippets show how the type is registered under a namespace and later + imported and instantiated by \e main.qml. For more information about registering C++ + classes as QML types, see \l {Defining QML Types from C++}. + + QML type registration: + + \code + #include <QtQml/qqml.h> + ... + qmlRegisterType<DocumentHandler>("io.qt.examples.texteditor", 1, 0, "DocumentHandler"); + ... + \endcode + + QML namespace import: + + \code + import io.qt.examples.texteditor 1.0 + \endcode + + QML instance: + + \quotefromfile texteditor/qml/texteditor.qml + \skipto DocumentHandler + \printuntil /^\s{4}\}$/ + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols2/texteditor/documenthandler.cpp b/examples/quickcontrols2/texteditor/documenthandler.cpp new file mode 100644 index 00000000..e57946fd --- /dev/null +++ b/examples/quickcontrols2/texteditor/documenthandler.cpp @@ -0,0 +1,371 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "documenthandler.h" + +#include <QFile> +#include <QFileInfo> +#include <QFileSelector> +#include <QQmlFile> +#include <QQmlFileSelector> +#include <QQuickTextDocument> +#include <QTextCharFormat> +#include <QTextCodec> +#include <QTextDocument> + +DocumentHandler::DocumentHandler(QObject *parent) + : QObject(parent) + , m_document(nullptr) + , m_cursorPosition(-1) + , m_selectionStart(0) + , m_selectionEnd(0) +{ +} + +QQuickTextDocument *DocumentHandler::document() const +{ + return m_document; +} + +void DocumentHandler::setDocument(QQuickTextDocument *document) +{ + if (document == m_document) + return; + + m_document = document; + emit documentChanged(); +} + +int DocumentHandler::cursorPosition() const +{ + return m_cursorPosition; +} + +void DocumentHandler::setCursorPosition(int position) +{ + if (position == m_cursorPosition) + return; + + m_cursorPosition = position; + reset(); + emit cursorPositionChanged(); +} + +int DocumentHandler::selectionStart() const +{ + return m_selectionStart; +} + +void DocumentHandler::setSelectionStart(int position) +{ + if (position == m_selectionStart) + return; + + m_selectionStart = position; + emit selectionStartChanged(); +} + +int DocumentHandler::selectionEnd() const +{ + return m_selectionEnd; +} + +void DocumentHandler::setSelectionEnd(int position) +{ + if (position == m_selectionEnd) + return; + + m_selectionEnd = position; + emit selectionEndChanged(); +} + +QString DocumentHandler::fontFamily() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return QString(); + QTextCharFormat format = cursor.charFormat(); + return format.font().family(); +} + +void DocumentHandler::setFontFamily(const QString &family) +{ + QTextCharFormat format; + format.setFontFamily(family); + mergeFormatOnWordOrSelection(format); + emit fontFamilyChanged(); +} + +QColor DocumentHandler::textColor() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return QColor(Qt::black); + QTextCharFormat format = cursor.charFormat(); + return format.foreground().color(); +} + +void DocumentHandler::setTextColor(const QColor &color) +{ + QTextCharFormat format; + format.setForeground(QBrush(color)); + mergeFormatOnWordOrSelection(format); + emit textColorChanged(); +} + +Qt::Alignment DocumentHandler::alignment() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return Qt::AlignLeft; + return textCursor().blockFormat().alignment(); +} + +void DocumentHandler::setAlignment(Qt::Alignment alignment) +{ + QTextBlockFormat format; + format.setAlignment(alignment); + QTextCursor cursor = textCursor(); + cursor.mergeBlockFormat(format); + emit alignmentChanged(); +} + +bool DocumentHandler::bold() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return false; + return textCursor().charFormat().fontWeight() == QFont::Bold; +} + +void DocumentHandler::setBold(bool bold) +{ + QTextCharFormat format; + format.setFontWeight(bold ? QFont::Bold : QFont::Normal); + mergeFormatOnWordOrSelection(format); + emit boldChanged(); +} + +bool DocumentHandler::italic() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return false; + return textCursor().charFormat().fontItalic(); +} + +void DocumentHandler::setItalic(bool italic) +{ + QTextCharFormat format; + format.setFontItalic(italic); + mergeFormatOnWordOrSelection(format); + emit italicChanged(); +} + +bool DocumentHandler::underline() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return false; + return textCursor().charFormat().fontUnderline(); +} + +void DocumentHandler::setUnderline(bool underline) +{ + QTextCharFormat format; + format.setFontUnderline(underline); + mergeFormatOnWordOrSelection(format); + emit underlineChanged(); +} + +int DocumentHandler::fontSize() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return 0; + QTextCharFormat format = cursor.charFormat(); + return format.font().pointSize(); +} + +void DocumentHandler::setFontSize(int size) +{ + if (size <= 0) + return; + + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return; + + if (!cursor.hasSelection()) + cursor.select(QTextCursor::WordUnderCursor); + + if (cursor.charFormat().property(QTextFormat::FontPointSize).toInt() == size) + return; + + QTextCharFormat format; + format.setFontPointSize(size); + mergeFormatOnWordOrSelection(format); + emit fontSizeChanged(); +} + +QString DocumentHandler::fileName() const +{ + const QString filePath = QQmlFile::urlToLocalFileOrQrc(m_fileUrl); + const QString fileName = QFileInfo(filePath).fileName(); + if (fileName.isEmpty()) + return QStringLiteral("untitled.txt"); + return fileName; +} + +QString DocumentHandler::fileType() const +{ + return QFileInfo(fileName()).suffix(); +} + +QUrl DocumentHandler::fileUrl() const +{ + return m_fileUrl; +} + +void DocumentHandler::load(const QUrl &fileUrl) +{ + if (fileUrl == m_fileUrl) + return; + + QQmlEngine *engine = qmlEngine(this); + if (!engine) { + qWarning() << "load() called before DocumentHandler has QQmlEngine"; + return; + } + + const QUrl path = QQmlFileSelector::get(engine)->selector()->select(fileUrl); + const QString fileName = QQmlFile::urlToLocalFileOrQrc(path); + if (QFile::exists(fileName)) { + QFile file(fileName); + if (file.open(QFile::ReadOnly)) { + QByteArray data = file.readAll(); + QTextCodec *codec = QTextCodec::codecForHtml(data); + if (QTextDocument *doc = textDocument()) + doc->setModified(false); + + emit loaded(codec->toUnicode(data)); + reset(); + } + } + + m_fileUrl = fileUrl; + emit fileUrlChanged(); +} + +void DocumentHandler::saveAs(const QUrl &fileUrl) +{ + QTextDocument *doc = textDocument(); + if (!doc) + return; + + const QString filePath = fileUrl.toLocalFile(); + const bool isHtml = QFileInfo(filePath).suffix().contains(QLatin1String("htm")); + QFile file(filePath); + if (!file.open(QFile::WriteOnly | QFile::Truncate | (isHtml ? QFile::NotOpen : QFile::Text))) { + emit error(tr("Cannot save: ") + file.errorString()); + return; + } + file.write((isHtml ? doc->toHtml() : doc->toPlainText()).toUtf8()); + file.close(); + + if (fileUrl == m_fileUrl) + return; + + m_fileUrl = fileUrl; + emit fileUrlChanged(); +} + +void DocumentHandler::reset() +{ + emit fontFamilyChanged(); + emit alignmentChanged(); + emit boldChanged(); + emit italicChanged(); + emit underlineChanged(); + emit fontSizeChanged(); + emit textColorChanged(); +} + +QTextCursor DocumentHandler::textCursor() const +{ + QTextDocument *doc = textDocument(); + if (!doc) + return QTextCursor(); + + QTextCursor cursor = QTextCursor(doc); + if (m_selectionStart != m_selectionEnd) { + cursor.setPosition(m_selectionStart); + cursor.setPosition(m_selectionEnd, QTextCursor::KeepAnchor); + } else { + cursor.setPosition(m_cursorPosition); + } + return cursor; +} + +QTextDocument *DocumentHandler::textDocument() const +{ + if (!m_document) + return nullptr; + + return m_document->textDocument(); +} + +void DocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat &format) +{ + QTextCursor cursor = textCursor(); + if (!cursor.hasSelection()) + cursor.select(QTextCursor::WordUnderCursor); + cursor.mergeCharFormat(format); +} diff --git a/examples/quickcontrols2/texteditor/documenthandler.h b/examples/quickcontrols2/texteditor/documenthandler.h new file mode 100644 index 00000000..dd3c3988 --- /dev/null +++ b/examples/quickcontrols2/texteditor/documenthandler.h @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DOCUMENTHANDLER_H +#define DOCUMENTHANDLER_H + +#include <QFont> +#include <QObject> +#include <QTextCursor> +#include <QUrl> + +QT_BEGIN_NAMESPACE +class QTextDocument; +class QQuickTextDocument; +QT_END_NAMESPACE + +class DocumentHandler : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QQuickTextDocument *document READ document WRITE setDocument NOTIFY documentChanged) + Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged) + Q_PROPERTY(int selectionStart READ selectionStart WRITE setSelectionStart NOTIFY selectionStartChanged) + Q_PROPERTY(int selectionEnd READ selectionEnd WRITE setSelectionEnd NOTIFY selectionEndChanged) + + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor NOTIFY textColorChanged) + Q_PROPERTY(QString fontFamily READ fontFamily WRITE setFontFamily NOTIFY fontFamilyChanged) + Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged) + + Q_PROPERTY(bool bold READ bold WRITE setBold NOTIFY boldChanged) + Q_PROPERTY(bool italic READ italic WRITE setItalic NOTIFY italicChanged) + Q_PROPERTY(bool underline READ underline WRITE setUnderline NOTIFY underlineChanged) + + Q_PROPERTY(int fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged) + + Q_PROPERTY(QString fileName READ fileName NOTIFY fileUrlChanged) + Q_PROPERTY(QString fileType READ fileType NOTIFY fileUrlChanged) + Q_PROPERTY(QUrl fileUrl READ fileUrl NOTIFY fileUrlChanged) + +public: + explicit DocumentHandler(QObject *parent = nullptr); + + QQuickTextDocument *document() const; + void setDocument(QQuickTextDocument *document); + + int cursorPosition() const; + void setCursorPosition(int position); + + int selectionStart() const; + void setSelectionStart(int position); + + int selectionEnd() const; + void setSelectionEnd(int position); + + QString fontFamily() const; + void setFontFamily(const QString &family); + + QColor textColor() const; + void setTextColor(const QColor &color); + + Qt::Alignment alignment() const; + void setAlignment(Qt::Alignment alignment); + + bool bold() const; + void setBold(bool bold); + + bool italic() const; + void setItalic(bool italic); + + bool underline() const; + void setUnderline(bool underline); + + int fontSize() const; + void setFontSize(int size); + + QString fileName() const; + QString fileType() const; + QUrl fileUrl() const; + +public Q_SLOTS: + void load(const QUrl &fileUrl); + void saveAs(const QUrl &fileUrl); + +Q_SIGNALS: + void documentChanged(); + void cursorPositionChanged(); + void selectionStartChanged(); + void selectionEndChanged(); + + void fontFamilyChanged(); + void textColorChanged(); + void alignmentChanged(); + + void boldChanged(); + void italicChanged(); + void underlineChanged(); + + void fontSizeChanged(); + + void textChanged(); + void fileUrlChanged(); + + void loaded(const QString &text); + void error(const QString &message); + +private: + void reset(); + QTextCursor textCursor() const; + QTextDocument *textDocument() const; + void mergeFormatOnWordOrSelection(const QTextCharFormat &format); + + QQuickTextDocument *m_document; + + int m_cursorPosition; + int m_selectionStart; + int m_selectionEnd; + + QFont m_font; + int m_fontSize; + QUrl m_fileUrl; +}; + +#endif // DOCUMENTHANDLER_H diff --git a/examples/quickcontrols2/texteditor/fonts/fontello.ttf b/examples/quickcontrols2/texteditor/fonts/fontello.ttf Binary files differnew file mode 100644 index 00000000..db957652 --- /dev/null +++ b/examples/quickcontrols2/texteditor/fonts/fontello.ttf diff --git a/examples/quickcontrols2/texteditor/images/qt-logo.png b/examples/quickcontrols2/texteditor/images/qt-logo.png Binary files differnew file mode 100644 index 00000000..e16b4182 --- /dev/null +++ b/examples/quickcontrols2/texteditor/images/qt-logo.png diff --git a/examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml b/examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml new file mode 100644 index 00000000..11d153f5 --- /dev/null +++ b/examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml @@ -0,0 +1,260 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples 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 The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.8 +import QtQuick.Controls 2.1 +import QtQuick.Controls.Material 2.1 +import QtQuick.Layouts 1.3 +import QtQuick.Window 2.0 + +import io.qt.examples.texteditor 1.0 + +// TODO: +// - make designer-friendly + +ApplicationWindow { + id: window + visible: true + title: document.fileName + " - Text Editor Example" + + header: ToolBar { + leftPadding: 5 + + RowLayout { + anchors.fill: parent + spacing: 0 + + ToolButton { + id: doneEditingButton + font.family: "fontello" + text: "\uE80A" // icon-ok + opacity: !textArea.readOnly ? 1 : 0 + onClicked: textArea.readOnly = true + + Material.foreground: Material.accent + } + + Label { + text: qsTr("Text Editor Example") + font.bold: true + font.pixelSize: 20 + elide: Label.ElideRight + Layout.fillWidth: true + } + + ToolButton { + font.family: "fontello" + text: "\uF142" // icon-ellipsis-vert + onClicked: menu.open() + + Menu { + id: menu + + MenuItem { + text: qsTr("About") + onTriggered: aboutDialog.open() + } + } + } + } + } + + DocumentHandler { + id: document + document: textArea.textDocument + cursorPosition: textArea.cursorPosition + selectionStart: textArea.selectionStart + selectionEnd: textArea.selectionEnd + // textColor: TODO + Component.onCompleted: document.load("qrc:/texteditor.html") + onLoaded: { + textArea.text = text + } + onError: { + errorDialog.text = message + errorDialog.visible = true + } + } + + Flickable { + id: flickable + flickableDirection: Flickable.VerticalFlick + anchors.fill: parent + + TextArea.flickable: TextArea { + id: textArea + textFormat: Qt.RichText + wrapMode: TextArea.Wrap + readOnly: true + persistentSelection: true + // Different styles have different padding and background + // decorations, but since this editor is almost taking up the + // entire window, we don't need them. + leftPadding: 6 + rightPadding: 6 + topPadding: 0 + bottomPadding: 0 + background: null + + onLinkActivated: Qt.openUrlExternally(link) + } + + ScrollBar.vertical: ScrollBar {} + } + + footer: ToolBar { + visible: !textArea.readOnly && textArea.activeFocus + + Material.primary: "#E0E0E0" + Material.elevation: 0 + + Flickable { + anchors.fill: parent + contentWidth: toolRow.implicitWidth + flickableDirection: Qt.Horizontal + boundsBehavior: Flickable.StopAtBounds + + Row { + id: toolRow + + ToolButton { + id: boldButton + text: "\uE800" // icon-bold + font.family: "fontello" + // Don't want to close the virtual keyboard when this is clicked. + focusPolicy: Qt.NoFocus + checkable: true + checked: document.bold + onClicked: document.bold = !document.bold + } + ToolButton { + id: italicButton + text: "\uE801" // icon-italic + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.italic + onClicked: document.italic = !document.italic + } + ToolButton { + id: underlineButton + text: "\uF0CD" // icon-underline + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.underline + onClicked: document.underline = !document.underline + } + + ToolSeparator {} + + ToolButton { + id: alignLeftButton + text: "\uE803" // icon-align-left + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.alignment == Qt.AlignLeft + onClicked: document.alignment = Qt.AlignLeft + } + ToolButton { + id: alignCenterButton + text: "\uE804" // icon-align-center + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.alignment == Qt.AlignHCenter + onClicked: document.alignment = Qt.AlignHCenter + } + ToolButton { + id: alignRightButton + text: "\uE805" // icon-align-right + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.alignment == Qt.AlignRight + onClicked: document.alignment = Qt.AlignRight + } + ToolButton { + id: alignJustifyButton + text: "\uE806" // icon-align-justify + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.alignment == Qt.AlignJustify + onClicked: document.alignment = Qt.AlignJustify + } + } + } + } + + RoundButton { + id: editButton + font.family: "fontello" + text: "\uE809" // icon-pencil + width: 48 + height: width + // Don't want to use anchors for the y position, because it will anchor + // to the footer, leaving a large vertical gap. + y: parent.height - height - 12 + anchors.right: parent.right + anchors.margins: 12 + visible: textArea.readOnly + highlighted: true + + onClicked: { + textArea.readOnly = false + // Force focus on the text area so the cursor and footer show up. + textArea.forceActiveFocus() + } + } + + Dialog { + id: aboutDialog + standardButtons: Dialog.Ok + modal: true + x: parent.width / 2 - width / 2 + y: parent.height / 2 - height / 2 + + contentItem: Label { + text: qsTr("Qt Quick Controls 2 - Text Editor Example") + } + } +} diff --git a/examples/quickcontrols2/texteditor/qml/texteditor.qml b/examples/quickcontrols2/texteditor/qml/texteditor.qml new file mode 100644 index 00000000..2247e8f1 --- /dev/null +++ b/examples/quickcontrols2/texteditor/qml/texteditor.qml @@ -0,0 +1,442 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples 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 The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.8 +import QtQuick.Controls 2.1 +import QtQuick.Window 2.0 +import Qt.labs.platform 1.0 + +import io.qt.examples.texteditor 1.0 + +// TODO: +// - make designer-friendly + +ApplicationWindow { + id: window + width: 1024 + height: 600 + visible: true + title: document.fileName + " - Text Editor Example" + + Component.onCompleted: { + x = Screen.width / 2 - width / 2 + y = Screen.height / 2 - height / 2 + } + + Shortcut { + sequence: StandardKey.Open + onActivated: openDialog.open() + } + Shortcut { + sequence: StandardKey.SaveAs + onActivated: saveDialog.open() + } + Shortcut { + sequence: StandardKey.Quit + onActivated: Qt.quit() + } + Shortcut { + sequence: StandardKey.Copy + onActivated: textArea.copy() + } + Shortcut { + sequence: StandardKey.Cut + onActivated: textArea.cut() + } + Shortcut { + sequence: StandardKey.Paste + onActivated: textArea.paste() + } + Shortcut { + sequence: StandardKey.Bold + onActivated: document.bold = !document.bold + } + Shortcut { + sequence: StandardKey.Italic + onActivated: document.italic = !document.italic + } + Shortcut { + sequence: StandardKey.Underline + onActivated: document.underline = !document.underline + } + + MenuBar { + Menu { + title: qsTr("&File") + + MenuItem { + text: qsTr("&Open") + onTriggered: openDialog.open() + } + MenuItem { + text: qsTr("&Save As...") + onTriggered: saveDialog.open() + } + MenuItem { + text: qsTr("&Quit") + onTriggered: Qt.quit() + } + } + + Menu { + title: qsTr("&Edit") + + MenuItem { + text: qsTr("&Copy") + enabled: textArea.selectedText + onTriggered: textArea.copy() + } + MenuItem { + text: qsTr("Cu&t") + enabled: textArea.selectedText + onTriggered: textArea.cut() + } + MenuItem { + text: qsTr("&Paste") + enabled: textArea.canPaste + onTriggered: textArea.paste() + } + } + + Menu { + title: qsTr("F&ormat") + + MenuItem { + text: qsTr("&Bold") + checkable: true + checked: document.bold + onTriggered: document.bold = !document.bold + } + MenuItem { + text: qsTr("&Italic") + checkable: true + checked: document.italic + onTriggered: document.italic = !document.italic + } + MenuItem { + text: qsTr("&Underline") + checkable: true + checked: document.underline + onTriggered: document.underline = !document.underline + } + } + } + + FileDialog { + id: openDialog + fileMode: FileDialog.OpenFile + selectedNameFilter.index: 1 + nameFilters: ["Text files (*.txt)", "HTML files (*.html *.htm)"] + folder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) + onAccepted: document.load(file) + } + + FileDialog { + id: saveDialog + fileMode: FileDialog.SaveFile + defaultSuffix: document.fileType + nameFilters: openDialog.nameFilters + selectedNameFilter.index: document.fileType === "txt" ? 0 : 1 + folder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) + onAccepted: document.saveAs(file) + } + + FontDialog { + id: fontDialog + onAccepted: { + document.fontFamily = font.family; + document.fontSize = font.pointSize; + } + } + + ColorDialog { + id: colorDialog + currentColor: "black" + } + + MessageDialog { + id: errorDialog + } + + header: ToolBar { + leftPadding: 8 + + Flow { + id: flow + width: parent.width + + Row { + id: fileRow + ToolButton { + id: openButton + text: "\uF115" // icon-folder-open-empty + font.family: "fontello" + onClicked: openDialog.open() + } + ToolSeparator { + contentItem.visible: fileRow.y === editRow.y + } + } + + Row { + id: editRow + ToolButton { + id: copyButton + text: "\uF0C5" // icon-docs + font.family: "fontello" + focusPolicy: Qt.TabFocus + enabled: textArea.selectedText + onClicked: textArea.copy() + } + ToolButton { + id: cutButton + text: "\uE802" // icon-scissors + font.family: "fontello" + focusPolicy: Qt.TabFocus + enabled: textArea.selectedText + onClicked: textArea.cut() + } + ToolButton { + id: pasteButton + text: "\uF0EA" // icon-paste + font.family: "fontello" + focusPolicy: Qt.TabFocus + enabled: textArea.canPaste + onClicked: textArea.paste() + } + ToolSeparator { + contentItem.visible: editRow.y === formatRow.y + } + } + + Row { + id: formatRow + ToolButton { + id: boldButton + text: "\uE800" // icon-bold + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.bold + onClicked: document.bold = !document.bold + } + ToolButton { + id: italicButton + text: "\uE801" // icon-italic + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.italic + onClicked: document.italic = !document.italic + } + ToolButton { + id: underlineButton + text: "\uF0CD" // icon-underline + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.underline + onClicked: document.underline = !document.underline + } + ToolButton { + id: fontFamilyToolButton + text: qsTr("\uE808") // icon-font + font.family: "fontello" + font.bold: document.bold + font.italic: document.italic + font.underline: document.underline + onClicked: { + fontDialog.currentFont.family = document.fontFamily; + fontDialog.currentFont.pointSize = document.fontSize; + fontDialog.open(); + } + } + ToolButton { + id: textColorButton + text: "\uF1FC" // icon-brush + font.family: "fontello" + focusPolicy: Qt.TabFocus + onClicked: colorDialog.open() + + Rectangle { + width: aFontMetrics.width + 3 + height: 2 + color: document.textColor + parent: textColorButton.contentItem + anchors.horizontalCenter: parent.horizontalCenter + anchors.baseline: parent.baseline + anchors.baselineOffset: 6 + + TextMetrics { + id: aFontMetrics + font: textColorButton.font + text: textColorButton.text + } + } + } + ToolSeparator { + contentItem.visible: formatRow.y === alignRow.y + } + } + + Row { + id: alignRow + ToolButton { + id: alignLeftButton + text: "\uE803" // icon-align-left + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.alignment == Qt.AlignLeft + onClicked: document.alignment = Qt.AlignLeft + } + ToolButton { + id: alignCenterButton + text: "\uE804" // icon-align-center + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.alignment == Qt.AlignHCenter + onClicked: document.alignment = Qt.AlignHCenter + } + ToolButton { + id: alignRightButton + text: "\uE805" // icon-align-right + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.alignment == Qt.AlignRight + onClicked: document.alignment = Qt.AlignRight + } + ToolButton { + id: alignJustifyButton + text: "\uE806" // icon-align-justify + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.alignment == Qt.AlignJustify + onClicked: document.alignment = Qt.AlignJustify + } + } + } + } + + DocumentHandler { + id: document + document: textArea.textDocument + cursorPosition: textArea.cursorPosition + selectionStart: textArea.selectionStart + selectionEnd: textArea.selectionEnd + textColor: colorDialog.color + Component.onCompleted: document.load("qrc:/texteditor.html") + onLoaded: { + textArea.text = text + } + onError: { + errorDialog.text = message + errorDialog.visible = true + } + } + + Flickable { + id: flickable + flickableDirection: Flickable.VerticalFlick + anchors.fill: parent + + TextArea.flickable: TextArea { + id: textArea + textFormat: Qt.RichText + wrapMode: TextArea.Wrap + focus: true + selectByMouse: true + persistentSelection: true + // Different styles have different padding and background + // decorations, but since this editor is almost taking up the + // entire window, we don't need them. + leftPadding: 6 + rightPadding: 6 + topPadding: 0 + bottomPadding: 0 + background: null + + MouseArea { + acceptedButtons: Qt.RightButton + anchors.fill: parent + onClicked: contextMenu.open() + } + + onLinkActivated: Qt.openUrlExternally(link) + } + + ScrollBar.vertical: ScrollBar {} + } + + Menu { + id: contextMenu + + MenuItem { + text: qsTr("Copy") + enabled: textArea.selectedText + onTriggered: textArea.copy() + } + MenuItem { + text: qsTr("Cut") + enabled: textArea.selectedText + onTriggered: textArea.cut() + } + MenuItem { + text: qsTr("Paste") + enabled: textArea.canPaste + onTriggered: textArea.paste() + } + + MenuSeparator {} + + MenuItem { + text: qsTr("Font...") + onTriggered: fontDialog.open() + } + + MenuItem { + text: qsTr("Color...") + onTriggered: colorDialog.open() + } + } +} diff --git a/examples/quickcontrols2/texteditor/qtquickcontrols2.conf b/examples/quickcontrols2/texteditor/qtquickcontrols2.conf new file mode 100644 index 00000000..ecac617f --- /dev/null +++ b/examples/quickcontrols2/texteditor/qtquickcontrols2.conf @@ -0,0 +1,11 @@ +[Controls] +Style=Material + +[Material] +Primary=White +Foreground=#444444 +Accent=Blue +Theme=System + +[Universal] +Theme=System diff --git a/examples/quickcontrols2/gallery/pages/PopupPage.qml b/examples/quickcontrols2/texteditor/texteditor.cpp index 66c46143..10ba675c 100644 --- a/examples/quickcontrols2/gallery/pages/PopupPage.qml +++ b/examples/quickcontrols2/texteditor/texteditor.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -38,31 +38,52 @@ ** ****************************************************************************/ -import QtQuick 2.6 -import QtQuick.Controls 2.0 +#ifdef QT_WIDGETS_LIB +#include <QApplication> +#else +#include <QGuiApplication> +#endif +#include <QFontDatabase> +#include <QDebug> +#include <QQmlApplicationEngine> +#include <QQmlContext> +#include <QQmlFileSelector> +#include <QQuickStyle> -ScrollablePage { - id: page +#include "documenthandler.h" - Column { - spacing: 40 - width: parent.width +int main(int argc, char *argv[]) +{ + QGuiApplication::setApplicationName("Text Editor"); + QGuiApplication::setOrganizationName("QtProject"); + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - Label { - width: parent.width - wrapMode: Label.Wrap - horizontalAlignment: Qt.AlignHCenter - text: "Popup is used to display modal or modeless content that overlays other " - + "application content. In this example, the settings are shown in a popup." - } +#ifdef QT_WIDGETS_LIB + QApplication app(argc, argv); +#else + QGuiApplication app(argc, argv); +#endif - Button { - id: button - text: "Open" - anchors.horizontalCenter: parent.horizontalCenter - width: Math.max(implicitWidth, Math.min(implicitWidth * 2, page.availableWidth / 3)) + QFontDatabase fontDatabase; + if (fontDatabase.addApplicationFont(":/fonts/fontello.ttf") == -1) + qWarning() << "Failed to load fontello.ttf"; - onClicked: settingsPopup.open() - } - } + qmlRegisterType<DocumentHandler>("io.qt.examples.texteditor", 1, 0, "DocumentHandler"); + + QStringList selectors; +#ifdef QT_EXTRA_FILE_SELECTOR + selectors += QT_EXTRA_FILE_SELECTOR; +#else + if (app.arguments().contains("-touch")) + selectors += "touch"; +#endif + + QQmlApplicationEngine engine; + QQmlFileSelector::get(&engine)->setExtraSelectors(selectors); + + engine.load(QUrl("qrc:/qml/texteditor.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); } diff --git a/examples/quickcontrols2/texteditor/texteditor.html b/examples/quickcontrols2/texteditor/texteditor.html new file mode 100644 index 00000000..1310da42 --- /dev/null +++ b/examples/quickcontrols2/texteditor/texteditor.html @@ -0,0 +1,44 @@ +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <meta name="qrichtext" content="1"> + <title>Text Editor Example</title> + <style type="text/css"> + p, + body, <!-- specifiying font-size for body seems to be necessary to avoid bullet points being incorrectly positioned --> + li { + white-space: pre-wrap; + font-size:11pt; + } + </style> +</head> +<body> + <p align="center"> + <img src="qrc:/images/qt-logo.png" /> + </p> + <h2 align="center"> + Qt Quick Controls 2 + </h2> + <p align="center"> + This example demonstrates a modern rich text editor. The UI uses Qt Labs Platforms to provide native menus and dialogs. + </p> + <br /> + <br /> + <br /> + + <p> + Below you'll find a list of the native controls used in this application. + </p> + + <ul> + <!-- TODO: update the links before the 5.8 release --> + <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-menu.html">Menu</a> - provides a QML API for native platform menu popups.</li> + <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-menubar.html">MenuBar</a> - provides a QML API for native platform menubars.</li> + <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-menuitem.html">MenuItem</a> - provides a QML API for native platform menu items.</li> + <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-filedialog.html">FileDialog</a> - provides a QML API for native platform file dialogs.</li> + <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-fontdialog.html">FontDialog</a> - provides a QML API for native platform font dialogs.</li> + <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-colordialog.html">ColorDialog</a> - provides a QML API for native platform color dialogs.</li> + <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-messagedialog.html">MessageDialog</a> - provides a QML API for native platform message dialogs.</li> + </ul> +</body> +</html> diff --git a/examples/quickcontrols2/texteditor/texteditor.pro b/examples/quickcontrols2/texteditor/texteditor.pro new file mode 100644 index 00000000..deb24576 --- /dev/null +++ b/examples/quickcontrols2/texteditor/texteditor.pro @@ -0,0 +1,22 @@ +TEMPLATE = app +TARGET = texteditor +QT += quick quickcontrols2 +qtHaveModule(widgets): QT += widgets + +cross_compile: DEFINES += QT_EXTRA_FILE_SELECTOR=\\\"touch\\\" + +HEADERS += \ + documenthandler.h + +SOURCES += \ + texteditor.cpp \ + documenthandler.cpp + +OTHER_FILES += \ + qml/*.qml + +RESOURCES += \ + texteditor.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/texteditor +INSTALLS += target diff --git a/examples/quickcontrols2/texteditor/texteditor.qrc b/examples/quickcontrols2/texteditor/texteditor.qrc new file mode 100644 index 00000000..8f2da843 --- /dev/null +++ b/examples/quickcontrols2/texteditor/texteditor.qrc @@ -0,0 +1,11 @@ +<RCC> + <qresource prefix="/"> + <file>qtquickcontrols2.conf</file> + <file>images/qt-logo.png</file> + <file>fonts/fontello.ttf</file> + <file>qml/texteditor.qml</file> + <file>texteditor.html</file> + <file>qml/+touch/texteditor.qml</file> + <file>+touch/texteditor.html</file> + </qresource> +</RCC> |