1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
49 #include "qdatastream.h"
53 #include "qkeysequence.h"
54 #include "qtransform.h"
61 #include "qtextformat.h"
62 #include "qmatrix4x4.h"
63 #include "qvector2d.h"
64 #include "qvector3d.h"
65 #include "qvector4d.h"
66 #include "qquaternion.h"
70 #include "qbitarray.h"
71 #include "qbytearray.h"
72 #include "qdatastream.h"
75 #include "qdatetime.h"
76 #include "qeasingcurve.h"
79 #include "qstringlist.h"
84 #ifndef QT_NO_GEOM_VARIANT
93 #include "private/qvariant_p.h"
94 #include <private/qmetatype_p.h>
98 Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler();
102 struct TypeDefinition {
103 static const bool IsAvailable = true;
105 // Ignore these types, as incomplete
106 #ifdef QT_NO_GEOM_VARIANT
107 template<> struct TypeDefinition<QRect> { static const bool IsAvailable = false; };
108 template<> struct TypeDefinition<QRectF> { static const bool IsAvailable = false; };
109 template<> struct TypeDefinition<QSize> { static const bool IsAvailable = false; };
110 template<> struct TypeDefinition<QSizeF> { static const bool IsAvailable = false; };
111 template<> struct TypeDefinition<QLine> { static const bool IsAvailable = false; };
112 template<> struct TypeDefinition<QLineF> { static const bool IsAvailable = false; };
113 template<> struct TypeDefinition<QPoint> { static const bool IsAvailable = false; };
114 template<> struct TypeDefinition<QPointF> { static const bool IsAvailable = false; };
116 #ifdef QT_NO_SHORTCUT
117 template<> struct TypeDefinition<QKeySequence> { static const bool IsAvailable = false; };
120 template<> struct TypeDefinition<QCursor> { static const bool IsAvailable = false; };
122 #ifdef QT_NO_MATRIX4X4
123 template<> struct TypeDefinition<QMatrix4x4> { static const bool IsAvailable = false; };
125 #ifdef QT_NO_VECTOR2D
126 template<> struct TypeDefinition<QVector2D> { static const bool IsAvailable = false; };
128 #ifdef QT_NO_VECTOR3D
129 template<> struct TypeDefinition<QVector3D> { static const bool IsAvailable = false; };
131 #ifdef QT_NO_VECTOR4D
132 template<> struct TypeDefinition<QVector4D> { static const bool IsAvailable = false; };
134 #ifdef QT_NO_QUATERNION
135 template<> struct TypeDefinition<QQuaternion> { static const bool IsAvailable = false; };
138 struct GuiTypesFilter {
141 static const bool IsAccepted = QTypeModuleInfo<T>::IsGui && TypeDefinition<T>::IsAvailable;
144 } // namespace used to hide TypeDefinition
147 static void construct(QVariant::Private *x, const void *copy)
149 const int type = x->type;
150 if (Q_UNLIKELY(type == 62)) {
151 // small 'trick' to let a QVariant(Qt::blue) create a variant
153 // TODO Get rid of this hack.
154 x->type = QVariant::Color;
155 QColor color(*reinterpret_cast<const Qt::GlobalColor *>(copy));
156 v_construct<QColor>(x, &color);
159 QVariantConstructor<GuiTypesFilter> constructor(x, copy);
160 QMetaTypeSwitcher::switcher<void>(constructor, type, 0);
163 static void clear(QVariant::Private *d)
165 QVariantDestructor<GuiTypesFilter> destructor(d);
166 QMetaTypeSwitcher::switcher<void>(destructor, d->type, 0);
169 // This class is a hack that customizes access to QPolygon
170 template<class Filter>
171 class QGuiVariantIsNull : public QVariantIsNull<Filter> {
172 typedef QVariantIsNull<Filter> Base;
174 QGuiVariantIsNull(const QVariant::Private *d)
175 : QVariantIsNull<Filter>(d)
178 bool delegate(const T *p) { return Base::delegate(p); }
179 bool delegate(const QPolygon*) { return v_cast<QPolygon>(Base::m_d)->isEmpty(); }
180 bool delegate(const void *p) { return Base::delegate(p); }
182 static bool isNull(const QVariant::Private *d)
184 QGuiVariantIsNull<GuiTypesFilter> isNull(d);
185 return QMetaTypeSwitcher::switcher<bool>(isNull, d->type, 0);
188 // This class is a hack that customizes access to QPixmap, QBitmap and QCursor
189 template<class Filter>
190 class QGuiVariantComparator : public QVariantComparator<Filter> {
191 typedef QVariantComparator<Filter> Base;
193 QGuiVariantComparator(const QVariant::Private *a, const QVariant::Private *b)
194 : QVariantComparator<Filter>(a, b)
197 bool delegate(const T *p)
199 return Base::delegate(p);
201 bool delegate(const QPixmap*)
203 return v_cast<QPixmap>(Base::m_a)->cacheKey() == v_cast<QPixmap>(Base::m_b)->cacheKey();
205 bool delegate(const QBitmap*)
207 return v_cast<QBitmap>(Base::m_a)->cacheKey() == v_cast<QBitmap>(Base::m_b)->cacheKey();
210 bool delegate(const QCursor*)
212 return v_cast<QCursor>(Base::m_a)->shape() == v_cast<QCursor>(Base::m_b)->shape();
215 bool delegate(const void *p) { return Base::delegate(p); }
218 static bool compare(const QVariant::Private *a, const QVariant::Private *b)
220 QGuiVariantComparator<GuiTypesFilter> comparator(a, b);
221 return QMetaTypeSwitcher::switcher<bool>(comparator, a->type, 0);
224 static bool convert(const QVariant::Private *d, int t,
225 void *result, bool *ok)
228 case QVariant::ByteArray:
229 if (d->type == QVariant::Color) {
230 *static_cast<QByteArray *>(result) = v_cast<QColor>(d)->name().toLatin1();
234 case QVariant::String: {
235 QString *str = static_cast<QString *>(result);
237 #ifndef QT_NO_SHORTCUT
238 case QVariant::KeySequence:
239 *str = QString(*v_cast<QKeySequence>(d));
243 *str = v_cast<QFont>(d)->toString();
245 case QVariant::Color:
246 *str = v_cast<QColor>(d)->name();
253 case QVariant::Pixmap:
254 if (d->type == QVariant::Image) {
255 *static_cast<QPixmap *>(result) = QPixmap::fromImage(*v_cast<QImage>(d));
257 } else if (d->type == QVariant::Bitmap) {
258 *static_cast<QPixmap *>(result) = *v_cast<QBitmap>(d);
260 } else if (d->type == QVariant::Brush) {
261 if (v_cast<QBrush>(d)->style() == Qt::TexturePattern) {
262 *static_cast<QPixmap *>(result) = v_cast<QBrush>(d)->texture();
267 case QVariant::Image:
268 if (d->type == QVariant::Pixmap) {
269 *static_cast<QImage *>(result) = v_cast<QPixmap>(d)->toImage();
271 } else if (d->type == QVariant::Bitmap) {
272 *static_cast<QImage *>(result) = v_cast<QBitmap>(d)->toImage();
276 case QVariant::Bitmap:
277 if (d->type == QVariant::Pixmap) {
278 *static_cast<QBitmap *>(result) = *v_cast<QPixmap>(d);
280 } else if (d->type == QVariant::Image) {
281 *static_cast<QBitmap *>(result) = QBitmap::fromImage(*v_cast<QImage>(d));
285 #ifndef QT_NO_SHORTCUT
287 if (d->type == QVariant::KeySequence) {
288 *static_cast<int *>(result) = (int)(*(v_cast<QKeySequence>(d)));
294 if (d->type == QVariant::String) {
295 QFont *f = static_cast<QFont *>(result);
296 f->fromString(*v_cast<QString>(d));
300 case QVariant::Color:
301 if (d->type == QVariant::String) {
302 static_cast<QColor *>(result)->setNamedColor(*v_cast<QString>(d));
303 return static_cast<QColor *>(result)->isValid();
304 } else if (d->type == QVariant::ByteArray) {
305 static_cast<QColor *>(result)->setNamedColor(QString::fromLatin1(
306 *v_cast<QByteArray>(d)));
308 } else if (d->type == QVariant::Brush) {
309 if (v_cast<QBrush>(d)->style() == Qt::SolidPattern) {
310 *static_cast<QColor *>(result) = v_cast<QBrush>(d)->color();
315 case QVariant::Brush:
316 if (d->type == QVariant::Color) {
317 *static_cast<QBrush *>(result) = QBrush(*v_cast<QColor>(d));
319 } else if (d->type == QVariant::Pixmap) {
320 *static_cast<QBrush *>(result) = QBrush(*v_cast<QPixmap>(d));
324 #ifndef QT_NO_SHORTCUT
325 case QVariant::KeySequence: {
326 QKeySequence *seq = static_cast<QKeySequence *>(result);
328 case QVariant::String:
329 *seq = QKeySequence(*v_cast<QString>(d));
332 *seq = QKeySequence(d->data.i);
342 return qcoreVariantHandler()->convert(d, t, result, ok);
345 #if !defined(QT_NO_DEBUG_STREAM)
346 static void streamDebug(QDebug dbg, const QVariant &v)
348 QVariant::Private *d = const_cast<QVariant::Private *>(&v.data_ptr());
349 QVariantDebugStream<GuiTypesFilter> stream(dbg, d);
350 QMetaTypeSwitcher::switcher<void>(stream, d->type, 0);
354 const QVariant::Handler qt_gui_variant_handler = {
358 #ifndef QT_NO_DATASTREAM
365 #if !defined(QT_NO_DEBUG_STREAM)
372 #define QT_IMPL_METATYPEINTERFACE_GUI_TYPES(MetaTypeName, MetaTypeId, RealName) \
373 QT_METATYPE_INTERFACE_INIT(RealName),
375 static const QMetaTypeInterface qVariantGuiHelper[] = {
376 QT_FOR_EACH_STATIC_GUI_CLASS(QT_IMPL_METATYPEINTERFACE_GUI_TYPES)
379 #undef QT_IMPL_METATYPEINTERFACE_GUI_TYPES
380 } // namespace used to hide QVariant handler
382 extern Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper;
384 void qRegisterGuiVariant()
386 QVariantPrivate::registerHandler(QModulesPrivate::Gui, &qt_gui_variant_handler);
387 qMetaTypeGuiHelper = qVariantGuiHelper;
389 Q_CONSTRUCTOR_FUNCTION(qRegisterGuiVariant)
391 void qUnregisterGuiVariant()
393 QVariantPrivate::unregisterHandler(QModulesPrivate::Gui);
394 qMetaTypeGuiHelper = 0;
396 Q_DESTRUCTOR_FUNCTION(qUnregisterGuiVariant)