doc/src/snippets/code/doc_src_qtscript.qdoc
branchRCL_3
changeset 7 3f74d0d4af4c
equal deleted inserted replaced
6:dee5afe5301f 7:3f74d0d4af4c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the documentation of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 //! [0]
       
    43 #include <QtScript>
       
    44 //! [0]
       
    45 
       
    46 
       
    47 //! [1]
       
    48 QT += script
       
    49 //! [1]
       
    50 
       
    51 
       
    52 //! [2]
       
    53 function myInterestingScriptFunction() { ... }
       
    54 ...
       
    55 myQObject.somethingChanged.connect(myInterestingScriptFunction);
       
    56 //! [2]
       
    57 
       
    58 
       
    59 //! [3]
       
    60 myQObject.somethingChanged.connect(myOtherQObject.doSomething);
       
    61 //! [3]
       
    62 
       
    63 
       
    64 //! [4]
       
    65 myQObject.somethingChanged.disconnect(myInterestingFunction);
       
    66 myQObject.somethingChanged.disconnect(myOtherQObject.doSomething);
       
    67 //! [4]
       
    68 
       
    69 
       
    70 //! [5]
       
    71 var obj = { x: 123 };
       
    72 var fun = function() { print(this.x); };
       
    73 myQObject.somethingChanged.connect(obj, fun);
       
    74 //! [5]
       
    75 
       
    76 
       
    77 //! [6]
       
    78 myQObject.somethingChanged.disconnect(obj, fun);
       
    79 //! [6]
       
    80 
       
    81 
       
    82 //! [7]
       
    83 var obj = { x: 123, fun: function() { print(this.x); } };
       
    84 myQObject.somethingChanged.connect(obj, "fun");
       
    85 //! [7]
       
    86 
       
    87 
       
    88 //! [8]
       
    89 myQObject.somethingChanged.disconnect(obj, "fun");
       
    90 //! [8]
       
    91 
       
    92 
       
    93 //! [9]
       
    94 try {
       
    95     myQObject.somethingChanged.connect(myQObject, "slotThatDoesntExist");
       
    96 } catch (e) {
       
    97     print(e);
       
    98 }
       
    99 //! [9]
       
   100 
       
   101 
       
   102 //! [10]
       
   103 myQObject.somethingChanged("hello");
       
   104 //! [10]
       
   105 
       
   106 
       
   107 //! [11]
       
   108 myQObject.myOverloadedSlot(10);   // will call the int overload
       
   109 myQObject.myOverloadedSlot("10"); // will call the QString overload
       
   110 //! [11]
       
   111 
       
   112 
       
   113 //! [12]
       
   114 myQObject['myOverloadedSlot(int)']("10");   // call int overload; the argument is converted to an int
       
   115 myQObject['myOverloadedSlot(QString)'](10); // call QString overload; the argument is converted to a string
       
   116 //! [12]
       
   117 
       
   118 
       
   119 //! [13]
       
   120 Q_PROPERTY(bool enabled READ enabled WRITE setEnabled)
       
   121 //! [13]
       
   122 
       
   123 
       
   124 //! [14]
       
   125 myQObject.enabled = true;
       
   126 
       
   127 ...
       
   128 
       
   129 myQObject.enabled = !myQObject.enabled;
       
   130 //! [14]
       
   131 
       
   132 
       
   133 //! [15]
       
   134 myDialog.okButton
       
   135 //! [15]
       
   136 
       
   137 
       
   138 //! [16]
       
   139 myDialog.okButton.objectName = "cancelButton";
       
   140 // from now on, myDialog.cancelButton references the button
       
   141 //! [16]
       
   142 
       
   143 
       
   144 //! [17]
       
   145 var okButton = myDialog.findChild("okButton");
       
   146 if (okButton != null) {
       
   147    // do something with the OK button
       
   148 }
       
   149 
       
   150 var buttons = myDialog.findChildren(RegExp("button[0-9]+"));
       
   151 for (var i = 0; i < buttons.length; ++i) {
       
   152    // do something with buttons[i]
       
   153 }
       
   154 //! [17]
       
   155 
       
   156 
       
   157 //! [18]
       
   158 QScriptValue myQObjectConstructor(QScriptContext *context, QScriptEngine *engine)
       
   159 {
       
   160   // let the engine manage the new object's lifetime.
       
   161   return engine->newQObject(new MyQObject(), QScriptEngine::ScriptOwnership);
       
   162 }
       
   163 //! [18]
       
   164 
       
   165 
       
   166 //! [19]
       
   167 class MyObject : public QObject
       
   168 {
       
   169     Q_OBJECT
       
   170 
       
   171 public:
       
   172     MyObject( ... );
       
   173 
       
   174     void aNonScriptableFunction();
       
   175 
       
   176 public slots: // these functions (slots) will be available in QtScript
       
   177     void calculate( ... );
       
   178     void setEnabled( bool enabled );
       
   179     bool isEnabled() const;
       
   180 
       
   181 private:
       
   182    ....
       
   183 
       
   184 };
       
   185 //! [19]
       
   186 
       
   187 
       
   188 //! [20]
       
   189 class MyObject : public QObject
       
   190 {
       
   191     Q_OBJECT
       
   192 
       
   193     public:
       
   194     Q_INVOKABLE void thisMethodIsInvokableInQtScript();
       
   195     void thisMethodIsNotInvokableInQtScript();
       
   196 
       
   197     ...
       
   198 };
       
   199 //! [20]
       
   200 
       
   201 
       
   202 //! [21]
       
   203 var obj = new MyObject;
       
   204 obj.setEnabled( true );
       
   205 print( "obj is enabled: " + obj.isEnabled() );
       
   206 //! [21]
       
   207 
       
   208 
       
   209 //! [22]
       
   210 var obj = new MyObject;
       
   211 obj.enabled = true;
       
   212 print( "obj is enabled: " + obj.enabled );
       
   213 //! [22]
       
   214 
       
   215 
       
   216 //! [23]
       
   217 class MyObject : public QObject
       
   218 {
       
   219     Q_OBJECT
       
   220     // define the enabled property
       
   221     Q_PROPERTY( bool enabled WRITE setEnabled READ isEnabled )
       
   222 
       
   223 public:
       
   224     MyObject( ... );
       
   225 
       
   226     void aNonScriptableFunction();
       
   227 
       
   228 public slots: // these functions (slots) will be available in QtScript
       
   229     void calculate( ... );
       
   230     void setEnabled( bool enabled );
       
   231     bool isEnabled() const;
       
   232 
       
   233 private:
       
   234    ....
       
   235 
       
   236 };
       
   237 //! [23]
       
   238 
       
   239 
       
   240 //! [24]
       
   241 Q_PROPERTY(int nonScriptableProperty READ foo WRITE bar SCRIPTABLE false)
       
   242 //! [24]
       
   243 
       
   244 
       
   245 //! [25]
       
   246 class MyObject : public QObject
       
   247 {
       
   248     Q_OBJECT
       
   249     // define the enabled property
       
   250     Q_PROPERTY( bool enabled WRITE setEnabled READ isEnabled )
       
   251 
       
   252 public:
       
   253     MyObject( ... );
       
   254 
       
   255     void aNonScriptableFunction();
       
   256 
       
   257 public slots: // these functions (slots) will be available in QtScript
       
   258     void calculate( ... );
       
   259     void setEnabled( bool enabled );
       
   260     bool isEnabled() const;
       
   261 
       
   262 signals: // the signals
       
   263     void enabledChanged( bool newState );
       
   264 
       
   265 private:
       
   266    ....
       
   267 
       
   268 };
       
   269 //! [25]
       
   270 
       
   271 
       
   272 //! [26]
       
   273 function enabledChangedHandler( b )
       
   274 {
       
   275     print( "state changed to: " + b );
       
   276 }
       
   277 
       
   278 function init()
       
   279 {
       
   280     var obj = new MyObject();
       
   281     // connect a script function to the signal
       
   282     obj["enabledChanged(bool)"].connect(enabledChangedHandler);
       
   283     obj.enabled = true;
       
   284     print( "obj is enabled: " + obj.enabled );
       
   285 }
       
   286 //! [26]
       
   287 
       
   288 
       
   289 //! [27]
       
   290 var o = new Object();
       
   291 o.foo = 123;
       
   292 print(o.hasOwnProperty('foo')); // true
       
   293 print(o.hasOwnProperty('bar')); // false
       
   294 print(o); // calls o.toString(), which returns "[object Object]"
       
   295 //! [27]
       
   296 
       
   297 
       
   298 //! [28]
       
   299 function Person(name)
       
   300 {
       
   301   this.name = name;
       
   302 }
       
   303 //! [28]
       
   304 
       
   305 
       
   306 //! [29]
       
   307 Person.prototype.toString = function() { return "Person(name: " + this.name + ")"; }
       
   308 //! [29]
       
   309 
       
   310 
       
   311 //! [30]
       
   312 var p1 = new Person("John Doe");
       
   313 var p2 = new Person("G.I. Jane");
       
   314 print(p1); // "Person(name: John Doe)"
       
   315 print(p2); // "Person(name: G.I. Jane)"
       
   316 //! [30]
       
   317 
       
   318 
       
   319 //! [31]
       
   320 print(p1.hasOwnProperty('name')); // 'name' is an instance variable, so this returns true
       
   321 print(p1.hasOwnProperty('toString')); // returns false; inherited from prototype
       
   322 print(p1 instanceof Person); // true
       
   323 print(p1 instanceof Object); // true
       
   324 //! [31]
       
   325 
       
   326 
       
   327 //! [32]
       
   328 function Employee(name, salary)
       
   329 {
       
   330   Person.call(this, name); // call base constructor
       
   331 
       
   332   this.salary = salary;
       
   333 }
       
   334 
       
   335 // set the prototype to be an instance of the base class
       
   336 Employee.prototype = new Person();
       
   337 
       
   338 // initialize prototype
       
   339 Employee.prototype.toString = function() { ... }
       
   340 //! [32]
       
   341 
       
   342 
       
   343 //! [33]
       
   344 var e = new Employee("Johnny Bravo", 5000000);
       
   345 print(e instanceof Employee); // true
       
   346 print(e instanceof Person);   // true
       
   347 print(e instanceof Object);   // true
       
   348 print(e instanceof Array);    // false
       
   349 //! [33]
       
   350 
       
   351 
       
   352 //! [34]
       
   353 QScriptValue Person_ctor(QScriptContext *context, QScriptEngine *engine)
       
   354 {
       
   355   QString name = context->argument(0).toString();
       
   356   context->thisObject().setProperty("name", name);
       
   357   return engine->undefinedValue();
       
   358 }
       
   359 //! [34]
       
   360 
       
   361 
       
   362 //! [35]
       
   363 QScriptValue Person_prototype_toString(QScriptContext *context, QScriptEngine *engine)
       
   364 {
       
   365   QString name = context->thisObject().property("name").toString();
       
   366   QString result = QString::fromLatin1("Person(name: %0)").arg(name);
       
   367   return result;
       
   368 }
       
   369 //! [35]
       
   370 
       
   371 
       
   372 //! [36]
       
   373 QScriptEngine engine;
       
   374 QScriptValue ctor = engine.newFunction(Person_ctor);
       
   375 ctor.property("prototype").setProperty("toString", engine.newFunction(Person_prototype_toString));
       
   376 QScriptValue global = engine.globalObject();
       
   377 global.setProperty("Person", ctor);
       
   378 //! [36]
       
   379 
       
   380 
       
   381 //! [37]
       
   382 QScriptValue Employee_ctor(QScriptContext *context, QScriptEngine *engine)
       
   383 {
       
   384   QScriptValue super = context->callee().property("prototype").property("constructor");
       
   385   super.call(context->thisObject(), QScriptValueList() << context->argument(0));
       
   386   context->thisObject().setProperty("salary", context->argument(1));
       
   387   return engine->undefinedValue();
       
   388 }
       
   389 //! [37]
       
   390 
       
   391 
       
   392 //! [38]
       
   393 QScriptValue empCtor = engine.newFunction(Employee_ctor);
       
   394 empCtor.setProperty("prototype", global.property("Person").construct());
       
   395 global.setProperty("Employee", empCtor);
       
   396 //! [38]
       
   397 
       
   398 
       
   399 //! [39]
       
   400 Q_DECLARE_METATYPE(QPointF)
       
   401 Q_DECLARE_METATYPE(QPointF*)
       
   402 
       
   403 QScriptValue QPointF_prototype_x(QScriptContext *context, QScriptEngine *engine)
       
   404 {
       
   405   // Since the point is not to be modified, it's OK to cast to a value here
       
   406     QPointF point = qscriptvalue_cast<QPointF>(context->thisObject());
       
   407     return point.x();
       
   408 }
       
   409 
       
   410 QScriptValue QPointF_prototype_setX(QScriptContext *context, QScriptEngine *engine)
       
   411 {
       
   412     // Cast to a pointer to be able to modify the underlying C++ value
       
   413     QPointF *point = qscriptvalue_cast<QPointF*>(context->thisObject());
       
   414     if (!point)
       
   415         return context->throwError(QScriptContext::TypeError, "QPointF.prototype.setX: this object is not a QPointF");
       
   416     point->setX(context->argument(0).toNumber());
       
   417     return engine->undefinedValue();
       
   418 }
       
   419 //! [39]
       
   420 
       
   421 
       
   422 //! [40]
       
   423 var o = new Object();
       
   424 (o.__proto__ === Object.prototype); // this evaluates to true
       
   425 //! [40]
       
   426 
       
   427 
       
   428 //! [41]
       
   429 var o = new Object();
       
   430 o.__defineGetter__("x", function() { return 123; });
       
   431 var y = o.x; // 123
       
   432 //! [41]
       
   433 
       
   434 
       
   435 //! [42]
       
   436 var o = new Object();
       
   437 o.__defineSetter__("x", function(v) { print("and the value is:", v); });
       
   438 o.x = 123; // will print "and the value is: 123"
       
   439 //! [42]
       
   440 
       
   441 
       
   442 //! [43]
       
   443 class MyObject : public QObject
       
   444 {
       
   445     Q_OBJECT
       
   446     ...
       
   447 };
       
   448 
       
   449 Q_DECLARE_METATYPE(MyObject*)
       
   450 
       
   451 QScriptValue myObjectToScriptValue(QScriptEngine *engine, MyObject* const &in)
       
   452 { return engine->newQObject(in); }
       
   453 
       
   454 void myObjectFromScriptValue(const QScriptValue &object, MyObject* &out)
       
   455 { out = qobject_cast<MyObject*>(object.toQObject()); }
       
   456 
       
   457 ...
       
   458 
       
   459 qScriptRegisterMetaType(&engine, myObjectToScriptValue, myObjectFromScriptValue);
       
   460 //! [43]
       
   461 
       
   462 //! [44]
       
   463 QScriptValue QPoint_ctor(QScriptContext *context, QScriptEngine *engine)
       
   464 {
       
   465     int x = context->argument(0).toInt32();
       
   466     int y = context->argument(1).toInt32();
       
   467     return engine->toScriptValue(QPoint(x, y));
       
   468 }
       
   469 
       
   470 ...
       
   471 
       
   472 engine.globalObject().setProperty("QPoint", engine.newFunction(QPoint_ctor));
       
   473 //! [44]
       
   474 
       
   475 //! [45]
       
   476 QScriptValue myPrintFunction(QScriptContext *context, QScriptEngine *engine)
       
   477 {
       
   478     QString result;
       
   479     for (int i = 0; i < context->argumentCount(); ++i) {
       
   480         if (i > 0)
       
   481             result.append(" ");
       
   482         result.append(context->argument(i).toString());
       
   483     }
       
   484 
       
   485     QScriptValue calleeData = context->callee().data();
       
   486     QPlainTextEdit *edit = qobject_cast<QPlainTextEdit*>(calleeData.toQObject());
       
   487     edit->appendPlainText(result);
       
   488 
       
   489     return engine->undefinedValue();
       
   490 }
       
   491 //! [45]
       
   492 
       
   493 //! [46]
       
   494 int main(int argc, char **argv)
       
   495 {
       
   496     QApplication app(argc, argv);
       
   497 
       
   498     QScriptEngine eng;
       
   499     QPlainTextEdit edit;
       
   500 
       
   501     QScriptValue fun = eng.newFunction(myPrintFunction);
       
   502     fun.setData(eng.newQObject(&edit));
       
   503     eng.globalObject().setProperty("print", fun);
       
   504 
       
   505     eng.evaluate("print('hello', 'world')");
       
   506 
       
   507     edit.show();
       
   508     return app.exec();
       
   509 }
       
   510 //! [46]
       
   511 
       
   512 
       
   513 //! [47]
       
   514 QScriptEngine eng;
       
   515 QLineEdit *edit = new QLineEdit(...);
       
   516 QScriptValue handler = eng.evaluate("(function(text) { print('text was changed to', text); })");
       
   517 qScriptConnect(edit, SIGNAL(textChanged(const QString &)), QScriptValue(), handler);
       
   518 //! [47]
       
   519 
       
   520 //! [48]
       
   521 QLineEdit *edit1 = new QLineEdit(...);
       
   522 QLineEdit *edit2 = new QLineEdit(...);
       
   523 
       
   524 QScriptValue handler = eng.evaluate("(function() { print('I am', this.name); })");
       
   525 QScriptValue obj1 = eng.newObject();
       
   526 obj1.setProperty("name", "the walrus");
       
   527 QScriptValue obj2 = eng.newObject();
       
   528 obj2.setProperty("name", "Sam");
       
   529 
       
   530 qScriptConnect(edit1, SIGNAL(returnPressed()), obj1, handler);
       
   531 qScriptConnect(edit2, SIGNAL(returnPressed()), obj2, handler);
       
   532 //! [48]
       
   533 
       
   534 //! [49]
       
   535 var getProperty = function(name) { return this[name]; };
       
   536 
       
   537 name = "Global Object"; // creates a global variable
       
   538 print(getProperty("name")); // "Global Object"
       
   539 
       
   540 var myObject = { name: 'My Object' };
       
   541 print(getProperty.call(myObject, "name")); // "My Object"
       
   542 
       
   543 myObject.getProperty = getProperty;
       
   544 print(myObject.getProperty("name")); // "My Object"
       
   545 
       
   546 getProperty.name = "The getProperty() function";
       
   547 getProperty.getProperty = getProperty;
       
   548 getProperty.getProperty("name"); // "The getProperty() function"
       
   549 //! [49]
       
   550 
       
   551 //! [50]
       
   552 var o = { a: 1, b: 2, sum: function() { return a + b; } };
       
   553 print(o.sum()); // reference error, or sum of global variables a and b!!
       
   554 //! [50]
       
   555 
       
   556 //! [51]
       
   557 var o = { a: 1, b: 2, sum: function() { return this.a + this.b; } };
       
   558 print(o.sum()); // 3
       
   559 //! [51]
       
   560 
       
   561 //! [52]
       
   562 QScriptValue getProperty(QScriptContext *ctx, QScriptEngine *eng)
       
   563 {
       
   564     QString name = ctx->argument(0).toString();
       
   565     return ctx->thisObject().property(name);
       
   566 }
       
   567 //! [52]
       
   568 
       
   569 //! [53]
       
   570 QScriptValue myCompare(QScriptContext *ctx, QScriptEngine *eng)
       
   571 {
       
   572     double first = ctx->argument(0).toNumber();
       
   573     double second = ctx->argument(1).toNumber();
       
   574     int result;
       
   575     if (first == second)
       
   576         result = 0;
       
   577     else if (first < second)
       
   578         result = -1;
       
   579     else
       
   580         result = 1;
       
   581     return result;
       
   582 }
       
   583 //! [53]
       
   584 
       
   585 //! [54]
       
   586 QScriptEngine eng;
       
   587 QScriptValue comparefn = eng.newFunction(myCompare);
       
   588 QScriptValue array = eng.evaluate("new Array(10, 5, 20, 15, 30)");
       
   589 array.property("sort").call(array, QScriptValueList() << comparefn);
       
   590 
       
   591 // prints "5,10,15,20,30"
       
   592 qDebug() << array.toString();
       
   593 //! [54]
       
   594 
       
   595 //! [55]
       
   596 QScriptValue rectifier(QScriptContext *ctx, QScriptEngine *eng)
       
   597 {
       
   598     QRectF magicRect = qscriptvalue_cast<QRectF>(ctx->callee().data());
       
   599     QRectF sourceRect = qscriptvalue_cast<QRectF>(ctx->argument(0));
       
   600     return eng->toScriptValue(sourceRect.intersected(magicRect));
       
   601 }
       
   602 
       
   603 ...
       
   604 
       
   605 QScriptValue fun = eng.newFunction(rectifier);
       
   606 QRectF magicRect = QRectF(10, 20, 30, 40);
       
   607 fun.setData(eng.toScriptValue(magicRect));
       
   608 eng.globalObject().setProperty("rectifier", fun);
       
   609 //! [55]
       
   610 
       
   611 //! [56]
       
   612 function add(a, b) {
       
   613     return a + b;
       
   614 }
       
   615 //! [56]
       
   616 
       
   617 //! [57]
       
   618 function add() {
       
   619     return arguments[0] + arguments[1];
       
   620 }
       
   621 //! [57]
       
   622 
       
   623 //! [58]
       
   624 QScriptValue add(QScriptContext *ctx, QScriptEngine *eng)
       
   625 {
       
   626     double a = ctx->argument(0).toNumber();
       
   627     double b = ctx->argument(1).toNumber();
       
   628     return a + b;
       
   629 }
       
   630 //! [58]
       
   631 
       
   632 //! [59]
       
   633 function add() {
       
   634     if (arguments.length != 2)
       
   635         throw Error("add() takes exactly two arguments");
       
   636     return arguments[0] + arguments[1];
       
   637 }
       
   638 //! [59]
       
   639 
       
   640 //! [60]
       
   641 function add() {
       
   642     if (arguments.length != 2)
       
   643         throw Error("add() takes exactly two arguments");
       
   644     if (typeof arguments[0] != "number")
       
   645         throw TypeError("add(): first argument is not a number");
       
   646     if (typeof arguments[1] != "number")
       
   647         throw TypeError("add(): second argument is not a number");
       
   648     return arguments[0] + arguments[1];
       
   649 }
       
   650 //! [60]
       
   651 
       
   652 //! [61]
       
   653 function add() {
       
   654     if (arguments.length != 2)
       
   655         throw Error("add() takes exactly two arguments");
       
   656     return Number(arguments[0]) + Number(arguments[1]);
       
   657 }
       
   658 //! [61]
       
   659 
       
   660 //! [62]
       
   661 QScriptValue add(QScriptContext *ctx, QScriptEngine *eng)
       
   662 {
       
   663     if (ctx->argumentCount() != 2)
       
   664         return ctx->throwError("add() takes exactly two arguments");
       
   665     double a = ctx->argument(0).toNumber();
       
   666     double b = ctx->argument(1).toNumber();
       
   667     return a + b;
       
   668 }
       
   669 //! [62]
       
   670 
       
   671 //! [63]
       
   672 QScriptValue add(QScriptContext *ctx, QScriptEngine *eng)
       
   673 {
       
   674     if (ctx->argumentCount() != 2)
       
   675         return ctx->throwError("add() takes exactly two arguments");
       
   676     if (!ctx->argument(0).isNumber())
       
   677         return ctx->throwError(QScriptContext::TypeError, "add(): first argument is not a number");
       
   678     if (!ctx->argument(1).isNumber())
       
   679         return ctx->throwError(QScriptContext::TypeError, "add(): second argument is not a number");
       
   680     double a = ctx->argument(0).toNumber();
       
   681     double b = ctx->argument(1).toNumber();
       
   682     return a + b;
       
   683 }
       
   684 //! [63]
       
   685 
       
   686 //! [64]
       
   687 function concat() {
       
   688     var result = "";
       
   689     for (var i = 0; i < arguments.length; ++i)
       
   690         result += String(arguments[i]);
       
   691     return result;
       
   692 }
       
   693 //! [64]
       
   694 
       
   695 //! [65]
       
   696 QScriptValue concat(QScriptContext *ctx, QScriptEngine *eng)
       
   697 {
       
   698     QString result = "";
       
   699     for (int i = 0; i < ctx->argumentCount(); ++i)
       
   700         result += ctx->argument(i).toString();
       
   701     return result;
       
   702 }
       
   703 //! [65]
       
   704 
       
   705 //! [66]
       
   706 function sort(comparefn) {
       
   707     if (comparefn == undefined)
       
   708         comparefn = /* the built-in comparison function */;
       
   709     else if (typeof comparefn != "function")
       
   710         throw TypeError("sort(): argument must be a function");
       
   711     ...
       
   712 }
       
   713 //! [66]
       
   714 
       
   715 //! [67]
       
   716 QScriptValue sort(QScriptContext *ctx, QScriptEngine *eng)
       
   717 {
       
   718     QScriptValue comparefn = ctx->argument(0);
       
   719     if (comparefn.isUndefined())
       
   720         comparefn = /* the built-in comparison function */;
       
   721     else if (!comparefn.isFunction())
       
   722         return ctx->throwError(QScriptContext::TypeError, "sort(): argument is not a function");
       
   723     ...
       
   724 }
       
   725 //! [67]
       
   726 
       
   727 //! [68]
       
   728 function foo() {
       
   729     // Let bar() take care of this.
       
   730     print("calling bar() with " + arguments.length + "arguments");
       
   731     var result = return bar.apply(this, arguments);
       
   732     print("bar() returned" + result);
       
   733     return result;
       
   734 }
       
   735 //! [68]
       
   736 
       
   737 //! [69]
       
   738 QScriptValue foo(QScriptContext *ctx, QScriptEngine *eng)
       
   739 {
       
   740     QScriptValue bar = eng->globalObject().property("bar");
       
   741     QScriptValue arguments = ctx->argumentsObject();
       
   742     qDebug() << "calling bar() with" << arguments.property("length").toInt32() << "arguments";
       
   743     QScriptValue result = bar.apply(ctx->thisObject(), arguments);
       
   744     qDebug() << "bar() returned" << result.toString();
       
   745     return result;
       
   746 }
       
   747 //! [69]
       
   748 
       
   749 //! [70]
       
   750 function counter() {
       
   751     var count = 0;
       
   752     return function() {
       
   753         return count++;
       
   754     }
       
   755 }
       
   756 //! [70]
       
   757 
       
   758 //! [71]
       
   759 var c1 = counter(); // create a new counter function
       
   760 var c2 = counter(); // create a new counter function
       
   761 print(c1()); // 0
       
   762 print(c1()); // 1
       
   763 print(c2()); // 0
       
   764 print(c2()); // 1
       
   765 //! [71]
       
   766 
       
   767 //! [72]
       
   768 QScriptValue counter(QScriptContext *ctx, QScriptEngine *eng)
       
   769 {
       
   770     QScriptValue act = ctx->activationObject();
       
   771     act.setProperty("count", 0);
       
   772     QScriptValue result = eng->newFunction(counter_inner);
       
   773     result.setScope(act);
       
   774     return result;
       
   775 }
       
   776 //! [72]
       
   777 
       
   778 //! [73]
       
   779 QScriptValue counter_inner(QScriptContext *ctx, QScriptEngine *eng)
       
   780 {
       
   781     QScriptValue outerAct = ctx->callee().scope();
       
   782     double count = outerAct.property("count").toNumber();
       
   783     outerAct.setProperty("count", count+1);
       
   784     return count;
       
   785 }
       
   786 //! [73]
       
   787 
       
   788 //! [74]
       
   789 QScriptValue counter_hybrid(QScriptContext *ctx, QScriptEngine *eng)
       
   790 {
       
   791     QScriptValue act = ctx->activationObject();
       
   792     act.setProperty("count", 0);
       
   793     return eng->evaluate("(function() { return count++; })");
       
   794 }
       
   795 //! [74]
       
   796 
       
   797 //! [75]
       
   798 function Book(isbn) {
       
   799     this.isbn = isbn;
       
   800 }
       
   801 
       
   802 var coolBook1 = new Book("978-0131872493");
       
   803 var coolBook2 = new Book("978-1593271473");
       
   804 //! [75]
       
   805 
       
   806 //! [76]
       
   807 QScriptValue Person_ctor(QScriptContext *ctx, QScriptEngine *eng)
       
   808 {
       
   809     QScriptValue object;
       
   810     if (ctx->isCalledAsConstructor()) {
       
   811         object = ctx->thisObject();
       
   812     } else {
       
   813         object = eng->newObject();
       
   814         object.setPrototype(ctx->callee().property("prototype"));
       
   815     }
       
   816     object.setProperty("name", ctx->argument(0));
       
   817     return object;
       
   818 }
       
   819 //! [76]
       
   820 
       
   821 //! [77]
       
   822 QScriptContext *ctx = eng.pushContext();
       
   823 QScriptValue act = ctx->activationObject();
       
   824 act.setProperty("digit", 7);
       
   825 
       
   826 qDebug() << eng.evaluate("digit + 1").toNumber(); // 8
       
   827 
       
   828 eng.popContext();
       
   829 //! [77]
       
   830 
       
   831 //! [78]
       
   832 QScriptValue getSet(QScriptContext *ctx, QScriptEngine *eng)
       
   833 {
       
   834     QScriptValue obj = ctx->thisObject();
       
   835     QScriptValue data = obj.data();
       
   836     if (!data.isValid()) {
       
   837         data = eng->newObject();
       
   838         obj.setData(data);
       
   839     }
       
   840     QScriptValue result;
       
   841     if (ctx->argumentCount() == 1) {
       
   842         QString str = ctx->argument(0).toString();
       
   843         str.replace("Roberta", "Ken");
       
   844         result = str;
       
   845         data.setProperty("x", result);
       
   846     } else {
       
   847         result = data.property("x");
       
   848     }
       
   849     return result;
       
   850 }
       
   851 //! [78]
       
   852 
       
   853 //! [79]
       
   854 QScriptEngine eng;
       
   855 QScriptValue obj = eng.newObject();
       
   856 obj.setProperty("x", eng.newFunction(getSet),
       
   857                 QScriptValue::PropertyGetter|QScriptValue::PropertySetter);
       
   858 //! [79]
       
   859 
       
   860 //! [80]
       
   861 obj.x = "Roberta sent me";
       
   862 print(obj.x); // "Ken sent me"
       
   863 obj.x = "I sent the bill to Roberta";
       
   864 print(obj.x); // "I sent the bill to Ken"
       
   865 //! [80]
       
   866 
       
   867 //! [81]
       
   868 obj = {};
       
   869 obj.__defineGetter__("x", function() { return this._x; });
       
   870 obj.__defineSetter__("x", function(v) { print("setting x to", v); this._x = v; });
       
   871 obj.x = 123;
       
   872 //! [81]
       
   873 
       
   874 //! [82]
       
   875 myButton.text = qsTr("Hello world!");
       
   876 //! [82]
       
   877 
       
   878 //! [83]
       
   879 myButton.text = qsTranslate("MyAwesomeScript", "Hello world!");
       
   880 //! [83]
       
   881 
       
   882 //! [84]
       
   883 FriendlyConversation.prototype.greeting = function(type)
       
   884 {
       
   885     if (FriendlyConversation['greeting_strings'] == undefined) {
       
   886         FriendlyConversation['greeting_strings'] = [
       
   887             QT_TR_NOOP("Hello"),
       
   888             QT_TR_NOOP("Goodbye")
       
   889         ];
       
   890     }
       
   891     return qsTr(FriendlyConversation.greeting_strings[type]);
       
   892 }
       
   893 //! [84]
       
   894 
       
   895 //! [85]
       
   896 FriendlyConversation.prototype.greeting = function(type)
       
   897 {
       
   898     if (FriendlyConversation['greeting_strings'] == undefined) {
       
   899         FriendlyConversation['greeting_strings'] = [
       
   900             QT_TRANSLATE_NOOP("FriendlyConversation", "Hello"),
       
   901             QT_TRANSLATE_NOOP("FriendlyConversation", "Goodbye")
       
   902         ];
       
   903     }
       
   904     return qsTranslate("FriendlyConversation", FriendlyConversation.greeting_strings[type]);
       
   905 }
       
   906 //! [85]
       
   907 
       
   908 //! [86]
       
   909 FileCopier.prototype.showProgress = function(done, total, currentFileName)
       
   910 {
       
   911     this.label.text = qsTr("%1 of %2 files copied.\nCopying: %3")
       
   912                       .arg(done)
       
   913                       .arg(total)
       
   914                       .arg(currentFileName));
       
   915 }
       
   916 //! [86]
       
   917 
       
   918 //! [87]
       
   919 lupdate myscript.qs -ts myscript_la.ts
       
   920 //! [87]
       
   921 
       
   922 //! [88]
       
   923 lupdate -extensions qs scripts/ -ts scripts_la.ts
       
   924 //! [88]
       
   925 
       
   926 //! [89]
       
   927 lrelease myscript_la.ts
       
   928 //! [89]
       
   929 
       
   930 //! [90]
       
   931 ({ unitName: "Celsius",
       
   932    toKelvin: function(x) { return x + 273; }
       
   933  })
       
   934 //! [90]
       
   935 
       
   936 //! [91]
       
   937 QScriptValue object = engine.evaluate("({ unitName: 'Celsius', toKelvin: function(x) { return x + 273; } })");
       
   938 QScriptValue toKelvin = object.property("toKelvin");
       
   939 QScriptValue result = toKelvin.call(object, QScriptValueList() << 100);
       
   940 qDebug() << result.toNumber(); // 373
       
   941 //! [91]
       
   942 
       
   943 //! [92]
       
   944 QScriptValue add = engine.globalObject().property("add");
       
   945 qDebug() << add.call(QScriptValue(), QScriptValueList() << 1 << 2).toNumber(); // 3
       
   946 //! [92]
       
   947 
       
   948 //! [93]
       
   949 typedef QSharedPointer<QXmlStreamReader> XmlStreamReaderPointer;
       
   950 
       
   951 Q_DECLARE_METATYPE(XmlStreamReaderPointer)
       
   952 
       
   953 QScriptValue constructXmlStreamReader(QScriptContext *context, QScriptEngine *engine)
       
   954 {
       
   955     if (!context->isCalledAsConstructor())
       
   956         return context->throwError(QScriptContext::SyntaxError, "please use the 'new' operator");
       
   957 
       
   958     QIODevice *device = qobject_cast<QIODevice*>(context->argument(0).toQObject());
       
   959     if (!device)
       
   960         return context->throwError(QScriptContext::TypeError, "please supply a QIODevice as first argument");
       
   961 
       
   962     // Create the C++ object
       
   963     QXmlStreamReader *reader = new QXmlStreamReader(device);
       
   964 
       
   965     XmlStreamReaderPointer pointer(reader);
       
   966 
       
   967     // store the shared pointer in the script object that we are constructing
       
   968     return engine->newVariant(context->thisObject(), qVariantFromValue(pointer));
       
   969 }
       
   970 //! [93]
       
   971 
       
   972 //! [94]
       
   973 QScriptValue xmlStreamReader_atEnd(QScriptContext *context, QScriptEngine *)
       
   974 {
       
   975     XmlStreamReaderPointer reader = qscriptvalue_cast<XmlStreamReaderPointer>(context->thisObject());
       
   976     if (!reader)
       
   977         return context->throwError(QScriptContext::TypeError, "this object is not an XmlStreamReader");
       
   978     return reader->atEnd();
       
   979 }
       
   980 //! [94]
       
   981 
       
   982 //! [95]
       
   983     QScriptEngine engine;
       
   984     QScriptValue xmlStreamReaderProto = engine.newObject();
       
   985     xmlStreamReaderProto.setProperty("atEnd", engine.newFunction(xmlStreamReader_atEnd));
       
   986 
       
   987     QScriptValue xmlStreamReaderCtor = engine.newFunction(constructXmlStreamReader, xmlStreamReaderProto);
       
   988     engine.globalObject().setProperty("XmlStreamReader", xmlStreamReaderCtor);
       
   989 //! [95]