File indexing completed on 2024-05-12 16:59:03

0001 /*
0002     SPDX-FileCopyrightText: 2019 Harald Sitter <sitter@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "product.h"
0008 
0009 #include <QMetaMethod>
0010 #include <QMetaType>
0011 
0012 namespace Bugzilla
0013 {
0014 Product::Product(const QVariantHash &object, const Connection &connection, QObject *parent)
0015     : QObject(parent)
0016     , m_connection(connection)
0017 {
0018     registerVariantConverters();
0019 
0020     for (auto it = object.constBegin(); it != object.constEnd(); ++it) {
0021         setProperty(qPrintable(it.key()), it.value());
0022     }
0023 }
0024 
0025 QList<ProductVersion *> Product::versions() const
0026 {
0027     return m_versions;
0028 }
0029 
0030 QList<ProductComponent *> Product::components() const
0031 {
0032     return m_components;
0033 }
0034 
0035 Product::~Product()
0036 {
0037     qDeleteAll(m_components);
0038     qDeleteAll(m_versions);
0039 }
0040 
0041 bool Product::isActive() const
0042 {
0043     return m_active;
0044 }
0045 
0046 QStringList Product::componentNames() const
0047 {
0048     QStringList ret;
0049     for (const auto *component : m_components) {
0050         ret << component->name();
0051     }
0052     return ret;
0053 }
0054 
0055 QStringList Product::allVersions() const
0056 {
0057     QStringList ret;
0058     for (const auto *version : m_versions) {
0059         ret << version->name();
0060     }
0061     return ret;
0062 }
0063 
0064 QStringList Product::inactiveVersions() const
0065 {
0066     QStringList ret;
0067     for (const auto *version : m_versions) {
0068         if (!version->isActive()) {
0069             ret << version->name();
0070         }
0071     }
0072     return ret;
0073 }
0074 
0075 void Product::registerVariantConverters()
0076 {
0077     // The way List QVariant get converted to QList<T> is a bit meh.
0078     // A List variant by default only can convert to a QStringList, regardless
0079     // of the T itself being a metatype known to QVariant. i.e. the QVariant
0080     // may know how to iterate a QList, and it may know how to convert T, but
0081     // it doesn't know how to put the two together into a list conversion.
0082     // This is true for all Ts. You can have a QList<int>, QVariant::fromValue
0083     // that into a QVariant{QVariantList} but that variant will no longer
0084     // convert<QList<int>>.
0085     // To bridge the conversion gap we need to register custom converters which
0086     // iterate the variant list and turn it into the relevant type.
0087 
0088     static bool convertersRegistered = false;
0089     if (convertersRegistered) {
0090         return;
0091     }
0092     convertersRegistered = true;
0093 
0094     QMetaType::registerConverter<QVariantList, QList<ProductComponent *>>([](QVariantList v) -> QList<ProductComponent *> {
0095         QList<ProductComponent *> list;
0096         list.reserve(v.size());
0097         for (const QVariant &variant : qAsConst(v)) {
0098             list.append(new ProductComponent(variant.toHash()));
0099         }
0100         return list;
0101     });
0102 
0103     QMetaType::registerConverter<QVariantList, QList<ProductVersion *>>([](QVariantList v) -> QList<ProductVersion *> {
0104         QList<ProductVersion *> list;
0105         list.reserve(v.size());
0106         for (const QVariant &variant : qAsConst(v)) {
0107             list.append(new ProductVersion(variant.toHash()));
0108         }
0109         return list;
0110     });
0111 }
0112 
0113 ProductVersion::ProductVersion(const QVariantHash &object, QObject *parent)
0114     : QObject(parent)
0115 {
0116     for (auto it = object.constBegin(); it != object.constEnd(); ++it) {
0117         setProperty(qPrintable(it.key()), it.value());
0118     }
0119 }
0120 
0121 ProductComponent::ProductComponent(const QVariantHash &object, QObject *parent)
0122     : QObject(parent)
0123 {
0124     for (auto it = object.constBegin(); it != object.constEnd(); ++it) {
0125         setProperty(qPrintable(it.key()), it.value());
0126     }
0127 }
0128 
0129 } // namespace Bugzilla