diff options
69 files changed, 752 insertions, 71 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 8330e47..579c225 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -127,6 +127,7 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *) void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0; void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0; +void (*QAbstractDeclarativeData::objectNameChanged)(QAbstractDeclarativeData *, QObject *) = 0; QObjectData::~QObjectData() {} @@ -1094,7 +1095,12 @@ QString QObject::objectName() const void QObject::setObjectName(const QString &name) { Q_D(QObject); + bool objectNameChanged = d->declarativeData && d->objectName != name; + d->objectName = name; + + if (objectNameChanged) + d->declarativeData->objectNameChanged(d->declarativeData, this); } diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 4800e6a..814769c 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -89,6 +89,7 @@ class Q_CORE_EXPORT QAbstractDeclarativeData public: static void (*destroyed)(QAbstractDeclarativeData *, QObject *); static void (*parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *); + static void (*objectNameChanged)(QAbstractDeclarativeData *, QObject *); }; class Q_CORE_EXPORT QObjectPrivate : public QObjectData diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 33c21b1..001abca 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -466,7 +466,7 @@ QDeclarativeFlickable::~QDeclarativeFlickable() qreal QDeclarativeFlickable::contentX() const { Q_D(const QDeclarativeFlickable); - return -d->hData.move.value(); + return -d->contentItem->x(); } void QDeclarativeFlickable::setContentX(qreal pos) @@ -484,7 +484,7 @@ void QDeclarativeFlickable::setContentX(qreal pos) qreal QDeclarativeFlickable::contentY() const { Q_D(const QDeclarativeFlickable); - return -d->vData.move.value(); + return -d->contentItem->y(); } void QDeclarativeFlickable::setContentY(qreal pos) diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 8216ab7..6ee6b0d 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -218,7 +218,14 @@ public: return visibleItems.last()->rowPos() + rows * rowSize(); } } else { - return (modelIndex / columns) * rowSize(); + qreal pos = (modelIndex / columns) * rowSize(); + if (header) { + qreal headerSize = flow == QDeclarativeGridView::LeftToRight + ? header->item->height() + : header->item->width(); + pos += headerSize; + } + return pos; } return 0; } diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp index 02b4807..c3bac2d 100644 --- a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp @@ -46,8 +46,6 @@ #include <qdeclarativeinfo.h> #include <qdeclarativepixmapcache_p.h> -#include <QFile> - QT_BEGIN_NAMESPACE QDeclarativeImageBase::QDeclarativeImageBase(QDeclarativeImageBasePrivate &dd, QDeclarativeItem *parent) @@ -115,6 +113,7 @@ void QDeclarativeImageBase::setSourceSize(const QSize& size) return; d->sourcesize = size; + d->explicitSourceSize = true; emit sourceSizeChanged(); if (isComponentComplete()) load(); @@ -123,7 +122,10 @@ void QDeclarativeImageBase::setSourceSize(const QSize& size) QSize QDeclarativeImageBase::sourceSize() const { Q_D(const QDeclarativeImageBase); - return d->sourcesize.isValid() ? d->sourcesize : QSize(implicitWidth(),implicitHeight()); + + int width = d->sourcesize.width(); + int height = d->sourcesize.height(); + return QSize(width != -1 ? width : implicitWidth(), height != -1 ? height : implicitHeight()); } void QDeclarativeImageBase::load() @@ -141,7 +143,7 @@ void QDeclarativeImageBase::load() pixmapChange(); update(); } else { - d->pix.load(qmlEngine(this), d->url, d->sourcesize, d->async); + d->pix.load(qmlEngine(this), d->url, d->explicitSourceSize ? sourceSize() : QSize(), d->async); if (d->pix.isLoading()) { d->progress = 0.0; @@ -186,11 +188,8 @@ void QDeclarativeImageBase::requestFinished() setImplicitWidth(d->pix.width()); setImplicitHeight(d->pix.height()); - if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height()) { - d->sourcesize.setWidth(d->pix.width()); - d->sourcesize.setHeight(d->pix.height()); + if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height()) emit sourceSizeChanged(); - } if (d->status != oldStatus) emit statusChanged(d->status); diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h b/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h index aee8b28..3d23ba9 100644 --- a/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h @@ -69,6 +69,7 @@ public: QDeclarativeImageBasePrivate() : status(QDeclarativeImageBase::Null), progress(0.0), + explicitSourceSize(false), async(false) { QGraphicsItemPrivate::flags = QGraphicsItemPrivate::flags & ~QGraphicsItem::ItemHasNoContents; @@ -79,6 +80,7 @@ public: QUrl url; qreal progress; QSize sourcesize; + bool explicitSourceSize : 1; bool async : 1; }; diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 250a43b..51eb5f2 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -56,7 +56,6 @@ #include <QDebug> #include <QPen> -#include <QFile> #include <QEvent> #include <QGraphicsSceneMouseEvent> #include <QtCore/qnumeric.h> @@ -1181,7 +1180,7 @@ void QDeclarativeKeysAttached::keyPressed(QKeyEvent *event, bool post) d->inPress = true; for (int ii = 0; ii < d->targets.count(); ++ii) { QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii)); - if (i) { + if (i && i->isVisible()) { d->item->scene()->sendEvent(i, event); if (event->isAccepted()) { d->inPress = false; @@ -1223,7 +1222,7 @@ void QDeclarativeKeysAttached::keyReleased(QKeyEvent *event, bool post) d->inRelease = true; for (int ii = 0; ii < d->targets.count(); ++ii) { QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii)); - if (i) { + if (i && i->isVisible()) { d->item->scene()->sendEvent(i, event); if (event->isAccepted()) { d->inRelease = false; @@ -1248,7 +1247,7 @@ void QDeclarativeKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool p d->inIM = true; for (int ii = 0; ii < d->targets.count(); ++ii) { QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii)); - if (i && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { + if (i && i->isVisible() && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { d->item->scene()->sendEvent(i, event); if (event->isAccepted()) { d->imeItem = i; @@ -1276,7 +1275,7 @@ QVariant QDeclarativeKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) if (d->item) { for (int ii = 0; ii < d->targets.count(); ++ii) { QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii)); - if (i && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod) && i == d->imeItem) { //### how robust is i == d->imeItem check? + if (i && i->isVisible() && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod) && i == d->imeItem) { //### how robust is i == d->imeItem check? QVariant v = static_cast<QDeclarativeItemAccessor *>(i)->doInputMethodQuery(query); if (v.userType() == QVariant::RectF) v = d->item->mapRectFromItem(i, v.toRectF()); //### cost? diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 6b46bc5..4943aef 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -1009,18 +1009,27 @@ void QDeclarativeListViewPrivate::updateSections() void QDeclarativeListViewPrivate::updateCurrentSection() { + Q_Q(QDeclarativeListView); if (!sectionCriteria || visibleItems.isEmpty()) { - currentSection.clear(); + if (!currentSection.isEmpty()) { + currentSection.clear(); + emit q->currentSectionChanged(); + } return; } int index = 0; while (index < visibleItems.count() && visibleItems.at(index)->endPosition() < position()) ++index; + QString newSection = currentSection; if (index < visibleItems.count()) - currentSection = visibleItems.at(index)->attached->section(); + newSection = visibleItems.at(index)->attached->section(); else - currentSection = visibleItems.first()->attached->section(); + newSection = visibleItems.first()->attached->section(); + if (newSection != currentSection) { + currentSection = newSection; + emit q->currentSectionChanged(); + } } void QDeclarativeListViewPrivate::updateCurrent(int modelIndex) diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index a0208ef..1533d55 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -557,6 +557,7 @@ void QDeclarativeMouseArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) ungrabMouse(); setKeepMouseGrab(false); } + d->doubleClick = false; } void QDeclarativeMouseArea::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) @@ -565,14 +566,12 @@ void QDeclarativeMouseArea::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *even if (!d->absorb) { QDeclarativeItem::mouseDoubleClickEvent(event); } else { + d->doubleClick = true; d->saveEvent(event); QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true, false); me.setAccepted(d->isDoubleClickConnected()); emit this->doubleClicked(&me); - if (!me.isAccepted()) { - // Only deliver the press event if we haven't accepted the double click. - QDeclarativeItem::mouseDoubleClickEvent(event); - } + QDeclarativeItem::mouseDoubleClickEvent(event); } } @@ -841,7 +840,8 @@ bool QDeclarativeMouseArea::setPressed(bool p) d->pressed = p; QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress); if (d->pressed) { - emit pressed(&me); + if (!d->doubleClick) + emit pressed(&me); me.setX(d->lastPos.x()); me.setY(d->lastPos.y()); emit mousePositionChanged(&me); @@ -849,7 +849,7 @@ bool QDeclarativeMouseArea::setPressed(bool p) emit released(&me); me.setX(d->lastPos.x()); me.setY(d->lastPos.y()); - if (isclick && !d->longPress) + if (isclick && !d->longPress && !d->doubleClick) emit clicked(&me); } diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h index 48a56d9..06a01d3 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h @@ -68,7 +68,7 @@ class QDeclarativeMouseAreaPrivate : public QDeclarativeItemPrivate public: QDeclarativeMouseAreaPrivate() : absorb(true), hovered(false), pressed(false), longPress(false), - moved(false), stealMouse(false), drag(0) + moved(false), stealMouse(false), doubleClick(false), drag(0) { } @@ -109,6 +109,7 @@ public: bool dragX : 1; bool dragY : 1; bool stealMouse : 1; + bool doubleClick : 1; QDeclarativeDrag *drag; QPointF startScene; qreal startX; diff --git a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp index a6db1fa..b470b3a 100644 --- a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp +++ b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp @@ -44,7 +44,6 @@ #include <QDebug> #include <QPen> -#include <QFile> #include <QEvent> #include <QApplication> #include <QGraphicsSceneMouseEvent> diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index 31943b2..81c84f5 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -1112,16 +1112,16 @@ void QDeclarativePathViewPrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent if (!interactive || !lastPosTime.isValid()) return; + qreal newPc; + QPointF pathPoint = pointNear(event->pos(), &newPc); if (!stealMouse) { - QPointF delta = event->pos() - startPoint; + QPointF delta = pathPoint - startPoint; if (qAbs(delta.x()) > QApplication::startDragDistance() || qAbs(delta.y()) > QApplication::startDragDistance()) stealMouse = true; } if (stealMouse) { moveReason = QDeclarativePathViewPrivate::Mouse; - qreal newPc; - pointNear(event->pos(), &newPc); qreal diff = (newPc - startPc)*modelCount*mappedRange; if (diff) { setOffset(offset + diff); diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp index 65f1564..54cb062 100644 --- a/src/declarative/graphicsitems/qdeclarativetext.cpp +++ b/src/declarative/graphicsitems/qdeclarativetext.cpp @@ -82,7 +82,7 @@ private: static QSet<QUrl> errors; }; -DEFINE_BOOL_CONFIG_OPTION(disableImageCache, QML_DISABLE_IMAGE_CACHE); +DEFINE_BOOL_CONFIG_OPTION(enableImageCache, QML_ENABLE_TEXT_IMAGE_CACHE); QDeclarativeTextPrivate::QDeclarativeTextPrivate() : color((QRgb)0), style(QDeclarativeText::Normal), @@ -90,7 +90,7 @@ QDeclarativeTextPrivate::QDeclarativeTextPrivate() imgDirty(true), dirty(true), richText(false), singleline(false), cache(true), internalWidthUpdate(false), doc(0), format(QDeclarativeText::AutoText), wrapMode(QDeclarativeText::NoWrap) { - cache = !disableImageCache(); + cache = enableImageCache(); QGraphicsItemPrivate::acceptedMouseButtons = Qt::LeftButton; QGraphicsItemPrivate::flags = QGraphicsItemPrivate::flags & ~QGraphicsItem::ItemHasNoContents; } diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index dc28e22..74bc5bd 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -1932,6 +1932,9 @@ bool QDeclarativeCompiler::buildPropertyAssignment(QDeclarativeParser::Property { obj->addValueProperty(prop); + if (prop->values.count() > 1) + COMPILE_EXCEPTION(prop->values.at(0), tr( "Cannot assign multiple values to a singular property") ); + for (int ii = 0; ii < prop->values.count(); ++ii) { Value *v = prop->values.at(ii); if (v->object) { @@ -2562,8 +2565,8 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder, QStringList alias = astNodeToStringList(node); - if (alias.count() != 1 && alias.count() != 2) - COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. An alias reference must be specified as <id> or <id>.<property>")); + if (alias.count() < 1 || alias.count() > 3) + COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. An alias reference must be specified as <id>, <id>.<property> or <id>.<value property>.<property>")); if (!compileState.ids.contains(alias.at(0))) COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. Unable to find id \"%1\"").arg(alias.at(0))); @@ -2575,11 +2578,14 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder, int propIdx = -1; int flags = 0; bool writable = false; - if (alias.count() == 2) { + if (alias.count() == 2 || alias.count() == 3) { propIdx = idObject->metaObject()->indexOfProperty(alias.at(1).toUtf8().constData()); - if (-1 == propIdx) + if (-1 == propIdx) { COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location")); + } else if (propIdx > 0xFFFF) { + COMPILE_EXCEPTION(prop.defaultValue, tr("Alias property exceeds alias bounds")); + } QMetaProperty aliasProperty = idObject->metaObject()->property(propIdx); if (!aliasProperty.isScriptable()) @@ -2587,6 +2593,22 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder, writable = aliasProperty.isWritable(); + if (alias.count() == 3) { + QDeclarativeValueType *valueType = enginePrivate->valueTypes[aliasProperty.type()]; + if (!valueType) + COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location")); + + propIdx |= ((unsigned int)aliasProperty.type()) << 24; + + int valueTypeIndex = valueType->metaObject()->indexOfProperty(alias.at(2).toUtf8().constData()); + if (valueTypeIndex == -1) + COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location")); + Q_ASSERT(valueTypeIndex <= 0xFF); + + aliasProperty = valueType->metaObject()->property(valueTypeIndex); + propIdx |= (valueTypeIndex << 16); + } + if (aliasProperty.isEnumType()) typeName = "int"; // Avoid introducing a dependency on the aliased metaobject else diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index b532b0c..cfef9cf 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -57,7 +57,6 @@ #include <QStack> #include <QStringList> -#include <QFileInfo> #include <QtCore/qdebug.h> #include <QApplication> diff --git a/src/declarative/qml/qdeclarativedata_p.h b/src/declarative/qml/qdeclarativedata_p.h index e916273..def4188 100644 --- a/src/declarative/qml/qdeclarativedata_p.h +++ b/src/declarative/qml/qdeclarativedata_p.h @@ -64,6 +64,7 @@ class QDeclarativeAbstractBinding; class QDeclarativeContext; class QDeclarativePropertyCache; class QDeclarativeContextData; +class QDeclarativeNotifier; // This class is structured in such a way, that simply zero'ing it is the // default state for elemental object allocations. This is crucial in the // workings of the QDeclarativeInstruction::CreateSimpleObject instruction. @@ -75,20 +76,23 @@ public: : ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false), context(0), outerContext(0), bindings(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0), bindingBits(0), lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0), - attachedProperties(0), scriptValue(0), objectDataRefCount(0), propertyCache(0), guards(0) { + scriptValue(0), objectDataRefCount(0), propertyCache(0), guards(0), extendedData(0) { init(); } static inline void init() { QAbstractDeclarativeData::destroyed = destroyed; QAbstractDeclarativeData::parentChanged = parentChanged; + QAbstractDeclarativeData::objectNameChanged = objectNameChanged; } static void destroyed(QAbstractDeclarativeData *, QObject *); static void parentChanged(QAbstractDeclarativeData *, QObject *, QObject *); + static void objectNameChanged(QAbstractDeclarativeData *, QObject *); void destroyed(QObject *); void parentChanged(QObject *, QObject *); + void objectNameChanged(QObject *); void setImplicitDestructible() { if (!explicitIndestructibleSet) indestructible = false; @@ -123,8 +127,6 @@ public: QDeclarativeCompiledData *deferredComponent; // Can't this be found from the context? unsigned int deferredIdx; - QHash<int, QObject *> *attachedProperties; - // ### Can we make this QScriptValuePrivate so we incur no additional allocation // cost? QScriptValue *scriptValue; @@ -147,6 +149,18 @@ public: return 0; } } + + QDeclarativeNotifier *objectNameNotifier() const; + QHash<int, QObject *> *attachedProperties() const; + + struct ExtendedData { + ExtendedData(); + ~ExtendedData(); + + QHash<int, QObject *> attachedProperties; + void *objectNameNotifier; + }; + mutable ExtendedData *extendedData; }; template<class T> diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 584c5ec..d768882 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -68,6 +68,7 @@ #include "private/qdeclarativelist_p.h" #include "private/qdeclarativetypenamecache_p.h" #include "private/qdeclarativeinclude_p.h" +#include "private/qdeclarativenotifier_p.h" #include <QtCore/qmetaobject.h> #include <QScriptClass> @@ -468,6 +469,11 @@ void QDeclarativeData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QO static_cast<QDeclarativeData *>(d)->parentChanged(o, p); } +void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o) +{ + static_cast<QDeclarativeData *>(d)->objectNameChanged(o); +} + void QDeclarativeEnginePrivate::init() { Q_Q(QDeclarativeEngine); @@ -949,7 +955,7 @@ QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool cre if (!data) return 0; // Attached properties are only on objects created by QML - QObject *rv = data->attachedProperties?data->attachedProperties->value(id):0; + QObject *rv = data->extendedData?data->attachedProperties()->value(id):0; if (rv || !create) return rv; @@ -959,11 +965,8 @@ QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool cre rv = pf(const_cast<QObject *>(object)); - if (rv) { - if (!data->attachedProperties) - data->attachedProperties = new QHash<int, QObject *>(); - data->attachedProperties->insert(id, rv); - } + if (rv) + data->attachedProperties()->insert(id, rv); return rv; } @@ -984,8 +987,6 @@ void QDeclarativeData::destroyed(QObject *object) { if (deferredComponent) deferredComponent->release(); - if (attachedProperties) - delete attachedProperties; if (nextContextObject) nextContextObject->prevContextObject = prevContextObject; @@ -1019,6 +1020,9 @@ void QDeclarativeData::destroyed(QObject *object) if (scriptValue) delete scriptValue; + if (extendedData) + delete extendedData; + if (ownMemory) delete this; } @@ -1028,6 +1032,11 @@ void QDeclarativeData::parentChanged(QObject *, QObject *parent) if (!parent && scriptValue) { delete scriptValue; scriptValue = 0; } } +void QDeclarativeData::objectNameChanged(QObject *) +{ + if (extendedData) objectNameNotifier()->notify(); +} + bool QDeclarativeData::hasBindingBit(int bit) const { if (bindingBitsSize > bit) @@ -1064,6 +1073,28 @@ void QDeclarativeData::setBindingBit(QObject *obj, int bit) bindingBits[bit / 32] |= (1 << (bit % 32)); } +QDeclarativeData::ExtendedData::ExtendedData() +: objectNameNotifier(0) +{ +} + +QDeclarativeData::ExtendedData::~ExtendedData() +{ + ((QDeclarativeNotifier *)&objectNameNotifier)->~QDeclarativeNotifier(); +} + +QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const +{ + if (!extendedData) extendedData = new ExtendedData; + return (QDeclarativeNotifier *)&extendedData->objectNameNotifier; +} + +QHash<int, QObject *> *QDeclarativeData::attachedProperties() const +{ + if (!extendedData) extendedData = new ExtendedData; + return &extendedData->attachedProperties; +} + /*! Creates a QScriptValue allowing you to use \a object in QML script. \a engine is the QDeclarativeEngine it is to be created in. @@ -2159,4 +2190,42 @@ const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const } } +bool QDeclarative_isFileCaseCorrect(const QString &fileName) +{ +#if defined(Q_OS_MAC) || defined(Q_OS_WIN) + QFileInfo info(fileName); + + QString absolute = info.absoluteFilePath(); + +#if defined(Q_OS_MAC) + QString canonical = info.canonicalFilePath(); +#elif defined(Q_OS_WIN) + wchar_t buffer[1024]; + + DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024); + if (rv == 0 || rv >= 1024) return true; + rv = ::GetLongPathName(buffer, buffer, 1024); + if (rv == 0 || rv >= 1024) return true; + + QString canonical((QChar *)buffer); +#endif + + int absoluteLength = absolute.length(); + int canonicalLength = canonical.length(); + + int length = qMin(absoluteLength, canonicalLength); + for (int ii = 0; ii < length; ++ii) { + const QChar &a = absolute.at(absoluteLength - 1 - ii); + const QChar &c = canonical.at(canonicalLength - 1 - ii); + + if (a.toLower() != c.toLower()) + return true; + if (a != c) + return false; + } +#endif + + return true; +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativefastproperties.cpp b/src/declarative/qml/qdeclarativefastproperties.cpp index eb69b6a..78e3afd 100644 --- a/src/declarative/qml/qdeclarativefastproperties.cpp +++ b/src/declarative/qml/qdeclarativefastproperties.cpp @@ -51,10 +51,19 @@ QT_BEGIN_NAMESPACE // primarily read from bindings is a candidate for inclusion as a fast // property. +static void QObject_objectName(QObject *object, void *output, QDeclarativeNotifierEndpoint *endpoint) +{ + if (endpoint) + endpoint->connect(QDeclarativeData::get(object, true)->objectNameNotifier()); + *((QString *)output) = object->objectName(); +} + QDeclarativeFastProperties::QDeclarativeFastProperties() { add(&QDeclarativeItem::staticMetaObject, QDeclarativeItem::staticMetaObject.indexOfProperty("parent"), QDeclarativeItemPrivate::parentProperty); + add(&QObject::staticMetaObject, QObject::staticMetaObject.indexOfProperty("objectName"), + QObject_objectName); } int QDeclarativeFastProperties::accessorIndexForProperty(const QMetaObject *metaObject, int propertyIndex) diff --git a/src/declarative/qml/qdeclarativeglobal_p.h b/src/declarative/qml/qdeclarativeglobal_p.h index 1041992..65d9b24 100644 --- a/src/declarative/qml/qdeclarativeglobal_p.h +++ b/src/declarative/qml/qdeclarativeglobal_p.h @@ -75,6 +75,19 @@ struct QDeclarativeGraphics_DerivedObject : public QObject }; /*! + Returns true if the case of \a fileName is equivalent to the file case of + \a fileName on disk, and false otherwise. + + This is used to ensure that the behavior of QML on a case-insensitive file + system is the same as on a case-sensitive file system. This function + performs a "best effort" attempt to determine the real case of the file. + It may have false positives (say the case is correct when it isn't), but it + should never have a false negative (say the case is incorrect when it is + correct). +*/ +bool QDeclarative_isFileCaseCorrect(const QString &fileName); + +/*! Makes the \a object a child of \a parent. Note that when using this method, neither \a parent nor the object's previous parent (if it had one) will receive ChildRemoved or ChildAdded events. diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp index fe4ed48..6f5216a 100644 --- a/src/declarative/qml/qdeclarativeimport.cpp +++ b/src/declarative/qml/qdeclarativeimport.cpp @@ -351,7 +351,11 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath { QFile file(absoluteFilePath); QString filecontent; - if (file.open(QFile::ReadOnly)) { + if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) { + if (errorString) + *errorString = QDeclarativeImportDatabase::tr("cannot load module \"%1\": File name case mismatch for \"%2\"").arg(uri).arg(absoluteFilePath); + return false; + } else if (file.open(QFile::ReadOnly)) { filecontent = QString::fromUtf8(file.readAll()); if (qmlImportTrace()) qDebug().nospace() << "QDeclarativeImports(" << qPrintable(base.toString()) << "::importExtension: " @@ -913,6 +917,11 @@ bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QSt } if (!engineInitialized || !typesRegistered) { + if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) { + if (errorString) + *errorString = tr("File name case mismatch for \"%2\"").arg(absoluteFilePath); + return false; + } QPluginLoader loader(absoluteFilePath); if (!loader.load()) { diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index ab6ff74..61a1f55 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -239,8 +239,13 @@ QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name) } } else { if (enginePriv->captureProperties && !(lastData->flags & QDeclarativePropertyCache::Data::IsConstant)) { - enginePriv->capturedProperties << - QDeclarativeEnginePrivate::CapturedProperty(obj, lastData->coreIndex, lastData->notifyIndex); + if (lastData->coreIndex == 0) { + enginePriv->capturedProperties << + QDeclarativeEnginePrivate::CapturedProperty(QDeclarativeData::get(obj, true)->objectNameNotifier()); + } else { + enginePriv->capturedProperties << + QDeclarativeEnginePrivate::CapturedProperty(obj, lastData->coreIndex, lastData->notifyIndex); + } } if (QDeclarativeValueTypeFactory::isValueType((uint)lastData->propType)) { diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp index 061f309..c8e1a07 100644 --- a/src/declarative/qml/qdeclarativetypeloader.cpp +++ b/src/declarative/qml/qdeclarativetypeloader.cpp @@ -44,6 +44,7 @@ #include <private/qdeclarativeengine_p.h> #include <private/qdeclarativecompiler_p.h> #include <private/qdeclarativecomponent_p.h> +#include <private/qdeclarativeglobal_p.h> #include <QtDeclarative/qdeclarativecomponent.h> #include <QtCore/qdebug.h> @@ -493,6 +494,13 @@ void QDeclarativeDataLoader::load(QDeclarativeDataBlob *blob) QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(blob->m_url); if (!lf.isEmpty()) { + if (!QDeclarative_isFileCaseCorrect(lf)) { + QDeclarativeError error; + error.setUrl(blob->m_url); + error.setDescription(QLatin1String("File name case mismatch")); + blob->setError(error); + return; + } QFile file(lf); if (file.open(QFile::ReadOnly)) { QByteArray data = file.readAll(); diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp index 37f08fc..e28062b 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject.cpp +++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp @@ -459,7 +459,7 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) id -= propOffset; if (id < metaData->propertyCount) { - int t = (metaData->propertyData() + id)->propertyType; + int t = (metaData->propertyData() + id)->propertyType; bool needActivate = false; if (t == -1) { @@ -586,11 +586,26 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) connectAlias(id); - if (d->propertyIdx == -1) { + if (d->isObjectAlias()) { *reinterpret_cast<QObject **>(a[0]) = target; return -1; + } else if (d->isValueTypeAlias()) { + // Value type property + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); + + QDeclarativeValueType *valueType = ep->valueTypes[d->valueType()]; + Q_ASSERT(valueType); + + valueType->read(target, d->propertyIndex()); + int rv = QMetaObject::metacall(valueType, c, d->valueTypeIndex(), a); + + if (c == QMetaObject::WriteProperty) + valueType->write(target, d->propertyIndex(), 0x00); + + return rv; + } else { - return QMetaObject::metacall(target, c, d->propertyIdx, a); + return QMetaObject::metacall(target, c, d->propertyIndex(), a); } } @@ -823,8 +838,8 @@ void QDeclarativeVMEMetaObject::connectAlias(int aliasId) int sigIdx = methodOffset + aliasId + metaData->propertyCount; QMetaObject::connect(context, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx); - if (d->propertyIdx != -1) { - QMetaProperty prop = target->metaObject()->property(d->propertyIdx); + if (!d->isObjectAlias()) { + QMetaProperty prop = target->metaObject()->property(d->propertyIndex()); if (prop.hasNotifySignal()) QDeclarativePropertyPrivate::connect(target, prop.notifySignalIndex(), object, sigIdx); } diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h index 4ccaa73..5134763 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject_p.h +++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h @@ -84,6 +84,25 @@ struct QDeclarativeVMEMetaData int contextIdx; int propertyIdx; int flags; + + bool isObjectAlias() const { + return propertyIdx == -1; + } + bool isPropertyAlias() const { + return !isObjectAlias() && !(propertyIdx & 0xFF000000); + } + bool isValueTypeAlias() const { + return !isObjectAlias() && (propertyIdx & 0xFF000000); + } + int propertyIndex() const { + return propertyIdx & 0x0000FFFF; + } + int valueTypeIndex() const { + return (propertyIdx & 0x00FF0000) >> 16; + } + int valueType() const { + return ((unsigned int)propertyIdx) >> 24; + } }; struct PropertyData { diff --git a/src/declarative/util/qdeclarativefontloader.cpp b/src/declarative/util/qdeclarativefontloader.cpp index 3e4a81a..d2f65ef 100644 --- a/src/declarative/util/qdeclarativefontloader.cpp +++ b/src/declarative/util/qdeclarativefontloader.cpp @@ -49,7 +49,6 @@ #include <QDebug> #include <QNetworkRequest> #include <QNetworkReply> -#include <QFile> #include <QFontDatabase> #include <private/qobject_p.h> diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 60cd020..e63acac 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -2365,7 +2365,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible()) fsi = fsi->d_ptr->focusScopeItem; fsi->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true, - /* focusFromShow = */ true); + /* focusFromHide = */ false); } break; } @@ -2375,6 +2375,10 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo QGraphicsItem *fi = subFocusItem; if (fi && fi != scene->focusItem()) { scene->setFocusItem(fi); + } else if (flags & QGraphicsItem::ItemIsFocusScope && + !scene->focusItem() && + q->isAncestorOf(scene->d_func()->lastFocusItem)) { + q_ptr->setFocus(); } } } else { @@ -2385,7 +2389,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo if (p->flags() & QGraphicsItem::ItemIsFocusScope) { if (p->d_ptr->visible) { p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true, - /* focusFromShow = */ true); + /* focusFromHide = */ true); } break; } @@ -3245,13 +3249,13 @@ bool QGraphicsItem::hasFocus() const */ void QGraphicsItem::setFocus(Qt::FocusReason focusReason) { - d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFromShow = */ false); + d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFromHide = */ false); } /*! \internal */ -void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromShow) +void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide) { // Disabled / unfocusable items cannot accept focus. if (!q_ptr->isEnabled() || !(flags & QGraphicsItem::ItemIsFocusable)) @@ -3272,7 +3276,7 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim if (p->flags() & QGraphicsItem::ItemIsFocusScope) { QGraphicsItem *oldFocusScopeItem = p->d_ptr->focusScopeItem; p->d_ptr->focusScopeItem = q_ptr; - if (!p->focusItem() && !focusFromShow) { + if (!p->focusItem() && !focusFromHide) { if (oldFocusScopeItem) oldFocusScopeItem->d_ptr->focusScopeItemChange(false); focusScopeItemChange(true); @@ -3334,7 +3338,7 @@ void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent) while (p) { if (p->flags() & QGraphicsItem::ItemIsFocusScope) { p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false, - /* focusFromShow = */ false); + /* focusFromHide = */ false); return; } p = p->d_ptr->parent; diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index c8a7699..8480c19 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -477,7 +477,7 @@ public: inline void markParentDirty(bool updateBoundingRect = false); - void setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromShow); + void setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide); void clearFocusHelper(bool giveFocusToParent); void setSubFocus(QGraphicsItem *rootItem = 0); void clearSubFocus(QGraphicsItem *rootItem = 0); diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml b/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml index 9fca5c3..56ac216 100644 --- a/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml +++ b/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml @@ -7,9 +7,9 @@ Rectangle { objectName: "MyRect" width: 100; height: 100; color: "green" Behavior on x { + id: myBehavior objectName: "MyBehavior" NumberAnimation {id: na1; duration: 200 } - NumberAnimation {id: na2; duration: 1000 } } } MouseArea { @@ -24,4 +24,9 @@ Rectangle { x: 200 } } + + NumberAnimation {id: na2; duration: 1000 } + Component.onCompleted: { + myBehavior.animation = na2; + } } diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/objectName.qml b/tests/auto/declarative/qdeclarativeecmascript/data/objectName.qml new file mode 100644 index 0000000..ca8c90d --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/objectName.qml @@ -0,0 +1,8 @@ +import QtQuick 1.0 + +QtObject { + objectName: "hello" + + property string test1: objectName + property string test2: objectName.substr(1, 3) +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 4feb630..02832f3 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -162,6 +162,7 @@ private slots: void deleteLater(); void in(); void sharedAttachedObject(); + void objectName(); void include(); @@ -2594,6 +2595,24 @@ void tst_qdeclarativeecmascript::sharedAttachedObject() delete o; } +// QTBUG-13999 +void tst_qdeclarativeecmascript::objectName() +{ + QDeclarativeComponent component(&engine, TEST_FILE("objectName.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("test1").toString(), QString("hello")); + QCOMPARE(o->property("test2").toString(), QString("ell")); + + o->setObjectName("world"); + + QCOMPARE(o->property("test1").toString(), QString("world")); + QCOMPARE(o->property("test2").toString(), QString("orl")); + + delete o; +} + QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" diff --git a/tests/auto/declarative/qdeclarativefocusscope/data/qtBug13380.qml b/tests/auto/declarative/qdeclarativefocusscope/data/qtBug13380.qml new file mode 100644 index 0000000..1784202 --- /dev/null +++ b/tests/auto/declarative/qdeclarativefocusscope/data/qtBug13380.qml @@ -0,0 +1,24 @@ +import QtQuick 1.0 + +Rectangle { + width: 400; height: 400 + + property bool showRect: false + onShowRectChanged: if (showRect) rect.visible = true + property bool noFocus: !fs2.activeFocus + + FocusScope { + id: fs1 + focus: true + } + Rectangle { + id: rect + visible: false + FocusScope { + id: fs2 + Rectangle { + focus: true + } + } + } +} diff --git a/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp b/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp index ec8f048..4cafbd9 100644 --- a/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp +++ b/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp @@ -70,6 +70,7 @@ private slots: void forceFocus(); void noParentFocus(); void signalEmission(); + void qtBug13380(); }; /* @@ -400,6 +401,31 @@ void tst_qdeclarativefocusscope::signalEmission() delete view; } +void tst_qdeclarativefocusscope::qtBug13380() +{ + QDeclarativeView *view = new QDeclarativeView; + view->setSource(QUrl::fromLocalFile(SRCDIR "/data/qtBug13380.qml")); + + view->show(); + QVERIFY(view->rootObject()); + qApp->setActiveWindow(view); + qApp->processEvents(); + +#ifdef Q_WS_X11 + // to be safe and avoid failing setFocus with window managers + qt_x11_wait_for_window_manager(view); +#endif + + QVERIFY(view->hasFocus()); + QVERIFY(view->scene()->hasFocus()); + QVERIFY(view->rootObject()->property("noFocus").toBool()); + + view->rootObject()->setProperty("showRect", true); + QVERIFY(view->rootObject()->property("noFocus").toBool()); + + delete view; +} + QTEST_MAIN(tst_qdeclarativefocusscope) #include "tst_qdeclarativefocusscope.moc" diff --git a/tests/auto/declarative/qdeclarativegridview/data/header.qml b/tests/auto/declarative/qdeclarativegridview/data/header.qml new file mode 100644 index 0000000..99baacd --- /dev/null +++ b/tests/auto/declarative/qdeclarativegridview/data/header.qml @@ -0,0 +1,32 @@ +import QtQuick 1.0 + +Rectangle { + width: 240 + height: 320 + color: "#ffffff" + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + width: 80 + height: 60 + border.color: "blue" + Text { + text: index + } + color: GridView.isCurrentItem ? "lightsteelblue" : "white" + } + } + GridView { + id: grid + objectName: "grid" + width: 240 + height: 320 + cellWidth: 80 + cellHeight: 60 + model: testModel + delegate: myDelegate + header: Text { objectName: "header"; text: "Header"; height: 30 } + } +} diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index 975cf8f..f7acd87 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -82,6 +82,7 @@ private slots: void QTBUG_8456(); void manualHighlight(); void footer(); + void header(); private: QDeclarativeView *createView(); @@ -1214,6 +1215,40 @@ void tst_QDeclarativeGridView::footer() QTRY_COMPARE(footer->y(), 0.0); } +void tst_QDeclarativeGridView::header() +{ + QDeclarativeView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 7; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml")); + qApp->processEvents(); + + QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QDeclarativeItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QDeclarativeText *header = findItem<QDeclarativeText>(contentItem, "header"); + QVERIFY(header); + + QCOMPARE(header->y(), 0.0); + QCOMPARE(gridview->contentY(), 0.0); + + QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0); + QVERIFY(item); + QCOMPARE(item->y(), 30.0); + + model.clear(); + QTRY_COMPARE(header->y(), 0.0); +} + QDeclarativeView *tst_QDeclarativeGridView::createView() { diff --git a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp index 8f9b2ea..f1e026f 100644 --- a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp +++ b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp @@ -84,6 +84,7 @@ private slots: void tiling_QTBUG_6716(); void noLoading(); void paintedWidthHeight(); + void sourceSize_QTBUG_14303(); private: template<typename T> @@ -377,7 +378,7 @@ void tst_qdeclarativeimage::noLoading() QTRY_COMPARE(statusSpy.count(), 0); // Loading remote file - ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/oldcolors.png"); + ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/heart200.png"); QTRY_VERIFY(obj->status() == QDeclarativeImage::Loading); QTRY_VERIFY(obj->progress() == 0.0); QTRY_VERIFY(obj->status() == QDeclarativeImage::Ready); @@ -388,7 +389,7 @@ void tst_qdeclarativeimage::noLoading() // Loading remote file again - should not go through 'Loading' state. ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/colors.png")); - ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/oldcolors.png"); + ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/heart200.png"); QTRY_VERIFY(obj->status() == QDeclarativeImage::Ready); QTRY_VERIFY(obj->progress() == 1.0); QTRY_COMPARE(sourceSpy.count(), 4); @@ -436,6 +437,35 @@ void tst_qdeclarativeimage::paintedWidthHeight() } } +void tst_qdeclarativeimage::sourceSize_QTBUG_14303() +{ + QString componentStr = "import QtQuick 1.0\nImage { source: srcImage }"; + QDeclarativeContext *ctxt = engine.rootContext(); + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/heart200.png")); + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeImage *obj = qobject_cast<QDeclarativeImage*>(component.create()); + + QSignalSpy sourceSizeSpy(obj, SIGNAL(sourceSizeChanged())); + + QTRY_VERIFY(obj != 0); + QTRY_VERIFY(obj->status() == QDeclarativeImage::Ready); + + QTRY_COMPARE(obj->sourceSize().width(), 200); + QTRY_COMPARE(obj->sourceSize().height(), 200); + QTRY_COMPARE(sourceSizeSpy.count(), 0); + + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/colors.png")); + QTRY_COMPARE(obj->sourceSize().width(), 120); + QTRY_COMPARE(obj->sourceSize().height(), 120); + QTRY_COMPARE(sourceSizeSpy.count(), 1); + + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/heart200.png")); + QTRY_COMPARE(obj->sourceSize().width(), 200); + QTRY_COMPARE(obj->sourceSize().height(), 200); + QTRY_COMPARE(sourceSizeSpy.count(), 2); +} + /* Find an item with the specified objectName. If index is supplied then the item must also evaluate the {index} expression equal to index diff --git a/tests/auto/declarative/qdeclarativeitem/data/keystest.qml b/tests/auto/declarative/qdeclarativeitem/data/keystest.qml index 3927f42..9af6e9f 100644 --- a/tests/auto/declarative/qdeclarativeitem/data/keystest.qml +++ b/tests/auto/declarative/qdeclarativeitem/data/keystest.qml @@ -17,6 +17,7 @@ Item { Item { id: item2 + visible: forwardeeVisible Keys.onPressed: keysTestObject.forwardedKey(event.key) Keys.onReleased: keysTestObject.forwardedKey(event.key) } diff --git a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp index bbbf73e..b4903ae 100644 --- a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp +++ b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp @@ -204,6 +204,7 @@ void tst_QDeclarativeItem::keys() canvas->rootContext()->setContextProperty("keysTestObject", testObject); canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true)); + canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(true)); canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keystest.qml")); canvas->show(); @@ -287,6 +288,17 @@ void tst_QDeclarativeItem::keys() testObject->reset(); + canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(false)); + key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, int(Qt::Key_A)); + QCOMPARE(testObject->mForwardedKey, 0); + QCOMPARE(testObject->mText, QLatin1String("A")); + QVERIFY(testObject->mModifiers == Qt::NoModifier); + QVERIFY(!key.isAccepted()); + + testObject->reset(); + canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(false)); QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), false); diff --git a/tests/auto/declarative/qdeclarativelanguage/data/alias.10.qml b/tests/auto/declarative/qdeclarativelanguage/data/alias.10.qml new file mode 100644 index 0000000..bf6352e --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/alias.10.qml @@ -0,0 +1,8 @@ +import Test 1.0 + +MyTypeObject { + id: root + property alias valueAlias: root.rectProperty + + rectProperty: "10,11,9x8" +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/alias.11.qml b/tests/auto/declarative/qdeclarativelanguage/data/alias.11.qml new file mode 100644 index 0000000..fbd50d9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/alias.11.qml @@ -0,0 +1,8 @@ +import Test 1.0 + +MyTypeObject { + id: root + + property alias aliasProperty: root.rectProperty.x + rectProperty: "19,13,100x120" +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/importIncorrectCase.qml b/tests/auto/declarative/qdeclarativelanguage/data/importIncorrectCase.qml new file mode 100644 index 0000000..247f527 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/importIncorrectCase.qml @@ -0,0 +1,5 @@ +import QtQuick 1.0 +import com.Nokia.installedtest 1.0 + +QtObject { +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/incorrectCase.errors.insensitive.txt b/tests/auto/declarative/qdeclarativelanguage/data/incorrectCase.errors.insensitive.txt new file mode 100644 index 0000000..3813680 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/incorrectCase.errors.insensitive.txt @@ -0,0 +1,2 @@ +3:1:Type IncorrectCaseType unavailable +-1:-1:File name case mismatch diff --git a/tests/auto/declarative/qdeclarativelanguage/data/incorrectCase.errors.sensitive.txt b/tests/auto/declarative/qdeclarativelanguage/data/incorrectCase.errors.sensitive.txt new file mode 100644 index 0000000..abed1a7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/incorrectCase.errors.sensitive.txt @@ -0,0 +1 @@ +3:1:IncorrectCaseType is not a type diff --git a/tests/auto/declarative/qdeclarativelanguage/data/incorrectCase.qml b/tests/auto/declarative/qdeclarativelanguage/data/incorrectCase.qml new file mode 100644 index 0000000..d11000b --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/incorrectCase.qml @@ -0,0 +1,4 @@ +import QtQuick 1.0 + +IncorrectCaseType { +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/incorrectCaseType.qml b/tests/auto/declarative/qdeclarativelanguage/data/incorrectCaseType.qml new file mode 100644 index 0000000..cf32b45 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/incorrectCaseType.qml @@ -0,0 +1,4 @@ +import QtQuick 1.0 + +QtObject { +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.10.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.10.errors.txt new file mode 100644 index 0000000..93652a7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.10.errors.txt @@ -0,0 +1 @@ +5:23:Invalid alias location diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.10.qml b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.10.qml new file mode 100644 index 0000000..3ff7b16 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.10.qml @@ -0,0 +1,6 @@ +import Test 1.0 + +MyTypeObject { + id: root + property alias a: root.rectProperty.blah +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.errors.txt index 7260be4..fbf1b58 100644 --- a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.errors.txt +++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.errors.txt @@ -1 +1 @@ -5:23:Invalid alias reference. An alias reference must be specified as <id> or <id>.<property> +5:23:Invalid alias reference. An alias reference must be specified as <id>, <id>.<property> or <id>.<value property>.<property> diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.qml b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.qml index cc71753..a363373 100644 --- a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.qml +++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.3.qml @@ -2,5 +2,5 @@ import Test 1.0 MyTypeObject { id: root - property alias a: root.rectProperty.x + property alias a: root.rectProperty.x.y } diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.4.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.4.errors.txt index 7260be4..fbf1b58 100644 --- a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.4.errors.txt +++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.4.errors.txt @@ -1 +1 @@ -5:23:Invalid alias reference. An alias reference must be specified as <id> or <id>.<property> +5:23:Invalid alias reference. An alias reference must be specified as <id>, <id>.<property> or <id>.<value property>.<property> diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.8.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.8.errors.txt new file mode 100644 index 0000000..93652a7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.8.errors.txt @@ -0,0 +1 @@ +5:23:Invalid alias location diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.8.qml b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.8.qml new file mode 100644 index 0000000..4faa52d --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.8.qml @@ -0,0 +1,7 @@ +import Test 1.0 + +MyTypeObject { + id: root + property alias a: root.imaginary.x +} + diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.9.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.9.errors.txt new file mode 100644 index 0000000..93652a7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.9.errors.txt @@ -0,0 +1 @@ +5:23:Invalid alias location diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.9.qml b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.9.qml new file mode 100644 index 0000000..f183912 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.9.qml @@ -0,0 +1,6 @@ +import Test 1.0 + +MyTypeObject { + id: root + property alias a: root.floatProperty.x +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/singularProperty.2.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/singularProperty.2.errors.txt new file mode 100644 index 0000000..beae562 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/singularProperty.2.errors.txt @@ -0,0 +1 @@ +5:10:Cannot assign multiple values to a singular property diff --git a/tests/auto/declarative/qdeclarativelanguage/data/singularProperty.2.qml b/tests/auto/declarative/qdeclarativelanguage/data/singularProperty.2.qml new file mode 100644 index 0000000..2fd7fd2 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/singularProperty.2.qml @@ -0,0 +1,7 @@ +import QtQuick 1.0 + +QtObject { + property QtObject a + a: [ QtObject {}, QtObject {} ] +} + diff --git a/tests/auto/declarative/qdeclarativelanguage/data/singularProperty.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/singularProperty.errors.txt new file mode 100644 index 0000000..beae562 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/singularProperty.errors.txt @@ -0,0 +1 @@ +5:10:Cannot assign multiple values to a singular property diff --git a/tests/auto/declarative/qdeclarativelanguage/data/singularProperty.qml b/tests/auto/declarative/qdeclarativelanguage/data/singularProperty.qml new file mode 100644 index 0000000..da56cb8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/singularProperty.qml @@ -0,0 +1,6 @@ +import QtQuick 1.0 + +QtObject { + property variant a + a: [ QtObject {}, QtObject {} ] +} diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/noqmldir/Test.qml b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/noqmldir/Test.qml new file mode 100644 index 0000000..0b054d0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/noqmldir/Test.qml @@ -0,0 +1,2 @@ +import QtQuick 1.0 +Rectangle { } diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 9a8c944..be04dee 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -144,6 +144,7 @@ private slots: void importsInstalled(); void importsOrder_data(); void importsOrder(); + void importIncorrectCase(); void qmlAttachedPropertiesObjectMethod(); void customOnProperty(); @@ -348,6 +349,9 @@ void tst_qdeclarativelanguage::errors_data() QTest::newRow("invalidAlias.5") << "invalidAlias.5.qml" << "invalidAlias.5.errors.txt" << false; QTest::newRow("invalidAlias.6") << "invalidAlias.6.qml" << "invalidAlias.6.errors.txt" << false; QTest::newRow("invalidAlias.7") << "invalidAlias.7.qml" << "invalidAlias.7.errors.txt" << false; + QTest::newRow("invalidAlias.8") << "invalidAlias.8.qml" << "invalidAlias.8.errors.txt" << false; + QTest::newRow("invalidAlias.9") << "invalidAlias.9.qml" << "invalidAlias.9.errors.txt" << false; + QTest::newRow("invalidAlias.10") << "invalidAlias.10.qml" << "invalidAlias.10.errors.txt" << false; QTest::newRow("invalidAttachedProperty.1") << "invalidAttachedProperty.1.qml" << "invalidAttachedProperty.1.errors.txt" << false; QTest::newRow("invalidAttachedProperty.2") << "invalidAttachedProperty.2.qml" << "invalidAttachedProperty.2.errors.txt" << false; @@ -380,6 +384,15 @@ void tst_qdeclarativelanguage::errors_data() QTest::newRow("invalidProperty") << "invalidProperty.qml" << "invalidProperty.errors.txt" << false; QTest::newRow("nonScriptableProperty") << "nonScriptableProperty.qml" << "nonScriptableProperty.errors.txt" << false; QTest::newRow("notAvailable") << "notAvailable.qml" << "notAvailable.errors.txt" << false; + QTest::newRow("singularProperty") << "singularProperty.qml" << "singularProperty.errors.txt" << false; + QTest::newRow("singularProperty.2") << "singularProperty.2.qml" << "singularProperty.2.errors.txt" << false; + QTest::newRow("incorrectCase") << "incorrectCase.qml" +#if defined(Q_OS_MAC) || defined(Q_OS_WIN) + << "incorrectCase.errors.insensitive.txt" +#else + << "incorrectCase.errors.sensitive.txt" +#endif + << false; } @@ -1054,6 +1067,47 @@ void tst_qdeclarativelanguage::aliasProperties() delete object; } + + // Valuetype alias + // Simple "int" alias + { + QDeclarativeComponent component(&engine, TEST_FILE("alias.10.qml")); + VERIFY_ERRORS(0); + QObject *object = component.create(); + QVERIFY(object != 0); + + // Read through alias + QCOMPARE(object->property("valueAlias").toRect(), QRect(10, 11, 9, 8)); + object->setProperty("rectProperty", QVariant(QRect(33, 12, 99, 100))); + QCOMPARE(object->property("valueAlias").toRect(), QRect(33, 12, 99, 100)); + + // Write throught alias + object->setProperty("valueAlias", QVariant(QRect(3, 3, 4, 9))); + QCOMPARE(object->property("valueAlias").toRect(), QRect(3, 3, 4, 9)); + QCOMPARE(object->property("rectProperty").toRect(), QRect(3, 3, 4, 9)); + + delete object; + } + + // Valuetype sub-alias + { + QDeclarativeComponent component(&engine, TEST_FILE("alias.11.qml")); + VERIFY_ERRORS(0); + QObject *object = component.create(); + QVERIFY(object != 0); + + // Read through alias + QCOMPARE(object->property("aliasProperty").toInt(), 19); + object->setProperty("rectProperty", QVariant(QRect(33, 8, 102, 111))); + QCOMPARE(object->property("aliasProperty").toInt(), 33); + + // Write throught alias + object->setProperty("aliasProperty", QVariant(4)); + QCOMPARE(object->property("aliasProperty").toInt(), 4); + QCOMPARE(object->property("rectProperty").toRect(), QRect(4, 8, 102, 111)); + + delete object; + } } // QTBUG-13374 Test that alias properties and signals can coexist @@ -1515,6 +1569,7 @@ void tst_qdeclarativelanguage::basicRemote_data() QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage/"; QTest::newRow("no need for qmldir") << QUrl(serverdir+"Test.qml") << "" << ""; + QTest::newRow("absent qmldir") << QUrl(serverdir+"/noqmldir/Test.qml") << "" << ""; QTest::newRow("need qmldir") << QUrl(serverdir+"TestLocal.qml") << "" << ""; } @@ -1722,6 +1777,22 @@ void tst_qdeclarativelanguage::importsOrder() testType(qml,type,error); } +void tst_qdeclarativelanguage::importIncorrectCase() +{ + QDeclarativeComponent component(&engine, TEST_FILE("importIncorrectCase.qml")); + + QList<QDeclarativeError> errors = component.errors(); + QCOMPARE(errors.count(), 1); + +#if defined(Q_OS_MAC) || defined(Q_OS_WIN) + QString expectedError = QLatin1String("cannot load module \"com.Nokia.installedtest\": File name case mismatch for \"") + QFileInfo(__FILE__).absoluteDir().filePath("data/lib/com/Nokia/installedtest/qmldir") + QLatin1String("\""); +#else + QString expectedError = QLatin1String("module \"com.Nokia.installedtest\" is not installed"); +#endif + + QCOMPARE(errors.at(0).description(), expectedError); +} + void tst_qdeclarativelanguage::qmlAttachedPropertiesObjectMethod() { QObject object; diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 6452bae..65ff635 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -937,6 +937,8 @@ void tst_QDeclarativeListView::sections() QCOMPARE(next->text().toInt(), (i+1)/5); } + QSignalSpy currentSectionChangedSpy(listview, SIGNAL(currentSectionChanged())); + // Remove section boundary model.removeItem(5); @@ -972,9 +974,13 @@ void tst_QDeclarativeListView::sections() listview->setContentY(140); QTRY_COMPARE(listview->currentSection(), QString("1")); + QTRY_COMPARE(currentSectionChangedSpy.count(), 1); + listview->setContentY(20); QTRY_COMPARE(listview->currentSection(), QString("0")); + QTRY_COMPARE(currentSectionChangedSpy.count(), 2); + item = findItem<QDeclarativeItem>(contentItem, "wrapper", 1); QTRY_VERIFY(item); QTRY_COMPARE(item->height(), 20.0); diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/data/incorrectCase.qml b/tests/auto/declarative/qdeclarativemoduleplugin/data/incorrectCase.qml new file mode 100644 index 0000000..a21ece7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativemoduleplugin/data/incorrectCase.qml @@ -0,0 +1,4 @@ +import com.nokia.WrongCase 1.0 + +MyPluginType { value: 123 } + diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/imports/com/nokia/WrongCase/qmldir b/tests/auto/declarative/qdeclarativemoduleplugin/imports/com/nokia/WrongCase/qmldir new file mode 100644 index 0000000..6c87874 --- /dev/null +++ b/tests/auto/declarative/qdeclarativemoduleplugin/imports/com/nokia/WrongCase/qmldir @@ -0,0 +1 @@ +plugin PluGin diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/pluginWrongCase/plugin.cpp b/tests/auto/declarative/qdeclarativemoduleplugin/pluginWrongCase/plugin.cpp new file mode 100644 index 0000000..5e91f4e --- /dev/null +++ b/tests/auto/declarative/qdeclarativemoduleplugin/pluginWrongCase/plugin.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QStringList> +#include <QtDeclarative/qdeclarativeextensionplugin.h> +#include <QtDeclarative/qdeclarative.h> +#include <QDebug> + +class MyPluginType : public QObject +{ + Q_OBJECT + Q_PROPERTY(int value READ value WRITE setValue) + +public: + MyPluginType(QObject *parent=0) : QObject(parent) + { + qWarning("import worked"); + } + + int value() const { return v; } + void setValue(int i) { v = i; } + +private: + int v; +}; + + +class MyPlugin : public QDeclarativeExtensionPlugin +{ + Q_OBJECT +public: + MyPlugin() + { + qWarning("plugin created"); + } + + void registerTypes(const char *uri) + { + Q_ASSERT(QLatin1String(uri) == "com.nokia.WrongCase"); + qmlRegisterType<MyPluginType>(uri, 1, 0, "MyPluginType"); + } +}; + +#include "plugin.moc" + +Q_EXPORT_PLUGIN2(plugin, MyPlugin); diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/pluginWrongCase/pluginWrongCase.pro b/tests/auto/declarative/qdeclarativemoduleplugin/pluginWrongCase/pluginWrongCase.pro new file mode 100644 index 0000000..c7337ca --- /dev/null +++ b/tests/auto/declarative/qdeclarativemoduleplugin/pluginWrongCase/pluginWrongCase.pro @@ -0,0 +1,10 @@ +TEMPLATE = lib +CONFIG += plugin +SOURCES = plugin.cpp +QT = core declarative +TARGET = Plugin +DESTDIR = ../imports/com/nokia/WrongCase + +symbian: { + TARGET.EPOCALLOWDLLDATA=1 +} diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/qdeclarativemoduleplugin.pro b/tests/auto/declarative/qdeclarativemoduleplugin/qdeclarativemoduleplugin.pro index 824b402..221e465 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/qdeclarativemoduleplugin.pro +++ b/tests/auto/declarative/qdeclarativemoduleplugin/qdeclarativemoduleplugin.pro @@ -1,6 +1,6 @@ QT = core TEMPLATE = subdirs -SUBDIRS = plugin +SUBDIRS = plugin pluginWrongCase tst_qdeclarativemoduleplugin_pro.depends += plugin SUBDIRS += tst_qdeclarativemoduleplugin.pro diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp index e1022e0..51f66a5 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp +++ b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp @@ -54,6 +54,7 @@ public: private slots: void importsPlugin(); + void incorrectPluginCase(); }; #ifdef Q_OS_SYMBIAN @@ -120,6 +121,30 @@ void tst_qdeclarativemoduleplugin::importsPlugin() delete object; } +void tst_qdeclarativemoduleplugin::incorrectPluginCase() +{ + QDeclarativeEngine engine; + engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports")); + + QDeclarativeComponent component(&engine, TEST_FILE("data/incorrectCase.qml")); + + QList<QDeclarativeError> errors = component.errors(); + QCOMPARE(errors.count(), 1); + +#if defined(Q_OS_MAC) || defined(Q_OS_WIN) +#if defined(Q_OS_MAC) + QString libname = "libPluGin.dylib"; +#elif defined(Q_OS_WIN) + QString libname = "PluGin.dll"; +#endif + QString expectedError = QLatin1String("plugin cannot be loaded for module \"com.nokia.WrongCase\": File name case mismatch for \"") + QFileInfo(__FILE__).absoluteDir().filePath("imports/com/nokia/WrongCase/" + libname) + QLatin1String("\""); +#else + QString expectedError = QLatin1String("module \"com.nokia.WrongCase\" plugin \"PluGin\" not found"); +#endif + + QCOMPARE(errors.at(0).description(), expectedError); +} + QTEST_MAIN(tst_qdeclarativemoduleplugin) #include "tst_qdeclarativemoduleplugin.moc" diff --git a/tests/auto/declarative/qdeclarativemousearea/data/doubleclick.qml b/tests/auto/declarative/qdeclarativemousearea/data/doubleclick.qml index 2348444..55b0812 100644 --- a/tests/auto/declarative/qdeclarativemousearea/data/doubleclick.qml +++ b/tests/auto/declarative/qdeclarativemousearea/data/doubleclick.qml @@ -4,11 +4,13 @@ Item { id: root property int clicked: 0 property int doubleClicked: 0 + property int released: 0 MouseArea { width: 200; height: 200 onClicked: { root.clicked++ } onDoubleClicked: { root.doubleClicked++ } + onReleased: { root.released++ } } } diff --git a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp index 5e88450..5a50e0d 100644 --- a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp +++ b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp @@ -413,14 +413,19 @@ void tst_QDeclarativeMouseArea::doubleClick() releaseEvent.setButtons(Qt::LeftButton); QApplication::sendEvent(scene, &releaseEvent); + QCOMPARE(canvas->rootObject()->property("released").toInt(), 1); + QGraphicsSceneMouseEvent dblClickEvent(QEvent::GraphicsSceneMouseDoubleClick); dblClickEvent.setScenePos(QPointF(100, 100)); dblClickEvent.setButton(Qt::LeftButton); dblClickEvent.setButtons(Qt::LeftButton); QApplication::sendEvent(scene, &dblClickEvent); + QApplication::sendEvent(scene, &releaseEvent); + QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1); QCOMPARE(canvas->rootObject()->property("doubleClicked").toInt(), 1); + QCOMPARE(canvas->rootObject()->property("released").toInt(), 2); } QTEST_MAIN(tst_QDeclarativeMouseArea) diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 2901dd5..2ddccd2 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -9065,6 +9065,9 @@ void tst_QGraphicsItem::focusScope() scope2->hide(); scope2->show(); QVERIFY(!scope2->hasFocus()); + QVERIFY(scope1->hasFocus()); + scope2->setFocus(); + scope3->setFocus(); QVERIFY(scope3->hasFocus()); QGraphicsRectItem *rect4 = new QGraphicsRectItem; |