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