diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/CMakeLists.txt | 15 | ||||
-rw-r--r-- | src/core/doc/qtqmlcore.qdocconf | 12 | ||||
-rw-r--r-- | src/core/doc/src/includes/qmlpermissions.qdocinc | 34 | ||||
-rw-r--r-- | src/core/doc/src/qmlpermissions.qdoc | 193 | ||||
-rw-r--r-- | src/core/doc/src/qtqmlcore-qmltypes.qdoc | 8 | ||||
-rw-r--r-- | src/core/doc/src/qtqmlcore.qdoc | 14 | ||||
-rw-r--r-- | src/core/qqmlcoreglobal_p.h | 2 | ||||
-rw-r--r-- | src/core/qqmlpermissions_p.h | 117 | ||||
-rw-r--r-- | src/core/qqmlsettings.cpp | 27 | ||||
-rw-r--r-- | src/core/qqmlsettings_p.h | 2 | ||||
-rw-r--r-- | src/core/qqmlstandardpaths.cpp | 8 | ||||
-rw-r--r-- | src/core/qqmlstandardpaths_p.h | 2 | ||||
-rw-r--r-- | src/core/qqmlsysteminformation_p.h | 2 |
13 files changed, 399 insertions, 37 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index fb6f15ffec..90a4c9f786 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -15,15 +15,22 @@ qt_internal_add_qml_module(QmlCore qqmlstandardpaths_p.h qqmlstandardpaths.cpp qqmlcoreglobal_p.h - qqmlsettings_p.h - qqmlsettings.cpp DEFINES QT_BUILD_QML_CORE_LIB PUBLIC_LIBRARIES Qt::Core Qt::Qml - GENERATE_CPP_EXPORTS - GENERATE_PRIVATE_CPP_EXPORTS + ) + +qt_internal_extend_target(QmlCore CONDITION QT_FEATURE_settings + SOURCES + qqmlsettings_p.h + qqmlsettings.cpp +) + +qt_internal_extend_target(QmlCore CONDITION QT_FEATURE_permissions + SOURCES + qqmlpermissions_p.h ) qt_internal_add_docs(QmlCore diff --git a/src/core/doc/qtqmlcore.qdocconf b/src/core/doc/qtqmlcore.qdocconf index 6e1ebb4fe6..47722f7de3 100644 --- a/src/core/doc/qtqmlcore.qdocconf +++ b/src/core/doc/qtqmlcore.qdocconf @@ -1,7 +1,7 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) project = QtQmlCore -description = Qt QML Core Reference Documentation +description = Qt Qml Core Reference Documentation version = $QT_VERSION qhp.projects = QtQmlCore @@ -9,12 +9,12 @@ qhp.projects = QtQmlCore qhp.QtQmlCore.file = qtqmlcore.qhp qhp.QtQmlCore.namespace = org.qt-project.qtqmlcore.$QT_VERSION_TAG qhp.QtQmlCore.virtualFolder = qtqmlcore -qhp.QtQmlCore.indexTitle = Qt QML Core +qhp.QtQmlCore.indexTitle = Qt Qml Core qhp.QtQmlCore.indexRoot = qhp.QtQmlCore.subprojects = qmltypes qhp.QtQmlCore.subprojects.qmltypes.title = QML Types -qhp.QtQmlCore.subprojects.qmltypes.indexTitle = Qt QML Core QML Types +qhp.QtQmlCore.subprojects.qmltypes.indexTitle = Qt Qml Core QML Types qhp.QtQmlCore.subprojects.qmltypes.selectors = qmlclass qhp.QtQmlCore.subprojects.qmltypes.sortPages = true @@ -28,10 +28,10 @@ sourcedirs += ../ imagedirs += images -navigation.landingpage = "Qt QML Core" -navigation.qmltypespage = "Qt QML Core QML Types" +navigation.landingpage = "Qt Qml Core" +navigation.qmltypespage = "Qt Qml Core QML Types" tagfile = qtqmlcore.tags -# Fail the documentation build if there are more warnings than the limit +# Enforce zero documentation warnings warninglimit = 0 diff --git a/src/core/doc/src/includes/qmlpermissions.qdocinc b/src/core/doc/src/includes/qmlpermissions.qdocinc new file mode 100644 index 0000000000..6255394511 --- /dev/null +++ b/src/core/doc/src/includes/qmlpermissions.qdocinc @@ -0,0 +1,34 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +//! [type-docs] + \qmltype \1 + \inqmlmodule QtCore + \ingroup qml-permissions + + \brief Access to the user's \3. + + This type represents a \2, and can be used to + check the status of and request access to the user's \3. + + See \2 for documentation of the individual properties + and detailed usage requirements. + + \sa {QML Application Permissions}, {Application Permissions}, \2 +//! [type-docs] + +//! [status-docs] + \qmlproperty Qt::PermissionStatus \1::status + + This property holds the current status of the permission. + + \sa QCoreApplication::checkPermission +//! [status-docs] + +//! [request-docs] + \qmlmethod \1::request() + + Requests the permission with its current properties. + + \sa QCoreApplication::requestPermission +//! [request-docs] diff --git a/src/core/doc/src/qmlpermissions.qdoc b/src/core/doc/src/qmlpermissions.qdoc new file mode 100644 index 0000000000..72c7d23756 --- /dev/null +++ b/src/core/doc/src/qmlpermissions.qdoc @@ -0,0 +1,193 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page qml-application-permissions.html + \title QML Application Permissions + \brief Managing application permissions via QML + + Many features of today's devices and operating systems can have + significant privacy, security, and performance implications if + misused. It's therefore increasingly common for platforms to + require explicit consent from the user before accessing these + features. + + The \l{Qt Qml Core} module exposes the Qt C++ + \l [QtCore] {Application Permissions} functionality to QML via a set of + permission types that can be used to check or request permission in a cross + platform manner. + + \annotatedlist qml-permissions + + \section1 Usage + + To check and request a specific permission in your application, + include an instance of the appropriate permission type, and set + any of its properties if needed: + + \qml + CalendarPermission { + id: calendarPermission + accessMode: CalendarPermission.ReadWrite + } + \endqml + + The type can be used to check the current state of the + permissions, for example to drive a state based UI: + + \qml + states: [ + State { + name: "waitingForPermission" + when: calendarPermission.status == Qt.PermissionStatus.Undetermined + PropertyChanges { target: permissionRequestItem; visible: true } + }, + State { + name: "permissionDenied" + when: calendarPermission.status == Qt.PermissionStatus.Denied + PropertyChanges { target: permissionDeniedItem; visible: true } + } + ] + \endqml + + In the example above, two permission specific items will be overlaid if the + permission status is not granted. The request UI could perhaps look like: + + \qml + Rectangle { + id: permissionRequestItem + anchors.fill: parent + visible: false + + Text { + anchors.centerIn: parent + text: qsTr("We need your permission to access the calendar." + + "Please tap this screen to request permission.") + + } + + MouseArea { + anchors.fill: parent + onClicked: calendarPermission.request() + } + } + \endqml + + With a corresponding denied UI: + + \qml + Rectangle { + id: permissionDeniedItem + anchors.fill: parent + color: "red" + visible: false + Text { + anchors.centerIn: parent + text: qsTr("We need your permission to access the calendar," + + "but permission was not granted. Please resolve.") + } + } + \endqml + + \section2 Changing permission properties + + The properties of a permission can be changed, even after + a request has been initiated by calling `request()`. This + will update the status, if it changes a result of the new + property values, but will not result in an automatic request + using the new set of properties. + + For example, if upgrading an already granted calendar permission + for access mode \c Qt.CalendarPermission.ReadOnly to + \c Qt.CalendarPermission.ReadWrite, the platform will + respond in one of three ways: + + \list + \li By implicitly granting the extended permission, for example + because the platform doesn't distinguish between the two + access modes, which will result in no state change. + \li By moving the status back to \ Undetermined, so that + the user can be consulted again for access to the now + extended permission. + \li By moving the status to \c Denied, for example if permissions + can not be upgraded once initially requested. + \endlist + + All these states should then move the application's UI into + the appropriate state, where the user is informed of the + new state, with the possibility of requesting the new + permission if possible, or reverting to a less extensive + permission. + + \section2 Interaction between permission items + + Although the permission state is ultimately tied to the + underlying application, each permission item reports its own + status independently of all other items, and needs to be + independently requested if needed. + + For example, requesting calendar access for one item will + not update the status of another CalendarPermission item, + even if these have the exact same properties. +*/ + +/*! + \include qmlpermissions.qdocinc {type-docs} {CalendarPermission} {QCalendarPermission} {calendar} + \since 6.6 +*/ +/*! + \include qmlpermissions.qdocinc {status-docs} {CalendarPermission} +*/ +/*! + \include qmlpermissions.qdocinc {request-docs} {CalendarPermission} +*/ +/*! + \include qmlpermissions.qdocinc {type-docs} {ContactsPermission} {QContactsPermission} {contacts} + \since 6.6 +*/ +/*! + \include qmlpermissions.qdocinc {status-docs} {ContactsPermission} +*/ +/*! + \include qmlpermissions.qdocinc {request-docs} {ContactsPermission} +*/ +/*! + \include qmlpermissions.qdocinc {type-docs} {CameraPermission} {QCameraPermission} {camera} + \since 6.6 +*/ +/*! + \include qmlpermissions.qdocinc {status-docs} {CameraPermission} +*/ +/*! + \include qmlpermissions.qdocinc {request-docs} {CameraPermission} +*/ +/*! + \include qmlpermissions.qdocinc {type-docs} {MicrophonePermission} {QMicrophonePermission} {microphone} + \since 6.6 +*/ +/*! + \include qmlpermissions.qdocinc {status-docs} {MicrophonePermission} +*/ +/*! + \include qmlpermissions.qdocinc {request-docs} {MicrophonePermission} +*/ +/*! + \include qmlpermissions.qdocinc {type-docs} {BluetoothPermission} {QBluetoothPermission} {Bluetooth peripherals} + \since 6.6 +*/ +/*! + \include qmlpermissions.qdocinc {status-docs} {BluetoothPermission} +*/ +/*! + \include qmlpermissions.qdocinc {request-docs} {BluetoothPermission} +*/ +/*! + \include qmlpermissions.qdocinc {type-docs} {LocationPermission} {QLocationPermission} {location} + \since 6.6 +*/ +/*! + \include qmlpermissions.qdocinc {status-docs} {LocationPermission} +*/ +/*! + \include qmlpermissions.qdocinc {request-docs} {LocationPermission} +*/ diff --git a/src/core/doc/src/qtqmlcore-qmltypes.qdoc b/src/core/doc/src/qtqmlcore-qmltypes.qdoc index c49dc6acd3..47349c380a 100644 --- a/src/core/doc/src/qtqmlcore-qmltypes.qdoc +++ b/src/core/doc/src/qtqmlcore-qmltypes.qdoc @@ -2,12 +2,12 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! - \qmlmodule QtCore 6.\QtMinorVersion - \title Qt QML Core QML Types + \qmlmodule QtCore + \title Qt Qml Core QML Types \ingroup qmlmodules \brief Provides core system functionality in QML. - The Qt QML Core module provides core system functionality in QML. + The Qt Qml Core module provides core system functionality in QML. The QML types can be imported into your application using the following import statement in your .qml file: @@ -24,7 +24,7 @@ \list \li \l {Qt Core} - \li \l {Qt QML QML Types}{Base QML Types} + \li \l {Qt Qml QML Types}{Base QML Types} \endlist \noautolist diff --git a/src/core/doc/src/qtqmlcore.qdoc b/src/core/doc/src/qtqmlcore.qdoc index 59ec6ea556..cf7d71727c 100644 --- a/src/core/doc/src/qtqmlcore.qdoc +++ b/src/core/doc/src/qtqmlcore.qdoc @@ -3,9 +3,17 @@ /*! \page qtqmlcore-index.html - \title Qt QML Core + \title Qt Qml Core - \brief The Qt QML Core module provides core system functionality in QML. + \brief The Qt Qml Core module provides core system functionality in QML. + + \section1 Application Permissions + + The module exposes the Qt C++ \l [QtCore] {Application Permissions} + functionality to QML via a set of permission types that + can be used to check or request permission in a cross + platform manner. See \l{QML Application Permissions} + for more details. \section1 QML Types @@ -15,6 +23,6 @@ \list \li \l{Qt Core} - \li \l{Qt QML} + \li \l{Qt Qml} \endlist */ diff --git a/src/core/qqmlcoreglobal_p.h b/src/core/qqmlcoreglobal_p.h index 686a61d0b1..57bb5b0f93 100644 --- a/src/core/qqmlcoreglobal_p.h +++ b/src/core/qqmlcoreglobal_p.h @@ -16,6 +16,6 @@ // #include <QtCore/qglobal.h> -#include <QtQmlCore/private/qtqmlcoreexports_p.h> +#include <QtQmlCore/qtqmlcoreexports.h> #endif // QQMLCOREGLOBAL_P_H diff --git a/src/core/qqmlpermissions_p.h b/src/core/qqmlpermissions_p.h new file mode 100644 index 0000000000..6bba2d1c6a --- /dev/null +++ b/src/core/qqmlpermissions_p.h @@ -0,0 +1,117 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QQMLPERMISSIONS_P_H +#define QQMLPERMISSIONS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qqmlglobal_p.h> + +#if QT_CONFIG(permissions) + +#include <QtQml/qqmlregistration.h> + +#include <QtCore/qpermissions.h> +#include <QtCore/qnamespace.h> +#include <QtCore/qproperty.h> +#include <QtCore/qglobal.h> + +#include <QtCore/qcoreapplication.h> + +QT_BEGIN_NAMESPACE + +#define QML_PERMISSION(Permission) \ + Q_OBJECT \ + QML_NAMED_ELEMENT(Permission) \ +public: \ + Q_PROPERTY(Qt::PermissionStatus status READ status NOTIFY statusChanged) \ + Qt::PermissionStatus status() const { return qApp->checkPermission(m_permission); } \ + Q_SIGNAL void statusChanged(); \ + Q_INVOKABLE void request() { \ + const auto previousStatus = status(); \ + qApp->requestPermission(m_permission, this, \ + [this, previousStatus](const QPermission &permission) { \ + if (previousStatus != permission.status()) \ + emit statusChanged(); \ + }); \ + } \ +private: \ + Q##Permission m_permission; \ +public: + +#define QML_PERMISSION_PROPERTY(PropertyType, getterName, setterName) \ + Q_PROPERTY(PropertyType getterName READ getterName WRITE setterName NOTIFY getterName##Changed) \ + PropertyType getterName() const { return m_permission.getterName(); } \ + void setterName(const PropertyType &value) { \ + const auto previousValue = m_permission.getterName(); \ + const auto previousStatus = status(); \ + m_permission.setterName(value); \ + if (m_permission.getterName() != previousValue) { \ + emit getterName##Changed(); \ + if (status() != previousStatus) \ + emit statusChanged(); \ + } \ + } \ + Q_SIGNAL void getterName##Changed(); + + +struct QQmlQLocationPermission : public QObject +{ + QML_PERMISSION(LocationPermission) + QML_ADDED_IN_VERSION(6, 6) + QML_EXTENDED_NAMESPACE(QLocationPermission) + QML_PERMISSION_PROPERTY(QLocationPermission::Availability, availability, setAvailability) + QML_PERMISSION_PROPERTY(QLocationPermission::Accuracy, accuracy, setAccuracy) +}; + +struct QQmlCalendarPermission : public QObject +{ + QML_PERMISSION(CalendarPermission) + QML_ADDED_IN_VERSION(6, 6) + QML_EXTENDED_NAMESPACE(QCalendarPermission) + QML_PERMISSION_PROPERTY(QCalendarPermission::AccessMode, accessMode, setAccessMode) +}; + +struct QQmlContactsPermission : public QObject +{ + QML_PERMISSION(ContactsPermission) + QML_ADDED_IN_VERSION(6, 6) + QML_EXTENDED_NAMESPACE(QContactsPermission) + QML_PERMISSION_PROPERTY(QContactsPermission::AccessMode, accessMode, setAccessMode) +}; + +struct QQmlBluetoothPermission : public QObject +{ + QML_PERMISSION(BluetoothPermission) + QML_ADDED_IN_VERSION(6, 6) + QML_EXTENDED_NAMESPACE(QBluetoothPermission) + QML_PERMISSION_PROPERTY(QBluetoothPermission::CommunicationModes, communicationModes, setCommunicationModes) +}; + +struct QQmlCameraPermission : public QObject +{ + QML_PERMISSION(CameraPermission) + QML_ADDED_IN_VERSION(6, 6) +}; + +struct QQmlMicrophonePermission : public QObject +{ + QML_PERMISSION(MicrophonePermission) + QML_ADDED_IN_VERSION(6, 6) +}; + +QT_END_NAMESPACE + +#endif // QT_CONFIG(permissions) + +#endif // QQMLPERMISSIONS_P_H diff --git a/src/core/qqmlsettings.cpp b/src/core/qqmlsettings.cpp index 1b4481cfc7..0b3bc9ebd3 100644 --- a/src/core/qqmlsettings.cpp +++ b/src/core/qqmlsettings.cpp @@ -2,15 +2,18 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qqmlsettings_p.h" -#include <qcoreevent.h> -#include <qcoreapplication.h> -#include <qloggingcategory.h> -#include <qsettings.h> -#include <qpointer.h> -#include <qjsvalue.h> -#include <qqmlinfo.h> -#include <qdebug.h> -#include <qhash.h> + +#include <QtQml/qjsvalue.h> +#include <QtQml/qqmlfile.h> +#include <QtQml/qqmlinfo.h> + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qcoreevent.h> +#include <QtCore/qdebug.h> +#include <QtCore/qhash.h> +#include <QtCore/qloggingcategory.h> +#include <QtCore/qpointer.h> +#include <QtCore/qsettings.h> QT_BEGIN_NAMESPACE @@ -236,7 +239,9 @@ QSettings *QQmlSettingsPrivate::instance() const return settings; QQmlSettings *q = const_cast<QQmlSettings *>(q_func()); - settings = location.isLocalFile() ? new QSettings(location.toLocalFile(), QSettings::IniFormat, q) : new QSettings(q); + settings = QQmlFile::isLocalFile(location) + ? new QSettings(QQmlFile::urlToLocalFileOrQrc(location), QSettings::IniFormat, q) + : new QSettings(q); if (settings->status() != QSettings::NoError) { // TODO: can't print out the enum due to the following error: @@ -379,6 +384,8 @@ QQmlSettings::~QQmlSettings() This property holds the name of the settings category. Categories can be used to group related settings together. + + \sa QSettings::group */ QString QQmlSettings::category() const { diff --git a/src/core/qqmlsettings_p.h b/src/core/qqmlsettings_p.h index 90d664efaf..1a6a5be463 100644 --- a/src/core/qqmlsettings_p.h +++ b/src/core/qqmlsettings_p.h @@ -26,7 +26,7 @@ QT_BEGIN_NAMESPACE class QQmlSettingsPrivate; -class Q_QMLCORE_PRIVATE_EXPORT QQmlSettings : public QObject, public QQmlParserStatus +class Q_QMLCORE_EXPORT QQmlSettings : public QObject, public QQmlParserStatus { Q_OBJECT Q_INTERFACES(QQmlParserStatus) diff --git a/src/core/qqmlstandardpaths.cpp b/src/core/qqmlstandardpaths.cpp index ea4c534568..a06b9e3454 100644 --- a/src/core/qqmlstandardpaths.cpp +++ b/src/core/qqmlstandardpaths.cpp @@ -28,12 +28,8 @@ static QList<QUrl> toUrlList(const QStringList &paths) { QList<QUrl> urls; urls.reserve(paths.size()); - for (const QString &path : paths) { - QUrl url = QUrl(path); - if (url.scheme().isEmpty()) - url = QUrl::fromLocalFile(path); - urls += url; - } + for (const QString &path : paths) + urls += QUrl::fromLocalFile(path); return urls; } diff --git a/src/core/qqmlstandardpaths_p.h b/src/core/qqmlstandardpaths_p.h index fb4d1494b0..b9e82f1656 100644 --- a/src/core/qqmlstandardpaths_p.h +++ b/src/core/qqmlstandardpaths_p.h @@ -26,7 +26,7 @@ QT_BEGIN_NAMESPACE class QQmlEngine; class QJSEngine; -class Q_QMLCORE_PRIVATE_EXPORT QQmlStandardPaths : public QObject +class Q_QMLCORE_EXPORT QQmlStandardPaths : public QObject { Q_OBJECT QML_SINGLETON diff --git a/src/core/qqmlsysteminformation_p.h b/src/core/qqmlsysteminformation_p.h index 868bce1823..e01a5c42c6 100644 --- a/src/core/qqmlsysteminformation_p.h +++ b/src/core/qqmlsysteminformation_p.h @@ -20,7 +20,7 @@ #include <QtQml/qqmlregistration.h> QT_BEGIN_NAMESPACE -class Q_QMLCORE_PRIVATE_EXPORT QQmlSystemInformation : public QObject +class Q_QMLCORE_EXPORT QQmlSystemInformation : public QObject { Q_OBJECT QML_SINGLETON |