summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qguivariant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qguivariant.cpp')
-rw-r--r--src/gui/kernel/qguivariant.cpp447
1 files changed, 142 insertions, 305 deletions
diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp
index 72f7e183e1..2bb7524ab9 100644
--- a/src/gui/kernel/qguivariant.cpp
+++ b/src/gui/kernel/qguivariant.cpp
@@ -41,6 +41,7 @@
#include "qvariant.h"
+// Gui types
#include "qbitmap.h"
#include "qbrush.h"
#include "qcolor.h"
@@ -64,7 +65,32 @@
#include "qvector4d.h"
#include "qquaternion.h"
+// Core types
+#include "qvariant.h"
+#include "qbitarray.h"
+#include "qbytearray.h"
+#include "qdatastream.h"
+#include "qdebug.h"
+#include "qmap.h"
+#include "qdatetime.h"
+#include "qeasingcurve.h"
+#include "qlist.h"
+#include "qstring.h"
+#include "qstringlist.h"
+#include "qurl.h"
+#include "qlocale.h"
+
+#ifndef QT_NO_GEOM_VARIANT
+#include "qsize.h"
+#include "qpoint.h"
+#include "qrect.h"
+#include "qline.h"
+#endif
+
+#include <float.h>
+
#include "private/qvariant_p.h"
+#include <private/qmetatype_p.h>
QT_BEGIN_NAMESPACE
@@ -72,339 +98,150 @@ Q_GUI_EXPORT const QVariant::Handler *qt_widgets_variant_handler = 0;
Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler();
-static void construct(QVariant::Private *x, const void *copy)
-{
- switch (x->type) {
- case QVariant::Bitmap:
- v_construct<QBitmap>(x, copy);
- break;
- case QVariant::Region:
- v_construct<QRegion>(x, copy);
- break;
- case QVariant::Polygon:
- v_construct<QPolygon>(x, copy);
- break;
- case QVariant::Font:
- v_construct<QFont>(x, copy);
- break;
- case QVariant::Pixmap:
- v_construct<QPixmap>(x, copy);
- break;
- case QVariant::Image:
- v_construct<QImage>(x, copy);
- break;
- case QVariant::Brush:
- v_construct<QBrush>(x, copy);
- break;
- case QVariant::Color:
- v_construct<QColor>(x, copy);
- break;
- case QVariant::Palette:
- v_construct<QPalette>(x, copy);
- break;
- case QVariant::Matrix:
- v_construct<QMatrix>(x, copy);
- break;
- case QVariant::Transform:
- v_construct<QTransform>(x, copy);
- break;
- case QVariant::TextFormat:
- v_construct<QTextFormat>(x, copy);
- break;
- case QVariant::TextLength:
- v_construct<QTextLength>(x, copy);
- break;
-#ifndef QT_NO_SHORTCUT
- case QVariant::KeySequence:
- v_construct<QKeySequence>(x, copy);
- break;
+template<typename T>
+struct TypeDefiniton {
+ static const bool IsAvailable = true;
+};
+// Ignore these types, as incomplete
+#ifdef QT_NO_GEOM_VARIANT
+template<> struct TypeDefiniton<QRect> { static const bool IsAvailable = false; };
+template<> struct TypeDefiniton<QRectF> { static const bool IsAvailable = false; };
+template<> struct TypeDefiniton<QSize> { static const bool IsAvailable = false; };
+template<> struct TypeDefiniton<QSizeF> { static const bool IsAvailable = false; };
+template<> struct TypeDefiniton<QLine> { static const bool IsAvailable = false; };
+template<> struct TypeDefiniton<QLineF> { static const bool IsAvailable = false; };
+template<> struct TypeDefiniton<QPoint> { static const bool IsAvailable = false; };
+template<> struct TypeDefiniton<QPointF> { static const bool IsAvailable = false; };
#endif
- case QVariant::Pen:
- v_construct<QPen>(x, copy);
- break;
-#ifndef QT_NO_CURSOR
- case QVariant::Cursor:
- v_construct<QCursor>(x, copy);
- break;
+#ifdef QT_NO_SHORTCUT
+template<> struct TypeDefiniton<QKeySequence> { static const bool IsAvailable = false; };
#endif
- case 62: {
- // small 'trick' to let a QVariant(Qt::blue) create a variant
- // of type QColor
- x->type = QVariant::Color;
- QColor color(*reinterpret_cast<const Qt::GlobalColor *>(copy));
- v_construct<QColor>(x, &color);
- break;
- }
-#ifndef QT_NO_MATRIX4X4
- case QVariant::Matrix4x4:
- v_construct<QMatrix4x4>(x, copy);
- break;
+#ifdef QT_NO_CURSOR
+template<> struct TypeDefiniton<QCursor> { static const bool IsAvailable = false; };
#endif
-#ifndef QT_NO_VECTOR2D
- case QVariant::Vector2D:
- v_construct<QVector2D>(x, copy);
- break;
+#ifdef QT_NO_MATRIX4X4
+template<> struct TypeDefiniton<QMatrix4x4> { static const bool IsAvailable = false; };
#endif
-#ifndef QT_NO_VECTOR3D
- case QVariant::Vector3D:
- v_construct<QVector3D>(x, copy);
- break;
+#ifdef QT_NO_VECTOR2D
+template<> struct TypeDefiniton<QVector2D> { static const bool IsAvailable = false; };
#endif
-#ifndef QT_NO_VECTOR4D
- case QVariant::Vector4D:
- v_construct<QVector4D>(x, copy);
- break;
+#ifdef QT_NO_VECTOR3D
+template<> struct TypeDefiniton<QVector3D> { static const bool IsAvailable = false; };
#endif
-#ifndef QT_NO_QUATERNION
- case QVariant::Quaternion:
- v_construct<QQuaternion>(x, copy);
- break;
+#ifdef QT_NO_VECTOR4D
+template<> struct TypeDefiniton<QVector4D> { static const bool IsAvailable = false; };
#endif
- case QVariant::SizePolicy:
- case QVariant::Icon:
- if (qt_widgets_variant_handler) {
- qt_widgets_variant_handler->construct(x, copy);
+#ifdef QT_NO_QUATERNION
+template<> struct TypeDefiniton<QQuaternion> { static const bool IsAvailable = false; };
+#endif
+
+struct CoreAndGuiTypesFilter {
+ template<typename T>
+ struct Acceptor {
+ static const bool IsAccepted = (QTypeModuleInfo<T>::IsCore || QTypeModuleInfo<T>::IsGui) && TypeDefiniton<T>::IsAvailable;
+ };
+};
+
+static void construct(QVariant::Private *x, const void *copy)
+{
+ const int type = x->type;
+ QVariantConstructor<CoreAndGuiTypesFilter> constructor(x, copy);
+ QMetaTypeSwitcher::switcher<void>(constructor, type, 0);
+
+ // FIXME This is an ugly hack if QVariantConstructor fails to build a value it constructs an invalid type
+ if (Q_UNLIKELY(x->type == QVariant::Invalid)) {
+ if (type == 62) {
+ // small 'trick' to let a QVariant(Qt::blue) create a variant
+ // of type QColor
+ // TODO Get rid of this hack.
+ x->type = QVariant::Color;
+ QColor color(*reinterpret_cast<const Qt::GlobalColor *>(copy));
+ v_construct<QColor>(x, &color);
return;
}
- break;
- default:
- qcoreVariantHandler()->construct(x, copy);
- return;
+ if (type == QVariant::Icon || type == QVariant::SizePolicy) {
+ // TODO we need to clean up variant handlers, so they are replacament, not extension
+ x->type = type;
+ if (qt_widgets_variant_handler) {
+ qt_widgets_variant_handler->construct(x, copy);
+ }
+ }
}
- x->is_null = !copy;
}
static void clear(QVariant::Private *d)
{
- switch (d->type) {
- case QVariant::Bitmap:
- v_clear<QBitmap>(d);
- break;
- case QVariant::Cursor:
- v_clear<QCursor>(d);
- break;
- case QVariant::Region:
- v_clear<QRegion>(d);
- break;
- case QVariant::Polygon:
- v_clear<QPolygon>(d);
- break;
- case QVariant::Font:
- v_clear<QFont>(d);
- break;
- case QVariant::Pixmap:
- v_clear<QPixmap>(d);
- break;
- case QVariant::Image:
- v_clear<QImage>(d);
- break;
- case QVariant::Brush:
- v_clear<QBrush>(d);
- break;
- case QVariant::Color:
- v_clear<QColor>(d);
- break;
- case QVariant::Palette:
- v_clear<QPalette>(d);
- break;
- case QVariant::Matrix:
- v_clear<QMatrix>(d);
- break;
- case QVariant::Transform:
- v_clear<QTransform>(d);
- break;
- case QVariant::TextFormat:
- v_clear<QTextFormat>(d);
- break;
- case QVariant::TextLength:
- v_clear<QTextLength>(d);
- break;
-#ifndef QT_NO_SHORTCUT
- case QVariant::KeySequence:
- v_clear<QKeySequence>(d);
- break;
-#endif
- case QVariant::Pen:
- v_clear<QPen>(d);
- break;
-#ifndef QT_NO_MATRIX4X4
- case QVariant::Matrix4x4:
- v_clear<QMatrix4x4>(d);
- break;
-#endif
-#ifndef QT_NO_VECTOR2D
- case QVariant::Vector2D:
- v_clear<QVector2D>(d);
- break;
-#endif
-#ifndef QT_NO_VECTOR3D
- case QVariant::Vector3D:
- v_clear<QVector3D>(d);
- break;
-#endif
-#ifndef QT_NO_VECTOR4D
- case QVariant::Vector4D:
- v_clear<QVector4D>(d);
- break;
-#endif
-#ifndef QT_NO_QUATERNION
- case QVariant::Quaternion:
- v_clear<QVector4D>(d);
- break;
-#endif
- case QVariant::SizePolicy:
- case QVariant::Icon:
+ const int type = d->type;
+ if (type == QVariant::Icon || type == QVariant::SizePolicy) {
+ // TODO we need to clean up variant handlers, so they are replacament, not extension
if (qt_widgets_variant_handler) {
qt_widgets_variant_handler->clear(d);
return;
}
- break;
- default:
- qcoreVariantHandler()->clear(d);
- return;
}
-
- d->type = QVariant::Invalid;
- d->is_null = true;
- d->is_shared = false;
+ QVariantDestructor<CoreAndGuiTypesFilter> destructor(d);
+ QMetaTypeSwitcher::switcher<void>(destructor, type, 0);
}
-
+// This class is a hack that customizes access to QPolygon
+template<class Filter>
+class QGuiVariantIsNull : public QVariantIsNull<Filter> {
+ typedef QVariantIsNull<Filter> Base;
+public:
+ QGuiVariantIsNull(const QVariant::Private *d)
+ : QVariantIsNull<Filter>(d)
+ {}
+ template<typename T>
+ bool delegate(const T *p) { return Base::delegate(p); }
+ bool delegate(const QPolygon*) { return v_cast<QPolygon>(Base::m_d)->isEmpty(); }
+ bool delegate(const void *p) { return Base::delegate(p); }
+};
static bool isNull(const QVariant::Private *d)
{
- switch(d->type) {
- case QVariant::Bitmap:
- return v_cast<QBitmap>(d)->isNull();
- case QVariant::Region:
- return v_cast<QRegion>(d)->isEmpty();
- case QVariant::Polygon:
- return v_cast<QPolygon>(d)->isEmpty();
- case QVariant::Pixmap:
- return v_cast<QPixmap>(d)->isNull();
- case QVariant::Image:
- return v_cast<QImage>(d)->isNull();
- case QVariant::Matrix:
- case QVariant::TextFormat:
- case QVariant::TextLength:
- case QVariant::Cursor:
- case QVariant::StringList:
- case QVariant::Font:
- case QVariant::Brush:
- case QVariant::Color:
- case QVariant::Palette:
- case QVariant::SizePolicy:
-#ifndef QT_NO_SHORTCUT
- case QVariant::KeySequence:
-#endif
- case QVariant::Pen:
-#ifndef QT_NO_MATRIX4X4
- case QVariant::Matrix4x4:
-#endif
- break;
-#ifndef QT_NO_VECTOR2D
- case QVariant::Vector2D:
- return v_cast<QVector2D>(d)->isNull();
-#endif
-#ifndef QT_NO_VECTOR3D
- case QVariant::Vector3D:
- return v_cast<QVector3D>(d)->isNull();
-#endif
-#ifndef QT_NO_VECTOR4D
- case QVariant::Vector4D:
- return v_cast<QVector4D>(d)->isNull();
-#endif
-#ifndef QT_NO_QUATERNION
- case QVariant::Quaternion:
- return v_cast<QQuaternion>(d)->isNull();
-#endif
- case QVariant::Icon:
- if (qt_widgets_variant_handler)
- return qt_widgets_variant_handler->isNull(d);
- break;
- default:
- return qcoreVariantHandler()->isNull(d);
- }
- return d->is_null;
+ QGuiVariantIsNull<CoreAndGuiTypesFilter> isNull(d);
+ return QMetaTypeSwitcher::switcher<bool>(isNull, d->type, 0);
}
-static bool compare(const QVariant::Private *a, const QVariant::Private *b)
-{
- Q_ASSERT(a->type == b->type);
- switch(a->type) {
- case QVariant::Cursor:
+// This class is a hack that customizes access to QPixmap, QBitmap and QCursor
+template<class Filter>
+class QGuiVariantComparator : public QVariantComparator<Filter> {
+ typedef QVariantComparator<Filter> Base;
+public:
+ QGuiVariantComparator(const QVariant::Private *a, const QVariant::Private *b)
+ : QVariantComparator<Filter>(a, b)
+ {}
+ template<typename T>
+ bool delegate(const T *p)
+ {
+ if (Q_UNLIKELY(Base::m_a->type == QVariant::Icon || Base::m_a->type == QVariant::SizePolicy)) {
+ // TODO we need to clean up variant handlers, so they are replacament, not extension
+ if (Q_LIKELY(qt_widgets_variant_handler))
+ return qt_widgets_variant_handler->compare(Base::m_a, Base::m_b);
+ }
+ return Base::delegate(p);
+ }
+ bool delegate(const QPixmap*)
+ {
+ return v_cast<QPixmap>(Base::m_a)->cacheKey() == v_cast<QPixmap>(Base::m_b)->cacheKey();
+ }
+ bool delegate(const QBitmap*)
+ {
+ return v_cast<QBitmap>(Base::m_a)->cacheKey() == v_cast<QBitmap>(Base::m_b)->cacheKey();
+ }
#ifndef QT_NO_CURSOR
- return v_cast<QCursor>(a)->shape() == v_cast<QCursor>(b)->shape();
-#endif
- case QVariant::Bitmap:
- return v_cast<QBitmap>(a)->cacheKey()
- == v_cast<QBitmap>(b)->cacheKey();
- case QVariant::Polygon:
- return *v_cast<QPolygon>(a) == *v_cast<QPolygon>(b);
- case QVariant::Region:
- return *v_cast<QRegion>(a) == *v_cast<QRegion>(b);
- case QVariant::Font:
- return *v_cast<QFont>(a) == *v_cast<QFont>(b);
- case QVariant::Pixmap:
- return v_cast<QPixmap>(a)->cacheKey() == v_cast<QPixmap>(b)->cacheKey();
- case QVariant::Image:
- return *v_cast<QImage>(a) == *v_cast<QImage>(b);
- case QVariant::Brush:
- return *v_cast<QBrush>(a) == *v_cast<QBrush>(b);
- case QVariant::Color:
- return *v_cast<QColor>(a) == *v_cast<QColor>(b);
- case QVariant::Palette:
- return *v_cast<QPalette>(a) == *v_cast<QPalette>(b);
-#ifndef QT_NO_ICON
- case QVariant::Icon:
- /* QIcon::operator==() cannot be reasonably implemented for QIcon,
- * so we always return false. */
- return false;
-#endif
- case QVariant::Matrix:
- return *v_cast<QMatrix>(a) == *v_cast<QMatrix>(b);
- case QVariant::Transform:
- return *v_cast<QTransform>(a) == *v_cast<QTransform>(b);
- case QVariant::TextFormat:
- return *v_cast<QTextFormat>(a) == *v_cast<QTextFormat>(b);
- case QVariant::TextLength:
- return *v_cast<QTextLength>(a) == *v_cast<QTextLength>(b);
-#ifndef QT_NO_SHORTCUT
- case QVariant::KeySequence:
- return *v_cast<QKeySequence>(a) == *v_cast<QKeySequence>(b);
-#endif
- case QVariant::Pen:
- return *v_cast<QPen>(a) == *v_cast<QPen>(b);
-#ifndef QT_NO_MATRIX4X4
- case QVariant::Matrix4x4:
- return *v_cast<QMatrix4x4>(a) == *v_cast<QMatrix4x4>(b);
-#endif
-#ifndef QT_NO_VECTOR2D
- case QVariant::Vector2D:
- return *v_cast<QVector2D>(a) == *v_cast<QVector2D>(b);
-#endif
-#ifndef QT_NO_VECTOR3D
- case QVariant::Vector3D:
- return *v_cast<QVector3D>(a) == *v_cast<QVector3D>(b);
-#endif
-#ifndef QT_NO_VECTOR4D
- case QVariant::Vector4D:
- return *v_cast<QVector4D>(a) == *v_cast<QVector4D>(b);
-#endif
-#ifndef QT_NO_QUATERNION
- case QVariant::Quaternion:
- return *v_cast<QQuaternion>(a) == *v_cast<QQuaternion>(b);
-#endif
- case QVariant::SizePolicy:
- if (qt_widgets_variant_handler)
- return qt_widgets_variant_handler->compare(a, b);
- break;
- default:
- break;
+ bool delegate(const QCursor*)
+ {
+ return v_cast<QCursor>(Base::m_a)->shape() == v_cast<QCursor>(Base::m_b)->shape();
}
- return qcoreVariantHandler()->compare(a, b);
-}
-
+#endif
+ bool delegate(const void *p) { return Base::delegate(p); }
+};
+static bool compare(const QVariant::Private *a, const QVariant::Private *b)
+{
+ QGuiVariantComparator<CoreAndGuiTypesFilter> comparator(a, b);
+ return QMetaTypeSwitcher::switcher<bool>(comparator, a->type, 0);
+}
static bool convert(const QVariant::Private *d, QVariant::Type t,
void *result, bool *ok)