swift
variant.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include "misc/variant.h"
7 
8 #include <QDBusArgument>
9 #include <QDBusVariant>
10 #include <QDataStream>
11 #include <QDate>
12 #include <QFlags>
13 #include <QHash>
14 #include <QJsonArray>
15 #include <QJsonValue>
16 #include <QString>
17 #include <QTime>
18 #include <Qt>
19 #include <QtDebug>
20 
21 #include "misc/imageutils.h"
22 #include "misc/logmessage.h"
23 #include "misc/propertyindexref.h"
24 #include "misc/statusmessage.h"
25 #include "misc/stringutils.h"
26 
27 namespace swift::misc
28 {
30  int qMetaTypeId_CVariantList = -1; // referenced in variantlist.cpp
31 
32  private_ns::IValueObjectMetaInfo *private_ns::getValueObjectMetaInfo(int typeId)
33  {
34  return getValueObjectMetaInfo(QVariant(QMetaType(typeId), nullptr));
35  }
36 
37  private_ns::IValueObjectMetaInfo *private_ns::getValueObjectMetaInfo(const QVariant &v)
38  {
39  return v.value<IValueObjectMetaInfo *>();
40  }
41 
42  bool CVariant::canConvert(int typeId) const
43  {
44  if (m_v.canConvert(typeId)) { return true; }
45  if (typeId == qMetaTypeId_CVariantList)
46  {
47  return m_v.canConvert<QVector<CVariant>>() || m_v.canConvert<QVariantList>();
48  }
49  if (userType() == qMetaTypeId_CVariantList)
50  {
51  return QVariant::fromValue(QVector<CVariant>()).canConvert(typeId) ||
52  QVariant(QMetaType(typeId), nullptr).canConvert<QVariantList>();
53  }
54  return false;
55  }
56 
57  bool CVariant::convert(int typeId)
58  {
59  if (!m_v.canConvert(typeId))
60  {
61  if (!canConvert(typeId)) { return false; }
62  if (typeId == qMetaTypeId_CVariantList)
63  {
64  if (m_v.canConvert<QVector<CVariant>>())
65  {
66  if (!m_v.convert(qMetaTypeId<QVector<CVariant>>())) { return false; }
67  }
68  else if (m_v.canConvert<QVariantList>())
69  {
70  QVector<CVariant> vec;
71  const auto seqit = m_v.value<QSequentialIterable>();
72  vec.reserve(seqit.size());
73  for (auto it = seqit.begin(); it != seqit.end(); ++it) { vec.push_back(*it); }
74  m_v.setValue(vec);
75  }
76  else { return false; }
77  }
78  if (userType() == qMetaTypeId_CVariantList)
79  {
80  if (QVariant::fromValue(QVector<CVariant>()).canConvert(typeId))
81  {
82  if (!m_v.convert(qMetaTypeId<QVector<CVariant>>())) { return false; }
83  }
84  else { return false; }
85  }
86  }
87  return m_v.convert(typeId);
88  }
89 
90  bool CVariant::isVariantList() const { return userType() == qMetaTypeId_CVariantList; }
91 
92  QString CVariant::convertToQString(bool i18n) const
93  {
94  auto *meta = getValueObjectMetaInfo();
95  if (meta) { return meta->toQString(data(), i18n); }
96  return m_v.toString();
97  }
98 
99  bool CVariant::isIntegral() const
100  {
101  switch (type())
102  {
103  case QMetaType::Bool:
104  case QMetaType::Char:
105  case QMetaType::UChar:
106  case QMetaType::SChar:
107  case QMetaType::Short:
108  case QMetaType::UShort:
109  case QMetaType::Int:
110  case QMetaType::UInt:
111  case QMetaType::Long:
112  case QMetaType::ULong:
113  case QMetaType::LongLong:
114  case QMetaType::ULongLong: return true;
115  default: return false;
116  }
117  }
118 
119  bool CVariant::isArithmetic() const
120  {
121  return isIntegral() || type() == QMetaType::Float || type() == QMetaType::Double;
122  }
123 
124  qint64 CVariant::toQInt64(bool *ok) const
125  {
126  if (this->type() == QMetaType::LongLong) { return this->toLongLong(ok); }
127  return this->toInt(ok);
128  }
129 
130  int CVariant::compareImpl(const CVariant &a, const CVariant &b)
131  {
132  if (a.userType() < b.userType()) { return -1; }
133  if (a.userType() > b.userType()) { return 1; }
134  auto *aMeta = a.getValueObjectMetaInfo();
135  auto *bMeta = b.getValueObjectMetaInfo();
136  if (aMeta && bMeta)
137  {
138  try
139  {
140  const void *casted = nullptr;
141  if ((casted = aMeta->upCastTo(a.data(), bMeta->getMetaTypeId())))
142  {
143  return bMeta->compareImpl(casted, b.data());
144  }
145  else if ((casted = bMeta->upCastTo(b.data(), aMeta->getMetaTypeId())))
146  {
147  return aMeta->compareImpl(a.data(), casted);
148  }
149  else
150  {
151  CLogMessage(&a).warning(
152  u"Comparing two CVariants containing unrelated value objects: %1 (%2) and %3 (%4)")
153  << a.typeName() << a.userType() << b.typeName() << b.userType();
154  return 0;
155  }
156  }
157  catch (const private_ns::CVariantException &ex)
158  {
159  CLogMessage(&a).debug() << ex.what();
160  return 0;
161  }
162  }
163  const QPartialOrdering order = QVariant::compare(a.m_v, b.m_v);
164  if (order == QPartialOrdering::Less) { return -1; }
165  if (order == QPartialOrdering::Greater) { return 1; }
166  return 0; // for "Equivalent" and "Unordered"
167  }
168 
169  QJsonObject CVariant::toJson() const
170  {
171  QJsonObject json;
172  json.insert("type", this->typeName());
173 
174  switch (m_v.type())
175  {
176  case QVariant::Invalid: json.insert("value", 0); break;
177  case QVariant::Int: json.insert("value", m_v.toInt()); break;
178  case QVariant::UInt: json.insert("value", m_v.toInt()); break;
179  case QVariant::Bool: json.insert("value", m_v.toBool()); break;
180  case QVariant::Double: json.insert("value", m_v.toDouble()); break;
181  case QVariant::LongLong: json.insert("value", m_v.toLongLong()); break;
182  case QVariant::ULongLong: json.insert("value", m_v.toLongLong()); break;
183  case QVariant::String: json.insert("value", m_v.toString()); break;
184  case QVariant::Char: json.insert("value", m_v.toString()); break;
185  case QVariant::ByteArray: json.insert("value", m_v.toString()); break;
186  case QVariant::DateTime: json.insert("value", m_v.toDateTime().toString(Qt::ISODate)); break;
187  case QVariant::Date: json.insert("value", m_v.toDate().toString(Qt::ISODate)); break;
188  case QVariant::Time: json.insert("value", m_v.toTime().toString(Qt::ISODate)); break;
189  case QVariant::StringList: json.insert("value", QJsonArray::fromStringList(m_v.toStringList())); break;
190  default:
191  try
192  {
193  auto *meta = getValueObjectMetaInfo();
194  if (meta) { json.insert("value", meta->toJson(data())); }
195  else if (m_v.canConvert<QString>()) { json.insert("value", m_v.toString()); }
196  else
197  {
198  CLogMessage(this).warning(u"Unsupported CVariant type for toJson: %1 (%2)")
199  << typeName() << userType();
200  }
201  }
202  catch (const private_ns::CVariantException &ex)
203  {
204  CLogMessage(this).debug() << ex.what();
205  }
206  }
207  return json;
208  }
209 
210  QString CVariant::toJsonString(QJsonDocument::JsonFormat format) const
211  {
212  QJsonDocument jsonDoc(toJson());
213  return jsonDoc.toJson(format);
214  }
215 
216  void CVariant::convertFromJson(const QJsonObject &json)
217  {
218  // Remark: Names "type" and "value" are also used for drag and drop
219  // Changing the names here requires the change for drag and drop too
220  const QJsonValue typeValue = json.value("type");
221  if (typeValue.isUndefined()) { throw CJsonException("Missing 'type'"); }
222  const QString typeName = typeValue.toString();
223  if (typeName.isEmpty())
224  {
225  m_v.clear();
226  return;
227  }
228  const int typeId = QMetaType::type(qPrintable(typeName));
229 
230  const QJsonValue value = json.value("value");
231  if (value.isUndefined()) { throw CJsonException("Missing 'value'"); }
232  switch (typeId)
233  {
234  case QVariant::Invalid: throw CJsonException("Type not recognized by QMetaType");
235  case QVariant::Int: m_v.setValue(value.toInt()); break;
236  case QVariant::UInt: m_v.setValue<uint>(static_cast<uint>(value.toInt())); break;
237  case QVariant::Bool: m_v.setValue(value.toBool()); break;
238  case QVariant::Double: m_v.setValue(value.toDouble()); break;
239  case QVariant::LongLong: m_v.setValue(static_cast<qlonglong>(value.toDouble())); break;
240  case QVariant::ULongLong: m_v.setValue(static_cast<qulonglong>(value.toDouble())); break;
241  case QVariant::String: m_v.setValue(value.toString()); break;
242  case QVariant::Char: m_v.setValue(value.toString().size() > 0 ? value.toString().at(0) : '\0'); break;
243  case QVariant::ByteArray: m_v.setValue(value.toString().toLatin1()); break;
244  case QVariant::DateTime: m_v.setValue(fromStringUtc(value.toString(), Qt::ISODate)); break;
245  case QVariant::Date: m_v.setValue(QDate::fromString(value.toString(), Qt::ISODate)); break;
246  case QVariant::Time: m_v.setValue(QTime::fromString(value.toString(), Qt::ISODate)); break;
247  case QVariant::StringList: m_v.setValue(QVariant(value.toArray().toVariantList()).toStringList()); break;
248  default:
249  try
250  {
251  auto *meta = private_ns::getValueObjectMetaInfo(typeId);
252  if (meta)
253  {
254  CJsonScope scope("value"); // tracker
255  Q_UNUSED(scope);
256  m_v = QVariant(QMetaType(typeId), nullptr);
257 
258  // this will call convertFromJson if there is no MemoizedJson
259  meta->convertFromMemoizedJson(value.toObject(), data(), true);
260  }
261  else if (QMetaType::hasRegisteredConverterFunction(QMetaType(qMetaTypeId<QString>()),
262  QMetaType(typeId)))
263  {
264  m_v.setValue(value.toString());
265  if (!m_v.convert(typeId)) { throw CJsonException("Failed to convert from JSON string"); }
266  }
267  else { throw CJsonException("Type not supported by convertFromJson"); }
268  }
269  catch (const private_ns::CVariantException &ex)
270  {
271  throw CJsonException(ex.what());
272  }
273  }
274  }
275 
276  CStatusMessage CVariant::convertFromJsonNoThrow(const QJsonObject &json, const CLogCategoryList &categories,
277  const QString &prefix)
278  {
279  try
280  {
281  convertFromJson(json);
282  }
283  catch (const CJsonException &ex)
284  {
285  return CStatusMessage::fromJsonException(ex, categories, prefix);
286  }
287  return {};
288  }
289 
290  QJsonObject CVariant::toMemoizedJson() const
291  {
292  auto *meta = getValueObjectMetaInfo();
293  if (meta)
294  {
295  try
296  {
297  QJsonObject json;
298  json.insert("type", this->typeName());
299  json.insert("value", meta->toMemoizedJson(data()));
300  return json;
301  }
302  catch (const private_ns::CVariantException &ex)
303  {
304  CLogMessage(this).debug() << ex.what();
305  return {};
306  }
307  }
308  else { return toJson(); }
309  }
310 
311  void CVariant::convertFromMemoizedJson(const QJsonObject &json, bool allowFallbackToJson)
312  {
313  QJsonValue typeValue = json.value("type");
314  if (typeValue.isUndefined()) { throw CJsonException("Missing 'type'"); }
315  QString typeName = typeValue.toString();
316  if (typeName.isEmpty())
317  {
318  m_v.clear();
319  return;
320  }
321  int typeId = QMetaType::type(qPrintable(typeName));
322 
323  auto *meta = private_ns::getValueObjectMetaInfo(typeId);
324  if (meta)
325  {
326  try
327  {
328  QJsonValue value = json.value("value");
329  if (value.isUndefined()) { throw CJsonException("Missing 'value'"); }
330 
331  CJsonScope scope("value");
332  m_v = QVariant(QMetaType(typeId), nullptr);
333  meta->convertFromMemoizedJson(value.toObject(), data(), allowFallbackToJson);
334  }
335  catch (const private_ns::CVariantException &ex)
336  {
337  throw CJsonException(ex.what());
338  }
339  }
340  else { convertFromJson(json); }
341  }
342 
343  CStatusMessage CVariant::convertFromMemoizedJsonNoThrow(const QJsonObject &json, const CLogCategoryList &categories,
344  const QString &prefix)
345  {
346  try
347  {
348  convertFromMemoizedJson(json, false);
349  }
350  catch (const CJsonException &ex)
351  {
352  return CStatusMessage::fromJsonException(ex, categories, prefix);
353  }
354  return {};
355  }
356 
357  size_t CVariant::getValueHash() const
358  {
359  switch (m_v.type())
360  {
361  case QVariant::Invalid: return 0;
362  case QVariant::Int: return qHash(m_v.toInt());
363  case QVariant::UInt: return qHash(m_v.toUInt());
364  case QVariant::Bool: return qHash(m_v.toUInt());
365  case QVariant::Double: return qHash(m_v.toUInt());
366  case QVariant::LongLong: return qHash(m_v.toLongLong());
367  case QVariant::ULongLong: return qHash(m_v.toULongLong());
368  case QVariant::String: return qHash(m_v.toString());
369  case QVariant::Char: return qHash(m_v.toChar());
370  case QVariant::ByteArray: return qHash(m_v.toByteArray());
371  default:
372  try
373  {
374  auto *meta = getValueObjectMetaInfo();
375  if (meta) { return meta->getValueHash(data()); }
376  else if (m_v.canConvert<QString>()) { return qHash(m_v.toString()); }
377  else
378  {
379  CLogMessage(this).warning(u"Unsupported CVariant type for getValueHash: %1 (%2)")
380  << typeName() << userType();
381  return 0;
382  }
383  }
384  catch (const private_ns::CVariantException &ex)
385  {
386  CLogMessage(this).debug() << ex.what();
387  return 0;
388  }
389  }
390  }
391 
392  void CVariant::marshallToDbus(QDBusArgument &arg) const
393  {
394  if (isValid()) { arg << QString(typeName()) << QDBusVariant(getQVariant()); }
395  else { arg << QString() << QDBusVariant(QVariant(0)); }
396  }
397 
399 
403  QVariant fixQVariantFromDbusArgument(const QVariant &variant, int localUserType, const QString &typeName);
404  QVariant complexQtTypeFromDbusArgument(const QDBusArgument &argument, int type);
406 
407  void CVariant::unmarshallFromDbus(const QDBusArgument &arg)
408  {
409  QString typeName;
410  QDBusVariant dbusVar;
411  arg >> typeName >> dbusVar;
412 
413  if (typeName.isEmpty()) { *this = CVariant(); }
414  else
415  {
416  *this = fixQVariantFromDbusArgument(dbusVar.variant(), QMetaType::type(qPrintable(typeName)), typeName);
417  }
418  }
419 
420  void CVariant::marshalToDataStream(QDataStream &stream) const { stream << m_v; }
421 
422  void CVariant::unmarshalFromDataStream(QDataStream &stream) { stream >> m_v; }
423 
424  void CVariant::setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
425  {
426  auto *meta = getValueObjectMetaInfo();
427  Q_ASSERT(meta);
428  try
429  {
430  meta->setPropertyByIndex(data(), variant, index);
431  }
432  catch (const private_ns::CVariantException &ex)
433  {
434  CLogMessage(this).debug() << ex.what();
435  }
436  }
437 
439  {
440  auto *meta = getValueObjectMetaInfo();
441  Q_ASSERT(meta);
442  try
443  {
444  QVariant result;
445  meta->propertyByIndex(data(), result, index);
446  return result;
447  }
448  catch (const private_ns::CVariantException &ex)
449  {
450  CLogMessage(this).debug() << ex.what();
451  return {};
452  }
453  }
454 
455  bool CVariant::equalsPropertyByIndex(const CVariant &compareValue, CPropertyIndexRef index) const
456  {
457  auto *meta = getValueObjectMetaInfo();
458  Q_ASSERT(meta);
459  try
460  {
461  return meta->equalsPropertyByIndex(data(), compareValue, index);
462  }
463  catch (const private_ns::CVariantException &ex)
464  {
465  CLogMessage(this).debug() << ex.what();
466  return false;
467  }
468  }
469 
471  {
472  auto *meta = getValueObjectMetaInfo();
473  if (!meta) { return {}; }
474  try
475  {
476  return static_cast<CIcons::IconIndex>(meta->toIcon(data()));
477  }
478  catch (const private_ns::CVariantException &ex)
479  {
480  CLogMessage(this).debug() << ex.what();
481  return CIcons::StandardIconError16;
482  }
483  }
484 
485  QPixmap CVariant::toPixmap() const
486  {
487  if (m_v.type() == QVariant::Pixmap) { return m_v.value<QPixmap>(); }
488  if (m_v.type() == QVariant::Image) { return QPixmap::fromImage(m_v.value<QImage>()); }
489  if (m_v.type() == QVariant::Icon) { return iconToPixmap(m_v.value<QIcon>()); }
490 
491  return CIcon(toIcon()).toPixmap();
492  }
493 
494  void CVariant::registerMetadata() { private_ns::MetaTypeHelper<CVariant>::maybeRegisterMetaType(); }
495 
496  int CVariant::getMetaTypeId() const { return private_ns::MetaTypeHelper<CVariant>::maybeGetMetaTypeId(); }
497 
498  QString CVariant::getClassName() const { return QMetaType::typeName(getMetaTypeId()); }
499 
500  bool CVariant::isA(int metaTypeId) const
501  {
502  if (metaTypeId == QMetaType::UnknownType) { return false; }
503  if (metaTypeId == getMetaTypeId()) { return true; }
504  return false;
505  }
506 
507  bool CVariant::matches(const CVariant &value) const
508  {
509  if (!isValid()) { return false; }
510  auto *meta = getValueObjectMetaInfo();
511  if (!meta)
512  {
513  CLogMessage(this).warning(u"Invalid type for CVariant::matches: %1") << typeName();
514  return false;
515  }
516  try
517  {
518  return meta->matches(data(), value);
519  }
520  catch (const private_ns::CVariantException &ex)
521  {
522  CLogMessage(this).debug() << ex.what();
523  return false;
524  }
525  }
526 
527  QVariant fixQVariantFromDbusArgument(const QVariant &variant, int localUserType, const QString &typeName)
528  {
529  if (localUserType == static_cast<int>(QVariant::Invalid))
530  {
531  CLogMessage(&variant).warning(u"Invalid type for unmarshall: %1") << typeName;
532  }
533 
534  // my business?
535  if (!variant.canConvert<QDBusArgument>()) { return variant; }
536 
537  // complex, user type
538  // it has to be made sure, that the cast works
539  const QDBusArgument arg = variant.value<QDBusArgument>();
540  constexpr int userType = static_cast<int>(QVariant::UserType);
541  if (localUserType < userType)
542  {
543  // complex Qt type, e.g. QDateTime
544  return complexQtTypeFromDbusArgument(arg, localUserType);
545  }
546  else if (QMetaType(localUserType).flags() & QMetaType::IsEnumeration)
547  {
548  arg.beginStructure();
549  int i;
550  arg >> i;
551  arg.endStructure();
552 
553  QVariant valueVariant = QVariant::fromValue(i);
554  bool ok = valueVariant.convert(localUserType);
555  Q_ASSERT_X(ok, Q_FUNC_INFO, "int could not be converted to enum");
556  Q_UNUSED(ok);
557  return valueVariant;
558  }
559  else
560  {
561  QVariant valueVariant(QMetaType(localUserType), nullptr);
562  auto *meta = private_ns::getValueObjectMetaInfo(valueVariant);
563  if (meta)
564  {
565  meta->unmarshall(arg, valueVariant.data());
566  return valueVariant;
567  }
568  Q_ASSERT_X(false, Q_FUNC_INFO, "no meta");
569  return valueVariant;
570  }
571  }
572 
573  QVariant complexQtTypeFromDbusArgument(const QDBusArgument &argument, int type)
574  {
575  // QDate = 14, QTime = 15, QDateTime = 16, QUrl = 17,
576 
577  switch (type)
578  {
579  case QMetaType::QDateTime:
580  {
581  QDateTime dt;
582  argument >> dt;
583  return QVariant::fromValue(dt);
584  }
585  case QMetaType::QDate:
586  {
587  QDate date;
588  argument >> date;
589  return QVariant::fromValue(date);
590  }
591  case QMetaType::QTime:
592  {
593  QTime time;
594  argument >> time;
595  return QVariant::fromValue(time);
596  }
597  default:
598  {
599  const char *name = QMetaType::typeName(type);
600  qFatal("Type cannot be resolved: %s (%d)", name ? name : "", type);
601  }
602  }
603  return QVariant(); // suppress compiler warning
604  }
605 
606 } // namespace swift::misc
607 
IconIndex
Index for each icon, allows to send them via DBus, efficiently store them, etc.
Definition: icons.h:32
Non-owning reference to a CPropertyIndex with a subset of its features.
static CStatusMessage fromJsonException(const CJsonException &ex, const CLogCategoryList &categories, const QString &prefix)
Object from JSON exception message.
friend size_t qHash(const CVariant &var)
qHash overload, needed for storing value in a QSet.
Definition: variant.h:103
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.
Definition: variant.h:169
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.
Definition: variant.h:204
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.
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.
Definition: variant.h:261
bool isValid() const
True if this variant is valid.
Definition: variant.h:252
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 char * typeName() const
Return the typename of the value in this variant.
Definition: variant.h:258
bool isArithmetic() const
True if this variant's type is an integral or floating-point type.
const QVariant & getQVariant() const
Return the internal QVariant.
Definition: variant.h:191
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.
Definition: variant.h:255
qlonglong toLongLong(bool *ok=nullptr) const
Convert this variant to a longlong integer.
Definition: variant.h:228
void marshalToDataStream(QDataStream &stream) const
Marshal a value to a QDataStream.
CVariant()
Default constructor.
Definition: variant.h:73
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.
Definition: variant.h:225
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.
Definition: imageutils.cpp:55
SWIFT_MISC_EXPORT QDateTime fromStringUtc(const QString &dateTimeString, const QString &format)
Same as QDateTime::fromString but QDateTime will be set to UTC.