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()); casted)
142  {
143  return bMeta->compareImpl(casted, b.data());
144  }
145  if (casted = bMeta->upCastTo(b.data(), aMeta->getMetaTypeId()); casted)
146  {
147  return aMeta->compareImpl(a.data(), casted);
148  }
149  CLogMessage(&a).warning(
150  u"Comparing two CVariants containing unrelated value objects: %1 (%2) and %3 (%4)")
151  << a.typeName() << a.userType() << b.typeName() << b.userType();
152  return 0;
153  }
154  catch (const private_ns::CVariantException &ex)
155  {
156  CLogMessage(&a).debug() << ex.what();
157  return 0;
158  }
159  }
160  const QPartialOrdering order = QVariant::compare(a.m_v, b.m_v);
161  if (order == QPartialOrdering::Less) { return -1; }
162  if (order == QPartialOrdering::Greater) { return 1; }
163  return 0; // for "Equivalent" and "Unordered"
164  }
165 
166  QJsonObject CVariant::toJson() const
167  {
168  QJsonObject json;
169  json.insert("type", this->typeName());
170 
171  switch (m_v.type())
172  {
173  case QVariant::Invalid: json.insert("value", 0); break;
174  case QVariant::Int: json.insert("value", m_v.toInt()); break;
175  case QVariant::UInt: json.insert("value", m_v.toInt()); break;
176  case QVariant::Bool: json.insert("value", m_v.toBool()); break;
177  case QVariant::Double: json.insert("value", m_v.toDouble()); break;
178  case QVariant::LongLong: json.insert("value", m_v.toLongLong()); break;
179  case QVariant::ULongLong: json.insert("value", m_v.toLongLong()); break;
180  case QVariant::String: json.insert("value", m_v.toString()); break;
181  case QVariant::Char: json.insert("value", m_v.toString()); break;
182  case QVariant::ByteArray: json.insert("value", m_v.toString()); break;
183  case QVariant::DateTime: json.insert("value", m_v.toDateTime().toString(Qt::ISODate)); break;
184  case QVariant::Date: json.insert("value", m_v.toDate().toString(Qt::ISODate)); break;
185  case QVariant::Time: json.insert("value", m_v.toTime().toString(Qt::ISODate)); break;
186  case QVariant::StringList: json.insert("value", QJsonArray::fromStringList(m_v.toStringList())); break;
187  default:
188  try
189  {
190  auto *meta = getValueObjectMetaInfo();
191  if (meta) { json.insert("value", meta->toJson(data())); }
192  else if (m_v.canConvert<QString>()) { json.insert("value", m_v.toString()); }
193  else
194  {
195  CLogMessage(this).warning(u"Unsupported CVariant type for toJson: %1 (%2)")
196  << typeName() << userType();
197  }
198  }
199  catch (const private_ns::CVariantException &ex)
200  {
201  CLogMessage(this).debug() << ex.what();
202  }
203  }
204  return json;
205  }
206 
207  QString CVariant::toJsonString(QJsonDocument::JsonFormat format) const
208  {
209  QJsonDocument jsonDoc(toJson());
210  return jsonDoc.toJson(format);
211  }
212 
213  void CVariant::convertFromJson(const QJsonObject &json)
214  {
215  // Remark: Names "type" and "value" are also used for drag and drop
216  // Changing the names here requires the change for drag and drop too
217  const QJsonValue typeValue = json.value("type");
218  if (typeValue.isUndefined()) { throw CJsonException("Missing 'type'"); }
219  const QString typeName = typeValue.toString();
220  if (typeName.isEmpty())
221  {
222  m_v.clear();
223  return;
224  }
225  const int typeId = QMetaType::type(qPrintable(typeName));
226 
227  const QJsonValue value = json.value("value");
228  if (value.isUndefined()) { throw CJsonException("Missing 'value'"); }
229  switch (typeId)
230  {
231  case QVariant::Invalid: throw CJsonException("Type not recognized by QMetaType");
232  case QVariant::Int: m_v.setValue(value.toInt()); break;
233  case QVariant::UInt: m_v.setValue<uint>(static_cast<uint>(value.toInt())); break;
234  case QVariant::Bool: m_v.setValue(value.toBool()); break;
235  case QVariant::Double: m_v.setValue(value.toDouble()); break;
236  case QVariant::LongLong: m_v.setValue(static_cast<qlonglong>(value.toDouble())); break;
237  case QVariant::ULongLong: m_v.setValue(static_cast<qulonglong>(value.toDouble())); break;
238  case QVariant::String: m_v.setValue(value.toString()); break;
239  case QVariant::Char: m_v.setValue(value.toString().size() > 0 ? value.toString().at(0) : '\0'); break;
240  case QVariant::ByteArray: m_v.setValue(value.toString().toLatin1()); break;
241  case QVariant::DateTime: m_v.setValue(fromStringUtc(value.toString(), Qt::ISODate)); break;
242  case QVariant::Date: m_v.setValue(QDate::fromString(value.toString(), Qt::ISODate)); break;
243  case QVariant::Time: m_v.setValue(QTime::fromString(value.toString(), Qt::ISODate)); break;
244  case QVariant::StringList: m_v.setValue(QVariant(value.toArray().toVariantList()).toStringList()); break;
245  default:
246  try
247  {
248  auto *meta = private_ns::getValueObjectMetaInfo(typeId);
249  if (meta)
250  {
251  CJsonScope scope("value"); // tracker
252  Q_UNUSED(scope);
253  m_v = QVariant(QMetaType(typeId), nullptr);
254 
255  // this will call convertFromJson if there is no MemoizedJson
256  meta->convertFromMemoizedJson(value.toObject(), data(), true);
257  }
258  else if (QMetaType::hasRegisteredConverterFunction(QMetaType(qMetaTypeId<QString>()),
259  QMetaType(typeId)))
260  {
261  m_v.setValue(value.toString());
262  if (!m_v.convert(typeId)) { throw CJsonException("Failed to convert from JSON string"); }
263  }
264  else { throw CJsonException("Type not supported by convertFromJson"); }
265  }
266  catch (const private_ns::CVariantException &ex)
267  {
268  throw CJsonException(ex.what());
269  }
270  }
271  }
272 
273  CStatusMessage CVariant::convertFromJsonNoThrow(const QJsonObject &json, const CLogCategoryList &categories,
274  const QString &prefix)
275  {
276  try
277  {
278  convertFromJson(json);
279  }
280  catch (const CJsonException &ex)
281  {
282  return CStatusMessage::fromJsonException(ex, categories, prefix);
283  }
284  return {};
285  }
286 
287  QJsonObject CVariant::toMemoizedJson() const
288  {
289  auto *meta = getValueObjectMetaInfo();
290  if (meta)
291  {
292  try
293  {
294  QJsonObject json;
295  json.insert("type", this->typeName());
296  json.insert("value", meta->toMemoizedJson(data()));
297  return json;
298  }
299  catch (const private_ns::CVariantException &ex)
300  {
301  CLogMessage(this).debug() << ex.what();
302  return {};
303  }
304  }
305  else { return toJson(); }
306  }
307 
308  void CVariant::convertFromMemoizedJson(const QJsonObject &json, bool allowFallbackToJson)
309  {
310  QJsonValue typeValue = json.value("type");
311  if (typeValue.isUndefined()) { throw CJsonException("Missing 'type'"); }
312  QString typeName = typeValue.toString();
313  if (typeName.isEmpty())
314  {
315  m_v.clear();
316  return;
317  }
318  int typeId = QMetaType::type(qPrintable(typeName));
319 
320  auto *meta = private_ns::getValueObjectMetaInfo(typeId);
321  if (meta)
322  {
323  try
324  {
325  QJsonValue value = json.value("value");
326  if (value.isUndefined()) { throw CJsonException("Missing 'value'"); }
327 
328  CJsonScope scope("value");
329  m_v = QVariant(QMetaType(typeId), nullptr);
330  meta->convertFromMemoizedJson(value.toObject(), data(), allowFallbackToJson);
331  }
332  catch (const private_ns::CVariantException &ex)
333  {
334  throw CJsonException(ex.what());
335  }
336  }
337  else { convertFromJson(json); }
338  }
339 
340  CStatusMessage CVariant::convertFromMemoizedJsonNoThrow(const QJsonObject &json, const CLogCategoryList &categories,
341  const QString &prefix)
342  {
343  try
344  {
345  convertFromMemoizedJson(json, false);
346  }
347  catch (const CJsonException &ex)
348  {
349  return CStatusMessage::fromJsonException(ex, categories, prefix);
350  }
351  return {};
352  }
353 
354  size_t CVariant::getValueHash() const
355  {
356  switch (m_v.type())
357  {
358  case QVariant::Invalid: return 0;
359  case QVariant::Int: return qHash(m_v.toInt());
360  case QVariant::UInt: return qHash(m_v.toUInt());
361  case QVariant::Bool: return qHash(m_v.toUInt());
362  case QVariant::Double: return qHash(m_v.toUInt());
363  case QVariant::LongLong: return qHash(m_v.toLongLong());
364  case QVariant::ULongLong: return qHash(m_v.toULongLong());
365  case QVariant::String: return qHash(m_v.toString());
366  case QVariant::Char: return qHash(m_v.toChar());
367  case QVariant::ByteArray: return qHash(m_v.toByteArray());
368  default:
369  try
370  {
371  auto *meta = getValueObjectMetaInfo();
372  if (meta) { return meta->getValueHash(data()); }
373  else if (m_v.canConvert<QString>()) { return qHash(m_v.toString()); }
374  else
375  {
376  CLogMessage(this).warning(u"Unsupported CVariant type for getValueHash: %1 (%2)")
377  << typeName() << userType();
378  return 0;
379  }
380  }
381  catch (const private_ns::CVariantException &ex)
382  {
383  CLogMessage(this).debug() << ex.what();
384  return 0;
385  }
386  }
387  }
388 
389  void CVariant::marshallToDbus(QDBusArgument &arg) const
390  {
391  if (isValid()) { arg << QString(typeName()) << QDBusVariant(getQVariant()); }
392  else { arg << QString() << QDBusVariant(QVariant(0)); }
393  }
394 
396 
400  QVariant fixQVariantFromDbusArgument(const QVariant &variant, int localUserType, const QString &typeName);
401  QVariant complexQtTypeFromDbusArgument(const QDBusArgument &argument, int type);
403 
404  void CVariant::unmarshallFromDbus(const QDBusArgument &arg)
405  {
406  QString typeName;
407  QDBusVariant dbusVar;
408  arg >> typeName >> dbusVar;
409 
410  if (typeName.isEmpty()) { *this = CVariant(); }
411  else
412  {
413  *this = fixQVariantFromDbusArgument(dbusVar.variant(), QMetaType::type(qPrintable(typeName)), typeName);
414  }
415  }
416 
417  void CVariant::marshalToDataStream(QDataStream &stream) const { stream << m_v; }
418 
419  void CVariant::unmarshalFromDataStream(QDataStream &stream) { stream >> m_v; }
420 
421  void CVariant::setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
422  {
423  auto *meta = getValueObjectMetaInfo();
424  Q_ASSERT(meta);
425  try
426  {
427  meta->setPropertyByIndex(data(), variant, index);
428  }
429  catch (const private_ns::CVariantException &ex)
430  {
431  CLogMessage(this).debug() << ex.what();
432  }
433  }
434 
436  {
437  auto *meta = getValueObjectMetaInfo();
438  Q_ASSERT(meta);
439  try
440  {
441  QVariant result;
442  meta->propertyByIndex(data(), result, index);
443  return result;
444  }
445  catch (const private_ns::CVariantException &ex)
446  {
447  CLogMessage(this).debug() << ex.what();
448  return {};
449  }
450  }
451 
452  bool CVariant::equalsPropertyByIndex(const CVariant &compareValue, CPropertyIndexRef index) const
453  {
454  auto *meta = getValueObjectMetaInfo();
455  Q_ASSERT(meta);
456  try
457  {
458  return meta->equalsPropertyByIndex(data(), compareValue, index);
459  }
460  catch (const private_ns::CVariantException &ex)
461  {
462  CLogMessage(this).debug() << ex.what();
463  return false;
464  }
465  }
466 
468  {
469  auto *meta = getValueObjectMetaInfo();
470  if (!meta) { return {}; }
471  try
472  {
473  return static_cast<CIcons::IconIndex>(meta->toIcon(data()));
474  }
475  catch (const private_ns::CVariantException &ex)
476  {
477  CLogMessage(this).debug() << ex.what();
478  return CIcons::StandardIconError16;
479  }
480  }
481 
482  QPixmap CVariant::toPixmap() const
483  {
484  if (m_v.type() == QVariant::Pixmap) { return m_v.value<QPixmap>(); }
485  if (m_v.type() == QVariant::Image) { return QPixmap::fromImage(m_v.value<QImage>()); }
486  if (m_v.type() == QVariant::Icon) { return iconToPixmap(m_v.value<QIcon>()); }
487 
488  return CIcon(toIcon()).toPixmap();
489  }
490 
491  void CVariant::registerMetadata() { private_ns::MetaTypeHelper<CVariant>::maybeRegisterMetaType(); }
492 
493  int CVariant::getMetaTypeId() const { return private_ns::MetaTypeHelper<CVariant>::maybeGetMetaTypeId(); }
494 
495  QString CVariant::getClassName() const { return QMetaType::typeName(getMetaTypeId()); }
496 
497  bool CVariant::isA(int metaTypeId) const
498  {
499  if (metaTypeId == QMetaType::UnknownType) { return false; }
500  if (metaTypeId == getMetaTypeId()) { return true; }
501  return false;
502  }
503 
504  bool CVariant::matches(const CVariant &value) const
505  {
506  if (!isValid()) { return false; }
507  auto *meta = getValueObjectMetaInfo();
508  if (!meta)
509  {
510  CLogMessage(this).warning(u"Invalid type for CVariant::matches: %1") << typeName();
511  return false;
512  }
513  try
514  {
515  return meta->matches(data(), value);
516  }
517  catch (const private_ns::CVariantException &ex)
518  {
519  CLogMessage(this).debug() << ex.what();
520  return false;
521  }
522  }
523 
524  QVariant fixQVariantFromDbusArgument(const QVariant &variant, int localUserType, const QString &typeName)
525  {
526  if (localUserType == static_cast<int>(QVariant::Invalid))
527  {
528  CLogMessage(&variant).warning(u"Invalid type for unmarshall: %1") << typeName;
529  }
530 
531  // my business?
532  if (!variant.canConvert<QDBusArgument>()) { return variant; }
533 
534  // complex, user type
535  // it has to be made sure, that the cast works
536  const QDBusArgument arg = variant.value<QDBusArgument>();
537  constexpr int userType = static_cast<int>(QVariant::UserType);
538  if (localUserType < userType)
539  {
540  // complex Qt type, e.g. QDateTime
541  return complexQtTypeFromDbusArgument(arg, localUserType);
542  }
543  else if (QMetaType(localUserType).flags() & QMetaType::IsEnumeration)
544  {
545  arg.beginStructure();
546  int i;
547  arg >> i;
548  arg.endStructure();
549 
550  QVariant valueVariant = QVariant::fromValue(i);
551  bool ok = valueVariant.convert(localUserType);
552  Q_ASSERT_X(ok, Q_FUNC_INFO, "int could not be converted to enum");
553  Q_UNUSED(ok);
554  return valueVariant;
555  }
556  else
557  {
558  QVariant valueVariant(QMetaType(localUserType), nullptr);
559  auto *meta = private_ns::getValueObjectMetaInfo(valueVariant);
560  if (meta)
561  {
562  meta->unmarshall(arg, valueVariant.data());
563  return valueVariant;
564  }
565  Q_ASSERT_X(false, Q_FUNC_INFO, "no meta");
566  return valueVariant;
567  }
568  }
569 
570  QVariant complexQtTypeFromDbusArgument(const QDBusArgument &argument, int type)
571  {
572  // QDate = 14, QTime = 15, QDateTime = 16, QUrl = 17,
573 
574  switch (type)
575  {
576  case QMetaType::QDateTime:
577  {
578  QDateTime dt;
579  argument >> dt;
580  return QVariant::fromValue(dt);
581  }
582  case QMetaType::QDate:
583  {
584  QDate date;
585  argument >> date;
586  return QVariant::fromValue(date);
587  }
588  case QMetaType::QTime:
589  {
590  QTime time;
591  argument >> time;
592  return QVariant::fromValue(time);
593  }
594  default:
595  {
596  const char *name = QMetaType::typeName(type);
597  qFatal("Type cannot be resolved: %s (%d)", name ? name : "", type);
598  }
599  }
600  return QVariant(); // suppress compiler warning
601  }
602 
603 } // namespace swift::misc
604 
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.