QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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
18#include "qgsapplication.h"
19#include "qgslogger.h"
21
22#include <QBitArray>
23#include <QBitmap>
24#include <QBrush>
25#include <QColor>
26#include <QDate>
27#include <QDateTime>
28#include <QIcon>
29#include <QImage>
30#include <QLine>
31#include <QPixmap>
32#include <QQuaternion>
33#include <QRect>
34#include <QTime>
35#include <QUuid>
36#include <QVector2D>
37#include <QVector3D>
38#include <QVector4D>
39
40QString QgsVariantUtils::typeToDisplayString( QMetaType::Type type, QMetaType::Type subType )
41{
42 switch ( type )
43 {
44 case QMetaType::Type::UnknownType:
45 break;
46 case QMetaType::Type::Bool:
47 return QObject::tr( "Boolean" );
48 case QMetaType::Type::Int:
49 return QObject::tr( "Integer (32 bit)" );
50 case QMetaType::Type::UInt:
51 return QObject::tr( "Integer (unsigned 32 bit)" );
52 case QMetaType::Type::LongLong:
53 return QObject::tr( "Integer (64 bit)" );
54 case QMetaType::Type::ULongLong:
55 return QObject::tr( "Integer (unsigned 64 bit)" );
56 case QMetaType::Type::Double:
57 return QObject::tr( "Decimal (double)" );
58 case QMetaType::Type::QChar:
59 return QObject::tr( "Character" );
60 case QMetaType::Type::QVariantMap:
61 return QObject::tr( "Map" );
62 case QMetaType::Type::QVariantList:
63 {
64 switch ( subType )
65 {
66 case QMetaType::Type::Int:
67 return QObject::tr( "Integer List" );
68 case QMetaType::Type::LongLong:
69 return QObject::tr( "Integer (64 bit) List" );
70 case QMetaType::Type::Double:
71 return QObject::tr( "Decimal (double) List" );
72 default:
73 return QObject::tr( "List" );
74 }
75 }
76 case QMetaType::Type::QString:
77 return QObject::tr( "Text (string)" );
78 case QMetaType::Type::QStringList:
79 return QObject::tr( "String List" );
80 case QMetaType::Type::QByteArray:
81 return QObject::tr( "Binary Object (BLOB)" );
82 case QMetaType::Type::QBitArray:
83 return QObject::tr( "Bit Array" );
84 case QMetaType::Type::QDate:
85 return QObject::tr( "Date" );
86 case QMetaType::Type::QTime:
87 return QObject::tr( "Time" );
88 case QMetaType::Type::QDateTime:
89 return QObject::tr( "Date & Time" );
90 case QMetaType::Type::QUrl:
91 return QObject::tr( "URL" );
92 case QMetaType::Type::QLocale:
93 return QObject::tr( "Locale" );
94 case QMetaType::Type::QRect:
95 case QMetaType::Type::QRectF:
96 return QObject::tr( "Rectangle" );
97 case QMetaType::Type::QSize:
98 case QMetaType::Type::QSizeF:
99 return QObject::tr( "Size" );
100 case QMetaType::Type::QLine:
101 case QMetaType::Type::QLineF:
102 return QObject::tr( "Line" );
103 case QMetaType::Type::QPoint:
104 case QMetaType::Type::QPointF:
105 return QObject::tr( "Point" );
106 case QMetaType::Type::QRegularExpression:
107 return QObject::tr( "Regular Expression" );
108 case QMetaType::Type::QVariantHash:
109 return QObject::tr( "Hash" );
110 case QMetaType::Type::QEasingCurve:
111 return QObject::tr( "Easing Curve" );
112 case QMetaType::Type::QUuid:
113 return QObject::tr( "UUID" );
114 case QMetaType::Type::QModelIndex:
115 case QMetaType::Type::QPersistentModelIndex:
116 return QObject::tr( "Model Index" );
117 case QMetaType::Type::QFont:
118 return QObject::tr( "Font" );
119 case QMetaType::Type::QPixmap:
120 return QObject::tr( "Pixmap" );
121 case QMetaType::Type::QBrush:
122 return QObject::tr( "Brush" );
123 case QMetaType::Type::QColor:
124 return QObject::tr( "Color" );
125 case QMetaType::Type::QPalette:
126 return QObject::tr( "Palette" );
127 case QMetaType::Type::QImage:
128 return QObject::tr( "Image" );
129 case QMetaType::Type::QPolygon:
130 case QMetaType::Type::QPolygonF:
131 return QObject::tr( "Polygon" );
132 case QMetaType::Type::QRegion:
133 return QObject::tr( "Region" );
134 case QMetaType::Type::QBitmap:
135 return QObject::tr( "Bitmap" );
136 case QMetaType::Type::QCursor:
137 return QObject::tr( "Cursor" );
138 case QMetaType::Type::QKeySequence:
139 return QObject::tr( "Key Sequence" );
140 case QMetaType::Type::QPen:
141 return QObject::tr( "Pen" );
142 case QMetaType::Type::QTextLength:
143 return QObject::tr( "Text Length" );
144 case QMetaType::Type::QTextFormat:
145 return QObject::tr( "Text Format" );
146 case QMetaType::Type::QMatrix4x4:
147 return QObject::tr( "Matrix" );
148 case QMetaType::Type::QTransform:
149 return QObject::tr( "Transform" );
150 case QMetaType::Type::QVector2D:
151 case QMetaType::Type::QVector3D:
152 case QMetaType::Type::QVector4D:
153 return QObject::tr( "Vector" );
154 case QMetaType::Type::QQuaternion:
155 return QObject::tr( "Quaternion" );
156 case QMetaType::Type::QIcon:
157 return QObject::tr( "Icon" );
158 case QMetaType::Type::QSizePolicy:
159 return QObject::tr( "Size Policy" );
160
161 default:
162 break;
163 }
164 return QString();
165}
166
167QString QgsVariantUtils::typeToDisplayString( QVariant::Type type, QVariant::Type subType )
168{
170}
171
172bool QgsVariantUtils::isNull( const QVariant &variant, bool silenceNullWarnings )
173{
174#ifndef QGISDEBUG
175 ( void )silenceNullWarnings;
176#endif
177
178 if ( variant.isNull() || !variant.isValid() )
179 return true;
180
181 switch ( variant.userType() )
182 {
183 case QMetaType::Type::UnknownType:
184 case QMetaType::Type::Bool:
185 case QMetaType::Type::Int:
186 case QMetaType::Type::UInt:
187 case QMetaType::Type::LongLong:
188 case QMetaType::Type::ULongLong:
189 case QMetaType::Type::Double:
190 case QMetaType::Type::QVariantMap:
191 case QMetaType::Type::QVariantList:
192 case QMetaType::Type::QStringList:
193 case QMetaType::Type::QUrl:
194 case QMetaType::Type::QLocale:
195 case QMetaType::Type::QRegularExpression:
196 case QMetaType::Type::QVariantHash:
197 case QMetaType::Type::QEasingCurve:
198 case QMetaType::Type::QModelIndex:
199 case QMetaType::Type::QPersistentModelIndex:
200
201 return false;
202
203 case QMetaType::Type::QDate:
204 if ( variant.toDate().isNull() )
205 {
206 if ( !silenceNullWarnings )
207 {
208 QgsDebugError( QStringLiteral( "NULL QDateTime was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
209 }
210 return true;
211 }
212 return false;
213 case QMetaType::Type::QTime:
214 if ( variant.toTime().isNull() )
215 {
216 if ( !silenceNullWarnings )
217 {
218 QgsDebugError( QStringLiteral( "NULL QTime was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
219 }
220 return true;
221 }
222 return false;
223 case QMetaType::Type::QDateTime:
224 if ( variant.toDate().isNull() )
225 {
226 if ( !silenceNullWarnings )
227 {
228 QgsDebugError( QStringLiteral( "NULL QDate was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
229 }
230 return true;
231 }
232 return false;
233 case QMetaType::Type::QChar:
234 if ( variant.toChar().isNull() )
235 {
236 if ( !silenceNullWarnings )
237 {
238 QgsDebugError( QStringLiteral( "NULL QChar was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
239 }
240 return true;
241 }
242 return false;
243 case QMetaType::Type::QString:
244 if ( variant.toString().isNull() )
245 {
246 if ( !silenceNullWarnings )
247 {
248 QgsDebugError( QStringLiteral( "NULL QString was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
249 }
250 return true;
251 }
252 return false;
253 case QMetaType::Type::QByteArray:
254 if ( variant.toByteArray().isNull() )
255 {
256 if ( !silenceNullWarnings )
257 {
258 QgsDebugError( QStringLiteral( "NULL QByteArray was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
259 }
260 return true;
261 }
262 return false;
263 case QMetaType::Type::QBitArray:
264 if ( variant.toBitArray().isNull() )
265 {
266 if ( !silenceNullWarnings )
267 {
268 QgsDebugError( QStringLiteral( "NULL QBitArray was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
269 }
270 return true;
271 }
272 return false;
273 case QMetaType::Type::QRect:
274 if ( variant.toRect().isNull() )
275 {
276 if ( !silenceNullWarnings )
277 {
278 QgsDebugError( QStringLiteral( "NULL QRect was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
279 }
280 return true;
281 }
282 return false;
283 case QMetaType::Type::QRectF:
284 if ( variant.toRectF().isNull() )
285 {
286 if ( !silenceNullWarnings )
287 {
288 QgsDebugError( QStringLiteral( "NULL QRectF was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
289 }
290 return true;
291 }
292 return false;
293 case QMetaType::Type::QSize:
294 if ( variant.toSize().isNull() )
295 {
296 if ( !silenceNullWarnings )
297 {
298 QgsDebugError( QStringLiteral( "NULL QSize was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
299 }
300 return true;
301 }
302 return false;
303 case QMetaType::Type::QSizeF:
304 if ( variant.toSizeF().isNull() )
305 {
306 if ( !silenceNullWarnings )
307 {
308 QgsDebugError( QStringLiteral( "NULL QSizeF was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
309 }
310 return true;
311 }
312 return false;
313 case QMetaType::Type::QLine:
314 if ( variant.toLine().isNull() )
315 {
316 if ( !silenceNullWarnings )
317 {
318 QgsDebugError( QStringLiteral( "NULL QLine was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
319 }
320 return true;
321 }
322 return false;
323 case QMetaType::Type::QLineF:
324 if ( variant.toLineF().isNull() )
325 {
326 if ( !silenceNullWarnings )
327 {
328 QgsDebugError( QStringLiteral( "NULL QLineF was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
329 }
330 return true;
331 }
332 return false;
333 case QMetaType::Type::QPoint:
334 if ( variant.toPoint().isNull() )
335 {
336 if ( !silenceNullWarnings )
337 {
338 QgsDebugError( QStringLiteral( "NULL QPoint was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
339 }
340 return true;
341 }
342 return false;
343 case QMetaType::Type::QPointF:
344 if ( variant.toPointF().isNull() )
345 {
346 if ( !silenceNullWarnings )
347 {
348 QgsDebugError( QStringLiteral( "NULL QPointF was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
349 }
350 return true;
351 }
352 return false;
353 case QMetaType::Type::QUuid:
354 if ( variant.toUuid().isNull() )
355 {
356 if ( !silenceNullWarnings )
357 {
358 QgsDebugError( QStringLiteral( "NULL QUuid was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
359 }
360 return true;
361 }
362 return false;
363 case QMetaType::Type::QPixmap:
364 if ( variant.value< QPixmap >().isNull() )
365 {
366 if ( !silenceNullWarnings )
367 {
368 QgsDebugError( QStringLiteral( "NULL QPixmap was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
369 }
370 return true;
371 }
372 return false;
373 case QMetaType::Type::QImage:
374 if ( variant.value< QImage >().isNull() )
375 {
376 if ( !silenceNullWarnings )
377 {
378 QgsDebugError( QStringLiteral( "NULL QImage was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
379 }
380 return true;
381 }
382 return false;
383 case QMetaType::Type::QRegion:
384 if ( variant.value< QRegion >().isNull() )
385 {
386 if ( !silenceNullWarnings )
387 {
388 QgsDebugError( QStringLiteral( "NULL QRegion was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
389 }
390 return true;
391 }
392 return false;
393 case QMetaType::Type::QBitmap:
394 if ( variant.value< QBitmap >().isNull() )
395 {
396 if ( !silenceNullWarnings )
397 {
398 QgsDebugError( QStringLiteral( "NULL QBitmap was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
399 }
400 return true;
401 }
402 return false;
403 case QMetaType::Type::QIcon:
404 if ( variant.value< QIcon >().isNull() )
405 {
406 if ( !silenceNullWarnings )
407 {
408 QgsDebugError( QStringLiteral( "NULL QIcon was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
409 }
410 return true;
411 }
412 return false;
413 case QMetaType::Type::QVector2D:
414 if ( variant.value< QVector2D >().isNull() )
415 {
416 if ( !silenceNullWarnings )
417 {
418 QgsDebugError( QStringLiteral( "NULL QVector2D was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
419 }
420 return true;
421 }
422 return false;
423 case QMetaType::Type::QVector3D:
424 if ( variant.value< QVector3D >().isNull() )
425 {
426 if ( !silenceNullWarnings )
427 {
428 QgsDebugError( QStringLiteral( "NULL QVector3D was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
429 }
430 return true;
431 }
432 return false;
433 case QMetaType::Type::QVector4D:
434 if ( variant.value< QVector4D >().isNull() )
435 {
436 if ( !silenceNullWarnings )
437 {
438 QgsDebugError( QStringLiteral( "NULL QVector4D was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
439 }
440 return true;
441 }
442 return false;
443 case QMetaType::Type::QQuaternion:
444 if ( variant.value< QQuaternion >().isNull() )
445 {
446 if ( !silenceNullWarnings )
447 {
448 QgsDebugError( QStringLiteral( "NULL QQuaternion was stored in a QVariant -- stop it! Always use an invalid QVariant() instead." ) );
449 }
450 return true;
451 }
452 return false;
453
454 case QMetaType::Type::QColor:
455 case QMetaType::Type::QFont:
456 case QMetaType::Type::QBrush:
457 case QMetaType::Type::QPolygon:
458 case QMetaType::Type::QPalette:
459 case QMetaType::Type::QCursor:
460 case QMetaType::Type::QKeySequence:
461 case QMetaType::Type::QPen:
462 case QMetaType::Type::QTextLength:
463 case QMetaType::Type::QPolygonF:
464 case QMetaType::Type::QTextFormat:
465 case QMetaType::Type::QTransform:
466 case QMetaType::Type::QMatrix4x4:
467 case QMetaType::Type::QSizePolicy:
468 case QMetaType::Type::User:
469 default:
470 break;
471 }
472
473 return false;
474}
475
476bool QgsVariantUtils::isNumericType( QMetaType::Type metaType )
477{
478 switch ( metaType )
479 {
480 case QMetaType::Type::Int:
481 case QMetaType::Type::UInt:
482 case QMetaType::Type::LongLong:
483 case QMetaType::Type::ULongLong:
484 case QMetaType::Type::Double:
485 case QMetaType::Type::Float:
486 case QMetaType::Type::Short:
487 case QMetaType::Type::UShort:
488 case QMetaType::Type::Char:
489 case QMetaType::Type::UChar:
490 case QMetaType::Type::SChar:
491 return true;
492 default:
493 return false;
494 }
495}
496
497QMetaType::Type QgsVariantUtils::variantTypeToMetaType( QVariant::Type variantType )
498{
499 // variant types can be directly mapped to meta types
500 return static_cast< QMetaType::Type >( variantType );
501}
502
503QVariant::Type QgsVariantUtils::metaTypeToVariantType( QMetaType::Type metaType )
504{
505 // NOLINTBEGIN(bugprone-branch-clone)
506 switch ( metaType )
507 {
508 // exact mapping, these are identical:
509 case QMetaType::Bool:
510 case QMetaType::Int:
511 case QMetaType::UInt:
512 case QMetaType::LongLong:
513 case QMetaType::ULongLong:
514 case QMetaType::Double:
515 case QMetaType::QChar:
516 case QMetaType::QVariantMap:
517 case QMetaType::QVariantList:
518 case QMetaType::QString:
519 case QMetaType::QStringList:
520 case QMetaType::QByteArray:
521 case QMetaType::QBitArray:
522 case QMetaType::QDate:
523 case QMetaType::QTime:
524 case QMetaType::QDateTime:
525 case QMetaType::QUrl:
526 case QMetaType::QLocale:
527 case QMetaType::QRect:
528 case QMetaType::QRectF:
529 case QMetaType::QSize:
530 case QMetaType::QSizeF:
531 case QMetaType::QLine:
532 case QMetaType::QLineF:
533 case QMetaType::QPoint:
534 case QMetaType::QPointF:
535 case QMetaType::QRegularExpression:
536 case QMetaType::QVariantHash:
537 case QMetaType::QEasingCurve:
538 case QMetaType::QUuid:
539 case QMetaType::QModelIndex:
540 case QMetaType::QPersistentModelIndex:
541 case QMetaType::QFont:
542 case QMetaType::QPixmap:
543 case QMetaType::QBrush:
544 case QMetaType::QColor:
545 case QMetaType::QPalette:
546 case QMetaType::QImage:
547 case QMetaType::QPolygon:
548 case QMetaType::QRegion:
549 case QMetaType::QBitmap:
550 case QMetaType::QCursor:
551 case QMetaType::QKeySequence:
552 case QMetaType::QPen:
553 case QMetaType::QTextLength:
554 case QMetaType::QTextFormat:
555 case QMetaType::QTransform:
556 case QMetaType::QMatrix4x4:
557 case QMetaType::QVector2D:
558 case QMetaType::QVector3D:
559 case QMetaType::QVector4D:
560 case QMetaType::QQuaternion:
561 case QMetaType::QPolygonF:
562 case QMetaType::QIcon:
563 case QMetaType::QSizePolicy:
564 case QMetaType::UnknownType:
565 case QMetaType::User:
566 return static_cast< QVariant::Type >( metaType );
567
568 // lossy, not exact mappings. We prefer to "expand" types
569 // to avoid truncation
570 case QMetaType::Long:
571 return QVariant::Type::LongLong;
572
573 case QMetaType::ULong:
574 return QVariant::Type::ULongLong;
575
576 case QMetaType::Char:
577#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
578 case QMetaType::Char16:
579 case QMetaType::Char32:
580#endif
581 case QMetaType::Short:
582 case QMetaType::SChar:
583 return QVariant::Type::Int;
584
585 case QMetaType::UShort:
586 case QMetaType::UChar:
587 return QVariant::Type::UInt;
588
589 case QMetaType::Float:
590#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
591 case QMetaType::Float16:
592#endif
593 return QVariant::Type::Double;
594
595 // no mapping possible:
596 case QMetaType::Nullptr:
597 case QMetaType::QCborSimpleType:
598 case QMetaType::Void:
599 case QMetaType::VoidStar:
600 case QMetaType::QVariant:
601 case QMetaType::QJsonValue:
602 case QMetaType::QJsonObject:
603 case QMetaType::QJsonArray:
604 case QMetaType::QJsonDocument:
605 case QMetaType::QCborValue:
606 case QMetaType::QCborArray:
607 case QMetaType::QCborMap:
608 case QMetaType::QObjectStar:
609#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
610 case QMetaType::QVariantPair:
611#endif
612 case QMetaType::QByteArrayList:
613 case QMetaType::QColorSpace:
614 break;
615
616 default:
617 break;
618 }
619 // NOLINTEND(bugprone-branch-clone)
620 return QVariant::Type::UserType;
621}
622
623bool QgsVariantUtils::isUnsetAttributeValue( const QVariant &variant )
624{
625 return variant.userType() == qMetaTypeId< QgsUnsetAttributeValue >();
626}
627
628QVariant QgsVariantUtils::createNullVariant( QMetaType::Type metaType )
629{
630#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
631 return QVariant( QgsVariantUtils::metaTypeToVariantType( metaType ) );
632#else
633 return QVariant( QMetaType( metaType ) );
634#endif
635
636}
637
638QString QgsVariantUtils::displayString( const QVariant &variant, int precision )
639{
640
641 auto _displayString = [ ]( const QVariant & variant, int precision ) -> QString
642 {
643
644 if ( QgsVariantUtils::isNull( variant ) )
645 {
647 }
648
649 // Special treatment for numeric types if group separator is set or decimalPoint is not a dot
650 if ( variant.userType() == QMetaType::Type::Double )
651 {
652 // Locales with decimal point != '.' or that require group separator: use QLocale
653 if ( QLocale().decimalPoint() != '.' ||
654 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
655 {
656 if ( precision > 0 )
657 {
658 if ( -1 < variant.toDouble() && variant.toDouble() < 1 )
659 {
660 return QLocale().toString( variant.toDouble(), 'g', precision );
661 }
662 else
663 {
664 return QLocale().toString( variant.toDouble(), 'f', precision );
665 }
666 }
667 else
668 {
669 // Precision is not set, let's guess it from the
670 // standard conversion to string
671 const QString str( variant.toString() );
672 const int dotPosition( static_cast<int>( str.indexOf( '.' ) ) );
673 int precision;
674 if ( dotPosition < 0 && str.indexOf( 'e', 0, Qt::CaseInsensitive ) < 0 )
675 {
676 precision = 0;
677 return QLocale().toString( variant.toDouble(), 'f', precision );
678 }
679 else
680 {
681 if ( dotPosition < 0 ) precision = 0;
682 else precision = static_cast<int>( str.length() ) - dotPosition - 1;
683
684 if ( -1 < variant.toDouble() && variant.toDouble() < 1 )
685 {
686 return QLocale().toString( variant.toDouble(), 'g', precision );
687 }
688 else
689 {
690 return QLocale().toString( variant.toDouble(), 'f', precision );
691 }
692 }
693 }
694 }
695 // Default for doubles with precision
696 else if ( precision > 0 )
697 {
698 if ( -1 < variant.toDouble() && variant.toDouble() < 1 )
699 {
700 return QString::number( variant.toDouble(), 'g', precision );
701 }
702 else
703 {
704 return QString::number( variant.toDouble(), 'f', precision );
705 }
706 }
707 }
708 // Other numeric types than doubles
709 else if ( QgsVariantUtils::isNumericType( static_cast< QMetaType::Type >( variant.userType() ) ) &&
710 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
711 {
712 bool ok;
713 const qlonglong converted( variant.toLongLong( &ok ) );
714 if ( ok )
715 return QLocale().toString( converted );
716 }
717 else if ( variant.userType() == QMetaType::Type::QByteArray )
718 {
719 return QObject::tr( "BLOB" );
720 }
721
722 // Fallback if special rules do not apply
723 return variant.toString();
724 };
725
726 if ( variant.userType() == QMetaType::Type::QStringList || variant.userType() == QMetaType::Type::QVariantList )
727 {
728 QString result;
729 const QVariantList list = variant.toList();
730 for ( const QVariant &var : list )
731 {
732 if ( !result.isEmpty() )
733 {
734 result.append( ';' );
735 }
736 result.append( _displayString( var, precision ) );
737 }
738 return result;
739 }
740 else
741 {
742 return _displayString( variant, precision );
743 }
744}
static QString nullRepresentation()
Returns the string used to represent the value NULL throughout QGIS.
static QMetaType::Type variantTypeToMetaType(QVariant::Type variantType)
Converts a QVariant::Type to a QMetaType::Type.
static QString displayString(const QVariant &variant, int precision=-1)
Returns a localized representation of value with the given precision, if precision is -1 then precisi...
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
static QString typeToDisplayString(QMetaType::Type type, QMetaType::Type subType=QMetaType::Type::UnknownType)
Returns a user-friendly translated string representing a QVariant type.
static QVariant createNullVariant(QMetaType::Type metaType)
Helper method to properly create a null QVariant from a metaType Returns the created QVariant.
static bool isNumericType(QMetaType::Type metaType)
Returns true if the specified metaType is a numeric type.
static bool isUnsetAttributeValue(const QVariant &variant)
Check if the variant is a QgsUnsetAttributeValue.
static QVariant::Type metaTypeToVariantType(QMetaType::Type metaType)
Converts a QMetaType::Type to a QVariant::Type.
#define QgsDebugError(str)
Definition qgslogger.h:57