From 7d566bc4eb5b5e47b48f28012fed24109a8dd735 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 1 Sep 2009 15:52:10 +1000 Subject: Remove unused member variables from QmlEnginePrivate --- src/declarative/qml/qmlengine.cpp | 9 +-------- src/declarative/qml/qmlengine_p.h | 4 ---- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 1640dcb..652144d 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -107,7 +107,7 @@ QScriptValue desktopOpenUrl(QScriptContext *ctxt, QScriptEngine *e) } QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e) -: rootContext(0), currentBindContext(0), currentExpression(0), +: rootContext(0), currentExpression(0), isDebugging(false), contextClass(0), objectClass(0), valueTypeClass(0), nodeListClass(0), namedNodeMapClass(0), scriptEngine(this), rootComponent(0), networkAccessManager(0), typeManager(e), uniqueId(1) @@ -199,13 +199,6 @@ void QmlEnginePrivate::init() } } -QmlContext *QmlEnginePrivate::setCurrentBindContext(QmlContext *c) -{ - QmlContext *old = currentBindContext; - currentBindContext = c; - return old; -} - QmlEnginePrivate::CapturedProperty::CapturedProperty(const QmlMetaProperty &p) : object(p.object()), coreIndex(p.coreIndex()), notifyIndex(p.property().notifySignalIndex()) { diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index b3c6279..b595e7c 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -114,7 +114,6 @@ public: QPODVector capturedProperties; QmlContext *rootContext; - QmlContext *currentBindContext; // ### Remove me QmlExpression *currentExpression; bool isDebugging; #ifdef QT_SCRIPTTOOLS_LIB @@ -128,9 +127,6 @@ public: QScriptClass *nodeListClass; QScriptClass *namedNodeMapClass; - QmlContext *setCurrentBindContext(QmlContext *); - QStack activeContexts; // ### Remove me - struct QmlScriptEngine : public QScriptEngine { QmlScriptEngine(QmlEnginePrivate *priv) -- cgit v0.12 From dbdaaa78c6b7c7a9498de9703d15b654eab163de Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 2 Sep 2009 10:49:14 +1000 Subject: Fix propertyValueSource test --- tests/auto/declarative/qmlparser/tst_qmlparser.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp index 36471a4..e953717 100644 --- a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp +++ b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp @@ -429,23 +429,25 @@ void tst_qmlparser::autoComponentCreation() void tst_qmlparser::propertyValueSource() { - QVERIFY(false); - -/* Does not compile... - QmlComponent component(&engine, TEST_FILE("propertyValueSource.qml")); VERIFY_ERRORS(0); MyTypeObject *object = qobject_cast(component.create()); QVERIFY(object != 0); - QList valueSources = - object->findChildren(); + + QList valueSources; + QObjectList allChildren = object->findChildren(); + foreach (QObject *child, allChildren) { + QmlType *type = QmlMetaType::qmlType(child->metaObject()); + if (type && type->propertyValueSourceCast() != -1) + valueSources.append(child); + } + QCOMPARE(valueSources.count(), 1); MyPropertyValueSource *valueSource = qobject_cast(valueSources.at(0)); QVERIFY(valueSource != 0); QCOMPARE(valueSource->prop.object(), object); QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty"))); -*/ } void tst_qmlparser::attachedProperties() -- cgit v0.12 From 5ef36ea88e15bb4a12575c6639b1d9e6c3be9de6 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 2 Sep 2009 10:57:30 +1000 Subject: Add TextInput key handling test --- .../declarative/qfxtextinput/data/navigation.qml | 23 +++++++ .../auto/declarative/qfxtextinput/qfxtextinput.pro | 6 ++ .../declarative/qfxtextinput/tst_qfxtextinput.cpp | 78 ++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 tests/auto/declarative/qfxtextinput/data/navigation.qml create mode 100644 tests/auto/declarative/qfxtextinput/qfxtextinput.pro create mode 100644 tests/auto/declarative/qfxtextinput/tst_qfxtextinput.cpp diff --git a/tests/auto/declarative/qfxtextinput/data/navigation.qml b/tests/auto/declarative/qfxtextinput/data/navigation.qml new file mode 100644 index 0000000..c1a6162 --- /dev/null +++ b/tests/auto/declarative/qfxtextinput/data/navigation.qml @@ -0,0 +1,23 @@ +import Qt 4.6 + +Rectangle { + property var myInput: Input + + width: 800; height: 600; color: "blue" + + Item { + id: FirstItem + KeyNavigation.right: Input + } + + TextInput { id: Input; focus: true; + KeyNavigation.left: FirstItem + KeyNavigation.right: LastItem + KeyNavigation.up: FirstItem + KeyNavigation.down: LastItem + } + Item { + id: LastItem + KeyNavigation.left: Input + } +} diff --git a/tests/auto/declarative/qfxtextinput/qfxtextinput.pro b/tests/auto/declarative/qfxtextinput/qfxtextinput.pro new file mode 100644 index 0000000..396e66d --- /dev/null +++ b/tests/auto/declarative/qfxtextinput/qfxtextinput.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative gui +SOURCES += tst_qfxtextinput.cpp + +# Define SRCDIR equal to test's source directory +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qfxtextinput/tst_qfxtextinput.cpp b/tests/auto/declarative/qfxtextinput/tst_qfxtextinput.cpp new file mode 100644 index 0000000..852a868 --- /dev/null +++ b/tests/auto/declarative/qfxtextinput/tst_qfxtextinput.cpp @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include + +class tst_qfxtextinput : public QObject + +{ + Q_OBJECT +public: + tst_qfxtextinput(); + +private slots: + void navigation(); + +private: + void simulateKey(QFxView *, int key); + QFxView *createView(const QString &filename); + + QmlEngine engine; +}; + +tst_qfxtextinput::tst_qfxtextinput() +{ +} + +/* +TextInput element should only handle left/right keys until the cursor reaches +the extent of the text, then they should ignore the keys. +*/ +void tst_qfxtextinput::navigation() +{ + QFxView *canvas = createView(SRCDIR "/data/navigation.qml"); + canvas->execute(); + canvas->show(); + + QVERIFY(canvas->root() != 0); + + QFxItem *input = qobject_cast(qvariant_cast(canvas->root()->property("myInput"))); + + QVERIFY(input != 0); + QVERIFY(input->hasFocus() == true); + simulateKey(canvas, Qt::Key_Left); + QVERIFY(input->hasFocus() == false); + simulateKey(canvas, Qt::Key_Right); + QVERIFY(input->hasFocus() == true); + simulateKey(canvas, Qt::Key_Right); + QVERIFY(input->hasFocus() == false); + simulateKey(canvas, Qt::Key_Left); + QVERIFY(input->hasFocus() == true); +} + +void tst_qfxtextinput::simulateKey(QFxView *view, int key) +{ + QKeyEvent press(QKeyEvent::KeyPress, key, 0); + QKeyEvent release(QKeyEvent::KeyRelease, key, 0); + + QApplication::sendEvent(view, &press); + QApplication::sendEvent(view, &release); +} + +QFxView *tst_qfxtextinput::createView(const QString &filename) +{ + QFxView *canvas = new QFxView(0); + + QFile file(filename); + file.open(QFile::ReadOnly); + QString xml = file.readAll(); + canvas->setQml(xml, filename); + + return canvas; +} + +QTEST_MAIN(tst_qfxtextinput) + +#include "tst_qfxtextinput.moc" -- cgit v0.12 From 964fd4a7272d8fb7ddcea578ac7dbe2596fb4482 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 2 Sep 2009 11:00:45 +1000 Subject: Clear animation only in the direction being fixed in fixupX/Y. --- src/declarative/fx/qfxflickable.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/declarative/fx/qfxflickable.cpp b/src/declarative/fx/qfxflickable.cpp index 27bfa27..d3e1a52 100644 --- a/src/declarative/fx/qfxflickable.cpp +++ b/src/declarative/fx/qfxflickable.cpp @@ -201,12 +201,12 @@ void QFxFlickablePrivate::fixupX() vTime = _tl.time(); if (_moveX.value() > q->minXExtent() || (q->maxXExtent() > q->maxXExtent())) { - _tl.clear(); + _tl.reset(_moveY); if (_moveX.value() != q->minXExtent()) _tl.move(_moveX, q->minXExtent(), QEasingCurve(QEasingCurve::InOutQuad), 200); //emit flickingChanged(); } else if (_moveX.value() < q->maxXExtent()) { - _tl.clear(); + _tl.reset(_moveY); _tl.move(_moveX, q->maxXExtent(), QEasingCurve(QEasingCurve::InOutQuad), 200); //emit flickingChanged(); } else { @@ -223,12 +223,12 @@ void QFxFlickablePrivate::fixupY() vTime = _tl.time(); if (_moveY.value() > q->minYExtent() || (q->maxYExtent() > q->minYExtent())) { - _tl.clear(); + _tl.reset(_moveY); if (_moveY.value() != q->minYExtent()) _tl.move(_moveY, q->minYExtent(), QEasingCurve(QEasingCurve::InOutQuad), 200); //emit flickingChanged(); } else if (_moveY.value() < q->maxYExtent()) { - _tl.clear(); + _tl.reset(_moveY); _tl.move(_moveY, q->maxYExtent(), QEasingCurve(QEasingCurve::InOutQuad), 200); //emit flickingChanged(); } else { -- cgit v0.12 From 8eed5aa528f668acfa1831432f97f7333c7d9e71 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 2 Sep 2009 11:37:35 +1000 Subject: Flickable locked property changed to interactive. Note that the meaning of the property has been reversed. --- demos/declarative/contacts/contacts.qml | 2 +- examples/declarative/listview/recipes.qml | 6 +++--- .../contacts/3_Collections/2/ContactView.qml | 2 +- .../contacts/3_Collections/3/ContactView.qml | 2 +- src/declarative/QmlChanges.txt | 3 ++- src/declarative/fx/qfxflickable.cpp | 24 ++++++++++++++-------- src/declarative/fx/qfxflickable.h | 6 +++--- src/declarative/fx/qfxflickable_p.h | 2 +- src/declarative/fx/qfxgridview.cpp | 2 +- src/declarative/fx/qfxlistview.cpp | 2 +- 10 files changed, 29 insertions(+), 22 deletions(-) diff --git a/demos/declarative/contacts/contacts.qml b/demos/declarative/contacts/contacts.qml index 81d8352..f009631 100644 --- a/demos/declarative/contacts/contacts.qml +++ b/demos/declarative/contacts/contacts.qml @@ -105,7 +105,7 @@ Rectangle { } PropertyChanges { target: contactListView - locked: 1 + interactive: 0 } PropertyChanges { target: label diff --git a/examples/declarative/listview/recipes.qml b/examples/declarative/listview/recipes.qml index eac8bb5..2148ef4 100644 --- a/examples/declarative/listview/recipes.qml +++ b/examples/declarative/listview/recipes.qml @@ -104,9 +104,9 @@ Rectangle { // Make the detailed view fill the entire list area PropertyChanges { target: wrapper; height: List.height } // Move the list so that this item is at the top. - PropertyChanges { target: wrapper.ListView.view; explicit: true; yPosition: wrapper.y } + PropertyChanges { target: wrapper.ListView.view; explicit: true; viewportY: wrapper.y } // Disallow flicking while we're in detailed view - PropertyChanges { target: wrapper.ListView.view; locked: 1 } + PropertyChanges { target: wrapper.ListView.view; interactive: false } } ] transitions: [ @@ -115,7 +115,7 @@ Rectangle { ParallelAnimation { ColorAnimation { property: "color"; duration: 500 } NumberAnimation { - duration: 300; properties: "detailsOpacity,x,yPosition,height,width" + duration: 300; properties: "detailsOpacity,x,viewportY,height,width" } } } diff --git a/examples/declarative/tutorials/contacts/3_Collections/2/ContactView.qml b/examples/declarative/tutorials/contacts/3_Collections/2/ContactView.qml index d16e3ca..8ee51c3 100644 --- a/examples/declarative/tutorials/contacts/3_Collections/2/ContactView.qml +++ b/examples/declarative/tutorials/contacts/3_Collections/2/ContactView.qml @@ -84,7 +84,7 @@ Item { } PropertyChanges { target: contactListView - locked: 1 + interactive: 0 } PropertyChanges { target: label diff --git a/examples/declarative/tutorials/contacts/3_Collections/3/ContactView.qml b/examples/declarative/tutorials/contacts/3_Collections/3/ContactView.qml index bf73367..76dc3e2 100644 --- a/examples/declarative/tutorials/contacts/3_Collections/3/ContactView.qml +++ b/examples/declarative/tutorials/contacts/3_Collections/3/ContactView.qml @@ -102,7 +102,7 @@ Item { } PropertyChanges { target: contactListView - locked: 1 + interactive: 0 } PropertyChanges { target: label diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 069bf49..a401a70 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -1,7 +1,7 @@ QML API Review ============== -The QML API is being reviewed from 17 to 28 August 2009. This +The QML API is being reviewed from 17 to 4 September 2009. This file documents the changes. Note that the changes are incremental, so a rename A->B for example may be follow by another subseqent rename B->C, if later reviews override earlier reviews. @@ -47,6 +47,7 @@ Flickable: yPosition -> viewportY Flickable: xVelocity -> horizontalVelocity Flickable: yVelocity -> verticalVelocity Flickable: velocityDecay -> reportedVelocitySmoothing +Flickable: locked -> interactive (note reversal of meaning) WebView: idealWidth -> preferredWidth WebView: idealHeight -> preferredHeight WebView: status -> statusText diff --git a/src/declarative/fx/qfxflickable.cpp b/src/declarative/fx/qfxflickable.cpp index d3e1a52..0690df1 100644 --- a/src/declarative/fx/qfxflickable.cpp +++ b/src/declarative/fx/qfxflickable.cpp @@ -95,7 +95,7 @@ void ElasticValue::updateCurrentTime(int) QFxFlickablePrivate::QFxFlickablePrivate() : _flick(new QFxItem), _moveX(_flick, &QFxItem::setX), _moveY(_flick, &QFxItem::setY) , vWidth(-1), vHeight(-1), overShoot(true), flicked(false), moving(false), stealMouse(false) - , pressed(false), maxVelocity(-1), locked(false), dragMode(QFxFlickable::Hard) + , pressed(false), maxVelocity(-1), interactive(true), dragMode(QFxFlickable::Hard) , elasticY(_moveY), elasticX(_moveX), reportedVelocitySmoothing(100), horizontalVelocity(this), verticalVelocity(this) , vTime(0), atXEnd(false), atXBeginning(true), pageXPosition(0.), pageWidth(0.) , atYEnd(false), atYBeginning(true), pageYPosition(0.), pageHeight(0.) @@ -411,24 +411,30 @@ void QFxFlickable::setViewportY(qreal pos) } /*! - \qmlproperty bool Flickable::locked + \qmlproperty bool Flickable::interactive - A user cannot drag or flick a Flickable that is locked. + A user cannot drag or flick a Flickable that is not interactive. This property is useful for temporarily disabling flicking. This allows special interaction with Flickable's children: for example, you might want to freeze a flickable map while viewing detailed information on a location popup that is a child of the Flickable. */ -bool QFxFlickable::isLocked() const +bool QFxFlickable::isInteractive() const { Q_D(const QFxFlickable); - return d->locked; + return d->interactive; } -void QFxFlickable::setLocked(bool lock) +void QFxFlickable::setInteractive(bool interactive) { Q_D(QFxFlickable); - d->locked = lock; + d->interactive = interactive; + if (!interactive && d->flicked) { + d->_tl.clear(); + d->flicked = false; + emit flickingChanged(); + emit flickEnded(); + } } /*! @@ -577,7 +583,7 @@ qreal QFxFlickable::visibleY() const void QFxFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event) { - if (!locked && _tl.isActive() && (qAbs(velocityX) > 10 || qAbs(velocityY) > 10)) + if (interactive && _tl.isActive() && (qAbs(velocityX) > 10 || qAbs(velocityY) > 10)) stealMouse = true; // If we've been flicked then steal the click. else stealMouse = false; @@ -602,7 +608,7 @@ void QFxFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event) void QFxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) { Q_Q(QFxFlickable); - if (locked || lastPosTime.isNull()) + if (!interactive || lastPosTime.isNull()) return; bool rejectY = false; bool rejectX = false; diff --git a/src/declarative/fx/qfxflickable.h b/src/declarative/fx/qfxflickable.h index c27b29f..57a01d7 100644 --- a/src/declarative/fx/qfxflickable.h +++ b/src/declarative/fx/qfxflickable.h @@ -69,7 +69,7 @@ class Q_DECLARATIVE_EXPORT QFxFlickable : public QFxItem Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged) Q_PROPERTY(bool flicking READ isFlicking NOTIFY flickingChanged) - Q_PROPERTY(bool locked READ isLocked WRITE setLocked) //### interactive, ensure flicking is stopped, etc. + Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive) Q_PROPERTY(DragMode dragMode READ dragMode WRITE setDragMode) //### remove. Consider a better way to implement different drag behavior Q_PROPERTY(bool atXEnd READ isAtXEnd NOTIFY isAtBoundaryChanged) @@ -117,8 +117,8 @@ public: qreal maximumFlickVelocity() const; void setMaximumFlickVelocity(qreal); - bool isLocked() const; - void setLocked(bool); + bool isInteractive() const; + void setInteractive(bool); Q_ENUMS(DragMode) enum DragMode { Hard, Elastic }; diff --git a/src/declarative/fx/qfxflickable_p.h b/src/declarative/fx/qfxflickable_p.h index a0ac011..ad9484f 100644 --- a/src/declarative/fx/qfxflickable_p.h +++ b/src/declarative/fx/qfxflickable_p.h @@ -121,7 +121,7 @@ public: QmlTimeLineEvent fixupXEvent; QmlTimeLineEvent fixupYEvent; qreal maxVelocity; - bool locked; + bool interactive; QFxFlickable::DragMode dragMode; ElasticValue elasticY; ElasticValue elasticX; diff --git a/src/declarative/fx/qfxgridview.cpp b/src/declarative/fx/qfxgridview.cpp index 138a8ae..6fd080b 100644 --- a/src/declarative/fx/qfxgridview.cpp +++ b/src/declarative/fx/qfxgridview.cpp @@ -1069,7 +1069,7 @@ qreal QFxGridView::maxXExtent() const void QFxGridView::keyPressEvent(QKeyEvent *event) { Q_D(QFxGridView); - if (d->model && d->model->count() && !d->locked) { + if (d->model && d->model->count() && d->interactive) { if ((d->flow == QFxGridView::LeftToRight && event->key() == Qt::Key_Up) || (d->flow == QFxGridView::TopToBottom && event->key() == Qt::Key_Left)) { if (currentIndex() >= d->columns || d->wrap) { diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp index 147c977..34fe827 100644 --- a/src/declarative/fx/qfxlistview.cpp +++ b/src/declarative/fx/qfxlistview.cpp @@ -1344,7 +1344,7 @@ qreal QFxListView::maxXExtent() const void QFxListView::keyPressEvent(QKeyEvent *event) { Q_D(QFxListView); - if (d->model && d->model->count() && !d->locked) { + if (d->model && d->model->count() && d->interactive) { if ((d->orient == Qt::Horizontal && event->key() == Qt::Key_Left) || (d->orient == Qt::Vertical && event->key() == Qt::Key_Up)) { if (currentIndex() > 0 || d->wrap) { -- cgit v0.12 From 1ccca16e3e032cb90d09dc4a161fe35114d8360d Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 2 Sep 2009 12:59:09 +1000 Subject: SameGame high score server support. This commit contains all the functionality for sending high scores to a server, and the server. The server files have been installed at http://qtfx-nokia.trolltech.com.au/samegame for internal testing. --- demos/declarative/samegame/content/samegame.js | 46 +++++++++++++++++++++- demos/declarative/samegame/highscores/README | 1 + .../declarative/samegame/highscores/score_data.xml | 2 + .../samegame/highscores/score_style.xsl | 27 +++++++++++++ demos/declarative/samegame/highscores/scores.php | 34 ++++++++++++++++ 5 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 demos/declarative/samegame/highscores/README create mode 100755 demos/declarative/samegame/highscores/score_data.xml create mode 100755 demos/declarative/samegame/highscores/score_style.xsl create mode 100755 demos/declarative/samegame/highscores/scores.php diff --git a/demos/declarative/samegame/content/samegame.js b/demos/declarative/samegame/content/samegame.js index f04fb4c..355dbfd 100755 --- a/demos/declarative/samegame/content/samegame.js +++ b/demos/declarative/samegame/content/samegame.js @@ -6,13 +6,22 @@ var tileSize = 40; var maxIndex = maxX*maxY; var board = new Array(maxIndex); var tileSrc = "content/BoomBlock.qml"; +var scoresURL = "http://qtfx-nokia.trolltech.com.au/samegame/scores.php"; +var timer; var component; //Index function used instead of a 2D array -function index(xIdx,yIdx){ +function index(xIdx,yIdx) { return xIdx + (yIdx * maxX); } +function timeStr(msecs) { + var secs = Math.floor(msecs/1000); + var m = Math.floor(secs/60); + var ret = "" + m + "m " + (secs%60) + "s"; + return ret; +} + function initBoard() { for(i = 0; i1000000Alan the Tester0x00 +6213Alan12x1751 diff --git a/demos/declarative/samegame/highscores/score_style.xsl b/demos/declarative/samegame/highscores/score_style.xsl new file mode 100755 index 0000000..7dcf07e --- /dev/null +++ b/demos/declarative/samegame/highscores/score_style.xsl @@ -0,0 +1,27 @@ + + + + + SameGame High Scores + +

SameGame High Scores

+ + + + + + + + + + + + + + + +
NameScoreGrid SizeTime, s
+ + +
+
diff --git a/demos/declarative/samegame/highscores/scores.php b/demos/declarative/samegame/highscores/scores.php new file mode 100755 index 0000000..3cceb2d --- /dev/null +++ b/demos/declarative/samegame/highscores/scores.php @@ -0,0 +1,34 @@ +"; + echo "SameGame High Scores"; + if($score > 0){#Sending in a new high score + $name = $_POST["name"]; + $grid = $_POST["gridSize"]; + $time = $_POST["time"]; + if($name == "") + $name = "Anonymous"; + //if($grid != "10x10"){ + //Need a standard, so as to reject others? + //} + $file = fopen("score_data.xml", "a"); #It's XML. Happy? + $ret = fwrite($file, "". $score . "" + . $name . "" . $grid . "" + . $time . "\n"); + echo "Your score has been recorded. Thanks for playing!"; + if($ret == False) + echo "
There was an error though, so don't expect to see that score again."; + }else{#Read high score list + #Now uses XSLT to display. So just print the file. With XML cruft added. + #Note that firefox at least won't apply the XSLT on a php file. So redirecting + $file = fopen("scores.xml", "w"); + $ret = fwrite($file, '' . "\n" + . '' . "\n" + . "\n" . file_get_contents("score_data.xml") . "\n"); + if($ret == False) + echo "There was an internal error. Sorry."; + else + echo ''; + } + echo ""; +?> -- cgit v0.12 From 9c831fc9a405dcfefbbf4bad09a8f95bd682c0eb Mon Sep 17 00:00:00 2001 From: "Mehul R. Patel" Date: Wed, 2 Sep 2009 13:16:35 +1000 Subject: =?UTF-8?q?Fixed=20crash=20in=20keyPressed.=20keyToSignal=20functi?= =?UTF-8?q?on=20suppose=20to=20return=20=E2=80=9Cconst=20QbyteArray?= =?UTF-8?q?=E2=80=9D=20not=20=E2=80=9Cconst=20char=20*=E2=80=9D.=20Crash?= =?UTF-8?q?=20was=20coming=20because=20keyPressed=20was=20getting=20invali?= =?UTF-8?q?d=20memory=20pointer=20from=20keyToSignal=20function.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge-request: 1374 Reviewed-by: Martin Jones --- src/declarative/fx/qfxitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp index c436622..d28f531 100644 --- a/src/declarative/fx/qfxitem.cpp +++ b/src/declarative/fx/qfxitem.cpp @@ -928,7 +928,7 @@ private: virtual void keyPressed(QKeyEvent *event); virtual void keyReleased(QKeyEvent *event); - const char *keyToSignal(int key) { + const QByteArray keyToSignal(int key) { QByteArray keySignal; if (key >= Qt::Key_0 && key <= Qt::Key_9) { keySignal = "digit0Pressed"; -- cgit v0.12 From c67b9e5e9925d422dca0c5243f91c3e08fe90304 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 2 Sep 2009 13:25:52 +1000 Subject: SameGame now asks for a name and saves your score. Included a rewriting of the Dialog item to be half-decent. Watch http://qtfx-nokia.trolltech.com.au/samegame/scores.php on the internal network for highscores! --- demos/declarative/samegame/SameGame.qml | 13 +++++++++++++ demos/declarative/samegame/content/Dialog.qml | 18 ++++++++++++------ demos/declarative/samegame/content/samegame.js | 12 +++++------- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/demos/declarative/samegame/SameGame.qml b/demos/declarative/samegame/SameGame.qml index 0da5679..877c1cc 100644 --- a/demos/declarative/samegame/SameGame.qml +++ b/demos/declarative/samegame/SameGame.qml @@ -34,6 +34,19 @@ Rectangle { } Dialog { id: dialog; anchors.centerIn: parent; z: 21 } + Dialog { + id: scoreName; anchors.centerIn: parent; z: 22; + TextInput { + id: Editor + onAccepted: { + if(scoreName.opacity==1&&Editor.text!="") + sendHighScore(Editor.text); + scoreName.forceClose(); + } + anchors.verticalCenter: parent.verticalCenter + x:160; width: 200; height:20; focus: true + } + } Rectangle { id: ToolBar diff --git a/demos/declarative/samegame/content/Dialog.qml b/demos/declarative/samegame/content/Dialog.qml index 72c7900..401d211 100644 --- a/demos/declarative/samegame/content/Dialog.qml +++ b/demos/declarative/samegame/content/Dialog.qml @@ -2,14 +2,20 @@ import Qt 4.6 Rectangle { id: page + function forceClose() { + page.closed(); + page.opacity = 0; + } + function show(txt) { + MyText.text = txt; + page.opacity = 1; + } + signal closed(); color: "white"; border.width: 1; width: MyText.width + 20; height: 60; - property string text: "Hello World!" opacity: 0 opacity: Behavior { - SequentialAnimation { - NumberAnimation {property: "opacity"; from: 0; duration: 1500 } - NumberAnimation {property: "opacity"; to: 0; duration: 1500 } - } + NumberAnimation { duration: 1000 } } - Text { id: MyText; anchors.centerIn: parent; text: parent.text } + Text { id: MyText; anchors.centerIn: parent; text: "Hello World!" } + MouseRegion { id: mr; anchors.fill: parent; onClicked: forceClose(); } } diff --git a/demos/declarative/samegame/content/samegame.js b/demos/declarative/samegame/content/samegame.js index 355dbfd..d890cd2 100755 --- a/demos/declarative/samegame/content/samegame.js +++ b/demos/declarative/samegame/content/samegame.js @@ -144,10 +144,10 @@ function victoryCheck() gameCanvas.score += 500; //Checks for game over if(deservesBonus || !(floodMoveCheck(0,maxY-1, -1))){ - dialog.text = "Game Over. Your score is " + gameCanvas.score; - dialog.opacity = 1; + dialog.show("Game Over. Your score is " + gameCanvas.score); timer = new Date() - timer; - //if(scoresURL != "") sendHighScore(name); + if(scoresURL != "") + scoreName.show("Please enter your name: "); } } @@ -233,8 +233,7 @@ function tweetHighScore(twitterName, twitterPass) { postman.open("POST", "http://twitter.com/statuses/update.xml", true, twitterName, twitterPass); postman.onreadystatechange = function() { if (postman.readyState == postman.DONE) { - dialog.text = "Your score has been tweeted for you."; - dialog.opacity = 1; + dialog.show("Your score has been tweeted for you."); } } postman.send(postData); @@ -247,8 +246,7 @@ function sendHighScore(name) { postman.open("POST", scoresURL, true); postman.onreadystatechange = function() { if (postman.readyState == postman.DONE) { - dialog.text = "Your score has been uploaded."; - dialog.opacity = 1; + dialog.show("Your score has been uploaded."); } } postman.send(postData); -- cgit v0.12 From 5477cb3bbc97e4b419c5ea5bbe4f137959b9140d Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 2 Sep 2009 13:29:08 +1000 Subject: Don't need to tweet high scores too --- demos/declarative/samegame/content/samegame.js | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/demos/declarative/samegame/content/samegame.js b/demos/declarative/samegame/content/samegame.js index d890cd2..9914edb 100755 --- a/demos/declarative/samegame/content/samegame.js +++ b/demos/declarative/samegame/content/samegame.js @@ -222,23 +222,6 @@ function startCreatingBlock(xIdx,yIdx){ return; } -function tweetHighScore(twitterName, twitterPass) { - if(twitterName == '' || twitterPass == '') - return false;//Can't login like that - - var scoreStr = "I just played the QML SameGame, and got " + gameCanvas.score + " points on a " - + maxX + "x" + maxY + " grid. It took me " + timeStr(timer) + "."; - var postData = "status=" + scoreStr; - var postman = new XMLHttpRequest(); - postman.open("POST", "http://twitter.com/statuses/update.xml", true, twitterName, twitterPass); - postman.onreadystatechange = function() { - if (postman.readyState == postman.DONE) { - dialog.show("Your score has been tweeted for you."); - } - } - postman.send(postData); -} - function sendHighScore(name) { var postman = new XMLHttpRequest() var postData = "name="+name+"&score="+gameCanvas.score -- cgit v0.12 From 9e7bd55bde0d614719c67977507b270dc7326f05 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 2 Sep 2009 13:34:07 +1000 Subject: Save object creation line and column number This info is used by the debugger interface, and by the qmlInfo() stream. --- src/declarative/qml/qmldeclarativedata_p.h | 5 +++++ src/declarative/qml/qmlenginedebug.cpp | 11 +++++++++-- src/declarative/qml/qmlinfo.cpp | 16 +++++++++++++++- src/declarative/qml/qmlinstruction_p.h | 1 + src/declarative/qml/qmlvme.cpp | 5 +++++ 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/declarative/qml/qmldeclarativedata_p.h b/src/declarative/qml/qmldeclarativedata_p.h index 5a51eb7..a316c0c 100644 --- a/src/declarative/qml/qmldeclarativedata_p.h +++ b/src/declarative/qml/qmldeclarativedata_p.h @@ -59,6 +59,7 @@ QT_BEGIN_NAMESPACE class QmlCompiledData; class QmlAbstractBinding; +class QmlContext; class QmlDeclarativeData : public QDeclarativeData { public: @@ -69,6 +70,10 @@ public: QmlContext *context; QmlAbstractBinding *bindings; + QmlContext *outerContext; // Can't this be found from context? + ushort lineNumber; + ushort columnNumber; + QmlCompiledData *deferredComponent; // Can't this be found from the context? unsigned int deferredIdx; diff --git a/src/declarative/qml/qmlenginedebug.cpp b/src/declarative/qml/qmlenginedebug.cpp index 0e78cad..321fe74 100644 --- a/src/declarative/qml/qmlenginedebug.cpp +++ b/src/declarative/qml/qmlenginedebug.cpp @@ -181,9 +181,16 @@ void QmlEngineDebugServer::buildObjectList(QDataStream &message, QmlEngineDebugServer::QmlObjectData QmlEngineDebugServer::objectData(QObject *object) { + QmlDeclarativeData *ddata = QmlDeclarativeData::get(object); QmlObjectData rv; - rv.lineNumber = -1; - rv.columnNumber = -1; + if (ddata) { + rv.url = ddata->outerContext->baseUrl(); + rv.lineNumber = ddata->lineNumber; + rv.columnNumber = ddata->columnNumber; + } else { + rv.lineNumber = -1; + rv.columnNumber = -1; + } rv.objectName = object->objectName(); rv.objectType = object->metaObject()->className(); diff --git a/src/declarative/qml/qmlinfo.cpp b/src/declarative/qml/qmlinfo.cpp index 65a4298..e47b4ab 100644 --- a/src/declarative/qml/qmlinfo.cpp +++ b/src/declarative/qml/qmlinfo.cpp @@ -40,6 +40,8 @@ ****************************************************************************/ #include "qmlinfo.h" +#include +#include QT_BEGIN_NAMESPACE @@ -80,7 +82,19 @@ QmlInfo::QmlInfo(QObject *object) *this << "QML"; if (object) *this << object->metaObject()->className(); - *this << "(unknown location):"; + QmlDeclarativeData *ddata = QmlDeclarativeData::get(object); + if (ddata) { + QString location = QLatin1String("("); + location += ddata->outerContext->baseUrl().toString(); + location += QLatin1String(":"); + location += QString::number(ddata->lineNumber); + location += QLatin1String(":"); + location += QString::number(ddata->columnNumber); + location += QLatin1String(")"); + *this << location.toLatin1().constData(); + } else { + *this << "(unknown location):"; + } } /*! diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h index 8861609a..ede06a2 100644 --- a/src/declarative/qml/qmlinstruction_p.h +++ b/src/declarative/qml/qmlinstruction_p.h @@ -170,6 +170,7 @@ public: struct { int type; int data; + ushort column; } create; struct { int data; diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index 930e6e4..7907195 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -174,6 +174,11 @@ QObject *QmlVME::run(QStack &stack, QmlContext *ctxt, QmlCompiledData VME_EXCEPTION("Unable to create object of type" << types.at(instr.create.type).className); } + QmlDeclarativeData *ddata = QmlDeclarativeData::get(o); + ddata->outerContext = ctxt; + ddata->lineNumber = instr.line; + ddata->columnNumber = instr.create.column; + if (instr.create.data != -1) { QmlCustomParser *customParser = types.at(instr.create.type).type->customParser(); -- cgit v0.12 From c3af2cb805d1ac5f7a5a944a23dc4c4238f8f530 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 2 Sep 2009 15:02:46 +1000 Subject: Provide some color manipulation functions. These may not be the final location for these, but it allows us to start testing. --- src/declarative/fx/qfxrect.cpp | 61 +-------------------- src/declarative/fx/qfxrect.h | 4 -- src/declarative/fx/qfxrect_p.h | 1 - src/declarative/qml/qmlengine.cpp | 112 ++++++++++++++++++++++++++++++++++++++ src/declarative/qml/qmlengine_p.h | 4 ++ 5 files changed, 118 insertions(+), 64 deletions(-) diff --git a/src/declarative/fx/qfxrect.cpp b/src/declarative/fx/qfxrect.cpp index f8223f2..fbd7ee8 100644 --- a/src/declarative/fx/qfxrect.cpp +++ b/src/declarative/fx/qfxrect.cpp @@ -328,63 +328,6 @@ void QFxRect::setColor(const QColor &c) update(); } -/*! - \qmlproperty color Rectangle::tintColor - This property holds The color to tint the rectangle. - - This color will be drawn over the rectangle's color when the rectangle is painted. The tint color should usually be mostly transparent, or you will not be able to see the underlying color. The below example provides a slight red tint by having the tint color be pure red which is only 1/16th opaque. - - \qml - Rectangle { x: 0; width: 80; height: 80; color: "lightsteelblue" } - Rectangle { x: 100; width: 80; height: 80; color: "lightsteelblue"; tintColor: "#10FF0000" } - \endqml - \image declarative-rect_tint.png - - This attribute is not intended to be used with a single color over the lifetime of an user interface. It is most useful when a subtle change is intended to be conveyed due to some event; you can then use the tint color to more effectively tune the visible color. -*/ -QColor QFxRect::tintColor() const -{ - Q_D(const QFxRect); - return d->tintColor; -} - -void QFxRect::setTintColor(const QColor &c) -{ - Q_D(QFxRect); - if (d->tintColor == c) - return; - - d->tintColor = c; - update(); -} - -QColor QFxRectPrivate::getColor() -{ - if (tintColor.isValid()) { - int a = tintColor.alpha(); - if (a == 0xFF) - return tintColor; - else if (a == 0x00) - return color; - else { - uint src = tintColor.rgba(); - uint dest = color.rgba(); - - uint res = (((a * (src & 0xFF00FF)) + - ((0xFF - a) * (dest & 0xFF00FF))) >> 8) & 0xFF00FF; - res |= (((a * ((src >> 8) & 0xFF00FF)) + - ((0xFF - a) * ((dest >> 8) & 0xFF00FF)))) & 0xFF00FF00; - if ((src & 0xFF000000) == 0xFF000000) - res |= 0xFF000000; - - return QColor::fromRgba(res); - } - } else { - return color; - } -} - - void QFxRect::generateRoundedRect() { Q_D(QFxRect); @@ -443,7 +386,7 @@ void QFxRect::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) bool oldAA = p->testRenderHint(QPainter::Antialiasing); if (d->smooth) p->setRenderHints(QPainter::Antialiasing, true); - p->fillRect(QRectF(0, 0, width(), height()), d->getColor()); + p->fillRect(QRectF(0, 0, width(), height()), d->color); if (d->smooth) p->setRenderHint(QPainter::Antialiasing, oldAA); } @@ -527,7 +470,7 @@ void QFxRect::drawRect(QPainter &p) // Middle if (xMiddles && yMiddles) // XXX paint errors in animation example - //p.fillRect(xOffset-pw/2, yOffset-pw/2, width() - xSide + pw, height() - ySide + pw, d->getColor()); + //p.fillRect(xOffset-pw/2, yOffset-pw/2, width() - xSide + pw, height() - ySide + pw, d->color); p.drawPixmap(QRect(xOffset-pw/2, yOffset-pw/2, width() - xSide + pw, height() - ySide + pw), d->rectImage, QRect(d->rectImage.width()/2, d->rectImage.height()/2, 1, 1)); // Middle right diff --git a/src/declarative/fx/qfxrect.h b/src/declarative/fx/qfxrect.h index 359e8fc..439cc65 100644 --- a/src/declarative/fx/qfxrect.h +++ b/src/declarative/fx/qfxrect.h @@ -136,7 +136,6 @@ class Q_DECLARATIVE_EXPORT QFxRect : public QFxItem Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor) - Q_PROPERTY(QColor tintColor READ tintColor WRITE setTintColor) Q_PROPERTY(QFxGradient *gradient READ gradient WRITE setGradient) Q_PROPERTY(QFxPen * border READ border) Q_PROPERTY(qreal radius READ radius WRITE setRadius) @@ -146,9 +145,6 @@ public: QColor color() const; void setColor(const QColor &); - QColor tintColor() const; - void setTintColor(const QColor &); - QFxPen *border(); QFxGradient *gradient() const; diff --git a/src/declarative/fx/qfxrect_p.h b/src/declarative/fx/qfxrect_p.h index 25fa38d..8eb074a 100644 --- a/src/declarative/fx/qfxrect_p.h +++ b/src/declarative/fx/qfxrect_p.h @@ -81,7 +81,6 @@ public: QColor getColor(); QColor color; QFxGradient *gradient; - QColor tintColor; QFxPen *getPen() { if (!pen) { Q_Q(QFxRect); diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index d2d0590..0bd3931 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -80,6 +80,7 @@ #include #include #include +#include #include Q_DECLARE_METATYPE(QmlMetaProperty) @@ -121,12 +122,18 @@ QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e) qt_add_qmlxmlhttprequest(&scriptEngine); + //types qtObject.setProperty(QLatin1String("rgba"), scriptEngine.newFunction(QmlEnginePrivate::rgba, 4)); qtObject.setProperty(QLatin1String("hsla"), scriptEngine.newFunction(QmlEnginePrivate::hsla, 4)); qtObject.setProperty(QLatin1String("rect"), scriptEngine.newFunction(QmlEnginePrivate::rect, 4)); qtObject.setProperty(QLatin1String("point"), scriptEngine.newFunction(QmlEnginePrivate::point, 2)); qtObject.setProperty(QLatin1String("size"), scriptEngine.newFunction(QmlEnginePrivate::size, 2)); qtObject.setProperty(QLatin1String("vector3d"), scriptEngine.newFunction(QmlEnginePrivate::vector, 3)); + + //color helpers + qtObject.setProperty(QLatin1String("lighter"), scriptEngine.newFunction(QmlEnginePrivate::lighter, 1)); + qtObject.setProperty(QLatin1String("darker"), scriptEngine.newFunction(QmlEnginePrivate::darker, 1)); + qtObject.setProperty(QLatin1String("tint"), scriptEngine.newFunction(QmlEnginePrivate::tint, 2)); } QmlEnginePrivate::~QmlEnginePrivate() @@ -809,6 +816,111 @@ QScriptValue QmlEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine) return qScriptValueFromValue(engine, qVariantFromValue(QSizeF(w, h))); } +QScriptValue QmlEnginePrivate::lighter(QScriptContext *ctxt, QScriptEngine *engine) +{ + if(ctxt->argumentCount() < 1) + return engine->nullValue(); + QVariant v = ctxt->argument(0).toVariant(); + QColor color; + if (v.type() == QVariant::Color) + color = v.value(); + else if (v.type() == QVariant::String) { + bool ok; + color = QmlStringConverters::colorFromString(v.toString(), &ok); + if (!ok) + return engine->nullValue(); + } else + return engine->nullValue(); + color = color.lighter(); + return qScriptValueFromValue(engine, qVariantFromValue(color)); +} + +QScriptValue QmlEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engine) +{ + if(ctxt->argumentCount() < 1) + return engine->nullValue(); + QVariant v = ctxt->argument(0).toVariant(); + QColor color; + if (v.type() == QVariant::Color) + color = v.value(); + else if (v.type() == QVariant::String) { + bool ok; + color = QmlStringConverters::colorFromString(v.toString(), &ok); + if (!ok) + return engine->nullValue(); + } else + return engine->nullValue(); + color = color.darker(); + return qScriptValueFromValue(engine, qVariantFromValue(color)); +} + +/*! + This function allows tinting one color with another. + + The tint color should usually be mostly transparent, or you will not be able to see the underlying color. The below example provides a slight red tint by having the tint color be pure red which is only 1/16th opaque. + + \qml + Rectangle { x: 0; width: 80; height: 80; color: "lightsteelblue" } + Rectangle { x: 100; width: 80; height: 80; color: Qt.tint("lightsteelblue", "#10FF0000") } + \endqml + \image declarative-rect_tint.png + + 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. +*/ +QScriptValue QmlEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine) +{ + if(ctxt->argumentCount() < 2) + return engine->nullValue(); + //get color + QVariant v = ctxt->argument(0).toVariant(); + QColor color; + if (v.type() == QVariant::Color) + color = v.value(); + else if (v.type() == QVariant::String) { + bool ok; + color = QmlStringConverters::colorFromString(v.toString(), &ok); + if (!ok) + return engine->nullValue(); + } else + return engine->nullValue(); + + //get tint color + v = ctxt->argument(1).toVariant(); + QColor tintColor; + if (v.type() == QVariant::Color) + tintColor = v.value(); + else if (v.type() == QVariant::String) { + bool ok; + tintColor = QmlStringConverters::colorFromString(v.toString(), &ok); + if (!ok) + return engine->nullValue(); + } else + return engine->nullValue(); + + //tint + QColor finalColor; + int a = tintColor.alpha(); + if (a == 0xFF) + finalColor = tintColor; + else if (a == 0x00) + finalColor = color; + else { + uint src = tintColor.rgba(); + uint dest = color.rgba(); + + uint res = (((a * (src & 0xFF00FF)) + + ((0xFF - a) * (dest & 0xFF00FF))) >> 8) & 0xFF00FF; + res |= (((a * ((src >> 8) & 0xFF00FF)) + + ((0xFF - a) * ((dest >> 8) & 0xFF00FF)))) & 0xFF00FF00; + if ((src & 0xFF000000) == 0xFF000000) + res |= 0xFF000000; + + finalColor = QColor::fromRgba(res); + } + + return qScriptValueFromValue(engine, qVariantFromValue(finalColor)); +} + QmlScriptClass::QmlScriptClass(QmlEngine *bindengine) : QScriptClass(QmlEnginePrivate::getScriptEngine(bindengine)), engine(bindengine) diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index b3c6279..1e251cc 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -223,6 +223,10 @@ public: static QScriptValue size(QScriptContext*, QScriptEngine*); static QScriptValue rect(QScriptContext*, QScriptEngine*); + static QScriptValue lighter(QScriptContext*, QScriptEngine*); + static QScriptValue darker(QScriptContext*, QScriptEngine*); + static QScriptValue tint(QScriptContext*, QScriptEngine*); + static QScriptEngine *getScriptEngine(QmlEngine *e) { return &e->d_func()->scriptEngine; } static QmlEngine *getEngine(QScriptEngine *e) { return static_cast(e)->p->q_func(); } static QmlEnginePrivate *get(QmlEngine *e) { return e->d_func(); } -- cgit v0.12