QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsvariantutils.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvariantutils.h
3 ------------------
4 Date : January 2022
5 Copyright : (C) 2022 Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgsvariantutils.h"
17#include "qgslogger.h"
18
19#include <QDate>
20#include <QTime>
21#include <QDateTime>
22#include <QBitArray>
23#include <QRect>
24#include <QLine>
25#include <QUuid>
26#include <QImage>
27#include <QPixmap>
28#include <QBrush>
29#include <QColor>
30#include <QBitmap>
31#include <QIcon>
32#include <QVector2D>
33#include <QVector3D>
34#include <QVector4D>
35#include <QQuaternion>
36
37QString QgsVariantUtils::typeToDisplayString( QVariant::Type type, QVariant::Type subType )
38{
39 switch ( type )
40 {
41 case QVariant::Invalid:
42 break;
43 case QVariant::Bool:
44 return QObject::tr( "Boolean" );
45 case QVariant::Int:
46 return QObject::tr( "Integer (32 bit)" );
47 case QVariant::UInt:
48 return QObject::tr( "Integer (unsigned 32 bit)" );
49 case QVariant::LongLong:
50 return QObject::tr( "Integer (64 bit)" );
51 case QVariant::ULongLong:
52 return QObject::tr( "Integer (unsigned 64 bit)" );
53 case QVariant::Double:
54 return QObject::tr( "Decimal (double)" );
55 case QVariant::Char:
56 return QObject::tr( "Character" );
57 case QVariant::Map:
58 return QObject::tr( "Map" );
59 case QVariant::List:
60 {
61 switch ( subType )
62 {
63 case QVariant::Int:
64 return QObject::tr( "Integer List" );
65 case QVariant::LongLong:
66 return QObject::tr( "Integer (64 bit) List" );
67 case QVariant::Double:
68 return QObject::tr( "Decimal (double) List" );
69 default:
70 return QObject::tr( "List" );
71 }
72 }
73 case QVariant::String:
74 return QObject::tr( "Text (string)" );
75 case QVariant::StringList:
76 return QObject::tr( "String List" );
77 case QVariant::ByteArray:
78 return QObject::tr( "Binary Object (BLOB)" );
79 case QVariant::BitArray:
80 return QObject::tr( "Bit Array" );
81 case QVariant::Date:
82 return QObject::tr( "Date" );
83 case QVariant::Time:
84 return QObject::tr( "Time" );
85 case QVariant::DateTime:
86 return QObject::tr( "Date & Time" );
87 case QVariant::Url:
88 return QObject::tr( "URL" );
89 case QVariant::Locale:
90 return QObject::tr( "Locale" );
91 case QVariant::Rect:
92 case QVariant::RectF:
93 return QObject::tr( "Rectangle" );
94 case QVariant::Size:
95 case QVariant::SizeF:
96 return QObject::tr( "Size" );
97 case QVariant::Line:
98 case QVariant::LineF:
99 return QObject::tr( "Line" );
100 case QVariant::Point:
101 case QVariant::PointF:
102 return QObject::tr( "Point" );
103 case QVariant::RegularExpression:
104 return QObject::tr( "Regular Expression" );
105 case QVariant::Hash:
106 return QObject::tr( "Hash" );
107 case QVariant::EasingCurve:
108 return QObject::tr( "Easing Curve" );
109 case QVariant::Uuid:
110 return QObject::tr( "UUID" );
111 case QVariant::ModelIndex:
112 case QVariant::PersistentModelIndex:
113 return QObject::tr( "Model Index" );
114 case QVariant::Font:
115 return QObject::tr( "Font" );
116 case QVariant::Pixmap:
117 return QObject::tr( "Pixmap" );
118 case QVariant::Brush:
119 return QObject::tr( "Brush" );
120 case QVariant::Color:
121 return QObject::tr( "Color" );
122 case QVariant::Palette:
123 return QObject::tr( "Palette" );
124 case QVariant::Image:
125 return QObject::tr( "Image" );
126 case QVariant::Polygon:
127 case QVariant::PolygonF:
128 return QObject::tr( "Polygon" );
129 case QVariant::Region:
130 return QObject::tr( "Region" );
131 case QVariant::Bitmap:
132 return QObject::tr( "Bitmap" );
133 case QVariant::Cursor:
134 return QObject::tr( "Cursor" );
135 case QVariant::KeySequence:
136 return QObject::tr( "Key Sequence" );
137 case QVariant::Pen:
138 return QObject::tr( "Pen" );
139 case QVariant::TextLength:
140 return QObject::tr( "Text Length" );
141 case QVariant::TextFormat:
142 return QObject::tr( "Text Format" );
143 case QVariant::Matrix4x4:
144 return QObject::tr( "Matrix" );
145 case QVariant::Transform:
146 return QObject::tr( "Transform" );
147 case QVariant::Vector2D:
148 case QVariant::Vector3D:
149 case QVariant::Vector4D:
150 return QObject::tr( "Vector" );
151 case QVariant::Quaternion:
152 return QObject::tr( "Quaternion" );
153 case QVariant::Icon:
154 return QObject::tr( "Icon" );
155 case QVariant::SizePolicy:
156 return QObject::tr( "Size Policy" );
157
158 default:
159 break;
160 }
161 return QString();
162}
163
164bool QgsVariantUtils::isNull( const QVariant &variant, bool silenceNullWarnings )
165{
166#ifndef QGISDEBUG
167 ( void )silenceNullWarnings;
168#endif
169
170 if ( variant.isNull() || !variant.isValid() )
171 return true;
172
173 switch ( variant.type() )
174 {
175 case QVariant::Invalid:
176 case QVariant::Bool:
177 case QVariant::Int:
178 case QVariant::UInt:
179 case QVariant::LongLong:
180 case QVariant::ULongLong:
181 case QVariant::Double:
182 case QVariant::Map:
183 case QVariant::List:
184 case QVariant::StringList:
185 case QVariant::Url:
186 case QVariant::Locale:
187 case QVariant::RegularExpression:
188 case QVariant::Hash:
189 case QVariant::EasingCurve:
190 case QVariant::ModelIndex:
191 case QVariant::PersistentModelIndex:
192
193 case QVariant::LastType:
194
195 return false;
196
197 case QVariant::Date:
198 if ( variant.toDate().isNull() )
199 {
200 if ( !silenceNullWarnings )
201 {
202 QgsDebugError( QStringLiteral( "NULL QDateTime was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
203 }
204 return true;
205 }
206 return false;
207 case QVariant::Time:
208 if ( variant.toTime().isNull() )
209 {
210 if ( !silenceNullWarnings )
211 {
212 QgsDebugError( QStringLiteral( "NULL QTime was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
213 }
214 return true;
215 }
216 return false;
217 case QVariant::DateTime:
218 if ( variant.toDate().isNull() )
219 {
220 if ( !silenceNullWarnings )
221 {
222 QgsDebugError( QStringLiteral( "NULL QDate was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
223 }
224 return true;
225 }
226 return false;
227 case QVariant::Char:
228 if ( variant.toChar().isNull() )
229 {
230 if ( !silenceNullWarnings )
231 {
232 QgsDebugError( QStringLiteral( "NULL QChar was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
233 }
234 return true;
235 }
236 return false;
237 case QVariant::String:
238 if ( variant.toString().isNull() )
239 {
240 if ( !silenceNullWarnings )
241 {
242 QgsDebugError( QStringLiteral( "NULL QString was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
243 }
244 return true;
245 }
246 return false;
247 case QVariant::ByteArray:
248 if ( variant.toByteArray().isNull() )
249 {
250 if ( !silenceNullWarnings )
251 {
252 QgsDebugError( QStringLiteral( "NULL QByteArray was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
253 }
254 return true;
255 }
256 return false;
257 case QVariant::BitArray:
258 if ( variant.toBitArray().isNull() )
259 {
260 if ( !silenceNullWarnings )
261 {
262 QgsDebugError( QStringLiteral( "NULL QBitArray was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
263 }
264 return true;
265 }
266 return false;
267 case QVariant::Rect:
268 if ( variant.toRect().isNull() )
269 {
270 if ( !silenceNullWarnings )
271 {
272 QgsDebugError( QStringLiteral( "NULL QRect was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
273 }
274 return true;
275 }
276 return false;
277 case QVariant::RectF:
278 if ( variant.toRectF().isNull() )
279 {
280 if ( !silenceNullWarnings )
281 {
282 QgsDebugError( QStringLiteral( "NULL QRectF was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
283 }
284 return true;
285 }
286 return false;
287 case QVariant::Size:
288 if ( variant.toSize().isNull() )
289 {
290 if ( !silenceNullWarnings )
291 {
292 QgsDebugError( QStringLiteral( "NULL QSize was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
293 }
294 return true;
295 }
296 return false;
297 case QVariant::SizeF:
298 if ( variant.toSizeF().isNull() )
299 {
300 if ( !silenceNullWarnings )
301 {
302 QgsDebugError( QStringLiteral( "NULL QSizeF was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
303 }
304 return true;
305 }
306 return false;
307 case QVariant::Line:
308 if ( variant.toLine().isNull() )
309 {
310 if ( !silenceNullWarnings )
311 {
312 QgsDebugError( QStringLiteral( "NULL QLine was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
313 }
314 return true;
315 }
316 return false;
317 case QVariant::LineF:
318 if ( variant.toLineF().isNull() )
319 {
320 if ( !silenceNullWarnings )
321 {
322 QgsDebugError( QStringLiteral( "NULL QLineF was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
323 }
324 return true;
325 }
326 return false;
327 case QVariant::Point:
328 if ( variant.toPoint().isNull() )
329 {
330 if ( !silenceNullWarnings )
331 {
332 QgsDebugError( QStringLiteral( "NULL QPoint was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
333 }
334 return true;
335 }
336 return false;
337 case QVariant::PointF:
338 if ( variant.toPointF().isNull() )
339 {
340 if ( !silenceNullWarnings )
341 {
342 QgsDebugError( QStringLiteral( "NULL QPointF was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
343 }
344 return true;
345 }
346 return false;
347 case QVariant::Uuid:
348 if ( variant.toUuid().isNull() )
349 {
350 if ( !silenceNullWarnings )
351 {
352 QgsDebugError( QStringLiteral( "NULL QUuid was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
353 }
354 return true;
355 }
356 return false;
357 case QVariant::Pixmap:
358 if ( variant.value< QPixmap >().isNull() )
359 {
360 if ( !silenceNullWarnings )
361 {
362 QgsDebugError( QStringLiteral( "NULL QPixmap was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
363 }
364 return true;
365 }
366 return false;
367 case QVariant::Image:
368 if ( variant.value< QImage >().isNull() )
369 {
370 if ( !silenceNullWarnings )
371 {
372 QgsDebugError( QStringLiteral( "NULL QImage was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
373 }
374 return true;
375 }
376 return false;
377 case QVariant::Region:
378 if ( variant.value< QRegion >().isNull() )
379 {
380 if ( !silenceNullWarnings )
381 {
382 QgsDebugError( QStringLiteral( "NULL QRegion was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
383 }
384 return true;
385 }
386 return false;
387 case QVariant::Bitmap:
388 if ( variant.value< QBitmap >().isNull() )
389 {
390 if ( !silenceNullWarnings )
391 {
392 QgsDebugError( QStringLiteral( "NULL QBitmap was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
393 }
394 return true;
395 }
396 return false;
397 case QVariant::Icon:
398 if ( variant.value< QIcon >().isNull() )
399 {
400 if ( !silenceNullWarnings )
401 {
402 QgsDebugError( QStringLiteral( "NULL QIcon was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
403 }
404 return true;
405 }
406 return false;
407 case QVariant::Vector2D:
408 if ( variant.value< QVector2D >().isNull() )
409 {
410 if ( !silenceNullWarnings )
411 {
412 QgsDebugError( QStringLiteral( "NULL QVector2D was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
413 }
414 return true;
415 }
416 return false;
417 case QVariant::Vector3D:
418 if ( variant.value< QVector3D >().isNull() )
419 {
420 if ( !silenceNullWarnings )
421 {
422 QgsDebugError( QStringLiteral( "NULL QVector3D was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
423 }
424 return true;
425 }
426 return false;
427 case QVariant::Vector4D:
428 if ( variant.value< QVector4D >().isNull() )
429 {
430 if ( !silenceNullWarnings )
431 {
432 QgsDebugError( QStringLiteral( "NULL QVector4D was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
433 }
434 return true;
435 }
436 return false;
437 case QVariant::Quaternion:
438 if ( variant.value< QQuaternion >().isNull() )
439 {
440 if ( !silenceNullWarnings )
441 {
442 QgsDebugError( QStringLiteral( "NULL QQuaternion was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
443 }
444 return true;
445 }
446 return false;
447
448 case QVariant::Color:
449 case QVariant::Font:
450 case QVariant::Brush:
451 case QVariant::Polygon:
452 case QVariant::Palette:
453 case QVariant::Cursor:
454 case QVariant::KeySequence:
455 case QVariant::Pen:
456 case QVariant::TextLength:
457 case QVariant::PolygonF:
458 case QVariant::TextFormat:
459 case QVariant::Transform:
460 case QVariant::Matrix4x4:
461 case QVariant::SizePolicy:
462 break;
463
464 case QVariant::UserType:
465 break;
466
467 default:
468 break;
469 }
470
471 return false;
472}
473
474QMetaType::Type QgsVariantUtils::variantTypeToMetaType( QVariant::Type variantType )
475{
476 // variant types can be directly mapped to meta types
477 return static_cast< QMetaType::Type >( variantType );
478}
479
480QVariant::Type QgsVariantUtils::metaTypeToVariantType( QMetaType::Type metaType )
481{
482 // NOLINTBEGIN(bugprone-branch-clone)
483 switch ( metaType )
484 {
485 // exact mapping, these are identical:
486 case QMetaType::Bool:
487 case QMetaType::Int:
488 case QMetaType::UInt:
489 case QMetaType::LongLong:
490 case QMetaType::ULongLong:
491 case QMetaType::Double:
492 case QMetaType::QChar:
493 case QMetaType::QVariantMap:
494 case QMetaType::QVariantList:
495 case QMetaType::QString:
496 case QMetaType::QStringList:
497 case QMetaType::QByteArray:
498 case QMetaType::QBitArray:
499 case QMetaType::QDate:
500 case QMetaType::QTime:
501 case QMetaType::QDateTime:
502 case QMetaType::QUrl:
503 case QMetaType::QLocale:
504 case QMetaType::QRect:
505 case QMetaType::QRectF:
506 case QMetaType::QSize:
507 case QMetaType::QSizeF:
508 case QMetaType::QLine:
509 case QMetaType::QLineF:
510 case QMetaType::QPoint:
511 case QMetaType::QPointF:
512 case QMetaType::QRegularExpression:
513 case QMetaType::QVariantHash:
514 case QMetaType::QEasingCurve:
515 case QMetaType::QUuid:
516 case QMetaType::QModelIndex:
517 case QMetaType::QPersistentModelIndex:
518 case QMetaType::QFont:
519 case QMetaType::QPixmap:
520 case QMetaType::QBrush:
521 case QMetaType::QColor:
522 case QMetaType::QPalette:
523 case QMetaType::QImage:
524 case QMetaType::QPolygon:
525 case QMetaType::QRegion:
526 case QMetaType::QBitmap:
527 case QMetaType::QCursor:
528 case QMetaType::QKeySequence:
529 case QMetaType::QPen:
530 case QMetaType::QTextLength:
531 case QMetaType::QTextFormat:
532 case QMetaType::QTransform:
533 case QMetaType::QMatrix4x4:
534 case QMetaType::QVector2D:
535 case QMetaType::QVector3D:
536 case QMetaType::QVector4D:
537 case QMetaType::QQuaternion:
538 case QMetaType::QPolygonF:
539 case QMetaType::QIcon:
540 case QMetaType::QSizePolicy:
541 case QMetaType::UnknownType:
542 case QMetaType::User:
543 return static_cast< QVariant::Type >( metaType );
544
545 // lossy, not exact mappings. We prefer to "expand" types
546 // to avoid truncation
547 case QMetaType::Long:
548 return QVariant::Type::LongLong;
549
550 case QMetaType::ULong:
551 return QVariant::Type::ULongLong;
552
553 case QMetaType::Char:
554#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
555 case QMetaType::Char16:
556 case QMetaType::Char32:
557#endif
558 case QMetaType::Short:
559 case QMetaType::SChar:
560 return QVariant::Type::Int;
561
562 case QMetaType::UShort:
563 case QMetaType::UChar:
564 return QVariant::Type::UInt;
565
566 case QMetaType::Float:
567#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
568 case QMetaType::Float16:
569#endif
570 return QVariant::Type::Double;
571
572 // no mapping possible:
573 case QMetaType::Nullptr:
574 case QMetaType::QCborSimpleType:
575 case QMetaType::Void:
576 case QMetaType::VoidStar:
577 case QMetaType::QVariant:
578 case QMetaType::QJsonValue:
579 case QMetaType::QJsonObject:
580 case QMetaType::QJsonArray:
581 case QMetaType::QJsonDocument:
582 case QMetaType::QCborValue:
583 case QMetaType::QCborArray:
584 case QMetaType::QCborMap:
585 case QMetaType::QObjectStar:
586#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
587 case QMetaType::QVariantPair:
588#endif
589 case QMetaType::QByteArrayList:
590 case QMetaType::QColorSpace:
591 break;
592
593 default:
594 break;
595 }
596 // NOLINTEND(bugprone-branch-clone)
597 return QVariant::Type::UserType;
598}
599
600
static QString typeToDisplayString(QVariant::Type type, QVariant::Type subType=QVariant::Type::Invalid)
Returns a user-friendly translated string representing a QVariant type.
static QMetaType::Type variantTypeToMetaType(QVariant::Type variantType)
Converts a QVariant::Type to a QMetaType::Type.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
static QVariant::Type metaTypeToVariantType(QMetaType::Type metaType)
Converts a QMetaType::Type to a QVariant::Type.
#define QgsDebugError(str)
Definition: qgslogger.h:38