diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-05-13 22:12:48 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-05-13 22:12:48 +0200 |
commit | bf332f213bce8ee4d139572baf0934620f5d8103 (patch) | |
tree | 4706f8378a16910999d3d6bbb6d1ab9cbf232a14 | |
parent | cf7166e266e20d3da940b9f58d8631d23cc38482 (diff) | |
parent | c4a8d4a747559433e94d4af56c810ef86244d91f (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Change-Id: I24827851643247b938b3a1b7182864293e5c3fe7
25 files changed, 283 insertions, 469 deletions
diff --git a/examples/quick/demos/photosurface/doc/src/photosurface.qdoc b/examples/quick/demos/photosurface/doc/src/photosurface.qdoc index d56b34365d..b66143368e 100644 --- a/examples/quick/demos/photosurface/doc/src/photosurface.qdoc +++ b/examples/quick/demos/photosurface/doc/src/photosurface.qdoc @@ -29,13 +29,135 @@ \title Qt Quick Demo - Photo Surface \ingroup qtquickdemos \example demos/photosurface - \brief A touch-based app for shuffling photos around a virtual surface. + \brief A QML app for touch devices that uses a Repeater with a + FolderListModel to access content in a folder, and a PinchArea that contains + a MouseArea to handle pinch gestures on the fetched content. \image qtquick-demo-photosurface-small.png - \e{Photo Surface} demonstrates how to handle dragging, rotation and pinch - zooming within the same item using a \l PinchArea containing a \l MouseArea. + \e{Photo Surface} demonstrates how to use a \l{Repeater} with a + FolderListModel and a FileDialog to access images from a folder selected + by a user and how to handle dragging, rotation and pinch zooming within the + same item using a \l PinchArea that contains a \l MouseArea. + + All the app code is contained in one QML file, photosurface.qml. Inline + JavaScript code is used to place, rotate, and scale images on the photo + surface. \include examples-run.qdocinc - \sa {QML Applications} + \section1 Creating the Main Window + + To create the main window for the Photo Surface app, we use the \l{Window} + QML type as the root item. It automatically sets up the window for use with + \l{Qt Quick} graphical types: + + \quotefromfile demos/photosurface/photosurface.qml + \skipto Window { + \printuntil defaultSize + + To use the \l{Window} type, we must import it: + + \code + import QtQuick.Window 2.1 + \endcode + + \section1 Accessing Folder Contents + + We use a \l{Repeater} QML type together with the FolderListModel to display + GIF, JPG, and PNG images located in a folder: + + \quotefromfile demos/photosurface/photosurface.qml + \skipto Repeater + \printuntil } + + To use the FolderListModel type, we must import it: + + \code + import Qt.labs.folderlistmodel 1.0 + \endcode + + We use a FileDialog to enable users to select the folder that contains + the images: + + \quotefromfile demos/photosurface/photosurface.qml + \skipto FileDialog + \printuntil } + + To use the FileDialog type, we must import \l{Qt Quick Dialogs}: + + \code + import QtQuick.Dialogs 1.0 + \endcode + + We use the \c {fileDialog.open()} function to open the file dialog when the + app starts: + + \code + Component.onCompleted: fileDialog.open() + \endcode + + Users can also click the file dialog icon to open the file dialog. We use + an \l{Image} QML type to display the icon. Inside the \l{Image} type, we + use a MouseArea with the \c onClicked signal handler to call the + \c {fileDialog.open()} function: + + \quotefromfile demos/photosurface/photosurface.qml + \skipuntil Image { + \skipto Image { + \printuntil } + \printuntil } + + \section1 Displaying Images on the Photo Surface + + We use a \l{Rectangle} as a delegate for a \l{Repeater} to provide a frame + for each image that the FolderListModel finds in the selected folder. We use + JavaScript \c Math() methods to place the frames randomly on the photo + surface and to rotate them at random angles, as well as to scale the images: + + \quotefromfile demos/photosurface/photosurface.qml + \skipto Rectangle + \printuntil } + + \section1 Handling Pinch Gestures + + We use a PinchArea that contains a MouseArea in the photo frames to handle + dragging, rotation and pinch zooming of the frame: + + \quotefromfile demos/photosurface/photosurface.qml + \skipto PinchArea + \printuntil onPinchFinished + + We use the \c pinch group property to control how the photo frames react to + pinch gestures. The \c pinch.target sets \c photoFrame as the item to + manipulate. The rotation properties specify that the frames can be rotated + at all angles and the scale properties specify that they can be scaled + between \c 0.1 and \c 10. + + In the MouseArea's \c onPressed signal handler, we raise the selected photo + frame to the top by increasing the value of its \c z property. The root item + stores the z value of the top-most frame. The border color of the photo + frame is controlled in the \c onEntered and \c onExited signal handlers to + highlight the selected image. + + \quotefromfile demos/photosurface/photosurface.qml + \skipto MouseArea + \printuntil onExited + + To enable you to test the example on the desktop, we use the MouseArea's + \c onWheel signal handler to simulate pinch gestures by using a mouse: + + \quotefromfile demos/photosurface/photosurface.qml + \skipto onWheel + \printuntil photoFrame.y + \printuntil } + \printuntil } + \printuntil } + + The \c onWheel signal handler is called in response to mouse wheel gestures. + Use the vertical wheel to zoom and Ctrl and the vertical wheel to rotate + frames. If the mouse has a horizontal wheel, use it to rotate frames. + + \section1 List of Files + + \sa {QML Applications} */ diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h index 398d5d5fa0..9eff90dd30 100644 --- a/src/qml/compiler/qv4jsir_p.h +++ b/src/qml/compiler/qv4jsir_p.h @@ -773,8 +773,6 @@ public: BasicBlock *catchBlock; QVector<BasicBlock *> in; QVector<BasicBlock *> out; - QBitArray liveIn; - QBitArray liveOut; QQmlJS::AST::SourceLocation nextLocation; BasicBlock(Function *function, BasicBlock *containingLoop, BasicBlock *catcher) @@ -785,7 +783,10 @@ public: , _isExceptionHandler(false) , _groupStart(false) , _isRemoved(false) - {} + { + in.reserve(2); + out.reserve(2); + } ~BasicBlock(); const QVector<Stmt *> &statements() const diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri index 5f3aec1c9a..2545c7836d 100644 --- a/src/qml/debugger/debugger.pri +++ b/src/qml/debugger/debugger.pri @@ -3,7 +3,6 @@ SOURCES += \ $$PWD/qqmlprofilerservice.cpp \ $$PWD/qqmldebugserver.cpp \ $$PWD/qqmlinspectorservice.cpp \ - $$PWD/qv4profilerservice.cpp \ $$PWD/qqmlenginedebugservice.cpp \ $$PWD/qdebugmessageservice.cpp \ $$PWD/qv4debugservice.cpp \ @@ -22,7 +21,6 @@ HEADERS += \ $$PWD/qqmldebugstatesdelegate_p.h \ $$PWD/qqmlinspectorservice_p.h \ $$PWD/qqmlinspectorinterface_p.h \ - $$PWD/qv4profilerservice_p.h \ $$PWD/qqmlenginedebugservice_p.h \ $$PWD/qqmldebug.h \ $$PWD/qdebugmessageservice_p.h \ diff --git a/src/qml/debugger/qqmldebugserver.cpp b/src/qml/debugger/qqmldebugserver.cpp index b1eb130ee8..0a99030897 100644 --- a/src/qml/debugger/qqmldebugserver.cpp +++ b/src/qml/debugger/qqmldebugserver.cpp @@ -44,7 +44,6 @@ #include "qqmldebugservice_p_p.h" #include "qqmlenginedebugservice_p.h" #include "qv4debugservice_p.h" -#include "qv4profilerservice_p.h" #include "qdebugmessageservice_p.h" #include "qqmlprofilerservice_p.h" diff --git a/src/qml/debugger/qv4profilerservice.cpp b/src/qml/debugger/qv4profilerservice.cpp deleted file mode 100644 index d8f69aecd9..0000000000 --- a/src/qml/debugger/qv4profilerservice.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv4profilerservice_p.h" -#include "qqmlconfigurabledebugservice_p_p.h" - -#include <QtCore/QHash> -#include <QtCore/QMutex> -#include <QtCore/QWaitCondition> - -QT_BEGIN_NAMESPACE - -Q_GLOBAL_STATIC(QV4ProfilerService, v4ProfilerInstance) - -#if 0 -// ### FIXME: v4 -class DebugServiceOutputStream : public v8::OutputStream -{ -public: - DebugServiceOutputStream() - : v8::OutputStream() {} - void EndOfStream() {} - WriteResult WriteAsciiChunk(char *rawData, int size) - { - QByteArray data; - QQmlDebugStream ds(&data, QIODevice::WriteOnly); - ds << QV4ProfilerService::V4SnapshotChunk << QByteArray(rawData, size); - messages.append(data); - return kContinue; - } - QList<QByteArray> messages; -}; -#endif - -// convert to a QByteArray that can be sent to the debug client -QByteArray QV4ProfilerData::toByteArray() const -{ - QByteArray data; - //### using QDataStream is relatively expensive - QQmlDebugStream ds(&data, QIODevice::WriteOnly); - ds << messageType << filename << functionname << lineNumber << totalTime << selfTime << treeLevel; - - return data; -} - -class QV4ProfilerServicePrivate : public QQmlConfigurableDebugServicePrivate -{ - Q_DECLARE_PUBLIC(QV4ProfilerService) - -public: - QV4ProfilerServicePrivate() - :initialized(false) - { - } - - // ### FIXME: v4 -// void takeSnapshot(v8::HeapSnapshot::Type); -// void printProfileTree(const v8::CpuProfileNode *node, int level = 0); -// void sendMessages(); - - QList<QV4ProfilerData> m_data; - - bool initialized; - QList<QString> m_ongoing; -}; - -QV4ProfilerService::QV4ProfilerService(QObject *parent) - : QQmlConfigurableDebugService(*(new QV4ProfilerServicePrivate()), QStringLiteral("V8Profiler"), 1, parent) -{ -} - -QV4ProfilerService::~QV4ProfilerService() -{ -} - -QV4ProfilerService *QV4ProfilerService::instance() -{ - return v4ProfilerInstance(); -} - -void QV4ProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState) -{ - Q_D(QV4ProfilerService); - QMutexLocker lock(configMutex()); - - if (state() == newState) - return; - - if (state() == Enabled) { - foreach (const QString &title, d->m_ongoing) { - QMetaObject::invokeMethod(this, "stopProfiling", Qt::BlockingQueuedConnection, - Q_ARG(QString, title)); - } - QMetaObject::invokeMethod(this, "sendProfilingData", Qt::BlockingQueuedConnection); - } -} - -void QV4ProfilerService::messageReceived(const QByteArray &message) -{ - Q_D(QV4ProfilerService); - - QQmlDebugStream ds(message); - QByteArray command; - QByteArray option; - QByteArray title; - ds >> command >> option; - - QMutexLocker lock(configMutex()); - - if (command == "V8PROFILER") { - ds >> title; - QString titleStr = QString::fromUtf8(title); - if (option == "start") { - QMetaObject::invokeMethod(this, "startProfiling", Qt::QueuedConnection, Q_ARG(QString, titleStr)); - } else if (option == "stop" && d->initialized) { - QMetaObject::invokeMethod(this, "stopProfiling", Qt::QueuedConnection, Q_ARG(QString, titleStr)); - QMetaObject::invokeMethod(this, "sendProfilingData", Qt::QueuedConnection); - } - d->initialized = true; - } - - if (command == "V8SNAPSHOT") { - if (option == "full") - QMetaObject::invokeMethod(this, "takeSnapshot", Qt::QueuedConnection); - else if (option == "delete") { - QMetaObject::invokeMethod(this, "deleteSnapshots", Qt::QueuedConnection); - } - } - - // wake up constructor in blocking mode - stopWaiting(); - - QQmlDebugService::messageReceived(message); -} - -void QV4ProfilerService::startProfiling(const QString &title) -{ - Q_D(QV4ProfilerService); - // Start Profiling - - if (d->m_ongoing.contains(title)) - return; - -// v8::Handle<v8::String> v8title = v8::String::New(reinterpret_cast<const uint16_t*>(title.data()), title.size()); - // ### FIXME: v4 -// v8::CpuProfiler::StartProfiling(v8title); - - d->m_ongoing.append(title); - - // indicate profiling started - QByteArray data; - QQmlDebugStream ds(&data, QIODevice::WriteOnly); - ds << (int)QV4ProfilerService::V4Started; - - sendMessage(data); -} - -void QV4ProfilerService::stopProfiling(const QString &title) -{ - Q_D(QV4ProfilerService); - // Stop profiling - - if (!d->m_ongoing.contains(title)) - return; - d->m_ongoing.removeOne(title); - -#if 0 - // ### FIXME: v4 - v8::HandleScope handle_scope; - v8::Handle<v8::String> v8title = v8::String::New(reinterpret_cast<const uint16_t*>(title.data()), title.size()); - const v8::CpuProfile *cpuProfile = v8::CpuProfiler::StopProfiling(v8title); - if (cpuProfile) { - // can happen at start - const v8::CpuProfileNode *rootNode = cpuProfile->GetTopDownRoot(); - d->printProfileTree(rootNode); - } else { -#endif - // indicate completion, even without data - QByteArray data; - QQmlDebugStream ds(&data, QIODevice::WriteOnly); - ds << (int)QV4ProfilerService::V4Complete; - - sendMessage(data); -#if 0 - } -#endif -} - -void QV4ProfilerService::takeSnapshot() -{ -// Q_D(QV4ProfilerService); - // ### FIXME: v4 -// d->takeSnapshot(v8::HeapSnapshot::kFull); -} - -void QV4ProfilerService::deleteSnapshots() -{ - // ### FIXME: v4 -// v8::HeapProfiler::DeleteAllSnapshots(); -} - -void QV4ProfilerService::sendProfilingData() -{ -// Q_D(QV4ProfilerService); - // Send messages to client - // ### FIXME: v4 -// d->sendMessages(); -} - -#if 0 -// ### FIXME: v4 -void QV4ProfilerServicePrivate::printProfileTree(const v8::CpuProfileNode *node, int level) -{ - for (int index = 0 ; index < node->GetChildrenCount() ; index++) { - const v8::CpuProfileNode* childNode = node->GetChild(index); - QString scriptResourceName = QJSConverter::toString(childNode->GetScriptResourceName()); - if (scriptResourceName.length() > 0) { - - QV4ProfilerData rd = {(int)QV4ProfilerService::V4Entry, scriptResourceName, - QJSConverter::toString(childNode->GetFunctionName()), - childNode->GetLineNumber(), childNode->GetTotalTime(), childNode->GetSelfTime(), level}; - m_data.append(rd); - - // different nodes might have common children: fix at client side - if (childNode->GetChildrenCount() > 0) { - printProfileTree(childNode, level+1); - } - } - } -} - -void QV4ProfilerServicePrivate::takeSnapshot(v8::HeapSnapshot::Type snapshotType) -{ - Q_Q(QV4ProfilerService); - - v8::HandleScope scope; - v8::Handle<v8::String> title = v8::String::New(""); - - DebugServiceOutputStream outputStream; - const v8::HeapSnapshot *snapshot = v8::HeapProfiler::TakeSnapshot(title, snapshotType); - snapshot->Serialize(&outputStream, v8::HeapSnapshot::kJSON); - QList<QByteArray> messages = outputStream.messages; - - //indicate completion - QByteArray data; - QQmlDebugStream ds(&data, QIODevice::WriteOnly); - ds << (int)QV4ProfilerService::V4SnapshotComplete; - messages.append(data); - - q->sendMessages(messages); -} - -void QV4ProfilerServicePrivate::sendMessages() -{ - Q_Q(QV4ProfilerService); - - QList<QByteArray> messages; - for (int i = 0; i < m_data.count(); ++i) - messages.append(m_data.at(i).toByteArray()); - m_data.clear(); - - //indicate completion - QByteArray data; - QQmlDebugStream ds(&data, QIODevice::WriteOnly); - ds << (int)QV4ProfilerService::V4Complete; - messages.append(data); - - q->sendMessages(messages); -} -#endif - -QT_END_NAMESPACE diff --git a/src/qml/debugger/qv4profilerservice_p.h b/src/qml/debugger/qv4profilerservice_p.h deleted file mode 100644 index b1a58dae03..0000000000 --- a/src/qml/debugger/qv4profilerservice_p.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV4PROFILERSERVICE_P_H -#define QV4PROFILERSERVICE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qqmlconfigurabledebugservice_p.h> - -QT_BEGIN_NAMESPACE - - -struct Q_AUTOTEST_EXPORT QV4ProfilerData -{ - int messageType; - QString filename; - QString functionname; - int lineNumber; - double totalTime; - double selfTime; - int treeLevel; - - QByteArray toByteArray() const; -}; - -class QQmlEngine; -class QV4ProfilerServicePrivate; - -class Q_AUTOTEST_EXPORT QV4ProfilerService : public QQmlConfigurableDebugService -{ - Q_OBJECT -public: - enum MessageType { - V4Entry, - V4Complete, - V4SnapshotChunk, - V4SnapshotComplete, - V4Started, - - V4MaximumMessage - }; - - QV4ProfilerService(QObject *parent = 0); - ~QV4ProfilerService(); - - static QV4ProfilerService *instance(); - -public Q_SLOTS: - void startProfiling(const QString &title); - void stopProfiling(const QString &title); - void takeSnapshot(); - void deleteSnapshots(); - - void sendProfilingData(); - -protected: - void stateAboutToBeChanged(State state); - void messageReceived(const QByteArray &); - -private: - Q_DISABLE_COPY(QV4ProfilerService) - Q_DECLARE_PRIVATE(QV4ProfilerService) -}; - -QT_END_NAMESPACE - -#endif // QV4PROFILERSERVICE_P_H diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index d378d77bb0..610bbcfe1e 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -69,7 +69,6 @@ #include <private/qqmlenginecontrolservice_p.h> #include "qqmlincubator.h" #include "qqmlabstracturlinterceptor.h" -#include <private/qv4profilerservice_p.h> #include <private/qqmlboundsignal_p.h> #include <QtCore/qstandardpaths.h> @@ -823,7 +822,6 @@ void QQmlEnginePrivate::init() isDebugging = true; QQmlEngineDebugService::instance(); QV4DebugService::instance(); - QV4ProfilerService::instance(); QQmlProfilerService::instance(); QDebugMessageService::instance(); QQmlEngineControlService::instance(); diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 5e0e68472d..0bb77d8077 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -48,7 +48,6 @@ #include <private/qqmllocale_p.h> #include <private/qv8engine_p.h> -#include <private/qv4profilerservice_p.h> #include <private/qqmlprofilerservice_p.h> #include <private/qqmlglobal_p.h> diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index be479ee17d..4591d42710 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -1521,9 +1521,64 @@ void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelInd _q_itemsChanged(begin.row(), end.row() - begin.row() + 1, roles); } -void QQmlDelegateModel::_q_layoutChanged() +void QQmlDelegateModel::_q_layoutAboutToBeChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint) { - _q_modelReset(); + Q_D(QQmlDelegateModel); + if (!d->m_complete) + return; + + if (hint == QAbstractItemModel::VerticalSortHint) { + d->m_storedPersistentIndexes.clear(); + if (!parents.contains(d->m_adaptorModel.rootIndex)) + return; + + for (int i = 0; i < d->m_count; ++i) { + const QModelIndex index = d->m_adaptorModel.aim()->index(i, 0, d->m_adaptorModel.rootIndex); + d->m_storedPersistentIndexes.append(index); + } + } else if (hint == QAbstractItemModel::HorizontalSortHint) { + // Ignored + } else { + // Triggers model reset, no preparations for that are needed + } +} + +void QQmlDelegateModel::_q_layoutChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint) +{ + Q_D(QQmlDelegateModel); + if (!d->m_complete) + return; + + if (hint == QAbstractItemModel::VerticalSortHint) { + if (!parents.contains(d->m_adaptorModel.rootIndex)) + return; + + for (int i = 0, c = d->m_storedPersistentIndexes.count(); i < c; ++i) { + const QPersistentModelIndex &index = d->m_storedPersistentIndexes.at(i); + if (i == index.row()) + continue; + + QVector<Compositor::Insert> inserts; + QVector<Compositor::Remove> removes; + d->m_compositor.listItemsMoved(&d->m_adaptorModel, i, index.row(), 1, &removes, &inserts); + if (!removes.isEmpty() || !inserts.isEmpty()) { + d->itemsMoved(removes, inserts); + } + } + + d->m_storedPersistentIndexes.clear(); + + // layoutUpdate does not necessarily have any move changes, but it can + // also mean data changes. We can't detect what exactly has changed, so + // just emit it for all items + _q_itemsChanged(0, d->m_count, QVector<int>()); + + } else if (hint == QAbstractItemModel::HorizontalSortHint) { + // Ignored + } else { + // We don't know what's going on, so reset the model + _q_modelReset(); + } } QQmlDelegateModelAttached *QQmlDelegateModel::qmlAttachedProperties(QObject *obj) diff --git a/src/qml/types/qqmldelegatemodel_p.h b/src/qml/types/qqmldelegatemodel_p.h index 51f846ea0b..0b67179163 100644 --- a/src/qml/types/qqmldelegatemodel_p.h +++ b/src/qml/types/qqmldelegatemodel_p.h @@ -139,7 +139,8 @@ private Q_SLOTS: void _q_rowsRemoved(const QModelIndex &,int,int); void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int); void _q_dataChanged(const QModelIndex&,const QModelIndex&,const QVector<int> &); - void _q_layoutChanged(); + void _q_layoutAboutToBeChanged(const QList<QPersistentModelIndex>&, QAbstractItemModel::LayoutChangeHint); + void _q_layoutChanged(const QList<QPersistentModelIndex>&, QAbstractItemModel::LayoutChangeHint); private: Q_DISABLE_COPY(QQmlDelegateModel) diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h index 7da089c9b8..d64f641a1b 100644 --- a/src/qml/types/qqmldelegatemodel_p_p.h +++ b/src/qml/types/qqmldelegatemodel_p_p.h @@ -331,6 +331,8 @@ public: }; QQmlDelegateModelGroup *m_groups[Compositor::MaximumGroupCount]; }; + + QList<QPersistentModelIndex> m_storedPersistentIndexes; }; class QQmlPartsModel : public QQmlInstanceModel, public QQmlDelegateModelGroupEmitter diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp index d38e5ac3df..c1c8bfa81d 100644 --- a/src/qml/util/qqmladaptormodel.cpp +++ b/src/qml/util/qqmladaptormodel.cpp @@ -467,8 +467,10 @@ public: vdm, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int))); QObject::disconnect(aim, SIGNAL(modelReset()), vdm, SLOT(_q_modelReset())); - QObject::disconnect(aim, SIGNAL(layoutChanged()), - vdm, SLOT(_q_layoutChanged())); + QObject::disconnect(aim, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)), + vdm, SLOT(_q_layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint))); + QObject::disconnect(aim, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)), + vdm, SLOT(_q_layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint))); } const_cast<VDMAbstractItemModelDataType *>(this)->release(); @@ -920,8 +922,10 @@ void QQmlAdaptorModel::setModel(const QVariant &variant, QQmlDelegateModel *vdm, vdm, QQmlDelegateModel, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int))); qmlobject_connect(model, QAbstractItemModel, SIGNAL(modelReset()), vdm, QQmlDelegateModel, SLOT(_q_modelReset())); - qmlobject_connect(model, QAbstractItemModel, SIGNAL(layoutChanged()), - vdm, QQmlDelegateModel, SLOT(_q_layoutChanged())); + qmlobject_connect(model, QAbstractItemModel, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)), + vdm, QQmlDelegateModel, SLOT(_q_layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint))); + qmlobject_connect(model, QAbstractItemModel, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)), + vdm, QQmlDelegateModel, SLOT(_q_layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint))); } else { accessors = new VDMObjectDelegateDataType; } diff --git a/src/qmldevtools/qmldevtools.pro b/src/qmldevtools/qmldevtools.pro index 25d6494558..5af5443df7 100644 --- a/src/qmldevtools/qmldevtools.pro +++ b/src/qmldevtools/qmldevtools.pro @@ -10,6 +10,12 @@ MODULE_PRIVATE_INCLUDES = \ \$\$QT_MODULE_INCLUDE_BASE/QtQml/$$QT.qml.VERSION \ \$\$QT_MODULE_INCLUDE_BASE/QtQml/$$QT.qml.VERSION/QtQml +# 2415: variable "xx" of static storage duration was declared but never referenced +# unused variable 'xx' [-Werror,-Wunused-const-variable] +intel_icc: WERROR += -ww2415 +clang:if(greaterThan(QT_CLANG_MAJOR_VERSION, 3)|greaterThan(QT_CLANG_MINOR_VERSION, 3)): \ + WERROR += -Wno-error=unused-const-variable + load(qt_module) include(../3rdparty/masm/masm-defs.pri) diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index 82658c73fc..2c03903f36 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -1524,7 +1524,7 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight) This property determines whether delegates are retained outside the visible area of the view. - If non-zero the view may keep as many delegates + If this value is greater than zero, the view may keep as many delegates instantiated as will fit within the buffer specified. For example, if in a vertical view the delegate is 20 pixels high, there are 3 columns and \c cacheBuffer is @@ -1535,7 +1535,7 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight) delegates outside the visible area are not painted. The default value of this property is platform dependent, but will usually - be a non-zero value. + be a value greater than zero. Negative values are ignored. Note that cacheBuffer is not a pixel buffer - it only maintains additional instantiated delegates. diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index b4f6c34c6a..87e6728f86 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -454,6 +454,11 @@ int QQuickItemView::cacheBuffer() const void QQuickItemView::setCacheBuffer(int b) { Q_D(QQuickItemView); + if (b < 0) { + qmlInfo(this) << "Cannot set a negative cache buffer"; + return; + } + if (d->buffer != b) { d->buffer = b; if (isComponentComplete()) { diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 8f9dbb567f..ba4f1c53ba 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -2138,7 +2138,7 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation) This property determines whether delegates are retained outside the visible area of the view. - If this value is non-zero, the view may keep as many delegates + If this value is greater than zero, the view may keep as many delegates instantiated as it can fit within the buffer specified. For example, if in a vertical view the delegate is 20 pixels high and \c cacheBuffer is set to 40, then up to 2 delegates above and 2 delegates below the visible @@ -2148,7 +2148,7 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation) delegates outside the visible area are not painted. The default value of this property is platform dependent, but will usually - be a non-zero value. + be a value greater than zero. Negative values are ignored. Note that cacheBuffer is not a pixel buffer - it only maintains additional instantiated delegates. diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 312cd483e2..cbdea3917a 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -2359,7 +2359,7 @@ void QQuickText::setLineHeightMode(LineHeightMode mode) within the width of the item without wrapping is used. \li Text.VerticalFit - The largest size up to the size specified that fits the height of the item is used. - \li Text.Fit - The largest size up to the size specified the fits within the + \li Text.Fit - The largest size up to the size specified that fits within the width and height of the item is used. \endlist diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index 3c4d0d4b42..5280301675 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -1709,9 +1709,9 @@ void QQuickTextEdit::inputMethodEvent(QInputMethodEvent *event) /*! \overload -Returns the value of the given \a property. +Returns the value of the given \a property and \a argument. */ -QVariant QQuickTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const +QVariant QQuickTextEdit::inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const { Q_D(const QQuickTextEdit); @@ -1724,11 +1724,19 @@ QVariant QQuickTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const v = (int)d->effectiveInputMethodHints(); break; default: - v = d->control->inputMethodQuery(property); + v = d->control->inputMethodQuery(property, argument); break; } return v; +} +/*! +\overload +Returns the value of the given \a property. +*/ +QVariant QQuickTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const +{ + return inputMethodQuery(property, QVariant()); } #endif // QT_NO_IM diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h index c6b7ce3699..614effd4c9 100644 --- a/src/quick/items/qquicktextedit_p.h +++ b/src/quick/items/qquicktextedit_p.h @@ -229,6 +229,7 @@ public: #ifndef QT_NO_IM QVariant inputMethodQuery(Qt::InputMethodQuery property) const; + Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const; #endif qreal contentWidth() const; diff --git a/src/quick/items/qquicktextnode.cpp b/src/quick/items/qquicktextnode.cpp index 1133636a74..da0d9cd714 100644 --- a/src/quick/items/qquicktextnode.cpp +++ b/src/quick/items/qquicktextnode.cpp @@ -144,8 +144,15 @@ QSGGlyphNode *QQuickTextNode::addGlyphs(const QPointF &position, const QGlyphRun { QSGRenderContext *sg = QQuickItemPrivate::get(m_ownerElement)->sceneGraphRenderContext(); QRawFont font = glyphs.rawFont(); - bool smoothScalable = QFontDatabase().isSmoothlyScalable(font.familyName(), font.styleName()); - bool preferNativeGlyphNode = m_useNativeRenderer || !smoothScalable; + bool preferNativeGlyphNode = m_useNativeRenderer; + if (!preferNativeGlyphNode) { + QRawFontPrivate *fontPriv = QRawFontPrivate::get(font); + if (fontPriv->fontEngine->hasUnreliableGlyphOutline()) + preferNativeGlyphNode = true; + else + preferNativeGlyphNode = !QFontDatabase().isSmoothlyScalable(font.familyName(), font.styleName()); + } + QSGGlyphNode *node = sg->sceneGraphContext()->createGlyphNode(sg, preferNativeGlyphNode); node->setOwnerElement(m_ownerElement); diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index 1786317356..1a631703fb 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -102,7 +102,7 @@ QT_BEGIN_NAMESPACE \note PropertyChanges can be used to change anchor margins, but not other anchor values; use AnchorChanges for this instead. Similarly, to change an \l Item's - \l {Item::}{parent} value, use ParentChanges instead. + \l {Item::}{parent} value, use ParentChange instead. \section2 Resetting property values diff --git a/src/src.pro b/src/src.pro index 0f09f34211..ac48f017e6 100644 --- a/src/src.pro +++ b/src/src.pro @@ -8,6 +8,8 @@ qtHaveModule(gui):contains(QT_CONFIG, opengl(es1|es2)?) { quick \ qmltest \ particles + + qtHaveModule(widgets): SUBDIRS += quickwidgets } SUBDIRS += \ @@ -15,6 +17,4 @@ SUBDIRS += \ imports \ qmldevtools -qtHaveModule(quick):qtHaveModule(widgets): SUBDIRS += quickwidgets - qmldevtools.CONFIG = host_build diff --git a/tests/auto/qmltest/textedit/tst_textedit.qml b/tests/auto/qmltest/textedit/tst_textedit.qml index eb53eaa604..1dc7084049 100644 --- a/tests/auto/qmltest/textedit/tst_textedit.qml +++ b/tests/auto/qmltest/textedit/tst_textedit.qml @@ -43,6 +43,8 @@ import QtTest 1.0 Item { id: top + height: 30 + width: 60 TextEdit { id: emptyText @@ -82,6 +84,13 @@ Item { TextEdit { id: txtfunctions + text: "The quick brown fox" + height: 20 + width: 50 + } + + TextEdit { + id: txtclipboard text: "The quick brown fox jumped over the lazy dog" height: 20 width: 50 @@ -148,31 +157,51 @@ Item { compare(txtentry2.text, "hello World") } - function test_functions() { + function test_select_insert() { compare(txtfunctions.getText(4,9), "quick") txtfunctions.select(4,9); compare(txtfunctions.selectedText, "quick") + txtfunctions.insert(4, "very ") + compare(txtfunctions.text, "The very quick brown fox") txtfunctions.deselect(); compare(txtfunctions.selectedText, "") - txtfunctions.select(4,9); - txtfunctions.cut(); - compare(txtfunctions.text, "The brown fox jumped over the lazy dog") txtfunctions.text = "Qt"; txtfunctions.insert(txtfunctions.text.length, " ") compare(txtfunctions.text, "Qt "); - txtfunctions.cursorPosition = txtfunctions.text.length; - txtfunctions.paste(); + txtfunctions.insert(txtfunctions.text.length, "quick") compare(txtfunctions.text, "Qt quick"); txtfunctions.cursorPosition = txtfunctions.text.length; txtfunctions.selectWord(); compare(txtfunctions.selectedText, "quick") - txtfunctions.copy(); txtfunctions.selectAll(); compare(txtfunctions.selectedText, "Qt quick") txtfunctions.deselect(); compare(txtfunctions.selectedText, "") - txtfunctions.paste(); - compare(txtfunctions.text, "Qt quickquick"); + } + + function test_clipboard() { + if (typeof(txtclipboard.copy) !== "function" + || typeof(txtclipboard.paste) !== "function" + || typeof(txtclipboard.cut) !== "function") { + skip("Clipboard is not supported on this platform.") + } + txtclipboard.select(4,10); + txtclipboard.cut(); + compare(txtclipboard.text, "The brown fox jumped over the lazy dog") + txtclipboard.select(30,35) + txtclipboard.paste(); + compare(txtclipboard.text, "The brown fox jumped over the quick dog") + txtclipboard.text = "Qt "; + txtclipboard.cursorPosition = txtclipboard.text.length; + txtclipboard.paste(); + compare(txtclipboard.text, "Qt quick "); + txtclipboard.cursorPosition = txtclipboard.text.length-1; + txtclipboard.selectWord(); + compare(txtclipboard.selectedText, "quick") + txtclipboard.copy(); + txtclipboard.cursorPosition = txtclipboard.text.length; + txtclipboard.paste(); + compare(txtclipboard.text, "Qt quick quick"); } function test_linecounts() { diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 29755e3890..5cc3c7e642 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -3012,6 +3012,10 @@ void tst_QQuickListView::cacheBuffer() controller.incubateWhile(&b); } + // negative cache buffer is ignored + listview->setCacheBuffer(-1); + QCOMPARE(listview->cacheBuffer(), 200); + delete window; delete testObject; } diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index 3fa36ad8f7..1c349d8538 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -264,8 +264,8 @@ void printUsage() printf("Any argument ending in .qml will be treated as a QML file to be loaded.\n"); printf("Any number of QML files can be loaded. They will share the same engine.\n"); printf("Any argument which is not a recognized option and which does not end in .qml will be ignored.\n"); - printf("'gui' application type is only available if the QtGui module is avaialble.\n"); - printf("'widget' application type is only available if the QtWidgets module is avaialble.\n"); + printf("'gui' application type is only available if the QtGui module is available.\n"); + printf("'widget' application type is only available if the QtWidgets module is available.\n"); printf("\n"); printf("General Options:\n"); printf("\t-h, -help..................... Print this usage information and exit.\n"); |