summaryrefslogtreecommitdiffstats
path: root/src/declarative/extra
diff options
context:
space:
mode:
authorMichael Brasser <michael.brasser@nokia.com>2009-04-22 04:47:24 (GMT)
committerMichael Brasser <michael.brasser@nokia.com>2009-04-22 04:47:24 (GMT)
commit2366667fc97eb6a56203b2dd7dac776ff4164abd (patch)
treeb2acb6cc6bfe475d7e619e4788973b61fff775e0 /src/declarative/extra
parent2c762f3b8b284a7c6dc0c499b7052013bad5b707 (diff)
downloadQt-2366667fc97eb6a56203b2dd7dac776ff4164abd.zip
Qt-2366667fc97eb6a56203b2dd7dac776ff4164abd.tar.gz
Qt-2366667fc97eb6a56203b2dd7dac776ff4164abd.tar.bz2
Initial import of kinetic-dui branch from the old kinetic
Diffstat (limited to 'src/declarative/extra')
-rw-r--r--src/declarative/extra/extra.pri24
-rw-r--r--src/declarative/extra/qfxintegermodel.cpp126
-rw-r--r--src/declarative/extra/qfxintegermodel.h86
-rw-r--r--src/declarative/extra/qmlnumberformatter.cpp214
-rw-r--r--src/declarative/extra/qmlnumberformatter.h92
-rw-r--r--src/declarative/extra/qmlsqlconnection.cpp441
-rw-r--r--src/declarative/extra/qmlsqlconnection.h117
-rw-r--r--src/declarative/extra/qmlsqlquery.cpp696
-rw-r--r--src/declarative/extra/qmlsqlquery.h143
-rw-r--r--src/declarative/extra/qmlxmllistmodel.cpp357
-rw-r--r--src/declarative/extra/qmlxmllistmodel.h139
-rw-r--r--src/declarative/extra/qnumberformat.cpp224
-rw-r--r--src/declarative/extra/qnumberformat.h172
13 files changed, 2831 insertions, 0 deletions
diff --git a/src/declarative/extra/extra.pri b/src/declarative/extra/extra.pri
new file mode 100644
index 0000000..83978f1
--- /dev/null
+++ b/src/declarative/extra/extra.pri
@@ -0,0 +1,24 @@
+SOURCES += \
+ extra/qnumberformat.cpp \
+ extra/qmlnumberformatter.cpp \
+ extra/qfxintegermodel.cpp
+
+HEADERS += \
+ extra/qnumberformat.h \
+ extra/qmlnumberformatter.h \
+ extra/qfxintegermodel.h
+
+contains(QT_CONFIG, xmlpatterns) {
+ QT+=xmlpatterns
+ SOURCES += extra/qmlxmllistmodel.cpp
+ HEADERS += extra/qmlxmllistmodel.h
+}
+
+# SQL is permanently enabled :-/
+#contains(QT_CONFIG, sql) {
+ QT+= sql
+ SOURCES += extra/qmlsqlquery.cpp \
+ extra/qmlsqlconnection.cpp
+ HEADERS += extra/qmlsqlquery.h \
+ extra/qmlsqlconnection.h
+#}
diff --git a/src/declarative/extra/qfxintegermodel.cpp b/src/declarative/extra/qfxintegermodel.cpp
new file mode 100644
index 0000000..3c4d0d9
--- /dev/null
+++ b/src/declarative/extra/qfxintegermodel.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** 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 "qfxintegermodel.h"
+
+
+QT_BEGIN_NAMESPACE
+QML_DEFINE_TYPE(QFxIntegerModel, IntegerModel);
+
+class QFxIntegerModelPrivate
+{
+public:
+ QFxIntegerModelPrivate() : min(0), max(0) {}
+ int min;
+ int max;
+};
+
+QFxIntegerModel::QFxIntegerModel(QObject *parent)
+ : QListModelInterface(parent)
+{
+ d = new QFxIntegerModelPrivate;
+}
+
+QFxIntegerModel::~QFxIntegerModel()
+{
+ delete d;
+}
+
+int QFxIntegerModel::minimum() const
+{
+ return d->min;
+}
+
+void QFxIntegerModel::setMinimum(int min)
+{
+ d->min = min;
+}
+
+int QFxIntegerModel::maximum() const
+{
+ return d->max;
+}
+
+void QFxIntegerModel::setMaximum(int max)
+{
+ d->max = max;
+}
+
+int QFxIntegerModel::count() const
+{
+ return qMax(0, d->max - d->min + 1);
+}
+
+QHash<int,QVariant> QFxIntegerModel::data(int index, const QList<int> &roles) const
+{
+ QHash<int,QVariant> returnHash;
+
+ for (int i = 0; i < roles.size(); ++i) {
+ int role = roles.at(i);
+ QVariant info;
+ switch(role) {
+ case Qt::DisplayRole:
+ info = QVariant(QString::number(d->min+index));
+ break;
+ default:
+ break;
+ }
+ returnHash.insert(role, info);
+ }
+ return returnHash;
+}
+
+QString QFxIntegerModel::toString(int role) const
+{
+ switch(role) {
+ case Qt::DisplayRole:
+ return QLatin1String("display");
+ default:
+ return QLatin1String("");
+ }
+}
+
+QList<int> QFxIntegerModel::roles() const
+{
+ return QList<int>() << Qt::DisplayRole;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/extra/qfxintegermodel.h b/src/declarative/extra/qfxintegermodel.h
new file mode 100644
index 0000000..3a48a56
--- /dev/null
+++ b/src/declarative/extra/qfxintegermodel.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** 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 QFXINTMODEL_H
+#define QFXINTMODEL_H
+
+#include <QObject>
+#include "qml.h"
+#include <qlistmodelinterface.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QFxIntegerModelPrivate;
+class Q_DECLARATIVE_EXPORT QFxIntegerModel : public QListModelInterface
+{
+ Q_OBJECT
+public:
+ QFxIntegerModel(QObject *parent=0);
+ ~QFxIntegerModel();
+
+ Q_PROPERTY(int minimum READ minimum WRITE setMinimum);
+ int minimum() const;
+ void setMinimum(int);
+
+ Q_PROPERTY(int maximum READ maximum WRITE setMaximum);
+ int maximum() const;
+ void setMaximum(int);
+
+ int count() const;
+ QHash<int, QVariant> data(int index, const QList<int> &roles) const;
+ QList<int> roles() const;
+ QString toString(int role) const;
+
+private:
+ QFxIntegerModelPrivate *d;
+};
+
+QML_DECLARE_TYPE(QFxIntegerModel);
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif
diff --git a/src/declarative/extra/qmlnumberformatter.cpp b/src/declarative/extra/qmlnumberformatter.cpp
new file mode 100644
index 0000000..a12c4e6
--- /dev/null
+++ b/src/declarative/extra/qmlnumberformatter.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** 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 "qmlnumberformatter.h"
+#include "private/qobject_p.h"
+
+
+QT_BEGIN_NAMESPACE
+//TODO: set locale
+// docs
+// this is a wrapper around qnumberformat (test integration)
+// if number or format haven't been explictly set, text should be an empty string
+
+class QmlNumberFormatterPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlNumberFormatter)
+public:
+ QmlNumberFormatterPrivate() : locale(QLocale::system()), number(0), classComplete(true) {}
+
+ void updateText();
+
+ QLocale locale;
+ QString format;
+ QNumberFormat numberFormat;
+ QString text;
+ qreal number;
+ bool classComplete;
+};
+/*!
+ \qmlclass NumberFormatter
+ \brief The NumberFormatter allows you to control the format of a number string.
+
+ The format property documentation has more details on how the format can be manipulated.
+
+ In the following example, the text element will display the text "1,234.57".
+ \code
+ <NumberFormatter id="Formatter" number="1234.5678" format="##,##0.##"/>
+ <Text text="{Formatter.text}"/>
+ \endcode
+
+ */
+/*!
+ \class QmlNumberFormatter
+ \ingroup utility
+ \brief The QmlNumberFormatter class allows you to format a number to a particular string format/locale specific number format.
+*/
+
+QmlNumberFormatter::QmlNumberFormatter(QObject *parent)
+: QObject(*(new QmlNumberFormatterPrivate), parent)
+{
+}
+
+QmlNumberFormatter::~QmlNumberFormatter()
+{
+}
+
+/*!
+ \qmlproperty string NumberFormatter::text
+
+ The number in the specified format.
+ <br>
+ If no format is specified the text will be empty.
+*/
+
+QString QmlNumberFormatter::text() const
+{
+ Q_D(const QmlNumberFormatter);
+ return d->text;
+}
+
+/*!
+ \qmlproperty qreal NumberFormatter::number
+
+ A single point precision number. (Doubles are not yet supported)
+
+*/
+qreal QmlNumberFormatter::number() const
+{
+ Q_D(const QmlNumberFormatter);
+ return d->number;
+}
+
+/*!
+ \qmlproperty string NumberFormatter::format
+
+ The particular format the number will adhere to during the conversion to text.
+ <br>
+ The format syntax follows a style similar to the Unicode Standard (UTS35).
+
+ The table below shows the characters, patterns that can be used in the format.
+
+ <table border="0" align="center">
+ <tr style="background-color: #D6E2E8"><th> Character </th><th> Meaning </th></tr>
+ <tr><td> # </td><td> Any digit(s), zero shows as absent (for leading/trailing zeroes) </td></tr>
+ <tr><td> 0 </td><td> Implicit digit. Zero will show in the case that the input number is too small.</td></tr>
+ <tr><td> . </td><td> Decimal separator. Output decimal seperator will be dependant on system locale.</td></tr>
+ <tr><td> , </td><td> Grouping separator. The number of digits (either #, or 0) between the grouping separator and the decimal (or the rightmost digit) will determine the groupingSize)</td></tr>
+ <tr><td> other </td><td> Any other character will be taken as a string literal and placed directly into the output string </td></tr>
+ </table>
+
+ Invalid formats will not guarantee a meaningful text output.<br>
+
+ \note <i>Input numbers that are too long for the given format will be rounded dependent on precison based on the position of the decimal point </i>
+
+ The following table illustrates the output text created by applying some examples of numeric formats to the formatter.
+
+ <table border="0" align="center">
+ <tr style="background-color: #D6E2E8"><th> Format </th><th> Number </th><th> Output </th></tr>
+ <tr><td> ### </td><td> 123456 </td><td> 123456 </td></tr>
+ <tr><td> 000 </td><td> 123456 </td><td> 123456 </td></tr>
+ <tr><td> ###### </td><td> 1234 </td><td> 1234 </td></tr>
+ <tr><td> 000000 </td><td> 1234 </td><td> 001234 </td></tr>
+ <tr><td> ##,##0.## </td><td> 1234.456 </td><td> 1,234.46 (for US locale)<br> 1 234,46 (for FR locale)</td></tr>
+ <tr><td> 000000,000.# </td><td> 123456 </td><td> 000,123,456 (for US locale)<br> 000 123 456 (for FR locale)</td></tr>
+ <tr><td> 0.0### </td><td> 0.999997 </td><td> 1.0 </td></tr>
+ <tr><td> (000) 000 - 000 </td><td> 12345678 </td><td> (012) 345 - 678 </td></tr>
+ <tr><td> #A</td><td>12</td><td>12A</td></tr>
+ </table>
+
+*/
+QString QmlNumberFormatter::format() const
+{
+ Q_D(const QmlNumberFormatter);
+ return d->format;
+}
+
+void QmlNumberFormatter::setNumber(const qreal &number)
+{
+ Q_D(QmlNumberFormatter);
+ if (d->number == number)
+ return;
+ d->number = number;
+ d->updateText();
+}
+
+void QmlNumberFormatter::setFormat(const QString &format)
+{
+ Q_D(QmlNumberFormatter);
+ //no format checking
+ if (format.isEmpty())
+ d->format = QString::null;
+ else
+ d->format = format;
+ d->updateText();
+}
+
+void QmlNumberFormatterPrivate::updateText()
+{
+ Q_Q(QmlNumberFormatter);
+ if (!classComplete)
+ return;
+
+ QNumberFormat tempFormat;
+ tempFormat.setFormat(format);
+ tempFormat.setNumber(number);
+
+ text = tempFormat.text();
+
+ emit q->textChanged();
+}
+
+void QmlNumberFormatter::classBegin()
+{
+ Q_D(QmlNumberFormatter);
+ d->classComplete = false;
+}
+
+void QmlNumberFormatter::classComplete()
+{
+ Q_D(QmlNumberFormatter);
+ d->classComplete = true;
+ d->updateText();
+}
+
+QML_DEFINE_TYPE(QmlNumberFormatter, NumberFormatter);
+QT_END_NAMESPACE
diff --git a/src/declarative/extra/qmlnumberformatter.h b/src/declarative/extra/qmlnumberformatter.h
new file mode 100644
index 0000000..e053be5
--- /dev/null
+++ b/src/declarative/extra/qmlnumberformatter.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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 QMLNUMBERFORMATTER_H
+#define QMLNUMBERFORMATTER_H
+
+#include <qml.h>
+#include "qnumberformat.h"
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QmlNumberFormatterPrivate;
+class Q_DECLARATIVE_EXPORT QmlNumberFormatter : public QObject, public QmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QmlParserStatus)
+
+ Q_PROPERTY(QString text READ text NOTIFY textChanged)
+ Q_PROPERTY(QString format READ format WRITE setFormat)
+ Q_PROPERTY(qreal number READ number WRITE setNumber)
+public:
+ QmlNumberFormatter(QObject *parent=0);
+ ~QmlNumberFormatter();
+
+ QString text() const;
+
+ qreal number() const;
+ void setNumber(const qreal &);
+
+ QString format() const;
+ void setFormat(const QString &);
+
+ virtual void classBegin();
+ virtual void classComplete();
+
+Q_SIGNALS:
+ void textChanged();
+
+private:
+ Q_DISABLE_COPY(QmlNumberFormatter)
+ Q_DECLARE_PRIVATE(QmlNumberFormatter)
+};
+
+QML_DECLARE_TYPE(QmlNumberFormatter);
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif
diff --git a/src/declarative/extra/qmlsqlconnection.cpp b/src/declarative/extra/qmlsqlconnection.cpp
new file mode 100644
index 0000000..3e2032c
--- /dev/null
+++ b/src/declarative/extra/qmlsqlconnection.cpp
@@ -0,0 +1,441 @@
+/****************************************************************************
+**
+** 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 "qmlsqlconnection.h"
+#include "private/qobject_p.h"
+
+#include <QSqlError>
+#include <QSqlDriver>
+#include <QDebug>
+
+#include <qml.h>
+#include <qmlcontext.h>
+
+QT_BEGIN_NAMESPACE
+
+QML_DEFINE_TYPE(QmlSqlConnection, SqlConnection);
+
+class QmlSqlConnectionPrivate: public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlSqlConnection)
+public:
+ QmlSqlConnectionPrivate() : port(0) {}
+
+ int port;
+ QString name, databaseName, connectionOptions;
+ QString hostName, userName, password, driver;
+ QmlContext *context;
+};
+
+/*!
+ \qmlclass SqlConnection QmlSqlConnection
+ \brief The SqlConnection element describes a connection to an SQL database.
+*/
+
+/*!
+ \qmlproperty QString SqlConnection::name
+ \default
+
+ Defines the connection's name. The name allows the connection to be
+ retrieved using the connection property of SqlQuery or when
+ QSqlDatabase::database()
+*/
+
+/*!
+ \qmlproperty QStringList SqlConnection::tables
+
+ Defines the set of tables that exist in the database for the connection.
+*/
+
+/*!
+ \qmlproperty QString SqlConnection::databaseName
+
+ Defines the connection's database name. This is used when opening the
+ connection to the database.
+*/
+
+/*!
+ \qmlproperty QString SqlConnection::driver
+
+ Defines the driver type of the connection. This is used when opening the
+ connection to the database.
+*/
+
+/*!
+ \qmlproperty QString SqlConnection::connectOptions
+
+ Defines the options used when connecting to the database. These are used
+ when opening the connection to the database.
+*/
+
+/*!
+ \qmlproperty QString SqlConnection::hostName
+
+ Defines the connection's host name. This is used when opening the
+ connection to the database.
+*/
+
+/*!
+ \qmlproperty int SqlConnection::port
+
+ Defines the connection's port number. This is used when opening the
+ connection to the database.
+*/
+
+/*!
+ \qmlproperty QString SqlConnection::userName
+
+ Defines the connection's user name. This is used when opening the
+ connection to the database.
+*/
+
+/*!
+ \qmlproperty QString SqlConnection::password
+
+ Defines the connection's password. This is used when opening the
+ connection to the database.
+*/
+
+/*!
+ \qmlproperty QString SqlConnection::lastError
+
+ Defines the last error, if one occurred, when working with the database.
+ If the error occurred in conjunction with an SQL query the error will be
+ defined by SqlQuery::lastError.
+*/
+
+/*!
+ \class QmlSqlConnection
+ \brief The QmlSqlConnection class manages a connection to an SQL database.
+
+ \qmltext
+
+ The SqlConnection element works in a similar way to
+ QSqlDatabase::addDatabase(). It allows setting the database properties
+ such that the connection does not need to be set up in C++ code.
+ It differs from QSqlDatabase::addDatabase() in that it will automatically
+ open the database.
+
+ The database can then either be used from an SqlQuery element using its id
+ as a bind, or using its name. If the database is set up externally to
+ Qml the query should connect using its name.
+
+ \qml
+ <SqlConnection id="myConnection">
+ <name>qmlConnection</name>
+ <driver>QSQLITE</driver>
+ <databaseName>"mydb.sqlite"</databaseName>
+ </SqlConnection>
+ <SqlQuery id="listmodel" connection="{myConnection}">SELECT * FROM mytable</SqlQuery>
+ <SqlQuery id="othermodel" connection="qmlConnection">SELECT * FROM myothertable</SqlQuery>
+ \endqml
+
+ \endqmltext
+*/
+
+/*!
+ Constructs a QmlSqlConnection with the given \a parent.
+*/
+QmlSqlConnection::QmlSqlConnection(QObject *parent)
+: QObject(*(new QmlSqlConnectionPrivate), parent)
+{
+ Q_D(QmlSqlConnection);
+ d->context = QmlContext::activeContext();
+}
+
+/*!
+ Destroys the QmlSqlConnection.
+*/
+QmlSqlConnection::~QmlSqlConnection()
+{
+ QSqlDatabase db = database();
+ if (db.isOpen())
+ db.close();
+}
+
+/*!
+ Returns the connection's name.
+ This is equivalent to QSqlDatabase::connectionName().
+ \sa setName()
+*/
+QString QmlSqlConnection::name() const
+{
+ Q_D(const QmlSqlConnection);
+ return d->name;
+}
+
+/*!
+ Returns the connection's database name.
+ This is equivalent to QSqlDatabase::databaseName().
+ \sa setDatabaseName()
+*/
+QString QmlSqlConnection::databaseName() const
+{
+ Q_D(const QmlSqlConnection);
+ return d->databaseName;
+}
+
+/*!
+ Returns the connect options string used for this connection.
+
+ \sa setConnectOptions()
+*/
+QString QmlSqlConnection::connectOptions() const
+{
+ Q_D(const QmlSqlConnection);
+ return d->connectionOptions;
+}
+
+/*!
+ Returns the connection's host name.
+ \sa setHostName()
+*/
+QString QmlSqlConnection::hostName() const
+{
+ Q_D(const QmlSqlConnection);
+ return d->hostName;
+}
+
+/*!
+ Returns the connection's port number. The value is undefined if the port
+ number has not been set.
+
+ \sa setPort()
+*/
+int QmlSqlConnection::port() const
+{
+ Q_D(const QmlSqlConnection);
+ return d->port;
+}
+
+/*!
+ Returns the connection's user name.
+
+ \sa setUserName()
+*/
+QString QmlSqlConnection::userName() const
+{
+ Q_D(const QmlSqlConnection);
+ return d->userName;
+}
+
+/*!
+ Returns the connection's password.
+
+ \sa setPassword)()
+*/
+QString QmlSqlConnection::password() const
+{
+ Q_D(const QmlSqlConnection);
+ return d->password;
+}
+
+/*!
+ Returns the connection's driver name.
+
+ \sa setDriver()
+*/
+QString QmlSqlConnection::driver() const
+{
+ Q_D(const QmlSqlConnection);
+ return d->driver;
+}
+
+/*!
+ Returns a list of the database's tables.
+*/
+QStringList QmlSqlConnection::tables() const
+{
+ return database().tables();
+}
+
+/*!
+ Sets the connection's name to the given \a name.
+
+ \sa name()
+*/
+void QmlSqlConnection::setName(const QString &name)
+{
+ Q_D(QmlSqlConnection);
+ d->name = name;
+}
+
+/*!
+ Set's the connection's database name to the given \a name.
+
+ \sa databaseName()
+*/
+void QmlSqlConnection::setDatabaseName(const QString &name)
+{
+ Q_D(QmlSqlConnection);
+ d->databaseName = name;
+}
+
+/*!
+ Sets the connection's options to the given \a options.
+
+ \sa connectOptions(), QSqlDatabase::setConnectOptions()
+*/
+void QmlSqlConnection::setConnectOptions(const QString &options)
+{
+ Q_D(QmlSqlConnection);
+ d->connectionOptions = options;
+}
+
+/*!
+ Sets the connection's host name to the given \a name.
+
+ \sa hostName()
+*/
+void QmlSqlConnection::setHostName(const QString &name)
+{
+ Q_D(QmlSqlConnection);
+ d->hostName = name;
+}
+
+/*!
+ Sets the connection's port number to the given \a port.
+
+ \sa port()
+*/
+void QmlSqlConnection::setPort(int port)
+{
+ Q_D(QmlSqlConnection);
+ d->port = port;
+}
+
+/*!
+ Sets the connection's user name to the given \a name.
+
+ \sa userName()
+*/
+void QmlSqlConnection::setUserName(const QString &name)
+{
+ Q_D(QmlSqlConnection);
+ d->userName = name;
+}
+
+/*!
+ Sets the connection's password to the given \a password.
+
+ \sa password()
+*/
+void QmlSqlConnection::setPassword(const QString &password)
+{
+ Q_D(QmlSqlConnection);
+ d->password = password;
+}
+
+/*!
+ Returns information about the last error that occurred on the database.
+
+ Failures that occur in conjunction with an individual query are
+ reported by QmlSqlQuery::lastError()
+*/
+QString QmlSqlConnection::lastError() const
+{
+ return database().lastError().text();
+}
+
+/*!
+ Sets the connection's driver to the specified driver \a type.
+
+ \sa driver(), QSqlDatabase::addDatabase()
+*/
+void QmlSqlConnection::setDriver(const QString &type)
+{
+ Q_D(QmlSqlConnection);
+ d->driver = type;
+}
+
+/*!
+ \reimp
+*/
+void QmlSqlConnection::classComplete()
+{
+}
+
+/*!
+ Returns the database object associated with this connection.
+ If the database is not yet open, it will open the database
+ passed on the settings specified for the SQL connection.
+*/
+QSqlDatabase QmlSqlConnection::database() const
+{
+ Q_D(const QmlSqlConnection);
+
+ QSqlDatabase db;
+ if (QSqlDatabase::connectionNames().contains(d->name)) {
+ db = QSqlDatabase::database(d->name);
+ } else {
+ db = QSqlDatabase::addDatabase(
+ d->driver.isEmpty()
+ ? QLatin1String("QSQLITE")
+ : d->driver,
+ d->name.isEmpty()
+ ? QLatin1String(QSqlDatabase::defaultConnection)
+ : d->name);
+ }
+ if (db.isOpen())
+ return db;
+ if ((d->driver.isEmpty() || d->driver == QLatin1String("QSQLITE")) && d->context) {
+ // SQLITE uses files for databases, hence use relative pathing
+ // if possible.
+ QUrl url = d->context->resolvedUrl(d->databaseName);
+ if (url.isRelative() || url.scheme() == QLatin1String("file"))
+ db.setDatabaseName(url.toLocalFile());
+ else
+ db.setDatabaseName(d->databaseName);
+ } else {
+ db.setDatabaseName(d->databaseName);
+ }
+ db.setConnectOptions(d->connectionOptions);
+ db.setHostName(d->hostName);
+ db.setPassword(d->password);
+ db.setPort(d->port);
+ db.setUserName(d->userName);
+ if (!db.open())
+ qWarning() << "Failed to open database" << lastError();
+
+ return db;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/extra/qmlsqlconnection.h b/src/declarative/extra/qmlsqlconnection.h
new file mode 100644
index 0000000..2cc5774
--- /dev/null
+++ b/src/declarative/extra/qmlsqlconnection.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** 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 QMLSQLCONNECTION_H
+#define QMLSQLCONNECTION_H
+
+#include <qml.h>
+#include <QSqlDatabase>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QSqlDatabase;
+class QmlSqlConnectionPrivate;
+class Q_DECLARATIVE_EXPORT QmlSqlConnection : public QObject, public QmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QmlParserStatus)
+
+ Q_PROPERTY(QString name READ name WRITE setName);
+ Q_PROPERTY(QStringList tables READ tables);
+ Q_PROPERTY(QString databaseName READ databaseName WRITE setDatabaseName);
+ Q_PROPERTY(QString driver READ driver WRITE setDriver);
+ Q_PROPERTY(QString connectOptions READ connectOptions WRITE setConnectOptions);
+ Q_PROPERTY(QString hostName READ hostName WRITE setHostName);
+ Q_PROPERTY(int port READ port WRITE setPort);
+ Q_PROPERTY(QString userName READ userName WRITE setUserName);
+ Q_PROPERTY(QString password READ password WRITE setPassword);
+ Q_PROPERTY(QString lastError READ lastError);
+ Q_CLASSINFO("DefaultProperty", "name")
+public:
+ QmlSqlConnection(QObject *parent = 0);
+ ~QmlSqlConnection();
+
+ QString name() const;
+ void setName(const QString &);
+
+ QStringList tables() const;
+
+ QString databaseName() const;
+ void setDatabaseName(const QString &);
+
+ QString connectOptions() const;
+ void setConnectOptions(const QString &);
+
+ QString hostName() const;
+ void setHostName(const QString &);
+
+ int port() const;
+ void setPort(int);
+
+ QString userName() const;
+ void setUserName(const QString &);
+
+ QString password() const;
+ void setPassword(const QString &);
+
+ QString driver() const;
+ void setDriver(const QString &);
+
+ QString lastError() const;
+
+ virtual void classComplete();
+
+ QSqlDatabase database() const;
+private:
+ Q_DISABLE_COPY(QmlSqlConnection)
+ Q_DECLARE_PRIVATE(QmlSqlConnection)
+};
+
+QML_DECLARE_TYPE(QmlSqlConnection);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif // QMLXMLLISTMODEL_H
+
diff --git a/src/declarative/extra/qmlsqlquery.cpp b/src/declarative/extra/qmlsqlquery.cpp
new file mode 100644
index 0000000..39d3aa2
--- /dev/null
+++ b/src/declarative/extra/qmlsqlquery.cpp
@@ -0,0 +1,696 @@
+/****************************************************************************
+**
+** 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 "qmlsqlquery.h"
+#include "qmlsqlconnection.h"
+#include "private/qobject_p.h"
+
+#include <QDebug>
+#include <QSqlQuery>
+#include <QSqlError>
+#include <QSqlField>
+#include <QSqlRecord>
+#include <QSqlDatabase>
+#include <QSqlDriver>
+
+QT_BEGIN_NAMESPACE
+QML_DEFINE_TYPE(QmlSqlBind, SqlBind);
+QML_DEFINE_TYPE(QmlSqlQuery, SqlQuery);
+
+class QmlSqlBindPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlSqlBind)
+public:
+ QmlSqlBindPrivate() {}
+
+ QString name;
+ QVariant value;
+};
+
+/*!
+ \qmlclass SqlBind QmlSqlBind
+ \brief the SqlBind element specifies a value binding for an SqlQuery element.
+*/
+
+/*!
+ \class QmlSqlBind
+ \brief the QmlSqlBind class specifies a value binding for a QmlSqlQuery.
+
+ \qmltext
+
+ \qml
+ By using bindings its possible to cause a SqlQuery to update itself
+ when values bound through the SqlBind change. Hence in the example
+ below the results for the SqlQuery will change as searchText changes.
+
+ If the query is not a SELECT statement, the effects of the bound
+ values will only apply when the SqlQuery exec() slot is called.
+
+ <SqlQuery>
+ SELECT * FROM mytable WHERE name LIKE :value
+ <bindings>
+ <SqlBind name=":value" value="{searchText + '%'}"/>
+ </bindings>
+ </SqlQuery>
+ <SqlQuery>
+ SELECT * FROM mytable WHERE type = ?
+ <bindings>
+ <SqlBind value="simple"/>
+ </bindings>
+ <SqlQuery>
+ \endqml
+ \endqmltext
+*/
+
+/*!
+ \fn void QmlSqlBind::valueChanged()
+
+ This signal is emitted when the value property of the SqlBind changes.
+*/
+
+/*!
+ \qmlproperty QString SqlBind::name
+
+ Defines the placeholder name of the bind. If no name is specified the
+ bind will use its position within the SqlQuery's bindings to bind
+ into the query.
+*/
+
+/*!
+ \qmlproperty QVariant SqlBind::value
+
+ Defines the value to bind into the query.
+*/
+
+/*!
+ Constructs a QmlSqlVind with the given \a parent
+*/
+QmlSqlBind::QmlSqlBind(QObject *parent)
+: QObject(*(new QmlSqlBindPrivate()), parent)
+{
+}
+
+/*!
+ Destroys the QmlSqlBind.
+*/
+QmlSqlBind::~QmlSqlBind()
+{
+}
+
+/*!
+ Returns the binding's name.
+
+ \sa setName()
+*/
+QString QmlSqlBind::name() const
+{
+ Q_D(const QmlSqlBind);
+ return d->name;
+}
+
+/*!
+ Returns the binding's value.
+
+ \sa setValue()
+*/
+QVariant QmlSqlBind::value() const
+{
+ Q_D(const QmlSqlBind);
+ return d->value;
+}
+
+/*!
+ Sets the binding's name to the given \a name.
+
+ \sa name()
+*/
+void QmlSqlBind::setName(const QString &name)
+{
+ Q_D(QmlSqlBind);
+ d->name = name;
+}
+
+/*!
+ Sets the binding's value to the given \a value.
+
+ \sa value()
+*/
+void QmlSqlBind::setValue(const QVariant &value)
+{
+ Q_D(QmlSqlBind);
+ if (d->value != value) {
+ d->value = value;
+ emit valueChanged();
+ }
+}
+
+/*!
+ \reimp
+*/
+void QmlSqlBind::classComplete()
+{
+}
+
+class QmlSqlQueryPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlSqlQuery)
+public:
+ QmlSqlQueryPrivate(QmlSqlQuery *owner) : isSel(false), query(NULL), requireCache(false), count(-1), binds(owner) {}
+ void prepareQuery() const;
+ void bindQuery() const;
+ void cacheQuery() const;
+ void grabRoles() const;
+
+ QString queryText;
+ bool isSel;
+ QVariant connectionVariant;
+ mutable QSqlQuery *query;
+ mutable bool requireCache;
+ mutable int count;
+ mutable QList<int> roles;
+ mutable QStringList roleNames;
+ mutable QVector< QVector< QVariant > > cache;
+
+ class QmlSqlBindList : public QmlList<QmlSqlBind *>
+ {
+ public:
+ QmlSqlBindList(QmlSqlQuery *owner)
+ : q(owner){}
+
+ void append(QmlSqlBind *o) {
+ m_contents.append(o);
+ QObject::connect(o, SIGNAL(valueChanged()), q, SLOT(resetBinds()));
+ }
+ void clear() { m_contents.clear(); }
+ int count() const { return m_contents.count(); }
+ void removeAt(int pos) { return m_contents.removeAt(pos); }
+ QmlSqlBind *at(int pos) const { return m_contents.at(pos); }
+ void insert(int pos, QmlSqlBind *o) { m_contents.insert(pos, o); }
+ private:
+ QList<QmlSqlBind *> m_contents;
+ QmlSqlQuery *q;
+ };
+
+ QmlSqlBindList binds;
+};
+
+/*!
+ \qmlclass SqlQuery QmlSqlQuery
+ \brief The SqlQuery element describes a query into an SQL database.
+*/
+
+/*
+ \class QmlSqlQuery
+ \brief the QmlSqlQuery class manages a query into an SQL database.
+
+ \qmltext
+ The SqlQuery element has three parts. The first is the query itself,
+ which can either be specified using the query property or by the
+ default text for the element. The second specifies the connection
+ to the database. This can either be a bound id from an SqlConnection
+ or the connections name. If the connection is specified in a QML
+ SqlConnection it is recommend to bind to the id to help ensure the
+ database is complete before attempting to attach to it. If no
+ connectoin is specified the default connection is used.
+
+ It is also possible to bind values into the query using the bindings
+ property. See SqlBind for more information on how to bind values into
+ the query.
+
+ If the query is a select statement it can be used as a model for a ListView.
+ The roles will be the columns of the result set. Use the SQL AS keyword
+ in the query if you want to override the column names from that of the
+ table selected. You should also use the AS keyword if there is no
+ appropriate table column name for the result column.
+
+ \qml
+ <SqlQuery connection="{qmlConnectionId}" query="DELETE FROM mytable"/>
+ <SqlQuery connection="connectionName">
+ SELECT * FROM mytable
+ </SqlQuery>
+ <SqlQuery>SELECT id AS recordId, (firstName || ' ' || lastName) AS fullName FROM mytable</SqlQuery>
+ \endqml
+ \endqmltext
+*/
+
+/*!
+ \qmlproperty QString SqlQuery::query
+ \default
+
+ Defines the query text.
+*/
+
+/*!
+ \qmlproperty QVariant SqlQuery::connection
+
+ Defines the connection to an SQL database used by the query.
+*/
+
+/*!
+ \qmlproperty QString SqlQuery::lastError
+
+ Defines the last error, if one occurred, when working with the query.
+*/
+
+/*!
+ \qmlproperty list<SqlBind> SqlQuery::bindings
+
+ The bindings property contains the list of values to bind into the
+ query. See SqlBind for more information.
+*/
+
+/*!
+ Constructs a QmlSqlQuery with the given \a parent.
+*/
+QmlSqlQuery::QmlSqlQuery(QObject *parent)
+: QListModelInterface(*(new QmlSqlQueryPrivate(this)), parent)
+{
+}
+
+/*!
+ Destroys the QmlSqlQuery.
+*/
+QmlSqlQuery::~QmlSqlQuery()
+{
+ Q_D(QmlSqlQuery);
+ if (d->query)
+ delete d->query;
+}
+
+/*!
+ Returns the query's bound variables.
+*/
+QmlList<QmlSqlBind *> *QmlSqlQuery::bindings()
+{
+ Q_D(QmlSqlQuery);
+ return &d->binds;
+}
+
+/*!
+ Returns the query's bound variables.
+*/
+const QmlList<QmlSqlBind *> *QmlSqlQuery::bindings() const
+{
+ Q_D(const QmlSqlQuery);
+ return &d->binds;
+}
+
+/*!
+ Returns the query text.
+
+ \sa setQuery()
+*/
+QString QmlSqlQuery::query() const
+{
+ Q_D(const QmlSqlQuery);
+ return d->queryText;
+}
+
+/*!
+ Sets the query text to the given \a text.
+*/
+void QmlSqlQuery::setQuery(const QString &text)
+{
+ Q_D(QmlSqlQuery);
+ if (text != d->queryText) {
+ d->queryText = text;
+
+ static const QLatin1String select("select");
+ d-> isSel = text.trimmed().indexOf(select, 0, Qt::CaseInsensitive) == 0;
+
+ if (d->query)
+ resetQuery();
+ }
+}
+
+/*!
+ Returns the query's connection specifier.
+
+ \sa setConnection()
+*/
+QVariant QmlSqlQuery::connection() const
+{
+ Q_D(const QmlSqlQuery);
+ return d->connectionVariant;
+}
+
+/*!
+ Sets the query's connection specifier.
+
+ \sa connection()
+*/
+void QmlSqlQuery::setConnection(const QVariant &connection)
+{
+ Q_D(QmlSqlQuery);
+ if (connection != d->connectionVariant) {
+ d->connectionVariant = connection;
+ if (d->query)
+ resetQuery();
+ else if (d->count == 0) // data has been requested
+ d->prepareQuery();
+ }
+}
+
+/*!
+ Returns the set of values for a given set of requested \a roles for the
+ specified \a row of the query result set. Returns an empty hash if the
+ query is not a select statement.
+
+ \sa count(), roles(), toString()
+*/
+QHash<int,QVariant> QmlSqlQuery::data(int row, const QList<int> &roles) const
+{
+ Q_D(const QmlSqlQuery);
+ if (!d->query)
+ d->prepareQuery();
+ QHash<int, QVariant> result;
+
+ if (!d->isSel)
+ return result;
+
+ Q_ASSERT(row >= 0 && row <= d->count);
+
+ if (!d->requireCache)
+ d->query->seek(row);
+
+ for (int i = 0; i < roles.count(); ++i) {
+ int column = roles[i];
+ Q_ASSERT(column >= 0 && column < d->cache.size());
+ if (d->requireCache)
+ result.insert(column, d->cache[column].at(row));
+ else
+ result.insert(column, d->query->value(column));
+ }
+ return result;
+}
+
+/*!
+ Returns the number of rows in the query result set. Returns 0 if
+ the query is not a select statement.
+
+ \sa data(), roles(), toString()
+*/
+int QmlSqlQuery::count() const
+{
+ Q_D(const QmlSqlQuery);
+ if (!d->query)
+ d->prepareQuery();
+ return d->count;
+}
+
+/*!
+ Returns the list of role integer identifiers for the query result set.
+ Returns and empty list if the query is not a select statement.
+
+ \sa data(), count(), toString()
+*/
+QList<int> QmlSqlQuery::roles() const
+{
+ Q_D(const QmlSqlQuery);
+ if (!d->query)
+ d->prepareQuery();
+
+ if (!d->isSel)
+ return QList<int>();
+
+ if (d->roleNames.isEmpty() && !d->requireCache) {
+ d->query->seek(0);
+ d->grabRoles();
+ }
+
+ return d->roles;
+}
+
+/*!
+ Returns the corresponding role name for the given \a role identifier.
+
+ \sa data(), roles(), toString()
+*/
+QString QmlSqlQuery::toString(int role) const
+{
+ Q_D(const QmlSqlQuery);
+ if (!d->query)
+ d->prepareQuery();
+
+ if (d->roleNames.isEmpty() && !d->requireCache) {
+ d->query->seek(0);
+ d->grabRoles();
+ }
+
+ return d->roleNames[role];
+}
+
+/*!
+ Returns information about the last error that occurred on the query.
+*/
+QString QmlSqlQuery::lastError() const
+{
+ Q_D(const QmlSqlQuery);
+ if (d->query)
+ return d->query->lastError().text();
+ return QString();
+}
+
+/*!
+ \reimp
+*/
+void QmlSqlQuery::classComplete()
+{
+ Q_D(QmlSqlQuery);
+ if (!d->query)
+ d->prepareQuery();
+}
+
+/*!
+ \internal
+ Rebinds the query, and if needed, emits rows inserted or rows
+ added so any attached ListView elements will correctly.
+
+ This slot is called automatically when the SqlBind elements in
+ the bindings property of the query change.
+*/
+void QmlSqlQuery::resetBinds()
+{
+ Q_D(QmlSqlQuery);
+ if (!d->query)
+ return;
+ int oldcount = d->count;
+ d->cache.resize(0);
+ d->roles.clear();
+ d->roleNames.clear();
+ d->bindQuery();
+ if (d->isSel) {
+ if (!d->query->isActive()) {
+ if (!d->query->exec())
+ qWarning() << "failed to execute query" << d->query->lastQuery() << d->query->boundValues() << d->query->lastError().text();
+ }
+ d->cacheQuery(); // may finish query
+ emitChanges(oldcount);
+ }
+}
+
+/*!
+ Executes the query. For SELECT statements this is normally only required
+ if the database changes outside of the SQL query element. Statements that
+ modify the database, such as UPDATE and INSERT, will not be applied until
+ this function is called.
+*/
+void QmlSqlQuery::exec()
+{
+ Q_D(QmlSqlQuery);
+ if (!d->query)
+ d->prepareQuery();
+ Q_ASSERT(d->query);
+
+ if (d->isSel) {
+ int oldcount = d->count;
+ d->cache.resize(0);
+ d->roles.clear();
+ d->roleNames.clear();
+ if (!d->query->exec())
+ qWarning() << "failed to execute query" << d->query->lastQuery() << d->query->boundValues() << d->query->lastError().text();
+ d->cacheQuery(); // may finish query
+ emitChanges(oldcount);
+ } else {
+ if (!d->query->exec())
+ qWarning() << "failed to execute query" << d->query->lastQuery() << d->query->boundValues() << d->query->lastError().text();
+ d->query->finish();
+ }
+}
+
+/*!
+ \internal
+
+ Resets the query and query cache.
+*/
+void QmlSqlQuery::resetQuery()
+{
+ Q_D(QmlSqlQuery);
+ Q_ASSERT(d->query != 0);
+ delete d->query;
+ d->query = 0;
+ d->cache.resize(0);
+ d->roles.clear();
+ d->roleNames.clear();
+ int oldcount = d->count;
+ d->prepareQuery();
+ emitChanges(oldcount);
+}
+
+/*!
+ \internal
+
+ emits row number changes based of differences between the given
+ \a oldcount and the current count of the query result set.
+*/
+void QmlSqlQuery::emitChanges(int oldcount)
+{
+ Q_D(QmlSqlQuery);
+ if (d->count > oldcount)
+ emit itemsInserted(oldcount, d->count-oldcount);
+ else if (d->count < oldcount)
+ emit itemsRemoved(d->count, oldcount-d->count);
+ if (d->count > 0 && oldcount > 0)
+ emit itemsChanged(0, qMin(d->count, oldcount), roles());
+}
+
+/*
+ Prepares the query. If the query starts with SELECT it is assumed to
+ be a SELECT statement and the query is also executed.
+*/
+void QmlSqlQueryPrivate::prepareQuery() const
+{
+ QObject *object = qvariant_cast<QObject*>(connectionVariant);
+ QmlSqlConnection *connection = qobject_cast<QmlSqlConnection *>(object);
+ QString connectionString = qvariant_cast<QString>(connectionVariant);
+
+ Q_ASSERT(query == 0);
+ QSqlDatabase db = connection ? connection->database()
+ : QSqlDatabase::database(connectionString.isEmpty()
+ ? QLatin1String(QSqlDatabase::defaultConnection)
+ : connectionString, false);
+
+ if (!db.isOpen()) {
+ count = 0;
+ return;
+ }
+
+ query = new QSqlQuery(db);
+
+ requireCache =
+ query->driver()->hasFeature(QSqlDriver::SimpleLocking)
+ || !query->driver()->hasFeature(QSqlDriver::QuerySize);
+
+ if (requireCache)
+ query->setForwardOnly(true);
+ if (!query->prepare(queryText))
+ qWarning() << "failed to prepare query" << query->lastQuery() << query->lastError().text();
+ bindQuery();
+ if (isSel) {
+ if (!query->exec())
+ qWarning() << "failed to execute query" << query->lastQuery() << query->boundValues() << query->lastError().text();
+ cacheQuery();
+ }
+}
+
+/*
+ Binds values into the prepared query using the bindings property of the SqlQuery element.
+*/
+void QmlSqlQueryPrivate::bindQuery() const
+{
+ for (int i = 0; i < binds.count(); ++i) {
+ QmlSqlBind *bind = binds.at(i);
+ if (bind->name().isEmpty()) {
+ query->bindValue(i, bind->value());
+ } else {
+ query->bindValue(bind->name(), bind->value());
+ }
+ }
+}
+
+/*
+ If the query is connected to a database with simple locking or
+ that cannot ask for the count of a result set, caches the required
+ data of the query and finishes the query to release locks.
+
+ Otherwise just caches the count of the query.
+*/
+void QmlSqlQueryPrivate::cacheQuery() const
+{
+ if (requireCache) {
+ int row = 0;
+ while (query->next()) {
+ if (roleNames.isEmpty()) {
+ grabRoles();
+ cache.resize(roleNames.count());
+ }
+ Q_ASSERT(cache.size() > 0);
+ for (int i = 0; i < cache.size(); ++i) {
+ cache[i].append(query->value(i));
+ }
+ row++;
+ }
+ count = row;
+ query->finish();
+ } else {
+ count = query->size();
+ }
+}
+
+/*
+ Gets the column names for the roles of the SqlQuery element.
+
+ The query must be active and on a valid row.
+*/
+void QmlSqlQueryPrivate::grabRoles() const
+{
+ Q_ASSERT(query);
+ Q_ASSERT(query->isValid());
+ Q_ASSERT(roleNames.isEmpty());
+ Q_ASSERT(roles.isEmpty());
+
+ QSqlRecord record = query->record();
+ for (int i = 0; i < record.count(); ++i) {
+ roleNames.append(record.fieldName(i));
+ roles.append(i);
+ }
+}
+QT_END_NAMESPACE
diff --git a/src/declarative/extra/qmlsqlquery.h b/src/declarative/extra/qmlsqlquery.h
new file mode 100644
index 0000000..984483c
--- /dev/null
+++ b/src/declarative/extra/qmlsqlquery.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** 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 QMLSQLQUERYMODEL_H
+#define QMLSQLQUERYMODEL_H
+
+#include <qml.h>
+#include <QListModelInterface>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QmlSqlBindPrivate;
+class Q_DECLARATIVE_EXPORT QmlSqlBind : public QObject, public QmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QmlParserStatus)
+
+ Q_PROPERTY(QString name READ name WRITE setName)
+ Q_PROPERTY(QVariant value READ value WRITE setValue)
+
+ Q_CLASSINFO("DefaultValue", "value");
+
+public:
+ QmlSqlBind(QObject *parent = 0);
+ ~QmlSqlBind();
+
+ QString name() const;
+ QVariant value() const;
+
+ void setName(const QString &name);
+ void setValue(const QVariant &);
+
+ virtual void classComplete();
+
+Q_SIGNALS:
+ void valueChanged();
+
+private:
+ Q_DISABLE_COPY(QmlSqlBind)
+ Q_DECLARE_PRIVATE(QmlSqlBind)
+};
+
+QML_DECLARE_TYPE(QmlSqlBind);
+
+class QSqlQuery;
+class QmlSqlQueryPrivate;
+class Q_DECLARATIVE_EXPORT QmlSqlQuery : public QListModelInterface, public QmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QmlParserStatus)
+
+ Q_PROPERTY(QString query READ query WRITE setQuery)
+ Q_PROPERTY(QVariant connection READ connection WRITE setConnection)
+ Q_PROPERTY(QString lastError READ lastError)
+
+ Q_PROPERTY(QmlList<QmlSqlBind *> *bindings READ bindings)
+
+ Q_CLASSINFO("DefaultProperty", "query")
+public:
+ QmlSqlQuery(QObject *parent = 0);
+ ~QmlSqlQuery();
+
+ QString query() const;
+ void setQuery(const QString &);
+
+ QVariant connection() const;
+ void setConnection(const QVariant &);
+
+ virtual QHash<int,QVariant> data(int index, const QList<int> &roles = (QList<int>())) const;
+ virtual int count() const;
+ virtual QList<int> roles() const;
+ virtual QString toString(int role) const;
+
+ QString lastError() const;
+
+ virtual void classComplete();
+
+ QmlList<QmlSqlBind *> *bindings();
+ const QmlList<QmlSqlBind *> *bindings() const;
+
+public slots:
+ void exec();
+
+private slots:
+ void resetBinds();
+ void resetQuery();
+
+private:
+ void emitChanges(int oldcount);
+
+ Q_DISABLE_COPY(QmlSqlQuery)
+ Q_DECLARE_PRIVATE(QmlSqlQuery)
+};
+
+QML_DECLARE_TYPE(QmlSqlQuery);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif
+
diff --git a/src/declarative/extra/qmlxmllistmodel.cpp b/src/declarative/extra/qmlxmllistmodel.cpp
new file mode 100644
index 0000000..13faab2
--- /dev/null
+++ b/src/declarative/extra/qmlxmllistmodel.cpp
@@ -0,0 +1,357 @@
+/****************************************************************************
+**
+** 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 "qmlxmllistmodel.h"
+#include "private/qobject_p.h"
+
+#include <QtDeclarative/qmlcontext.h>
+#include <QtDeclarative/qmlengine.h>
+#include <QDebug>
+#include <QXmlQuery>
+#include <QXmlResultItems>
+#include <QXmlNodeModelIndex>
+#include <QBuffer>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+
+QT_BEGIN_NAMESPACE
+
+QML_DEFINE_TYPE(XmlListModelRole, Role);
+QML_DEFINE_TYPE(QmlXmlListModel, XmlListModel);
+
+//TODO: do something smart while waiting for data to load
+// error handling (currently quite fragile)
+// profile doQuery and doSubquery
+// some sort of loading indication while we wait for initial data load (status property similar to QWebImage?)
+// support complex/nested objects?
+// how do we handle data updates (like rss feed -- usually items inserted at beginning)
+
+/*!
+ \qmlclass XmlListModel
+ \brief The XmlListModel class allows you to specify a model using XQuery.
+
+ XmlListModel allows you to construct a model from XML data that can then be used as a data source
+ for the view classes (ListView, PathView, GridView) and any other classes that interact with model
+ data (like Repeater).
+
+ The following is an example of a model containing news from a Yahoo RSS feed:
+ \qml
+ <XmlListModel id="FeedModel" src="http://rss.news.yahoo.com/rss/oceania" query="doc($src)/rss/channel/item">
+ <Role name="title" query="title/string()"/>
+ <Role name="link" query="link/string()"/>
+ <Role name="description" query="description/string()" isCData="true"/>
+ </XmlListModel>
+ \endqml
+ \note The model is currently static, so the above is really just a snapshot of an RSS feed.
+*/
+
+class QmlXmlListModelPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlXmlListModel)
+public:
+ QmlXmlListModelPrivate() : size(-1), highestRole(Qt::UserRole), reply(0), context(0), roleObjects(this) {}
+
+ QString src;
+ QString query;
+ QString namespaces;
+ QList<int> roles;
+ QStringList roleNames;
+ mutable QList<QList<QVariant> > data;
+ int size;
+ int highestRole;
+ QNetworkReply *reply;
+ mutable QByteArray xml;
+ QString prefix;
+ QmlContext *context;
+
+ struct RoleList : public QmlConcreteList<XmlListModelRole *>
+ {
+ RoleList(QmlXmlListModelPrivate *p)
+ : model(p) {}
+ virtual void append(XmlListModelRole *role) {
+ QmlConcreteList<XmlListModelRole *>::append(role);
+ model->roles << model->highestRole;
+ model->roleNames << role->name();
+ ++model->highestRole;
+ }
+ //XXX clear, removeAt, and insert need to invalidate any cached data (in data table) as well
+ // (and the model should emit the appropriate signals)
+ virtual void clear()
+ {
+ model->roles.clear();
+ model->roleNames.clear();
+ QmlConcreteList<XmlListModelRole *>::clear();
+ }
+ virtual void removeAt(int i)
+ {
+ model->roles.removeAt(i);
+ model->roleNames.removeAt(i);
+ QmlConcreteList<XmlListModelRole *>::removeAt(i);
+ }
+ virtual void insert(int i, XmlListModelRole *role)
+ {
+ QmlConcreteList<XmlListModelRole *>::insert(i, role);
+ model->roles.insert(i, model->highestRole);
+ model->roleNames.insert(i, role->name());
+ ++model->highestRole;
+ }
+
+ QmlXmlListModelPrivate *model;
+ };
+
+ RoleList roleObjects;
+};
+
+QmlXmlListModel::QmlXmlListModel(QObject *parent)
+ : QListModelInterface(*(new QmlXmlListModelPrivate), parent)
+{
+ Q_D(QmlXmlListModel);
+ d->context = QmlContext::activeContext();
+}
+
+QmlXmlListModel::~QmlXmlListModel()
+{
+}
+
+QmlList<XmlListModelRole *> *QmlXmlListModel::roleObjects()
+{
+ Q_D(QmlXmlListModel);
+ return &d->roleObjects;
+}
+
+QHash<int,QVariant> QmlXmlListModel::data(int index, const QList<int> &roles) const
+{
+ Q_D(const QmlXmlListModel);
+ QHash<int, QVariant> rv;
+
+ if (index > d->data.count() - 1)
+ doSubquery(index);
+
+ for (int i = 0; i < roles.size(); ++i) {
+ int role = roles.at(i);
+ int roleIndex = d->roles.indexOf(role);
+ rv.insert(role, d->data.at(index).at(roleIndex));
+ }
+ return rv;
+}
+
+int QmlXmlListModel::count() const
+{
+ Q_D(const QmlXmlListModel);
+ return d->size;
+}
+
+QList<int> QmlXmlListModel::roles() const
+{
+ Q_D(const QmlXmlListModel);
+ return d->roles;
+}
+
+QString QmlXmlListModel::toString(int role) const
+{
+ Q_D(const QmlXmlListModel);
+ int index = d->roles.indexOf(role);
+ if (index == -1)
+ return QString();
+ return d->roleNames.at(index);
+}
+
+QString QmlXmlListModel::src() const
+{
+ Q_D(const QmlXmlListModel);
+ return d->src;
+}
+
+void QmlXmlListModel::setSrc(const QString &src)
+{
+ Q_D(QmlXmlListModel);
+ d->src = src;
+}
+
+QString QmlXmlListModel::query() const
+{
+ Q_D(const QmlXmlListModel);
+ return d->query;
+}
+
+void QmlXmlListModel::setQuery(const QString &query)
+{
+ Q_D(QmlXmlListModel);
+ d->query = query;
+}
+
+QString QmlXmlListModel::namespaceDeclarations() const
+{
+ Q_D(const QmlXmlListModel);
+ return d->namespaces;
+}
+
+void QmlXmlListModel::setNamespaceDeclarations(const QString &declarations)
+{
+ Q_D(QmlXmlListModel);
+ d->namespaces = declarations;
+}
+
+void QmlXmlListModel::classComplete()
+{
+ fetch();
+}
+
+void QmlXmlListModel::fetch()
+{
+ Q_D(QmlXmlListModel);
+ if (d->src.isEmpty()) {
+ qWarning() << "Can't fetch empty src string";
+ //clear existing data?
+ //int count = d->data.count();
+ //d->data.clear();
+ //emit itemsRemoved(0, count);
+ return;
+ }
+
+ QNetworkRequest req((QUrl(d->src)));
+ req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
+ d->reply = d->context->engine()->networkAccessManager()->get(req);
+ QObject::connect(d->reply, SIGNAL(finished()),
+ this, SLOT(requestFinished()));
+}
+
+void QmlXmlListModel::requestFinished()
+{
+ Q_D(QmlXmlListModel);
+ if(d->reply->error() != QNetworkReply::NoError) {
+ d->reply->deleteLater();
+ d->reply = 0;
+ } else {
+ QByteArray data = d->reply->readAll();
+ doQuery(data);
+ d->reply->deleteLater();
+ d->reply = 0;
+ }
+}
+
+void QmlXmlListModel::doQuery(QByteArray &rawData)
+{
+ Q_D(QmlXmlListModel);
+ QString r;
+ QXmlQuery query;
+ QBuffer rawBuffer(&rawData);
+ rawBuffer.open(QIODevice::ReadOnly);
+ query.bindVariable(QLatin1String("src"), &rawBuffer);
+ query.setQuery(d->namespaces + d->query);
+ query.evaluateTo(&r);
+ //qDebug() << r;
+
+ //always need a single root element
+ QByteArray xml = "<dummy:items xmlns:dummy=\"http://qtsotware.com/dummy\">\n" + r.toUtf8() + "</dummy:items>";
+ QBuffer b(&xml);
+ b.open(QIODevice::ReadOnly);
+ //qDebug() << xml;
+
+ QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + d->namespaces;
+ QString prefix = QLatin1String("doc($inputDocument)/dummy:items") +
+ d->query.mid(d->query.lastIndexOf(QLatin1Char('/')));
+
+ //figure out how many items we are dealing with
+ int count = -1;
+ {
+ QXmlResultItems result;
+ QXmlQuery countquery;
+ countquery.bindVariable(QLatin1String("inputDocument"), &b);
+ countquery.setQuery(namespaces + QLatin1String("count(") + prefix + QLatin1String(")"));
+ countquery.evaluateTo(&result);
+ QXmlItem item(result.next());
+ if (item.isAtomicValue())
+ count = item.toAtomicValue().toInt();
+ b.seek(0);
+ prefix += QLatin1String("[%1]/");
+ }
+ //qDebug() << count;
+
+ QXmlQuery subquery;
+ subquery.bindVariable(QLatin1String("inputDocument"), &b);
+ d->prefix = namespaces + prefix;
+ d->xml = xml;
+
+ d->size = count;
+ emit itemsInserted(0, count);
+}
+
+void QmlXmlListModel::doSubquery(int index) const
+{
+ Q_D(const QmlXmlListModel);
+ //qDebug() << "doSubQuery" << index;
+ QBuffer b(&d->xml);
+ b.open(QIODevice::ReadOnly);
+
+ QXmlQuery subquery;
+ subquery.bindVariable(QLatin1String("inputDocument"), &b);
+
+ //XXX should we use an array of objects or something else rather than a table?
+ for (int j = d->data.count(); j <= index; ++j) {
+ QList<QVariant> resultList;
+ for (int i = 0; i < d->roleObjects.size(); ++i) {
+ XmlListModelRole *role = d->roleObjects.at(i);
+ subquery.setQuery(d->prefix.arg(j+1) + role->query());
+ if (role->isStringList()) {
+ QStringList data;
+ subquery.evaluateTo(&data);
+ resultList << QVariant(data);
+ //qDebug() << data;
+ } else {
+ QString s;
+ subquery.evaluateTo(&s);
+ if (role->isCData()) {
+ //un-escape
+ s.replace(QLatin1String("&lt;"), QLatin1String("<"));
+ s.replace(QLatin1String("&gt;"), QLatin1String(">"));
+ s.replace(QLatin1String("&amp;"), QLatin1String("&"));
+ }
+ resultList << s;
+ //qDebug() << s;
+ }
+ b.seek(0);
+ }
+ d->data << resultList;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/extra/qmlxmllistmodel.h b/src/declarative/extra/qmlxmllistmodel.h
new file mode 100644
index 0000000..a8f3087
--- /dev/null
+++ b/src/declarative/extra/qmlxmllistmodel.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** 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 QMLXMLLISTMODEL_H
+#define QMLXMLLISTMODEL_H
+
+#include <qml.h>
+#include <QListModelInterface>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QmlContext;
+class Q_DECLARATIVE_EXPORT XmlListModelRole : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString name READ name WRITE setName)
+ Q_PROPERTY(QString query READ query WRITE setQuery)
+ Q_PROPERTY(bool isCData READ isCData WRITE setIsCData)
+ Q_PROPERTY(bool isStringList READ isStringList WRITE setIsStringList)
+
+public:
+ XmlListModelRole() : m_isList(false), m_isCData(false) {}
+ ~XmlListModelRole() {}
+
+ QString name() const { return m_name; }
+ void setName(const QString &name) { m_name = name; }
+
+ QString query() const { return m_query; }
+ void setQuery(const QString &query) { m_query = query; }
+
+ bool isStringList() const { return m_isList; }
+ void setIsStringList(bool b) { m_isList = b; }
+
+ bool isCData() const { return m_isCData; }
+ void setIsCData(bool b) { m_isCData = b; }
+
+private:
+ QString m_name;
+ QString m_query;
+ bool m_isList;
+ bool m_isCData;
+};
+QML_DECLARE_TYPE(XmlListModelRole);
+
+class QmlXmlListModelPrivate;
+class Q_DECLARATIVE_EXPORT QmlXmlListModel : public QListModelInterface, public QmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QmlParserStatus)
+
+ Q_PROPERTY(QString src READ src WRITE setSrc)
+ Q_PROPERTY(QString query READ query WRITE setQuery)
+ Q_PROPERTY(QString namespaceDeclarations READ namespaceDeclarations WRITE setNamespaceDeclarations)
+ Q_PROPERTY(QmlList<XmlListModelRole *> *roles READ roleObjects)
+ Q_CLASSINFO("DefaultProperty", "roles")
+public:
+ QmlXmlListModel(QObject *parent = 0);
+ ~QmlXmlListModel();
+
+ virtual QHash<int,QVariant> data(int index, const QList<int> &roles = (QList<int>())) const;
+ virtual int count() const;
+ virtual QList<int> roles() const;
+ virtual QString toString(int role) const;
+
+ QmlList<XmlListModelRole *> *roleObjects();
+
+ QString src() const;
+ void setSrc(const QString&);
+
+ QString query() const;
+ void setQuery(const QString&);
+
+ QString namespaceDeclarations() const;
+ void setNamespaceDeclarations(const QString&);
+
+ virtual void classComplete();
+ void fetch();
+
+protected:
+ void doQuery(QByteArray &rawData);
+ void doSubquery(int index) const;
+
+private Q_SLOTS:
+ void requestFinished();
+
+private:
+ Q_DECLARE_PRIVATE(QmlXmlListModel)
+ Q_DISABLE_COPY(QmlXmlListModel)
+};
+
+QML_DECLARE_TYPE(QmlXmlListModel);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMLXMLLISTMODEL_H
diff --git a/src/declarative/extra/qnumberformat.cpp b/src/declarative/extra/qnumberformat.cpp
new file mode 100644
index 0000000..79e328a
--- /dev/null
+++ b/src/declarative/extra/qnumberformat.cpp
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** 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 "qnumberformat.h"
+
+
+QT_BEGIN_NAMESPACE
+QML_DEFINE_TYPE(QNumberFormat,NumberFormat);
+
+QNumberFormat::QNumberFormat(QObject *parent) : QObject(parent), _number(0), _type(Decimal),
+ _groupingSize(0)
+{
+ _locale = QLocale::system();
+ _groupingSeparator = _locale.groupSeparator();
+ _decimalSeparator = _locale.decimalPoint();
+ _currencySymbol = QLatin1Char('$');
+}
+
+QNumberFormat::~QNumberFormat()
+{
+
+}
+
+void QNumberFormat::updateText()
+{
+ QTime t;
+ t.start();
+ static int totalTime;
+
+ handleFormat();
+
+ totalTime += t.elapsed();
+ emit textChanged();
+}
+
+void QNumberFormat::handleFormat()
+{
+ // ### is extremely messy
+ if (_format.isEmpty()) {
+ _text = QString(QLatin1String("%1")).arg(_number, -1, 'f', -1);
+ return;
+ }
+
+ QString inputString;
+
+ // ### possible to use the following parsed data in the future
+
+ int remainingLength = _format.size();
+ int currentIndex = _format.size()-1;
+
+ int maxDigits = 0;
+ int minDigits = 0;
+ int decimalLength = 0;
+
+ while (remainingLength > 0) {
+ switch(_format.at(currentIndex).unicode()) {
+ case ',':
+ if (decimalLength && !_groupingSize)
+ setGroupingSize(maxDigits - decimalLength);
+ else if (!_groupingSize)
+ setGroupingSize(maxDigits);
+ break;
+ case '.':
+ if (!decimalLength)
+ decimalLength = maxDigits;
+ break;
+ case '0':
+ minDigits++;
+ case '#':
+ maxDigits++;
+ break;
+ default:
+ break;
+ }
+ currentIndex--;
+ remainingLength--;
+ }
+
+ // round given the decimal length/precision
+ inputString = QString(QLatin1String("%1")).arg(_number, -1, 'f', decimalLength);
+
+ QStringList parts = inputString.split(QLatin1Char('.'));
+ QStringList formatParts = _format.split(QLatin1Char('.'));
+
+ if (formatParts.size() > 2 || parts.size() > 2 )
+ return;
+
+ QString formatInt = formatParts.at(0);
+
+ QString formatDec;
+ if (formatParts.size() == 2)
+ formatDec = formatParts.at(1);
+
+ QString integer = parts.at(0);
+
+ QString decimal;
+ if (parts.size() == 2)
+ decimal = parts.at(1);
+
+ QString outputDecimal = formatDecimal(formatDec, decimal);
+ QString outputInteger = formatInteger(formatInt, integer);
+
+ // insert separators
+ if (_groupingSize) {
+ unsigned int count = 0;
+ for (int i = outputInteger.size()-1; i > 0; i--) {
+ if (outputInteger.at(i).digitValue() >= 0) {
+ if (count == _groupingSize - 1) {
+ count = 0;
+ outputInteger.insert(i, _groupingSeparator);
+ }
+ else
+ count++;
+ }
+ }
+ }
+ if (!outputDecimal.isEmpty())
+ _text = outputInteger + _decimalSeparator + outputDecimal;
+ else
+ _text = outputInteger;
+}
+
+QString QNumberFormat::formatInteger(const QString &formatInt, const QString &integer)
+{
+ if (formatInt.isEmpty() || integer.isEmpty())
+ return QString();
+
+ QString outputInteger;
+ int formatIndex = formatInt.size()-1;
+
+ //easier for carry?
+ for (int index= integer.size()-1; index >= 0; index--) {
+ if (formatIndex < 0) {
+ outputInteger.push_front(integer.at(index));
+ }
+ else {
+ switch(formatInt.at(formatIndex).unicode()) {
+ case '0':
+ if (index > integer.size()-1) {
+ outputInteger.push_front(QLatin1Char('0'));
+ break;
+ }
+ case '#':
+ outputInteger.push_front(integer.at(index));
+ break;
+ case ',':
+ index++;
+ break;
+ default:
+ outputInteger.push_front(formatInt.at(formatIndex));
+ index++;
+ break;
+ }
+ formatIndex--;
+ }
+ }
+ while (formatIndex >= 0) {
+ if (formatInt.at(formatIndex).unicode() != '#' && formatInt.at(formatIndex).unicode() != ',')
+ outputInteger.push_front(formatInt.at(formatIndex));
+ formatIndex--;
+ }
+ return outputInteger;
+}
+
+QString QNumberFormat::formatDecimal(const QString &formatDec, const QString &decimal)
+{
+ QString outputDecimal;
+
+ // up to max 6 decimal places
+ for (int index=formatDec.size()-1; index >= 0; index--) {
+ switch(formatDec.at(index).unicode()) {
+ case '0':
+ outputDecimal.push_front(decimal.at(index));
+ break;
+ case '#':
+ if (decimal.at(index) != QLatin1Char('0') || outputDecimal.size() > 0)
+ outputDecimal.push_front(decimal.at(index));
+ break;
+ default:
+ outputDecimal.push_front(formatDec.at(index));
+ break;
+ }
+ }
+ return outputDecimal;
+}
+QT_END_NAMESPACE
diff --git a/src/declarative/extra/qnumberformat.h b/src/declarative/extra/qnumberformat.h
new file mode 100644
index 0000000..6ee333c
--- /dev/null
+++ b/src/declarative/extra/qnumberformat.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** 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 NUMBERFORMAT_H
+#define NUMBERFORMAT_H
+
+#include "qml.h"
+#include <QtGui>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+// TODO
+// be able to set Locale, instead of default system for dynamic formatting
+// add currency support
+// add additional syntax, extend to format scientific, percentiles, significant digits etc
+
+
+class QNumberFormat : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(NumberType)
+public:
+ QNumberFormat(QObject *parent=0);
+ ~QNumberFormat();
+
+ enum NumberType {
+ Percent,
+ Scientific,
+ Currency,
+ Decimal
+ };
+
+ //external property, only visible
+ Q_PROPERTY(QString text READ text NOTIFY textChanged);
+
+ //mutatable properties to modify the output (text)
+ Q_PROPERTY(qreal number READ number WRITE setNumber);
+ Q_PROPERTY(QString format READ format WRITE setFormat);
+ Q_PROPERTY(QLocale locale READ locale WRITE setLocale);
+
+ //Format specific settings
+ Q_PROPERTY(unsigned short groupingSeparator READ groupingSeparator WRITE setGroupingSeparator);
+ Q_PROPERTY(unsigned short decimalSeperator READ decimalSeparator WRITE setDecimalSeparator);
+ Q_PROPERTY(unsigned int groupingSize READ groupingSize WRITE setGroupingSize);
+ Q_PROPERTY(unsigned short currencySymbol READ currencySymbol WRITE setCurrencySymbol);
+
+
+ QString text() const { return _text; }
+
+ qreal number() const { return _number; }
+ void setNumber(qreal n) {
+ if (_number == n)
+ return;
+ _number = n;
+ updateText();
+ }
+
+ QString format() const { return _format; }
+ void setFormat(const QString &format) {
+ if (format.isEmpty())
+ _format = QString::null;
+ else if (_format == format)
+ return;
+
+ _format = format;
+ updateText();
+ }
+
+ QLocale locale() const { return _locale; }
+ void setLocale(const QLocale &locale) { _locale = locale; updateText(); }
+
+ //Do we deal with unicode standard? or create our own
+ // ### since this is the backend for the number conversions, we will use the unicode
+ // the front-end will handle the QChar/QString -> short int
+
+ unsigned short groupingSeparator() { return _groupingSeparator.unicode(); }
+ void setGroupingSeparator(unsigned short unicodeSymbol)
+ {
+ _groupingSeparator = QChar(unicodeSymbol);
+ }
+
+ unsigned short decimalSeparator() { return _decimalSeparator.unicode(); }
+ void setDecimalSeparator(unsigned short unicodeSymbol)
+ {
+ _decimalSeparator = QChar(unicodeSymbol);
+ }
+
+ unsigned short currencySymbol() { return _currencySymbol.unicode(); }
+ void setCurrencySymbol(unsigned short unicodeSymbol)
+ {
+ _currencySymbol = QChar(unicodeSymbol);
+ }
+
+ unsigned int groupingSize() { return _groupingSize; }
+ void setGroupingSize(unsigned int size)
+ {
+ _groupingSize = size;
+ }
+
+Q_SIGNALS:
+ void textChanged();
+
+private:
+ void updateText();
+ void handleFormat();
+ QString formatInteger(const QString &formatInt, const QString &integer);
+ QString formatDecimal(const QString &formatDec, const QString &decimal);
+
+ qreal _number;
+ NumberType _type;
+ QChar _groupingSeparator;
+ QChar _decimalSeparator;
+ QChar _currencySymbol;
+ unsigned int _groupingSize;
+
+ QLocale _locale;
+ QString _format;
+
+ // only hooked member at the moment
+ QString _text;
+
+};
+QML_DECLARE_TYPE(QNumberFormat);
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif