From f21957b3bb12a16a905f79f3a791931eb77663d9 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Fri, 13 Nov 2009 13:09:40 +1000 Subject: Enforce unique role names for XmlListModel. --- src/declarative/util/qmlxmllistmodel.cpp | 26 ++++++++-------------- .../declarative/qmlxmllistmodel/data/unique.qml | 8 +++++++ .../qmlxmllistmodel/tst_qmlxmllistmodel.cpp | 15 +++++++++++++ 3 files changed, 32 insertions(+), 17 deletions(-) create mode 100644 tests/auto/declarative/qmlxmllistmodel/data/unique.qml diff --git a/src/declarative/util/qmlxmllistmodel.cpp b/src/declarative/util/qmlxmllistmodel.cpp index 3d90b44..8407b1d 100644 --- a/src/declarative/util/qmlxmllistmodel.cpp +++ b/src/declarative/util/qmlxmllistmodel.cpp @@ -132,8 +132,6 @@ struct QmlXmlRoleList : public QmlConcreteList QmlXmlRoleList(QmlXmlListModelPrivate *p) : model(p) {} virtual void append(QmlXmlListModelRole *role); - //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(); virtual void removeAt(int i); virtual void insert(int i, QmlXmlListModelRole *role); @@ -309,7 +307,7 @@ void QmlXmlQuery::doSubQueryJob() b.seek(0); } - //XXX this method is much slower, but would work better for incremental loading + //this method is much slower, but works better for incremental loading /*for (int j = 0; j < m_size; ++j) { QList resultList; for (int i = 0; i < m_roleObjects->size(); ++i) { @@ -338,13 +336,6 @@ void QmlXmlQuery::doSubQueryJob() }*/ } - -//TODO: error handling (currently quite fragile) -// profile doQuery and doSubquery -// support complex/nested objects? -// how do we handle data updates (like rss feed -- usually items inserted at beginning) - - class QmlXmlListModelPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QmlXmlListModel) @@ -373,14 +364,12 @@ public: }; -void QmlXmlRoleList::append(QmlXmlListModelRole *role) { - QmlConcreteList::append(role); - model->roles << model->highestRole; - model->roleNames << role->name(); - ++model->highestRole; +void QmlXmlRoleList::append(QmlXmlListModelRole *role) +{ + insert(size(), role); } -//XXX clear, removeAt, and insert need to invalidate any cached data (in data table) as well +//### clear, removeAt, and insert need to invalidate any cached data (in data table) as well // (and the model should emit the appropriate signals) void QmlXmlRoleList::clear() { @@ -396,10 +385,13 @@ void QmlXmlRoleList::removeAt(int i) QmlConcreteList::removeAt(i); } -//### we should enforce unique role names void QmlXmlRoleList::insert(int i, QmlXmlListModelRole *role) { QmlConcreteList::insert(i, role); + if (model->roleNames.contains(role->name())) { + qmlInfo(role) << QObject::tr("\"%1\" duplicates a previous role name and will be disabled.").arg(role->name()); + return; + } model->roles.insert(i, model->highestRole); model->roleNames.insert(i, role->name()); ++model->highestRole; diff --git a/tests/auto/declarative/qmlxmllistmodel/data/unique.qml b/tests/auto/declarative/qmlxmllistmodel/data/unique.qml new file mode 100644 index 0000000..ed0f293 --- /dev/null +++ b/tests/auto/declarative/qmlxmllistmodel/data/unique.qml @@ -0,0 +1,8 @@ +import Qt 4.6 + +XmlListModel { + source: "model.xml" + query: "/Pets/Pet" + XmlRole { name: "name"; query: "name/string()" } + XmlRole { name: "name"; query: "type/string()" } +} diff --git a/tests/auto/declarative/qmlxmllistmodel/tst_qmlxmllistmodel.cpp b/tests/auto/declarative/qmlxmllistmodel/tst_qmlxmllistmodel.cpp index 71bc4f9..a68006d 100644 --- a/tests/auto/declarative/qmlxmllistmodel/tst_qmlxmllistmodel.cpp +++ b/tests/auto/declarative/qmlxmllistmodel/tst_qmlxmllistmodel.cpp @@ -58,6 +58,7 @@ private slots: void attributes(); void roles(); void roleErrors(); + void uniqueRoleNames(); private: QmlEngine engine; @@ -175,6 +176,20 @@ void tst_qmlxmllistmodel::roleErrors() delete listModel; } +void tst_qmlxmllistmodel::uniqueRoleNames() +{ + QmlComponent component(&engine, QUrl("file://" SRCDIR "/data/unique.qml")); + QTest::ignoreMessage(QtWarningMsg, "QML QmlXmlListModelRole (file://" SRCDIR "/data/unique.qml:7:5) \"name\" duplicates a previous role name and will be disabled."); + QmlXmlListModel *listModel = qobject_cast(component.create()); + QVERIFY(listModel != 0); + QTRY_COMPARE(listModel->count(), 9); + + QList roles = listModel->roles(); + QCOMPARE(roles.count(), 1); + + delete listModel; +} + QTEST_MAIN(tst_qmlxmllistmodel) #include "tst_qmlxmllistmodel.moc" -- cgit v0.12 From cd2187091e6b357c79f4e0db0a14f210df79f3fd Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Fri, 13 Nov 2009 13:36:01 +1000 Subject: Cleanup. --- src/declarative/util/qmltransition.cpp | 3 +-- src/declarative/util/qmlview.cpp | 38 ++++------------------------- src/declarative/util/qmlview.h | 2 -- src/declarative/widgets/graphicslayouts.cpp | 13 +++------- src/declarative/widgets/graphicslayouts_p.h | 13 +--------- src/declarative/widgets/graphicswidgets.cpp | 26 ++++++-------------- 6 files changed, 19 insertions(+), 76 deletions(-) diff --git a/src/declarative/util/qmltransition.cpp b/src/declarative/util/qmltransition.cpp index 7eb9e53..204887c 100644 --- a/src/declarative/util/qmltransition.cpp +++ b/src/declarative/util/qmltransition.cpp @@ -111,7 +111,7 @@ public: public: AnimationList() : parent(0) {} virtual void append(QmlAbstractAnimation *a); - virtual void clear() { QmlConcreteList::clear(); } //XXX + virtual void clear() { QmlConcreteList::clear(); } //### QmlTransitionPrivate *parent; }; @@ -127,7 +127,6 @@ void QmlTransitionPrivate::AnimationList::append(QmlAbstractAnimation *a) void ParallelAnimationWrapper::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) { QParallelAnimationGroup::updateState(newState, oldState); - //XXX not 100% guaranteed to be at end (if there are many zero duration animations at the end)? if (newState == Stopped && ((direction() == QAbstractAnimation::Forward && currentLoopTime() == duration()) || (direction() == QAbstractAnimation::Backward && currentLoopTime() == 0))) diff --git a/src/declarative/util/qmlview.cpp b/src/declarative/util/qmlview.cpp index 0a2cc75..a55a57a 100644 --- a/src/declarative/util/qmlview.cpp +++ b/src/declarative/util/qmlview.cpp @@ -124,12 +124,6 @@ void FrameBreakAnimation::updateCurrentTime(int msecs) server->frameBreak(); } - -static QVariant stringToKeySequence(const QString &str) -{ - return QVariant::fromValue(QKeySequence(str)); -} - class QmlViewPrivate { public: @@ -190,13 +184,12 @@ QmlView::QmlView(QWidget *parent) void QmlViewPrivate::init() { - // XXX: These need to be put in a central location for this kind of thing - QmlMetaType::registerCustomStringConverter(QVariant::KeySequence, &stringToKeySequence); - #ifdef Q_ENABLE_PERFORMANCE_LOG - QmlPerfTimer perf; + { + QmlPerfTimer perf; + QFontDatabase database; + } #endif - QFontDatabase database; q->setScene(&scene); @@ -520,7 +513,7 @@ QmlGraphicsItem* QmlView::addItem(const QString &qml, QmlGraphicsItem* parent) } /*! - Deletes the view's \l {QmlGraphicsItem} {items} and the \l {QmlEngine} + Deletes the view's \l {QmlGraphicsItem} {items} and clears the \l {QmlEngine} {QML engine's} Component cache. */ void QmlView::reset() @@ -582,25 +575,4 @@ void QmlView::paintEvent(QPaintEvent *event) qDebug() << "paintEvent:" << d->frameTimer.elapsed() << "time since last frame:" << time; } -/*! \fn void QmlView::focusInEvent(QFocusEvent *e) - This virtual function does nothing with the event \a e - in this class. - */ -void QmlView::focusInEvent(QFocusEvent *e) -{ - // Do nothing (do not call QWidget::update()) - QGraphicsView::focusInEvent(e); -} - - -/*! \fn void QmlView::focusOutEvent(QFocusEvent *e) - This virtual function does nothing with the event \a e - in this class. - */ -void QmlView::focusOutEvent(QFocusEvent *e) -{ - // Do nothing (do not call QWidget::update()) - QGraphicsView::focusOutEvent(e); -} - QT_END_NAMESPACE diff --git a/src/declarative/util/qmlview.h b/src/declarative/util/qmlview.h index 08d69bc..83c4f97 100644 --- a/src/declarative/util/qmlview.h +++ b/src/declarative/util/qmlview.h @@ -98,8 +98,6 @@ private Q_SLOTS: protected: virtual void resizeEvent(QResizeEvent *); virtual void paintEvent(QPaintEvent *event); - void focusInEvent(QFocusEvent *); - void focusOutEvent(QFocusEvent *); void timerEvent(QTimerEvent*); private: diff --git a/src/declarative/widgets/graphicslayouts.cpp b/src/declarative/widgets/graphicslayouts.cpp index 9658049..0721102 100644 --- a/src/declarative/widgets/graphicslayouts.cpp +++ b/src/declarative/widgets/graphicslayouts.cpp @@ -128,11 +128,11 @@ void QGraphicsLinearLayoutObject::insertLayoutItem(int index, QGraphicsLayoutIte this, SLOT(updateStretch(QGraphicsLayoutItem*,int))); QObject::connect(obj, SIGNAL(alignmentChanged(QGraphicsLayoutItem*,Qt::Alignment)), this, SLOT(updateAlignment(QGraphicsLayoutItem*,Qt::Alignment))); - //XXX need to disconnect when widget is removed? + //### need to disconnect when widget is removed? } } -//XXX is there a better way to do this? +//### is there a better way to do this? void QGraphicsLinearLayoutObject::clearChildren() { for (int i = 0; i < count(); ++i) @@ -156,11 +156,6 @@ LinearLayoutAttached *QGraphicsLinearLayoutObject::qmlAttachedProperties(QObject if (!qobject_cast(obj)) return 0; LinearLayoutAttached *rv = new LinearLayoutAttached(obj); - /*if (QGraphicsLinearLayoutObject *lo = qobject_cast(obj->parent())) - QObject::connect(rv, SIGNAL(stretchChanged(QGraphicsLayoutItem*,int)), - lo, SLOT(updateStretch(QGraphicsLayoutItem*,int))); - QObject::connect(rv, SIGNAL(alignmentChanged(QGraphicsLayoutItem*,Qt::Alignment)), - lo, SLOT(updateAlignment(QGraphicsLayoutItem*,Qt::Alignment)));*/ attachedProperties.insert(qobject_cast(obj), rv); return rv; } @@ -293,7 +288,7 @@ void QGraphicsGridLayoutObject::addLayoutItem(QGraphicsLayoutItem *item) } } -//XXX is there a better way to do this? +//### is there a better way to do this? void QGraphicsGridLayoutObject::clearChildren() { for (int i = 0; i < count(); ++i) @@ -304,7 +299,7 @@ qreal QGraphicsGridLayoutObject::spacing() const { if (verticalSpacing() == horizontalSpacing()) return verticalSpacing(); - return -1; //XXX + return -1; //### } QHash QGraphicsGridLayoutObject::attachedProperties; diff --git a/src/declarative/widgets/graphicslayouts_p.h b/src/declarative/widgets/graphicslayouts_p.h index 5358e2b..c44cb79 100644 --- a/src/declarative/widgets/graphicslayouts_p.h +++ b/src/declarative/widgets/graphicslayouts_p.h @@ -62,10 +62,6 @@ public: virtual QSizeF sizeHint(Qt::SizeHint, const QSizeF &) const; }; -//TODO: -// -content margins -// -per-item spacing (does this need to be exposed?) -// -per-item alignment class LinearLayoutAttached; class QGraphicsLinearLayoutObject : public QObject, public QGraphicsLinearLayout { @@ -117,13 +113,6 @@ private: ChildList _children; }; -//TODO: -// -content margins -// -column and row specific settings: -// -alignment -// -fixed/min/max/preferred width -// -spacing -// -stretch class GridLayoutAttached; class QGraphicsGridLayoutObject : public QObject, public QGraphicsGridLayout { @@ -166,7 +155,7 @@ private: virtual int count() const { return obj->count(); } virtual void removeAt(int i) { obj->removeAt(i); } virtual QGraphicsLayoutItem *at(int i) const { return obj->itemAt(i); } - //XXX GridLayout doesn't have an insert, so for now we treat it as an append. + //### GridLayout doesn't have an insert, so for now we treat it as an append. // this is obviously potenitally dangerous -- perhaps should be a concrete // list with no relation to layout index, etc at all. virtual void insert(int, QGraphicsLayoutItem *item) { append(item); } diff --git a/src/declarative/widgets/graphicswidgets.cpp b/src/declarative/widgets/graphicswidgets.cpp index 5678520..40ba93e 100644 --- a/src/declarative/widgets/graphicswidgets.cpp +++ b/src/declarative/widgets/graphicswidgets.cpp @@ -43,7 +43,6 @@ QT_BEGIN_NAMESPACE -//### the single (default) property could alternatively be added to graphics view directly class QGraphicsViewDeclarativeUI : public QObject { Q_OBJECT @@ -83,27 +82,23 @@ private: virtual void clear() { for (int i = 0; i < count(); ++i) - if (QGraphicsWidget *w = qobject_cast(at(i))) - static_cast(q)->removeItem(w); + if (QGraphicsObject *go = qobject_cast(at(i))) + static_cast(q)->removeItem(go); QmlConcreteList::clear(); } virtual void removeAt(int i) { - if (QGraphicsWidget *w = qobject_cast(at(i))) - static_cast(q)->removeItem(w); + if (QGraphicsObject *go = qobject_cast(at(i))) + static_cast(q)->removeItem(go); QmlConcreteList::removeAt(i); } virtual void insert(int i, QObject *o) { QmlConcreteList::insert(i, o); - - //XXX are there any cases when insertion should be different from appension? - if (QGraphicsWidget *w = qobject_cast(o)) - static_cast(q)->addItem(w); + if (QGraphicsObject *go = qobject_cast(o)) + static_cast(q)->addItem(go); //else if (QWidget *w = qobject_cast(o)) // static_cast(q)->addWidget(w); - //else - // qWarning() << "Can't add" << o << "to a QGraphicsScene"; } private: QObject *q; @@ -139,11 +134,6 @@ private: wid->setParentItem(static_cast(parent())); } - //### - void clearWidget() - { - } - class WidgetList : public QmlConcreteList { public: @@ -151,8 +141,8 @@ private: : obj(o) {} virtual void append(QGraphicsItem *w) { QmlConcreteList::append(w); obj->setItemParent(w); } - virtual void clear() { QmlConcreteList::clear(); obj->clearWidget(); } - virtual void removeAt(int i) { QmlConcreteList::removeAt(i); } //XXX + virtual void clear() { QmlConcreteList::clear(); } //### + virtual void removeAt(int i) { QmlConcreteList::removeAt(i); } //### virtual void insert(int i, QGraphicsItem *item) { QmlConcreteList::insert(i, item); obj->setItemParent(item); } private: -- cgit v0.12 From e8a762a61f380b2e27c14ac363767759c34064cf Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Fri, 13 Nov 2009 13:43:55 +1000 Subject: Add missing test file. --- .../visual/Package_Views/packageviews.qml | 81 ++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 tests/auto/declarative/visual/Package_Views/packageviews.qml diff --git a/tests/auto/declarative/visual/Package_Views/packageviews.qml b/tests/auto/declarative/visual/Package_Views/packageviews.qml new file mode 100644 index 0000000..a9719ca --- /dev/null +++ b/tests/auto/declarative/visual/Package_Views/packageviews.qml @@ -0,0 +1,81 @@ +import Qt 4.6 + +Rectangle { + id: root + width: 200 + height: 200 + color: "black" + + VisualDataModel { + id: Model + model: ListModel { + ListElement { itemColor: "red" } + ListElement { itemColor: "green" } + ListElement { itemColor: "blue" } + ListElement { itemColor: "orange" } + ListElement { itemColor: "purple" } + ListElement { itemColor: "yellow" } + ListElement { itemColor: "slategrey" } + ListElement { itemColor: "cyan" } + } + delegate: Package { + Rectangle { + id: listItem; Package.name: "list"; width:root.width/2; height: 50; color: "transparent"; border.color: "white" + MouseRegion { + anchors.fill: parent + onClicked: myState.state = myState.state == "list" ? "grid" : "list" + } + } + Rectangle { + id: gridItem; Package.name: "grid"; width:50; height: 50; color: "transparent"; border.color: "white" + MouseRegion { + anchors.fill: parent + onClicked: myState.state = myState.state == "list" ? "grid" : "list" + } + } + Rectangle { id: myContent; width:50; height: 50; color: itemColor } + + StateGroup { + id: myState + state: "list" + states: [ + State { + name: "list" + ParentChange { target: myContent; parent: listItem } + PropertyChanges { target: myContent; x: 0; y: 0; width: listItem.width } + }, + State { + name: "grid" + ParentChange { target: myContent; parent: gridItem } + PropertyChanges { target: myContent; x: 0; y: 0; width: gridItem.width } + } + ] + + transitions: [ + Transition { + from: "*"; to: "*" + SequentialAnimation { + ParentAction{} + NumberAnimation { matchProperties: "x,y,width"; easing: "easeInOutQuad" } + } + } + ] + } + } + } + + ListView { + width: parent.width/2 + height: parent.height + model: Model.parts.list + } + + GridView { + x: parent.width/2 + width: parent.width/2 + cellWidth: 50 + cellHeight: 50 + height: parent.height + model: Model.parts.grid + } +} -- cgit v0.12