diff options
author | Jani Korteniemi <jani.korteniemi@qt.io> | 2021-07-26 13:42:14 +0300 |
---|---|---|
committer | Jani Korteniemi <jani.korteniemi@qt.io> | 2021-11-10 13:46:03 +0200 |
commit | 2eff5e431435f2b5be3511823400080d4029a6c1 (patch) | |
tree | 7d4647e00bdb463bc4bb29b85b445745bc18c0f3 /examples/demos/hangman/purchasing/qmltypes | |
parent | 28dd0b133435e044224c3141265e14f2a2586efc (diff) |
Add QtPurchasing module as an example under Qt demos
QtPurchasing module is deprecated in Qt6. However, the purchasing
code is moved as example/demo under qtdoc to demonstrate the use of
in-app purchases in Android/iOS.
The demo is under demos\hangman.
Few fixes done to the original code:
* Ported the code to Qt 6.
* Removed reinterpret_casts and QQmlListPropertys.
* Fixed few QML warnings.
* Added documentation
* Fixed documentation
* Added CMake port
* Fixed Cmake for iOS
* Modified Fonts in qml file
* project name changed from qthangmanpurchasing to hangman
Task-number: QTBUG-84776
Pick-to: 6.2
Change-Id: I86051b29d54cfb4a48b310ebc8d538c806fbf8da
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Nicholas Bennett <nicholas.bennett@qt.io>
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
Diffstat (limited to 'examples/demos/hangman/purchasing/qmltypes')
4 files changed, 557 insertions, 0 deletions
diff --git a/examples/demos/hangman/purchasing/qmltypes/inappproductqmltype.cpp b/examples/demos/hangman/purchasing/qmltypes/inappproductqmltype.cpp new file mode 100644 index 000000000..e0b13fe73 --- /dev/null +++ b/examples/demos/hangman/purchasing/qmltypes/inappproductqmltype.cpp @@ -0,0 +1,260 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qcoreevent.h> + +#include "inappproductqmltype.h" +#include "inappstoreqmltype.h" +#include "../inapp/inapptransaction.h" +#include "../inapp/inappstore.h" + +InAppProductQmlType::InAppProductQmlType(QObject *parent) + : QObject(parent) + , m_status(Uninitialized) + , m_type(InAppProductQmlType::ProductType(-1)) + , m_componentComplete(false) + , m_store(0) + , m_product(0) +{ +} + +void InAppProductQmlType::setStore(InAppStoreQmlType *store) +{ + if (m_store == store) + return; + + if (m_store != 0) + m_store->store()->disconnect(this); + + m_store = store; + connect(m_store->store(), &InAppStore::productRegistered, + this, &InAppProductQmlType::handleProductRegistered); + connect(m_store->store(), &InAppStore::productUnknown, + this, &InAppProductQmlType::handleProductUnknown); + connect(m_store->store(), &InAppStore::transactionReady, + this, &InAppProductQmlType::handleTransaction); + + updateProduct(); + + emit storeChanged(); +} + +InAppStoreQmlType *InAppProductQmlType::store() const +{ + return m_store; +} + +void InAppProductQmlType::componentComplete() +{ + if (!m_componentComplete) { + m_componentComplete = true; + updateProduct(); + } +} + +void InAppProductQmlType::setIdentifier(const QString &identifier) +{ + if (m_identifier == identifier) + return; + + if (m_status != Uninitialized) { + qWarning("A product's identifier cannot be changed once the product has been initialized."); + return; + } + + m_identifier = identifier; + if (m_componentComplete) + updateProduct(); + emit identifierChanged(); +} + +void InAppProductQmlType::updateProduct() +{ + if (m_store == 0) + return; + + Status oldStatus = m_status; + InAppProduct *product = 0; + if (m_identifier.isEmpty() || m_type == InAppProductQmlType::ProductType(-1)) { + m_status = Uninitialized; + } else { + product = m_store->store()->registeredProduct(m_identifier); + if (product != 0 && product == m_product) + return; + + if (product == 0) { + m_status = PendingRegistration; + m_store->store()->registerProduct(InAppProduct::ProductType(m_type), m_identifier); + } else if (product->productType() != InAppProduct::ProductType(m_type)) { + qWarning("Product registered multiple times with different product types."); + product = 0; + m_status = Uninitialized; + } else { + m_status = Registered; + } + } + + setProduct(product); + if (oldStatus != m_status) + emit statusChanged(); +} + +void InAppProductQmlType::resetStatus() +{ + updateProduct(); +} + +QString InAppProductQmlType::identifier() const +{ + return m_identifier; +} + +void InAppProductQmlType::setType(InAppProductQmlType::ProductType type) +{ + if (m_type == type) + return; + + if (m_status != Uninitialized) { + qWarning("A product's type cannot be changed once the product has been initialized."); + return; + } + + m_type = type; + if (m_componentComplete) + updateProduct(); + + emit typeChanged(); +} + +InAppProductQmlType::ProductType InAppProductQmlType::type() const +{ + return m_type; +} + +InAppProductQmlType::Status InAppProductQmlType::status() const +{ + return m_status; +} + +QString InAppProductQmlType::price() const +{ + return m_product != 0 ? m_product->price() : QString(); +} + +QString InAppProductQmlType::title() const +{ + return m_product != 0 ? m_product->title() : QString(); +} + +QString InAppProductQmlType::description() const +{ + return m_product != 0 ? m_product->description() : QString(); +} + +void InAppProductQmlType::setProduct(InAppProduct *product) +{ + if (m_product == product) + return; + + QString oldPrice = price(); + QString oldTitle = title(); + QString oldDescription = description(); + m_product = product; + if (price() != oldPrice) + emit priceChanged(); + if (title() != oldTitle) + emit titleChanged(); + if (description() != oldDescription) + emit descriptionChanged(); +} + +void InAppProductQmlType::handleProductRegistered(InAppProduct *product) +{ + if (product->identifier() == m_identifier) { + Q_ASSERT(product->productType() == InAppProduct::ProductType(m_type)); + setProduct(product); + if (m_status != Registered) { + m_status = Registered; + emit statusChanged(); + } + } +} + +void InAppProductQmlType::handleProductUnknown(InAppProduct::ProductType, const QString &identifier) +{ + if (identifier == m_identifier) { + setProduct(0); + if (m_status != Unknown) { + m_status = Unknown; + emit statusChanged(); + } + } +} + +void InAppProductQmlType::handleTransaction(InAppTransaction *transaction) +{ + if (transaction->product()->identifier() != m_identifier) + return; + + if (transaction->status() == InAppTransaction::PurchaseApproved) + emit purchaseSucceeded(transaction); + else if (transaction->status() == InAppTransaction::PurchaseRestored) + emit purchaseRestored(transaction); + else{ + emit purchaseFailed(transaction);} +} + +void InAppProductQmlType::purchase() +{ + if (m_product != 0 && m_status == Registered) + m_product->purchase(); + else + qWarning("Attempted to purchase unregistered product"); +} diff --git a/examples/demos/hangman/purchasing/qmltypes/inappproductqmltype.h b/examples/demos/hangman/purchasing/qmltypes/inappproductqmltype.h new file mode 100644 index 000000000..9abcfe1ad --- /dev/null +++ b/examples/demos/hangman/purchasing/qmltypes/inappproductqmltype.h @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INAPPPRODUCTQMLTYPE_H +#define INAPPPRODUCTQMLTYPE_H + +#include <QtQml/qqmlparserstatus.h> +#include <QObject> +#include <QtQml/qqml.h> + +#include "inappstoreqmltype.h" +#include "../inapp/inappproduct.h" +#include "../inapp/inapptransaction.h" + +class InAppTransaction; +class InAppStoreQmlType; +class InAppProductQmlType : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + Q_PROPERTY(QString identifier READ identifier WRITE setIdentifier NOTIFY identifierChanged) + Q_PROPERTY(ProductType type READ type WRITE setType NOTIFY typeChanged) + Q_PROPERTY(QString price READ price NOTIFY priceChanged) + Q_PROPERTY(QString title READ title NOTIFY titleChanged) + Q_PROPERTY(QString description READ description NOTIFY descriptionChanged) + Q_PROPERTY(Status status READ status NOTIFY statusChanged) + Q_PROPERTY(InAppStoreQmlType *store READ store WRITE setStore NOTIFY storeChanged) + QML_NAMED_ELEMENT(Product) + +public: + enum Status { + Uninitialized, + PendingRegistration, + Registered, + Unknown + }; + Q_ENUM(Status); + + // Must match InAppProduct::ProductType + enum ProductType { + Consumable, + Unlockable + }; + Q_ENUM(ProductType); + + explicit InAppProductQmlType(QObject *parent = 0); + + Q_INVOKABLE void purchase(); + Q_INVOKABLE void resetStatus(); + + void setIdentifier(const QString &identifier); + QString identifier() const; + + Status status() const; + QString price() const; + QString title() const; + QString description() const; + + void setStore(InAppStoreQmlType *store); + InAppStoreQmlType *store() const; + + void setType(ProductType type); + ProductType type() const; + +Q_SIGNALS: + void purchaseSucceeded(InAppTransaction *transaction); + void purchaseFailed(InAppTransaction *transaction); + void purchaseRestored(InAppTransaction *transaction); + void identifierChanged(); + void statusChanged(); + void priceChanged(); + void titleChanged(); + void descriptionChanged(); + void storeChanged(); + void typeChanged(); + +protected: + void componentComplete(); + void classBegin() {} + +private Q_SLOTS: + void handleTransaction(InAppTransaction *transaction); + void handleProductRegistered(InAppProduct *product); + void handleProductUnknown(InAppProduct::ProductType, const QString &identifier); + +private: + void setProduct(InAppProduct *product); + void updateProduct(); + + QString m_identifier; + Status m_status; + InAppProductQmlType::ProductType m_type; + bool m_componentComplete; + + InAppStoreQmlType *m_store; + InAppProduct *m_product; +}; + +#endif // INAPPPRODUCTQMLTYPE_H diff --git a/examples/demos/hangman/purchasing/qmltypes/inappstoreqmltype.cpp b/examples/demos/hangman/purchasing/qmltypes/inappstoreqmltype.cpp new file mode 100644 index 000000000..4625d9908 --- /dev/null +++ b/examples/demos/hangman/purchasing/qmltypes/inappstoreqmltype.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "inappstoreqmltype.h" +#include "../inapp/inappstore.h" + +InAppStoreQmlType::InAppStoreQmlType(QObject *parent) + : QObject(parent) + , m_store(new InAppStore(this)) +{ +} + +InAppStore *InAppStoreQmlType::store() const +{ + return m_store; +} + +void InAppStoreQmlType::restorePurchases() +{ + m_store->restorePurchases(); +} diff --git a/examples/demos/hangman/purchasing/qmltypes/inappstoreqmltype.h b/examples/demos/hangman/purchasing/qmltypes/inappstoreqmltype.h new file mode 100644 index 000000000..a0fa5e26c --- /dev/null +++ b/examples/demos/hangman/purchasing/qmltypes/inappstoreqmltype.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INAPPSTOREQMLTYPE_H +#define INAPPSTOREQMLTYPE_H + +#include <QList> +#include <QObject> +#include <QQmlListProperty> +#include <QtQml/qqml.h> + +#include "inappproductqmltype.h" +#include "../inapp/inappstore.h" + +class InAppStore; +class InAppProductQmlType; +class InAppStoreQmlType : public QObject +{ + Q_OBJECT + QML_NAMED_ELEMENT(Store) + +public: + explicit InAppStoreQmlType(QObject *parent = 0); + + InAppStore *store() const; + + Q_INVOKABLE void restorePurchases(); + +private: + InAppStore *m_store; + QList<InAppProductQmlType *> m_products; +}; + + + +#endif // INAPPSTOREQMLTYPE_H |