diff options
Diffstat (limited to 'src')
39 files changed, 462 insertions, 110 deletions
diff --git a/src/particles/qquickparticleemitter.cpp b/src/particles/qquickparticleemitter.cpp index 6e53b0940c..7db1707d74 100644 --- a/src/particles/qquickparticleemitter.cpp +++ b/src/particles/qquickparticleemitter.cpp @@ -472,7 +472,12 @@ void QQuickParticleEmitter::emitWindow(int timeStamp) } } + foreach (QQuickParticleData* d, toEmit) + m_system->emitParticle(d); + if (isEmitConnected()) { + //Done after emitParticle so that the Painter::load is done first, this allows you to customize its static variables + //We then don't need to request another reload, because the first reload isn't scheduled until we get back to the render thread v8::HandleScope handle_scope; v8::Context::Scope scope(QQmlEnginePrivate::getV8Engine(qmlEngine(this))->context()); v8::Handle<v8::Array> array = v8::Array::New(toEmit.size()); @@ -481,8 +486,6 @@ void QQuickParticleEmitter::emitWindow(int timeStamp) emitParticles(QQmlV8Handle::fromHandle(array));//A chance for arbitrary JS changes } - foreach (QQuickParticleData* d, toEmit) - m_system->emitParticle(d); m_last_emission = pt; diff --git a/src/particles/qquicktrailemitter.cpp b/src/particles/qquicktrailemitter.cpp index 68b43a0e99..5f094105e1 100644 --- a/src/particles/qquicktrailemitter.cpp +++ b/src/particles/qquicktrailemitter.cpp @@ -118,7 +118,7 @@ QQuickTrailEmitter::QQuickTrailEmitter(QQuickItem *parent) : \qmlproperty real QtQuick.Particles2::TrailEmitter::emitRatePerParticle */ /*! - \qmlsignal QtQuick.Particles2::TrailEmitter::emitFollowParticles(Array particles, real followed) + \qmlsignal QtQuick.Particles2::TrailEmitter::emitFollowParticles(Array particles, QtQuick.Particles2::Particle followed) This handler is called when particles are emitted from the \a followed particle. \a particles contains an array of particle objects which can be directly manipulated. @@ -264,6 +264,9 @@ void QQuickTrailEmitter::emitWindow(int timeStamp) } } + foreach (QQuickParticleData* d, toEmit) + m_system->emitParticle(d); + if (isEmitConnected() || isEmitFollowConnected()) { v8::HandleScope handle_scope; v8::Context::Scope scope(QQmlEnginePrivate::getV8Engine(qmlEngine(this))->context()); @@ -276,8 +279,6 @@ void QQuickTrailEmitter::emitWindow(int timeStamp) else if (isEmitConnected()) emitParticles(QQmlV8Handle::fromHandle(array));//A chance for arbitrary JS changes } - foreach (QQuickParticleData* d, toEmit) - m_system->emitParticle(d); m_lastEmission[d->index] = pt; } diff --git a/src/qml/doc/qtqml.qdocconf b/src/qml/doc/qtqml.qdocconf index 80f7cefb91..7cc65b76bd 100644 --- a/src/qml/doc/qtqml.qdocconf +++ b/src/qml/doc/qtqml.qdocconf @@ -1,3 +1,6 @@ +include(global/qt-html-templates-offline.qdocconf) +include(global/qt-cpp-ignore.qdocconf) + project = QtQml description = Qt QML Reference Documentation url = http://qt-project.org/doc/qt-5.0/qtqml @@ -8,7 +11,7 @@ outputencoding = UTF-8 naturallanguage = en_US qhp.projects = QtCore -depends += qtcore qtjsbackend qtxmlpatterns qtquick +depends += qtcore qtxmlpatterns qhp.QtQml.file = qtqml.qhp qhp.QtQml.namespace = org.qt-project.qtqml.500 @@ -52,7 +55,7 @@ HTML.nobreadcrumbs = "true" HTML.templatedir = . -HTML.stylesheets = ../../../doc/global/style/offline.css +HTML.stylesheets = global/style/offline.css HTML.headerstyles = \ " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/offline.css\" />\n" diff --git a/src/qml/doc/src/cppintegration/registercpptypes.qdoc b/src/qml/doc/src/cppintegration/registercpptypes.qdoc index 9ccf428aaf..0e1188310b 100644 --- a/src/qml/doc/src/cppintegration/registercpptypes.qdoc +++ b/src/qml/doc/src/cppintegration/registercpptypes.qdoc @@ -265,6 +265,9 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c \code template<typename T, int metaObjectRevision> int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) + + template<typename T, int metaObjectRevision> + int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason) \endcode For example, if \c BaseObject is changed and now has a revision 1, you can specify that diff --git a/src/qml/doc/src/typesystem/basictypes.qdoc b/src/qml/doc/src/typesystem/basictypes.qdoc index 3c1b849b5b..c24787b4c8 100644 --- a/src/qml/doc/src/typesystem/basictypes.qdoc +++ b/src/qml/doc/src/typesystem/basictypes.qdoc @@ -167,6 +167,21 @@ See \l {QML Basic Types} for the list of basic types that are supported by the Q Usually you will only have to do this once, because relative URLs resolved from that file will use the same protocol. + URLs may contain encoded characters using the 'percent-encoding' scheme + specified by \l {http://tools.ietf.org/html/rfc3986}{RFC 3986}. These characters + will be preserved within properties of type \c url, to allow QML code to + construct precise URL values. An exception to this rule is the preemptive + decoding of directory-separator characters (\c '/') - these characters are decoded + to allow the URL to be correctly classified. + + For example, a local file containing a '#' character, which would normally be + interpreted as the beginning of the URL 'fragment' element, can be accessed by + encoding the characters of the file name: + + \qml + Image { source: encodeURIComponent("/tmp/test#1.png") } + \endqml + \sa {QML Basic Types} */ diff --git a/src/qml/qml.pro b/src/qml/qml.pro index 311ee3ca4d..5c165027fc 100644 --- a/src/qml/qml.pro +++ b/src/qml/qml.pro @@ -17,6 +17,8 @@ exists("qqml_enable_gcov") { MODULE_DEFINES = QQmlImageProvider=QQuickImageProvider load(qt_module_config) +QMAKE_DOCS = $$PWD/doc/qtqml.qdocconf + # private dependencies QT += v8-private diff --git a/src/qml/qml/ftw/qpodvector_p.h b/src/qml/qml/ftw/qpodvector_p.h index c96692667a..d7f51b43e3 100644 --- a/src/qml/qml/ftw/qpodvector_p.h +++ b/src/qml/qml/ftw/qpodvector_p.h @@ -58,13 +58,13 @@ QT_BEGIN_NAMESPACE -template<class T, int Increment=1024> -class QPODVector +template<class T, int Increment> +class QPODVector { public: QPODVector() : m_count(0), m_capacity(0), m_data(0) {} - ~QPODVector() { if (m_data) ::free(m_data); } + ~QPODVector() { if (m_data) ::free(m_data); } const T &at(int idx) const { return m_data[idx]; @@ -109,8 +109,8 @@ public: int newSize = m_count + count; reserve(newSize); int moveCount = m_count - idx; - if (moveCount) - ::memmove(m_data + idx + count, m_data + idx, + if (moveCount) + ::memmove(m_data + idx + count, m_data + idx, moveCount * sizeof(T)); m_count = newSize; } @@ -118,7 +118,7 @@ public: void remove(int idx, int count = 1) { int moveCount = m_count - (idx + count); if (moveCount) - ::memmove(m_data + idx, m_data + idx + count, + ::memmove(m_data + idx, m_data + idx + count, moveCount * sizeof(T)); m_count -= count; } diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index c7092a6c76..528f8e6416 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -167,6 +167,37 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); } +template<typename T, int metaObjectRevision> +int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason) +{ + QML_GETTYPENAMES + + QQmlPrivate::RegisterType type = { + 1, + + qRegisterNormalizedMetaType<T *>(pointerName.constData()), + qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()), + 0, 0, + reason, + + uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject, + + QQmlPrivate::attachedPropertiesFunc<T>(), + QQmlPrivate::attachedPropertiesMetaObject<T>(), + + QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(), + QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(), + QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(), + + 0, 0, + + 0, + metaObjectRevision + }; + + return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); +} + template<typename T> int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) { diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp index 2bb99ddbab..13ff9e81e3 100644 --- a/src/qml/qml/qqmlcompiler.cpp +++ b/src/qml/qml/qqmlcompiler.cpp @@ -515,6 +515,8 @@ void QQmlCompiler::genLiteralAssignment(QQmlScript::Property *prop, { Instruction::StoreUrl instr; QString string = v->value.asString(); + // Encoded dir-separators defeat QUrl processing - decode them first + string.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive); QUrl u = string.isEmpty() ? QUrl() : output->url.resolved(QUrl(string)); instr.propertyIndex = prop->index; instr.value = output->indexForUrl(u); diff --git a/src/qml/qml/qqmlfile.cpp b/src/qml/qml/qqmlfile.cpp index b0da80f102..df876b6879 100644 --- a/src/qml/qml/qqmlfile.cpp +++ b/src/qml/qml/qqmlfile.cpp @@ -51,7 +51,7 @@ \class QQmlFile \brief The QQmlFile class gives access to local and remote files. -Supports file://, qrc://, bundle:// uris and whatever QNetworkAccessManager supports. +Supports file://, qrc:/, bundle:// uris and whatever QNetworkAccessManager supports. */ #define QQMLFILE_MAX_REDIRECT_RECURSION 16 @@ -481,7 +481,7 @@ bool QQmlFile::connectDownloadProgress(QObject *object, int method) /*! Returns true if QQmlFile will open \a url synchronously. -Synchronous urls have a qrc://, file://, or bundle:// scheme. +Synchronous urls have a qrc:/, file://, or bundle:// scheme. */ bool QQmlFile::isSynchronous(const QUrl &url) { @@ -498,11 +498,11 @@ bool QQmlFile::isSynchronous(const QUrl &url) /*! Returns true if QQmlFile will open \a url synchronously. -Synchronous urls have a qrc://, file://, or bundle:// scheme. +Synchronous urls have a qrc:/, file://, or bundle:// scheme. */ bool QQmlFile::isSynchronous(const QString &url) { - if (url.length() < 6 /* qrc:// */) + if (url.length() < 5 /* qrc:/ */) return false; QChar f = url[0]; @@ -521,9 +521,9 @@ bool QQmlFile::isSynchronous(const QString &url) } else if (f == QLatin1Char('q') || f == QLatin1Char('Q')) { - return url.length() >= 6 /* bundle:// */ && + return url.length() >= 5 /* qrc:/ */ && url.startsWith(qrc_string, Qt::CaseInsensitive) && - url[3] == QLatin1Char(':') && url[4] == QLatin1Char('/') && url[5] == QLatin1Char('/'); + url[3] == QLatin1Char(':') && url[4] == QLatin1Char('/'); } @@ -556,7 +556,7 @@ bool QQmlFile::isBundle(const QUrl &url) /*! Returns true if \a url is a local file that can be opened with QFile. -Local file urls have either a qrc:// or file:// scheme. +Local file urls have either a qrc:/ or file:// scheme. */ bool QQmlFile::isLocalFile(const QUrl &url) { @@ -572,11 +572,11 @@ bool QQmlFile::isLocalFile(const QUrl &url) /*! Returns true if \a url is a local file that can be opened with QFile. -Local file urls have either a qrc:// or file:// scheme. +Local file urls have either a qrc:/ or file:// scheme. */ bool QQmlFile::isLocalFile(const QString &url) { - if (url.length() < 6 /* qrc:// */) + if (url.length() < 5 /* qrc:/ */) return false; QChar f = url[0]; @@ -589,9 +589,9 @@ bool QQmlFile::isLocalFile(const QString &url) } else if (f == QLatin1Char('q') || f == QLatin1Char('Q')) { - return url.length() >= 6 /* bundle:// */ && + return url.length() >= 5 /* qrc:/ */ && url.startsWith(qrc_string, Qt::CaseInsensitive) && - url[3] == QLatin1Char(':') && url[4] == QLatin1Char('/') && url[5] == QLatin1Char('/'); + url[3] == QLatin1Char(':') && url[4] == QLatin1Char('/'); } diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 33f860fb17..d0c2761373 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -1319,10 +1319,16 @@ bool QQmlPropertyPrivate::write(QObject *object, u = value.toUrl(); found = true; } else if (variantType == QVariant::ByteArray) { - u = QUrl(QString::fromUtf8(value.toByteArray())); + QString input(QString::fromUtf8(value.toByteArray())); + // Encoded dir-separators defeat QUrl processing - decode them first + input.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive); + u = QUrl(input); found = true; } else if (variantType == QVariant::String) { - u = QUrl(value.toString()); + QString input(value.toString()); + // Encoded dir-separators defeat QUrl processing - decode them first + input.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive); + u = QUrl(input); found = true; } diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 87e707d1a0..d922b9942a 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -210,7 +210,8 @@ void QQmlPropertyData::lazyLoad(const QMetaMethod &m) propType = QMetaType::Void; const char *returnType = m.typeName(); - Q_ASSERT(returnType != 0); + if (!returnType) + returnType = "\0"; if ((*returnType != 'v') || (qstrcmp(returnType+1, "oid") != 0)) { propTypeName = returnType; flags |= NotFullyResolved; diff --git a/src/qml/qml/qquicklistmodel.cpp b/src/qml/qml/qquicklistmodel.cpp index 52ef2ab61f..03f9e3a790 100644 --- a/src/qml/qml/qquicklistmodel.cpp +++ b/src/qml/qml/qquicklistmodel.cpp @@ -2327,6 +2327,8 @@ void QQuickListModelParser::setCustomData(QObject *obj, const QByteArray &d) const ListModelData *lmd = (const ListModelData *)d.constData(); const char *data = ((const char *)lmd) + lmd->dataOffset; + bool setRoles = false; + QStack<DataStackElement> stack; for (int ii = 0; ii < lmd->instrCount; ++ii) { @@ -2398,6 +2400,7 @@ void QQuickListModelParser::setCustomData(QObject *obj, const QByteArray &d) } e1.model->setOrCreateProperty(e1.elementIndex, name, value); + setRoles = true; } break; @@ -2410,6 +2413,9 @@ void QQuickListModelParser::setCustomData(QObject *obj, const QByteArray &d) break; } } + + if (setRoles == false) + qmlInfo(obj) << "All ListElement declarations are empty, no roles can be created unless dynamicRoles is set."; } bool QQuickListModelParser::definesEmptyList(const QString &s) diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp index ff16f3b95b..7d42b47d53 100644 --- a/src/qml/qml/v4/qv4bindings.cpp +++ b/src/qml/qml/v4/qv4bindings.cpp @@ -1296,7 +1296,9 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks, if (src.isUndefined()) { output.setUndefined(); } else { - const QString tmp(*src.getstringptr()); + QString tmp(*src.getstringptr()); + // Encoded dir-separators defeat QUrl processing - decode them first + tmp.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive); if (instr->unaryop.src == instr->unaryop.output) { output.cleanupString(); MARK_CLEAN_REGISTER(instr->unaryop.output); @@ -1326,7 +1328,7 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks, COLOR_REGISTER(instr->unaryop.output); } } - QML_V4_END_INSTR(ConvertStringToUrl, unaryop) + QML_V4_END_INSTR(ConvertStringToColor, unaryop) QML_V4_BEGIN_INSTR(ConvertStringToVariant, unaryop) { diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf index 423627819b..9aa056e26c 100644 --- a/src/quick/doc/qtquick.qdocconf +++ b/src/quick/doc/qtquick.qdocconf @@ -1,9 +1,12 @@ +include(global/qt-html-templates-offline.qdocconf) +include(global/qt-cpp-ignore.qdocconf) + project = QtQuick description = Qt Quick Reference Documentation url = http://qt-project.org/doc/qt-5.0/qtquick version = 5.0.0 -depends += qtqcore qtxmlpatterns qtjsbackend qtqml +depends += qtqcore qtxmlpatterns qtqml sourceencoding = UTF-8 outputencoding = UTF-8 @@ -52,7 +55,7 @@ HTML.nobreadcrumbs = "true" HTML.templatedir = . -HTML.stylesheets = ../../../doc/global/style/offline.css +HTML.stylesheets = global/style/offline.css HTML.headerstyles = \ " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/offline.css\" />\n" diff --git a/src/quick/doc/src/concepts/effects-particles.qdoc b/src/quick/doc/src/concepts/effects-particles.qdoc index 8d77c26d37..9fbe85c5bb 100644 --- a/src/quick/doc/src/concepts/effects-particles.qdoc +++ b/src/quick/doc/src/concepts/effects-particles.qdoc @@ -47,6 +47,7 @@ \inqmlmodule QtQuick.Particles 2.0 \title Using the Qt Quick Particle System + Documentation for all Particle System elements can be found on the \l{QML Module QtQuick.Particles 2}{QtQuick.Particles} module page. Note that to use elements from the particles module, you will need to import the types with the following line: \code diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp index 5d4ce7f494..abd20c66f0 100644 --- a/src/quick/items/qquickborderimage.cpp +++ b/src/quick/items/qquickborderimage.cpp @@ -274,8 +274,8 @@ QQuickBorderImage::~QQuickBorderImage() void QQuickBorderImage::setSource(const QUrl &url) { Q_D(QQuickBorderImage); - //equality is fairly expensive, so we bypass for simple, common case - if ((d->url.isEmpty() == url.isEmpty()) && url == d->url) + + if (url == d->url) return; if (d->sciReply) { @@ -305,6 +305,7 @@ void QQuickBorderImage::load() setImplicitSize(0, 0); emit statusChanged(d->status); update(); + return; } else { d->status = Loading; if (d->url.path().endsWith(QLatin1String("sci"))) { @@ -347,6 +348,7 @@ void QQuickBorderImage::load() emit statusChanged(d->status); emit progressChanged(d->progress); update(); + return; } } } diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp index 82fabd047b..7c59a9df9e 100644 --- a/src/quick/items/qquickcanvas.cpp +++ b/src/quick/items/qquickcanvas.cpp @@ -1062,12 +1062,14 @@ bool QQuickCanvas::event(QEvent *e) d->clearHover(); d->lastMousePosition = QPoint(); break; +#ifndef QT_NO_DRAGANDDROP case QEvent::DragEnter: case QEvent::DragLeave: case QEvent::DragMove: case QEvent::Drop: d->deliverDragEvent(&d->dragGrabber, e); break; +#endif case QEvent::WindowDeactivate: rootItem()->windowDeactivateEvent(); break; @@ -1578,6 +1580,7 @@ bool QQuickCanvasPrivate::deliverTouchPoints(QQuickItem *item, QTouchEvent *even return false; } +#ifndef QT_NO_DRAGANDDROP void QQuickCanvasPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QEvent *event) { Q_Q(QQuickCanvas); @@ -1697,6 +1700,7 @@ bool QQuickCanvasPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQuickIte return accepted; } +#endif // QT_NO_DRAGANDDROP bool QQuickCanvasPrivate::sendFilteredMouseEvent(QQuickItem *target, QQuickItem *item, QEvent *event) { @@ -1792,12 +1796,14 @@ bool QQuickCanvas::sendEvent(QQuickItem *item, QEvent *e) QQuickItemPrivate::get(item)->deliverTouchEvent(static_cast<QTouchEvent *>(e)); } break; +#ifndef QT_NO_DRAGANDDROP case QEvent::DragEnter: case QEvent::DragMove: case QEvent::DragLeave: case QEvent::Drop: QQuickItemPrivate::get(item)->deliverDragEvent(e); break; +#endif default: break; } diff --git a/src/quick/items/qquickcanvas_p.h b/src/quick/items/qquickcanvas_p.h index 29c0d51b60..e08c342c44 100644 --- a/src/quick/items/qquickcanvas_p.h +++ b/src/quick/items/qquickcanvas_p.h @@ -68,7 +68,6 @@ #include <qopenglcontext.h> #include <QtGui/qopenglframebufferobject.h> #include <QtGui/qevent.h> -#include <QtGui/qinputpanel.h> QT_BEGIN_NAMESPACE @@ -112,7 +111,9 @@ public: QQuickItem *activeFocusItem; QQuickItem *mouseGrabberItem; +#ifndef QT_NO_DRAGANDDROP QQuickDragGrabber dragGrabber; +#endif int touchMouseId; ulong touchMousePressTimestamp; @@ -132,8 +133,10 @@ public: bool sendHoverEvent(QEvent::Type, QQuickItem *, const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, bool accepted); bool clearHover(); +#ifndef QT_NO_DRAGANDDROP void deliverDragEvent(QQuickDragGrabber *, QEvent *); bool deliverDragEvent(QQuickDragGrabber *, QQuickItem *, QDragMoveEvent *); +#endif QList<QQuickItem*> hoverItems; enum FocusOption { diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp index 2357e3a7db..80dbf2b6db 100644 --- a/src/quick/items/qquickdrag.cpp +++ b/src/quick/items/qquickdrag.cpp @@ -49,6 +49,8 @@ #include <QtQml/qqmlinfo.h> #include <QtGui/qevent.h> +#ifndef QT_NO_DRAGANDDROP + QT_BEGIN_NAMESPACE class QQuickDragAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener @@ -614,3 +616,5 @@ void QQuickDragAttached::cancel() } QT_END_NAMESPACE + +#endif // QT_NO_DRAGANDDROP diff --git a/src/quick/items/qquickdrag_p.h b/src/quick/items/qquickdrag_p.h index 720946924f..4ed98fa08c 100644 --- a/src/quick/items/qquickdrag_p.h +++ b/src/quick/items/qquickdrag_p.h @@ -49,6 +49,7 @@ #include <QtCore/qmimedata.h> #include <QtCore/qstringlist.h> +#ifndef QT_NO_DRAGANDDROP QT_BEGIN_HEADER @@ -206,4 +207,6 @@ QT_END_NAMESPACE QT_END_HEADER +#endif // QT_NO_DRAGANDDROP + #endif diff --git a/src/quick/items/qquickdroparea.cpp b/src/quick/items/qquickdroparea.cpp index 6c178c5c1f..1f5d98cb9a 100644 --- a/src/quick/items/qquickdroparea.cpp +++ b/src/quick/items/qquickdroparea.cpp @@ -46,6 +46,8 @@ #include <private/qqmlengine_p.h> +#ifndef QT_NO_DRAGANDDROP + QT_BEGIN_NAMESPACE QQuickDropAreaDrag::QQuickDropAreaDrag(QQuickDropAreaPrivate *d, QObject *parent) @@ -429,3 +431,4 @@ void QQuickDropEvent::accept(QQmlV8Function *args) QT_END_NAMESPACE +#endif // QT_NO_DRAGANDDROP diff --git a/src/quick/items/qquickdroparea_p.h b/src/quick/items/qquickdroparea_p.h index e207787198..082c3dadb9 100644 --- a/src/quick/items/qquickdroparea_p.h +++ b/src/quick/items/qquickdroparea_p.h @@ -49,6 +49,8 @@ #include <QtGui/qevent.h> +#ifndef QT_NO_DRAGANDDROP + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -162,4 +164,6 @@ QML_DECLARE_TYPE(QQuickDropArea) QT_END_HEADER +#endif // QT_NO_DRAGANDDROP + #endif // QQUICKDROPAREA_P_H diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp index 0bdfab67a9..735910e7ff 100644 --- a/src/quick/items/qquickimagebase.cpp +++ b/src/quick/items/qquickimagebase.cpp @@ -100,8 +100,8 @@ QUrl QQuickImageBase::source() const void QQuickImageBase::setSource(const QUrl &url) { Q_D(QQuickImageBase); - //equality is fairly expensive, so we bypass for simple, common case - if ((d->url.isEmpty() == url.isEmpty()) && url == d->url) + + if (url == d->url) return; d->url = url; diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 00e01828be..ab942f6489 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -3254,6 +3254,7 @@ void QQuickItem::hoverLeaveEvent(QHoverEvent *event) Q_UNUSED(event); } +#ifndef QT_NO_DRAGANDDROP void QQuickItem::dragEnterEvent(QDragEnterEvent *event) { Q_UNUSED(event); @@ -3275,6 +3276,7 @@ void QQuickItem::dropEvent(QDropEvent *event) { Q_UNUSED(event); } +#endif // QT_NO_DRAGANDDROP bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *) { @@ -3860,6 +3862,7 @@ void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e) } } +#ifndef QT_NO_DRAGANDDROP void QQuickItemPrivate::deliverDragEvent(QEvent *e) { Q_Q(QQuickItem); @@ -3880,6 +3883,7 @@ void QQuickItemPrivate::deliverDragEvent(QEvent *e) break; } } +#endif // QT_NO_DRAGANDDROP void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value) { diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h index 69122bdbcd..c0fd01fb7e 100644 --- a/src/quick/items/qquickitem.h +++ b/src/quick/items/qquickitem.h @@ -384,10 +384,12 @@ protected: virtual void hoverEnterEvent(QHoverEvent *event); virtual void hoverMoveEvent(QHoverEvent *event); virtual void hoverLeaveEvent(QHoverEvent *event); +#ifndef QT_NO_DRAGANDDROP virtual void dragEnterEvent(QDragEnterEvent *); virtual void dragMoveEvent(QDragMoveEvent *); virtual void dragLeaveEvent(QDragLeaveEvent *); virtual void dropEvent(QDropEvent *); +#endif virtual bool childMouseEventFilter(QQuickItem *, QEvent *); virtual void windowDeactivateEvent(); diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index bbff26089d..0b4b2bd855 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -532,7 +532,9 @@ public: void deliverWheelEvent(QWheelEvent *); void deliverTouchEvent(QTouchEvent *); void deliverHoverEvent(QHoverEvent *); +#ifndef QT_NO_DRAGANDDROP void deliverDragEvent(QEvent *); +#endif bool calcEffectiveVisible() const; bool setEffectiveVisibleRecur(bool); diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index bb1305545e..380354c57d 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -214,10 +214,12 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickPathAnimation>("QtQuick",2,0,"PathAnimation"); qmlRegisterType<QQuickPathInterpolator>("QtQuick",2,0,"PathInterpolator"); +#ifndef QT_NO_DRAGANDDROP qmlRegisterType<QQuickDropArea>("QtQuick", 2, 0, "DropArea"); qmlRegisterType<QQuickDropEvent>(); qmlRegisterType<QQuickDropAreaDrag>(); qmlRegisterUncreatableType<QQuickDrag>("QtQuick", 2, 0, "Drag", QQuickDragAttached::tr("Drag is only available via attached properties")); +#endif qmlRegisterType<QQuickMultiPointTouchArea>("QtQuick", 2, 0, "MultiPointTouchArea"); qmlRegisterType<QQuickTouchPoint>("QtQuick", 2, 0, "TouchPoint"); diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index d42d1cbc48..f12da439b5 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -113,6 +113,7 @@ public: virtual void updateSections(); QQuickItem *getSectionItem(const QString §ion); void releaseSectionItem(QQuickItem *item); + void releaseSectionItems(); void updateInlineSection(FxListItemSG *); void updateCurrentSection(); void updateStickySections(); @@ -143,6 +144,8 @@ public: QSmoothedAnimation *highlightPosAnimator; QSmoothedAnimation *highlightSizeAnimator; + qreal highlightMoveVelocity; + qreal highlightResizeVelocity; int highlightResizeDuration; QQuickViewSection *sectionCriteria; @@ -166,7 +169,7 @@ public: , averageSize(100.0), spacing(0.0) , snapMode(QQuickListView::NoSnap) , highlightPosAnimator(0), highlightSizeAnimator(0) - , highlightResizeDuration(250) + , highlightMoveVelocity(400), highlightResizeVelocity(400), highlightResizeDuration(-1) , sectionCriteria(0), currentSectionItem(0), nextSectionItem(0) , overshootDist(0.0), correctFlick(false), inFlickCorrection(false) {} @@ -207,6 +210,8 @@ void QQuickViewSection::setCriteria(QQuickViewSection::SectionCriteria criteria) void QQuickViewSection::setDelegate(QQmlComponent *delegate) { if (delegate != m_delegate) { + if (m_delegate) + m_view->releaseSectionItems(); m_delegate = delegate; emit delegateChanged(); m_view->updateSections(); @@ -873,10 +878,12 @@ void QQuickListViewPrivate::createHighlight() const QLatin1String posProp(orient == QQuickListView::Vertical ? "y" : "x"); highlightPosAnimator = new QSmoothedAnimation; highlightPosAnimator->target = QQmlProperty(item, posProp); + highlightPosAnimator->velocity = highlightMoveVelocity; highlightPosAnimator->userDuration = highlightMoveDuration; const QLatin1String sizeProp(orient == QQuickListView::Vertical ? "height" : "width"); highlightSizeAnimator = new QSmoothedAnimation; + highlightSizeAnimator->velocity = highlightResizeVelocity; highlightSizeAnimator->userDuration = highlightResizeDuration; highlightSizeAnimator->target = QQmlProperty(item, sizeProp); @@ -976,6 +983,24 @@ void QQuickListViewPrivate::releaseSectionItem(QQuickItem *item) delete item; } + +void QQuickListViewPrivate::releaseSectionItems() +{ + for (int i = 0; i < visibleItems.count(); ++i) { + FxListItemSG *listItem = static_cast<FxListItemSG *>(visibleItems.at(i)); + if (listItem->section()) { + qreal pos = listItem->position(); + releaseSectionItem(listItem->section()); + listItem->setSection(0); + listItem->setPosition(pos); + } + } + for (int i = 0; i < sectionCacheSize; ++i) { + delete sectionCache[i]; + sectionCache[i] = 0; + } +} + void QQuickListViewPrivate::updateInlineSection(FxListItemSG *listItem) { if (!sectionCriteria || !sectionCriteria->delegate()) @@ -1140,6 +1165,8 @@ void QQuickListViewPrivate::updateSections() lastVisibleSection = QString(); updateCurrentSection(); updateStickySections(); + forceLayout = true; + q->polish(); } void QQuickListViewPrivate::updateCurrentSection() @@ -1901,7 +1928,7 @@ QQuickListView::~QQuickListView() is scrolled. This is because the view moves to maintain the highlight within the preferred highlight range (or visible viewport). - \sa highlight + \sa highlight, highlightMoveVelocity */ //###Possibly rename these properties, since they are very useful even without a highlight? /*! @@ -2190,20 +2217,42 @@ QString QQuickListView::currentSection() const } /*! + \qmlproperty real QtQuick2::ListView::highlightMoveVelocity \qmlproperty int QtQuick2::ListView::highlightMoveDuration + \qmlproperty real QtQuick2::ListView::highlightResizeVelocity \qmlproperty int QtQuick2::ListView::highlightResizeDuration - These properties hold the move and resize animation duration of - the highlight delegate. + These properties control the speed of the move and resize animations for the + highlight delegate. \l highlightFollowsCurrentItem must be true for these properties to have effect. - The default value for highlightMoveDuration is 150ms and the - default value for highlightResizeDuration is 250ms. + The default value for the velocity properties is 400 pixels/second. + The default value for the duration properties is -1, i.e. the + highlight will take as much time as necessary to move at the set speed. + + These properties have the same characteristics as a SmoothedAnimation. \sa highlightFollowsCurrentItem */ +qreal QQuickListView::highlightMoveVelocity() const +{ + Q_D(const QQuickListView); + return d->highlightMoveVelocity; +} + +void QQuickListView::setHighlightMoveVelocity(qreal speed) +{ + Q_D(QQuickListView); + if (d->highlightMoveVelocity != speed) { + d->highlightMoveVelocity = speed; + if (d->highlightPosAnimator) + d->highlightPosAnimator->velocity = d->highlightMoveVelocity; + emit highlightMoveVelocityChanged(); + } +} + void QQuickListView::setHighlightMoveDuration(int duration) { Q_D(QQuickListView); @@ -2214,6 +2263,23 @@ void QQuickListView::setHighlightMoveDuration(int duration) } } +qreal QQuickListView::highlightResizeVelocity() const +{ + Q_D(const QQuickListView); + return d->highlightResizeVelocity; +} + +void QQuickListView::setHighlightResizeVelocity(qreal speed) +{ + Q_D(QQuickListView); + if (d->highlightResizeVelocity != speed) { + d->highlightResizeVelocity = speed; + if (d->highlightSizeAnimator) + d->highlightSizeAnimator->velocity = d->highlightResizeVelocity; + emit highlightResizeVelocityChanged(); + } +} + int QQuickListView::highlightResizeDuration() const { Q_D(const QQuickListView); diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h index 6bdd4cb674..a40a01aa30 100644 --- a/src/quick/items/qquicklistview_p.h +++ b/src/quick/items/qquicklistview_p.h @@ -102,6 +102,8 @@ class Q_AUTOTEST_EXPORT QQuickListView : public QQuickItemView Q_OBJECT Q_DECLARE_PRIVATE(QQuickListView) + Q_PROPERTY(qreal highlightMoveVelocity READ highlightMoveVelocity WRITE setHighlightMoveVelocity NOTIFY highlightMoveVelocityChanged) + Q_PROPERTY(qreal highlightResizeVelocity READ highlightResizeVelocity WRITE setHighlightResizeVelocity NOTIFY highlightResizeVelocityChanged) Q_PROPERTY(int highlightResizeDuration READ highlightResizeDuration WRITE setHighlightResizeDuration NOTIFY highlightResizeDurationChanged) Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged) @@ -132,6 +134,12 @@ public: virtual void setHighlightFollowsCurrentItem(bool); + qreal highlightMoveVelocity() const; + void setHighlightMoveVelocity(qreal); + + qreal highlightResizeVelocity() const; + void setHighlightResizeVelocity(qreal); + int highlightResizeDuration() const; void setHighlightResizeDuration(int); @@ -151,6 +159,8 @@ Q_SIGNALS: void spacingChanged(); void orientationChanged(); void currentSectionChanged(); + void highlightMoveVelocityChanged(); + void highlightResizeVelocityChanged(); void highlightResizeDurationChanged(); void snapModeChanged(); diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index f114292ad7..17458abee6 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -59,6 +59,8 @@ DEFINE_BOOL_CONFIG_OPTION(qmlVisualTouchDebugging, QML_VISUAL_TOUCH_DEBUGGING) static const int PressAndHoldDelay = 800; +#ifndef QT_NO_DRAGANDDROP + QQuickDrag::QQuickDrag(QObject *parent) : QObject(parent), _target(0), _axis(XandYAxis), _xmin(-FLT_MAX), _xmax(FLT_MAX), _ymin(-FLT_MAX), _ymax(FLT_MAX), _active(false), _filterChildren(false) @@ -186,16 +188,29 @@ QQuickDragAttached *QQuickDrag::qmlAttachedProperties(QObject *obj) return new QQuickDragAttached(obj); } +#endif // QT_NO_DRAGANDDROP + QQuickMouseAreaPrivate::QQuickMouseAreaPrivate() : enabled(true), hovered(false), pressed(false), longPress(false), moved(false), dragX(true), dragY(true), stealMouse(false), doubleClick(false), preventStealing(false), - propagateComposedEvents(false), drag(0) + propagateComposedEvents(false) +#ifndef QT_NO_DRAGANDDROP + , drag(0) +#endif +#ifndef QT_NO_CURSOR + , cursor(0) +#endif { } QQuickMouseAreaPrivate::~QQuickMouseAreaPrivate() { +#ifndef QT_NO_DRAGANDDROP delete drag; +#endif +#ifndef QT_NO_CURSOR + delete cursor; +#endif } void QQuickMouseAreaPrivate::init() @@ -696,18 +711,22 @@ void QQuickMouseArea::mousePressEvent(QMouseEvent *event) else { d->longPress = false; d->saveEvent(event); +#ifndef QT_NO_DRAGANDDROP if (d->drag) d->drag->setActive(false); +#endif setHovered(true); d->startScene = event->windowPos(); d->pressAndHoldTimer.start(PressAndHoldDelay, this); setKeepMouseGrab(d->stealMouse); event->setAccepted(setPressed(true)); +#ifndef QT_NO_DRAGANDDROP if (d->drag) { d->dragX = drag()->axis() & QQuickDrag::XAxis; d->dragY = drag()->axis() & QQuickDrag::YAxis; } +#endif } } @@ -729,6 +748,7 @@ void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event) else if (!d->hovered && isInside) setHovered(true); +#ifndef QT_NO_DRAGANDDROP if (d->drag && d->drag->target()) { if (!d->moved) { d->targetStartPos = d->drag->target()->parentItem() @@ -789,6 +809,8 @@ void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event) d->moved = true; } +#endif + QQuickMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress); emit mouseXChanged(&me); me.setPosition(d->lastPos); @@ -806,8 +828,10 @@ void QQuickMouseArea::mouseReleaseEvent(QMouseEvent *event) } else { d->saveEvent(event); setPressed(false); +#ifndef QT_NO_DRAGANDDROP if (d->drag) d->drag->setActive(false); +#endif // If we don't accept hover, we need to reset containsMouse. if (!acceptHoverEvents()) setHovered(false); @@ -969,7 +993,13 @@ bool QQuickMouseArea::sendMouseEvent(QMouseEvent *event) bool QQuickMouseArea::childMouseEventFilter(QQuickItem *i, QEvent *e) { Q_D(QQuickMouseArea); - if (!d->pressed && (!d->enabled || !isVisible() || !d->drag || !d->drag->filterChildren())) + if (!d->pressed && + (!d->enabled || !isVisible() +#ifndef QT_NO_DRAGANDDROP + || !d->drag || !d->drag->filterChildren() +#endif + ) + ) return QQuickItem::childMouseEventFilter(i, e); switch (e->type()) { case QEvent::MouseButtonPress: @@ -988,7 +1018,11 @@ void QQuickMouseArea::timerEvent(QTimerEvent *event) Q_D(QQuickMouseArea); if (event->timerId() == d->pressAndHoldTimer.timerId()) { d->pressAndHoldTimer.stop(); +#ifndef QT_NO_DRAGANDDROP bool dragged = d->drag && d->drag->active(); +#else + bool dragged = false; +#endif if (d->pressed && dragged == false && d->hovered == true) { d->longPress = true; QQuickMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress); @@ -1091,8 +1125,18 @@ void QQuickMouseArea::setHovered(bool h) d->hovered = h; emit hoveredChanged(); d->hovered ? emit entered() : emit exited(); +#ifndef QT_NO_CURSOR + if (d->cursor) { + if (d->hovered) { + canvas()->setCursor(QCursor(*d->cursor)); + } else { + canvas()->unsetCursor(); + } + } +#endif } } + /*! \qmlproperty QtQuick2::Qt::MouseButtons MouseArea::acceptedButtons This property holds the mouse buttons that the mouse area reacts to. @@ -1129,7 +1173,11 @@ void QQuickMouseArea::setAcceptedButtons(Qt::MouseButtons buttons) bool QQuickMouseArea::setPressed(bool p) { Q_D(QQuickMouseArea); +#ifndef QT_NO_DRAGANDDROP bool dragged = d->drag && d->drag->active(); +#else + bool dragged = false; +#endif bool isclick = d->pressed == true && p == false && dragged == false && d->hovered == true; if (d->pressed != p) { @@ -1160,6 +1208,68 @@ bool QQuickMouseArea::setPressed(bool p) return false; } + +/*! + \qmlproperty QtQuick2::Qt::CursorShape MouseArea::cursorShape + This property holds the cursor shape for this mouse area. + Note that on platforms that do not display a mouse cursor this may have + no effect. + + The available cursor shapes are: + \list + \li Qt.ArrowCursor + \li Qt.UpArrowCursor + \li Qt.CrossCursor + \li Qt.WaitCursor + \li Qt.IBeamCursor + \li Qt.SizeVerCursor + \li Qt.SizeHorCursor + \li Qt.SizeBDiagCursor + \li Qt.SizeFDiagCursor + \li Qt.SizeAllCursor + \li Qt.BlankCursor + \li Qt.SplitVCursor + \li Qt.SplitHCursor + \li Qt.PointingHandCursor + \li Qt.ForbiddenCursor + \li Qt.WhatsThisCursor + \li Qt.BusyCursor + \li Qt.OpenHandCursor + \li Qt.ClosedHandCursor + \li Qt.DragCopyCursor + \li Qt.DragMoveCursor + \li Qt.DragLinkCursor + \endlist + + In order to only set a mouse cursor shape for a region without reacting + to mouse events set the acceptedButtons to none: + + \code + MouseArea { cursorShape: Qt.IBeamCursor; acceptedButtons: Qt.NoButton } + \endcode + + The default value is \c Qt.ArrowCursor. + \sa Qt::CursorShape +*/ + +#ifndef QT_NO_CURSOR +Qt::CursorShape QQuickMouseArea::cursorShape() const +{ + Q_D(const QQuickMouseArea); + if (d->cursor) + return d->cursor->shape(); + return Qt::ArrowCursor; +} + +void QQuickMouseArea::setCursorShape(Qt::CursorShape shape) +{ + Q_D(QQuickMouseArea); + setHoverEnabled(true); + delete d->cursor; + d->cursor = new QCursor(shape); +} +#endif + /*! \qmlproperty Item QtQuick2::MouseArea::drag.target \qmlproperty bool QtQuick2::MouseArea::drag.active @@ -1197,6 +1307,7 @@ bool QQuickMouseArea::setPressed(bool p) */ +#ifndef QT_NO_DRAGANDDROP QQuickDrag *QQuickMouseArea::drag() { Q_D(QQuickMouseArea); @@ -1204,6 +1315,7 @@ QQuickDrag *QQuickMouseArea::drag() d->drag = new QQuickDrag; return d->drag; } +#endif QSGNode *QQuickMouseArea::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) { diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h index 177d2839f1..14b74f45d0 100644 --- a/src/quick/items/qquickmousearea_p.h +++ b/src/quick/items/qquickmousearea_p.h @@ -50,8 +50,11 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QQuickDragAttached; class QQuickMouseEvent; + +#ifndef QT_NO_DRAGANDDROP + +class QQuickDragAttached; class Q_AUTOTEST_EXPORT QQuickDrag : public QObject { Q_OBJECT @@ -118,6 +121,8 @@ private: Q_DISABLE_COPY(QQuickDrag) }; +#endif // QT_NO_DRAGANDDROP + class QQuickMouseAreaPrivate; class QQuickWheelEvent; // used in QtLocation @@ -133,9 +138,14 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseArea : public QQuickItem Q_PROPERTY(Qt::MouseButtons pressedButtons READ pressedButtons NOTIFY pressedChanged) Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged) Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged) +#ifndef QT_NO_DRAGANDDROP Q_PROPERTY(QQuickDrag *drag READ drag CONSTANT) //### add flicking to QQuickDrag or add a QQuickFlick ??? +#endif Q_PROPERTY(bool preventStealing READ preventStealing WRITE setPreventStealing NOTIFY preventStealingChanged) Q_PROPERTY(bool propagateComposedEvents READ propagateComposedEvents WRITE setPropagateComposedEvents NOTIFY propagateComposedEventsChanged) +#ifndef QT_NO_CURSOR + Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape NOTIFY cursorShapeChanged) +#endif public: QQuickMouseArea(QQuickItem *parent=0); @@ -158,7 +168,9 @@ public: bool hoverEnabled() const; void setHoverEnabled(bool h); +#ifndef QT_NO_DRAGANDDROP QQuickDrag *drag(); +#endif bool preventStealing() const; void setPreventStealing(bool prevent); @@ -166,12 +178,20 @@ public: bool propagateComposedEvents() const; void setPropagateComposedEvents(bool propagate); +#ifndef QT_NO_CURSOR + Qt::CursorShape cursorShape() const; + void setCursorShape(Qt::CursorShape shape); +#endif + Q_SIGNALS: void hoveredChanged(); void pressedChanged(); void enabledChanged(); void acceptedButtonsChanged(); void hoverEnabledChanged(); +#ifndef QT_NO_CURSOR + void cursorShapeChanged(); +#endif void positionChanged(QQuickMouseEvent *mouse); void mouseXChanged(QQuickMouseEvent *mouse); void mouseYChanged(QQuickMouseEvent *mouse); @@ -223,8 +243,10 @@ private: QT_END_NAMESPACE +#ifndef QT_NO_DRAGANDDROP QML_DECLARE_TYPE(QQuickDrag) QML_DECLARE_TYPEINFO(QQuickDrag, QML_HAS_ATTACHED_PROPERTIES) +#endif QML_DECLARE_TYPE(QQuickMouseArea) QT_END_HEADER diff --git a/src/quick/items/qquickmousearea_p_p.h b/src/quick/items/qquickmousearea_p_p.h index d73fb121f9..39a06161b7 100644 --- a/src/quick/items/qquickmousearea_p_p.h +++ b/src/quick/items/qquickmousearea_p_p.h @@ -96,7 +96,9 @@ public: bool doubleClick : 1; bool preventStealing : 1; bool propagateComposedEvents : 1; +#ifndef QT_NO_DRAGANDDROP QQuickDrag *drag; +#endif QPointF startScene; QPointF targetStartPos; QPointF lastPos; @@ -105,6 +107,9 @@ public: Qt::MouseButtons lastButtons; Qt::KeyboardModifiers lastModifiers; QBasicTimer pressAndHoldTimer; +#ifndef QT_NO_CURSOR + QCursor *cursor; +#endif }; QT_END_NAMESPACE diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index f03afd657a..b19b13fec2 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -47,6 +47,8 @@ #include <private/qsgadaptationlayer_p.h> #include "qquicktextnode_p.h" #include "qquickimage_p_p.h" +#include "qquicktextutil_p.h" + #include <QtQuick/private/qsgtexture_p.h> #include <QtQml/qqmlinfo.h> @@ -2011,36 +2013,13 @@ QRectF QQuickText::boundingRect() const Q_D(const QQuickText); QRectF rect = d->layedOutTextRect; + rect.moveLeft(QQuickTextUtil::alignedX(rect, width(), d->hAlign)); + rect.moveTop(QQuickTextUtil::alignedY(rect, height(), d->vAlign)); + if (d->style != Normal) rect.adjust(-1, 0, 1, 2); - // Could include font max left/right bearings to either side of rectangle. - qreal w = width(); - switch (d->hAlign) { - case AlignLeft: - case AlignJustify: - break; - case AlignRight: - rect.moveLeft(w - rect.width()); - break; - case AlignHCenter: - rect.moveLeft((w - rect.width()) / 2); - break; - } - - qreal h = height(); - switch (d->vAlign) { - case AlignTop: - break; - case AlignBottom: - rect.moveTop(h - rect.height()); - break; - case AlignVCenter: - rect.moveTop((h - rect.height()) / 2); - break; - } - return rect; } @@ -2131,7 +2110,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data d->updateType = QQuickTextPrivate::UpdateNone; - QRectF bounds = boundingRect(); + const qreal dy = QQuickTextUtil::alignedY(d->layedOutTextRect, height(), d->vAlign); // We need to make sure the layout is done in the current thread #if defined(Q_OS_MAC) @@ -2156,27 +2135,28 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data if (d->richText) { d->ensureDoc(); - node->addTextDocument(bounds.topLeft(), d->extra->doc, color, d->style, styleColor, linkColor); - } else if (d->elideMode == QQuickText::ElideNone || bounds.width() > 0.) { + const qreal dx = QQuickTextUtil::alignedX(d->layedOutTextRect, width(), d->hAlign); + node->addTextDocument(QPointF(dx, dy), d->extra->doc, color, d->style, styleColor, linkColor); + } else if (d->elideMode == QQuickText::ElideNone || d->layedOutTextRect.width() > 0.) { int unelidedLineCount = d->lineCount; if (d->elideLayout) unelidedLineCount -= 1; if (unelidedLineCount > 0) { node->addTextLayout( - QPoint(0, bounds.y()), + QPoint(0, dy), &d->layout, color, d->style, styleColor, linkColor, QColor(), QColor(), -1, -1, 0, unelidedLineCount); } if (d->elideLayout) - node->addTextLayout(QPoint(0, bounds.y()), d->elideLayout, color, d->style, styleColor, linkColor); + node->addTextLayout(QPoint(0, dy), d->elideLayout, color, d->style, styleColor, linkColor); } foreach (QQuickStyledTextImgTag *img, d->visibleImgTags) { QQuickPixmap *pix = img->pix; if (pix && pix->isReady()) - node->addImage(QRectF(img->pos.x(), img->pos.y() + bounds.y(), pix->width(), pix->height()), pix->image()); + node->addImage(QRectF(img->pos.x(), img->pos.y() + dy, pix->width(), pix->height()), pix->image()); } return node; } @@ -2397,28 +2377,42 @@ void QQuickText::componentComplete() d->updateLayout(); } - -QString QQuickTextPrivate::anchorAt(const QPointF &mousePos) +QString QQuickTextPrivate::anchorAt(const QTextLayout *layout, const QPointF &mousePos) { - if (styledText) { - for (int i = 0; i < layout.lineCount(); ++i) { - QTextLine line = layout.lineAt(i); - if (line.naturalTextRect().contains(mousePos)) { - int charPos = line.xToCursor(mousePos.x()); - foreach (const QTextLayout::FormatRange &formatRange, layout.additionalFormats()) { - if (formatRange.format.isAnchor() - && charPos >= formatRange.start - && charPos <= formatRange.start + formatRange.length) { - return formatRange.format.anchorHref(); - } + for (int i = 0; i < layout->lineCount(); ++i) { + QTextLine line = layout->lineAt(i); + if (line.naturalTextRect().contains(mousePos)) { + int charPos = line.xToCursor(mousePos.x(), QTextLine::CursorOnCharacter); + foreach (const QTextLayout::FormatRange &formatRange, layout->additionalFormats()) { + if (formatRange.format.isAnchor() + && charPos >= formatRange.start + && charPos < formatRange.start + formatRange.length) { + return formatRange.format.anchorHref(); } - break; } + break; } } return QString(); } +QString QQuickTextPrivate::anchorAt(const QPointF &mousePos) const +{ + Q_Q(const QQuickText); + QPointF translatedMousePos = mousePos; + translatedMousePos.ry() -= QQuickTextUtil::alignedY(layedOutTextRect, q->height(), vAlign); + if (styledText) { + QString link = anchorAt(&layout, translatedMousePos); + if (link.isEmpty() && elideLayout) + link = anchorAt(elideLayout, translatedMousePos); + return link; + } else if (richText && extra.isAllocated() && extra->doc) { + translatedMousePos.rx() -= QQuickTextUtil::alignedX(layedOutTextRect, q->width(), hAlign); + return extra->doc->documentLayout()->anchorAt(translatedMousePos); + } + return QString(); +} + bool QQuickTextPrivate::isLinkActivatedConnected() { Q_Q(QQuickText); @@ -2431,14 +2425,8 @@ void QQuickText::mousePressEvent(QMouseEvent *event) Q_D(QQuickText); QString link; - if (d->isLinkActivatedConnected()) { - if (d->styledText) - link = d->anchorAt(event->localPos()); - else if (d->richText) { - d->ensureDoc(); - link = d->extra->doc->documentLayout()->anchorAt(event->localPos()); - } - } + if (d->isLinkActivatedConnected()) + link = d->anchorAt(event->localPos()); if (link.isEmpty()) { event->setAccepted(false); @@ -2450,9 +2438,9 @@ void QQuickText::mousePressEvent(QMouseEvent *event) if (!event->isAccepted()) QQuickItem::mousePressEvent(event); - } + /*! \internal */ void QQuickText::mouseReleaseEvent(QMouseEvent *event) { @@ -2461,14 +2449,8 @@ void QQuickText::mouseReleaseEvent(QMouseEvent *event) // ### confirm the link, and send a signal out QString link; - if (d->isLinkActivatedConnected()) { - if (d->styledText) - link = d->anchorAt(event->localPos()); - else if (d->richText) { - d->ensureDoc(); - link = d->extra->doc->documentLayout()->anchorAt(event->localPos()); - } - } + if (d->isLinkActivatedConnected()) + link = d->anchorAt(event->localPos()); if (!link.isEmpty() && d->extra.isAllocated() && d->extra->activeLink == link) emit linkActivated(d->extra->activeLink); diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h index 2afcd8f369..985b1e1c80 100644 --- a/src/quick/items/qquicktext_p_p.h +++ b/src/quick/items/qquicktext_p_p.h @@ -166,7 +166,8 @@ public: QRectF setupTextLayout(qreal *const naturalWidth, qreal * const baseline); void setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset = 0); bool isLinkActivatedConnected(); - QString anchorAt(const QPointF &pos); + static QString anchorAt(const QTextLayout *layout, const QPointF &mousePos); + QString anchorAt(const QPointF &pos) const; inline qreal lineHeight() const { return extra.isAllocated() ? extra->lineHeight : 1.0; } inline int maximumLineCount() const { return extra.isAllocated() ? extra->maximumLineCount : INT_MAX; } diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 0d05d6f9d7..30512a142b 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -1588,7 +1588,7 @@ void QQuickTextInput::geometryChanged(const QRectF &newGeometry, { Q_D(QQuickTextInput); if (!d->inLayout) { - if (newGeometry.width() != oldGeometry.width() && d->wrapMode != NoWrap) + if (newGeometry.width() != oldGeometry.width()) d->updateLayout(); updateCursorRectangle(); } diff --git a/src/quick/items/qquicktextutil.cpp b/src/quick/items/qquicktextutil.cpp index c2c11b3daa..176301d450 100644 --- a/src/quick/items/qquicktextutil.cpp +++ b/src/quick/items/qquicktextutil.cpp @@ -78,4 +78,37 @@ QQuickItem *QQuickTextUtil::createCursor( return item; } +qreal QQuickTextUtil::alignedX(const QRectF &rect, qreal width, int alignment) +{ + qreal x = 0; + switch (alignment) { + case Qt::AlignLeft: + case Qt::AlignJustify: + break; + case Qt::AlignRight: + x = width - rect.width(); + break; + case Qt::AlignHCenter: + x = (width - rect.width()) / 2; + break; + } + return x; +} + +qreal QQuickTextUtil::alignedY(const QRectF &rect, const qreal height, int alignment) +{ + qreal y = 0; + switch (alignment) { + case Qt::AlignTop: + break; + case Qt::AlignBottom: + y = height - rect.height(); + break; + case Qt::AlignVCenter: + y = (height - rect.height()) / 2; + break; + } + return y; +} + QT_END_NAMESPACE diff --git a/src/quick/items/qquicktextutil_p.h b/src/quick/items/qquicktextutil_p.h index 91ef40b221..d6c05aac3b 100644 --- a/src/quick/items/qquicktextutil_p.h +++ b/src/quick/items/qquicktextutil_p.h @@ -66,12 +66,16 @@ public: template <typename Private> static void setCursorDelegate(Private *d, QQmlComponent *delegate); template <typename Private> static void createCursor(Private *d); + static qreal alignedX(const QRectF &rect, qreal width, int alignment); + static qreal alignedY(const QRectF &rect, qreal height, int alignment); + private: static QQuickItem *createCursor( QQmlComponent *component, QQuickItem *parent, const QRectF &cursorRectangle, const char *className); + }; template <typename Private> diff --git a/src/quick/quick.pro b/src/quick/quick.pro index 29098e4389..7df0491248 100644 --- a/src/quick/quick.pro +++ b/src/quick/quick.pro @@ -17,6 +17,9 @@ exists("qqml_enable_gcov") { load(qt_module_config) +QMAKE_DOCS = $$PWD/doc/qtquick.qdocconf +QMAKE_DOCS_INDEX = ../../doc + # private dependencies QT += v8-private network |