Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qndefnfcsmartposterrecord.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 - 2012 Research In Motion
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <qndefnfcsmartposterrecord.h>
6#include <qndefmessage.h>
7
8#include <QtCore/QString>
9#include <QtCore/QStringList>
10#include <QtCore/QUrl>
11
12QT_BEGIN_NAMESPACE
13
14/*!
15 \class QNdefNfcIconRecord
16 \brief The QNdefNfcIconRecord class provides an NFC MIME record to hold an
17 icon.
18
19 \ingroup connectivity-nfc
20 \inmodule QtNfc
21 \since Qt 5.2
22
23 This class wraps the image data into an NDEF message.
24 It provides an NDEF record of type \l QNdefRecord::Mime.
25 The \l {QNdefRecord::}{payload}() contains the raw image data.
26*/
27
28/*!
29 \fn QNdefNfcIconRecord::QNdefNfcIconRecord()
30
31 Constructs an empty NDEF record of type \l QNdefRecord::Mime.
32*/
33
34/*!
35 \fn QNdefNfcIconRecord::QNdefNfcIconRecord(const QNdefRecord &other)
36
37 Constructs an NDEF icon record that is a copy of \a other.
38*/
39
40/*!
41 \class QNdefNfcSmartPosterRecord
42 \brief The QNdefNfcSmartPosterRecord class provides an NFC RTD-SmartPoster.
43
44 \ingroup connectivity-nfc
45 \inmodule QtNfc
46 \since Qt 5.2
47
48 RTD-SmartPoster encapsulates a Smart Poster.
49 */
50
51/*!
52 \enum QNdefNfcSmartPosterRecord::Action
53
54 This enum describes the course of action that a device should take with the content.
55
56 \value UnspecifiedAction The action is not defined.
57 \value DoAction Do the action (send the SMS, launch the browser, make the telephone call).
58 \value SaveAction Save for later (store the SMS in INBOX, put the URI in a bookmark, save the telephone number in contacts).
59 \value EditAction Open for editing (open an SMS in the SMS editor, open the URI in a URI editor, open the telephone number for editing).
60 */
61
62QNdefNfcSmartPosterRecordPrivate::~QNdefNfcSmartPosterRecordPrivate()
63{
64 cleanup();
65}
66
67void QNdefNfcSmartPosterRecordPrivate::cleanup()
68{
69 // Clean-up existing internal structure
70 m_titleList.clear();
71 delete m_uri;
72 delete m_action;
73 m_iconList.clear();
74 delete m_size;
75 delete m_type;
76}
77
78/*!
79 Constructs a new empty smart poster.
80*/
81QNdefNfcSmartPosterRecord::QNdefNfcSmartPosterRecord()
82 : QNdefRecord(QNdefRecord::NfcRtd, "Sp"),
83 d(new QNdefNfcSmartPosterRecordPrivate)
84{
85}
86
87/*!
88 Constructs a new smart poster that is a copy of \a other.
89*/
90QNdefNfcSmartPosterRecord::QNdefNfcSmartPosterRecord(const QNdefRecord &other)
91 : QNdefRecord(other, QNdefRecord::NfcRtd, "Sp"),
92 d(new QNdefNfcSmartPosterRecordPrivate)
93{
94 // Need to set payload again to create internal structure
95 setPayload(other.payload());
96}
97
98/*!
99 Constructs a new smart poster that is a copy of \a other.
100*/
101QNdefNfcSmartPosterRecord::QNdefNfcSmartPosterRecord(const QNdefNfcSmartPosterRecord &other)
102 : QNdefRecord(other, QNdefRecord::NfcRtd, "Sp"), d(other.d)
103{
104}
105
106/*!
107 Assigns the \a other smart poster record to this record and returns a reference to
108 this record.
109*/
110QNdefNfcSmartPosterRecord &QNdefNfcSmartPosterRecord::operator=(const QNdefNfcSmartPosterRecord &other)
111{
112 if (this != &other)
113 d = other.d;
114
115 return *this;
116}
117
118/*!
119 Destroys the smart poster.
120*/
121QNdefNfcSmartPosterRecord::~QNdefNfcSmartPosterRecord()
122{
123}
124
125void QNdefNfcSmartPosterRecord::cleanup()
126{
127 if (d)
128 d->cleanup();
129}
130
131/*!
132 \internal
133 Sets the payload of the NDEF record to \a payload
134*/
135void QNdefNfcSmartPosterRecord::setPayload(const QByteArray &payload)
136{
137 QNdefRecord::setPayload(payload);
138
139 cleanup();
140
141 if (!payload.isEmpty()) {
142 // Create new structure
143 const QNdefMessage message = QNdefMessage::fromByteArray(payload);
144
145 // Iterate through all the records contained in the payload's message.
146 for (const QNdefRecord& record : message) {
147 // Title
148 if (record.isRecordType<QNdefNfcTextRecord>()) {
149 addTitleInternal(record);
150 }
151
152 // URI
153 else if (record.isRecordType<QNdefNfcUriRecord>()) {
154 d->m_uri = new QNdefNfcUriRecord(record);
155 }
156
157 // Action
158 else if (record.isRecordType<QNdefNfcActRecord>()) {
159 d->m_action = new QNdefNfcActRecord(record);
160 }
161
162 // Icon
163 else if (record.isRecordType<QNdefNfcIconRecord>()) {
164 addIconInternal(record);
165 }
166
167 // Size
168 else if (record.isRecordType<QNdefNfcSizeRecord>()) {
169 d->m_size = new QNdefNfcSizeRecord(record);
170 }
171
172 // Type
173 else if (record.isRecordType<QNdefNfcTypeRecord>()) {
174 d->m_type = new QNdefNfcTypeRecord(record);
175 }
176 }
177 }
178}
179
180void QNdefNfcSmartPosterRecord::convertToPayload()
181{
182 QNdefMessage message;
183
184 // Title
185 for (qsizetype t = 0; t < titleCount(); t++)
186 message.append(titleRecord(t));
187
188 // URI
189 if (d->m_uri)
190 message.append(*(d->m_uri));
191
192 // Action
193 if (d->m_action)
194 message.append(*(d->m_action));
195
196 // Icon
197 for (qsizetype i = 0; i < iconCount(); i++)
198 message.append(iconRecord(i));
199
200 // Size
201 if (d->m_size)
202 message.append(*(d->m_size));
203
204 // Type
205 if (d->m_type)
206 message.append(*(d->m_type));
207
208 QNdefRecord::setPayload(message.toByteArray());
209}
210
211/*!
212 Returns \c true if the smart poster contains a title record using the locale
213 \a locale. If \a locale is empty, then \c true is returned if the smart
214 poster contains at least one title record. In all other cases, \c false is
215 returned.
216 */
217bool QNdefNfcSmartPosterRecord::hasTitle(const QString &locale) const
218{
219 for (qsizetype i = 0; i < d->m_titleList.size(); ++i) {
220 const QNdefNfcTextRecord &text = d->m_titleList[i];
221
222 if (locale.isEmpty() || text.locale() == locale)
223 return true;
224 }
225
226 return false;
227}
228
229/*!
230 Returns \c true if the smart poster contains an action record, otherwise
231 returns \c false.
232 */
233bool QNdefNfcSmartPosterRecord::hasAction() const
234{
235 return d->m_action != nullptr;
236}
237
238/*!
239 Returns \c true if the smart poster contains an icon record using the type
240 \a mimetype. If \a mimetype is empty, then \c true is returned if the smart
241 poster contains at least one icon record.
242 In all other cases, \c false is returned.
243 */
244bool QNdefNfcSmartPosterRecord::hasIcon(const QByteArray &mimetype) const
245{
246 for (qsizetype i = 0; i < d->m_iconList.size(); ++i) {
247 const QNdefNfcIconRecord &icon = d->m_iconList[i];
248
249 if (mimetype.isEmpty() || icon.type() == mimetype)
250 return true;
251 }
252
253 return false;
254}
255
256/*!
257 Returns \c true if the smart poster contains a size record, otherwise
258 returns \c false.
259 */
260bool QNdefNfcSmartPosterRecord::hasSize() const
261{
262 return d->m_size != nullptr;
263}
264
265/*!
266 Returns \c true if the smart poster contains a type record, otherwise
267 returns \c false.
268 */
269bool QNdefNfcSmartPosterRecord::hasTypeInfo() const
270{
271 return d->m_type != nullptr;
272}
273
274/*!
275 Returns the number of title records contained inside the smart poster.
276 */
277qsizetype QNdefNfcSmartPosterRecord::titleCount() const
278{
279 return d->m_titleList.size();
280}
281
282/*!
283 Returns the title record corresponding to the index \a index inside the
284 smart poster, where \a index is a value between 0 and titleCount() - 1.
285 Values outside of this range return an empty record.
286 */
287QNdefNfcTextRecord QNdefNfcSmartPosterRecord::titleRecord(qsizetype index) const
288{
289 if (index >= 0 && index < d->m_titleList.size())
290 return d->m_titleList[index];
291
292 return QNdefNfcTextRecord();
293}
294
295/*!
296 Returns the title record text associated with locale \a locale if available. If \a locale
297 is empty then the title text of the first available record is returned. In all other
298 cases an empty string is returned.
299 */
300QString QNdefNfcSmartPosterRecord::title(const QString &locale) const
301{
302 for (qsizetype i = 0; i < d->m_titleList.size(); ++i) {
303 const QNdefNfcTextRecord &text = d->m_titleList[i];
304
305 if (locale.isEmpty() || text.locale() == locale)
306 return text.text();
307 }
308
309 return QString();
310}
311
312/*!
313 Returns a copy of all title records inside the smart poster.
314 */
315QList<QNdefNfcTextRecord> QNdefNfcSmartPosterRecord::titleRecords() const
316{
317 return d->m_titleList;
318}
319
320/*!
321 Attempts to add a title record \a text to the smart poster. If the smart poster does not already
322 contain a title record with the same locale as title record \a text, then the title record is added
323 and the function returns \c true. Otherwise \c false is returned.
324 */
325bool QNdefNfcSmartPosterRecord::addTitle(const QNdefNfcTextRecord &text)
326{
327 const bool status = addTitleInternal(text);
328
329 // Convert to payload if the title is added
330 if (status)
331 convertToPayload();
332
333 return status;
334}
335
336bool QNdefNfcSmartPosterRecord::addTitleInternal(const QNdefNfcTextRecord &text)
337{
338 for (qsizetype i = 0; i < d->m_titleList.size(); ++i) {
339 const QNdefNfcTextRecord &rec = d->m_titleList[i];
340
341 if (rec.locale() == text.locale())
342 return false;
343 }
344
345 d->m_titleList.append(text);
346 return true;
347}
348
349/*!
350 Attempts to add a new title record with title \a text, locale \a locale and encoding \a encoding.
351 If the smart poster does not already contain a title record with locale \a locale, then the title record
352 is added and the function returns \c true. Otherwise \c false is returned.
353 */
354bool QNdefNfcSmartPosterRecord::addTitle(const QString &text, const QString &locale, QNdefNfcTextRecord::Encoding encoding)
355{
356 QNdefNfcTextRecord rec;
357 rec.setText(text);
358 rec.setLocale(locale);
359 rec.setEncoding(encoding);
360
361 return addTitle(rec);
362}
363
364/*!
365 Attempts to remove the title record \a text from the smart poster. Removes
366 the record and returns \c true if the smart poster contains a matching
367 record, otherwise \c false is returned.
368 */
369bool QNdefNfcSmartPosterRecord::removeTitle(const QNdefNfcTextRecord &text)
370{
371 bool status = false;
372
373 for (qsizetype i = 0; i < d->m_titleList.size(); ++i) {
374 const QNdefNfcTextRecord &rec = d->m_titleList[i];
375
376 if (rec.text() == text.text() && rec.locale() == text.locale() && rec.encoding() == text.encoding()) {
377 d->m_titleList.removeAt(i);
378 status = true;
379 break;
380 }
381 }
382
383 // Convert to payload if the title list has changed
384 if (status)
385 convertToPayload();
386
387 return status;
388}
389
390/*!
391 Attempts to remove a title record with the locale \a locale from the smart
392 poster. Removes the record and returns \c true if the smart poster contains
393 a matching record, otherwise \c false is returned.
394 */
395bool QNdefNfcSmartPosterRecord::removeTitle(const QString &locale)
396{
397 bool status = false;
398
399 for (qsizetype i = 0; i < d->m_titleList.size(); ++i) {
400 const QNdefNfcTextRecord &rec = d->m_titleList[i];
401
402 if (rec.locale() == locale) {
403 d->m_titleList.removeAt(i);
404 status = true;
405 break;
406 }
407 }
408
409 // Convert to payload if the title list has changed
410 if (status)
411 convertToPayload();
412
413 return status;
414}
415
416/*!
417 Adds the title record list \a titles to the smart poster. Any existing records are overwritten.
418 */
419void QNdefNfcSmartPosterRecord::setTitles(const QList<QNdefNfcTextRecord> &titles)
420{
421 d->m_titleList = titles;
422
423 // Convert to payload
424 convertToPayload();
425}
426
427/*!
428 Returns the URI from the smart poster's URI record if set. Otherwise an empty URI is returned.
429 */
430QUrl QNdefNfcSmartPosterRecord::uri() const
431{
432 if (d->m_uri)
433 return d->m_uri->uri();
434
435 return QUrl();
436}
437
438/*!
439 Returns the smart poster's URI record if set. Otherwise an empty URI is returned.
440 */
441QNdefNfcUriRecord QNdefNfcSmartPosterRecord::uriRecord() const
442{
443 if (d->m_uri)
444 return *(d->m_uri);
445
446 return QNdefNfcUriRecord();
447}
448
449/*!
450 Sets the URI record to \a url
451 */
452void QNdefNfcSmartPosterRecord::setUri(const QNdefNfcUriRecord &url)
453{
454 if (d->m_uri)
455 delete d->m_uri;
456
457 d->m_uri = new QNdefNfcUriRecord(url);
458
459 // Convert to payload
460 convertToPayload();
461}
462
463/*!
464 Constructs a URI record and sets its content inside the smart poster to \a url
465 */
466void QNdefNfcSmartPosterRecord::setUri(const QUrl &url)
467{
468 QNdefNfcUriRecord rec;
469 rec.setUri(url);
470
471 setUri(rec);
472}
473
474/*!
475 Returns the action from the action record if available. Otherwise \l UnspecifiedAction is returned.
476 */
477QNdefNfcSmartPosterRecord::Action QNdefNfcSmartPosterRecord::action() const
478{
479 if (d->m_action)
480 return d->m_action->action();
481
482 return UnspecifiedAction;
483}
484
485/*!
486 Sets the action record to \a act
487 */
488void QNdefNfcSmartPosterRecord::setAction(Action act)
489{
490 if (!d->m_action)
491 d->m_action = new QNdefNfcActRecord();
492
493 d->m_action->setAction(act);
494
495 // Convert to payload
496 convertToPayload();
497}
498
499/*!
500 Returns the number of icon records contained inside the smart poster.
501 */
502qsizetype QNdefNfcSmartPosterRecord::iconCount() const
503{
504 return d->m_iconList.size();
505}
506
507/*!
508 Returns the icon record corresponding to the index \a index inside the smart
509 poster, where \a index is a value between 0 and \l iconCount() - 1.
510 Values outside of this range return an empty record.
511 */
512QNdefNfcIconRecord QNdefNfcSmartPosterRecord::iconRecord(qsizetype index) const
513{
514 if (index >= 0 && index < d->m_iconList.size())
515 return d->m_iconList[index];
516
517 return QNdefNfcIconRecord();
518}
519
520/*!
521 Returns the associated icon record data if the smart poster contains an icon record with MIME type \a mimetype.
522 If \a mimetype is omitted or empty then the first icon's record data is returned. In all other cases, an empty array is returned.
523 */
524QByteArray QNdefNfcSmartPosterRecord::icon(const QByteArray& mimetype) const
525{
526 for (qsizetype i = 0; i < d->m_iconList.size(); ++i) {
527 const QNdefNfcIconRecord &icon = d->m_iconList[i];
528
529 if (mimetype.isEmpty() || icon.type() == mimetype)
530 return icon.data();
531 }
532
533 return QByteArray();
534}
535
536/*!
537 Returns a copy of all icon records inside the smart poster.
538 */
539QList<QNdefNfcIconRecord> QNdefNfcSmartPosterRecord::iconRecords() const
540{
541 return d->m_iconList;
542}
543
544/*!
545 Adds an icon record \a icon to the smart poster. If the smart poster already contains an icon
546 record with the same type then the existing icon record is replaced.
547 */
548void QNdefNfcSmartPosterRecord::addIcon(const QNdefNfcIconRecord &icon)
549{
550 addIconInternal(icon);
551
552 // Convert to payload
553 convertToPayload();
554}
555
556void QNdefNfcSmartPosterRecord::addIconInternal(const QNdefNfcIconRecord &icon)
557{
558 for (qsizetype i = 0; i < d->m_iconList.size(); ++i) {
559 const QNdefNfcIconRecord &rec = d->m_iconList[i];
560
561 if (rec.type() == icon.type())
562 d->m_iconList.removeAt(i);
563 }
564
565 d->m_iconList.append(icon);
566}
567
568/*!
569 Adds an icon record with type \a type and data \a data to the smart poster. If the smart poster
570 already contains an icon record with the same type then the existing icon record is replaced.
571 */
572void QNdefNfcSmartPosterRecord::addIcon(const QByteArray &type, const QByteArray &data)
573{
574 QNdefNfcIconRecord rec;
575 rec.setType(type);
576 rec.setData(data);
577
578 addIcon(rec);
579}
580
581/*!
582 Attempts to remove the icon record \a icon from the smart poster.
583 Removes the record and returns \c true if the smart poster contains
584 a matching record, otherwise \c false is returned.
585 */
586bool QNdefNfcSmartPosterRecord::removeIcon(const QNdefNfcIconRecord &icon)
587{
588 bool status = false;
589
590 for (qsizetype i = 0; i < d->m_iconList.size(); ++i) {
591 const QNdefNfcIconRecord &rec = d->m_iconList[i];
592
593 if (rec.type() == icon.type() && rec.data() == icon.data()) {
594 d->m_iconList.removeAt(i);
595 status = true;
596 break;
597 }
598 }
599
600 // Convert to payload if the icon list has changed
601 if (status)
602 convertToPayload();
603
604 return status;
605}
606
607/*!
608 Attempts to remove the icon record with the type \a type from the smart
609 poster. Removes the record and returns \c true if the smart poster contains
610 a matching record, otherwise \c false is returned.
611 */
612bool QNdefNfcSmartPosterRecord::removeIcon(const QByteArray &type)
613{
614 bool status = false;
615
616 for (qsizetype i = 0; i < d->m_iconList.size(); ++i) {
617 const QNdefNfcIconRecord &rec = d->m_iconList[i];
618
619 if (rec.type() == type) {
620 d->m_iconList.removeAt(i);
621 status = true;
622 break;
623 }
624 }
625
626 // Convert to payload if the icon list has changed
627 if (status)
628 convertToPayload();
629
630 return status;
631}
632
633/*!
634 Adds the icon record list \a icons to the smart poster.
635 Any existing records are overwritten.
636
637 \sa hasIcon(), icon()
638 */
639void QNdefNfcSmartPosterRecord::setIcons(const QList<QNdefNfcIconRecord> &icons)
640{
641 d->m_iconList = icons;
642
643 // Convert to payload
644 convertToPayload();
645}
646
647/*!
648 Returns the size from the size record if available; otherwise returns 0.
649
650 The value is optional and contains the size in bytes of the object
651 that the URI refers to. It may be used by the device to determine
652 whether it can accommodate the object.
653
654 \sa setSize()
655 */
656quint32 QNdefNfcSmartPosterRecord::size() const
657{
658 if (d->m_size)
659 return d->m_size->size();
660
661 return 0;
662}
663
664/*!
665 Sets the record \a size. The value contains the size in bytes of
666 the object that the URI refers to.
667
668 \sa size(), hasSize()
669 */
670void QNdefNfcSmartPosterRecord::setSize(quint32 size)
671{
672 if (!d->m_size)
673 d->m_size = new QNdefNfcSizeRecord();
674
675 d->m_size->setSize(size);
676
677 // Convert to payload
678 convertToPayload();
679}
680
681/*!
682 Returns the MIME type that describes the type of the objects that can be
683 reached via uri().
684
685 If the type is not known, the returned QString is empty.
686
687 \sa setTypeInfo(), hasTypeInfo()
688 */
689QString QNdefNfcSmartPosterRecord::typeInfo() const
690{
691 if (d->m_type)
692 return d->m_type->typeInfo();
693
694 return QString();
695}
696
697/*!
698 Sets the type record to \a type. \a type describes the type of the object
699 referenced by uri().
700
701 \sa typeInfo()
702 */
703void QNdefNfcSmartPosterRecord::setTypeInfo(const QString &type)
704{
705 if (d->m_type)
706 delete d->m_type;
707
708 d->m_type = new QNdefNfcTypeRecord();
709 d->m_type->setTypeInfo(type);
710
711 // Convert to payload
712 convertToPayload();
713}
714
715void QNdefNfcActRecord::setAction(QNdefNfcSmartPosterRecord::Action action)
716{
717 QByteArray data(1, action);
718
719 setPayload(data);
720}
721
722QNdefNfcSmartPosterRecord::Action QNdefNfcActRecord::action() const
723{
724 const QByteArray p = payload();
725 QNdefNfcSmartPosterRecord::Action value =
726 QNdefNfcSmartPosterRecord::UnspecifiedAction;
727
728 if (!p.isEmpty())
729 value = QNdefNfcSmartPosterRecord::Action(static_cast<signed char>(p[0]));
730
731 return value;
732}
733
734/*!
735 Sets the contents of the icon record to \a data.
736*/
737void QNdefNfcIconRecord::setData(const QByteArray &data)
738{
739 setPayload(data);
740}
741
742/*!
743 Returns the icon data as \l QByteArray.
744*/
745QByteArray QNdefNfcIconRecord::data() const
746{
747 return payload();
748}
749
750void QNdefNfcSizeRecord::setSize(quint32 size)
751{
752 QByteArray data(4, 0);
753
754 data[0] = (int) ((size & 0xFF000000) >> 24);
755 data[1] = (int) ((size & 0x00FF0000) >> 16);
756 data[2] = (int) ((size & 0x0000FF00) >> 8);
757 data[3] = (int) ((size & 0x000000FF));
758
759 setPayload(data);
760}
761
762quint32 QNdefNfcSizeRecord::size() const
763{
764 const QByteArray p = payload();
765
766 if (p.isEmpty())
767 return 0;
768
769 return ((p[0] << 24) & 0xFF000000) + ((p[1] << 16) & 0x00FF0000)
770 + ((p[2] << 8) & 0x0000FF00) + (p[3] & 0x000000FF);
771}
772
773void QNdefNfcTypeRecord::setTypeInfo(const QString &type)
774{
775 setPayload(type.toUtf8());
776}
777
778QString QNdefNfcTypeRecord::typeInfo() const
779{
780 return QString::fromUtf8(payload());
781}
782
783QT_END_NAMESPACE