2753fca455497d95e26cd9dbcac3fa8e7baf7863
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativestringconverters.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qdeclarativestringconverters_p.h"
43
44 #include <QtGui/qcolor.h>
45 #include <QtGui/qvector3d.h>
46 #include <QtGui/qvector4d.h>
47 #include <QtCore/qpoint.h>
48 #include <QtCore/qrect.h>
49 #include <QtCore/qsize.h>
50 #include <QtCore/qvariant.h>
51 #include <QtCore/qdatetime.h>
52
53 QT_BEGIN_NAMESPACE
54
55 static uchar fromHex(const uchar c, const uchar c2)
56 {
57     uchar rv = 0;
58     if (c >= '0' && c <= '9')
59         rv += (c - '0') * 16;
60     else if (c >= 'A' && c <= 'F')
61         rv += (c - 'A' + 10) * 16;
62     else if (c >= 'a' && c <= 'f')
63         rv += (c - 'a' + 10) * 16;
64
65     if (c2 >= '0' && c2 <= '9')
66         rv += (c2 - '0');
67     else if (c2 >= 'A' && c2 <= 'F')
68         rv += (c2 - 'A' + 10);
69     else if (c2 >= 'a' && c2 <= 'f')
70         rv += (c2 - 'a' + 10);
71
72     return rv;
73 }
74
75 static uchar fromHex(const QString &s, int idx)
76 {
77     uchar c = s.at(idx).toAscii();
78     uchar c2 = s.at(idx + 1).toAscii();
79     return fromHex(c, c2);
80 }
81
82 QVariant QDeclarativeStringConverters::variantFromString(const QString &s)
83 {
84     if (s.isEmpty())
85         return QVariant(s);
86     bool ok = false;
87     QRectF r = rectFFromString(s, &ok);
88     if (ok) return QVariant(r);
89     QColor c = colorFromString(s, &ok);
90     if (ok) return QVariant(c);
91     QPointF p = pointFFromString(s, &ok);
92     if (ok) return QVariant(p);
93     QSizeF sz = sizeFFromString(s, &ok);
94     if (ok) return QVariant(sz);
95     QVector3D v = vector3DFromString(s, &ok);
96     if (ok) return QVariant::fromValue(v);
97     QVector4D v4 = vector4DFromString(s, &ok);
98     if (ok) return QVariant::fromValue(v4);
99
100     return QVariant(s);
101 }
102
103 QVariant QDeclarativeStringConverters::variantFromString(const QString &s, int preferredType, bool *ok)
104 {
105     switch (preferredType) {
106     case QMetaType::Int:
107         return QVariant(int(qRound(s.toDouble(ok))));
108     case QMetaType::UInt:
109         return QVariant(uint(qRound(s.toDouble(ok))));
110     case QMetaType::QColor:
111         return QVariant::fromValue(colorFromString(s, ok));
112 #ifndef QT_NO_DATESTRING
113     case QMetaType::QDate:
114         return QVariant::fromValue(dateFromString(s, ok));
115     case QMetaType::QTime:
116         return QVariant::fromValue(timeFromString(s, ok));
117     case QMetaType::QDateTime:
118         return QVariant::fromValue(dateTimeFromString(s, ok));
119 #endif // QT_NO_DATESTRING
120     case QMetaType::QPointF:
121         return QVariant::fromValue(pointFFromString(s, ok));
122     case QMetaType::QPoint:
123         return QVariant::fromValue(pointFFromString(s, ok).toPoint());
124     case QMetaType::QSizeF:
125         return QVariant::fromValue(sizeFFromString(s, ok));
126     case QMetaType::QSize:
127         return QVariant::fromValue(sizeFFromString(s, ok).toSize());
128     case QMetaType::QRectF:
129         return QVariant::fromValue(rectFFromString(s, ok));
130     case QMetaType::QRect:
131         return QVariant::fromValue(rectFFromString(s, ok).toRect());
132     case QMetaType::QVector3D:
133         return QVariant::fromValue(vector3DFromString(s, ok));
134     case QMetaType::QVector4D:
135         return QVariant::fromValue(vector4DFromString(s, ok));
136     default:
137         if (ok) *ok = false;
138         return QVariant();
139     }
140 }
141
142 QColor QDeclarativeStringConverters::colorFromString(const QString &s, bool *ok)
143 {
144     if (s.length() == 9 && s.startsWith(QLatin1Char('#'))) {
145         uchar a = fromHex(s, 1);
146         uchar r = fromHex(s, 3);
147         uchar g = fromHex(s, 5);
148         uchar b = fromHex(s, 7);
149         if (ok) *ok = true;
150         return QColor(r, g, b, a);
151     } else {
152         QColor rv(s);
153         if (ok) *ok = rv.isValid();
154         return rv;
155     }
156 }
157
158 #ifndef QT_NO_DATESTRING
159 QDate QDeclarativeStringConverters::dateFromString(const QString &s, bool *ok)
160 {
161     QDate d = QDate::fromString(s, Qt::ISODate);
162     if (ok) *ok =  d.isValid();
163     return d;
164 }
165
166 QTime QDeclarativeStringConverters::timeFromString(const QString &s, bool *ok)
167 {
168     QTime t = QTime::fromString(s, Qt::ISODate);
169     if (ok) *ok = t.isValid();
170     return t;
171 }
172
173 QDateTime QDeclarativeStringConverters::dateTimeFromString(const QString &s, bool *ok)
174 {
175     QDateTime d = QDateTime::fromString(s, Qt::ISODate);
176     if (ok) *ok =  d.isValid();
177     return d;
178 }
179 #endif // QT_NO_DATESTRING
180
181 //expects input of "x,y"
182 QPointF QDeclarativeStringConverters::pointFFromString(const QString &s, bool *ok)
183 {
184     if (s.count(QLatin1Char(',')) != 1) {
185         if (ok)
186             *ok = false;
187         return QPointF();
188     }
189
190     bool xGood, yGood;
191     int index = s.indexOf(QLatin1Char(','));
192     qreal xCoord = s.left(index).toDouble(&xGood);
193     qreal yCoord = s.mid(index+1).toDouble(&yGood);
194     if (!xGood || !yGood) {
195         if (ok)
196             *ok = false;
197         return QPointF();
198     }
199
200     if (ok)
201         *ok = true;
202     return QPointF(xCoord, yCoord);
203 }
204
205 //expects input of "widthxheight"
206 QSizeF QDeclarativeStringConverters::sizeFFromString(const QString &s, bool *ok)
207 {
208     if (s.count(QLatin1Char('x')) != 1) {
209         if (ok)
210             *ok = false;
211         return QSizeF();
212     }
213
214     bool wGood, hGood;
215     int index = s.indexOf(QLatin1Char('x'));
216     qreal width = s.left(index).toDouble(&wGood);
217     qreal height = s.mid(index+1).toDouble(&hGood);
218     if (!wGood || !hGood) {
219         if (ok)
220             *ok = false;
221         return QSizeF();
222     }
223
224     if (ok)
225         *ok = true;
226     return QSizeF(width, height);
227 }
228
229 //expects input of "x,y,widthxheight" //### use space instead of second comma?
230 QRectF QDeclarativeStringConverters::rectFFromString(const QString &s, bool *ok)
231 {
232     if (s.count(QLatin1Char(',')) != 2 || s.count(QLatin1Char('x')) != 1) {
233         if (ok)
234             *ok = false;
235         return QRectF();
236     }
237
238     bool xGood, yGood, wGood, hGood;
239     int index = s.indexOf(QLatin1Char(','));
240     qreal x = s.left(index).toDouble(&xGood);
241     int index2 = s.indexOf(QLatin1Char(','), index+1);
242     qreal y = s.mid(index+1, index2-index-1).toDouble(&yGood);
243     index = s.indexOf(QLatin1Char('x'), index2+1);
244     qreal width = s.mid(index2+1, index-index2-1).toDouble(&wGood);
245     qreal height = s.mid(index+1).toDouble(&hGood);
246     if (!xGood || !yGood || !wGood || !hGood) {
247         if (ok)
248             *ok = false;
249         return QRectF();
250     }
251
252     if (ok)
253         *ok = true;
254     return QRectF(x, y, width, height);
255 }
256
257 //expects input of "x,y,z"
258 QVector3D QDeclarativeStringConverters::vector3DFromString(const QString &s, bool *ok)
259 {
260     if (s.count(QLatin1Char(',')) != 2) {
261         if (ok)
262             *ok = false;
263         return QVector3D();
264     }
265
266     bool xGood, yGood, zGood;
267     int index = s.indexOf(QLatin1Char(','));
268     int index2 = s.indexOf(QLatin1Char(','), index+1);
269     qreal xCoord = s.left(index).toDouble(&xGood);
270     qreal yCoord = s.mid(index+1, index2-index-1).toDouble(&yGood);
271     qreal zCoord = s.mid(index2+1).toDouble(&zGood);
272     if (!xGood || !yGood || !zGood) {
273         if (ok)
274             *ok = false;
275         return QVector3D();
276     }
277
278     if (ok)
279         *ok = true;
280     return QVector3D(xCoord, yCoord, zCoord);
281 }
282
283 //expects input of "x,y,z,w"
284 QVector4D QDeclarativeStringConverters::vector4DFromString(const QString &s, bool *ok)
285 {
286     if (s.count(QLatin1Char(',')) != 3) {
287         if (ok)
288             *ok = false;
289         return QVector4D();
290     }
291
292     bool xGood, yGood, zGood, wGood;
293     int index = s.indexOf(QLatin1Char(','));
294     int index2 = s.indexOf(QLatin1Char(','), index+1);
295     int index3 = s.indexOf(QLatin1Char(','), index2+1);
296     qreal xCoord = s.left(index).toDouble(&xGood);
297     qreal yCoord = s.mid(index+1, index2-index-1).toDouble(&yGood);
298     qreal zCoord = s.mid(index2+1, index3-index2-1).toDouble(&zGood);
299     qreal wCoord = s.mid(index3+1).toDouble(&wGood);
300     if (!xGood || !yGood || !zGood || !wGood) {
301         if (ok)
302             *ok = false;
303         return QVector4D();
304     }
305
306     if (ok)
307         *ok = true;
308     return QVector4D(xCoord, yCoord, zCoord, wCoord);
309 }
310
311 QT_END_NAMESPACE