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 QtDeclarative 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 ****************************************************************************/
42 #include "qdeclarativebuiltinfunctions_p.h"
44 #include <QtDeclarative/qdeclarativecomponent.h>
45 #include <private/qdeclarativeengine_p.h>
46 #include <private/qdeclarativecomponent_p.h>
47 #include <private/qdeclarativestringconverters_p.h>
48 #include <private/qdeclarativelocale_p.h>
49 #include <private/qv8engine_p.h>
51 #include <private/qv8profilerservice_p.h>
52 #include <private/qdeclarativedebugtrace_p.h>
54 #include <QtCore/qstring.h>
55 #include <QtCore/qdatetime.h>
56 #include <QtCore/qcryptographichash.h>
57 #include <QtCore/qrect.h>
58 #include <QtCore/qsize.h>
59 #include <QtCore/qpoint.h>
60 #include <QtCore/qurl.h>
61 #include <QtCore/qfile.h>
62 #include <QtCore/qcoreapplication.h>
64 #include <QtGui/qcolor.h>
65 #include <QtGui/qvector3d.h>
66 #include <QtGui/qvector4d.h>
67 #include <QtGui/qdesktopservices.h>
68 #include <QtGui/qfontdatabase.h>
72 // send more information such as file, line etc for console APIs
73 DEFINE_BOOL_CONFIG_OPTION(qmlConsoleExtended, QML_CONSOLE_EXTENDED)
75 namespace QDeclarativeBuiltinFunctions {
77 enum ConsoleLogTypes {
83 static QString extendMessage(const QString &msg) {
84 if (qmlConsoleExtended()) {
85 v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(1);
86 if (stackTrace->GetFrameCount()) {
87 v8::Local<v8::StackFrame> frame = stackTrace->GetFrame(0);
88 int line = frame->GetLineNumber();
89 QString scriptName = QString::fromUtf16(*v8::String::Value(frame->GetScriptName()));
91 return QString::fromLatin1("%1 (%2:%3)").arg(msg).arg(scriptName).arg(line);
97 static void printStack() {
98 //The v8 default is currently 10 stack frames.
99 v8::Handle<v8::StackTrace> stackTrace =
100 v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kOverview);
101 int stackCount = stackTrace->GetFrameCount();
103 for (int i = 0; i < stackCount; i++) {
104 v8::Local<v8::StackFrame> frame = stackTrace->GetFrame(i);
105 v8::String::Utf8Value func_name(frame->GetFunctionName());
106 v8::String::Utf8Value script_name(frame->GetScriptName());
107 int lineNumber = frame->GetLineNumber();
108 int columnNumber = frame->GetColumn();
109 qDebug("%s (%s:%d:%d)\n", *func_name, *script_name, lineNumber, columnNumber);
113 v8::Handle<v8::Value> console(ConsoleLogTypes logType, const v8::Arguments &args)
115 v8::HandleScope handleScope;
118 for (int i = 0; i < args.Length(); ++i) {
120 result.append(QLatin1Char(' '));
122 v8::Local<v8::Value> value = args[i];
123 //Check for Object Type
124 if (value->IsObject() && !value->IsFunction()
125 && !value->IsArray() && !value->IsDate()
126 && !value->IsRegExp()) {
127 result.append(QLatin1String("Object"));
129 v8::Local<v8::String> jsstr = value->ToString();
130 QString tmp = V8ENGINE()->toString(jsstr);
131 if (value->IsArray())
132 result.append(QString::fromLatin1("[%1]").arg(tmp));
138 result = extendMessage(result);
142 qDebug("%s", qPrintable(result));
145 qWarning("%s", qPrintable(result));
148 qCritical("%s", qPrintable(result));
154 return v8::Undefined();
157 v8::Handle<v8::Value> gc(const v8::Arguments &args)
161 return v8::Undefined();
164 v8::Handle<v8::Value> consoleError(const v8::Arguments &args)
166 return console(Error, args);
169 v8::Handle<v8::Value> consoleLog(const v8::Arguments &args)
175 return console(Log, args);
178 v8::Handle<v8::Value> consoleProfile(const v8::Arguments &args)
180 //DeclarativeDebugTrace cannot handle nested profiling
181 //although v8 can handle several profiling at once,
182 //we do not allow that. Hence, we pass an empty(default) title
186 if (QDeclarativeDebugTrace::startProfiling()) {
187 QV8ProfilerService::instance()->startProfiling(title);
188 qDebug("Profiling started.");
190 qWarning("Profiling is already in progress. First, end current profiling session.");
193 return v8::Undefined();
196 v8::Handle<v8::Value> consoleProfileEnd(const v8::Arguments &args)
198 //DeclarativeDebugTrace cannot handle nested profiling
199 //although v8 can handle several profiling at once,
200 //we do not allow that. Hence, we pass an empty(default) title
204 if (QDeclarativeDebugTrace::stopProfiling()) {
205 QV8ProfilerService *profiler = QV8ProfilerService::instance();
206 profiler->stopProfiling(title);
207 QDeclarativeDebugTrace::sendProfilingData();
208 profiler->sendProfilingData();
209 qDebug("Profiling ended.");
211 qWarning("Profiling was not started.");
214 return v8::Undefined();
217 v8::Handle<v8::Value> consoleTime(const v8::Arguments &args)
219 if (args.Length() != 1)
220 V8THROW_ERROR("console.time(): Invalid arguments");
221 QString name = V8ENGINE()->toString(args[0]);
222 V8ENGINE()->startTimer(name);
223 return v8::Undefined();
226 v8::Handle<v8::Value> consoleTimeEnd(const v8::Arguments &args)
228 if (args.Length() != 1)
229 V8THROW_ERROR("console.time(): Invalid arguments");
230 QString name = V8ENGINE()->toString(args[0]);
232 qint64 elapsed = V8ENGINE()->stopTimer(name, &wasRunning);
234 qDebug("%s: %llims", qPrintable(name), elapsed);
236 return v8::Undefined();
239 v8::Handle<v8::Value> consoleCount(const v8::Arguments &args)
241 // first argument: name to print. Ignore any additional arguments
243 if (args.Length() > 0)
244 name = V8ENGINE()->toString(args[0]);
246 v8::Handle<v8::StackTrace> stackTrace =
247 v8::StackTrace::CurrentStackTrace(1, v8::StackTrace::kOverview);
249 if (stackTrace->GetFrameCount()) {
250 v8::Local<v8::StackFrame> frame = stackTrace->GetFrame(0);
252 QString scriptName = V8ENGINE()->toString(frame->GetScriptName());
253 int line = frame->GetLineNumber();
254 int column = frame->GetColumn();
256 int value = V8ENGINE()->consoleCountHelper(scriptName, line, column);
257 QString message = name + QLatin1String(": ") + QString::number(value);
258 if (qmlConsoleExtended())
259 message = QString::fromLatin1("%1 (%2:%3)").arg(message).arg(scriptName).arg(line);
260 qDebug("%s", qPrintable(message));
263 return v8::Undefined();
266 v8::Handle<v8::Value> consoleTrace(const v8::Arguments &args)
268 if (args.Length() != 0)
269 V8THROW_ERROR("console.trace(): Invalid arguments");
272 return v8::Undefined();
275 v8::Handle<v8::Value> consoleWarn(const v8::Arguments &args)
277 return console(Warn, args);
280 v8::Handle<v8::Value> consoleAssert(const v8::Arguments &args)
282 if (args.Length() == 0)
283 V8THROW_ERROR("console.assert(): Missing argument");
285 if (!args[0]->ToBoolean()->Value()) {
287 for (int i = 1; i < args.Length(); ++i) {
289 message.append(QLatin1Char(' '));
291 v8::Local<v8::Value> value = args[i];
292 message.append(V8ENGINE()->toString(value->ToString()));
295 message = extendMessage(message);
296 qCritical("%s", qPrintable(message));
299 return v8::Undefined();
302 v8::Handle<v8::Value> consoleException(const v8::Arguments &args)
304 if (args.Length() == 0)
305 V8THROW_ERROR("console.exception(): Missing argument");
306 console(Error, args);
309 return v8::Undefined();
312 v8::Handle<v8::Value> stringArg(const v8::Arguments &args)
314 QString value = V8ENGINE()->toString(args.This()->ToString());
315 if (args.Length() != 1)
316 V8THROW_ERROR("String.arg(): Invalid arguments");
318 v8::Handle<v8::Value> arg = args[0];
320 return V8ENGINE()->toString(value.arg(arg->Uint32Value()));
321 else if (arg->IsInt32())
322 return V8ENGINE()->toString(value.arg(arg->Int32Value()));
323 else if (arg->IsNumber())
324 return V8ENGINE()->toString(value.arg(arg->NumberValue()));
325 else if (arg->IsBoolean())
326 return V8ENGINE()->toString(value.arg(arg->BooleanValue()));
328 return V8ENGINE()->toString(value.arg(V8ENGINE()->toString(arg)));
332 \qmlmethod bool Qt::isQtObject(object)
333 Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
335 v8::Handle<v8::Value> isQtObject(const v8::Arguments &args)
337 if (args.Length() == 0)
338 return v8::Boolean::New(false);
340 return v8::Boolean::New(0 != V8ENGINE()->toQObject(args[0]));
344 \qmlmethod color Qt::rgba(real red, real green, real blue, real alpha)
346 Returns a color with the specified \c red, \c green, \c blue and \c alpha components.
347 All components should be in the range 0-1 inclusive.
349 v8::Handle<v8::Value> rgba(const v8::Arguments &args)
351 int argCount = args.Length();
352 if (argCount < 3 || argCount > 4)
353 V8THROW_ERROR("Qt.rgba(): Invalid arguments");
355 double r = args[0]->NumberValue();
356 double g = args[1]->NumberValue();
357 double b = args[2]->NumberValue();
358 double a = (argCount == 4) ? args[3]->NumberValue() : 1;
369 return V8ENGINE()->fromVariant(QVariant::fromValue(QColor::fromRgbF(r, g, b, a)));
373 \qmlmethod color Qt::hsla(real hue, real saturation, real lightness, real alpha)
375 Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components.
376 All components should be in the range 0-1 inclusive.
378 v8::Handle<v8::Value> hsla(const v8::Arguments &args)
380 int argCount = args.Length();
381 if (argCount < 3 || argCount > 4)
382 V8THROW_ERROR("Qt.hsla(): Invalid arguments");
384 double h = args[0]->NumberValue();
385 double s = args[1]->NumberValue();
386 double l = args[2]->NumberValue();
387 double a = (argCount == 4) ? args[3]->NumberValue() : 1;
398 return V8ENGINE()->fromVariant(QVariant::fromValue(QColor::fromHslF(h, s, l, a)));
402 \qmlmethod rect Qt::rect(int x, int y, int width, int height)
404 Returns a \c rect with the top-left corner at \c x, \c y and the specified \c width and \c height.
406 The returned object has \c x, \c y, \c width and \c height attributes with the given values.
408 v8::Handle<v8::Value> rect(const v8::Arguments &args)
410 if (args.Length() != 4)
411 V8THROW_ERROR("Qt.rect(): Invalid arguments");
413 double x = args[0]->NumberValue();
414 double y = args[1]->NumberValue();
415 double w = args[2]->NumberValue();
416 double h = args[3]->NumberValue();
418 return V8ENGINE()->fromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
422 \qmlmethod point Qt::point(int x, int y)
423 Returns a Point with the specified \c x and \c y coordinates.
425 v8::Handle<v8::Value> point(const v8::Arguments &args)
427 if (args.Length() != 2)
428 V8THROW_ERROR("Qt.point(): Invalid arguments");
430 double x = args[0]->ToNumber()->Value();
431 double y = args[1]->ToNumber()->Value();
433 return V8ENGINE()->fromVariant(QVariant::fromValue(QPointF(x, y)));
437 \qmlmethod Qt::size(int width, int height)
438 Returns a Size with the specified \c width and \c height.
440 v8::Handle<v8::Value> size(const v8::Arguments &args)
442 if (args.Length() != 2)
443 V8THROW_ERROR("Qt.size(): Invalid arguments");
445 double w = args[0]->ToNumber()->Value();
446 double h = args[1]->ToNumber()->Value();
448 return V8ENGINE()->fromVariant(QVariant::fromValue(QSizeF(w, h)));
452 \qmlmethod Qt::vector3d(real x, real y, real z)
453 Returns a Vector3D with the specified \c x, \c y and \c z.
455 v8::Handle<v8::Value> vector3d(const v8::Arguments &args)
457 if (args.Length() != 3)
458 V8THROW_ERROR("Qt.vector(): Invalid arguments");
460 double x = args[0]->ToNumber()->Value();
461 double y = args[1]->ToNumber()->Value();
462 double z = args[2]->ToNumber()->Value();
464 return V8ENGINE()->fromVariant(QVariant::fromValue(QVector3D(x, y, z)));
468 \qmlmethod Qt::vector4d(real x, real y, real z, real w)
469 Returns a Vector4D with the specified \c x, \c y, \c z and \c w.
471 v8::Handle<v8::Value> vector4d(const v8::Arguments &args)
473 if (args.Length() != 4)
474 V8THROW_ERROR("Qt.vector4d(): Invalid arguments");
476 double x = args[0]->NumberValue();
477 double y = args[1]->NumberValue();
478 double z = args[2]->NumberValue();
479 double w = args[3]->NumberValue();
481 return V8ENGINE()->fromVariant(QVariant::fromValue(QVector4D(x, y, z, w)));
485 \qmlmethod color Qt::lighter(color baseColor, real factor)
486 Returns a color lighter than \c baseColor by the \c factor provided.
488 If the factor is greater than 1.0, this functions returns a lighter color.
489 Setting factor to 1.5 returns a color that is 50% brighter. If the factor is less than 1.0,
490 the return color is darker, but we recommend using the Qt.darker() function for this purpose.
491 If the factor is 0 or negative, the return value is unspecified.
493 The function converts the current RGB color to HSV, multiplies the value (V) component
494 by factor and converts the color back to RGB.
496 If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5).
498 v8::Handle<v8::Value> lighter(const v8::Arguments &args)
500 if (args.Length() != 1 && args.Length() != 2)
501 V8THROW_ERROR("Qt.lighter(): Invalid arguments");
504 QVariant v = V8ENGINE()->toVariant(args[0], -1);
505 if (v.userType() == QVariant::Color) {
506 color = v.value<QColor>();
507 } else if (v.userType() == QVariant::String) {
509 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
518 if (args.Length() == 2)
519 factor = args[1]->ToNumber()->Value();
521 color = color.lighter(int(qRound(factor*100.)));
522 return V8ENGINE()->fromVariant(QVariant::fromValue(color));
526 \qmlmethod color Qt::darker(color baseColor, real factor)
527 Returns a color darker than \c baseColor by the \c factor provided.
529 If the factor is greater than 1.0, this function returns a darker color.
530 Setting factor to 3.0 returns a color that has one-third the brightness.
531 If the factor is less than 1.0, the return color is lighter, but we recommend using
532 the Qt.lighter() function for this purpose. If the factor is 0 or negative, the return
533 value is unspecified.
535 The function converts the current RGB color to HSV, divides the value (V) component
536 by factor and converts the color back to RGB.
538 If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0).
540 v8::Handle<v8::Value> darker(const v8::Arguments &args)
542 if (args.Length() != 1 && args.Length() != 2)
543 V8THROW_ERROR("Qt.darker(): Invalid arguments");
546 QVariant v = V8ENGINE()->toVariant(args[0], -1);
547 if (v.userType() == QVariant::Color) {
548 color = v.value<QColor>();
549 } else if (v.userType() == QVariant::String) {
551 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
560 if (args.Length() == 2)
561 factor = args[1]->ToNumber()->Value();
563 color = color.darker(int(qRound(factor*100.)));
564 return V8ENGINE()->fromVariant(QVariant::fromValue(color));
568 \qmlmethod color Qt::tint(color baseColor, color tintColor)
569 This function allows tinting one color with another.
571 The tint color should usually be mostly transparent, or you will not be
572 able to see the underlying color. The below example provides a slight red
573 tint by having the tint color be pure red which is only 1/16th opaque.
578 x: 0; width: 80; height: 80
579 color: "lightsteelblue"
582 x: 100; width: 80; height: 80
583 color: Qt.tint("lightsteelblue", "#10FF0000")
587 \image declarative-rect_tint.png
589 Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color.
591 v8::Handle<v8::Value> tint(const v8::Arguments &args)
593 if (args.Length() != 2)
594 V8THROW_ERROR("Qt.tint(): Invalid arguments");
598 QVariant v = V8ENGINE()->toVariant(args[0], -1);
599 if (v.userType() == QVariant::Color) {
600 color = v.value<QColor>();
601 } else if (v.userType() == QVariant::String) {
603 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
613 v = V8ENGINE()->toVariant(args[1], -1);
614 if (v.userType() == QVariant::Color) {
615 tintColor = v.value<QColor>();
616 } else if (v.userType() == QVariant::String) {
618 tintColor = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
626 // tint the base color and return the final color
628 int a = tintColor.alpha();
630 finalColor = tintColor;
634 qreal a = tintColor.alphaF();
635 qreal inv_a = 1.0 - a;
637 finalColor.setRgbF(tintColor.redF() * a + color.redF() * inv_a,
638 tintColor.greenF() * a + color.greenF() * inv_a,
639 tintColor.blueF() * a + color.blueF() * inv_a,
640 a + inv_a * color.alphaF());
643 return V8ENGINE()->fromVariant(QVariant::fromValue(finalColor));
647 \qmlmethod string Qt::formatDate(datetime date, variant format)
649 Returns a string representation of \c date, optionally formatted according
652 The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
653 property, a QDate, or QDateTime value. The \a format parameter may be any of
654 the possible format values as described for
655 \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
657 If \a format is not specified, \a date is formatted using
658 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
662 v8::Handle<v8::Value> formatDate(const v8::Arguments &args)
664 if (args.Length() < 1 || args.Length() > 2)
665 V8THROW_ERROR("Qt.formatDate(): Invalid arguments");
667 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
668 QDate date = V8ENGINE()->toVariant(args[0], -1).toDateTime().date();
669 QString formattedDate;
670 if (args.Length() == 2) {
671 if (args[1]->IsString()) {
672 QString format = V8ENGINE()->toVariant(args[1], -1).toString();
673 formattedDate = date.toString(format);
674 } else if (args[1]->IsNumber()) {
675 quint32 intFormat = args[1]->ToNumber()->Value();
676 Qt::DateFormat format = Qt::DateFormat(intFormat);
677 formattedDate = date.toString(format);
679 V8THROW_ERROR("Qt.formatDate(): Invalid date format");
682 formattedDate = date.toString(enumFormat);
685 return V8ENGINE()->fromVariant(QVariant::fromValue(formattedDate));
689 \qmlmethod string Qt::formatTime(datetime time, variant format)
691 Returns a string representation of \c time, optionally formatted according to
694 The \a time parameter may be a JavaScript \c Date object, a QTime, or QDateTime
695 value. The \a format parameter may be any of the possible format values as
696 described for \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
698 If \a format is not specified, \a time is formatted using
699 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
703 v8::Handle<v8::Value> formatTime(const v8::Arguments &args)
705 if (args.Length() < 1 || args.Length() > 2)
706 V8THROW_ERROR("Qt.formatTime(): Invalid arguments");
708 QVariant argVariant = V8ENGINE()->toVariant(args[0], -1);
710 if (args[0]->IsDate() || (argVariant.type() == QVariant::String))
711 time = argVariant.toDateTime().time();
712 else // if (argVariant.type() == QVariant::Time), or invalid.
713 time = argVariant.toTime();
715 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
716 QString formattedTime;
717 if (args.Length() == 2) {
718 if (args[1]->IsString()) {
719 QString format = V8ENGINE()->toVariant(args[1], -1).toString();
720 formattedTime = time.toString(format);
721 } else if (args[1]->IsNumber()) {
722 quint32 intFormat = args[1]->ToNumber()->Value();
723 Qt::DateFormat format = Qt::DateFormat(intFormat);
724 formattedTime = time.toString(format);
726 V8THROW_ERROR("Qt.formatTime(): Invalid time format");
729 formattedTime = time.toString(enumFormat);
732 return V8ENGINE()->fromVariant(QVariant::fromValue(formattedTime));
736 \qmlmethod string Qt::formatDateTime(datetime dateTime, variant format)
738 Returns a string representation of \c datetime, optionally formatted according to
741 The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
742 property, a QDate, QTime, or QDateTime value.
744 If \a format is not provided, \a dateTime is formatted using
745 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}. Otherwise,
746 \a format should be either:
749 \o One of the Qt::DateFormat enumeration values, such as
750 \c Qt.DefaultLocaleShortDate or \c Qt.ISODate
751 \o A string that specifies the format of the returned string, as detailed below.
754 If \a format specifies a format string, it should use the following expressions
758 \header \i Expression \i Output
759 \row \i d \i the day as number without a leading zero (1 to 31)
760 \row \i dd \i the day as number with a leading zero (01 to 31)
762 \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
763 Uses QDate::shortDayName().
765 \i the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
766 Uses QDate::longDayName().
767 \row \i M \i the month as number without a leading zero (1-12)
768 \row \i MM \i the month as number with a leading zero (01-12)
770 \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
771 Uses QDate::shortMonthName().
773 \i the long localized month name (e.g. 'January' to 'December').
774 Uses QDate::longMonthName().
775 \row \i yy \i the year as two digit number (00-99)
776 \row \i yyyy \i the year as four digit number
779 In addition the following expressions can be used to specify the time:
782 \header \i Expression \i Output
784 \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
786 \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
787 \row \i m \i the minute without a leading zero (0 to 59)
788 \row \i mm \i the minute with a leading zero (00 to 59)
789 \row \i s \i the second without a leading zero (0 to 59)
790 \row \i ss \i the second with a leading zero (00 to 59)
791 \row \i z \i the milliseconds without leading zeroes (0 to 999)
792 \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
794 \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
796 \i use am/pm display. \e ap will be replaced by either "am" or "pm".
799 All other input characters will be ignored. Any sequence of characters that
800 are enclosed in single quotes will be treated as text and not be used as an
801 expression. Two consecutive single quotes ("''") are replaced by a single quote
804 For example, if the following date/time value was specified:
807 // 21 May 2001 14:13:09
808 var dateTime = new Date(2001, 5, 21, 14, 13, 09)
811 This \a dateTime value could be passed to \c Qt.formatDateTime(),
812 \l {QML:Qt::formatDate()}{Qt.formatDate()} or \l {QML:Qt::formatTime()}{Qt.formatTime()}
813 with the \a format values below to produce the following results:
816 \header \i Format \i Result
817 \row \i "dd.MM.yyyy" \i 21.05.2001
818 \row \i "ddd MMMM d yy" \i Tue May 21 01
819 \row \i "hh:mm:ss.zzz" \i 14:13:09.042
820 \row \i "h:m:s ap" \i 2:13:9 pm
825 v8::Handle<v8::Value> formatDateTime(const v8::Arguments &args)
827 if (args.Length() < 1 || args.Length() > 2)
828 V8THROW_ERROR("Qt.formatDateTime(): Invalid arguments");
830 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
831 QDateTime dt = V8ENGINE()->toVariant(args[0], -1).toDateTime();
833 if (args.Length() == 2) {
834 if (args[1]->IsString()) {
835 QString format = V8ENGINE()->toVariant(args[1], -1).toString();
836 formattedDt = dt.toString(format);
837 } else if (args[1]->IsNumber()) {
838 quint32 intFormat = args[1]->ToNumber()->Value();
839 Qt::DateFormat format = Qt::DateFormat(intFormat);
840 formattedDt = dt.toString(format);
842 V8THROW_ERROR("Qt.formatDateTime(): Invalid datetime format");
845 formattedDt = dt.toString(enumFormat);
848 return V8ENGINE()->fromVariant(QVariant::fromValue(formattedDt));
852 \qmlmethod bool Qt::openUrlExternally(url target)
853 Attempts to open the specified \c target url in an external application, based on the user's desktop preferences. Returns true if it succeeds, and false otherwise.
855 v8::Handle<v8::Value> openUrlExternally(const v8::Arguments &args)
857 if (args.Length() != 1)
858 return V8ENGINE()->fromVariant(false);
861 #ifndef QT_NO_DESKTOPSERVICES
862 ret = QDesktopServices::openUrl(V8ENGINE()->toVariant(resolvedUrl(args), -1).toUrl());
864 return V8ENGINE()->fromVariant(ret);
868 \qmlmethod url Qt::resolvedUrl(url url)
869 Returns \a url resolved relative to the URL of the caller.
871 v8::Handle<v8::Value> resolvedUrl(const v8::Arguments &args)
873 QUrl url = V8ENGINE()->toVariant(args[0], -1).toUrl();
874 QDeclarativeEngine *e = V8ENGINE()->engine();
875 QDeclarativeEnginePrivate *p = 0;
876 if (e) p = QDeclarativeEnginePrivate::get(e);
878 QDeclarativeContextData *ctxt = V8ENGINE()->callingContext();
880 return V8ENGINE()->toString(ctxt->resolvedUrl(url).toString());
882 return V8ENGINE()->toString(url.toString());
885 return V8ENGINE()->toString(e->baseUrl().resolved(url).toString());
889 \qmlmethod list<string> Qt::fontFamilies()
890 Returns a list of the font families available to the application.
892 v8::Handle<v8::Value> fontFamilies(const v8::Arguments &args)
894 if (args.Length() != 0)
895 V8THROW_ERROR("Qt.fontFamilies(): Invalid arguments");
897 QFontDatabase database;
898 return V8ENGINE()->fromVariant(database.families());
902 \qmlmethod string Qt::md5(data)
903 Returns a hex string of the md5 hash of \c data.
905 v8::Handle<v8::Value> md5(const v8::Arguments &args)
907 if (args.Length() != 1)
908 V8THROW_ERROR("Qt.md5(): Invalid arguments");
910 QByteArray data = V8ENGINE()->toString(args[0]->ToString()).toUtf8();
911 QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
912 return V8ENGINE()->toString(QLatin1String(result.toHex()));
916 \qmlmethod string Qt::btoa(data)
917 Binary to ASCII - this function returns a base64 encoding of \c data.
919 v8::Handle<v8::Value> btoa(const v8::Arguments &args)
921 if (args.Length() != 1)
922 V8THROW_ERROR("Qt.btoa(): Invalid arguments");
924 QByteArray data = V8ENGINE()->toString(args[0]->ToString()).toUtf8();
926 return V8ENGINE()->toString(QLatin1String(data.toBase64()));
930 \qmlmethod string Qt::atob(data)
931 ASCII to binary - this function returns a base64 decoding of \c data.
933 v8::Handle<v8::Value> atob(const v8::Arguments &args)
935 if (args.Length() != 1)
936 V8THROW_ERROR("Qt.atob(): Invalid arguments");
938 QByteArray data = V8ENGINE()->toString(args[0]->ToString()).toUtf8();
940 return V8ENGINE()->toString(QLatin1String(QByteArray::fromBase64(data)));
944 \qmlmethod Qt::quit()
945 This function causes the QDeclarativeEngine::quit() signal to be emitted.
946 Within the \l {QML Viewer}, this causes the launcher application to exit;
947 to quit a C++ application when this method is called, connect the
948 QDeclarativeEngine::quit() signal to the QCoreApplication::quit() slot.
950 v8::Handle<v8::Value> quit(const v8::Arguments &args)
952 QDeclarativeEnginePrivate::get(V8ENGINE()->engine())->sendQuit();
953 return v8::Undefined();
957 \qmlmethod object Qt::createQmlObject(string qml, object parent, string filepath)
959 Returns a new object created from the given \a string of QML which will have the specified \a parent,
960 or \c null if there was an error in creating the object.
962 If \a filepath is specified, it will be used for error reporting for the created object.
964 Example (where \c parentItem is the id of an existing QML item):
966 \snippet doc/src/snippets/declarative/createQmlObject.qml 0
968 In the case of an error, a QtScript Error object is thrown. This object has an additional property,
969 \c qmlErrors, which is an array of the errors encountered.
970 Each object in this array has the members \c lineNumber, \c columnNumber, \c fileName and \c message.
971 For example, if the above snippet had misspelled color as 'colro' then the array would contain an object like the following:
972 { "lineNumber" : 1, "columnNumber" : 32, "fileName" : "dynamicSnippet1", "message" : "Cannot assign to non-existent property \"colro\""}.
974 Note that this function returns immediately, and therefore may not work if
975 the \a qml string loads new components (that is, external QML files that have not yet been loaded).
976 If this is the case, consider using \l{QML:Qt::createComponent()}{Qt.createComponent()} instead.
978 See \l {Dynamic Object Management in QML} for more information on using this function.
980 v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args)
982 if (args.Length() < 2 || args.Length() > 3)
983 V8THROW_ERROR("Qt.createQmlObject(): Invalid arguments");
986 static v8::Local<v8::Value> create(QV8Engine *engine, const QList<QDeclarativeError> &errors) {
987 QString errorstr = QLatin1String("Qt.createQmlObject(): failed to create object: ");
989 v8::Local<v8::Array> qmlerrors = v8::Array::New(errors.count());
990 for (int ii = 0; ii < errors.count(); ++ii) {
991 const QDeclarativeError &error = errors.at(ii);
992 errorstr += QLatin1String("\n ") + error.toString();
993 v8::Local<v8::Object> qmlerror = v8::Object::New();
994 qmlerror->Set(v8::String::New("lineNumber"), v8::Integer::New(error.line()));
995 qmlerror->Set(v8::String::New("columnNumber"), v8::Integer::New(error.line()));
996 qmlerror->Set(v8::String::New("fileName"), engine->toString(error.url().toString()));
997 qmlerror->Set(v8::String::New("message"), engine->toString(error.description()));
998 qmlerrors->Set(ii, qmlerror);
1001 v8::Local<v8::Value> error = v8::Exception::Error(engine->toString(errorstr));
1002 v8::Local<v8::Object> errorObject = error->ToObject();
1003 errorObject->Set(v8::String::New("qmlErrors"), qmlerrors);
1008 QV8Engine *v8engine = V8ENGINE();
1009 QDeclarativeEngine *engine = v8engine->engine();
1011 QDeclarativeContextData *context = v8engine->callingContext();
1012 QDeclarativeContext *effectiveContext = 0;
1013 if (context->isPragmaLibraryContext)
1014 effectiveContext = engine->rootContext();
1016 effectiveContext = context->asQDeclarativeContext();
1017 Q_ASSERT(context && effectiveContext);
1019 QString qml = v8engine->toString(args[0]->ToString());
1024 if (args.Length() > 2)
1025 url = QUrl(v8engine->toString(args[2]->ToString()));
1027 url = QUrl(QLatin1String("inline"));
1029 if (url.isValid() && url.isRelative())
1030 url = context->resolvedUrl(url);
1032 QObject *parentArg = v8engine->toQObject(args[1]);
1034 V8THROW_ERROR("Qt.createQmlObject(): Missing parent object");
1036 QDeclarativeComponent component(engine);
1037 component.setData(qml.toUtf8(), url);
1039 if (component.isError()) {
1040 v8::ThrowException(Error::create(v8engine, component.errors()));
1041 return v8::Undefined();
1044 if (!component.isReady())
1045 V8THROW_ERROR("Qt.createQmlObject(): Component is not ready");
1047 QObject *obj = component.beginCreate(effectiveContext);
1049 QDeclarativeData::get(obj, true)->setImplicitDestructible();
1050 component.completeCreate();
1052 if (component.isError()) {
1053 v8::ThrowException(Error::create(v8engine, component.errors()));
1054 return v8::Undefined();
1059 obj->setParent(parentArg);
1061 QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions();
1062 for (int ii = 0; ii < functions.count(); ++ii) {
1063 if (QDeclarativePrivate::Parented == functions.at(ii)(obj, parentArg))
1067 return v8engine->newQObject(obj);
1071 \qmlmethod object Qt::createComponent(url)
1073 Returns a \l Component object created using the QML file at the specified \a url,
1074 or \c null if an empty string was given.
1076 The returned component's \l Component::status property indicates whether the
1077 component was successfully created. If the status is \c Component.Error,
1078 see \l Component::errorString() for an error description.
1080 Call \l {Component::createObject()}{Component.createObject()} on the returned
1081 component to create an object instance of the component.
1085 \snippet doc/src/snippets/declarative/createComponent-simple.qml 0
1087 See \l {Dynamic Object Management in QML} for more information on using this function.
1089 To create a QML object from an arbitrary string of QML (instead of a file),
1090 use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}.
1092 v8::Handle<v8::Value> createComponent(const v8::Arguments &args)
1094 if (args.Length() != 1)
1095 V8THROW_ERROR("Qt.createComponent(): Invalid arguments");
1097 QV8Engine *v8engine = V8ENGINE();
1098 QDeclarativeEngine *engine = v8engine->engine();
1100 QDeclarativeContextData *context = v8engine->callingContext();
1101 QDeclarativeContextData *effectiveContext = context;
1102 if (context->isPragmaLibraryContext)
1103 effectiveContext = 0;
1106 QString arg = v8engine->toString(args[0]->ToString());
1110 QUrl url = context->resolvedUrl(QUrl(arg));
1111 QDeclarativeComponent *c = new QDeclarativeComponent(engine, url, engine);
1112 QDeclarativeComponentPrivate::get(c)->creationContext = effectiveContext;
1113 QDeclarativeData::get(c, true)->setImplicitDestructible();
1114 return v8engine->newQObject(c);
1117 v8::Handle<v8::Value> qsTranslate(const v8::Arguments &args)
1119 if (args.Length() < 2)
1120 V8THROW_ERROR("qsTranslate() requires at least two arguments");
1121 if (!args[0]->IsString())
1122 V8THROW_ERROR("qsTranslate(): first argument (context) must be a string");
1123 if (!args[1]->IsString())
1124 V8THROW_ERROR("qsTranslate(): second argument (text) must be a string");
1125 if ((args.Length() > 2) && !args[2]->IsString())
1126 V8THROW_ERROR("qsTranslate(): third argument (comment) must be a string");
1127 if ((args.Length() > 3) && !args[3]->IsString())
1128 V8THROW_ERROR("qsTranslate(): fourth argument (encoding) must be a string");
1130 QV8Engine *v8engine = V8ENGINE();
1131 QString context = v8engine->toString(args[0]);
1132 QString text = v8engine->toString(args[1]);
1134 if (args.Length() > 2) comment = v8engine->toString(args[2]);
1136 QCoreApplication::Encoding encoding = QCoreApplication::UnicodeUTF8;
1137 if (args.Length() > 3) {
1138 QString encStr = v8engine->toString(args[3]);
1139 if (encStr == QLatin1String("CodecForTr")) {
1140 encoding = QCoreApplication::CodecForTr;
1141 } else if (encStr == QLatin1String("UnicodeUTF8")) {
1142 encoding = QCoreApplication::UnicodeUTF8;
1144 QString msg = QString::fromLatin1("qsTranslate(): invalid encoding '%0'").arg(encStr);
1145 V8THROW_ERROR((uint16_t *)msg.constData());
1150 if (args.Length() > 4)
1151 n = args[4]->Int32Value();
1153 QString result = QCoreApplication::translate(context.toUtf8().constData(),
1154 text.toUtf8().constData(),
1155 comment.toUtf8().constData(),
1158 return v8engine->toString(result);
1161 v8::Handle<v8::Value> qsTranslateNoOp(const v8::Arguments &args)
1163 if (args.Length() < 2)
1164 return v8::Undefined();
1168 v8::Handle<v8::Value> qsTr(const v8::Arguments &args)
1170 if (args.Length() < 1)
1171 V8THROW_ERROR("qsTr() requires at least one argument");
1172 if (!args[0]->IsString())
1173 V8THROW_ERROR("qsTr(): first argument (text) must be a string");
1174 if ((args.Length() > 1) && !args[1]->IsString())
1175 V8THROW_ERROR("qsTr(): second argument (comment) must be a string");
1176 if ((args.Length() > 2) && !args[2]->IsNumber())
1177 V8THROW_ERROR("qsTr(): third argument (n) must be a number");
1179 QV8Engine *v8engine = V8ENGINE();
1180 QDeclarativeContextData *ctxt = v8engine->callingContext();
1182 QString path = ctxt->url.toString();
1183 int lastSlash = path.lastIndexOf(QLatin1Char('/'));
1184 QString context = (lastSlash > -1) ? path.mid(lastSlash + 1, path.length()-lastSlash-5) : QString();
1186 QString text = v8engine->toString(args[0]);
1188 if (args.Length() > 1)
1189 comment = v8engine->toString(args[1]);
1191 if (args.Length() > 2)
1192 n = args[2]->Int32Value();
1194 QString result = QCoreApplication::translate(context.toUtf8().constData(), text.toUtf8().constData(),
1195 comment.toUtf8().constData(), QCoreApplication::UnicodeUTF8, n);
1197 return v8engine->toString(result);
1200 v8::Handle<v8::Value> qsTrNoOp(const v8::Arguments &args)
1202 if (args.Length() < 1)
1203 return v8::Undefined();
1207 v8::Handle<v8::Value> qsTrId(const v8::Arguments &args)
1209 if (args.Length() < 1)
1210 V8THROW_ERROR("qsTrId() requires at least one argument");
1211 if (!args[0]->IsString())
1212 V8THROW_TYPE("qsTrId(): first argument (id) must be a string");
1213 if (args.Length() > 1 && !args[1]->IsNumber())
1214 V8THROW_TYPE("qsTrId(): second argument (n) must be a number");
1217 if (args.Length() > 1)
1218 n = args[1]->Int32Value();
1220 QV8Engine *v8engine = V8ENGINE();
1221 return v8engine->toString(qtTrId(v8engine->toString(args[0]).toUtf8().constData(), n));
1224 v8::Handle<v8::Value> qsTrIdNoOp(const v8::Arguments &args)
1226 if (args.Length() < 1)
1227 return v8::Undefined();
1233 \qmlmethod Qt::locale(name)
1235 Returns a JS object representing the locale with the specified
1236 name, which has the format "language[_territory][.codeset][@modifier]"
1240 \o language is a lowercase, two-letter, ISO 639 language code,
1241 \o territory is an uppercase, two-letter, ISO 3166 country code,
1242 \o and codeset and modifier are ignored.
1245 If the string violates the locale format, or language is not a
1246 valid ISO 369 code, the "C" locale is used instead. If country
1247 is not present, or is not a valid ISO 3166 code, the most
1248 appropriate country is chosen for the specified language.
1250 \sa QtQuick2::Locale
1252 v8::Handle<v8::Value> locale(const v8::Arguments &args)
1255 if (args.Length() > 1)
1256 V8THROW_ERROR("locale() requires 0 or 1 argument");
1257 if (args.Length() == 1 && !args[0]->IsString())
1258 V8THROW_TYPE("locale(): argument (locale code) must be a string");
1260 QV8Engine *v8engine = V8ENGINE();
1261 if (args.Length() == 1)
1262 code = v8engine->toString(args[0]);
1264 return QDeclarativeLocale::locale(v8engine, code);
1267 } // namespace QDeclarativeBuiltinFunctions