From 9f629961ad9f569eb1d31b5698a0779f104e65aa Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 16 Sep 2009 15:30:23 +1000 Subject: Make flicking a bit more resistant to spurrious input. --- src/declarative/fx/qfxflickable.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/declarative/fx/qfxflickable.cpp b/src/declarative/fx/qfxflickable.cpp index 1e6ad5a..c4d593c 100644 --- a/src/declarative/fx/qfxflickable.cpp +++ b/src/declarative/fx/qfxflickable.cpp @@ -587,8 +587,8 @@ void QFxFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event) stealMouse = false; pressed = true; timeline.clear(); - velocityX = -1; - velocityY = -1; + velocityX = 0; + velocityY = 0; lastPos = QPoint(); lastPosTime.start(); pressPos = event->pos(); @@ -654,12 +654,16 @@ void QFxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) elapsed = 1; if (q->yflick()) { qreal diff = event->pos().y() - lastPos.y(); - velocityY = diff / elapsed; + // average to reduce the effect of spurious moves + velocityY += diff / elapsed; + velocityY /= 2; } if (q->xflick()) { qreal diff = event->pos().x() - lastPos.x(); - velocityX = diff / elapsed; + // average to reduce the effect of spurious moves + velocityX += diff / elapsed; + velocityX /= 2; } } @@ -681,6 +685,12 @@ void QFxFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *even if (lastPosTime.isNull()) return; + if (lastPosTime.elapsed() > 100) { + // if we drag then pause before release we should not cause a flick. + velocityX = 0.0; + velocityY = 0.0; + } + vTime = timeline.time(); if (qAbs(velocityY) > 10 && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) flickY(velocityY); -- cgit v0.12 From 1713d5794cd578fbe1d083737647285ba7edac60 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 16 Sep 2009 15:31:02 +1000 Subject: Small tweaks. --- src/declarative/fx/qfxlistview.cpp | 10 ++-------- src/declarative/fx/qfxlistview.h | 1 - 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp index 168e4c4..015eacf 100644 --- a/src/declarative/fx/qfxlistview.cpp +++ b/src/declarative/fx/qfxlistview.cpp @@ -570,13 +570,7 @@ void QFxListViewPrivate::layout() return; q->refill(); updateHighlight(); - if (orient == Qt::Vertical) { - fixupY(); - q->setViewportHeight(endPosition() - startPosition()); - } else { - fixupX(); - q->setViewportWidth(endPosition() - startPosition()); - } + fixupPosition(); updateUnrequestedPositions(); } @@ -1131,7 +1125,7 @@ void QFxListView::setStrictlyEnforceHighlightRange(bool strict) } /*! - \qmlproperty int ListView::spacing + \qmlproperty real ListView::spacing This property holds the spacing to leave between items. */ diff --git a/src/declarative/fx/qfxlistview.h b/src/declarative/fx/qfxlistview.h index e5c3138..cc3d910 100644 --- a/src/declarative/fx/qfxlistview.h +++ b/src/declarative/fx/qfxlistview.h @@ -62,7 +62,6 @@ class Q_DECLARATIVE_EXPORT QFxListView : public QFxFlickable Q_OBJECT Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QFxListView) - Q_ENUMS(CurrentItemPositioning) Q_PROPERTY(QVariant model READ model WRITE setModel) Q_PROPERTY(QmlComponent *delegate READ delegate WRITE setDelegate) Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) -- cgit v0.12 From 64dba2e0de580853bd82ba2ce60229215c633396 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 16 Sep 2009 15:52:27 +1000 Subject: Basic first-working SQL database interface. A simple Qt-based implementation of HTML5 SQL local storage databases. --- examples/declarative/sql/hello.qml | 30 ++++ src/declarative/qml/qml.pri | 2 + src/declarative/qml/qmlengine.cpp | 2 + src/declarative/qml/qmlsqldatabase.cpp | 259 +++++++++++++++++++++++++++++++++ src/declarative/qml/qmlsqldatabase_p.h | 60 ++++++++ 5 files changed, 353 insertions(+) create mode 100644 examples/declarative/sql/hello.qml create mode 100644 src/declarative/qml/qmlsqldatabase.cpp create mode 100644 src/declarative/qml/qmlsqldatabase_p.h diff --git a/examples/declarative/sql/hello.qml b/examples/declarative/sql/hello.qml new file mode 100644 index 0000000..fb6d21c --- /dev/null +++ b/examples/declarative/sql/hello.qml @@ -0,0 +1,30 @@ +import Qt 4.6 + +Text { + Script { + function test() + { + var db = openDatabase("QmlExampleDB", "", "The Example QML SQL!", 1000000); + print(db) + 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) { + for(var i = 0; i < rs.rows.length; i++) { + r += rs.rows[i][0] + ", " + rs.rows[i][1] + "\n" + } + }, + function(tx, error) { + print("ERROR:", error.message) + } + ); + }) + + return r + } + } + text: test() +} 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 e3d4840..efe1a89 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -82,6 +82,7 @@ #include #include #include +#include Q_DECLARE_METATYPE(QmlMetaProperty) Q_DECLARE_METATYPE(QList); @@ -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)); diff --git a/src/declarative/qml/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp new file mode 100644 index 0000000..6063ac4 --- /dev/null +++ b/src/declarative/qml/qmlsqldatabase.cpp @@ -0,0 +1,259 @@ +/**************************************************************************** +** +** 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qmlsqldatabase_p.h" +#include +#include +#include + +#ifdef Q_OS_WIN // for %APPDATA% +#include "qt_windows.h" +#include "qlibrary.h" +#endif + + +class QmlSqlDatabaseTransaction : public QObject +{ + Q_OBJECT +public: + QmlSqlDatabaseTransaction(QSqlDatabase db, QmlEngine *engine) : database(db) {} + virtual ~QmlSqlDatabaseTransaction(){} + static QScriptValue executeSql(QScriptContext *context, QScriptEngine *engine) + { + QScriptValue tx = context->thisObject(); + QmlSqlDatabaseTransaction *trans = qobject_cast(tx.toQObject()); + QString sql = context->argument(0).toString(); + QScriptValue values = context->argument(1); + QScriptValue cb = context->argument(2); + QScriptValue cberr = context->argument(3); + QSqlQuery query(trans->database); + 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 rows = engine->newArray(); + int i=0; + for (; query.next(); ++i) { + QSqlRecord r = query.record(); + QScriptValue row = engine->newArray(r.count()); + for (int j=0; jnewObject(); + rs.setProperty(QLatin1String("rows"), rows); + cb.call(QScriptValue(), QScriptValueList() << tx << rs); + } else { + err = true; + } + } else { + err = true; + } + if (err) { + QScriptValue error = engine->newObject(); + error.setProperty(QLatin1String("message"), query.lastError().text()); + cberr.call(QScriptValue(), QScriptValueList() << tx << error); + } + return engine->undefinedValue(); + } + +private: + QSqlDatabase database; +}; + +class QmlSqlDatabase : public QObject +{ + Q_OBJECT +public: + QmlSqlDatabase(QmlEngine *engine, QScriptContext *context); + virtual ~QmlSqlDatabase(); + + QScriptValue callback() const; + void setCallback(const QScriptValue &); + + static QScriptValue transaction(QScriptContext *context, QScriptEngine *engine) + { + QmlSqlDatabase *db = qobject_cast(context->thisObject().toQObject()); + if (!db) + return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an SqlDatabase object")); + if (context->argumentCount() != 1) + return engine->undefinedValue(); + QScriptValue cb = context->argument(0); + if (!cb.isFunction()) + return engine->undefinedValue(); + + // XXX Call synchronously... + QScriptValue tx = engine->newQObject(new QmlSqlDatabaseTransaction(db->database, QmlEnginePrivate::getEngine(engine)), QScriptEngine::ScriptOwnership); + + tx.setProperty(QLatin1String("executeSql"), engine->newFunction(QmlSqlDatabaseTransaction::executeSql,4)); + + db->database.transaction(); + cb.call(QScriptValue(), QScriptValueList() << tx); + if (engine->hasUncaughtException()) { + db->database.rollback(); + QScriptValue cb = context->argument(1); + if (cb.isFunction()) + cb.call(); + } else { + db->database.commit(); + QScriptValue cb = context->argument(2); + if (cb.isFunction()) + cb.call(); + } + return engine->undefinedValue(); + } + +private: + QSqlDatabase database; +}; + +// XXX Something like this belongs in 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; +} + +QmlSqlDatabase::QmlSqlDatabase(QmlEngine *engine, QScriptContext *context) +{ + 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.utf8()); + md5.addData(dbversion.utf8()); + QString dbid(QLatin1String(md5.result().toHex())); + + QSqlDatabase db; + 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("Name", dbname); + ini.setValue("Version", dbversion); + ini.setValue("Description", dbdescription); + ini.setValue("EstimatedSize", dbestimatedsize); + database.open(); + } +} + +QmlSqlDatabase::~QmlSqlDatabase() +{ +} + +static QScriptValue qmlsqldatabase_open(QScriptContext *context, QScriptEngine *engine) +{ + QScriptValue proto = engine->newQObject(new QmlSqlDatabase(QmlEnginePrivate::getEngine(engine),context), QScriptEngine::ScriptOwnership); + proto.setProperty(QLatin1String("transaction"), engine->newFunction(QmlSqlDatabase::transaction,1)); + return proto; +} + +void qt_add_qmlsqldatabase(QScriptEngine *engine) +{ + QScriptValue openDatabase = engine->newFunction(qmlsqldatabase_open, 4); + engine->globalObject().setProperty(QLatin1String("openDatabase"), openDatabase); +} + +#include "qmlsqldatabase.moc" 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 + -- cgit v0.12 From 633b4b0655bf47b6f5100ee9a6c2f692b0aeb081 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 16 Sep 2009 16:26:46 +1000 Subject: Experiment with implicitWidth and implicitHeight functions. --- src/declarative/fx/qfxitem.cpp | 14 ++++++++++++++ src/declarative/fx/qfxitem.h | 2 ++ src/declarative/fx/qfxitem_p.h | 4 +++- src/declarative/fx/qfxloader.cpp | 6 ++---- src/declarative/fx/qfxtext.cpp | 14 +++----------- src/declarative/fx/qfxtextedit.cpp | 19 +++++++------------ 6 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp index 962fee2..c7e807c 100644 --- a/src/declarative/fx/qfxitem.cpp +++ b/src/declarative/fx/qfxitem.cpp @@ -2688,9 +2688,16 @@ void QFxItem::setWidth(qreal w) QRectF(x(), y(), oldWidth, height())); } +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 +2740,16 @@ void QFxItem::setHeight(qreal h) QRectF(x(), y(), width(), oldHeight)); } +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..9d2113f 100644 --- a/src/declarative/fx/qfxitem.h +++ b/src/declarative/fx/qfxitem.h @@ -134,9 +134,11 @@ public: qreal width() const; void setWidth(qreal); + qreal implicitWidth() const; qreal height() const; void setHeight(qreal); + 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/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/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 72f12cc..0185ce0 100644 --- a/src/declarative/fx/qfxtextedit.cpp +++ b/src/declarative/fx/qfxtextedit.cpp @@ -1044,18 +1044,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; -- cgit v0.12 From 4937e80baf3cce7444a007f5b3fa4979ea93f3fc Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 16 Sep 2009 16:28:34 +1000 Subject: Remove unnecessary use of QObjects QSqlDatabase is a shared copyable type anyway, so easy to use as QScriptValue variant. --- src/declarative/qml/qmlsqldatabase.cpp | 181 ++++++++++++++------------------- 1 file changed, 75 insertions(+), 106 deletions(-) diff --git a/src/declarative/qml/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp index 6063ac4..90d6e3e 100644 --- a/src/declarative/qml/qmlsqldatabase.cpp +++ b/src/declarative/qml/qmlsqldatabase.cpp @@ -64,109 +64,83 @@ #include "qlibrary.h" #endif +Q_DECLARE_METATYPE(QSqlDatabase) -class QmlSqlDatabaseTransaction : public QObject +static QScriptValue qmlsqldatabase_executeSql(QScriptContext *context, QScriptEngine *engine) { - Q_OBJECT -public: - QmlSqlDatabaseTransaction(QSqlDatabase db, QmlEngine *engine) : database(db) {} - virtual ~QmlSqlDatabaseTransaction(){} - static QScriptValue executeSql(QScriptContext *context, QScriptEngine *engine) - { - QScriptValue tx = context->thisObject(); - QmlSqlDatabaseTransaction *trans = qobject_cast(tx.toQObject()); - QString sql = context->argument(0).toString(); - QScriptValue values = context->argument(1); - QScriptValue cb = context->argument(2); - QScriptValue cberr = context->argument(3); - QSqlQuery query(trans->database); - 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()); + QSqlDatabase db = qscriptvalue_cast(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()); } - if (query.exec()) { - QScriptValue rows = engine->newArray(); - int i=0; - for (; query.next(); ++i) { - QSqlRecord r = query.record(); - QScriptValue row = engine->newArray(r.count()); - for (int j=0; jnewArray(); + int i=0; + for (; query.next(); ++i) { + QSqlRecord r = query.record(); + QScriptValue row = engine->newArray(r.count()); + for (int j=0; jnewObject(); - rs.setProperty(QLatin1String("rows"), rows); - cb.call(QScriptValue(), QScriptValueList() << tx << rs); - } else { - err = true; + rows.setProperty(i, row); } + QScriptValue rs = engine->newObject(); + rs.setProperty(QLatin1String("rows"), rows); + cb.call(QScriptValue(), QScriptValueList() << context->thisObject() << rs); } else { err = true; } - if (err) { - QScriptValue error = engine->newObject(); - error.setProperty(QLatin1String("message"), query.lastError().text()); - cberr.call(QScriptValue(), QScriptValueList() << tx << error); - } - return engine->undefinedValue(); + } 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(); +} -private: - QSqlDatabase database; -}; - -class QmlSqlDatabase : public QObject +static QScriptValue qmlsqldatabase_transaction(QScriptContext *context, QScriptEngine *engine) { - Q_OBJECT -public: - QmlSqlDatabase(QmlEngine *engine, QScriptContext *context); - virtual ~QmlSqlDatabase(); - - QScriptValue callback() const; - void setCallback(const QScriptValue &); - - static QScriptValue transaction(QScriptContext *context, QScriptEngine *engine) - { - QmlSqlDatabase *db = qobject_cast(context->thisObject().toQObject()); - if (!db) - return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an SqlDatabase object")); - if (context->argumentCount() != 1) - return engine->undefinedValue(); - QScriptValue cb = context->argument(0); - if (!cb.isFunction()) - return engine->undefinedValue(); - - // XXX Call synchronously... - QScriptValue tx = engine->newQObject(new QmlSqlDatabaseTransaction(db->database, QmlEnginePrivate::getEngine(engine)), QScriptEngine::ScriptOwnership); - - tx.setProperty(QLatin1String("executeSql"), engine->newFunction(QmlSqlDatabaseTransaction::executeSql,4)); - - db->database.transaction(); - cb.call(QScriptValue(), QScriptValueList() << tx); - if (engine->hasUncaughtException()) { - db->database.rollback(); - QScriptValue cb = context->argument(1); - if (cb.isFunction()) - cb.call(); - } else { - db->database.commit(); - QScriptValue cb = context->argument(2); - if (cb.isFunction()) - cb.call(); - } + QSqlDatabase db = qscriptvalue_cast(context->thisObject()); + if (context->argumentCount() < 1) + return engine->undefinedValue(); + QScriptValue cb = context->argument(0); + if (!cb.isFunction()) return engine->undefinedValue(); - } -private: - QSqlDatabase database; -}; + // 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 belongs in Qt. static QString userLocalDataPath(const QString& app) @@ -207,8 +181,11 @@ static QString userLocalDataPath(const QString& app) return result; } -QmlSqlDatabase::QmlSqlDatabase(QmlEngine *engine, QScriptContext *context) + +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(); @@ -219,7 +196,6 @@ QmlSqlDatabase::QmlSqlDatabase(QmlEngine *engine, QScriptContext *context) md5.addData(dbversion.utf8()); QString dbid(QLatin1String(md5.result().toHex())); - QSqlDatabase db; if (QSqlDatabase::connectionNames().contains(dbid)) { database = QSqlDatabase::database(dbid); } else { @@ -231,23 +207,16 @@ QmlSqlDatabase::QmlSqlDatabase(QmlEngine *engine, QScriptContext *context) basename += dbid; database.setDatabaseName(basename+QLatin1String(".sqllite")); QSettings ini(basename+QLatin1String(".ini"),QSettings::IniFormat); - ini.setValue("Name", dbname); - ini.setValue("Version", dbversion); - ini.setValue("Description", dbdescription); - ini.setValue("EstimatedSize", dbestimatedsize); + ini.setValue(QLatin1String("Name"), dbname); + ini.setValue(QLatin1String("Version"), dbversion); + ini.setValue(QLatin1String("Description"), dbdescription); + ini.setValue(QLatin1String("EstimatedSize"), dbestimatedsize); database.open(); } -} - -QmlSqlDatabase::~QmlSqlDatabase() -{ -} -static QScriptValue qmlsqldatabase_open(QScriptContext *context, QScriptEngine *engine) -{ - QScriptValue proto = engine->newQObject(new QmlSqlDatabase(QmlEnginePrivate::getEngine(engine),context), QScriptEngine::ScriptOwnership); - proto.setProperty(QLatin1String("transaction"), engine->newFunction(QmlSqlDatabase::transaction,1)); - return proto; + 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) -- cgit v0.12 From 30377d51a8568b9b778b58a63fb036e35a879124 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 16 Sep 2009 17:07:26 +1000 Subject: No need to copy the pixmap. --- src/declarative/fx/qfxborderimage.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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); -- cgit v0.12 From 5d35dbc3552f722cf4de220d8737e8201e4f61e5 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Wed, 16 Sep 2009 18:21:12 +1000 Subject: Better SQL database performance / memory usage. Rows accessible incrementally. Rows.forwardOnly for optimization. --- examples/declarative/sql/README | 7 +++ examples/declarative/sql/hello.qml | 12 +++- src/declarative/qml/qmlengine.cpp | 4 +- src/declarative/qml/qmlengine_p.h | 2 + src/declarative/qml/qmlsqldatabase.cpp | 100 +++++++++++++++++++++++++++++---- 5 files changed, 109 insertions(+), 16 deletions(-) create mode 100644 examples/declarative/sql/README 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 index fb6d21c..e43d320 100644 --- a/examples/declarative/sql/hello.qml +++ b/examples/declarative/sql/hello.qml @@ -2,10 +2,9 @@ import Qt 4.6 Text { Script { - function test() + function allGreetings() { var db = openDatabase("QmlExampleDB", "", "The Example QML SQL!", 1000000); - print(db) var r = "" db.transaction(function(tx) { @@ -13,9 +12,16 @@ 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) @@ -26,5 +32,5 @@ Text { return r } } - text: test() + text: allGreetings() } diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index efe1a89..c0dd1a8 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -111,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 = @@ -156,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/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp index 90d6e3e..4a7c3a3 100644 --- a/src/declarative/qml/qmlsqldatabase.cpp +++ b/src/declarative/qml/qmlsqldatabase.cpp @@ -65,6 +65,84 @@ #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(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(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; jundefinedValue(); + } + + void setProperty(QScriptValue &object, + const QScriptString &name, uint, const QScriptValue & value) + { + if (name == str_forwardOnly) { + QSqlQuery query = qscriptvalue_cast(object.data()); + query.setForwardOnly(value.toBool()); + } + } + +private: + QScriptString str_length; + QScriptString str_forwardOnly; +}; static QScriptValue qmlsqldatabase_executeSql(QScriptContext *context, QScriptEngine *engine) { @@ -85,18 +163,14 @@ static QScriptValue qmlsqldatabase_executeSql(QScriptContext *context, QScriptEn query.bindValue(0,values.toVariant()); } if (query.exec()) { - QScriptValue rows = engine->newArray(); - int i=0; - for (; query.next(); ++i) { - QSqlRecord r = query.record(); - QScriptValue row = engine->newArray(r.count()); - for (int j=0; jnewObject(); - rs.setProperty(QLatin1String("rows"), rows); + 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; @@ -142,7 +216,7 @@ static QScriptValue qmlsqldatabase_transaction(QScriptContext *context, QScriptE return engine->undefinedValue(); } -// XXX Something like this belongs in Qt. +// XXX Something like this should be exported by Qt. static QString userLocalDataPath(const QString& app) { QString result; @@ -196,6 +270,8 @@ static QScriptValue qmlsqldatabase_open(QScriptContext *context, QScriptEngine * md5.addData(dbversion.utf8()); 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 { -- cgit v0.12 From 2770d76a6d4af982c5b84b207150fde8c0cdadf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Wed, 16 Sep 2009 11:11:09 +0200 Subject: Some documentation link updates --- doc/src/declarative/elements.qdoc | 3 +-- src/declarative/fx/qfxlistview.cpp | 10 ++++++---- src/declarative/util/qmleasefollow.cpp | 2 ++ src/declarative/util/qmlspringfollow.cpp | 2 ++ 4 files changed, 11 insertions(+), 6 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/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/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) -- cgit v0.12 From 990a39008c38d5fed19cca3b5b7af5f148c90c55 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 16 Sep 2009 13:05:18 +0200 Subject: Fix compilation on Linux qmlsqldatabase.moc is not created any more --- src/declarative/qml/qmlsqldatabase.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/declarative/qml/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp index 4a7c3a3..33538d2 100644 --- a/src/declarative/qml/qmlsqldatabase.cpp +++ b/src/declarative/qml/qmlsqldatabase.cpp @@ -301,4 +301,3 @@ void qt_add_qmlsqldatabase(QScriptEngine *engine) engine->globalObject().setProperty(QLatin1String("openDatabase"), openDatabase); } -#include "qmlsqldatabase.moc" -- cgit v0.12 From 98da50b3d081cdf0e900cd6dbf9b8cf1053c73dd Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Wed, 16 Sep 2009 15:50:49 +0200 Subject: Added a virtual destructor to suppress warnings. --- src/declarative/qml/qmlpropertyvaluesource.cpp | 4 ++++ src/declarative/qml/qmlpropertyvaluesource.h | 1 + 2 files changed, 5 insertions(+) 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") -- cgit v0.12 From 90a04b8c22e1a5c2ac559bf09547a94e31388d28 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Wed, 16 Sep 2009 15:51:35 +0200 Subject: Changed the use of QString::utf8() to QString::toUtf8() to make it compile without QT3_SUPPORT. --- src/declarative/qml/qmlsqldatabase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/qml/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp index 33538d2..e4373d0 100644 --- a/src/declarative/qml/qmlsqldatabase.cpp +++ b/src/declarative/qml/qmlsqldatabase.cpp @@ -266,8 +266,8 @@ static QScriptValue qmlsqldatabase_open(QScriptContext *context, QScriptEngine * int dbestimatedsize = context->argument(3).toNumber(); QCryptographicHash md5(QCryptographicHash::Md5); - md5.addData(dbname.utf8()); - md5.addData(dbversion.utf8()); + md5.addData(dbname.toUtf8()); + md5.addData(dbversion.toUtf8()); QString dbid(QLatin1String(md5.result().toHex())); // Uses SQLLITE (like HTML5), but any could be used. -- cgit v0.12 From d5b554a7dc9204e65b1bfc3408d2d126d5ec2981 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 17 Sep 2009 09:41:42 +1000 Subject: Rect cleanup. --- src/declarative/fx/qfxrect.cpp | 11 ++++++++--- src/declarative/fx/qfxrect.h | 16 ++++++++++------ src/declarative/fx/qfxrect_p.h | 2 +- 3 files changed, 19 insertions(+), 10 deletions(-) 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; } -- cgit v0.12 From fc3e138a26f9add4def111e8f6305f1aa674fa05 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 17 Sep 2009 09:48:08 +1000 Subject: Experiment with reset functions for width and height. --- src/declarative/fx/qfxitem.cpp | 14 ++++++++++++++ src/declarative/fx/qfxitem.h | 6 ++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp index c7e807c..dd51aa6 100644 --- a/src/declarative/fx/qfxitem.cpp +++ b/src/declarative/fx/qfxitem.cpp @@ -2688,6 +2688,13 @@ 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); @@ -2740,6 +2747,13 @@ 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); diff --git a/src/declarative/fx/qfxitem.h b/src/declarative/fx/qfxitem.h index 9d2113f..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* states READ states DESIGNABLE false) Q_PROPERTY(QmlList* 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,10 +134,12 @@ 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; -- cgit v0.12 From d5a99c587a7495f67b01f820a8305f1ccdb6ad75 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 17 Sep 2009 10:45:48 +1000 Subject: Compile on windows --- src/declarative/qml/qmlsqldatabase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/declarative/qml/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp index e4373d0..144a170 100644 --- a/src/declarative/qml/qmlsqldatabase.cpp +++ b/src/declarative/qml/qmlsqldatabase.cpp @@ -62,6 +62,7 @@ #ifdef Q_OS_WIN // for %APPDATA% #include "qt_windows.h" #include "qlibrary.h" +#define CSIDL_APPDATA 0x001a // \Application Data #endif Q_DECLARE_METATYPE(QSqlDatabase) -- cgit v0.12 From 0c2e40683007c9405b8fc9f7efbd728ef519d78f Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 17 Sep 2009 16:36:47 +1000 Subject: Fix velocity notification. --- src/declarative/fx/qfxflickable.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/declarative/fx/qfxflickable.cpp b/src/declarative/fx/qfxflickable.cpp index c4d593c..5297516 100644 --- a/src/declarative/fx/qfxflickable.cpp +++ b/src/declarative/fx/qfxflickable.cpp @@ -1210,7 +1210,8 @@ void QFxFlickable::movementEnding() void QFxFlickablePrivate::updateVelocity() { Q_Q(QFxFlickable); - emit q->velocityChanged(q->horizontalVelocity(), q->verticalVelocity()); + emit q->horizontalVelocityChanged(); + emit q->verticalVelocityChanged(); } QT_END_NAMESPACE -- cgit v0.12 From 6f75efdaf7f4fb378506cf52ec56588f02453806 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 17 Sep 2009 17:00:06 +1000 Subject: Fix velocity notification (the rest). --- src/declarative/fx/qfxflickable.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/declarative/fx/qfxflickable.h b/src/declarative/fx/qfxflickable.h index b3339b0..aaf4e0f 100644 --- a/src/declarative/fx/qfxflickable.h +++ b/src/declarative/fx/qfxflickable.h @@ -143,7 +143,8 @@ Q_SIGNALS: void flickStarted(); void flickEnded(); void reportedVelocitySmoothingChanged(int); - void velocityChanged(qreal, qreal); + void horizontalVelocityChanged(); + void verticalVelocityChanged(); void isAtBoundaryChanged(); void pageChanged(); -- cgit v0.12 From 2a9bc5163553a05fee61c289d09ec2ba963911bc Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 17 Sep 2009 17:01:00 +1000 Subject: Switch Repeater over to use VisualModel. Also extend VisualModels to support the usage Repeater used to add. --- examples/declarative/easing/easing.qml | 1 - src/declarative/fx/qfxrepeater.cpp | 246 ++++++++++-------------------- src/declarative/fx/qfxrepeater.h | 4 + src/declarative/fx/qfxrepeater_p.h | 9 +- src/declarative/fx/qfxvisualitemmodel.cpp | 121 +++++++++------ src/declarative/util/qmllistaccessor.cpp | 47 ++++-- src/declarative/util/qmllistaccessor.h | 6 +- 7 files changed, 192 insertions(+), 242 deletions(-) diff --git a/examples/declarative/easing/easing.qml b/examples/declarative/easing/easing.qml index df301d8..1909e00 100644 --- a/examples/declarative/easing/easing.qml +++ b/examples/declarative/easing/easing.qml @@ -59,7 +59,6 @@ Rectangle { model: EasingTypes Component { Text { - id: Text text: type height: 18 font.italic: true diff --git a/src/declarative/fx/qfxrepeater.cpp b/src/declarative/fx/qfxrepeater.cpp index e6ee242..719aea9 100644 --- a/src/declarative/fx/qfxrepeater.cpp +++ b/src/declarative/fx/qfxrepeater.cpp @@ -42,12 +42,13 @@ #include "qfxrepeater.h" #include "qfxrepeater_p.h" #include "qmllistaccessor.h" +#include "qfxvisualitemmodel.h" #include QT_BEGIN_NAMESPACE QFxRepeaterPrivate::QFxRepeaterPrivate() -: component(0), count(0) +: model(0), ownModel(false) { } @@ -55,23 +56,6 @@ QFxRepeaterPrivate::~QFxRepeaterPrivate() { } -QFxItem *QFxRepeaterPrivate::addItem(QmlContext *ctxt, QFxItem *lastItem) -{ - Q_UNUSED(lastItem) - Q_Q(QFxRepeater); - QObject *nobj = component->create(ctxt); - QFxItem *item = qobject_cast(nobj); - if (item) { - item->setParent(q->parentItem()); -// item->stackUnder(lastItem); - deletables << nobj; - } else { - delete nobj; - } - - return item; -} - QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Repeater,QFxRepeater) /*! @@ -166,11 +150,47 @@ QVariant QFxRepeater::model() const return d->dataSource; } -void QFxRepeater::setModel(const QVariant &v) +void QFxRepeater::setModel(const QVariant &model) { Q_D(QFxRepeater); - d->dataSource = v; - regenerate(); + clear(); + /* + if (d->model) { + disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); + disconnect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int))); + disconnect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int))); + disconnect(d->model, SIGNAL(createdItem(int, QFxItem*)), this, SLOT(createdItem(int,QFxItem*))); + disconnect(d->model, SIGNAL(destroyingItem(QFxItem*)), this, SLOT(destroyingItem(QFxItem*))); + } + */ + d->dataSource = model; + QObject *object = qvariant_cast(model); + QFxVisualModel *vim = 0; + if (object && (vim = qobject_cast(object))) { + if (d->ownModel) { + delete d->model; + d->ownModel = false; + } + d->model = vim; + } else { + if (!d->ownModel) { + d->model = new QFxVisualDataModel(qmlContext(this)); + d->ownModel = true; + } + if (QFxVisualDataModel *dataModel = qobject_cast(d->model)) + dataModel->setModel(model); + } + if (d->model) { + /* + connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); + connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int))); + connect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int))); + connect(d->model, SIGNAL(createdItem(int, QFxItem*)), this, SLOT(createdItem(int,QFxItem*))); + connect(d->model, SIGNAL(destroyingItem(QFxItem*)), this, SLOT(destroyingItem(QFxItem*))); + */ + regenerate(); + emit countChanged(); + } } /*! @@ -182,14 +202,25 @@ void QFxRepeater::setModel(const QVariant &v) QmlComponent *QFxRepeater::delegate() const { Q_D(const QFxRepeater); - return d->component; + if (d->model) { + if (QFxVisualDataModel *dataModel = qobject_cast(d->model)) + return dataModel->delegate(); + } + + return 0; } -void QFxRepeater::setDelegate(QmlComponent *_c) +void QFxRepeater::setDelegate(QmlComponent *delegate) { Q_D(QFxRepeater); - d->component = _c; - regenerate(); + if (!d->ownModel) { + d->model = new QFxVisualDataModel(qmlContext(this)); + d->ownModel = true; + } + if (QFxVisualDataModel *dataModel = qobject_cast(d->model)) { + dataModel->setDelegate(delegate); + regenerate(); + } } /*! @@ -200,7 +231,9 @@ void QFxRepeater::setDelegate(QmlComponent *_c) int QFxRepeater::count() const { Q_D(const QFxRepeater); - return d->count; + if (d->model) + return d->model->count(); + return 0; } @@ -227,6 +260,16 @@ QVariant QFxRepeater::itemChange(GraphicsItemChange change, return rv; } +void QFxRepeater::clear() +{ + Q_D(QFxRepeater); + if (d->model) { + foreach (QFxItem *item, d->deletables) + d->model->release(item); + } + d->deletables.clear(); +} + /*! \internal */ @@ -234,152 +277,19 @@ void QFxRepeater::regenerate() { Q_D(QFxRepeater); - qDeleteAll(d->deletables); - d->deletables.clear(); - if (!d->component || !parentItem() || !isComponentComplete()) - return; - - QFxItem *lastItem = this; - - int count = 0; - - if (d->dataSource.type() == QVariant::StringList) { - QStringList sl = qvariant_cast(d->dataSource); - - count = sl.size(); - for (int ii = 0; ii < count; ++ii) { - QmlContext *ctxt = new QmlContext(qmlContext(this), this); - d->deletables << ctxt; + clear(); - ctxt->setContextProperty(QLatin1String("index"), ii); - ctxt->setContextProperty(QLatin1String("modelData"), sl.at(ii)); - - if (QFxItem *item = d->addItem(ctxt, lastItem)) - lastItem = item; - } - } else if (d->dataSource.type() == QMetaType::QVariantList) { - QVariantList sl = qvariant_cast(d->dataSource); - - count = sl.size(); - for (int ii = 0; ii < count; ++ii) { - QmlContext *ctxt = new QmlContext(qmlContext(this), this); - d->deletables << ctxt; - - ctxt->setContextProperty(QLatin1String("index"), ii); - ctxt->setContextProperty(QLatin1String("modelData"), sl.at(ii)); - - if (QFxItem *item = d->addItem(ctxt, lastItem)) - lastItem = item; - } - } else if (QmlMetaType::isList(d->dataSource)) { - count = QmlMetaType::listCount(d->dataSource); - if (count <= 0) - return; - - for (int ii = 0; ii < count; ++ii) { - QVariant v = QmlMetaType::listAt(d->dataSource, ii); - QObject *o = QmlMetaType::toQObject(v); - - QmlContext *ctxt = new QmlContext(qmlContext(this), this); - d->deletables << ctxt; - - ctxt->setContextProperty(QLatin1String("index"), ii); - ctxt->setContextProperty(QLatin1String("modelData"), o); - - if (QFxItem *item = d->addItem(ctxt, lastItem)) - lastItem = item; - } - } else if (QListModelInterface *model = qobject_cast(d->dataSource.value())) { - count = model->count(); - if (count <= 0) - return; - - for (int ii = 0; ii < count; ++ii) { - QmlContext *ctxt = new QmlContext(qmlContext(this), this); - d->deletables << ctxt; - - ctxt->setContextProperty(QLatin1String("index"), ii); - - QList roles = model->roles(); - QHash data = model->data(ii,roles); - for (int j = 0; j < roles.size(); ++j) { - ctxt->setContextProperty(model->toString(roles.at(j)), data.value(roles.at(j))); - } - - //for compatability with other lists, assign data if there is only a single role - if (roles.size() == 1) - ctxt->setContextProperty(QLatin1String("modelData"), data.value(roles.at(0))); - - if (QFxItem *item = d->addItem(ctxt, lastItem)) - lastItem = item; - } - } else if (QAbstractItemModel *model = qobject_cast(d->dataSource.value())) { - count = model->rowCount(); - if (count <= 0) - return; - - for (int ii = 0; ii < count; ++ii) { - QmlContext *ctxt = new QmlContext(qmlContext(this), this); - d->deletables << ctxt; - - ctxt->setContextProperty(QLatin1String("index"), ii); - - QList roles; - QStringList roleNames; - QHash data; - for (QHash::const_iterator it = model->roleNames().begin(); - it != model->roleNames().end(); ++it) { - roles.append(it.key()); - roleNames.append(QLatin1String(*it)); - } + if (!d->model || !d->model->count() || !d->model->isValid() || !parentItem() || !isComponentComplete()) + return; - QModelIndex index = model->index(ii, 0); - for (int j = 0; j < roles.size(); ++j) { - ctxt->setContextProperty(roleNames.at(j), model->data(index, roles.at(j))); + if (d->model) { + for (int ii = 0; ii < count(); ++ii) { + QFxItem *item = d->model->item(ii); + if (item) { + item->setParent(parentItem()); + d->deletables << item; } - - //for compatability with other lists, assign data if there is only a single role - if (roles.size() == 1) - ctxt->setContextProperty(QLatin1String("modelData"), data.value(roles.at(0))); - - if (QFxItem *item = d->addItem(ctxt, lastItem)) - lastItem = item; - } - } else if (QObject *object = d->dataSource.value()) { - // A single object (i.e. list of size 1). - // Properties are the roles (excluding objectName). - QmlContext *ctxt = new QmlContext(qmlContext(this), this); - d->deletables << ctxt; - - ctxt->setContextProperty(QLatin1String("index"), QVariant(0)); - count = object->metaObject()->propertyCount(); - for (int ii = 1; ii < count; ++ii) { - const QMetaProperty &prop = object->metaObject()->property(ii); - ctxt->setContextProperty(QLatin1String(prop.name()), prop.read(object)); - } - - //for compatability with other lists, assign data if there is only a single role (excluding objectName) - if (count == 2) { - const QMetaProperty &prop = object->metaObject()->property(1); - ctxt->setContextProperty(QLatin1String("modelData"), prop.read(object)); - } - - d->addItem(ctxt, lastItem); - - } else if (d->dataSource.canConvert(QVariant::Int)){ - - count = qvariant_cast(d->dataSource); - - for (int ii = 0; ii < count; ++ii) { - QmlContext *ctxt = new QmlContext(qmlContext(this), this); - d->deletables << ctxt; - - ctxt->setContextProperty(QLatin1String("index"), ii); - - if (QFxItem *item = d->addItem(ctxt, lastItem)) - lastItem = item; } } - d->count = count; } QT_END_NAMESPACE diff --git a/src/declarative/fx/qfxrepeater.h b/src/declarative/fx/qfxrepeater.h index 43afd63..7d64d86 100644 --- a/src/declarative/fx/qfxrepeater.h +++ b/src/declarative/fx/qfxrepeater.h @@ -72,7 +72,11 @@ public: int count() const; +Q_SIGNALS: + void countChanged(); + private: + void clear(); void regenerate(); protected: diff --git a/src/declarative/fx/qfxrepeater_p.h b/src/declarative/fx/qfxrepeater_p.h index 65b0973..a4eb96d 100644 --- a/src/declarative/fx/qfxrepeater_p.h +++ b/src/declarative/fx/qfxrepeater_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE class QmlContext; +class QFxVisualModel; class QFxRepeaterPrivate : public QFxItemPrivate { Q_DECLARE_PUBLIC(QFxRepeater) @@ -69,13 +70,11 @@ public: QFxRepeaterPrivate(); ~QFxRepeaterPrivate(); - QFxItem *addItem(QmlContext *ctxt, QFxItem *lastItem); - + QFxVisualModel *model; QVariant dataSource; - QmlComponent *component; - int count; + bool ownModel; - QList > deletables; + QList > deletables; }; QT_END_NAMESPACE diff --git a/src/declarative/fx/qfxvisualitemmodel.cpp b/src/declarative/fx/qfxvisualitemmodel.cpp index 81fbafa..1f8c079 100644 --- a/src/declarative/fx/qfxvisualitemmodel.cpp +++ b/src/declarative/fx/qfxvisualitemmodel.cpp @@ -243,14 +243,34 @@ public: QmlComponent *m_delegate; QmlContext *m_context; QList m_roles; - QHash m_roleNames; + QHash m_roleNames; void ensureRoles() { - if (m_roles.isEmpty()) { + if (m_roleNames.isEmpty()) { if (m_listModelInterface) { m_roles = m_listModelInterface->roles(); - for (int ii = 0; ii < m_roles.count(); ++ii) - m_roleNames.insert(m_roles.at(ii), - m_listModelInterface->toString(m_roles.at(ii))); + for (int ii = 0; ii < m_roles.count(); ++ii) + m_roleNames.insert(m_listModelInterface->toString(m_roles.at(ii)), m_roles.at(ii)); + if (m_roles.count() == 1) + m_roleNames.insert(QLatin1String("modelData"), m_roles.at(0)); + } else if (m_abstractItemModel) { + for (QHash::const_iterator it = m_abstractItemModel->roleNames().begin(); + it != m_abstractItemModel->roleNames().end(); ++it) { + m_roles.append(it.key()); + m_roleNames.insert(QLatin1String(*it), it.key()); + } + if (m_roles.count() == 1) + m_roleNames.insert(QLatin1String("modelData"), m_roles.at(0)); + } else if (m_modelList) { + m_roleNames.insert(QLatin1String("modelData"), 0); + if (m_modelList->type() == QmlListAccessor::Instance) { + if (QObject *object = m_modelList->at(0).value()) { + int count = object->metaObject()->propertyCount(); + for (int ii = 1; ii < count; ++ii) { + const QMetaProperty &prop = object->metaObject()->property(ii); + m_roleNames.insert(prop.name(), 0); + } + } + } } } } @@ -382,17 +402,14 @@ int QFxVisualDataModelDataMetaObject::createProperty(const char *name, const cha if ((!data->m_model->m_listModelInterface || !data->m_model->m_abstractItemModel) && data->m_model->m_modelList) { - if (!qstrcmp(name, "modelData")) + data->m_model->ensureRoles(); + if (data->m_model->m_roleNames.contains(QLatin1String(name))) return QmlOpenMetaObject::createProperty(name, type); } else { - const QLatin1String sname(name); data->m_model->ensureRoles(); - for (QHash::ConstIterator iter = data->m_model->m_roleNames.begin(); - iter != data->m_model->m_roleNames.end(); ++iter) { - - if (*iter == sname) - return QmlOpenMetaObject::createProperty(name, type); - } + const QLatin1String sname(name); + if (data->m_model->m_roleNames.contains(sname)) + return QmlOpenMetaObject::createProperty(name, type); } return -1; } @@ -407,31 +424,42 @@ QFxVisualDataModelDataMetaObject::propertyCreated(int, QMetaPropertyBuilder &pro QString name = QLatin1String(prop.name()); if ((!data->m_model->m_listModelInterface || !data->m_model->m_abstractItemModel) && data->m_model->m_modelList) { - return data->m_model->m_modelList->at(data->m_index); + if (name == QLatin1String("modelData")) { + if (data->m_model->m_modelList->type() == QmlListAccessor::Instance) { + QObject *object = data->m_model->m_modelList->at(0).value(); + return object->metaObject()->property(1).read(object); // the first property after objectName + } + return data->m_model->m_modelList->at(data->m_index); + } else { + // return any property of a single object instance. + QObject *object = data->m_model->m_modelList->at(0).value(); + return object->property(prop.name()); + } } else if (data->m_model->m_listModelInterface) { data->m_model->ensureRoles(); - for (QHash::ConstIterator iter = data->m_model->m_roleNames.begin(); - iter != data->m_model->m_roleNames.end(); ++iter) { - - if (*iter == name) { - roles.append(iter.key()); - QHash values = data->m_model->m_listModelInterface->data(data->m_index, QList() << iter.key()); - if (values.isEmpty()) - return QVariant(); - else - return values.value(iter.key()); - } + QHash::const_iterator it = data->m_model->m_roleNames.find(name); + if (it != data->m_model->m_roleNames.end()) { + roles.append(*it); + QHash values = data->m_model->m_listModelInterface->data(data->m_index, QList() << *it); + if (values.isEmpty()) + return QVariant(); + else + return values.value(*it); + } else if (data->m_model->m_roles.count() == 1 && name == QLatin1String("modelData")) { + //for compatability with other lists, assign modelData if there is only a single role + QHash values = data->m_model->m_listModelInterface->data(data->m_index, QList() << data->m_model->m_roles.first()); + if (values.isEmpty()) + return QVariant(); + else + return *values.begin(); } } else if (data->m_model->m_abstractItemModel) { data->m_model->ensureRoles(); - for (QHash::ConstIterator iter = data->m_model->m_roleNames.begin(); - iter != data->m_model->m_roleNames.end(); ++iter) { - - if (*iter == name) { - roles.append(iter.key()); - QModelIndex index = data->m_model->m_abstractItemModel->index(data->m_index, 0); - return data->m_model->m_abstractItemModel->data(index, iter.key()); - } + QHash::const_iterator it = data->m_model->m_roleNames.find(name); + if (it != data->m_model->m_roleNames.end()) { + roles.append(*it); + QModelIndex index = data->m_model->m_abstractItemModel->index(data->m_index, 0); + return data->m_model->m_abstractItemModel->data(index, *it); } } Q_ASSERT(!"Can never be reached"); @@ -505,10 +533,10 @@ QFxVisualDataModelPrivate::QFxVisualDataModelPrivate(QmlContext *ctxt) QFxVisualDataModelData *QFxVisualDataModelPrivate::data(QObject *item) { - QList dataList = - item->findChildren(); - Q_ASSERT(dataList.count() == 1); - return dataList.first(); + QFxVisualDataModelData *dataItem = + item->findChild(); + Q_ASSERT(dataItem); + return dataItem; } QFxVisualDataModel::QFxVisualDataModel() @@ -537,6 +565,8 @@ QVariant QFxVisualDataModel::model() const void QFxVisualDataModel::setModel(const QVariant &model) { Q_D(QFxVisualDataModel); + delete d->m_modelList; + d->m_modelList = 0; d->m_modelVariant = model; if (d->m_listModelInterface) { // Assume caller has released all items. @@ -570,11 +600,11 @@ void QFxVisualDataModel::setModel(const QVariant &model) d->m_visualItemModel = 0; } + d->m_roles.clear(); + d->m_roleNames.clear(); + QObject *object = qvariant_cast(model); if (object && (d->m_listModelInterface = qobject_cast(object))) { - d->m_roles.clear(); - d->m_roleNames.clear(); - QObject::connect(d->m_listModelInterface, SIGNAL(itemsChanged(int,int,QList)), this, SLOT(_q_itemsChanged(int,int,QList))); QObject::connect(d->m_listModelInterface, SIGNAL(itemsInserted(int,int)), @@ -583,18 +613,10 @@ void QFxVisualDataModel::setModel(const QVariant &model) this, SLOT(_q_itemsRemoved(int,int))); QObject::connect(d->m_listModelInterface, SIGNAL(itemsMoved(int,int,int)), this, SLOT(_q_itemsMoved(int,int,int))); - if (d->m_delegate && d->m_listModelInterface->count()) emit itemsInserted(0, d->m_listModelInterface->count()); return; } else if (object && (d->m_abstractItemModel = qobject_cast(object))) { - d->m_roles.clear(); - d->m_roleNames.clear(); - for (QHash::const_iterator it = d->m_abstractItemModel->roleNames().begin(); - it != d->m_abstractItemModel->roleNames().end(); ++it) { - d->m_roles.append(it.key()); - d->m_roleNames.insert(it.key(), QLatin1String(*it)); - } QObject::connect(d->m_abstractItemModel, SIGNAL(rowsInserted(const QModelIndex &,int,int)), this, SLOT(_q_rowsInserted(const QModelIndex &,int,int))); QObject::connect(d->m_abstractItemModel, SIGNAL(rowsRemoved(const QModelIndex &,int,int)), @@ -616,8 +638,7 @@ void QFxVisualDataModel::setModel(const QVariant &model) this, SLOT(_q_destroyingPackage(QmlPackage*))); return; } - if (!d->m_modelList) - d->m_modelList = new QmlListAccessor; + d->m_modelList = new QmlListAccessor; d->m_modelList->setList(model); if (d->m_delegate && d->modelCount()) { emit itemsInserted(0, d->modelCount()); diff --git a/src/declarative/util/qmllistaccessor.cpp b/src/declarative/util/qmllistaccessor.cpp index 0332b9e..1228952 100644 --- a/src/declarative/util/qmllistaccessor.cpp +++ b/src/declarative/util/qmllistaccessor.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE QmlListAccessor::QmlListAccessor() -: type(Invalid) +: m_type(Invalid) { } @@ -65,31 +65,35 @@ void QmlListAccessor::setList(const QVariant &v) d = v; if (!d.isValid()) { - type = Invalid; + m_type = Invalid; } else if (d.type() == QVariant::StringList) { - type = StringList; + m_type = StringList; } else if (d.type() == QMetaType::QVariantList) { - type = VariantList; + m_type = VariantList; + } else if (d.canConvert(QVariant::Int)) { + qDebug() << "integer"; + m_type = Integer; } else if (d.type() != QVariant::UserType) { - type = Instance; + m_type = Instance; } else if (QmlMetaType::isObject(d.userType())) { QObject *data = 0; data = *(QObject **)v.constData(); d = QVariant::fromValue(data); - type = Instance; + m_type = Instance; } else if (QmlMetaType::isQmlList(d.userType())) { - type = QmlList; + m_type = QmlList; } else if (QmlMetaType::isList(d.userType())) { - type = QList; + qDebug() << "list"; + m_type = QList; } else { - type = Invalid; + m_type = Invalid; d = QVariant(); } } int QmlListAccessor::count() const { - switch(type) { + switch(m_type) { case Invalid: return 0; case StringList: @@ -105,6 +109,8 @@ int QmlListAccessor::count() const return QmlMetaType::listCount(d); case Instance: return 1; + case Integer: + return d.toInt(); } return 0; @@ -113,7 +119,7 @@ int QmlListAccessor::count() const QVariant QmlListAccessor::at(int idx) const { Q_ASSERT(idx >= 0 && idx < count()); - switch(type) { + switch(m_type) { case Invalid: return QVariant(); case StringList: @@ -131,6 +137,8 @@ QVariant QmlListAccessor::at(int idx) const return QmlMetaType::listAt(d, idx); case Instance: return d; + case Integer: + return QVariant(); } return QVariant(); @@ -138,7 +146,7 @@ QVariant QmlListAccessor::at(int idx) const void QmlListAccessor::append(const QVariant &value) { - switch(type) { + switch(m_type) { case Invalid: break; case StringList: @@ -162,6 +170,7 @@ void QmlListAccessor::append(const QVariant &value) QmlMetaType::append(d, value); break; case Instance: + case Integer: //do nothing break; } @@ -169,7 +178,7 @@ void QmlListAccessor::append(const QVariant &value) void QmlListAccessor::insert(int index, const QVariant &value) { - switch(type) { + switch(m_type) { case Invalid: break; case StringList: @@ -198,12 +207,14 @@ void QmlListAccessor::insert(int index, const QVariant &value) if (index == 0) setList(value); break; + case Integer: + break; } } void QmlListAccessor::removeAt(int index) { - switch(type) { + switch(m_type) { case Invalid: break; case StringList: @@ -227,12 +238,14 @@ void QmlListAccessor::removeAt(int index) if (index == 0) setList(QVariant()); break; + case Integer: + break; } } void QmlListAccessor::clear() { - switch(type) { + switch(m_type) { case Invalid: break; case StringList: @@ -254,12 +267,14 @@ void QmlListAccessor::clear() //XXX what should we do here? setList(QVariant()); break; + case Integer: + d = 0; } } bool QmlListAccessor::isValid() const { - return type != Invalid; + return m_type != Invalid; } QT_END_NAMESPACE diff --git a/src/declarative/util/qmllistaccessor.h b/src/declarative/util/qmllistaccessor.h index c3017e1..f0d293f 100644 --- a/src/declarative/util/qmllistaccessor.h +++ b/src/declarative/util/qmllistaccessor.h @@ -69,9 +69,11 @@ public: virtual void removeAt(int); virtual void clear(); + enum Type { Invalid, StringList, VariantList, QmlList, QList, Instance, Integer }; + Type type() const { return m_type; } + private: - enum Type { Invalid, StringList, VariantList, QmlList, QList, Instance }; - Type type; + Type m_type; QVariant d; }; -- cgit v0.12