Merge remote-tracking branch 'gerrit/master' into newdocs
[profile/ivi/qtbase.git] / src / gui / kernel / qguivariant.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 // Gui types
43 #include "qbitmap.h"
44 #include "qbrush.h"
45 #include "qcolor.h"
46 #include "qcursor.h"
47 #include "qfont.h"
48 #include "qimage.h"
49 #include "qkeysequence.h"
50 #include "qtransform.h"
51 #include "qmatrix.h"
52 #include "qpalette.h"
53 #include "qpen.h"
54 #include "qpixmap.h"
55 #include "qpolygon.h"
56 #include "qregion.h"
57 #include "qtextformat.h"
58 #include "qmatrix4x4.h"
59 #include "qvector2d.h"
60 #include "qvector3d.h"
61 #include "qvector4d.h"
62 #include "qquaternion.h"
63 #include "qicon.h"
64
65 // Core types
66 #include "qvariant.h"
67 #include "qbitarray.h"
68 #include "qbytearray.h"
69 #include "qdatastream.h"
70 #include "qdebug.h"
71 #include "qmap.h"
72 #include "qdatetime.h"
73 #include "qeasingcurve.h"
74 #include "qlist.h"
75 #include "qstring.h"
76 #include "qstringlist.h"
77 #include "qurl.h"
78 #include "qlocale.h"
79 #include "quuid.h"
80
81 #ifndef QT_NO_GEOM_VARIANT
82 #include "qsize.h"
83 #include "qpoint.h"
84 #include "qrect.h"
85 #include "qline.h"
86 #endif
87
88 #include <float.h>
89
90 #include "private/qvariant_p.h"
91 #include <private/qmetatype_p.h>
92
93 QT_BEGIN_NAMESPACE
94
95 Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler();
96
97 namespace {
98 struct GuiTypesFilter {
99     template<typename T>
100     struct Acceptor {
101         static const bool IsAccepted = QModulesPrivate::QTypeModuleInfo<T>::IsGui && QtMetaTypePrivate::TypeDefinition<T>::IsAvailable;
102     };
103 };
104
105 static void construct(QVariant::Private *x, const void *copy)
106 {
107     const int type = x->type;
108     QVariantConstructor<GuiTypesFilter> constructor(x, copy);
109     QMetaTypeSwitcher::switcher<void>(constructor, type, 0);
110 }
111
112 static void clear(QVariant::Private *d)
113 {
114     QVariantDestructor<GuiTypesFilter> destructor(d);
115     QMetaTypeSwitcher::switcher<void>(destructor, d->type, 0);
116 }
117
118 // This class is a hack that customizes access to QPolygon
119 template<class Filter>
120 class QGuiVariantIsNull : public QVariantIsNull<Filter> {
121     typedef QVariantIsNull<Filter> Base;
122 public:
123     QGuiVariantIsNull(const QVariant::Private *d)
124         : QVariantIsNull<Filter>(d)
125     {}
126     template<typename T>
127     bool delegate(const T *p) { return Base::delegate(p); }
128     bool delegate(const QPolygon*) { return v_cast<QPolygon>(Base::m_d)->isEmpty(); }
129     bool delegate(const void *p) { return Base::delegate(p); }
130 };
131 static bool isNull(const QVariant::Private *d)
132 {
133     QGuiVariantIsNull<GuiTypesFilter> isNull(d);
134     return QMetaTypeSwitcher::switcher<bool>(isNull, d->type, 0);
135 }
136
137 // This class is a hack that customizes access to QPixmap, QBitmap, QCursor and QIcon
138 template<class Filter>
139 class QGuiVariantComparator : public QVariantComparator<Filter> {
140     typedef QVariantComparator<Filter> Base;
141 public:
142     QGuiVariantComparator(const QVariant::Private *a, const QVariant::Private *b)
143         : QVariantComparator<Filter>(a, b)
144     {}
145     template<typename T>
146     bool delegate(const T *p)
147     {
148         return Base::delegate(p);
149     }
150     bool delegate(const QPixmap*)
151     {
152         return v_cast<QPixmap>(Base::m_a)->cacheKey() == v_cast<QPixmap>(Base::m_b)->cacheKey();
153     }
154     bool delegate(const QBitmap*)
155     {
156         return v_cast<QBitmap>(Base::m_a)->cacheKey() == v_cast<QBitmap>(Base::m_b)->cacheKey();
157     }
158 #ifndef QT_NO_CURSOR
159     bool delegate(const QCursor*)
160     {
161         return v_cast<QCursor>(Base::m_a)->shape() == v_cast<QCursor>(Base::m_b)->shape();
162     }
163 #endif
164 #ifndef QT_NO_ICON
165     bool delegate(const QIcon *)
166     {
167         return false;
168     }
169 #endif
170     bool delegate(const void *p) { return Base::delegate(p); }
171 };
172
173 static bool compare(const QVariant::Private *a, const QVariant::Private *b)
174 {
175     QGuiVariantComparator<GuiTypesFilter> comparator(a, b);
176     return QMetaTypeSwitcher::switcher<bool>(comparator, a->type, 0);
177 }
178
179 static bool convert(const QVariant::Private *d, int t,
180                  void *result, bool *ok)
181 {
182     switch (t) {
183     case QVariant::ByteArray:
184         if (d->type == QVariant::Color) {
185             *static_cast<QByteArray *>(result) = v_cast<QColor>(d)->name().toLatin1();
186             return true;
187         }
188         break;
189     case QVariant::String: {
190         QString *str = static_cast<QString *>(result);
191         switch (d->type) {
192 #ifndef QT_NO_SHORTCUT
193         case QVariant::KeySequence:
194             *str = (*v_cast<QKeySequence>(d)).toString(QKeySequence::NativeText);
195             return true;
196 #endif
197         case QVariant::Font:
198             *str = v_cast<QFont>(d)->toString();
199             return true;
200         case QVariant::Color:
201             *str = v_cast<QColor>(d)->name();
202             return true;
203         default:
204             break;
205         }
206         break;
207     }
208     case QVariant::Pixmap:
209         if (d->type == QVariant::Image) {
210             *static_cast<QPixmap *>(result) = QPixmap::fromImage(*v_cast<QImage>(d));
211             return true;
212         } else if (d->type == QVariant::Bitmap) {
213             *static_cast<QPixmap *>(result) = *v_cast<QBitmap>(d);
214             return true;
215         } else if (d->type == QVariant::Brush) {
216             if (v_cast<QBrush>(d)->style() == Qt::TexturePattern) {
217                 *static_cast<QPixmap *>(result) = v_cast<QBrush>(d)->texture();
218                 return true;
219             }
220         }
221         break;
222     case QVariant::Image:
223         if (d->type == QVariant::Pixmap) {
224             *static_cast<QImage *>(result) = v_cast<QPixmap>(d)->toImage();
225             return true;
226         } else if (d->type == QVariant::Bitmap) {
227             *static_cast<QImage *>(result) = v_cast<QBitmap>(d)->toImage();
228             return true;
229         }
230         break;
231     case QVariant::Bitmap:
232         if (d->type == QVariant::Pixmap) {
233             *static_cast<QBitmap *>(result) = *v_cast<QPixmap>(d);
234             return true;
235         } else if (d->type == QVariant::Image) {
236             *static_cast<QBitmap *>(result) = QBitmap::fromImage(*v_cast<QImage>(d));
237             return true;
238         }
239         break;
240 #ifndef QT_NO_SHORTCUT
241     case QVariant::Int:
242         if (d->type == QVariant::KeySequence) {
243             const QKeySequence &seq = *v_cast<QKeySequence>(d);
244             *static_cast<int *>(result) = seq.isEmpty() ? 0 : seq[0];
245             return true;
246         }
247         break;
248 #endif
249     case QVariant::Font:
250         if (d->type == QVariant::String) {
251             QFont *f = static_cast<QFont *>(result);
252             f->fromString(*v_cast<QString>(d));
253             return true;
254         }
255         break;
256     case QVariant::Color:
257         if (d->type == QVariant::String) {
258             static_cast<QColor *>(result)->setNamedColor(*v_cast<QString>(d));
259             return static_cast<QColor *>(result)->isValid();
260         } else if (d->type == QVariant::ByteArray) {
261             static_cast<QColor *>(result)->setNamedColor(QString::fromLatin1(
262                                 *v_cast<QByteArray>(d)));
263             return true;
264         } else if (d->type == QVariant::Brush) {
265             if (v_cast<QBrush>(d)->style() == Qt::SolidPattern) {
266                 *static_cast<QColor *>(result) = v_cast<QBrush>(d)->color();
267                 return true;
268             }
269         }
270         break;
271     case QVariant::Brush:
272         if (d->type == QVariant::Color) {
273             *static_cast<QBrush *>(result) = QBrush(*v_cast<QColor>(d));
274             return true;
275         } else if (d->type == QVariant::Pixmap) {
276             *static_cast<QBrush *>(result) = QBrush(*v_cast<QPixmap>(d));
277             return true;
278         }
279         break;
280 #ifndef QT_NO_SHORTCUT
281     case QVariant::KeySequence: {
282         QKeySequence *seq = static_cast<QKeySequence *>(result);
283         switch (d->type) {
284         case QVariant::String:
285             *seq = QKeySequence(*v_cast<QString>(d));
286             return true;
287         case QVariant::Int:
288             *seq = QKeySequence(d->data.i);
289             return true;
290         default:
291             break;
292         }
293     }
294 #endif
295 #ifndef QT_NO_ICON
296     case QVariant::Icon: {
297         if (ok)
298             *ok = false;
299         return false;
300     }
301 #endif
302     default:
303         break;
304     }
305     return qcoreVariantHandler()->convert(d, t, result, ok);
306 }
307
308 #if !defined(QT_NO_DEBUG_STREAM)
309 static void streamDebug(QDebug dbg, const QVariant &v)
310 {
311     QVariant::Private *d = const_cast<QVariant::Private *>(&v.data_ptr());
312     QVariantDebugStream<GuiTypesFilter> stream(dbg, d);
313     QMetaTypeSwitcher::switcher<void>(stream, d->type, 0);
314 }
315 #endif
316
317 const QVariant::Handler qt_gui_variant_handler = {
318     construct,
319     clear,
320     isNull,
321 #ifndef QT_NO_DATASTREAM
322     0,
323     0,
324 #endif
325     compare,
326     convert,
327     0,
328 #if !defined(QT_NO_DEBUG_STREAM)
329     streamDebug
330 #else
331     0
332 #endif
333 };
334
335 #define QT_IMPL_METATYPEINTERFACE_GUI_TYPES(MetaTypeName, MetaTypeId, RealName) \
336     QT_METATYPE_INTERFACE_INIT(RealName),
337
338 static const QMetaTypeInterface qVariantGuiHelper[] = {
339     QT_FOR_EACH_STATIC_GUI_CLASS(QT_IMPL_METATYPEINTERFACE_GUI_TYPES)
340 };
341
342 #undef QT_IMPL_METATYPEINTERFACE_GUI_TYPES
343 } // namespace used to hide QVariant handler
344
345 extern Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper;
346
347 void qRegisterGuiVariant()
348 {
349     QVariantPrivate::registerHandler(QModulesPrivate::Gui, &qt_gui_variant_handler);
350     qMetaTypeGuiHelper = qVariantGuiHelper;
351 }
352 Q_CONSTRUCTOR_FUNCTION(qRegisterGuiVariant)
353
354 QT_END_NAMESPACE