summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2009-09-17 06:37:15 (GMT)
committerMartin Jones <martin.jones@nokia.com>2009-09-17 06:37:15 (GMT)
commit2f9017c7736b3f8db721f6605e6131ab376cb864 (patch)
treee2a5c7fdacdc19e2ebddcb6dcf628255d81d78f2
parent0c2e40683007c9405b8fc9f7efbd728ef519d78f (diff)
parent8caff8b4be02a2f28c9a2a50d3b5ef274138021e (diff)
downloadQt-2f9017c7736b3f8db721f6605e6131ab376cb864.zip
Qt-2f9017c7736b3f8db721f6605e6131ab376cb864.tar.gz
Qt-2f9017c7736b3f8db721f6605e6131ab376cb864.tar.bz2
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
-rw-r--r--doc/src/declarative/elements.qdoc3
-rw-r--r--examples/declarative/sql/README7
-rw-r--r--examples/declarative/sql/hello.qml36
-rw-r--r--src/declarative/fx/qfxborderimage.cpp4
-rw-r--r--src/declarative/fx/qfxitem.cpp28
-rw-r--r--src/declarative/fx/qfxitem.h8
-rw-r--r--src/declarative/fx/qfxitem_p.h4
-rw-r--r--src/declarative/fx/qfxlistview.cpp10
-rw-r--r--src/declarative/fx/qfxloader.cpp6
-rw-r--r--src/declarative/fx/qfxrect.cpp11
-rw-r--r--src/declarative/fx/qfxrect.h16
-rw-r--r--src/declarative/fx/qfxrect_p.h2
-rw-r--r--src/declarative/fx/qfxtext.cpp14
-rw-r--r--src/declarative/fx/qfxtextedit.cpp19
-rw-r--r--src/declarative/qml/qml.pri2
-rw-r--r--src/declarative/qml/qmlengine.cpp6
-rw-r--r--src/declarative/qml/qmlengine_p.h2
-rw-r--r--src/declarative/qml/qmlpropertyvaluesource.cpp4
-rw-r--r--src/declarative/qml/qmlpropertyvaluesource.h1
-rw-r--r--src/declarative/qml/qmlsqldatabase.cpp304
-rw-r--r--src/declarative/qml/qmlsqldatabase_p.h60
-rw-r--r--src/declarative/util/qmleasefollow.cpp2
-rw-r--r--src/declarative/util/qmlspringfollow.cpp2
23 files changed, 501 insertions, 50 deletions
diff --git a/doc/src/declarative/elements.qdoc b/doc/src/declarative/elements.qdoc
index ca17fda..1fe4892 100644
--- a/doc/src/declarative/elements.qdoc
+++ b/doc/src/declarative/elements.qdoc
@@ -36,7 +36,7 @@ The following table lists the QML elements provided by the Qt Declarative module
\o \l ParentAction
\o \l ScriptAction
\o \l Transition
-\o \l Follow
+\o \l SpringFollow
\o \l EaseFollow
\o \l Behavior
\endlist
@@ -86,7 +86,6 @@ The following table lists the QML elements provided by the Qt Declarative module
\list
\o \l MouseRegion
\o \l FocusScope
-\o \l KeyProxy
\endlist
\o
diff --git a/examples/declarative/sql/README b/examples/declarative/sql/README
new file mode 100644
index 0000000..a7baab2
--- /dev/null
+++ b/examples/declarative/sql/README
@@ -0,0 +1,7 @@
+Simple demonstration of HTML5-compatible SQL database interface.
+Adds another "hello, world" every time you run it.
+Database is stored in:
+ - %APPDATA%/Nokia/Qt/QML/Databases/ (Windows)
+ - ~/.local/share/Nokia/Qt/QML/Databases/ (Unix)
+ - ~/Library/Application Support/Nokia/Qt/QML/Databases/ (Mac OS X)
+No quota management.
diff --git a/examples/declarative/sql/hello.qml b/examples/declarative/sql/hello.qml
new file mode 100644
index 0000000..e43d320
--- /dev/null
+++ b/examples/declarative/sql/hello.qml
@@ -0,0 +1,36 @@
+import Qt 4.6
+
+Text {
+ Script {
+ function allGreetings()
+ {
+ var db = openDatabase("QmlExampleDB", "", "The Example QML SQL!", 1000000);
+ var r = ""
+
+ db.transaction(function(tx) {
+ tx.executeSql('CREATE TABLE IF NOT EXISTS Greeting(salutation TEXT, salutee TEXT)', []);
+ tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ]);
+ tx.executeSql('SELECT * FROM Greeting', [],
+ function(tx, rs) {
+ /* Inefficient HTML5-compatible way
+ for(var i = 0; i < rs.rows.length; i++) {
+ r += rs.rows[i][0] + ", " + rs.rows[i][1] + "\n"
+ }
+ */
+ /* Efficient way: forward only, not "length" query */
+ rs.rows.forwardOnly = true;
+ for(var i = 0; rs.rows[i]; i++) {
+ r += rs.rows[i][0] + ", " + rs.rows[i][1] + "\n"
+ }
+ },
+ function(tx, error) {
+ print("ERROR:", error.message)
+ }
+ );
+ })
+
+ return r
+ }
+ }
+ text: allGreetings()
+}
diff --git a/src/declarative/fx/qfxborderimage.cpp b/src/declarative/fx/qfxborderimage.cpp
index d199d5d..ee505f2 100644
--- a/src/declarative/fx/qfxborderimage.cpp
+++ b/src/declarative/fx/qfxborderimage.cpp
@@ -386,11 +386,9 @@ void QFxBorderImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidge
if (d->smooth)
p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth);
- QPixmap pix = d->pix;
-
QMargins margins(border()->top(), border()->left(), border()->bottom(), border()->right());
QTileRules rules((Qt::TileRule)d->horizontalTileMode, (Qt::TileRule)d->verticalTileMode);
- qDrawBorderPixmap(p, QRect(0, 0, (int)d->width, (int)d->height), margins, pix, pix.rect(), margins, rules);
+ qDrawBorderPixmap(p, QRect(0, 0, (int)d->width, (int)d->height), margins, d->pix, d->pix.rect(), margins, rules);
if (d->smooth) {
p->setRenderHint(QPainter::Antialiasing, oldAA);
p->setRenderHint(QPainter::SmoothPixmapTransform, oldSmooth);
diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp
index 962fee2..dd51aa6 100644
--- a/src/declarative/fx/qfxitem.cpp
+++ b/src/declarative/fx/qfxitem.cpp
@@ -2688,9 +2688,23 @@ void QFxItem::setWidth(qreal w)
QRectF(x(), y(), oldWidth, height()));
}
+void QFxItem::resetWidth()
+{
+ Q_D(QFxItem);
+ d->widthValid = false;
+ setImplicitWidth(implicitWidth());
+}
+
+qreal QFxItem::implicitWidth() const
+{
+ Q_D(const QFxItem);
+ return d->implicitWidth;
+}
+
void QFxItem::setImplicitWidth(qreal w)
{
Q_D(QFxItem);
+ d->implicitWidth = w;
if (d->width == w || widthValid())
return;
@@ -2733,9 +2747,23 @@ void QFxItem::setHeight(qreal h)
QRectF(x(), y(), width(), oldHeight));
}
+void QFxItem::resetHeight()
+{
+ Q_D(QFxItem);
+ d->heightValid = false;
+ setImplicitHeight(implicitHeight());
+}
+
+qreal QFxItem::implicitHeight() const
+{
+ Q_D(const QFxItem);
+ return d->implicitHeight;
+}
+
void QFxItem::setImplicitHeight(qreal h)
{
Q_D(QFxItem);
+ d->implicitHeight = h;
if (d->height == h || heightValid())
return;
diff --git a/src/declarative/fx/qfxitem.h b/src/declarative/fx/qfxitem.h
index 7ec1ab2..b309cb3 100644
--- a/src/declarative/fx/qfxitem.h
+++ b/src/declarative/fx/qfxitem.h
@@ -75,8 +75,8 @@ class Q_DECLARATIVE_EXPORT QFxItem : public QGraphicsObject, public QmlParserSta
Q_PROPERTY(QmlList<QmlState *>* states READ states DESIGNABLE false)
Q_PROPERTY(QmlList<QmlTransition *>* transitions READ transitions DESIGNABLE false)
Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged)
- Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY widthChanged FINAL)
- Q_PROPERTY(qreal height READ height WRITE setHeight NOTIFY heightChanged FINAL)
+ Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY widthChanged RESET resetWidth FINAL)
+ Q_PROPERTY(qreal height READ height WRITE setHeight NOTIFY heightChanged RESET resetHeight FINAL)
Q_PROPERTY(QRectF childrenRect READ childrenRect NOTIFY childrenRectChanged DESIGNABLE false FINAL)
Q_PROPERTY(QFxAnchors * anchors READ anchors DESIGNABLE false CONSTANT FINAL)
Q_PROPERTY(QFxAnchorLine left READ left CONSTANT FINAL)
@@ -134,9 +134,13 @@ public:
qreal width() const;
void setWidth(qreal);
+ void resetWidth();
+ qreal implicitWidth() const;
qreal height() const;
void setHeight(qreal);
+ void resetHeight();
+ qreal implicitHeight() const;
TransformOrigin transformOrigin() const;
void setTransformOrigin(TransformOrigin);
diff --git a/src/declarative/fx/qfxitem_p.h b/src/declarative/fx/qfxitem_p.h
index b2560ee..df75148 100644
--- a/src/declarative/fx/qfxitem_p.h
+++ b/src/declarative/fx/qfxitem_p.h
@@ -108,7 +108,7 @@ public:
widthValid(false), heightValid(false),
_componentComplete(true), _keepMouse(false),
smooth(false), keyHandler(0),
- width(0), height(0)
+ width(0), height(0), implicitWidth(0), implicitHeight(0)
{}
~QFxItemPrivate()
{ delete _anchors; }
@@ -213,6 +213,8 @@ public:
qreal width;
qreal height;
+ qreal implicitWidth;
+ qreal implicitHeight;
QPointF computeTransformOrigin() const;
diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp
index 015eacf..5de9bf3 100644
--- a/src/declarative/fx/qfxlistview.cpp
+++ b/src/declarative/fx/qfxlistview.cpp
@@ -831,8 +831,9 @@ void QFxListViewPrivate::fixupX()
\inherits Flickable
\brief The ListView item provides a list view of items provided by a model.
- The model is typically provided by a QAbstractListModel "C++ model object", but can also be created directly in QML.
- The items are laid out vertically or horizontally and may be flicked to scroll.
+ The model is typically provided by a QAbstractListModel "C++ model object",
+ but can also be created directly in QML. The items are laid out vertically
+ or horizontally and may be flicked to scroll.
The below example creates a very simple vertical list, using a QML model.
\image trivialListView.png
@@ -871,9 +872,10 @@ QFxListView::~QFxListView()
The model provides a set of data that is used to create the items
for the view. For large or dynamic datasets the model is usually
provided by a C++ model object. The C++ model object must be a \l
- {QAbstractItemModel} subclass, a VisualModel, or a simple list.
+ {QAbstractItemModel} subclass or a simple list.
- Models can also be created directly in QML, using a \l{ListModel} or \l{XmlListModel}.
+ Models can also be created directly in QML, using a \l{ListModel},
+ \l{XmlListModel} or \l{VisualItemModel}.
*/
QVariant QFxListView::model() const
{
diff --git a/src/declarative/fx/qfxloader.cpp b/src/declarative/fx/qfxloader.cpp
index 668faa4..d0c2690 100644
--- a/src/declarative/fx/qfxloader.cpp
+++ b/src/declarative/fx/qfxloader.cpp
@@ -361,10 +361,8 @@ void QFxLoaderPrivate::_q_updateSize()
return;
switch (resizeMode) {
case QFxLoader::SizeLoaderToItem:
- if (!q->widthValid())
- q->setImplicitWidth(item->width());
- if (!q->heightValid())
- q->setImplicitHeight(item->height());
+ q->setImplicitWidth(item->width());
+ q->setImplicitHeight(item->height());
break;
case QFxLoader::SizeItemToLoader:
item->setWidth(q->width());
diff --git a/src/declarative/fx/qfxrect.cpp b/src/declarative/fx/qfxrect.cpp
index fbd7ee8..7d6340f 100644
--- a/src/declarative/fx/qfxrect.cpp
+++ b/src/declarative/fx/qfxrect.cpp
@@ -69,14 +69,17 @@ void QFxPen::setColor(const QColor &c)
{
_color = c;
_valid = _color.alpha() ? true : false;
- emit updated();
+ emit penChanged();
}
void QFxPen::setWidth(int w)
{
+ if (_width == w)
+ return;
+
_width = w;
_valid = (_width < 1) ? false : true;
- emit updated();
+ emit penChanged();
}
@@ -293,6 +296,7 @@ void QFxRect::setRadius(qreal radius)
d->radius = radius;
d->rectImage = QPixmap();
update();
+ emit radiusChanged();
}
/*!
@@ -326,6 +330,7 @@ void QFxRect::setColor(const QColor &c)
d->color = c;
d->rectImage = QPixmap();
update();
+ emit colorChanged();
}
void QFxRect::generateRoundedRect()
@@ -395,7 +400,7 @@ void QFxRect::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
void QFxRect::drawRect(QPainter &p)
{
Q_D(QFxRect);
- if (d->gradient && d->gradient->gradient() /*|| p.usingQt() */) {
+ if (d->gradient && d->gradient->gradient()) {
// XXX This path is still slower than the image path
// Image path won't work for gradients though
bool oldAA = p.testRenderHint(QPainter::Antialiasing);
diff --git a/src/declarative/fx/qfxrect.h b/src/declarative/fx/qfxrect.h
index 439cc65..e5bb8d3 100644
--- a/src/declarative/fx/qfxrect.h
+++ b/src/declarative/fx/qfxrect.h
@@ -55,8 +55,8 @@ class Q_DECLARATIVE_EXPORT QFxPen : public QObject
{
Q_OBJECT
- Q_PROPERTY(int width READ width WRITE setWidth)
- Q_PROPERTY(QColor color READ color WRITE setColor)
+ Q_PROPERTY(int width READ width WRITE setWidth NOTIFY penChanged)
+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY penChanged)
public:
QFxPen(QObject *parent=0)
: QObject(parent), _width(1), _color("#000000"), _valid(false)
@@ -71,7 +71,7 @@ public:
bool isValid() { return _valid; };
Q_SIGNALS:
- void updated();
+ void penChanged();
private:
int _width;
@@ -135,10 +135,10 @@ class Q_DECLARATIVE_EXPORT QFxRect : public QFxItem
{
Q_OBJECT
- Q_PROPERTY(QColor color READ color WRITE setColor)
+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
Q_PROPERTY(QFxGradient *gradient READ gradient WRITE setGradient)
- Q_PROPERTY(QFxPen * border READ border)
- Q_PROPERTY(qreal radius READ radius WRITE setRadius)
+ Q_PROPERTY(QFxPen * border READ border CONSTANT)
+ Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged)
public:
QFxRect(QFxItem *parent=0);
@@ -157,6 +157,10 @@ public:
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+Q_SIGNALS:
+ void colorChanged();
+ void radiusChanged();
+
private Q_SLOTS:
void doUpdate();
diff --git a/src/declarative/fx/qfxrect_p.h b/src/declarative/fx/qfxrect_p.h
index 8eb074a..c055b76 100644
--- a/src/declarative/fx/qfxrect_p.h
+++ b/src/declarative/fx/qfxrect_p.h
@@ -85,7 +85,7 @@ public:
if (!pen) {
Q_Q(QFxRect);
pen = new QFxPen;
- QObject::connect(pen, SIGNAL(updated()), q, SLOT(doUpdate()));
+ QObject::connect(pen, SIGNAL(penChanged()), q, SLOT(doUpdate()));
}
return pen;
}
diff --git a/src/declarative/fx/qfxtext.cpp b/src/declarative/fx/qfxtext.cpp
index 5b10289..c4e534e 100644
--- a/src/declarative/fx/qfxtext.cpp
+++ b/src/declarative/fx/qfxtext.cpp
@@ -513,17 +513,9 @@ void QFxTextPrivate::updateSize()
}
q->setBaselineOffset(fm.ascent() + yoff);
- if (!q->widthValid()) {
- int newWidth = (richText ? (int)doc->idealWidth() : size.width());
- q->setImplicitWidth(newWidth);
- }
- if (!q->heightValid()) {
- if (richText) {
- q->setImplicitHeight((int)doc->size().height());
- } else {
- q->setImplicitHeight(size.height());
- }
- }
+ //### need to comfirm cost of always setting these for richText
+ q->setImplicitWidth(richText ? (int)doc->idealWidth() : size.width());
+ q->setImplicitHeight(richText ? (int)doc->size().height() : size.height());
} else {
dirty = true;
}
diff --git a/src/declarative/fx/qfxtextedit.cpp b/src/declarative/fx/qfxtextedit.cpp
index c106ee0..d1bafd6 100644
--- a/src/declarative/fx/qfxtextedit.cpp
+++ b/src/declarative/fx/qfxtextedit.cpp
@@ -1043,18 +1043,13 @@ void QFxTextEdit::updateSize()
yoff = dy/2;
}
setBaselineOffset(fm.ascent() + yoff + d->textMargin);
- if (!widthValid()) {
- int newWidth = (int)d->document->idealWidth();
- d->document->setTextWidth(newWidth); // ### QTextDoc> Alignment will not work unless textWidth is set
- setImplicitWidth(newWidth);
- }
- if (!heightValid()) {
- if (d->text.isEmpty()) {
- setImplicitHeight(fm.height());
- } else {
- setImplicitHeight((int)d->document->size().height());
- }
- }
+
+ //### need to comfirm cost of always setting these
+ int newWidth = (int)d->document->idealWidth();
+ d->document->setTextWidth(newWidth); // ### QTextDoc> Alignment will not work unless textWidth is set. Does Text need this line as well?
+ setImplicitWidth(newWidth);
+ setImplicitHeight(d->text.isEmpty() ? fm.height() : (int)d->document->size().height());
+
setContentsSize(QSize(width(), height()));
} else {
d->dirty = true;
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 29d97ba..9ca69df 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -32,6 +32,7 @@ SOURCES += qml/qmlparser.cpp \
qml/qmlvaluetype.cpp \
qml/qmlbindingoptimizations.cpp \
qml/qmlxmlhttprequest.cpp \
+ qml/qmlsqldatabase.cpp \
qml/qmetaobjectbuilder.cpp
HEADERS += qml/qmlparser_p.h \
@@ -81,6 +82,7 @@ HEADERS += qml/qmlparser_p.h \
qml/qmlvaluetype_p.h \
qml/qmlbindingoptimizations_p.h \
qml/qmlxmlhttprequest_p.h \
+ qml/qmlsqldatabase_p.h \
qml/qmetaobjectbuilder_p.h
# for qtscript debugger
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 3cf7e69..1aa2cb9 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -82,6 +82,7 @@
#include <private/qmlenginedebug_p.h>
#include <private/qmlstringconverters_p.h>
#include <private/qmlxmlhttprequest_p.h>
+#include <private/qmlsqldatabase_p.h>
Q_DECLARE_METATYPE(QmlMetaProperty)
Q_DECLARE_METATYPE(QList<QObject *>);
@@ -110,7 +111,7 @@ QScriptValue desktopOpenUrl(QScriptContext *ctxt, QScriptEngine *e)
QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e)
: rootContext(0), currentExpression(0),
isDebugging(false), contextClass(0), objectClass(0), valueTypeClass(0),
- nodeListClass(0), namedNodeMapClass(0), scriptEngine(this), rootComponent(0),
+ nodeListClass(0), namedNodeMapClass(0), sqlQueryClass(0), scriptEngine(this), rootComponent(0),
networkAccessManager(0), typeManager(e), uniqueId(1)
{
QScriptValue qtObject =
@@ -121,6 +122,7 @@ QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e)
scriptEngine.globalObject().setProperty(QLatin1String("Qt"), qtObject);
qt_add_qmlxmlhttprequest(&scriptEngine);
+ qt_add_qmlsqldatabase(&scriptEngine);
//types
qtObject.setProperty(QLatin1String("rgba"), scriptEngine.newFunction(QmlEnginePrivate::rgba, 4));
@@ -154,6 +156,8 @@ QmlEnginePrivate::~QmlEnginePrivate()
nodeListClass = 0;
delete namedNodeMapClass;
namedNodeMapClass = 0;
+ delete sqlQueryClass;
+ sqlQueryClass = 0;
for(int ii = 0; ii < bindValues.count(); ++ii)
clear(bindValues[ii]);
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index 15ab40d..0eeae0c 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -154,6 +154,8 @@ public:
// Used by DOM Core 3 API
QScriptClass *nodeListClass;
QScriptClass *namedNodeMapClass;
+ // Used by SQL database API
+ QScriptClass *sqlQueryClass;
struct QmlScriptEngine : public QScriptEngine
{
diff --git a/src/declarative/qml/qmlpropertyvaluesource.cpp b/src/declarative/qml/qmlpropertyvaluesource.cpp
index 429080b..529ce37 100644
--- a/src/declarative/qml/qmlpropertyvaluesource.cpp
+++ b/src/declarative/qml/qmlpropertyvaluesource.cpp
@@ -56,6 +56,10 @@ QmlPropertyValueSource::QmlPropertyValueSource()
{
}
+QmlPropertyValueSource::~QmlPropertyValueSource()
+{
+}
+
/*!
\fn void QmlPropertyValueSource::setTarget(const QmlMetaProperty &property)
Set the target \a property for the value source. This method will
diff --git a/src/declarative/qml/qmlpropertyvaluesource.h b/src/declarative/qml/qmlpropertyvaluesource.h
index ee4ea2c..384d2f9 100644
--- a/src/declarative/qml/qmlpropertyvaluesource.h
+++ b/src/declarative/qml/qmlpropertyvaluesource.h
@@ -55,6 +55,7 @@ class Q_DECLARATIVE_EXPORT QmlPropertyValueSource
{
public:
QmlPropertyValueSource();
+ virtual ~QmlPropertyValueSource();
virtual void setTarget(const QmlMetaProperty &) = 0;
};
Q_DECLARE_INTERFACE(QmlPropertyValueSource, "com.trolltech.qml.QmlPropertyValueSource")
diff --git a/src/declarative/qml/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp
new file mode 100644
index 0000000..144a170
--- /dev/null
+++ b/src/declarative/qml/qmlsqldatabase.cpp
@@ -0,0 +1,304 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qobject.h>
+#include <QtDeclarative/qmlengine.h>
+#include <private/qmlengine_p.h>
+#include <QtScript/qscriptvalue.h>
+#include <QtScript/qscriptvalueiterator.h>
+#include <QtScript/qscriptcontext.h>
+#include <QtScript/qscriptengine.h>
+#include <QtSql/qsqldatabase.h>
+#include <QtSql/qsqlquery.h>
+#include <QtSql/qsqlerror.h>
+#include <QtSql/qsqlrecord.h>
+#include <private/qmlrefcount_p.h>
+#include <private/qmlengine_p.h>
+#include <QtCore/qstack.h>
+#include <QtCore/qcryptographichash.h>
+#include "qmlsqldatabase_p.h"
+#include <QtCore/qsettings.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qdebug.h>
+
+#ifdef Q_OS_WIN // for %APPDATA%
+#include "qt_windows.h"
+#include "qlibrary.h"
+#define CSIDL_APPDATA 0x001a // <username>\Application Data
+#endif
+
+Q_DECLARE_METATYPE(QSqlDatabase)
+Q_DECLARE_METATYPE(QSqlQuery)
+
+class QmlSqlQueryScriptClass: public QScriptClass {
+public:
+ QmlSqlQueryScriptClass(QScriptEngine *engine) : QScriptClass(engine)
+ {
+ str_length = engine->toStringHandle(QLatin1String("length"));
+ str_forwardOnly = engine->toStringHandle(QLatin1String("forwardOnly")); // not in HTML5 (optimization)
+ }
+
+ QueryFlags queryProperty(const QScriptValue &object,
+ const QScriptString &name,
+ QueryFlags flags, uint *id)
+ {
+ if (flags & HandlesReadAccess) {
+ if (name == str_length) {
+ return HandlesReadAccess;
+ } else if (name == str_forwardOnly) {
+ return flags;
+ } else {
+ bool ok;
+ qint32 pos = name.toString().toInt(&ok);
+ if (pos < 0 || !ok)
+ return 0;
+ QSqlQuery query = qscriptvalue_cast<QSqlQuery>(object.data());
+ *id = pos;
+ if (*id < (uint)query.size())
+ return HandlesReadAccess;
+ }
+ }
+ if (flags & HandlesWriteAccess)
+ if (name == str_forwardOnly)
+ return flags;
+ return 0;
+ }
+
+ QScriptValue property(const QScriptValue &object,
+ const QScriptString &name, uint id)
+ {
+ QSqlQuery query = qscriptvalue_cast<QSqlQuery>(object.data());
+ if (name == str_length) {
+ int s = query.size();
+ if (s<0) {
+ // Inefficient.
+ query.last();
+ return query.at()+1;
+ } else {
+ return s;
+ }
+ } else if (name == str_forwardOnly) {
+ return query.isForwardOnly();
+ } else {
+ if (query.at() == id || query.seek(id)) { // Qt 4.6 doesn't optimize at()==id
+ QSqlRecord r = query.record();
+ QScriptValue row = engine()->newArray(r.count());
+ for (int j=0; j<r.count(); ++j) {
+ // XXX only strings
+ row.setProperty(j, QScriptValue(engine(),r.value(j).toString()));
+ }
+ return row;
+ }
+ }
+ return engine()->undefinedValue();
+ }
+
+ void setProperty(QScriptValue &object,
+ const QScriptString &name, uint, const QScriptValue & value)
+ {
+ if (name == str_forwardOnly) {
+ QSqlQuery query = qscriptvalue_cast<QSqlQuery>(object.data());
+ query.setForwardOnly(value.toBool());
+ }
+ }
+
+private:
+ QScriptString str_length;
+ QScriptString str_forwardOnly;
+};
+
+static QScriptValue qmlsqldatabase_executeSql(QScriptContext *context, QScriptEngine *engine)
+{
+ QSqlDatabase db = qscriptvalue_cast<QSqlDatabase>(context->thisObject());
+ QString sql = context->argument(0).toString();
+ QScriptValue values = context->argument(1);
+ QScriptValue cb = context->argument(2);
+ QScriptValue cberr = context->argument(3);
+ QSqlQuery query(db);
+ bool err = false;
+ if (query.prepare(sql)) {
+ if (values.isArray()) {
+ for (QScriptValueIterator it(values); it.hasNext();) {
+ it.next();
+ query.addBindValue(it.value().toVariant());
+ }
+ } else {
+ query.bindValue(0,values.toVariant());
+ }
+ if (query.exec()) {
+ QScriptValue rs = engine->newObject();
+ if (!QmlEnginePrivate::get(engine)->sqlQueryClass)
+ QmlEnginePrivate::get(engine)->sqlQueryClass= new QmlSqlQueryScriptClass(engine);
+ QScriptValue rows = engine->newObject(QmlEnginePrivate::get(engine)->sqlQueryClass);
+ rows.setData(engine->newVariant(qVariantFromValue(query)));
+ rs.setProperty(QLatin1String("rows"),rows);
+ rs.setProperty(QLatin1String("rowsAffected"),query.numRowsAffected());
+ rs.setProperty(QLatin1String("insertId"),query.lastInsertId().toString()); // XXX only string
+ cb.call(QScriptValue(), QScriptValueList() << context->thisObject() << rs);
+ } else {
+ err = true;
+ }
+ } else {
+ err = true;
+ }
+ if (err) {
+ QScriptValue error = engine->newObject();
+ error.setProperty(QLatin1String("message"), query.lastError().text());
+ cberr.call(QScriptValue(), QScriptValueList() << context->thisObject() << error);
+ }
+ return engine->undefinedValue();
+}
+
+static QScriptValue qmlsqldatabase_transaction(QScriptContext *context, QScriptEngine *engine)
+{
+ QSqlDatabase db = qscriptvalue_cast<QSqlDatabase>(context->thisObject());
+ if (context->argumentCount() < 1)
+ return engine->undefinedValue();
+ QScriptValue cb = context->argument(0);
+ if (!cb.isFunction())
+ return engine->undefinedValue();
+
+ // Call synchronously... - XXX could do asynch with threads
+ QScriptValue instance = engine->newObject();
+ instance.setProperty(QLatin1String("executeSql"), engine->newFunction(qmlsqldatabase_executeSql,4));
+ QScriptValue tx = engine->newVariant(instance,qVariantFromValue(db));
+
+ db.transaction();
+ cb.call(QScriptValue(), QScriptValueList() << tx);
+ if (engine->hasUncaughtException()) {
+ db.rollback();
+ QScriptValue cb = context->argument(1);
+ if (cb.isFunction())
+ cb.call();
+ } else {
+ db.commit();
+ QScriptValue cb = context->argument(2);
+ if (cb.isFunction())
+ cb.call();
+ }
+ return engine->undefinedValue();
+}
+
+// XXX Something like this should be exported by Qt.
+static QString userLocalDataPath(const QString& app)
+{
+ QString result;
+
+#ifdef Q_OS_WIN
+#ifndef Q_OS_WINCE
+ QLibrary library(QLatin1String("shell32"));
+#else
+ QLibrary library(QLatin1String("coredll"));
+#endif // Q_OS_WINCE
+ typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPWSTR, int, BOOL);
+ GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW");
+ if (SHGetSpecialFolderPath) {
+ wchar_t path[MAX_PATH];
+ SHGetSpecialFolderPath(0, path, CSIDL_APPDATA, FALSE);
+ result = QString::fromWCharArray(path);
+ }
+#endif // Q_OS_WIN
+
+#ifdef Q_OS_MAC
+ result = QLatin1String(qgetenv("HOME"));
+ result += "/Library/Application Support";
+#else
+ if (result.isEmpty()) {
+ // Fallback: UNIX style
+ result = QLatin1String(qgetenv("XDG_DATA_HOME"));
+ if (result.isEmpty()) {
+ result = QLatin1String(qgetenv("HOME"));
+ result += QLatin1String("/.local/share");
+ }
+ }
+#endif
+
+ result += QLatin1Char('/');
+ result += app;
+ return result;
+}
+
+
+static QScriptValue qmlsqldatabase_open(QScriptContext *context, QScriptEngine *engine)
+{
+ QSqlDatabase database;
+
+ QString dbname = context->argument(0).toString();
+ QString dbversion = context->argument(1).toString();
+ QString dbdescription = context->argument(2).toString();
+ int dbestimatedsize = context->argument(3).toNumber();
+
+ QCryptographicHash md5(QCryptographicHash::Md5);
+ md5.addData(dbname.toUtf8());
+ md5.addData(dbversion.toUtf8());
+ QString dbid(QLatin1String(md5.result().toHex()));
+
+ // Uses SQLLITE (like HTML5), but any could be used.
+
+ if (QSqlDatabase::connectionNames().contains(dbid)) {
+ database = QSqlDatabase::database(dbid);
+ } else {
+ database = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), dbid);
+ }
+ if (!database.isOpen()) {
+ QString basename = userLocalDataPath(QLatin1String("Nokia/Qt/QML/Databases/"));
+ QDir().mkpath(basename);
+ basename += dbid;
+ database.setDatabaseName(basename+QLatin1String(".sqllite"));
+ QSettings ini(basename+QLatin1String(".ini"),QSettings::IniFormat);
+ ini.setValue(QLatin1String("Name"), dbname);
+ ini.setValue(QLatin1String("Version"), dbversion);
+ ini.setValue(QLatin1String("Description"), dbdescription);
+ ini.setValue(QLatin1String("EstimatedSize"), dbestimatedsize);
+ database.open();
+ }
+
+ QScriptValue instance = engine->newObject();
+ instance.setProperty(QLatin1String("transaction"), engine->newFunction(qmlsqldatabase_transaction,3));
+ return engine->newVariant(instance,qVariantFromValue(database));
+}
+
+void qt_add_qmlsqldatabase(QScriptEngine *engine)
+{
+ QScriptValue openDatabase = engine->newFunction(qmlsqldatabase_open, 4);
+ engine->globalObject().setProperty(QLatin1String("openDatabase"), openDatabase);
+}
+
diff --git a/src/declarative/qml/qmlsqldatabase_p.h b/src/declarative/qml/qmlsqldatabase_p.h
new file mode 100644
index 0000000..f76a2fd
--- /dev/null
+++ b/src/declarative/qml/qmlsqldatabase_p.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLSQLDATABASE_P_H
+#define QMLSQLDATABASE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+class QScriptEngine;
+void qt_add_qmlsqldatabase(QScriptEngine *engine);
+
+#endif // QMLSQLDATABASE_P_H
+
diff --git a/src/declarative/util/qmleasefollow.cpp b/src/declarative/util/qmleasefollow.cpp
index b58ad14..860c63a 100644
--- a/src/declarative/util/qmleasefollow.cpp
+++ b/src/declarative/util/qmleasefollow.cpp
@@ -242,6 +242,8 @@ Rectangle {
Keys.onDownPressed: Rect1.y = Rect1.y + 100
}
\endcode
+
+ \sa SpringFollow
*/
QmlEaseFollow::QmlEaseFollow(QObject *parent)
diff --git a/src/declarative/util/qmlspringfollow.cpp b/src/declarative/util/qmlspringfollow.cpp
index 8c902aa..2dae448 100644
--- a/src/declarative/util/qmlspringfollow.cpp
+++ b/src/declarative/util/qmlspringfollow.cpp
@@ -236,6 +236,8 @@ void QmlSpringFollowPrivate::stop()
y: SpringFollow { source: Rect1.y; velocity: 200 }
}
\endcode
+
+ \sa EaseFollow
*/
QmlSpringFollow::QmlSpringFollow(QObject *parent)