8#include <QDBusArgument>
30 int qMetaTypeId_CVariantList = -1;
32 private_ns::IValueObjectMetaInfo *private_ns::getValueObjectMetaInfo(QMetaType mt)
34 return getValueObjectMetaInfo(QVariant(mt,
nullptr));
37 private_ns::IValueObjectMetaInfo *private_ns::getValueObjectMetaInfo(
const QVariant &v)
39 return v.
value<IValueObjectMetaInfo *>();
44 const QMetaType mt(typeId);
45 if (m_v.canConvert(mt))
49 if (typeId == qMetaTypeId_CVariantList)
51 return m_v.canConvert<QVector<CVariant>>() || m_v.canConvert<QVariantList>();
53 if (
userType() == qMetaTypeId_CVariantList)
56 QVariant(QMetaType(typeId),
nullptr).canConvert<QVariantList>();
63 const QMetaType mt(typeId);
64 if (!m_v.canConvert(mt))
70 if (typeId == qMetaTypeId_CVariantList)
72 if (m_v.canConvert<QVector<CVariant>>())
74 if (!m_v.convert(QMetaType(qMetaTypeId<QVector<CVariant>>())))
79 else if (m_v.canConvert<QVariantList>())
81 QVector<CVariant> vec;
82 const auto seqit = m_v.value<QMetaSequence::Iterable>();
84 for (
auto it = seqit.begin(); it != seqit.end(); ++it)
95 if (
userType() == qMetaTypeId_CVariantList)
99 if (!m_v.convert(QMetaType(qMetaTypeId<QVector<CVariant>>())))
110 return m_v.convert(mt);
113 bool CVariant::isVariantList()
const {
return userType() == qMetaTypeId_CVariantList; }
117 auto *meta = getValueObjectMetaInfo();
120 return meta->toQString(data(), i18n);
122 return m_v.toString();
141 default:
return false;
156 return this->
toInt(ok);
161 if (a.userType() < b.userType())
165 if (a.userType() > b.userType())
169 auto *aMeta = a.getValueObjectMetaInfo();
170 auto *bMeta = b.getValueObjectMetaInfo();
175 const void *casted =
nullptr;
176 if (casted = aMeta->upCastTo(a.data(), bMeta->getMetaTypeId()); casted)
178 return bMeta->compareImpl(casted, b.data());
180 if (casted = bMeta->upCastTo(b.data(), aMeta->getMetaTypeId()); casted)
182 return aMeta->compareImpl(a.data(), casted);
184 CLogMessage(&a).warning(
185 u
"Comparing two CVariants containing unrelated value objects: %1 (%2) and %3 (%4)")
186 << a.typeName() << a.userType() << b.typeName() << b.userType();
189 catch (
const private_ns::CVariantException &ex)
191 CLogMessage(&a).debug() << ex.what();
196 if (order == QPartialOrdering::Less)
200 if (order == QPartialOrdering::Greater)
212 switch (m_v.metaType().id())
231 auto *meta = getValueObjectMetaInfo();
234 json.
insert(
"value", meta->toJson(data()));
236 else if (m_v.canConvert<QString>())
238 json.
insert(
"value", m_v.toString());
242 CLogMessage(
this).warning(u
"Unsupported CVariant type for toJson: %1 (%2)")
246 catch (
const private_ns::CVariantException &ex)
248 CLogMessage(
this).debug() << ex.what();
256 QJsonDocument jsonDoc(
toJson());
257 return jsonDoc.toJson(format);
264 const QJsonValue typeValue = json.
value(
"type");
267 throw CJsonException(
"Missing 'type'");
279 if (
value.isUndefined())
281 throw CJsonException(
"Missing 'value'");
302 auto *meta = private_ns::getValueObjectMetaInfo(mt);
305 CJsonScope scope(
"value");
307 m_v = QVariant(mt,
nullptr);
310 meta->convertFromMemoizedJson(
value.toObject(), data(),
true);
314 m_v.setValue(
value.toString());
315 if (!m_v.convert(mt))
317 throw CJsonException(
"Failed to convert from JSON string");
322 throw CJsonException(
"Type not supported by convertFromJson");
325 catch (
const private_ns::CVariantException &ex)
327 throw CJsonException(ex.what());
333 const QString &prefix)
339 catch (
const CJsonException &ex)
348 auto *meta = getValueObjectMetaInfo();
355 json.
insert(
"value", meta->toMemoizedJson(data()));
358 catch (
const private_ns::CVariantException &ex)
360 CLogMessage(
this).debug() << ex.what();
372 QJsonValue typeValue = json.
value(
"type");
375 throw CJsonException(
"Missing 'type'");
385 auto *meta = private_ns::getValueObjectMetaInfo(mt);
391 if (
value.isUndefined())
393 throw CJsonException(
"Missing 'value'");
396 CJsonScope scope(
"value");
397 m_v = QVariant(mt,
nullptr);
398 meta->convertFromMemoizedJson(
value.toObject(), data(), allowFallbackToJson);
400 catch (
const private_ns::CVariantException &ex)
402 throw CJsonException(ex.what());
412 const QString &prefix)
418 catch (
const CJsonException &ex)
425 size_t CVariant::getValueHash()
const
427 switch (m_v.metaType().id())
442 auto *meta = getValueObjectMetaInfo();
445 return meta->getValueHash(data());
447 else if (m_v.canConvert<QString>())
449 return qHash(m_v.toString());
453 CLogMessage(
this).warning(u
"Unsupported CVariant type for getValueHash: %1 (%2)")
458 catch (
const private_ns::CVariantException &ex)
460 CLogMessage(
this).debug() << ex.what();
474 arg << QString() << QDBusVariant(QVariant(0));
483 QVariant fixQVariantFromDbusArgument(
const QVariant &variant, QMetaType localUserType,
const QString &typeName);
484 QVariant complexQtTypeFromDbusArgument(
const QDBusArgument &argument,
int type);
490 QDBusVariant dbusVar;
509 auto *meta = getValueObjectMetaInfo();
513 meta->setPropertyByIndex(data(), variant, index);
515 catch (
const private_ns::CVariantException &ex)
517 CLogMessage(
this).debug() << ex.what();
523 auto *meta = getValueObjectMetaInfo();
528 meta->propertyByIndex(data(), result, index);
531 catch (
const private_ns::CVariantException &ex)
533 CLogMessage(
this).debug() << ex.what();
540 auto *meta = getValueObjectMetaInfo();
544 return meta->equalsPropertyByIndex(data(), compareValue, index);
546 catch (
const private_ns::CVariantException &ex)
548 CLogMessage(
this).debug() << ex.what();
555 auto *meta = getValueObjectMetaInfo();
564 catch (
const private_ns::CVariantException &ex)
566 CLogMessage(
this).debug() << ex.what();
567 return CIcons::StandardIconError16;
575 return m_v.value<QPixmap>();
585 return CIcon(
toIcon()).toPixmap();
609 auto *meta = getValueObjectMetaInfo();
612 CLogMessage(
this).warning(u
"Invalid type for CVariant::matches: %1") <<
typeName();
617 return meta->matches(data(),
value);
619 catch (
const private_ns::CVariantException &ex)
621 CLogMessage(
this).debug() << ex.what();
626 QVariant fixQVariantFromDbusArgument(
const QVariant &variant, QMetaType localUserType,
const QString &typeName)
640 const auto arg = variant.
value<QDBusArgument>();
642 if (localUserType.
id() < userType)
645 return complexQtTypeFromDbusArgument(arg, localUserType.
id());
649 arg.beginStructure();
655 bool ok = valueVariant.
convert(localUserType);
656 Q_ASSERT_X(ok, Q_FUNC_INFO,
"int could not be converted to enum");
662 QVariant valueVariant(QMetaType(localUserType),
nullptr);
663 auto *meta = private_ns::getValueObjectMetaInfo(valueVariant);
666 meta->unmarshall(arg, valueVariant.
data());
669 Q_ASSERT_X(
false, Q_FUNC_INFO,
"no meta");
674 QVariant complexQtTypeFromDbusArgument(
const QDBusArgument &argument,
int type)
700 const char *name = QMetaType(type).name();
701 qFatal(
"Type cannot be resolved: %s (%d)", name ? name :
"", type);
IconIndex
Index for each icon, allows to send them via DBus, efficiently store them, etc.
A sequence of log categories.
Class for emitting a log message.
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
Non-owning reference to a CPropertyIndex with a subset of its features.
Streamable status message, e.g.
static CStatusMessage fromJsonException(const CJsonException &ex, const CLogCategoryList &categories, const QString &prefix)
Object from JSON exception message.
Wrapper around QVariant which provides transparent access to CValueObject methods of the contained ob...
friend size_t qHash(const CVariant &var)
qHash overload, needed for storing value in a QSet.
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
void marshallToDbus(QDBusArgument &argument) const
Marshall without begin/endStructure, for when composed within another object.
CStatusMessage convertFromMemoizedJsonNoThrow(const QJsonObject &json, const CLogCategoryList &categories, const QString &prefix)
Call convertFromMemoizedJson, catch any CJsonException that is thrown and return it as CStatusMessage...
T value() const
Return the value converted to the type T.
const char * typeName() const
Return the typename of the value in this variant.
bool isIntegral() const
True if this variant's type is an integral type.
QJsonObject toMemoizedJson() const
To compact JSON format.
CIcons::IconIndex toIcon() const
As icon, not implemented by all classes.
void unmarshalFromDataStream(QDataStream &stream)
Unmarshal a value from a QDataStream.
static void registerMetadata()
Register metadata.
qint64 toQInt64(bool *ok=nullptr) const
COnvert to qint64, which is used for all timestamps.
bool canConvert() const
True if this variant can be converted to the type T.
QString getClassName() const
Class name.
void convertFromMemoizedJson(const QJsonObject &json, bool allowFallbackToJson)
From compact JSON format.
void unmarshallFromDbus(const QDBusArgument &argument)
Unmarshall without begin/endStructure, for when composed within another object.
CVariant()=default
Default constructor.
bool convert(int typeId)
Convert this variant to the type with the given metatype ID and return true if successful.
int userType() const
Return the metatype ID of the value in this variant.
bool isValid() const
True if this variant is valid.
void convertFromJson(const QJsonObject &json)
Assign from JSON object.
QVariant propertyByIndex(swift::misc::CPropertyIndexRef index) const
Property by index.
bool equalsPropertyByIndex(const CVariant &compareValue, CPropertyIndexRef index) const
Is given variant equal to value of property index?
const QVariant & getQVariant() const
Return the internal QVariant.
bool isArithmetic() const
True if this variant's type is an integral or floating-point type.
bool matches(const CVariant &event) const
If this is an event subscription, return true if it matches the given event.
QMetaType::Type type() const
Return the metatype ID of the value in this variant, or QMetaType::User if it is a user type.
qlonglong toLongLong(bool *ok=nullptr) const
Convert this variant to a longlong integer.
void marshalToDataStream(QDataStream &stream) const
Marshal a value to a QDataStream.
QString convertToQString(bool i18n=false) const
Cast as QString.
CStatusMessage convertFromJsonNoThrow(const QJsonObject &json, const CLogCategoryList &categories, const QString &prefix)
Call convertFromJson, catch any CJsonException that is thrown and return it as CStatusMessage.
int toInt(bool *ok=nullptr) const
Convert this variant to an integer.
QPixmap toPixmap() const
Corresponding pixmap.
int getMetaTypeId() const
Returns the Qt meta type ID of this object.
bool isA(int metaTypeId) const
Returns true if this object is an instance of the class with the given meta type ID,...
QJsonObject toJson() const
Cast to JSON object.
QString toJsonString(QJsonDocument::JsonFormat format=QJsonDocument::Indented) const
Convenience function JSON as string.
Free functions in swift::misc.
SWIFT_MISC_EXPORT QPixmap iconToPixmap(const QIcon &icon)
Icon to pixmap.
SWIFT_MISC_EXPORT QDateTime fromStringUtc(const QString &dateTimeString, const QString &format)
Same as QDateTime::fromString but QDateTime will be set to UTC.
QDate fromString(QStringView string, QStringView format, QCalendar cal)
QVariant variant() const const
QJsonArray fromStringList(const QStringList &list)
QJsonObject::iterator insert(QLatin1StringView key, const QJsonValue &value)
QJsonValue value(QLatin1StringView key) const const
bool isUndefined() const const
QString toString() const const
void push_back(QList< T >::parameter_type value)
void reserve(qsizetype size)
QPixmap fromImage(QImage &&image, Qt::ImageConversionFlags flags)
QTime fromString(QStringView string, QStringView format)
bool canConvert() const const
QPartialOrdering compare(const QVariant &lhs, const QVariant &rhs)
bool convert(QMetaType targetType)
QVariant fromValue(T &&value)