NDEF Editor Example▲
Sélectionnez
/**
**************************************************************************
**
** 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 &
amp;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 &
amp;record) {
m_record =
record; }
QNdefRecord record() const
{
return
m_record; }
private
:
QNdefRecord m_record;
}
;
template
&
lt;typename
T&
gt;
void
addRecord(Ui::
MainWindow *
ui, const
QNdefRecord &
amp;record =
QNdefRecord())
{
QVBoxLayout *
vbox =
qobject_cast&
lt;QVBoxLayout *&
gt;(ui-&
gt;scrollAreaWidgetContents-&
gt;layout());
if
(!
vbox)
return
;
if
(!
vbox-&
gt;isEmpty()) {
QFrame *
hline =
new
QFrame;
hline-&
gt;setFrameShape(QFrame::
HLine);
hline-&
gt;setObjectName(QStringLiteral("line-spacer"
));
vbox-&
gt;addWidget(hline);
}
T *
recordEditor =
new
T;
recordEditor-&
gt;setObjectName(QStringLiteral("record-editor"
));
if
(!
record.isEmpty())
recordEditor-&
gt;setRecord(record);
vbox-&
gt;addWidget(recordEditor);
}
MainWindow::
MainWindow(QWidget *
parent)
:
QMainWindow(parent), ui(new
Ui::
MainWindow), m_touchAction(NoAction)
{
ui-&
gt;setupUi(this
);
QMenu *
addRecordMenu =
new
QMenu(this
);
addRecordMenu-&
gt;addAction(tr("NFC Text Record"
), this
, SLOT(addNfcTextRecord()));
addRecordMenu-&
gt;addAction(tr("NFC URI Record"
), this
, SLOT(addNfcUriRecord()));
addRecordMenu-&
gt;addAction(tr("MIME Image Record"
), this
, SLOT(addMimeImageRecord()));
addRecordMenu-&
gt;addAction(tr("Empty Record"
), this
, SLOT(addEmptyRecord()));
ui-&
gt;addRecord-&
gt;setMenu(addRecordMenu);
QVBoxLayout *
vbox =
new
QVBoxLayout;
ui-&
gt;scrollAreaWidgetContents-&
gt;setLayout(vbox);
m_manager =
new
QNearFieldManager(this
);
connect(m_manager, &
amp;QNearFieldManager::
targetDetected,
this
, &
amp;MainWindow::
targetDetected);
connect(m_manager, &
amp;QNearFieldManager::
targetLost,
this
, &
amp;MainWindow::
targetLost);
}
MainWindow::
~
MainWindow()
{
delete
ui;
}
void
MainWindow::
addNfcTextRecord()
{
addRecord&
lt;TextRecordEditor&
gt;(ui);
}
void
MainWindow::
addNfcUriRecord()
{
addRecord&
lt;UriRecordEditor&
gt;(ui);
}
void
MainWindow::
addMimeImageRecord()
{
addRecord&
lt;MimeImageRecordEditor&
gt;(ui);
}
void
MainWindow::
addEmptyRecord()
{
addRecord&
lt;EmptyRecordLabel&
gt;(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-&
gt;status-&
gt;setStyleSheet(QStringLiteral("background: blue"
));
m_touchAction =
ReadNdef;
m_manager-&
gt;setTargetAccessModes(QNearFieldManager::
NdefReadTargetAccess);
m_manager-&
gt;startTargetDetection();
}
void
MainWindow::
touchStore()
{
ui-&
gt;status-&
gt;setStyleSheet(QStringLiteral("background: yellow"
));
m_touchAction =
WriteNdef;
m_manager-&
gt;setTargetAccessModes(QNearFieldManager::
NdefWriteTargetAccess);
m_manager-&
gt;startTargetDetection();
}
void
MainWindow::
targetDetected(QNearFieldTarget *
target)
{
switch
(m_touchAction) {
case
NoAction:
break
;
case
ReadNdef:
connect(target, &
amp;QNearFieldTarget::
ndefMessageRead, this
, &
amp;MainWindow::
ndefMessageRead);
connect(target, &
amp;QNearFieldTarget::
error, this
, &
amp;MainWindow::
targetError);
m_request =
target-&
gt;readNdefMessages();
if
(!
m_request.isValid()) // cannot read messages
targetError(QNearFieldTarget::
NdefReadError, m_request);
break
;
case
WriteNdef:
connect(target, &
amp;QNearFieldTarget::
ndefMessagesWritten, this
, &
amp;MainWindow::
ndefMessageWritten);
connect(target, &
amp;QNearFieldTarget::
error, this
, &
amp;MainWindow::
targetError);
m_request =
target-&
gt;writeNdefMessages(QList&
lt;QNdefMessage&
gt;() &
lt;&
lt; ndefMessage());
if
(!
m_request.isValid()) // cannot write messages
targetError(QNearFieldTarget::
NdefWriteError, m_request);
break
;
}
}
void
MainWindow::
targetLost(QNearFieldTarget *
target)
{
target-&
gt;deleteLater();
}
void
MainWindow::
ndefMessageRead(const
QNdefMessage &
amp;message)
{
clearMessage();
for
(const
QNdefRecord &
amp;record : message) {
if
(record.isRecordType&
lt;QNdefNfcTextRecord&
gt;()) {
addRecord&
lt;TextRecordEditor&
gt;(ui, record);
}
else
if
(record.isRecordType&
lt;QNdefNfcUriRecord&
gt;()) {
addRecord&
lt;UriRecordEditor&
gt;(ui, record);
}
else
if
(record.typeNameFormat() ==
QNdefRecord::
Mime &
amp;&
amp;
record.type().startsWith("image/"
)) {
addRecord&
lt;MimeImageRecordEditor&
gt;(ui, record);
}
else
if
(record.isEmpty()) {
addRecord&
lt;EmptyRecordLabel&
gt;(ui);
}
else
{
addRecord&
lt;UnknownRecordLabel&
gt;(ui, record);
}
}
ui-&
gt;status-&
gt;setStyleSheet(QString());
m_manager-&
gt;setTargetAccessModes(QNearFieldManager::
NoTargetAccess);
m_manager-&
gt;stopTargetDetection();
m_request =
QNearFieldTarget::
RequestId();
ui-&
gt;statusBar-&
gt;clearMessage();
}
void
MainWindow::
ndefMessageWritten()
{
ui-&
gt;status-&
gt;setStyleSheet(QString());
m_manager-&
gt;setTargetAccessModes(QNearFieldManager::
NoTargetAccess);
m_manager-&
gt;stopTargetDetection();
m_request =
QNearFieldTarget::
RequestId();
ui-&
gt;statusBar-&
gt;clearMessage();
}
void
MainWindow::
targetError(QNearFieldTarget::
Error error, const
QNearFieldTarget::
RequestId &
amp;id)
{
Q_UNUSED(error);
Q_UNUSED(id);
if
(m_request ==
id) {
switch
(error) {
case
QNearFieldTarget::
NoError:
ui-&
gt;statusBar-&
gt;clearMessage();
break
;
case
QNearFieldTarget::
UnsupportedError:
ui-&
gt;statusBar-&
gt;showMessage(tr("Unsupported tag"
));
break
;
case
QNearFieldTarget::
TargetOutOfRangeError:
ui-&
gt;statusBar-&
gt;showMessage(tr("Tag removed from field"
));
break
;
case
QNearFieldTarget::
NoResponseError:
ui-&
gt;statusBar-&
gt;showMessage(tr("No response from tag"
));
break
;
case
QNearFieldTarget::
ChecksumMismatchError:
ui-&
gt;statusBar-&
gt;showMessage(tr("Checksum mismatch"
));
break
;
case
QNearFieldTarget::
InvalidParametersError:
ui-&
gt;statusBar-&
gt;showMessage(tr("Invalid parameters"
));
break
;
case
QNearFieldTarget::
NdefReadError:
ui-&
gt;statusBar-&
gt;showMessage(tr("NDEF read error"
));
break
;
case
QNearFieldTarget::
NdefWriteError:
ui-&
gt;statusBar-&
gt;showMessage(tr("NDEF write error"
));
break
;
default
:
ui-&
gt;statusBar-&
gt;showMessage(tr("Unknown error"
));
}
ui-&
gt;status-&
gt;setStyleSheet(QString());
m_manager-&
gt;setTargetAccessModes(QNearFieldManager::
NoTargetAccess);
m_manager-&
gt;stopTargetDetection();
m_request =
QNearFieldTarget::
RequestId();
}
}
void
MainWindow::
clearMessage()
{
QWidget *
scrollArea =
ui-&
gt;scrollAreaWidgetContents;
qDeleteAll(scrollArea-&
gt;findChildren&
lt;QWidget *&
gt;(QStringLiteral("line-spacer"
)));
qDeleteAll(scrollArea-&
gt;findChildren&
lt;QWidget *&
gt;(QStringLiteral("record-editor"
)));
}
QNdefMessage MainWindow::
ndefMessage() const
{
QVBoxLayout *
vbox =
qobject_cast&
lt;QVBoxLayout *&
gt;(ui-&
gt;scrollAreaWidgetContents-&
gt;layout());
if
(!
vbox)
return
QNdefMessage();
QNdefMessage message;
for
(int
i =
0
; i &
lt; vbox-&
gt;count(); ++
i) {
QWidget *
widget =
vbox-&
gt;itemAt(i)-&
gt;widget();
if
(TextRecordEditor *
editor =
qobject_cast&
lt;TextRecordEditor *&
gt;(widget)) {
message.append(editor-&
gt;record());
}
else
if
(UriRecordEditor *
editor =
qobject_cast&
lt;UriRecordEditor *&
gt;(widget)) {
message.append(editor-&
gt;record());
}
else
if
(MimeImageRecordEditor *
editor =
qobject_cast&
lt;MimeImageRecordEditor *&
gt;(widget)) {
message.append(editor-&
gt;record());
}
else
if
(qobject_cast&
lt;EmptyRecordLabel *&
gt;(widget)) {
message.append(QNdefRecord());
}
else
if
(UnknownRecordLabel *
label =
qobject_cast&
lt;UnknownRecordLabel *&
gt;(widget)) {
message.append(label-&
gt;record());
}
}
return
message;
}
#include
"mainwindow.moc"