6869d480d5bfa18fe41fab89d83cfcaed6045511
[profile/ivi/qtdeclarative.git] / src / quick / util / qquickglobal.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <private/qquickvaluetypes_p.h>
43 #include <private/qquickapplication_p.h>
44 #include <private/qqmlglobal_p.h>
45
46 #include <QtGui/QGuiApplication>
47 #include <QtGui/qdesktopservices.h>
48 #include <QtGui/qfontdatabase.h>
49
50
51 QT_BEGIN_NAMESPACE
52
53 class QQuickColorProvider : public QQmlColorProvider
54 {
55 public:
56     static inline QColor QColorFromString(const QString &s)
57     {
58         // Should we also handle #rrggbb here?
59         if (s.length() == 9 && s.startsWith(QLatin1Char('#'))) {
60             uchar a = fromHex(s, 1);
61             uchar r = fromHex(s, 3);
62             uchar g = fromHex(s, 5);
63             uchar b = fromHex(s, 7);
64             return QColor(r, g, b, a);
65         }
66
67         return QColor(s);
68     }
69
70     QVariant colorFromString(const QString &s, bool *ok)
71     {
72         QColor c(QColorFromString(s));
73         if (c.isValid()) {
74             if (ok) *ok = true;
75             return QVariant(c);
76         }
77
78         if (ok) *ok = false;
79         return QVariant();
80     }
81
82     unsigned rgbaFromString(const QString &s, bool *ok)
83     {
84         QColor c(QColorFromString(s));
85         if (c.isValid()) {
86             if (ok) *ok = true;
87             return c.rgba();
88         }
89
90         if (ok) *ok = false;
91         return 0;
92     }
93
94     QString stringFromRgba(unsigned rgba)
95     {
96         QColor c(QColor::fromRgba(rgba));
97         if (c.isValid()) {
98             return QVariant(c).toString();
99         }
100
101         return QString();
102     }
103
104     QVariant fromRgbF(double r, double g, double b, double a)
105     {
106         return QVariant(QColor::fromRgbF(r, g, b, a));
107     }
108
109     QVariant fromHslF(double h, double s, double l, double a)
110     {
111         return QVariant(QColor::fromHslF(h, s, l, a));
112     }
113
114     QVariant lighter(const QVariant &var, qreal factor)
115     {
116         QColor color = var.value<QColor>();
117         color = color.lighter(int(qRound(factor*100.)));
118         return QVariant::fromValue(color);
119     }
120
121     QVariant darker(const QVariant &var, qreal factor)
122     {
123         QColor color = var.value<QColor>();
124         color = color.darker(int(qRound(factor*100.)));
125         return QVariant::fromValue(color);
126     }
127
128     QVariant tint(const QVariant &baseVar, const QVariant &tintVar)
129     {
130         QColor tintColor = tintVar.value<QColor>();
131
132         int tintAlpha = tintColor.alpha();
133         if (tintAlpha == 0xFF) {
134             return tintVar;
135         } else if (tintAlpha == 0x00) {
136             return baseVar;
137         }
138
139         // tint the base color and return the final color
140         QColor baseColor = baseVar.value<QColor>();
141         qreal a = tintColor.alphaF();
142         qreal inv_a = 1.0 - a;
143
144         qreal r = tintColor.redF() * a + baseColor.redF() * inv_a;
145         qreal g = tintColor.greenF() * a + baseColor.greenF() * inv_a;
146         qreal b = tintColor.blueF() * a + baseColor.blueF() * inv_a;
147
148         return QVariant::fromValue(QColor::fromRgbF(r, g, b, a + inv_a * baseColor.alphaF()));
149     }
150
151 private:
152     static uchar fromHex(const uchar c, const uchar c2)
153     {
154         uchar rv = 0;
155         if (c >= '0' && c <= '9')
156             rv += (c - '0') * 16;
157         else if (c >= 'A' && c <= 'F')
158             rv += (c - 'A' + 10) * 16;
159         else if (c >= 'a' && c <= 'f')
160             rv += (c - 'a' + 10) * 16;
161
162         if (c2 >= '0' && c2 <= '9')
163             rv += (c2 - '0');
164         else if (c2 >= 'A' && c2 <= 'F')
165             rv += (c2 - 'A' + 10);
166         else if (c2 >= 'a' && c2 <= 'f')
167             rv += (c2 - 'a' + 10);
168
169         return rv;
170     }
171
172     static inline uchar fromHex(const QString &s, int idx)
173     {
174         uchar c = s.at(idx).toAscii();
175         uchar c2 = s.at(idx + 1).toAscii();
176         return fromHex(c, c2);
177     }
178 };
179
180
181 // Note: The functions in this class provide handling only for the types
182 // that the QML engine will currently actually call them for, so many
183 // appear incompletely implemented.  For some functions, the implementation
184 // would be obvious, but for others (particularly create and createFromString)
185 // the exact semantics are unknown.  For this reason unused functionality
186 // has been omitted.
187
188 class QQuickValueTypeProvider : public QQmlValueTypeProvider
189 {
190 public:
191     static QVector3D vector3DFromString(const QString &s, bool *ok)
192     {
193         if (s.count(QLatin1Char(',')) == 2) {
194             int index = s.indexOf(QLatin1Char(','));
195             int index2 = s.indexOf(QLatin1Char(','), index+1);
196
197             bool xGood, yGood, zGood;
198             qreal xCoord = s.left(index).toDouble(&xGood);
199             qreal yCoord = s.mid(index+1, index2-index-1).toDouble(&yGood);
200             qreal zCoord = s.mid(index2+1).toDouble(&zGood);
201
202             if (xGood && yGood && zGood) {
203                 if (ok) *ok = true;
204                 return QVector3D(xCoord, yCoord, zCoord);
205             }
206         }
207
208         if (ok) *ok = false;
209         return QVector3D();
210     }
211
212     static QVector4D vector4DFromString(const QString &s, bool *ok)
213     {
214         if (s.count(QLatin1Char(',')) == 3) {
215             int index = s.indexOf(QLatin1Char(','));
216             int index2 = s.indexOf(QLatin1Char(','), index+1);
217             int index3 = s.indexOf(QLatin1Char(','), index2+1);
218
219             bool xGood, yGood, zGood, wGood;
220             qreal xCoord = s.left(index).toDouble(&xGood);
221             qreal yCoord = s.mid(index+1, index2-index-1).toDouble(&yGood);
222             qreal zCoord = s.mid(index2+1, index3-index2-1).toDouble(&zGood);
223             qreal wCoord = s.mid(index3+1).toDouble(&wGood);
224
225             if (xGood && yGood && zGood && wGood) {
226                 if (ok) *ok = true;
227                 return QVector4D(xCoord, yCoord, zCoord, wCoord);
228             }
229         }
230
231         if (ok) *ok = false;
232         return QVector4D();
233     }
234
235     bool create(int type, QQmlValueType *&v)
236     {
237         switch (type) {
238         case QMetaType::QColor:
239             v = new QQuickColorValueType;
240             return true;
241         case QMetaType::QVector2D:
242             v = new QQuickVector2DValueType;
243             return true;
244         case QMetaType::QVector3D:
245             v = new QQuickVector3DValueType;
246             return true;
247         case QMetaType::QVector4D:
248             v = new QQuickVector4DValueType;
249             return true;
250         case QMetaType::QQuaternion:
251             v = new QQuickQuaternionValueType;
252             return true;
253         case QMetaType::QMatrix4x4:
254             v = new QQuickMatrix4x4ValueType;
255             return true;
256         case QMetaType::QFont:
257             v = new QQuickFontValueType;
258             return true;
259         default:
260             return false;
261         }
262     }
263
264     bool init(int type, void *data, size_t n)
265     {
266         if (type == QMetaType::QColor) {
267             Q_ASSERT(n >= sizeof(QColor));
268             QColor *color = reinterpret_cast<QColor *>(data);
269             new (color) QColor();
270             return true;
271         }
272
273         return false;
274     }
275
276     bool destroy(int type, void *data, size_t n)
277     {
278         if (type == QMetaType::QColor) {
279             Q_ASSERT(n >= sizeof(QColor));
280             QColor *color = reinterpret_cast<QColor *>(data);
281             color->~QColor();
282             return true;
283         }
284
285         return false;
286     }
287
288     bool copy(int type, const void *src, void *dst, size_t n)
289     {
290         if (type == QMetaType::QColor) {
291             Q_ASSERT(n >= sizeof(QColor));
292             const QColor *srcColor = reinterpret_cast<const QColor *>(src);
293             QColor *dstColor = reinterpret_cast<QColor *>(dst);
294             new (dstColor) QColor(*srcColor);
295             return true;
296         }
297
298         return false;
299     }
300
301     bool create(int type, int argc, const void *argv[], QVariant *v)
302     {
303         switch (type) {
304         case QMetaType::QVector3D:
305             if (argc == 1) {
306                 const float *xyz = reinterpret_cast<const float*>(argv[0]);
307                 QVector3D v3(xyz[0], xyz[1], xyz[2]);
308                 *v = QVariant(v3);
309                 return true;
310             }
311             break;
312         case QMetaType::QVector4D:
313             if (argc == 1) {
314                 const float *xyzw = reinterpret_cast<const float*>(argv[0]);
315                 QVector4D v4(xyzw[0], xyzw[1], xyzw[2], xyzw[3]);
316                 *v = QVariant(v4);
317                 return true;
318             }
319             break;
320         }
321
322         return false;
323     }
324
325     bool createFromString(int type, const QString &s, void *data, size_t n)
326     {
327         bool ok = false;
328
329         switch (type) {
330         case QMetaType::QColor:
331             {
332             Q_ASSERT(n >= sizeof(QColor));
333             QColor *color = reinterpret_cast<QColor *>(data);
334             new (color) QColor(QQuickColorProvider::QColorFromString(s));
335             return true;
336             }
337         case QMetaType::QVector3D:
338             {
339             Q_ASSERT(n >= sizeof(QVector3D));
340             QVector3D *v3 = reinterpret_cast<QVector3D *>(data);
341             new (v3) QVector3D(vector3DFromString(s, &ok));
342             return true;
343             }
344         case QMetaType::QVector4D:
345             {
346             Q_ASSERT(n >= sizeof(QVector4D));
347             QVector4D *v4 = reinterpret_cast<QVector4D *>(data);
348             new (v4) QVector4D(vector4DFromString(s, &ok));
349             return true;
350             }
351         }
352
353         return false;
354     }
355
356     bool createStringFrom(int type, const void *data, QString *s)
357     {
358         if (type == QMetaType::QColor) {
359             const QColor *color = reinterpret_cast<const QColor *>(data);
360             new (s) QString(QVariant(*color).toString());
361             return true;
362         }
363
364         return false;
365     }
366
367     bool variantFromString(const QString &s, QVariant *v)
368     {
369         QColor c(QQuickColorProvider::QColorFromString(s));
370         if (c.isValid()) {
371             *v = QVariant::fromValue(c);
372             return true;
373         }
374
375         bool ok = false;
376
377         QVector3D v3 = vector3DFromString(s, &ok);
378         if (ok) {
379             *v = QVariant::fromValue(v3);
380             return true;
381         }
382
383         QVector4D v4 = vector4DFromString(s, &ok);
384         if (ok) {
385             *v = QVariant::fromValue(v4);
386             return true;
387         }
388
389         return false;
390     }
391
392     bool variantFromString(int type, const QString &s, QVariant *v)
393     {
394         bool ok = false;
395
396         switch (type) {
397         case QMetaType::QColor:
398             {
399             QColor c(QQuickColorProvider::QColorFromString(s));
400             *v = QVariant::fromValue(c);
401             return true;
402             }
403         case QMetaType::QVector3D:
404             *v = QVariant::fromValue(vector3DFromString(s, &ok));
405             return true;
406         case QMetaType::QVector4D:
407             *v = QVariant::fromValue(vector4DFromString(s, &ok));
408             return true;
409         }
410
411         return false;
412     }
413
414     template<typename T>
415     bool typedEqual(const void *lhs, const void *rhs)
416     {
417         return (*(reinterpret_cast<const T *>(lhs)) == *(reinterpret_cast<const T *>(rhs)));
418     }
419
420     bool equal(int type, const void *lhs, const void *rhs)
421     {
422         switch (type) {
423         case QMetaType::QColor:
424             return typedEqual<QColor>(lhs, rhs);
425         case QMetaType::QVector3D:
426             return typedEqual<QVector3D>(lhs, rhs);
427         case QMetaType::QVector4D:
428             return typedEqual<QVector4D>(lhs, rhs);
429         }
430
431         return false;
432     }
433
434     bool store(int type, const void *src, void *dst, size_t n)
435     {
436         switch (type) {
437         case QMetaType::QColor:
438             {
439             Q_ASSERT(n >= sizeof(QColor));
440             const QRgb *rgb = reinterpret_cast<const QRgb *>(src);
441             QColor *color = reinterpret_cast<QColor *>(dst);
442             new (color) QColor(QColor::fromRgba(*rgb));
443             return true;
444             }
445         case QMetaType::QVector3D:
446             {
447             Q_ASSERT(n >= sizeof(QVector3D));
448             const QVector3D *srcVector = reinterpret_cast<const QVector3D *>(src);
449             QVector3D *dstVector = reinterpret_cast<QVector3D *>(dst);
450             new (dstVector) QVector3D(*srcVector);
451             return true;
452             }
453         case QMetaType::QVector4D:
454             {
455             Q_ASSERT(n >= sizeof(QVector4D));
456             const QVector4D *srcVector = reinterpret_cast<const QVector4D *>(src);
457             QVector4D *dstVector = reinterpret_cast<QVector4D *>(dst);
458             new (dstVector) QVector4D(*srcVector);
459             return true;
460             }
461         }
462
463         return false;
464     }
465
466     bool read(int srcType, const void *src, int dstType, void *dst)
467     {
468         if (dstType == QMetaType::QColor) {
469             QColor *dstColor = reinterpret_cast<QColor *>(dst);
470             if (srcType == QMetaType::QColor) {
471                 const QColor *srcColor = reinterpret_cast<const QColor *>(src);
472                 *dstColor = *srcColor;
473             } else {
474                 *dstColor = QColor();
475             }
476             return true;
477         }
478
479         return false;
480     }
481
482     bool write(int type, const void *src, void *dst, size_t n)
483     {
484         if (type == QMetaType::QColor) {
485             Q_ASSERT(n >= sizeof(QColor));
486             const QColor *srcColor = reinterpret_cast<const QColor *>(src);
487             QColor *dstColor = reinterpret_cast<QColor *>(dst);
488             if (*dstColor != *srcColor) {
489                 *dstColor = *srcColor;
490                 return true;
491             }
492         }
493
494         return false;
495     }
496 };
497
498
499 class QQuickGuiProvider : public QQmlGuiProvider
500 {
501 public:
502     QQuickApplication *application(QObject *parent)
503     {
504         return new QQuickApplication(parent);
505     }
506
507     QInputMethod *inputMethod()
508     {
509         return qGuiApp->inputMethod();
510     }
511
512     QStringList fontFamilies()
513     {
514         QFontDatabase database;
515         return database.families();
516     }
517
518     bool openUrlExternally(QUrl &url)
519     {
520 #ifndef QT_NO_DESKTOPSERVICES
521         return QDesktopServices::openUrl(url);
522 #else
523         return false;
524 #endif
525     }
526 };
527
528
529 static QQuickValueTypeProvider *getValueTypeProvider()
530 {
531     static QQuickValueTypeProvider valueTypeProvider;
532     return &valueTypeProvider;
533 }
534
535 static QQuickColorProvider *getColorProvider()
536 {
537     static QQuickColorProvider colorProvider;
538     return &colorProvider;
539 }
540
541 static QQuickGuiProvider *getGuiProvider()
542 {
543     static QQuickGuiProvider guiProvider;
544     return &guiProvider;
545 }
546
547 static bool initializeProviders()
548 {
549     QQml_addValueTypeProvider(getValueTypeProvider());
550     QQml_setColorProvider(getColorProvider());
551     QQml_setGuiProvider(getGuiProvider());
552     return true;
553 }
554
555 static bool initialized = initializeProviders();
556
557 QT_END_NAMESPACE