diff options
Diffstat (limited to 'examples/nfc')
90 files changed, 1532 insertions, 3099 deletions
diff --git a/examples/nfc/CMakeLists.txt b/examples/nfc/CMakeLists.txt new file mode 100644 index 00000000..96cd6112 --- /dev/null +++ b/examples/nfc/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +if(TARGET Qt6::Widgets) + qt_internal_add_example(annotatedurl) +endif() +if(TARGET Qt6::QuickControls2) + qt_internal_add_example(ndefeditor) +endif() diff --git a/examples/nfc/annotatedurl/CMakeLists.txt b/examples/nfc/annotatedurl/CMakeLists.txt new file mode 100644 index 00000000..a51a2052 --- /dev/null +++ b/examples/nfc/annotatedurl/CMakeLists.txt @@ -0,0 +1,55 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(annotatedurl LANGUAGES CXX) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/nfc/annotatedurl") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Nfc Widgets) + +qt_standard_project_setup() + +qt_add_executable(annotatedurl + MANUAL_FINALIZATION + annotatedurl.cpp annotatedurl.h + main.cpp + mainwindow.cpp mainwindow.h +) + +set_target_properties(annotatedurl PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +if(IOS) + set_target_properties(annotatedurl PROPERTIES + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist" + ) +endif() + +target_link_libraries(annotatedurl PRIVATE + Qt6::Core + Qt6::Gui + Qt6::Nfc + Qt6::Widgets +) + +if(ANDROID) + set_property(TARGET annotatedurl + APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR + ${CMAKE_CURRENT_SOURCE_DIR}/android + ) +endif() + +qt_finalize_target(annotatedurl) + +install(TARGETS annotatedurl + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/nfc/annotatedurl/Info.plist b/examples/nfc/annotatedurl/Info.plist new file mode 100644 index 00000000..7813167f --- /dev/null +++ b/examples/nfc/annotatedurl/Info.plist @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDisplayName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundleExecutable</key> + <string>${EXECUTABLE_NAME}</string> + <key>CFBundleIconFile</key> + <string>${ASSETCATALOG_COMPILER_APPICON_NAME}</string> + <key>CFBundleIdentifier</key> + <string>${PRODUCT_BUNDLE_IDENTIFIER}</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>${QMAKE_SHORT_VERSION}</string> + <key>CFBundleSignature</key> + <string>${QMAKE_PKGINFO_TYPEINFO}</string> + <key>CFBundleVersion</key> + <string>${QMAKE_FULL_VERSION}</string> + <key>LSRequiresIPhoneOS</key> + <true/> + <key>MinimumOSVersion</key> + <string>${IPHONEOS_DEPLOYMENT_TARGET}</string> + <key>NFCReaderUsageDescription</key> + <string>Qt's annotatedurl wants to access your NFC hardware</string> + <key>UILaunchStoryboardName</key> + <string>LaunchScreen</string> + <key>UISupportedInterfaceOrientations</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + <string>UIInterfaceOrientationPortraitUpsideDown</string> + <string>UIInterfaceOrientationLandscapeLeft</string> + <string>UIInterfaceOrientationLandscapeRight</string> + </array> +</dict> +</plist> diff --git a/examples/nfc/annotatedurl/android/AndroidManifest.xml b/examples/nfc/annotatedurl/android/AndroidManifest.xml new file mode 100644 index 00000000..101900ab --- /dev/null +++ b/examples/nfc/annotatedurl/android/AndroidManifest.xml @@ -0,0 +1,32 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.qtproject.annotatedurl" + android:installLocation="auto" + android:versionCode="-- %%INSERT_VERSION_CODE%% --" + android:versionName="-- %%INSERT_VERSION_NAME%% --"> + <!-- %%INSERT_PERMISSIONS --> + <!-- %%INSERT_FEATURES --> + <supports-screens android:anyDensity="true" + android:largeScreens="true" + android:normalScreens="true" + android:smallScreens="true"/> + <application android:name="org.qtproject.qt.android.bindings.QtApplication" + android:hardwareAccelerated="true" + android:label="-- %%INSERT_APP_NAME%% --" + android:requestLegacyExternalStorage="true" + android:allowBackup="true" + android:fullBackupOnly="false" + android:icon="@drawable/icon"> + <activity android:name="org.qtproject.qt.android.bindings.QtActivity" + android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" + android:launchMode="singleTop" + android:screenOrientation="unspecified" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + <meta-data android:name="android.app.lib_name" + android:value="-- %%INSERT_APP_LIB_NAME%% --"/> + </activity> + </application> +</manifest> diff --git a/examples/nfc/annotatedurl/annotatedurl.cpp b/examples/nfc/annotatedurl/annotatedurl.cpp index acd401f2..33d5109e 100644 --- a/examples/nfc/annotatedurl/annotatedurl.cpp +++ b/examples/nfc/annotatedurl/annotatedurl.cpp @@ -1,98 +1,41 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module. -** -** $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$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "annotatedurl.h" -#include <QtNfc/qnearfieldmanager.h> -#include <QtNfc/qnearfieldtarget.h> -#include <QtNfc/qndefmessage.h> -#include <QtNfc/qndefrecord.h> -#include <QtNfc/qndefnfctextrecord.h> -#include <QtNfc/qndefnfcurirecord.h> - -#include <QtWidgets/QGridLayout> -#include <QtWidgets/QLabel> -#include <QtGui/QMouseEvent> -#include <QtGui/QDesktopServices> -#include <QtCore/QDebug> -#include <QtCore/QLocale> -#include <QtCore/QUrl> +#include <QDebug> +#include <QLocale> +#include <QUrl> -AnnotatedUrl::AnnotatedUrl(QObject *parent) -: QObject(parent) -{ - //! [QNearFieldManager register handler] - manager = new QNearFieldManager(this); - if (!manager->isAvailable()) { - qWarning() << "NFC not available"; - return; - } +#include <QDesktopServices> +#include <QEvent> - QNdefFilter filter; - filter.setOrderMatch(false); - filter.appendRecord<QNdefNfcTextRecord>(1, UINT_MAX); - filter.appendRecord<QNdefNfcUriRecord>(); - // type parameter cannot specify substring so filter for "image/" below - filter.appendRecord(QNdefRecord::Mime, QByteArray(), 0, 1); +#include <QNdefMessage> +#include <QNdefNfcTextRecord> +#include <QNdefNfcUriRecord> +#include <QNdefRecord> +#include <QNearFieldManager> +#include <QNearFieldTarget> - int result = manager->registerNdefMessageHandler(filter, this, - SLOT(handleMessage(QNdefMessage,QNearFieldTarget*))); - //! [QNearFieldManager register handler] +#include <QGridLayout> +#include <QLabel> - if (result < 0) - qWarning() << "Platform does not support NDEF message handler registration"; - - manager->startTargetDetection(); +AnnotatedUrl::AnnotatedUrl(QObject *parent) + : QObject(parent), + manager(new QNearFieldManager(this)) +{ connect(manager, &QNearFieldManager::targetDetected, this, &AnnotatedUrl::targetDetected); connect(manager, &QNearFieldManager::targetLost, this, &AnnotatedUrl::targetLost); + connect(manager, &QNearFieldManager::adapterStateChanged, + this, &AnnotatedUrl::handleAdapterStateChange); + +//! [populateFilter] + messageFilter.setOrderMatch(false); + messageFilter.appendRecord<QNdefNfcTextRecord>(1, 100); + messageFilter.appendRecord<QNdefNfcUriRecord>(1, 1); + messageFilter.appendRecord(QNdefRecord::Mime, "", 0, 1); +//! [populateFilter] } AnnotatedUrl::~AnnotatedUrl() @@ -100,6 +43,18 @@ AnnotatedUrl::~AnnotatedUrl() } +void AnnotatedUrl::startDetection() +{ + if (!manager->isEnabled()) { + qWarning() << "NFC not enabled"; + emit nfcStateChanged(false); + return; + } + + if (manager->startTargetDetection(QNearFieldTarget::NdefAccess)) + emit nfcStateChanged(true); +} + void AnnotatedUrl::targetDetected(QNearFieldTarget *target) { if (!target) @@ -107,6 +62,8 @@ void AnnotatedUrl::targetDetected(QNearFieldTarget *target) connect(target, &QNearFieldTarget::ndefMessageRead, this, &AnnotatedUrl::handlePolledNdefMessage); + connect(target, &QNearFieldTarget::error, this, + [this]() { emit tagError("Tag read error"); }); target->readNdefMessages(); } @@ -122,12 +79,31 @@ void AnnotatedUrl::handlePolledNdefMessage(QNdefMessage message) handleMessage(message, target); } +//! [handleAdapterState] +void AnnotatedUrl::handleAdapterStateChange(QNearFieldManager::AdapterState state) +{ + if (state == QNearFieldManager::AdapterState::Online) { + startDetection(); + } else if (state == QNearFieldManager::AdapterState::Offline) { + manager->stopTargetDetection(); + emit nfcStateChanged(false); + } +} +//! [handleAdapterState] + //! [handleMessage 1] void AnnotatedUrl::handleMessage(const QNdefMessage &message, QNearFieldTarget *target) { //! [handleMessage 1] Q_UNUSED(target); +//! [handleMessage 2] + if (!messageFilter.match(message)) { + emit tagError("Invalid message format"); + return; + } +//! [handleMessage 2] + enum { MatchedNone, MatchedFirst, @@ -142,14 +118,14 @@ void AnnotatedUrl::handleMessage(const QNdefMessage &message, QNearFieldTarget * QUrl url; QPixmap pixmap; -//! [handleMessage 2] +//! [handleMessage 3] for (const QNdefRecord &record : message) { if (record.isRecordType<QNdefNfcTextRecord>()) { QNdefNfcTextRecord textRecord(record); title = textRecord.text(); QLocale locale(textRecord.locale()); -//! [handleMessage 2] +//! [handleMessage 3] // already found best match if (bestMatch == MatchedLanguageAndCountry) { // do nothing @@ -163,7 +139,7 @@ void AnnotatedUrl::handleMessage(const QNdefMessage &message, QNearFieldTarget * } else if (bestMatch == MatchedNone) { bestMatch = MatchedFirst; } -//! [handleMessage 3] +//! [handleMessage 4] } else if (record.isRecordType<QNdefNfcUriRecord>()) { QNdefNfcUriRecord uriRecord(record); @@ -172,10 +148,10 @@ void AnnotatedUrl::handleMessage(const QNdefMessage &message, QNearFieldTarget * record.type().startsWith("image/")) { pixmap = QPixmap::fromImage(QImage::fromData(record.payload())); } -//! [handleMessage 3] //! [handleMessage 4] +//! [handleMessage 5] } emit annotatedUrl(url, title, pixmap); } -//! [handleMessage 4] +//! [handleMessage 5] diff --git a/examples/nfc/annotatedurl/annotatedurl.h b/examples/nfc/annotatedurl/annotatedurl.h index 204bed5f..95404e55 100644 --- a/examples/nfc/annotatedurl/annotatedurl.h +++ b/examples/nfc/annotatedurl/annotatedurl.h @@ -1,64 +1,18 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module. -** -** $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$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #ifndef ANNOTATEDURL_H #define ANNOTATEDURL_H -#include <QtNfc/QNdefMessage> +#include <QNdefFilter> +#include <QNdefMessage> +#include <QNearFieldManager> -#include <QtCore/QObject> +#include <QObject> -QT_FORWARD_DECLARE_CLASS(QUrl) -QT_FORWARD_DECLARE_CLASS(QPixmap) -QT_FORWARD_DECLARE_CLASS(QNearFieldManager) QT_FORWARD_DECLARE_CLASS(QNearFieldTarget) +QT_FORWARD_DECLARE_CLASS(QPixmap) +QT_FORWARD_DECLARE_CLASS(QUrl) //! [0] class AnnotatedUrl : public QObject @@ -69,16 +23,23 @@ public: explicit AnnotatedUrl(QObject *parent = 0); ~AnnotatedUrl(); + void startDetection(); + signals: void annotatedUrl(const QUrl &url, const QString &title, const QPixmap &pixmap); + void nfcStateChanged(bool enabled); + void tagError(const QString &error); public slots: void targetDetected(QNearFieldTarget *target); void targetLost(QNearFieldTarget *target); void handleMessage(const QNdefMessage &message, QNearFieldTarget *target); void handlePolledNdefMessage(QNdefMessage message); + void handleAdapterStateChange(QNearFieldManager::AdapterState state); + private: QNearFieldManager *manager; + QNdefFilter messageFilter; }; //! [0] diff --git a/examples/nfc/annotatedurl/annotatedurl.pro b/examples/nfc/annotatedurl/annotatedurl.pro index e2bb7c06..a9ecf769 100644 --- a/examples/nfc/annotatedurl/annotatedurl.pro +++ b/examples/nfc/annotatedurl/annotatedurl.pro @@ -11,7 +11,14 @@ SOURCES += main.cpp \ HEADERS += mainwindow.h \ annotatedurl.h -FORMS += mainwindow.ui +ios: QMAKE_INFO_PLIST = Info.plist + +android { + ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android + + DISTFILES += \ + android/AndroidManifest.xml +} target.path = $$[QT_INSTALL_EXAMPLES]/nfc/annotatedurl INSTALLS += target diff --git a/examples/nfc/annotatedurl/doc/images/annotatedurl.png b/examples/nfc/annotatedurl/doc/images/annotatedurl.png Binary files differindex 01130ecd..39f2c66e 100644 --- a/examples/nfc/annotatedurl/doc/images/annotatedurl.png +++ b/examples/nfc/annotatedurl/doc/images/annotatedurl.png diff --git a/examples/nfc/annotatedurl/doc/images/annotatedurl2.png b/examples/nfc/annotatedurl/doc/images/annotatedurl2.png Binary files differindex 2ea6f12f..bb6208e9 100644 --- a/examples/nfc/annotatedurl/doc/images/annotatedurl2.png +++ b/examples/nfc/annotatedurl/doc/images/annotatedurl2.png diff --git a/examples/nfc/annotatedurl/doc/images/annotatedurl3.png b/examples/nfc/annotatedurl/doc/images/annotatedurl3.png Binary files differnew file mode 100644 index 00000000..363b7687 --- /dev/null +++ b/examples/nfc/annotatedurl/doc/images/annotatedurl3.png diff --git a/examples/nfc/annotatedurl/doc/src/annotatedurl.qdoc b/examples/nfc/annotatedurl/doc/src/annotatedurl.qdoc index 7fda040f..b76c349f 100644 --- a/examples/nfc/annotatedurl/doc/src/annotatedurl.qdoc +++ b/examples/nfc/annotatedurl/doc/src/annotatedurl.qdoc @@ -1,36 +1,14 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt local connectivty modules. -** -** $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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \example annotatedurl -\title Annotated URL Example -\brief An example showing reading from formatted NFC Data Exchange Format (NDEF) messages. +\title Annotated URL +\examplecategory {Connectivity} +\meta tags {nfc, ndef, widgets} +\brief Reads formatted NFC Data Exchange Format (NDEF) messages. -The Annotated URL example displays the contents of specifically +The Annotated URL example uses \l{Qt NFC} to display the contents of specifically formatted NFC Data Exchange Format (NDEF) messages read from an NFC Tag. The NDEF message should contain a URI record, an optional \c image/* MIME record, and one or more localized Text records. @@ -38,44 +16,115 @@ image/* MIME record, and one or more localized Text records. This is the initial state of the example: \image annotatedurl.png -In this example the NFC Tag used contains a text record. The UI -gets updated accordingly to: +If a tag is touched, its NDEF content will be shown. Here is the UI +for a tag that contains a text record and URI record: \image annotatedurl2.png +When the screen is tapped, the URL will be opened in the browser. + \section1 AnnotatedUrl Class Definition -The \c AnnotatedUrl class wraps the \c QNearFieldManager, the class -providing the NFC Tag detection functionality. NDEF messages are read -by the QNearFieldManager and forwarded to a handler contained in the +The \c AnnotatedUrl class wraps \l QNearFieldManager, the class providing +the NFC Tag detection functionality. NDEF messages are read by +\l QNearFieldManager and forwarded to a handler contained in the \c AnnotatedUrl class. After parsing the NDEF message the class emits -the signal AnnotatedUrl::annotatedUrl(const QUrl &url, const QString -&title, const QPixmap &pixmap). The UI reacts to the signal displaying +the \c annotatedUrl() signal. The UI reacts to the signal displaying the contents of the NDEF message. \snippet annotatedurl/annotatedurl.h 0 +\note The \c startDetection() method is used to defer the actual tag detection +until all the connections between the UI and NFC-related logic are established. +This is important when the application is automatically started once an NFC tag +is touched. Such usecase is currently supported on Android. + +\snippet annotatedurl/main.cpp 0 + +\section1 Message Filtering + +As it is mentioned above, the application supports the NDEF messages of a +specific format. A correct message should contain the following fields: + +\list + \li \e {At least one} NDEF Text record, which will be used as a header. + \li \e {Exactly one} NDEF URI record. + \li \e {An optional} MIME record with an icon. +\endlist + +The order of the records is not strictly specified. + +An instance of \l QNdefFilter is used to validate the NDEF message. The filter +is populated as follows: + +\snippet annotatedurl/annotatedurl.cpp populateFilter + +If the incoming message does not match the filter, an error message is shown: + +\image annotatedurl3.png + +\note The \l {ndefeditor}{NDEF Editor} example application can be used to create +the tags with correct or incorrect message structure. + \section1 AnnotatedUrl Handler Implementation -NFC messages read by the \c QNearFieldManager are forwarded to -AnnotatedUrl::handleMessage. The callback signature details can be -read in \l{QNearFieldManager::registerNdefMessageHandler}. +NFC messages read by the \l QNearFieldManager are forwarded to +\c {AnnotatedUrl::handleMessage}. \snippet annotatedurl/annotatedurl.cpp handleMessage 1 +At first the messages are validated using the \l QNdefFilter::match() method: + +\snippet annotatedurl/annotatedurl.cpp handleMessage 2 + +If the messages have the correct format, the parsing continues. + Because NFC messages are composed of several NDEF records, looping through all of the records allows the extraction of the 3 parameters to be displayed in the UI: the Uri, the Title and the Pixmap: - -\snippet annotatedurl/annotatedurl.cpp handleMessage 2 \snippet annotatedurl/annotatedurl.cpp handleMessage 3 +\snippet annotatedurl/annotatedurl.cpp handleMessage 4 Finally after having extracted the parameters of the NFC message the corresponding signal is emitted so that the UI can handle it. -\snippet annotatedurl/annotatedurl.cpp handleMessage 4 +\snippet annotatedurl/annotatedurl.cpp handleMessage 5 + +\section1 Adapter State Handling + +On Android the adapter state changes can be detected by connecting to the +\l QNearFieldManager::adapterStateChanged() signal. This allows stopping the +detection when the NFC adapter is disabled, and restarting it when the adapter +is enabled again. This approach is implemented in the +\c {AnnotatedUrl::handleAdapterStateChange} slot. + +\snippet annotatedurl/annotatedurl.cpp handleAdapterState + +\section1 Automatic Application Startup + +Android supports automatic application startup when the NDEF tag is touched. +See \l {Qt NFC on Android} for the required changes to the Android manifest +file. + +Introduction of a custom AndroidManifest.xml requires special steps on the +build system side. + +\section2 Building with qmake + +When using qmake, the following needs to be added to the \c {.pro} file: + +\quotefromfile annotatedurl/annotatedurl.pro +\skipto android { +\printuntil } + +\section2 Building with CMake + +When using CMake, the following needs to be added to the \c CMakeLists.txt: +\quotefromfile annotatedurl/CMakeLists.txt +\skipto if(ANDROID) +\printuntil endif() \include examples-run.qdocinc diff --git a/examples/nfc/annotatedurl/main.cpp b/examples/nfc/annotatedurl/main.cpp index 9ce6c1b9..352a959b 100644 --- a/examples/nfc/annotatedurl/main.cpp +++ b/examples/nfc/annotatedurl/main.cpp @@ -1,73 +1,32 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module. -** -** $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$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "annotatedurl.h" #include "mainwindow.h" -#include <QtNfc/qnearfieldmanager.h> -#include <QtNfc/qndefnfctextrecord.h> -#include <QtNfc/qndefnfcurirecord.h> +#include <QNearFieldManager> +#include <QNdefNfcTextRecord> +#include <QNdefNfcUriRecord> -#include <QtWidgets/QApplication> +#include <QApplication> +//! [0] int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow mainWindow; - AnnotatedUrl annotatedUrl; QObject::connect(&annotatedUrl, &AnnotatedUrl::annotatedUrl, &mainWindow, &MainWindow::displayAnnotatedUrl); + QObject::connect(&annotatedUrl, &AnnotatedUrl::nfcStateChanged, + &mainWindow, &MainWindow::nfcStateChanged); + QObject::connect(&annotatedUrl, &AnnotatedUrl::tagError, + &mainWindow, &MainWindow::showTagError); + annotatedUrl.startDetection(); mainWindow.show(); return a.exec(); } +//! [0] diff --git a/examples/nfc/annotatedurl/mainwindow.cpp b/examples/nfc/annotatedurl/mainwindow.cpp index 707c03eb..7b418360 100644 --- a/examples/nfc/annotatedurl/mainwindow.cpp +++ b/examples/nfc/annotatedurl/mainwindow.cpp @@ -1,82 +1,117 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module. -** -** $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$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "mainwindow.h" -#include "ui_mainwindow.h" -#include <QtGui/QDesktopServices> -#include <QtGui/QMouseEvent> -#include <QtCore/QUrl> +#include <QUrl> + +#include <QDesktopServices> +#include <QScreen> + +#include <QLabel> +#include <QLayout> MainWindow::MainWindow(QWidget *parent) -: QMainWindow(parent), ui(new Ui::MainWindow) + : QWidget(parent), + m_titleLabel(new QLabel(this)), + m_infoLabel(new QLabel(tr("Enable NFC"), this)), + m_uriLabel(new QLabel(this)), + m_landscapeIconLabel(new QLabel(this)), + m_portraitIconLabel(new QLabel(this)) { - ui->setupUi(this); + m_titleLabel->setAlignment(Qt::AlignCenter); + m_infoLabel->setAlignment(Qt::AlignCenter); + m_uriLabel->setAlignment(Qt::AlignCenter); + m_landscapeIconLabel->setAlignment(Qt::AlignCenter); + m_portraitIconLabel->setAlignment(Qt::AlignCenter); + + QFont f = m_titleLabel->font(); + f.setBold(true); + m_titleLabel->setFont(f); + + QVBoxLayout *verticalLayout = new QVBoxLayout; + verticalLayout->addWidget(m_titleLabel); + verticalLayout->addWidget(m_infoLabel); + verticalLayout->addWidget(m_portraitIconLabel); + verticalLayout->addWidget(m_uriLabel); + + QHBoxLayout *horizontalLayout = new QHBoxLayout; + horizontalLayout->addWidget(m_landscapeIconLabel); + horizontalLayout->addLayout(verticalLayout); + horizontalLayout->setSpacing(0); + + setLayout(horizontalLayout); + + handleScreenChange(); } MainWindow::~MainWindow() { - delete ui; } void MainWindow::displayAnnotatedUrl(const QUrl &url, const QString &title, const QPixmap &pixmap) { - ui->m_help->setHidden(true); + m_infoLabel->setHidden(true); + + m_uriLabel->setText(url.toString()); + m_titleLabel->setText(title); + + m_pixmap = pixmap; + updateWidgetLayout(m_screen->orientation()); +} + +void MainWindow::nfcStateChanged(bool enabled) +{ + const QString text = enabled ? "Touch a tag" : "Enable NFC"; + m_infoLabel->setText(text); +} + +void MainWindow::showTagError(const QString &message) +{ + m_uriLabel->clear(); + m_titleLabel->clear(); + m_pixmap = QPixmap(); + m_landscapeIconLabel->setVisible(false); + m_portraitIconLabel->setVisible(false); - ui->m_url->setText(url.toString()); - ui->m_title->setText(title); - ui->m_image->setPixmap(pixmap); + m_infoLabel->setHidden(false); + m_infoLabel->setText(message); } -void MainWindow::mouseReleaseEvent(QMouseEvent *event) +void MainWindow::mouseReleaseEvent(QMouseEvent * /*event*/) { - if (ui->centralWidget->rect().contains(event->pos())) - QDesktopServices::openUrl(QUrl(ui->m_url->text())); + QDesktopServices::openUrl(QUrl(m_uriLabel->text())); +} + +void MainWindow::moveEvent(QMoveEvent * /*event*/) +{ + if (screen() != m_screen) + handleScreenChange(); +} + +void MainWindow::updateWidgetLayout(Qt::ScreenOrientation orientation) +{ + m_landscapeIconLabel->setVisible(false); + m_portraitIconLabel->setVisible(false); + if (!m_pixmap.isNull()) { + const bool landscapeMode = (orientation == Qt::LandscapeOrientation) + || (orientation == Qt::InvertedLandscapeOrientation); + QLabel *imageLabel = landscapeMode ? m_landscapeIconLabel : m_portraitIconLabel; + imageLabel->setVisible(true); + if (m_pixmap.width() > imageLabel->width() || m_pixmap.height() > imageLabel->height()) + imageLabel->setPixmap(m_pixmap.scaled(imageLabel->size(), Qt::KeepAspectRatio)); + else + imageLabel->setPixmap(m_pixmap); + } +} + +void MainWindow::handleScreenChange() +{ + if (m_screen) + disconnect(m_screen, &QScreen::orientationChanged, this, &MainWindow::updateWidgetLayout); + + m_screen = screen(); + connect(m_screen, &QScreen::orientationChanged, this, &MainWindow::updateWidgetLayout); + + updateWidgetLayout(m_screen->orientation()); } diff --git a/examples/nfc/annotatedurl/mainwindow.h b/examples/nfc/annotatedurl/mainwindow.h index 9cfb6e7f..059c7038 100644 --- a/examples/nfc/annotatedurl/mainwindow.h +++ b/examples/nfc/annotatedurl/mainwindow.h @@ -1,71 +1,20 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module. -** -** $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$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #ifndef MAINWINDOW_H #define MAINWINDOW_H -#include <QtWidgets/QMainWindow> +#include <QPixmap> + +#include <QWidget> QT_FORWARD_DECLARE_CLASS(QMouseEvent) QT_FORWARD_DECLARE_CLASS(QUrl) -QT_FORWARD_DECLARE_CLASS(QPixmap) QT_FORWARD_DECLARE_CLASS(QString) -QT_FORWARD_DECLARE_CLASS(QWidget) - -QT_BEGIN_NAMESPACE -namespace Ui { - class MainWindow; -} -QT_END_NAMESPACE +QT_FORWARD_DECLARE_CLASS(QLabel) +QT_FORWARD_DECLARE_CLASS(QScreen) -class MainWindow : public QMainWindow +class MainWindow : public QWidget { Q_OBJECT @@ -75,12 +24,26 @@ public: public slots: void displayAnnotatedUrl(const QUrl &url, const QString &title, const QPixmap &pixmap); + void nfcStateChanged(bool enabled); + void showTagError(const QString &message); protected: - void mouseReleaseEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event) override; + void moveEvent(QMoveEvent *event) override; + +private slots: + void updateWidgetLayout(Qt::ScreenOrientation orientation); private: - Ui::MainWindow *ui; + void handleScreenChange(); + + QLabel *m_titleLabel; + QLabel *m_infoLabel; + QLabel *m_uriLabel; + QLabel *m_landscapeIconLabel; + QLabel *m_portraitIconLabel; + QScreen *m_screen = nullptr; + QPixmap m_pixmap; }; #endif // MAINWINDOW_H diff --git a/examples/nfc/annotatedurl/mainwindow.ui b/examples/nfc/annotatedurl/mainwindow.ui deleted file mode 100644 index 26e3b302..00000000 --- a/examples/nfc/annotatedurl/mainwindow.ui +++ /dev/null @@ -1,61 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>MainWindow</class> - <widget class="QMainWindow" name="MainWindow"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>590</width> - <height>420</height> - </rect> - </property> - <property name="windowTitle"> - <string>MainWindow</string> - </property> - <widget class="QWidget" name="centralWidget"> - <layout class="QGridLayout" name="gridLayout" rowstretch="1,0,1" columnstretch="0,0,0"> - <item row="0" column="1" colspan="2"> - <widget class="QLabel" name="m_title"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item row="0" column="0" rowspan="3"> - <widget class="QLabel" name="m_image"> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLabel" name="m_help"> - <property name="text"> - <string>Touch a tag</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item row="2" column="1" colspan="2"> - <widget class="QLabel" name="m_url"> - <property name="text"> - <string/> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - <layoutdefault spacing="6" margin="11"/> - <resources/> - <connections/> -</ui> diff --git a/examples/nfc/corkboard/Mode.qml b/examples/nfc/corkboard/Mode.qml deleted file mode 100644 index 0d427cf5..00000000 --- a/examples/nfc/corkboard/Mode.qml +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Copyright (C) 2014 BlackBerry Limited. All rights reserved. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the QtNfc module. -** -** $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.4 - -Item { - id: page - width: ListView.view.width; - height: ListView.view.height - - Image { - source: "qrc:/cork.jpg" - anchors.centerIn: parent - width: parent.width - 20 - height: parent.height - 20 - fillMode: Image.PreserveAspectCrop - - Text { - anchors { horizontalCenter: parent.horizontalCenter; top: parent.top; topMargin: 10} - text: name; - font { pixelSize: 30; bold: true } - color: "white" - style: Text.Outline; styleColor: "black" - } - - Repeater { - model: notes - Item { - id: stickyPage - - x: ListView.width * (0.7 * Math.random() + 0.1) - y: ListView.height * (0.7 * Math.random() + 0.1) - - rotation: -listView.horizontalVelocity / 200; - Behavior on rotation { - SpringAnimation { spring: 2.0; damping: 0.15 } - } - - Item { - id: sticky - scale: mouse.pressed ? 1 : 0.7 - rotation: mouse.pressed ? 8 : 0 - Behavior on rotation{ - NumberAnimation {duration: 200 } - } - Behavior on scale{ - NumberAnimation { duration: 200 } - } - - Image { - id: stickyImage - x: 8 + -width * 0.6 / 2; y: -20 - source: "qrc:/note-yellow.png" - scale: 0.6; transformOrigin: Item.TopLeft - smooth: true - } - - TextEdit { - id: myText - text: noteText - x: -104; y: 36; width: 215; height: 200 - smooth: true - font.pixelSize: 24 - readOnly: false - rotation: -8 - wrapMode: TextEdit.Wrap - } - - Item { - id: interactionItem - x: stickyImage.x; y: -20 - width: stickyImage.width * stickyImage.scale - height: stickyImage.height * stickyImage.scale - - MouseArea { - id: mouse - anchors.fill: parent - drag.target: stickyPage - drag.axis: Drag.XandYAxis - } - Image { - id: writeButton - source: "qrc:/NfcFlag.png" - rotation: -8 // Note image itself is rotated - anchors { bottom: parent.bottom; right:parent.right } - scale: flagMouse.pressed ? 1.3 : 1 - MouseArea { - id: flagMouse - anchors.fill: parent - } - } - } - } - - Image { - x: -width / 2; y: -height * 0.5 / 2 - source: "qrc:/tack.png" - scale: 0.7; transformOrigin: Item.TopLeft - } - } - } - } -} - - - - - - - - diff --git a/examples/nfc/corkboard/NfcFlag.png b/examples/nfc/corkboard/NfcFlag.png Binary files differdeleted file mode 100644 index 6d2b9f89..00000000 --- a/examples/nfc/corkboard/NfcFlag.png +++ /dev/null diff --git a/examples/nfc/corkboard/android/AndroidManifest.xml b/examples/nfc/corkboard/android/AndroidManifest.xml deleted file mode 100644 index 3aec51ae..00000000 --- a/examples/nfc/corkboard/android/AndroidManifest.xml +++ /dev/null @@ -1,84 +0,0 @@ -<?xml version='1.0' encoding='utf-8'?> -<manifest package="org.qtproject.example" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto" android:extractNativeLibs="true"> - <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --"> - <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" - android:name="org.qtproject.qt5.android.bindings.QtActivity" - android:label="-- %%INSERT_APP_NAME%% --" - android:screenOrientation="unspecified" - android:launchMode="singleTop"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - <intent-filter> - <action android:name="android.nfc.action.NDEF_DISCOVERED"/> - <category android:name="android.intent.category.DEFAULT"/> - <data android:mimeType="text/plain"/> - </intent-filter> - - <!-- Application arguments --> - <!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ --> - <!-- Application arguments --> - - <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/> - <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/> - <meta-data android:name="android.app.repository" android:value="default"/> - <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/> - <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/> - <!-- Deploy Qt libs as part of package --> - <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/> - <!-- Run with local libs --> - <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/> - <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/> - <meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/> - <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/> - <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/> - <!-- Messages maps --> - <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/> - <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/> - <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/> - <!-- Messages maps --> - - <!-- Splash screen --> - <!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ --> - <!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ --> - <!-- Splash screen --> - - <!-- Background running --> - <!-- Warning: changing this value to true may cause unexpected crashes if the - application still try to draw after - "applicationStateChanged(Qt::ApplicationSuspended)" - signal is sent! --> - <meta-data android:name="android.app.background_running" android:value="false"/> - <!-- Background running --> - - <!-- auto screen scale factor --> - <meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/> - <!-- auto screen scale factor --> - - <!-- extract android style --> - <!-- available android:values : - * full - useful QWidget & Quick Controls 1 apps - * minimal - useful for Quick Controls 2 apps, it is much faster than "full" - * none - useful for apps that don't use any of the above Qt modules - --> - <meta-data android:name="android.app.extract_android_style" android:value="full"/> - <!-- extract android style --> - </activity> - - <!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices --> - - </application> - - <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="21"/> - <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> - - <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application. - Remove the comment if you do not require these default permissions. --> - <!-- %%INSERT_PERMISSIONS --> - - <!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application. - Remove the comment if you do not require these default features. --> - <!-- %%INSERT_FEATURES --> - -</manifest> diff --git a/examples/nfc/corkboard/cork.jpg b/examples/nfc/corkboard/cork.jpg Binary files differdeleted file mode 100644 index 160bc002..00000000 --- a/examples/nfc/corkboard/cork.jpg +++ /dev/null diff --git a/examples/nfc/corkboard/corkboard.pro b/examples/nfc/corkboard/corkboard.pro deleted file mode 100644 index 858ac65d..00000000 --- a/examples/nfc/corkboard/corkboard.pro +++ /dev/null @@ -1,24 +0,0 @@ -QT += quick nfc - -SOURCES += \ - main.cpp - -TARGET = qml_corkboard -TEMPLATE = app - -RESOURCES += \ - corkboard.qrc - -OTHER_FILES += \ - corkboards.qml \ - Mode.qml - -!android-embedded { -ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android -} - -target.path = $$[QT_INSTALL_EXAMPLES]/nfc/corkboard -INSTALLS += target - -EXAMPLE_FILES += \ - icon.png diff --git a/examples/nfc/corkboard/corkboard.qrc b/examples/nfc/corkboard/corkboard.qrc deleted file mode 100644 index 10d80ce3..00000000 --- a/examples/nfc/corkboard/corkboard.qrc +++ /dev/null @@ -1,10 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>corkboards.qml</file> - <file>NfcFlag.png</file> - <file>tack.png</file> - <file>note-yellow.png</file> - <file>cork.jpg</file> - <file>Mode.qml</file> - </qresource> -</RCC> diff --git a/examples/nfc/corkboard/corkboards.qml b/examples/nfc/corkboard/corkboards.qml deleted file mode 100644 index 92cb6616..00000000 --- a/examples/nfc/corkboard/corkboards.qml +++ /dev/null @@ -1,128 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Copyright (C) 2014 BlackBerry Limited. All rights reserved. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the QtNfc module. -** -** $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.3 -import QtNfc 5.5 - -Rectangle { - width: 800; height: 480 - color: "darkred" - - NearField { - property bool requiresManualPolling: false - orderMatch: false - - onMessageRecordsChanged: { - var i; - for (i = 0; i < messageRecords.length; ++i) { - var data = ""; - if (messageRecords[i].typeNameFormat === NdefRecord.NfcRtd) { - if (messageRecords[i].type === "T") { - data = messageRecords[i].text; - } else if (messageRecords[i].type === "U") { - data = messageRecords[i].uri; - } - } - if (!data) - data = "Unknown content"; - - list.get(listView.currentIndex).notes.append( { - "noteText":data - }) - } - } - - onPollingChanged: { - if (!polling && requiresManualPolling) - polling = true; //restart polling - } - - Component.onCompleted: { - // Polling should be true if - // QNearFieldManager::registerNdefMessageHandler() was successful; - // otherwise the platform requires manual polling mode. - if (!polling) { - requiresManualPolling = true; - polling = true; - } - } - } - - ListModel { - id: list - - ListElement { - name: "Personal" - notes: [ - ListElement { noteText: "Near Field Communication" }, - ListElement { noteText: "Touch a tag and its contents will appear as a new note" } - ] - } - - ListElement { - name: "Work" - notes: [ - ListElement { noteText: "https://www.qt.io" }, - ListElement { noteText: "To write a tag, click the red flag of a note and then touch a tag" } - ] - } - } - - ListView { - id: listView - anchors.fill: parent - orientation: ListView.Horizontal - snapMode: ListView.SnapOneItem - model: list - highlightRangeMode: ListView.StrictlyEnforceRange - delegate: Mode {} - } -} diff --git a/examples/nfc/corkboard/doc/images/corkboard.png b/examples/nfc/corkboard/doc/images/corkboard.png Binary files differdeleted file mode 100644 index 3f54ea18..00000000 --- a/examples/nfc/corkboard/doc/images/corkboard.png +++ /dev/null diff --git a/examples/nfc/corkboard/doc/src/corkboard.qdoc b/examples/nfc/corkboard/doc/src/corkboard.qdoc deleted file mode 100644 index ac21187b..00000000 --- a/examples/nfc/corkboard/doc/src/corkboard.qdoc +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the QtNfc module. -** -** $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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! -\example corkboard -\title QML CorkBoard Example -\brief A QML example about displaying NFC Data Exchange Format (NDEF) messages. - -The QML corkboard example displays the contents of NDEF messages read -from an NFC Tag. Each newly detected NDEF message is added to the -corkboard and can be dragged into an arbitrary position on the -board. The corkboard has a \e Personal and \e Work space. The -workspace can be changed by sliding left or right. - - -\image corkboard.png - -\section1 Implementation details -In the corkboard example, we use the following .qml files: - \list - \li corkboards.qml - \li Mode.qml - \endlist - -The main.cpp holds the application logic to load the main view stored -in the corkboards.qml file. - -\snippet corkboard/main.cpp 0 - -\section1 corkboards.qml details -There are two basic QML components in this file: - \list - \li NearField - \li ListView - \endlist - -The first time the NearField QML type is instantiated, the -Component.onCompleted handler will start the NFC polling process. The -\l [Qml] {NearField} {onMessageRecordsChanged} handler parses NFC -Messages that are detected by the NearField component and builds up a -data model that is passed into the ListView. Additionally, every time the -NearField manager stops the polling process, the onPollingChanged -handler restarts it. - -\quotefromfile corkboard/corkboards.qml -\skipto NearField -\printuntil onMessageRecordsChanged -\dots 8 -\skipuntil } -\skipto onPollingChanged -\printuntil onPollingChanged -\dots 8 -\skipuntil } -\skipto Component -\printuntil Component -\dots 8 -\skipuntil } -\printline } -\skipto ListModel -\printto ListModel - -The ListView component takes a ListModel as parameter (built from the -NFC records). The view of each of the items of the model is defined by -the Mode component (its implementation details can be found in the -file Mode.qml). The data model consists of a list of corkboards. Each -corkboard can display multiple NFC text message records. - -\quotefromfile corkboard/corkboards.qml -\skipto ListView -\printuntil id -\dots 8 -\skipto model -\printuntil model -\dots 8 -\skipto delegate -\printuntil delegate -\skipto } -\printline } - -\section1 Mode.qml details - -A corkboard title is displayed for each of the items that form part -of the data model: - -\quotefromfile corkboard/Mode.qml -\skipto Text -\printuntil } -\printuntil } - -Every text record that was read from an NFC message, is represented by -a sticky note with its own position on the display. Initially the -position is set randomly. The text on the sticky note is set on a -TextField. - -\quotefromfile corkboard/Mode.qml -\skipto Repeater -\printuntil y: -\skipto Item -\dots 16 -\printuntil sticky -\dots 20 -\skipto TextEdit -\printuntil noteText -\dots 24 -\skipto } -\printuntil } -\dots 20 - -\include examples-run.qdocinc - -\sa {Qt NFC} - -*/ diff --git a/examples/nfc/corkboard/icon.png b/examples/nfc/corkboard/icon.png Binary files differdeleted file mode 100644 index b115f836..00000000 --- a/examples/nfc/corkboard/icon.png +++ /dev/null diff --git a/examples/nfc/corkboard/main.cpp b/examples/nfc/corkboard/main.cpp deleted file mode 100644 index 74fad72f..00000000 --- a/examples/nfc/corkboard/main.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Copyright (C) 2014 BlackBerry Limited. All rights reserved. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the QtNfc module. -** -** $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 <QtGui/QGuiApplication> -#include <QtQml/QQmlEngine> -#include <QtQuick/QQuickView> - -//! [0] -int main(int argc, char *argv[]) -{ - QGuiApplication application(argc, argv); - QQuickView view; - view.setSource(QUrl("qrc:/corkboards.qml")); - view.setResizeMode(QQuickView::SizeRootObjectToView); - view.show(); - return application.exec(); -} -//! [0] diff --git a/examples/nfc/corkboard/note-yellow.png b/examples/nfc/corkboard/note-yellow.png Binary files differdeleted file mode 100644 index 3195952a..00000000 --- a/examples/nfc/corkboard/note-yellow.png +++ /dev/null diff --git a/examples/nfc/corkboard/tack.png b/examples/nfc/corkboard/tack.png Binary files differdeleted file mode 100644 index cef2d1cd..00000000 --- a/examples/nfc/corkboard/tack.png +++ /dev/null diff --git a/examples/nfc/ndefeditor/CMakeLists.txt b/examples/nfc/ndefeditor/CMakeLists.txt new file mode 100644 index 00000000..2e295c20 --- /dev/null +++ b/examples/nfc/ndefeditor/CMakeLists.txt @@ -0,0 +1,69 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(ndefeditor LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/nfc/ndefeditor") + +find_package(Qt6 REQUIRED COMPONENTS Core Nfc Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(ndefeditor + main.cpp +) + +set(icon_files) +foreach(icon IN ITEMS add arrow_back file_download file_upload link text_snippet) + foreach(scale IN ITEMS "" "@2" "@3" "@4") + list(APPEND icon_files "icons/ndefeditor/20x20${scale}/${icon}.png") + endforeach() +endforeach() + +qt_add_resources(ndefeditor "theme" FILES + ${icon_files} + icons/ndefeditor/index.theme +) + +qt_add_qml_module(ndefeditor + URI NdefEditor + VERSION 1.0 + QML_FILES + Main.qml + MainWindow.qml + NdefRecordDelegate.qml + SOURCES + nfcmanager.h nfcmanager.cpp + nfctarget.h nfctarget.cpp + ndefmessagemodel.h ndefmessagemodel.cpp +) + +set_target_properties(ndefeditor PROPERTIES + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +if(IOS) + set_target_properties(ndefeditor PROPERTIES + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.cmake.plist" + ) +endif() + +target_link_libraries(ndefeditor PRIVATE + Qt6::Core + Qt6::Nfc + Qt6::Quick +) + +install(TARGETS ndefeditor + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/nfc/ndefeditor/Info.cmake.plist b/examples/nfc/ndefeditor/Info.cmake.plist new file mode 100644 index 00000000..ee87b3b2 --- /dev/null +++ b/examples/nfc/ndefeditor/Info.cmake.plist @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + + <key>CFBundlePackageType</key> + <string>APPL</string> + + <key>CFBundleName</key> + <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> + + <key>CFBundleDisplayName</key> + <string>NDEF Editor</string> + + <key>CFBundleIdentifier</key> + <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> + + <key>CFBundleExecutable</key> + <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> + + <key>CFBundleVersion</key> + <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> + + <key>CFBundleShortVersionString</key> + <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> + + <key>CFBundleIconFile</key> + <string>${MACOSX_BUNDLE_ICON_FILE}</string> + + <key>CFBundleDevelopmentRegion</key> + <string>$(DEVELOPMENT_LANGUAGE)</string> + <key>CFBundleAllowMixedLocalizations</key> + <true/> + + <key>LSRequiresIPhoneOS</key> + <true/> + + <key>NFCReaderUsageDescription</key> + <string>Qt's ndefeditor wants to access your NFC hardware</string> + + <key>UILaunchStoryboardName</key> + <string>LaunchScreen</string> + + <key>UISupportedInterfaceOrientations</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + <string>UIInterfaceOrientationPortraitUpsideDown</string> + <string>UIInterfaceOrientationLandscapeLeft</string> + <string>UIInterfaceOrientationLandscapeRight</string> + </array> +</dict> +</plist> diff --git a/examples/nfc/ndefeditor/Info.qmake.plist b/examples/nfc/ndefeditor/Info.qmake.plist new file mode 100644 index 00000000..079533e6 --- /dev/null +++ b/examples/nfc/ndefeditor/Info.qmake.plist @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + + <key>CFBundlePackageType</key> + <string>APPL</string> + + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> + + <key>CFBundleDisplayName</key> + <string>NDEF Editor</string> + + <key>CFBundleIdentifier</key> + <string>${PRODUCT_BUNDLE_IDENTIFIER}</string> + + <key>CFBundleExecutable</key> + <string>${EXECUTABLE_NAME}</string> + + <key>CFBundleVersion</key> + <string>${QMAKE_FULL_VERSION}</string> + + <key>CFBundleShortVersionString</key> + <string>${QMAKE_SHORT_VERSION}</string> + + <key>CFBundleIconFile</key> + <string>${ASSETCATALOG_COMPILER_APPICON_NAME}</string> + + <key>LSRequiresIPhoneOS</key> + <true/> + + <key>NFCReaderUsageDescription</key> + <string>Qt's ndefeditor wants to access your NFC hardware</string> + + <key>UILaunchStoryboardName</key> + <string>LaunchScreen</string> + + <key>UISupportedInterfaceOrientations</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + <string>UIInterfaceOrientationPortraitUpsideDown</string> + <string>UIInterfaceOrientationLandscapeLeft</string> + <string>UIInterfaceOrientationLandscapeRight</string> + </array> +</dict> +</plist> diff --git a/examples/nfc/ndefeditor/Main.qml b/examples/nfc/ndefeditor/Main.qml new file mode 100644 index 00000000..c5435e26 --- /dev/null +++ b/examples/nfc/ndefeditor/Main.qml @@ -0,0 +1,9 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +MainWindow { + width: 480 + height: 640 + visible: true + title: qsTr("NDEF Editor") +} diff --git a/examples/nfc/ndefeditor/MainWindow.qml b/examples/nfc/ndefeditor/MainWindow.qml new file mode 100644 index 00000000..d32540fb --- /dev/null +++ b/examples/nfc/ndefeditor/MainWindow.qml @@ -0,0 +1,384 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs +import QtQuick.Layouts + +import NdefEditor + +ApplicationWindow { + id: window + + enum TargetDetectedAction { + NoAction, + ReadMessage, + WriteMessage + } + + StackView { + id: stack + initialItem: mainView + anchors.fill: parent + } + + property int targetDetectedAction: MainWindow.NoAction + + Component { + id: mainView + + ColumnLayout { + ToolBar { + Layout.fillWidth: true + + RowLayout { + anchors.fill: parent + Label { + text: qsTr("NDEF Editor") + elide: Label.ElideRight + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + Layout.fillWidth: true + } + } + } + + Pane { + id: writeTab + Layout.fillWidth: true + Layout.fillHeight: true + + Flickable { + anchors.fill: parent + contentHeight: contentItem.childrenRect.height + + ColumnLayout { + width: parent.width + + ItemDelegate { + icon.name: "file_download" + text: qsTr("Read Tag") + Layout.fillWidth: true + + onClicked: window.readTag() + } + + ItemDelegate { + icon.name: "file_upload" + text: qsTr("Write to Tag") + Layout.fillWidth: true + + onClicked: window.writeTag() + } + + ItemDelegate { + icon.name: "add" + text: qsTr("Add a Record") + Layout.fillWidth: true + + onClicked: addRecordMenu.open() + + Menu { + id: addRecordMenu + title: qsTr("Add record") + + MenuItem { + icon.name: "text_snippet" + text: qsTr("Text record") + onTriggered: stack.push(textRecordDialog) + } + MenuItem { + icon.name: "link" + text: qsTr("URI record") + onTriggered: stack.push(uriRecordDialog) + } + } + } + + Item { + implicitHeight: 20 + } + + Label { + text: qsTr( + "Use buttons above to read an NFC tag or add records manually.\n\n" + + "Once added, swipe to the right to access options for each record.") + wrapMode: Text.Wrap + visible: messages.count === 0 + Layout.fillWidth: true + } + + Repeater { + id: messages + model: messageModel + + delegate: NdefRecordDelegate { + Layout.fillWidth: true + + onDeleteClicked: messageModel.removeRow(index) + + onClicked: { + if (recordType === NdefMessageModel.TextRecord) { + stack.push(textRecordDialog, { + text: recordText, + modelIndex: index + }) + } else if (recordType === NdefMessageModel.UriRecord) { + stack.push(uriRecordDialog, { + uri: recordText, + modelIndex: index + }) + } + } + } + } + } + } + } + } + } + + NdefMessageModel { + id: messageModel + } + + NfcManager { + id: nfcManager + onTargetDetected: (target) => { window.handleTargetDetected(target) } + } + + Connections { + id: targetConnections + target: null + + function onNdefMessageRead(message) { + messageModel.message = message + } + + function onRequestCompleted() { + communicationOverlay.close() + window.targetDetectedAction = MainWindow.NoAction + releaseTarget() + } + + function onError(code) { + communicationOverlay.close() + errorNotification.errorMessage = window.describeError(code) + errorNotification.open() + window.targetDetectedAction = MainWindow.NoAction + releaseTarget() + } + + function releaseTarget() { + target?.destroy() + } + } + + function handleTargetDetected(target: NfcTarget) { + targetConnections.releaseTarget() + + let ok = true + + if (targetDetectedAction === MainWindow.ReadMessage) { + targetConnections.target = target + communicationOverlay.message = qsTr("Target detected. Reading messages...") + errorNotification.errorMessage = qsTr("NDEF read error") + ok = target.readNdefMessages() + } else if (targetDetectedAction === MainWindow.WriteMessage) { + targetConnections.target = target + communicationOverlay.message = qsTr("Target detected. Writing the message...") + errorNotification.errorMessage = qsTr("NDEF write error") + ok = target.writeNdefMessage(messageModel.message) + } else { + target.destroy() + return + } + + if (!ok) { + communicationOverlay.close() + errorNotification.open() + targetConnections.releaseTarget() + } + } + + function readTag() { + window.targetDetectedAction = MainWindow.ReadMessage + nfcManager.startTargetDetection() + communicationOverlay.title = qsTr("Read Tag") + communicationOverlay.message = qsTr("Approach an NFC tag.") + communicationOverlay.open() + } + + function writeTag() { + window.targetDetectedAction = MainWindow.WriteMessage + nfcManager.startTargetDetection() + communicationOverlay.title = qsTr("Write to Tag") + communicationOverlay.message = qsTr("Approach an NFC tag.") + communicationOverlay.open() + } + + function describeError(error) { + switch (error) { + case 2: return qsTr("Usupported feature") + case 3: return qsTr("Target out of range") + case 4: return qsTr("No response") + case 5: return qsTr("Checksum mismatch") + case 6: return qsTr("Invalid parameters") + case 7: return qsTr("Connection error") + case 8: return qsTr("NDEF read error") + case 9: return qsTr("NDEF write error") + case 10: return qsTr("Command error") + case 11: return qsTr("Timeout") + } + + return qsTr("Unknown error") + } + + Dialog { + id: communicationOverlay + + property alias message: messageLabel.text + + anchors.centerIn: Overlay.overlay + + modal: true + standardButtons: Dialog.Cancel + + ColumnLayout { + Label { + id: messageLabel + } + + BusyIndicator { + Layout.fillWidth: true + } + } + + onClosed: nfcManager.stopTargetDetection() + } + + MessageDialog { + property alias errorMessage: errorNotification.text + + id: errorNotification + + buttons: MessageDialog.Close + title: qsTr("Error") + + onButtonClicked: errorNotification.close() + } + + Component { + id: uriRecordDialog + + ColumnLayout { + property alias uri: uriEditor.text + property int modelIndex: -1 + + ToolBar { + Layout.fillWidth: true + + RowLayout { + anchors.fill: parent + ToolButton { + icon.name: "arrow_back" + onClicked: stack.pop() + } + Label { + text: qsTr("URI Record") + elide: Label.ElideRight + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + Layout.fillWidth: true + } + ToolButton { + text: qsTr("Save") + onClicked: { + if (modelIndex < 0) { + messageModel.addUriRecord(uri) + } else { + messageModel.setTextData(modelIndex, uri) + } + stack.pop() + } + } + } + } + + Pane { + Layout.fillWidth: true + Layout.fillHeight: true + + ColumnLayout { + anchors.fill: parent + + TextField { + id: uriEditor + Layout.fillWidth: true + placeholderText: qsTr("https://qt.io") + inputMethodHints: Qt.ImhUrlCharactersOnly + } + Item { + Layout.fillHeight: true + } + } + } + } + } + + Component { + id: textRecordDialog + + ColumnLayout { + property alias text: textEditor.text + property int modelIndex: -1 + + ToolBar { + Layout.fillWidth: true + + RowLayout { + anchors.fill: parent + ToolButton { + icon.name: "arrow_back" + onClicked: stack.pop() + } + Label { + text: qsTr("Text Record") + elide: Label.ElideRight + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + Layout.fillWidth: true + } + ToolButton { + text: qsTr("Save") + onClicked: { + if (modelIndex < 0) { + messageModel.addTextRecord(textEditor.text) + } else { + messageModel.setTextData(modelIndex, textEditor.text) + } + stack.pop() + } + } + } + } + + Pane { + Layout.fillWidth: true + Layout.fillHeight: true + + ScrollView { + anchors.fill: parent + + TextArea { + id: textEditor + placeholderText: qsTr("Enter some text...") + Layout.fillWidth: true + } + } + } + } + } +} diff --git a/examples/nfc/ndefeditor/NdefRecordDelegate.qml b/examples/nfc/ndefeditor/NdefRecordDelegate.qml new file mode 100644 index 00000000..f01aff05 --- /dev/null +++ b/examples/nfc/ndefeditor/NdefRecordDelegate.qml @@ -0,0 +1,50 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import NdefEditor + +SwipeDelegate { + required property int index + required property int recordType + required property string recordText + + id: delegate + + contentItem: ColumnLayout { + Label { + text: qsTr("Record %L1 - %2").arg(delegate.index + 1).arg( + delegate.describeRecordType(delegate.recordType)) + font.bold: true + } + + Label { + text: delegate.recordText + elide: Text.ElideRight + maximumLineCount: 1 + Layout.fillWidth: true + } + } + + swipe.left: Button { + text: qsTr("Delete") + padding: 12 + height: delegate.height + anchors.left: delegate.left + SwipeDelegate.onClicked: delegate.deleteClicked() + } + + function describeRecordType(type) { + switch (type) { + case NdefMessageModel.TextRecord: return qsTr("Text") + case NdefMessageModel.UriRecord: return qsTr("URI") + default: return qsTr("Other") + } + } + + signal deleteClicked() +} diff --git a/examples/nfc/ndefeditor/doc/images/ndefeditor.png b/examples/nfc/ndefeditor/doc/images/ndefeditor.png Binary files differindex d203e474..2be32f60 100644 --- a/examples/nfc/ndefeditor/doc/images/ndefeditor.png +++ b/examples/nfc/ndefeditor/doc/images/ndefeditor.png diff --git a/examples/nfc/ndefeditor/doc/src/ndefeditor.qdoc b/examples/nfc/ndefeditor/doc/src/ndefeditor.qdoc index eb638200..0c7a0841 100644 --- a/examples/nfc/ndefeditor/doc/src/ndefeditor.qdoc +++ b/examples/nfc/ndefeditor/doc/src/ndefeditor.qdoc @@ -1,112 +1,25 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt local connectivity modules. -** -** $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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \example ndefeditor -\title NDEF Editor Example -\brief An example about reading and writing NFC Data Exchange Format (NDEF) messages to NFC Forum Tags. +\title NDEF Editor +\examplecategory {Connectivity} +\meta tags {nfc, ndef} +\brief Reads and writes NFC Data Exchange Format (NDEF) messages to NFC Forum Tags. -The NDEF Editor example reads and writes NFC Data Exchange Format +The NDEF Editor example uses \l{Qt NFC} to read and write NFC Data Exchange Format (NDEF) messages to NFC Forum Tags. NDEF messages can be composed by -adding records of supported types. Additionally, NDEF messages can be -loaded/saved from/into a file located in the file system of the -machine where the application is running. +adding text and URI records. Records can be deleted by swiping them to the left. -\image ndefeditor.png - -\section1 NFC Tag detection - -The MainWindow class is able to detect if a NFC Tag is in the range -for read/write operations. It can also detect if connectivity has been -lost. This is achieved by connecting the MainWindow class private -handlers to the signals QNearFieldManager::targetDetected and -QNearFieldManager::targetLost. - -\snippet ndefeditor/mainwindow.cpp QNearFieldManager init - -Through the UI a user requests when to start the detection of a NFC -Tag by calling the method QNearFieldManager::startTargetDetection. - -\snippet ndefeditor/mainwindow.cpp QNearFieldManager start detection - -Once the target is detected the MainWindow connects the following -signals to its internal private slots: -QNearFieldTarget::ndefMessageRead, QNearFieldTarget::NdefReadError, -QNearFieldTarget::ndefMessagesWritten, -QNearFieldTarget::NdefWriteError and QNearFieldTarget::error - -\snippet ndefeditor/mainwindow.cpp QNearFieldTarget detected - -If during the process of reading or writing to a NFC Tag the -connection is lost, the MainWindow reacts to this event by -scheduling the target deletion (QObject::deleteLater). - -\snippet ndefeditor/mainwindow.cpp QNearFieldTarget lost - -\section1 Record creation - -The main window of the ndefeditor example manages the composition and -creation of NFC records. The UI contains a QScrollArea where -RecordEditors are added dynamically on a user requests basis. The -following methods of the MainWindow class provide an interface towards -each of the record editing classes managing the different types of -records. +Press \b {Write to Tag} to write the records to an NFC tag. -\snippet ndefeditor/mainwindow.h 0 +Press \b {Read Tag} to read the contents of an NFC tag. A successful read of an +NFC tag replaces the manually added records with the NDEF message from the tag. +If the read operation was cancelled or failed, the NDEF message remains +unchanged. -The following sections explain each of the record editing classes. -\section1 Record editing classes - -\section2 TextRecordEditor - -The TextRecordEditor is a QWidget that can handle editing the values -of text record that has been requested by the user. For each text -record, there is a new instance of this class. - -\snippet ndefeditor/textrecordeditor.h 0 - -\section2 UriRecordEditor - -The UriRecordEditor is a QWidget that can handle editing the values of -Uri record that has been requested by the user. For each new Uri -record there is a new instance of this class. - -\snippet ndefeditor/urirecordeditor.h 0 - -\section2 MimeImageRecordEditor - -The UriRecordEditor is a QWidget that can handle editing the values of -a Mime Image record that has been requested by the user. For each Mime -Image record there is a new instance of this class. - -\snippet ndefeditor/mimeimagerecordeditor.h 0 - - -\include examples-run.qdocinc +\image ndefeditor.png \sa {Qt NFC} */ diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20/add.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20/add.png Binary files differnew file mode 100644 index 00000000..49659bf3 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20/add.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20/arrow_back.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20/arrow_back.png Binary files differnew file mode 100644 index 00000000..8d39f677 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20/arrow_back.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20/file_download.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20/file_download.png Binary files differnew file mode 100644 index 00000000..405a67b0 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20/file_download.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20/file_upload.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20/file_upload.png Binary files differnew file mode 100644 index 00000000..7a13c507 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20/file_upload.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20/link.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20/link.png Binary files differnew file mode 100644 index 00000000..6d663387 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20/link.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20/text_snippet.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20/text_snippet.png Binary files differnew file mode 100644 index 00000000..bada4338 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20/text_snippet.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/add.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/add.png Binary files differnew file mode 100644 index 00000000..8114d615 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/add.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/arrow_back.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/arrow_back.png Binary files differnew file mode 100644 index 00000000..843444e2 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/arrow_back.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/file_download.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/file_download.png Binary files differnew file mode 100644 index 00000000..d848b217 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/file_download.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/file_upload.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/file_upload.png Binary files differnew file mode 100644 index 00000000..22364309 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/file_upload.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/link.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/link.png Binary files differnew file mode 100644 index 00000000..0567312a --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/link.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/text_snippet.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/text_snippet.png Binary files differnew file mode 100644 index 00000000..96ab459a --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@2/text_snippet.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/add.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/add.png Binary files differnew file mode 100644 index 00000000..c55d4144 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/add.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/arrow_back.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/arrow_back.png Binary files differnew file mode 100644 index 00000000..bb620d68 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/arrow_back.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/file_download.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/file_download.png Binary files differnew file mode 100644 index 00000000..db8e7b13 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/file_download.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/file_upload.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/file_upload.png Binary files differnew file mode 100644 index 00000000..1b240284 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/file_upload.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/link.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/link.png Binary files differnew file mode 100644 index 00000000..e0569cbb --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/link.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/text_snippet.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/text_snippet.png Binary files differnew file mode 100644 index 00000000..9dc6683f --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@3/text_snippet.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/add.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/add.png Binary files differnew file mode 100644 index 00000000..4813a26f --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/add.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/arrow_back.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/arrow_back.png Binary files differnew file mode 100644 index 00000000..54354ddd --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/arrow_back.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/file_download.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/file_download.png Binary files differnew file mode 100644 index 00000000..20148b92 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/file_download.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/file_upload.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/file_upload.png Binary files differnew file mode 100644 index 00000000..22a98cc2 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/file_upload.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/link.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/link.png Binary files differnew file mode 100644 index 00000000..f8bedeef --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/link.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/text_snippet.png b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/text_snippet.png Binary files differnew file mode 100644 index 00000000..74a5f7fe --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/20x20@4/text_snippet.png diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/index.theme b/examples/nfc/ndefeditor/icons/ndefeditor/index.theme new file mode 100644 index 00000000..756b1232 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/index.theme @@ -0,0 +1,22 @@ +[Icon Theme] +Name=ndefeditor +Directories=20x20,20x20@2,20x20@3,20x20@4 + +[20x20] +Size=20 +Type=Fixed + +[20x20@2] +Size=20 +Scale=2 +Type=Fixed + +[20x20@3] +Size=20 +Scale=3 +Type=Fixed + +[20x20@4] +Size=20 +Scale=4 +Type=Fixed diff --git a/examples/nfc/ndefeditor/icons/ndefeditor/qt_attribution.json b/examples/nfc/ndefeditor/icons/ndefeditor/qt_attribution.json new file mode 100644 index 00000000..b9ee69b4 --- /dev/null +++ b/examples/nfc/ndefeditor/icons/ndefeditor/qt_attribution.json @@ -0,0 +1,14 @@ +{ + "Id": "ndefeditor", + "Name": "Selected Material Icons", + "QDocModule": "qtnfc", + "QtUsage": "Used in NDEF Editor example for Qt NFC.", + "QtParts": [ + "examples" + ], + "Files": "20x20 20x20@2 20x20@3 20x20@4", + "Homepage": "https://fonts.google.com/icons", + "License": "Apache License Version 2.0", + "LicenseId": "Apache-2.0", + "Copyright": "Copyright 2018 Google, Inc. All Rights Reserved." +} diff --git a/examples/nfc/ndefeditor/main.cpp b/examples/nfc/ndefeditor/main.cpp index 6ea32a57..a9e5218d 100644 --- a/examples/nfc/ndefeditor/main.cpp +++ b/examples/nfc/ndefeditor/main.cpp @@ -1,62 +1,22 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module 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$ -** -****************************************************************************/ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -#include <QApplication> -#include "mainwindow.h" +#include <QGuiApplication> +#include <QIcon> +#include <QQmlApplicationEngine> int main(int argc, char *argv[]) { - QApplication a(argc, argv); - MainWindow w; + QGuiApplication app(argc, argv); - w.show(); + QIcon::setThemeName("ndefeditor"); - return a.exec(); + QQmlApplicationEngine engine; + + QObject::connect( + &engine, &QQmlApplicationEngine::objectCreationFailed, &app, + []() { QCoreApplication::exit(1); }, Qt::QueuedConnection); + engine.loadFromModule("NdefEditor", "Main"); + + return app.exec(); } diff --git a/examples/nfc/ndefeditor/mainwindow.cpp b/examples/nfc/ndefeditor/mainwindow.cpp deleted file mode 100644 index 869f1790..00000000 --- a/examples/nfc/ndefeditor/mainwindow.cpp +++ /dev/null @@ -1,379 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module 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 "mainwindow.h" -#include "ui_mainwindow.h" - -#include "textrecordeditor.h" -#include "urirecordeditor.h" -#include "mimeimagerecordeditor.h" - -#include <QtNfc/qndefnfcurirecord.h> -#include <QtNfc/qndefnfctextrecord.h> -#include <QtNfc/qndefrecord.h> -#include <QtNfc/qndefmessage.h> -#include <QtNfc/qnearfieldmanager.h> -#include <QtNfc/qnearfieldtarget.h> - -#include <QtWidgets/QMenu> -#include <QtWidgets/QVBoxLayout> -#include <QtWidgets/QFrame> -#include <QtWidgets/QLabel> -#include <QtWidgets/QFileDialog> - -class EmptyRecordLabel : public QLabel -{ - Q_OBJECT - -public: - EmptyRecordLabel() : QLabel(tr("Empty Record")) { } - ~EmptyRecordLabel() { } - - void setRecord(const QNdefRecord &record) - { - Q_UNUSED(record); - } - - QNdefRecord record() const - { - return QNdefRecord(); - } -}; - -class UnknownRecordLabel : public QLabel -{ - Q_OBJECT - -public: - UnknownRecordLabel() : QLabel(tr("Unknown Record Type")) { } - ~UnknownRecordLabel() { } - - void setRecord(const QNdefRecord &record) { m_record = record; } - QNdefRecord record() const { return m_record; } - -private: - QNdefRecord m_record; -}; - -template <typename T> -void addRecord(Ui::MainWindow *ui, const QNdefRecord &record = QNdefRecord()) -{ - QVBoxLayout *vbox = qobject_cast<QVBoxLayout *>(ui->scrollAreaWidgetContents->layout()); - if (!vbox) - return; - - if (!vbox->isEmpty()) { - QFrame *hline = new QFrame; - hline->setFrameShape(QFrame::HLine); - hline->setObjectName(QStringLiteral("line-spacer")); - - vbox->addWidget(hline); - } - - T *recordEditor = new T; - recordEditor->setObjectName(QStringLiteral("record-editor")); - - if (!record.isEmpty()) - recordEditor->setRecord(record); - - vbox->addWidget(recordEditor); -} - -MainWindow::MainWindow(QWidget *parent) -: QMainWindow(parent), ui(new Ui::MainWindow), m_touchAction(NoAction) -{ - ui->setupUi(this); - - QMenu *addRecordMenu = new QMenu(this); - addRecordMenu->addAction(tr("NFC Text Record"), this, SLOT(addNfcTextRecord())); - addRecordMenu->addAction(tr("NFC URI Record"), this, SLOT(addNfcUriRecord())); - addRecordMenu->addAction(tr("MIME Image Record"), this, SLOT(addMimeImageRecord())); - addRecordMenu->addAction(tr("Empty Record"), this, SLOT(addEmptyRecord())); - ui->addRecord->setMenu(addRecordMenu); - - QVBoxLayout *vbox = new QVBoxLayout; - ui->scrollAreaWidgetContents->setLayout(vbox); - - //! [QNearFieldManager init] - m_manager = new QNearFieldManager(this); - connect(m_manager, &QNearFieldManager::targetDetected, - this, &MainWindow::targetDetected); - connect(m_manager, &QNearFieldManager::targetLost, - this, &MainWindow::targetLost); - //! [QNearFieldManager init] -} - -MainWindow::~MainWindow() -{ - delete ui; -} - -void MainWindow::addNfcTextRecord() -{ - addRecord<TextRecordEditor>(ui); -} - -void MainWindow::addNfcUriRecord() -{ - addRecord<UriRecordEditor>(ui); -} - -void MainWindow::addMimeImageRecord() -{ - addRecord<MimeImageRecordEditor>(ui); -} - -void MainWindow::addEmptyRecord() -{ - addRecord<EmptyRecordLabel>(ui); -} - -void MainWindow::loadMessage() -{ - QString filename = QFileDialog::getOpenFileName(this, tr("Select NDEF Message")); - if (filename.isEmpty()) - return; - - QFile file(filename); - if (!file.open(QIODevice::ReadOnly)) - return; - - QByteArray ndef = file.readAll(); - - ndefMessageRead(QNdefMessage::fromByteArray(ndef)); - - file.close(); -} - -void MainWindow::saveMessage() -{ - QString filename = QFileDialog::getSaveFileName(this, tr("Select NDEF Message")); - if (filename.isEmpty()) - return; - - QFile file(filename); - if (!file.open(QIODevice::WriteOnly)) - return; - - file.write(ndefMessage().toByteArray()); - - file.close(); -} - -void MainWindow::touchReceive() -{ - ui->status->setStyleSheet(QStringLiteral("background: blue")); - - m_touchAction = ReadNdef; - - m_manager->setTargetAccessModes(QNearFieldManager::NdefReadTargetAccess); - //! [QNearFieldManager start detection] - m_manager->startTargetDetection(); - //! [QNearFieldManager start detection] -} - -void MainWindow::touchStore() -{ - ui->status->setStyleSheet(QStringLiteral("background: yellow")); - - m_touchAction = WriteNdef; - - m_manager->setTargetAccessModes(QNearFieldManager::NdefWriteTargetAccess); - m_manager->startTargetDetection(); -} - -//! [QNearFieldTarget detected] -void MainWindow::targetDetected(QNearFieldTarget *target) -{ - switch (m_touchAction) { - case NoAction: - break; - case ReadNdef: - connect(target, &QNearFieldTarget::ndefMessageRead, this, &MainWindow::ndefMessageRead); - connect(target, &QNearFieldTarget::error, this, &MainWindow::targetError); - - m_request = target->readNdefMessages(); - if (!m_request.isValid()) // cannot read messages - targetError(QNearFieldTarget::NdefReadError, m_request); - break; - case WriteNdef: - connect(target, &QNearFieldTarget::ndefMessagesWritten, this, &MainWindow::ndefMessageWritten); - connect(target, &QNearFieldTarget::error, this, &MainWindow::targetError); - - m_request = target->writeNdefMessages(QList<QNdefMessage>() << ndefMessage()); - if (!m_request.isValid()) // cannot write messages - targetError(QNearFieldTarget::NdefWriteError, m_request); - break; - } -} -//! [QNearFieldTarget detected] - -//! [QNearFieldTarget lost] -void MainWindow::targetLost(QNearFieldTarget *target) -{ - target->deleteLater(); -} -//! [QNearFieldTarget lost] - -void MainWindow::ndefMessageRead(const QNdefMessage &message) -{ - clearMessage(); - - for (const QNdefRecord &record : message) { - if (record.isRecordType<QNdefNfcTextRecord>()) { - addRecord<TextRecordEditor>(ui, record); - } else if (record.isRecordType<QNdefNfcUriRecord>()) { - addRecord<UriRecordEditor>(ui, record); - } else if (record.typeNameFormat() == QNdefRecord::Mime && - record.type().startsWith("image/")) { - addRecord<MimeImageRecordEditor>(ui, record); - } else if (record.isEmpty()) { - addRecord<EmptyRecordLabel>(ui); - } else { - addRecord<UnknownRecordLabel>(ui, record); - } - } - - ui->status->setStyleSheet(QString()); - m_manager->setTargetAccessModes(QNearFieldManager::NoTargetAccess); - //! [QNearFieldManager stop detection] - m_manager->stopTargetDetection(); - //! [QNearFieldManager stop detection] - m_request = QNearFieldTarget::RequestId(); - ui->statusBar->clearMessage(); -} - -void MainWindow::ndefMessageWritten() -{ - ui->status->setStyleSheet(QString()); - m_manager->setTargetAccessModes(QNearFieldManager::NoTargetAccess); - m_manager->stopTargetDetection(); - m_request = QNearFieldTarget::RequestId(); - ui->statusBar->clearMessage(); -} - -void MainWindow::targetError(QNearFieldTarget::Error error, const QNearFieldTarget::RequestId &id) -{ - Q_UNUSED(error); - Q_UNUSED(id); - - if (m_request == id) { - switch (error) { - case QNearFieldTarget::NoError: - ui->statusBar->clearMessage(); - break; - case QNearFieldTarget::UnsupportedError: - ui->statusBar->showMessage(tr("Unsupported tag")); - break; - case QNearFieldTarget::TargetOutOfRangeError: - ui->statusBar->showMessage(tr("Tag removed from field")); - break; - case QNearFieldTarget::NoResponseError: - ui->statusBar->showMessage(tr("No response from tag")); - break; - case QNearFieldTarget::ChecksumMismatchError: - ui->statusBar->showMessage(tr("Checksum mismatch")); - break; - case QNearFieldTarget::InvalidParametersError: - ui->statusBar->showMessage(tr("Invalid parameters")); - break; - case QNearFieldTarget::NdefReadError: - ui->statusBar->showMessage(tr("NDEF read error")); - break; - case QNearFieldTarget::NdefWriteError: - ui->statusBar->showMessage(tr("NDEF write error")); - break; - default: - ui->statusBar->showMessage(tr("Unknown error")); - } - - ui->status->setStyleSheet(QString()); - m_manager->setTargetAccessModes(QNearFieldManager::NoTargetAccess); - m_manager->stopTargetDetection(); - m_request = QNearFieldTarget::RequestId(); - } -} - -void MainWindow::clearMessage() -{ - QWidget *scrollArea = ui->scrollAreaWidgetContents; - - qDeleteAll(scrollArea->findChildren<QWidget *>(QStringLiteral("line-spacer"))); - qDeleteAll(scrollArea->findChildren<QWidget *>(QStringLiteral("record-editor"))); -} - -QNdefMessage MainWindow::ndefMessage() const -{ - QVBoxLayout *vbox = qobject_cast<QVBoxLayout *>(ui->scrollAreaWidgetContents->layout()); - if (!vbox) - return QNdefMessage(); - - QNdefMessage message; - - for (int i = 0; i < vbox->count(); ++i) { - QWidget *widget = vbox->itemAt(i)->widget(); - - if (TextRecordEditor *editor = qobject_cast<TextRecordEditor *>(widget)) { - message.append(editor->record()); - } else if (UriRecordEditor *editor = qobject_cast<UriRecordEditor *>(widget)) { - message.append(editor->record()); - } else if (MimeImageRecordEditor *editor = qobject_cast<MimeImageRecordEditor *>(widget)) { - message.append(editor->record()); - } else if (qobject_cast<EmptyRecordLabel *>(widget)) { - message.append(QNdefRecord()); - } else if (UnknownRecordLabel *label = qobject_cast<UnknownRecordLabel *>(widget)) { - message.append(label->record()); - } - } - - return message; -} - -#include "mainwindow.moc" diff --git a/examples/nfc/ndefeditor/mainwindow.h b/examples/nfc/ndefeditor/mainwindow.h deleted file mode 100644 index 234efcd2..00000000 --- a/examples/nfc/ndefeditor/mainwindow.h +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module 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 MAINWINDOW_H -#define MAINWINDOW_H - -#include <QtNfc/qnearfieldtarget.h> - -#include <QtWidgets/QMainWindow> - -QT_FORWARD_DECLARE_CLASS(QNearFieldManager) -QT_FORWARD_DECLARE_CLASS(QNdefMessage) - -QT_BEGIN_NAMESPACE -namespace Ui { - class MainWindow; -} -QT_END_NAMESPACE - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit MainWindow(QWidget *parent = 0); - ~MainWindow(); - -private slots: - //! [0] - void addNfcTextRecord(); - void addNfcUriRecord(); - void addMimeImageRecord(); - void addEmptyRecord(); - //! [0] - void clearMessage(); - - void loadMessage(); - void saveMessage(); - - void touchReceive(); - void touchStore(); - - void targetDetected(QNearFieldTarget *target); - void targetLost(QNearFieldTarget *target); - - void ndefMessageRead(const QNdefMessage &message); - void ndefMessageWritten(); - void targetError(QNearFieldTarget::Error error, const QNearFieldTarget::RequestId &id); - -private: - enum TouchAction { - NoAction, - ReadNdef, - WriteNdef - }; - - QNdefMessage ndefMessage() const; - -private: - Ui::MainWindow *ui; - - QNearFieldManager *m_manager; - TouchAction m_touchAction; - QNearFieldTarget::RequestId m_request; -}; - -#endif // MAINWINDOW_H diff --git a/examples/nfc/ndefeditor/mainwindow.ui b/examples/nfc/ndefeditor/mainwindow.ui deleted file mode 100644 index adffa331..00000000 --- a/examples/nfc/ndefeditor/mainwindow.ui +++ /dev/null @@ -1,225 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>MainWindow</class> - <widget class="QMainWindow" name="MainWindow"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>553</width> - <height>397</height> - </rect> - </property> - <property name="windowTitle"> - <string>NDEF Message Editor</string> - </property> - <widget class="QWidget" name="centralWidget"> - <layout class="QVBoxLayout" name="verticalLayout"> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <property name="leftMargin"> - <number>9</number> - </property> - <property name="rightMargin"> - <number>9</number> - </property> - <item> - <widget class="QWidget" name="status" native="true"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>25</width> - <height>25</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>25</width> - <height>25</height> - </size> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="touchRetrieve"> - <property name="text"> - <string>Retrieve</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="touchStore"> - <property name="text"> - <string>Store</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="loadMessage"> - <property name="text"> - <string>Load</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="saveMessage"> - <property name="text"> - <string>Save</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="clearMessage"> - <property name="text"> - <string>Clear</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="addRecord"> - <property name="text"> - <string>Add</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QScrollArea" name="scrollArea"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Plain</enum> - </property> - <property name="verticalScrollBarPolicy"> - <enum>Qt::ScrollBarAsNeeded</enum> - </property> - <property name="horizontalScrollBarPolicy"> - <enum>Qt::ScrollBarAlwaysOff</enum> - </property> - <property name="widgetResizable"> - <bool>true</bool> - </property> - <widget class="QWidget" name="scrollAreaWidgetContents"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>553</width> - <height>335</height> - </rect> - </property> - </widget> - </widget> - </item> - </layout> - </widget> - <widget class="QStatusBar" name="statusBar"/> - </widget> - <layoutdefault spacing="6" margin="11"/> - <resources/> - <connections> - <connection> - <sender>saveMessage</sender> - <signal>clicked()</signal> - <receiver>MainWindow</receiver> - <slot>saveMessage()</slot> - <hints> - <hint type="sourcelabel"> - <x>419</x> - <y>47</y> - </hint> - <hint type="destinationlabel"> - <x>275</x> - <y>198</y> - </hint> - </hints> - </connection> - <connection> - <sender>touchRetrieve</sender> - <signal>clicked()</signal> - <receiver>MainWindow</receiver> - <slot>touchReceive()</slot> - <hints> - <hint type="sourcelabel"> - <x>142</x> - <y>47</y> - </hint> - <hint type="destinationlabel"> - <x>275</x> - <y>198</y> - </hint> - </hints> - </connection> - <connection> - <sender>touchStore</sender> - <signal>clicked()</signal> - <receiver>MainWindow</receiver> - <slot>touchStore()</slot> - <hints> - <hint type="sourcelabel"> - <x>244</x> - <y>47</y> - </hint> - <hint type="destinationlabel"> - <x>275</x> - <y>198</y> - </hint> - </hints> - </connection> - <connection> - <sender>loadMessage</sender> - <signal>clicked()</signal> - <receiver>MainWindow</receiver> - <slot>loadMessage()</slot> - <hints> - <hint type="sourcelabel"> - <x>334</x> - <y>47</y> - </hint> - <hint type="destinationlabel"> - <x>275</x> - <y>198</y> - </hint> - </hints> - </connection> - <connection> - <sender>clearMessage</sender> - <signal>clicked()</signal> - <receiver>MainWindow</receiver> - <slot>clearMessage()</slot> - <hints> - <hint type="sourcelabel"> - <x>419</x> - <y>22</y> - </hint> - <hint type="destinationlabel"> - <x>275</x> - <y>198</y> - </hint> - </hints> - </connection> - </connections> - <slots> - <slot>saveMessage()</slot> - <slot>loadMessage()</slot> - <slot>touchReceive()</slot> - <slot>touchStore()</slot> - <slot>clearMessage()</slot> - </slots> -</ui> diff --git a/examples/nfc/ndefeditor/mimeimagerecordeditor.cpp b/examples/nfc/ndefeditor/mimeimagerecordeditor.cpp deleted file mode 100644 index 8044e8a6..00000000 --- a/examples/nfc/ndefeditor/mimeimagerecordeditor.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module 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 "mimeimagerecordeditor.h" -#include "ui_mimeimagerecordeditor.h" - -#include <QtGui/QImageReader> -#include <QtWidgets/QFileDialog> -#include <QtCore/QBuffer> - -static QString imageFormatToMimeType(const QByteArray &format) -{ - if (format == "bmp") - return QStringLiteral("image/bmp"); - else if (format == "gif") - return QStringLiteral("image/gif"); - else if (format == "jpg" || format == "jpeg") - return QStringLiteral("image/jpeg"); - else if (format == "mng") - return QStringLiteral("video/x-mng"); - else if (format == "png") - return QStringLiteral("image/png"); - else if (format == "pbm") - return QStringLiteral("image/x-portable-bitmap"); - else if (format == "pgm") - return QStringLiteral("image/x-portable-graymap"); - else if (format == "ppm") - return QStringLiteral("image/x-portable-pixmap"); - else if (format == "tiff") - return QStringLiteral("image/tiff"); - else if (format == "xbm") - return QStringLiteral("image/x-xbitmap"); - else if (format == "xpm") - return QStringLiteral("image/x-xpixmap"); - else if (format == "svg") - return QStringLiteral("image/svg+xml"); - else - return QString(); -} - -MimeImageRecordEditor::MimeImageRecordEditor(QWidget *parent) : - QWidget(parent), - ui(new Ui::MimeImageRecordEditor) -{ - ui->setupUi(this); -} - -MimeImageRecordEditor::~MimeImageRecordEditor() -{ - delete ui; -} - -void MimeImageRecordEditor::setRecord(const QNdefRecord &record) -{ - m_record = record; - - QByteArray data = record.payload(); - QBuffer buffer(&data); - buffer.open(QIODevice::ReadOnly); - - QImageReader reader(&buffer); - - ui->mimeImageType->setText(imageFormatToMimeType(reader.format())); - - ui->mimeImageImage->setPixmap(QPixmap::fromImage(reader.read())); - ui->mimeImageFile->clear(); -} - -QNdefRecord MimeImageRecordEditor::record() const -{ - return m_record; -} - -void MimeImageRecordEditor::on_mimeImageOpen_clicked() -{ - QString mimeDataFile = QFileDialog::getOpenFileName(this, tr("Select Image File")); - if (mimeDataFile.isEmpty()) - return; - - QFile imageFile(mimeDataFile); - if (!imageFile.open(QIODevice::ReadOnly)) { - ui->mimeImageFile->clear(); - ui->mimeImageImage->clear(); - } - - QByteArray imageData = imageFile.readAll(); - - QBuffer buffer(&imageData); - buffer.open(QIODevice::ReadOnly); - - QImageReader reader(&buffer); - QString mimeType = imageFormatToMimeType(reader.format()); - ui->mimeImageType->setText(mimeType); - - QImage image = reader.read(); - - ui->mimeImageFile->setText(mimeDataFile); - ui->mimeImageImage->setPixmap(QPixmap::fromImage(image)); - - m_record.setTypeNameFormat(QNdefRecord::Mime); - m_record.setType(mimeType.toLatin1()); - m_record.setPayload(imageData); -} diff --git a/examples/nfc/ndefeditor/mimeimagerecordeditor.h b/examples/nfc/ndefeditor/mimeimagerecordeditor.h deleted file mode 100644 index 44cd084b..00000000 --- a/examples/nfc/ndefeditor/mimeimagerecordeditor.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module 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 MIMEIMAGERECORDEDITOR_H -#define MIMEIMAGERECORDEDITOR_H - -#include <QtNfc/qndefrecord.h> - -#include <QtWidgets/QWidget> - -QT_USE_NAMESPACE - -QT_BEGIN_NAMESPACE -namespace Ui { - class MimeImageRecordEditor; -} -QT_END_NAMESPACE - -//! [0] -class MimeImageRecordEditor : public QWidget -{ - Q_OBJECT - -public: - explicit MimeImageRecordEditor(QWidget *parent = 0); - ~MimeImageRecordEditor(); - - void setRecord(const QNdefRecord &record); - QNdefRecord record() const; - -private: - Ui::MimeImageRecordEditor *ui; - QNdefRecord m_record; - -private slots: - void on_mimeImageOpen_clicked(); -}; -//! [0] -#endif // MIMEIMAGERECORDEDITOR_H diff --git a/examples/nfc/ndefeditor/mimeimagerecordeditor.ui b/examples/nfc/ndefeditor/mimeimagerecordeditor.ui deleted file mode 100644 index 4cde216f..00000000 --- a/examples/nfc/ndefeditor/mimeimagerecordeditor.ui +++ /dev/null @@ -1,83 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>MimeImageRecordEditor</class> - <widget class="QWidget" name="MimeImageRecordEditor"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>403</width> - <height>106</height> - </rect> - </property> - <property name="windowTitle"> - <string>Form</string> - </property> - <layout class="QFormLayout" name="formLayout"> - <item row="0" column="0" colspan="2"> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>MIME Record <image/*></string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_11"> - <property name="text"> - <string>Type:</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLabel" name="mimeImageType"> - <property name="sizePolicy"> - <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>image/</string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_12"> - <property name="text"> - <string>File:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLineEdit" name="mimeImageFile"> - <property name="sizePolicy"> - <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="mimeImageOpen"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - </layout> - </item> - <item row="3" column="1"> - <widget class="QLabel" name="mimeImageImage"> - <property name="text"> - <string>TextLabel</string> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/examples/nfc/ndefeditor/ndefeditor.pro b/examples/nfc/ndefeditor/ndefeditor.pro index 4b81c17c..f6c270de 100644 --- a/examples/nfc/ndefeditor/ndefeditor.pro +++ b/examples/nfc/ndefeditor/ndefeditor.pro @@ -1,27 +1,66 @@ -QT += nfc widgets -requires(qtConfig(filedialog)) +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +QT += nfc quick quickcontrols2 + +CONFIG += qmltypes +QML_IMPORT_NAME = NdefEditor +QML_IMPORT_MAJOR_VERSION = 1 TARGET = ndefeditor TEMPLATE = app SOURCES += \ main.cpp \ - mainwindow.cpp \ - textrecordeditor.cpp \ - urirecordeditor.cpp \ - mimeimagerecordeditor.cpp + nfcmanager.cpp \ + nfctarget.cpp \ + ndefmessagemodel.cpp HEADERS += \ - mainwindow.h \ - textrecordeditor.h \ - urirecordeditor.h \ - mimeimagerecordeditor.h - -FORMS += \ - mainwindow.ui \ - textrecordeditor.ui \ - urirecordeditor.ui \ - mimeimagerecordeditor.ui + nfcmanager.h \ + nfctarget.h \ + ndefmessagemodel.h + +qml_resources.files = \ + qmldir \ + Main.qml \ + MainWindow.qml \ + NdefRecordDelegate.qml + +qml_resources.prefix = /qt/qml/NdefEditor + +theme_resources.files = \ + icons/ndefeditor/20x20@2/add.png \ + icons/ndefeditor/20x20@2/arrow_back.png \ + icons/ndefeditor/20x20@2/file_download.png \ + icons/ndefeditor/20x20@2/file_upload.png \ + icons/ndefeditor/20x20@2/link.png \ + icons/ndefeditor/20x20@2/text_snippet.png \ + icons/ndefeditor/20x20@3/add.png \ + icons/ndefeditor/20x20@3/arrow_back.png \ + icons/ndefeditor/20x20@3/file_download.png \ + icons/ndefeditor/20x20@3/file_upload.png \ + icons/ndefeditor/20x20@3/link.png \ + icons/ndefeditor/20x20@3/text_snippet.png \ + icons/ndefeditor/20x20@4/add.png \ + icons/ndefeditor/20x20@4/arrow_back.png \ + icons/ndefeditor/20x20@4/file_download.png \ + icons/ndefeditor/20x20@4/file_upload.png \ + icons/ndefeditor/20x20@4/link.png \ + icons/ndefeditor/20x20@4/text_snippet.png \ + icons/ndefeditor/20x20/add.png \ + icons/ndefeditor/20x20/arrow_back.png \ + icons/ndefeditor/20x20/file_download.png \ + icons/ndefeditor/20x20/file_upload.png \ + icons/ndefeditor/20x20/link.png \ + icons/ndefeditor/20x20/text_snippet.png \ + icons/ndefeditor/index.theme + +theme_resources.prefix = / + +RESOURCES += qml_resources theme_resources + +ios: QMAKE_INFO_PLIST = Info.qmake.plist target.path = $$[QT_INSTALL_EXAMPLES]/nfc/ndefeditor INSTALLS += target diff --git a/examples/nfc/ndefeditor/ndefmessagemodel.cpp b/examples/nfc/ndefeditor/ndefmessagemodel.cpp new file mode 100644 index 00000000..177d21dc --- /dev/null +++ b/examples/nfc/ndefeditor/ndefmessagemodel.cpp @@ -0,0 +1,156 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "ndefmessagemodel.h" + +#include <QNdefNfcTextRecord> +#include <QNdefNfcUriRecord> + +NdefMessageModel::NdefMessageModel(QObject *parent) : QAbstractListModel(parent) { } + +int NdefMessageModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_message.size(); +} + +static NdefMessageModel::RecordType getRecordType(const QNdefRecord &record) +{ + if (record.isRecordType<QNdefNfcTextRecord>()) { + return NdefMessageModel::TextRecord; + } else if (record.isRecordType<QNdefNfcUriRecord>()) { + return NdefMessageModel::UriRecord; + } + return NdefMessageModel::OtherRecord; +} + +static QString getText(const QNdefRecord &record) +{ + if (record.isRecordType<QNdefNfcTextRecord>()) { + QNdefNfcTextRecord r(record); + return r.text(); + } else if (record.isRecordType<QNdefNfcUriRecord>()) { + QNdefNfcUriRecord r(record); + return r.uri().toString(); + } + return record.payload().toHex(':'); +} + +QVariant NdefMessageModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return {}; + + if (index.row() < 0 || index.row() >= m_message.size()) + return {}; + + const auto &record = m_message.at(index.row()); + + switch (role) { + case RecordTypeRole: + return getRecordType(record); + case RecordTextRole: + return getText(record); + default: + return {}; + } +} + +QHash<int, QByteArray> NdefMessageModel::roleNames() const +{ + QHash<int, QByteArray> names; + names[RecordTypeRole] = "recordType"; + names[RecordTextRole] = "recordText"; + return names; +} + +bool NdefMessageModel::removeRows(int row, int count, const QModelIndex &parent) +{ + if (parent.isValid()) + return false; + if (row < 0 || count <= 0) + return false; + if (row >= m_message.size() || (m_message.size() - row) < count) + return false; + + beginRemoveRows(parent, row, row + count - 1); + m_message.remove(row, count); + endRemoveRows(); + Q_EMIT messageChanged(); + + return true; +} + +QNdefMessage NdefMessageModel::message() const +{ + return m_message; +} + +void NdefMessageModel::setMessage(const QNdefMessage &newMessage) +{ + if (m_message == newMessage) + return; + + beginResetModel(); + m_message = newMessage; + endResetModel(); + + Q_EMIT messageChanged(); +} + +void NdefMessageModel::clearMessage() +{ + if (m_message.isEmpty()) + return; + removeRows(0, m_message.size(), {}); +} + +void NdefMessageModel::addTextRecord(const QString &text) +{ + QNdefNfcTextRecord record; + record.setText(text); + + const auto newRow = m_message.size(); + beginInsertRows({}, newRow, newRow); + m_message.append(std::move(record)); + endInsertRows(); + Q_EMIT messageChanged(); +} + +void NdefMessageModel::addUriRecord(const QString &uri) +{ + QNdefNfcUriRecord record; + record.setUri(QUrl(uri)); + + const auto newRow = m_message.size(); + beginInsertRows({}, newRow, newRow); + m_message.append(std::move(record)); + endInsertRows(); + Q_EMIT messageChanged(); +} + +void NdefMessageModel::setTextData(int row, const QString &text) +{ + if (row < 0 || row >= m_message.size()) + return; + + const auto &record = m_message.at(row); + + if (record.isRecordType<QNdefNfcTextRecord>()) { + QNdefNfcTextRecord r(record); + r.setText(text); + m_message[row] = r; + } else if (record.isRecordType<QNdefNfcUriRecord>()) { + QNdefNfcUriRecord r(record); + r.setUri(text); + m_message[row] = r; + } else { + return; + } + + const auto idx = index(row); + Q_EMIT dataChanged(idx, idx, { RecordTextRole }); + Q_EMIT messageChanged(); +} diff --git a/examples/nfc/ndefeditor/ndefmessagemodel.h b/examples/nfc/ndefeditor/ndefmessagemodel.h new file mode 100644 index 00000000..5f9ddf24 --- /dev/null +++ b/examples/nfc/ndefeditor/ndefmessagemodel.h @@ -0,0 +1,53 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef NDEFMESSAGEMODEL_H +#define NDEFMESSAGEMODEL_H + +#include <QAbstractListModel> + +#include <QNdefMessage> +#include <QQmlEngine> + +class NdefMessageModel : public QAbstractListModel +{ + Q_OBJECT + QML_ELEMENT + Q_PROPERTY(QNdefMessage message READ message WRITE setMessage NOTIFY messageChanged) + +public: + explicit NdefMessageModel(QObject *parent = nullptr); + + enum Role { + RecordTypeRole, + RecordTextRole, + }; + + enum RecordType { + OtherRecord, + TextRecord, + UriRecord, + }; + Q_ENUM(RecordType) + + int rowCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role) const override; + QHash<int, QByteArray> roleNames() const override; + bool removeRows(int row, int count, const QModelIndex &parent) override; + + QNdefMessage message() const; + void setMessage(const QNdefMessage &newMessage); + + Q_INVOKABLE void clearMessage(); + Q_INVOKABLE void addTextRecord(const QString &text); + Q_INVOKABLE void addUriRecord(const QString &uri); + Q_INVOKABLE void setTextData(int row, const QString &text); + +Q_SIGNALS: + void messageChanged(); + +private: + QNdefMessage m_message; +}; + +#endif // NDEFMESSAGEMODEL_H diff --git a/examples/nfc/ndefeditor/nfcmanager.cpp b/examples/nfc/ndefeditor/nfcmanager.cpp new file mode 100644 index 00000000..bc09b89e --- /dev/null +++ b/examples/nfc/ndefeditor/nfcmanager.cpp @@ -0,0 +1,29 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "nfcmanager.h" + +#include <QNearFieldManager> + +#include "nfctarget.h" + +NfcManager::NfcManager(QObject *parent) : QObject(parent) +{ + m_manager = new QNearFieldManager(this); + + connect(m_manager, &QNearFieldManager::targetDetected, this, [this](QNearFieldTarget *target) { + auto jsTarget = new NfcTarget(target); + QJSEngine::setObjectOwnership(jsTarget, QJSEngine::JavaScriptOwnership); + Q_EMIT targetDetected(jsTarget); + }); +} + +void NfcManager::startTargetDetection() +{ + m_manager->startTargetDetection(QNearFieldTarget::NdefAccess); +} + +void NfcManager::stopTargetDetection() +{ + m_manager->stopTargetDetection(); +} diff --git a/examples/nfc/ndefeditor/nfcmanager.h b/examples/nfc/ndefeditor/nfcmanager.h new file mode 100644 index 00000000..b30f6f36 --- /dev/null +++ b/examples/nfc/ndefeditor/nfcmanager.h @@ -0,0 +1,33 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef NFCMANAGER_H +#define NFCMANAGER_H + +#include <QObject> + +#include <QQmlEngine> + +#include "nfctarget.h" + +QT_FORWARD_DECLARE_CLASS(QNearFieldManager); + +class NfcManager : public QObject +{ + Q_OBJECT + QML_ELEMENT + +public: + explicit NfcManager(QObject *parent = nullptr); + + Q_INVOKABLE void startTargetDetection(); + Q_INVOKABLE void stopTargetDetection(); + +Q_SIGNALS: + void targetDetected(NfcTarget *target); + +private: + QNearFieldManager *m_manager; +}; + +#endif // NFCMANAGER_H diff --git a/examples/nfc/ndefeditor/nfctarget.cpp b/examples/nfc/ndefeditor/nfctarget.cpp new file mode 100644 index 00000000..68b26df5 --- /dev/null +++ b/examples/nfc/ndefeditor/nfctarget.cpp @@ -0,0 +1,31 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "nfctarget.h" + +NfcTarget::NfcTarget(QNearFieldTarget *target, QObject *parent) : QObject(parent), m_target(target) +{ + target->setParent(this); + + connect(target, &QNearFieldTarget::ndefMessageRead, this, &NfcTarget::ndefMessageRead); + connect(target, &QNearFieldTarget::requestCompleted, this, &NfcTarget::requestCompleted); + connect(target, &QNearFieldTarget::error, this, &NfcTarget::error); +} + +bool NfcTarget::readNdefMessages() +{ + if (m_target.isNull()) + return false; + + auto req = m_target->readNdefMessages(); + return req.isValid(); +} + +bool NfcTarget::writeNdefMessage(const QNdefMessage &message) +{ + if (m_target.isNull()) + return false; + + auto req = m_target->writeNdefMessages({ message }); + return req.isValid(); +} diff --git a/examples/nfc/ndefeditor/nfctarget.h b/examples/nfc/ndefeditor/nfctarget.h new file mode 100644 index 00000000..fbe3183c --- /dev/null +++ b/examples/nfc/ndefeditor/nfctarget.h @@ -0,0 +1,35 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef NFCTARGET_H +#define NFCTARGET_H + +#include <QObject> + +#include <QNdefMessage> +#include <QNearFieldTarget> +#include <QPointer> +#include <QQmlEngine> + +class NfcTarget : public QObject +{ + Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("Created by NfcManager") + +public: + explicit NfcTarget(QNearFieldTarget *target, QObject *parent = nullptr); + + Q_INVOKABLE bool readNdefMessages(); + Q_INVOKABLE bool writeNdefMessage(const QNdefMessage &message); + +Q_SIGNALS: + void ndefMessageRead(const QNdefMessage &message); + void requestCompleted(); + void error(QNearFieldTarget::Error error); + +private: + QPointer<QNearFieldTarget> m_target; +}; + +#endif // NFCTARGET_H diff --git a/examples/nfc/ndefeditor/qmldir b/examples/nfc/ndefeditor/qmldir new file mode 100644 index 00000000..0a77d792 --- /dev/null +++ b/examples/nfc/ndefeditor/qmldir @@ -0,0 +1,5 @@ +module NdefEditor +prefer :/qt/qml/NdefEditor/ +Main 1.0 Main.qml +MainWindow 1.0 MainWindow.qml +NdefRecordDelegate 1.0 NdefRecordDelegate.qml diff --git a/examples/nfc/ndefeditor/textrecordeditor.cpp b/examples/nfc/ndefeditor/textrecordeditor.cpp deleted file mode 100644 index 381ff88f..00000000 --- a/examples/nfc/ndefeditor/textrecordeditor.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module 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 "textrecordeditor.h" -#include "ui_textrecordeditor.h" - -TextRecordEditor::TextRecordEditor(QWidget *parent) : - QWidget(parent), - ui(new Ui::TextRecordEditor) -{ - ui->setupUi(this); -} - -TextRecordEditor::~TextRecordEditor() -{ - delete ui; -} - -void TextRecordEditor::setRecord(const QNdefNfcTextRecord &textRecord) -{ - ui->text->setText(textRecord.text()); - ui->locale->setText(textRecord.locale()); - - if (textRecord.encoding() == QNdefNfcTextRecord::Utf8) - ui->encoding->setCurrentIndex(0); - else if (textRecord.encoding() == QNdefNfcTextRecord::Utf16) - ui->encoding->setCurrentIndex(1); -} - -QNdefNfcTextRecord TextRecordEditor::record() const -{ - QNdefNfcTextRecord record; - - if (ui->encoding->currentIndex() == 0) - record.setEncoding(QNdefNfcTextRecord::Utf8); - else if (ui->encoding->currentIndex() == 1) - record.setEncoding(QNdefNfcTextRecord::Utf16); - - record.setLocale(ui->locale->text()); - - record.setText(ui->text->text()); - - return record; -} diff --git a/examples/nfc/ndefeditor/textrecordeditor.h b/examples/nfc/ndefeditor/textrecordeditor.h deleted file mode 100644 index df3a872c..00000000 --- a/examples/nfc/ndefeditor/textrecordeditor.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module 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 TEXTRECORDEDITOR_H -#define TEXTRECORDEDITOR_H - -#include <QtNfc/qndefnfctextrecord.h> - -#include <QtWidgets/QWidget> - -QT_BEGIN_NAMESPACE -namespace Ui { - class TextRecordEditor; -} -QT_END_NAMESPACE - -//! [0] -class TextRecordEditor : public QWidget -{ - Q_OBJECT - -public: - explicit TextRecordEditor(QWidget *parent = 0); - ~TextRecordEditor(); - - void setRecord(const QNdefNfcTextRecord &textRecord); - QNdefNfcTextRecord record() const; - -private: - Ui::TextRecordEditor *ui; -}; -//! [0] - -#endif // TEXTRECORDEDITOR_H diff --git a/examples/nfc/ndefeditor/textrecordeditor.ui b/examples/nfc/ndefeditor/textrecordeditor.ui deleted file mode 100644 index 41950e7d..00000000 --- a/examples/nfc/ndefeditor/textrecordeditor.ui +++ /dev/null @@ -1,101 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>TextRecordEditor</class> - <widget class="QWidget" name="TextRecordEditor"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>344</width> - <height>115</height> - </rect> - </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Minimum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="windowTitle"> - <string>Form</string> - </property> - <layout class="QFormLayout" name="formLayout"> - <property name="rowWrapPolicy"> - <enum>QFormLayout::WrapLongRows</enum> - </property> - <item row="0" column="0" colspan="2"> - <widget class="QLabel" name="label_5"> - <property name="text"> - <string>NFC Text Record</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_7"> - <property name="text"> - <string>Text:</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLineEdit" name="text"> - <property name="sizePolicy"> - <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_6"> - <property name="text"> - <string>Locale:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLineEdit" name="locale"> - <property name="sizePolicy"> - <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Encoding:</string> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QComboBox" name="encoding"> - <property name="sizePolicy"> - <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <item> - <property name="text"> - <string>UTF-8</string> - </property> - </item> - <item> - <property name="text"> - <string>UTF-16</string> - </property> - </item> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/examples/nfc/ndefeditor/urirecordeditor.cpp b/examples/nfc/ndefeditor/urirecordeditor.cpp deleted file mode 100644 index 4088aece..00000000 --- a/examples/nfc/ndefeditor/urirecordeditor.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module 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 "urirecordeditor.h" -#include "ui_urirecordeditor.h" - -#include <QtCore/QUrl> - -UriRecordEditor::UriRecordEditor(QWidget *parent) : - QWidget(parent), - ui(new Ui::UriRecordEditor) -{ - ui->setupUi(this); -} - -UriRecordEditor::~UriRecordEditor() -{ - delete ui; -} - -void UriRecordEditor::setRecord(const QNdefNfcUriRecord &uriRecord) -{ - ui->uri->setText(uriRecord.uri().toString()); -} - -QNdefNfcUriRecord UriRecordEditor::record() const -{ - QNdefNfcUriRecord record; - - record.setUri(ui->uri->text()); - - return record; -} diff --git a/examples/nfc/ndefeditor/urirecordeditor.h b/examples/nfc/ndefeditor/urirecordeditor.h deleted file mode 100644 index aa3f4dfc..00000000 --- a/examples/nfc/ndefeditor/urirecordeditor.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module 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 URIRECORDEDITOR_H -#define URIRECORDEDITOR_H - -#include <QtNfc/qndefnfcurirecord.h> - -#include <QtWidgets/QWidget> - -QT_BEGIN_NAMESPACE -namespace Ui { - class UriRecordEditor; -} -QT_END_NAMESPACE - -//! [0] -class UriRecordEditor : public QWidget -{ - Q_OBJECT - -public: - explicit UriRecordEditor(QWidget *parent = 0); - ~UriRecordEditor(); - - void setRecord(const QNdefNfcUriRecord &uriRecord); - QNdefNfcUriRecord record() const; - -private: - Ui::UriRecordEditor *ui; -}; -//! [0] -#endif // URIRECORDEDITOR_H diff --git a/examples/nfc/ndefeditor/urirecordeditor.ui b/examples/nfc/ndefeditor/urirecordeditor.ui deleted file mode 100644 index 929c1eb4..00000000 --- a/examples/nfc/ndefeditor/urirecordeditor.ui +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>UriRecordEditor</class> - <widget class="QWidget" name="UriRecordEditor"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>439</width> - <height>59</height> - </rect> - </property> - <property name="windowTitle"> - <string>Form</string> - </property> - <layout class="QFormLayout" name="formLayout"> - <item row="0" column="0" colspan="2"> - <widget class="QLabel" name="label_8"> - <property name="text"> - <string>NFC URI Record</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_9"> - <property name="text"> - <string>Uri:</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLineEdit" name="uri"> - <property name="sizePolicy"> - <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/examples/nfc/nfc.pro b/examples/nfc/nfc.pro index 0076a711..49d54525 100644 --- a/examples/nfc/nfc.pro +++ b/examples/nfc/nfc.pro @@ -1,12 +1,7 @@ TEMPLATE = subdirs qtHaveModule(widgets) { - SUBDIRS += \ - annotatedurl \ - ndefeditor + SUBDIRS += annotatedurl } -qtHaveModule(quick) { - SUBDIRS += \ - poster +qtHaveModule(quickcontrols2) { + SUBDIRS += ndefeditor } - -qtHaveModule(quick): SUBDIRS += corkboard diff --git a/examples/nfc/poster/doc/images/qml-poster-example.png b/examples/nfc/poster/doc/images/qml-poster-example.png Binary files differdeleted file mode 100644 index 8ed2292c..00000000 --- a/examples/nfc/poster/doc/images/qml-poster-example.png +++ /dev/null diff --git a/examples/nfc/poster/doc/src/poster.qdoc b/examples/nfc/poster/doc/src/poster.qdoc deleted file mode 100644 index b94bcca8..00000000 --- a/examples/nfc/poster/doc/src/poster.qdoc +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt local connectivty modules. -** -** $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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! -\example poster -\title QML Poster Example -\brief A QML example about reading and displaying NFC Data Exchange Format (NDEF) messages. - -The QML Poster example displays the contents of specifically formatted NFC Data -Exchange Format (NDEF) messages read from an NFC Tag. The NDEF message must -contain a URI record, an optional \c image/* MIME record, and one or more -localized Text records. - -\image qml-poster-example.png - -\include examples-run.qdocinc - -\section1 Applying NDEF Filters - -The example is designed to display the content of a very specific type of NFC tag. -The tag must contain at least one URI record and one text record. If those two -record types do not exist, nothing will happen. Such filtering is applied via the -\l NearField type's filter property. The property accepts a list of \l NdefFilter objects. - -\snippet poster/poster.qml QML NDEF filtering - -\section1 Processing Found NDEF Messages - -Once an appropriate tag is found, the \l NearField::messageRecords property reflects the content. -It transports the list of found NDEF records. The QML snippet below -demonstrates how these records can be accessed: - -\snippet poster/poster.qml messageRecordsChanged 1 -\snippet poster/poster.qml messageRecordsChanged 2 -\snippet poster/poster.qml messageRecordsChanged 3 - -\sa {Qt NFC} -*/ diff --git a/examples/nfc/poster/poster.pro b/examples/nfc/poster/poster.pro deleted file mode 100644 index b6e87ed6..00000000 --- a/examples/nfc/poster/poster.pro +++ /dev/null @@ -1,16 +0,0 @@ -QT += qml quick network nfc - -SOURCES += \ - qmlposter.cpp - -TARGET = qml_poster -TEMPLATE = app - -RESOURCES += \ - poster.qrc - -OTHER_FILES += \ - poster.qml - -target.path = $$[QT_INSTALL_EXAMPLES]/nfc/poster -INSTALLS += target diff --git a/examples/nfc/poster/poster.qml b/examples/nfc/poster/poster.qml deleted file mode 100644 index 3e2a1eda..00000000 --- a/examples/nfc/poster/poster.qml +++ /dev/null @@ -1,218 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module 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.3 -import QtNfc 5.5 - -Rectangle { - id: root - width: 640 - height: 360 - - NearField { - id: nearfield - property bool requiresManualPolling: false - - onPollingChanged: { - if (!polling && requiresManualPolling) - polling = true; //restart polling - } - - Component.onCompleted: { - if (!polling) { - requiresManualPolling = true; - polling = true; - } - } - - //! [QML NDEF filtering] - filter: [ - NdefFilter { type: "U"; typeNameFormat: NdefRecord.NfcRtd; maximum: 1 }, - NdefFilter { type: "T"; typeNameFormat: NdefRecord.NfcRtd }, - NdefFilter { typeNameFormat: NdefRecord.Mime; minimum: 0; maximum: 1 } - ] - - //! [QML NDEF filtering] - - //! [messageRecordsChanged 1] - onMessageRecordsChanged: { - //! [messageRecordsChanged 1] - posterText.text = ""; - posterImage.source = ""; - posterUrl.text = ""; - - var currentLocaleMatch = NdefTextRecord.LocaleMatchedNone; - var i; - var found = false; - //! [messageRecordsChanged 2] - for (i = 0; i < messageRecords.length; ++i) { - switch (messageRecords[i].typeNameFormat) { - case NdefRecord.NfcRtd: - if (messageRecords[i].type === "T") { - if (messageRecords[i].localeMatch > currentLocaleMatch) { - currentLocaleMatch = messageRecords[i].localeMatch; - posterText.text = messageRecords[i].text; - found = true; - } - - } else if (messageRecords[i].type === "U") { - posterUrl.text = messageRecords[i].uri; - found = true; - } - break; - case NdefRecord.Mime: - if (messageRecords[i].type.indexOf("image/") === 0 ) { - posterImage.source = messageRecords[i].uri; - found = true; - } - break; - } - - if (!found) - console.warn("Unknown NFC tag detected. Cannot display content.") - } - //! [messageRecordsChanged 2] - - root.state = "show"; - //! [messageRecordsChanged 3] - } - //! [messageRecordsChanged 3] - } - - Text { - id: touchText - anchors { horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.verticalCenter } - text: "Touch an NFC tag with at least one Text and one URI record." - font { italic: true; pointSize: 18 } - wrapMode: Text.WordWrap - width: root.width*0.75 - horizontalAlignment: Text.AlignHCenter - } - - Image { - id: posterImage - scale: Image.PreserveAspectFit - height: parent.height * 0.8 - width: height * sourceSize.width / sourceSize.height - anchors.verticalCenter: parent.verticalCenter - x: -width - smooth: true - } - - Text { - id: posterText - y: -height - anchors { horizontalCenter: parent.right; horizontalCenterOffset: - parent.width / 4 } - font { italic: true; pointSize: 18 } - } - - Text { - id: posterUrl - y: parent.height - anchors { horizontalCenter: parent.right; horizontalCenterOffset: - parent.width / 4 } - font { italic: true; pointSize: 14 } - } - - MouseArea { - id: openMouseArea - anchors.fill: parent - enabled: root.state == "show" - onClicked: Qt.openUrlExternally(posterUrl.text) - - Rectangle { - id: testTouch - width: 50 - height: 50 - color: "lightsteelblue" - opacity: 0.3 - anchors { top: parent.top; right: close.left; rightMargin: 10 } - MouseArea { - id: touchMouseArea - anchors.fill: parent - onClicked: { - if (root.state == "") { - root.state = "show"; - } else { - root.state = ""; - } - } - } - } - - Rectangle { - id: close - width: 50 - height: 50 - color: "black" - radius: 0 - opacity: 0.3 - anchors { top: parent.top; topMargin: 0; right: parent.right; rightMargin: 0 } - MouseArea { - id: closeMouseArea - anchors.fill: parent - onClicked: Qt.quit(); - } - } - } - - states: State { - name: "show" - PropertyChanges { target: posterText; y: root.height / 3 } - PropertyChanges { target: posterUrl; y: 2 * root.height / 3 } - PropertyChanges { target: posterImage; x: root.width / 20 } - PropertyChanges { target: touchText; opacity: 0 } - } - - - transitions: Transition { - PropertyAnimation { easing.type: Easing.OutQuad; properties: "x,y" } - PropertyAnimation { property: "opacity"; duration: 125 } - } -} diff --git a/examples/nfc/poster/poster.qrc b/examples/nfc/poster/poster.qrc deleted file mode 100644 index 7bb30667..00000000 --- a/examples/nfc/poster/poster.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>poster.qml</file> - </qresource> -</RCC> diff --git a/examples/nfc/poster/qmlposter.cpp b/examples/nfc/poster/qmlposter.cpp deleted file mode 100644 index a4f98de3..00000000 --- a/examples/nfc/poster/qmlposter.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNfc module 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 <QtGui/QGuiApplication> -#include <QtQml/QQmlEngine> -#include <QtQuick/QQuickView> - -int main(int argc, char *argv[]) -{ - QGuiApplication application(argc, argv); - const QString mainQmlApp(QStringLiteral("qrc:/poster.qml")); - QQuickView view; - view.setSource(QUrl(mainQmlApp)); - view.setResizeMode(QQuickView::SizeRootObjectToView); - // Qt.quit() called in embedded .qml by default only emits - // quit() signal, so do this (optionally use Qt.exit()). - QObject::connect(view.engine(), &QQmlEngine::quit, qApp, &QGuiApplication::quit); - view.setGeometry(QRect(100, 100, 640, 360)); - view.show(); - return application.exec(); -} |