From a4e8b396bf6e4b4531b4bcf7b7901cfcd0002219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 24 Aug 2010 11:07:28 +0200 Subject: Adding placeholder for internal QFileSystemEntry class Reviewed-by: Thomas Zander --- src/corelib/io/io.pri | 6 ++-- src/corelib/io/qfilesystementry.cpp | 41 ++++++++++++++++++++++++ src/corelib/io/qfilesystementry_p.h | 64 +++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 src/corelib/io/qfilesystementry.cpp create mode 100644 src/corelib/io/qfilesystementry_p.h diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 3d964c6..bb38f42 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -29,7 +29,8 @@ HEADERS += \ io/qfsfileengine_p.h \ io/qfsfileengine_iterator_p.h \ io/qfilesystemwatcher.h \ - io/qfilesystemwatcher_p.h + io/qfilesystemwatcher_p.h \ + io/qfilesystementry_p.h SOURCES += \ io/qabstractfileengine.cpp \ @@ -52,7 +53,8 @@ SOURCES += \ io/qsettings.cpp \ io/qfsfileengine.cpp \ io/qfsfileengine_iterator.cpp \ - io/qfilesystemwatcher.cpp + io/qfilesystemwatcher.cpp \ + io/qfilesystementry.cpp win32 { SOURCES += io/qsettings_win.cpp diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp new file mode 100644 index 0000000..36ec012 --- /dev/null +++ b/src/corelib/io/qfilesystementry.cpp @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h new file mode 100644 index 0000000..2054f62 --- /dev/null +++ b/src/corelib/io/qfilesystementry_p.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef QFILESYSTEMENTRY_P_H_INCLUDED +#define QFILESYSTEMENTRY_P_H_INCLUDED + +// +// 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. +// + +QT_BEGIN_NAMESPACE + +class QFileSystemEntry +{ +}; + +QT_END_NAMESPACE + +#endif // include guard -- cgit v0.12 From 68f5623c6efcc76163fc3c5f8154aecf90c618f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 24 Aug 2010 11:18:35 +0200 Subject: Adding internal classes QFileSystem{Engine,MetaData} Empty for now. Reviewed-by: Thomas Zander --- src/corelib/io/io.pri | 4 ++- src/corelib/io/qfilesystemengine_p.h | 64 ++++++++++++++++++++++++++++++++++ src/corelib/io/qfilesystemmetadata_p.h | 64 ++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 src/corelib/io/qfilesystemengine_p.h create mode 100644 src/corelib/io/qfilesystemmetadata_p.h diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index bb38f42..0334534 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -30,7 +30,9 @@ HEADERS += \ io/qfsfileengine_iterator_p.h \ io/qfilesystemwatcher.h \ io/qfilesystemwatcher_p.h \ - io/qfilesystementry_p.h + io/qfilesystementry_p.h \ + io/qfilesystemengine_p.h \ + io/qfilesystemmetadata_p.h SOURCES += \ io/qabstractfileengine.cpp \ diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h new file mode 100644 index 0000000..817f925 --- /dev/null +++ b/src/corelib/io/qfilesystemengine_p.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef QFILESYSTEMENGINE_P_H_INCLUDED +#define QFILESYSTEMENGINE_P_H_INCLUDED + +// +// 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. +// + +QT_BEGIN_NAMESPACE + +class QFileSystemEngine +{ +}; + +QT_END_NAMESPACE + +#endif // include guard diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h new file mode 100644 index 0000000..c051bc5 --- /dev/null +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef QFILESYSTEMMETADATA_P_H_INCLUDED +#define QFILESYSTEMMETADATA_P_H_INCLUDED + +// +// 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. +// + +QT_BEGIN_NAMESPACE + +class QFileSystemMetaData +{ +}; + +QT_END_NAMESPACE + +#endif // include guard -- cgit v0.12 From b5905172d3c68f9b64334d9a2796bdf1df65e607 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Tue, 24 Aug 2010 12:23:44 +0200 Subject: Add constructors and basic getters to QFilesystemEntry Reviewed-by: Prasanth Ullattil --- src/corelib/io/qfilesystementry.cpp | 67 +++++++++++++++++++++++++++++++++++++ src/corelib/io/qfilesystementry_p.h | 24 +++++++++++++ 2 files changed, 91 insertions(+) diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index 36ec012..1cc82ef 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -39,3 +39,70 @@ ** ****************************************************************************/ +#include "qfilesystementry_p.h" +#include "qdir.h" + +QFileSystemEntry::QFileSystemEntry(const QString &filePath) + : m_filePath(filePath), + m_lastSeparator(-2) +{ +} + +QFileSystemEntry::QFileSystemEntry(const QByteArray &nativeFilePath) + : m_nativeFilePath(nativeFilePath), + m_lastSeparator(-2) +{ +} + +QFileSystemEntry::QFileSystemEntry(const QByteArray &nativeFilePath, const QString &filePath) + : m_filePath(filePath), + m_nativeFilePath(nativeFilePath), + m_lastSeparator(-2) +{ +} + +QString QFileSystemEntry::filePath() const +{ + resolveFilePath(); + return m_filePath; +} + +QByteArray QFileSystemEntry::nativeFileName() const +{ + resolveNativeFilePath(); + return m_nativeFilePath; +} + +void QFileSystemEntry::resolveFilePath() const +{ + if (m_filePath.isEmpty() && !m_nativeFilePath.isEmpty()) { + m_filePath = QDir::fromNativeSeparators(QString::fromLocal8Bit(m_nativeFilePath)); + } +} + +void QFileSystemEntry::resolveNativeFilePath() const +{ + if (!m_filePath.isEmpty() && m_nativeFilePath.isEmpty()) { + m_nativeFilePath = m_filePath.toLocal8Bit(); + } +} + +QString QFileSystemEntry::fileName() const +{ + findLastSeparator(); + return m_filePath.mid(m_lastSeparator + 1); +} + +void QFileSystemEntry::findLastSeparator() const +{ + resolveFilePath(); + if (m_lastSeparator == -2) { + m_lastSeparator = -1; + for (int i = m_filePath.size() - 1; i >= 0; --i) { + if (m_filePath[i].unicode() == '/') { + m_lastSeparator = i; + break; + } + } + } +} diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index 2054f62..3e67174 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -53,10 +53,34 @@ // We mean it. // +#include +#include + QT_BEGIN_NAMESPACE class QFileSystemEntry { + QFileSystemEntry(const QString &filePath); + QFileSystemEntry(const QByteArray &nativeFilePath); + QFileSystemEntry(const QByteArray &nativeFilePath, const QString &filePath); + + QString filePath() const; + QString fileName() const; + QByteArray nativeFileName() const; + +private: + // creates the QString version out of the bytearray version + void resolveFilePath() const; + // creates the bytearray version out of the QString version + void resolveNativeFilePath() const; + void findLastSeparator() const; + + mutable QString m_filePath; // always has slashes as separator + mutable QByteArray m_nativeFilePath; // native encoding and separators + + mutable int m_lastSeparator : 16; + + int dummy : 16; }; QT_END_NAMESPACE -- cgit v0.12 From a5c215ac09e9ede853024fc69a0b74a7af820ea4 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Tue, 24 Aug 2010 13:54:05 +0200 Subject: Add some more methods to the QFileSystemEntry --- src/corelib/io/qfilesystementry.cpp | 87 ++++++++++++++++++++++++++++++++++--- src/corelib/io/qfilesystementry_p.h | 15 +++++-- 2 files changed, 94 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index 1cc82ef..3e8b8b2 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -44,20 +44,26 @@ QFileSystemEntry::QFileSystemEntry(const QString &filePath) : m_filePath(filePath), - m_lastSeparator(-2) + m_lastSeparator(-2), + m_firstDotInFileName(-2), + m_lastDotInFileName(0) { } QFileSystemEntry::QFileSystemEntry(const QByteArray &nativeFilePath) : m_nativeFilePath(nativeFilePath), - m_lastSeparator(-2) + m_lastSeparator(-2), + m_firstDotInFileName(-2), + m_lastDotInFileName(0) { } QFileSystemEntry::QFileSystemEntry(const QByteArray &nativeFilePath, const QString &filePath) : m_filePath(filePath), m_nativeFilePath(nativeFilePath), - m_lastSeparator(-2) + m_lastSeparator(-2), + m_firstDotInFileName(-2), + m_lastDotInFileName(0) { } @@ -83,7 +89,7 @@ void QFileSystemEntry::resolveFilePath() const void QFileSystemEntry::resolveNativeFilePath() const { if (!m_filePath.isEmpty() && m_nativeFilePath.isEmpty()) { - m_nativeFilePath = m_filePath.toLocal8Bit(); + m_nativeFilePath = QDir::toNativeSeparators(m_filePath).toLocal8Bit(); } } @@ -93,10 +99,37 @@ QString QFileSystemEntry::fileName() const return m_filePath.mid(m_lastSeparator + 1); } -void QFileSystemEntry::findLastSeparator() const +QString QFileSystemEntry::suffix() const +{ + findFileNameSeparators(); + + if (m_lastDotInFileName == -1) + return QString(); + + return m_filePath.mid(m_lastSeparator + m_lastDotInFileName + 1); +} + +QString QFileSystemEntry::completeSuffix() const +{ + findFileNameSeparators(); + if (m_firstDotInFileName == -1) + return QString(); + + return m_filePath.mid(m_lastSeparator + m_firstDotInFileName + 1); +} + +bool QFileSystemEntry::isAbsolute() const { resolveFilePath(); + return !m_filePath.isEmpty() && (m_filePath[0].unicode() == '/' /*|| hasScheme()*/); +} + +// private methods + +void QFileSystemEntry::findLastSeparator() const +{ if (m_lastSeparator == -2) { + resolveFilePath(); m_lastSeparator = -1; for (int i = m_filePath.size() - 1; i >= 0; --i) { if (m_filePath[i].unicode() == '/') { @@ -106,3 +139,47 @@ void QFileSystemEntry::findLastSeparator() const } } } + +void QFileSystemEntry::findFileNameSeparators() const +{ + if (m_firstDotInFileName == -2) { + resolveFilePath(); + int firstDotInFileName = -1; + int lastDotInFileName = -1; + int lastSeparator = m_lastSeparator; + + int stop; + if (lastSeparator < 0) { + lastSeparator = -1; + stop = 0; + } else { + stop = lastSeparator; + } + + int i = m_filePath.size() - 1; + for (; i >= stop; --i) { + if (m_filePath[i].unicode() == '.') { + firstDotInFileName = lastDotInFileName = i; + break; + } else if (m_filePath[i].unicode() == '/') { + lastSeparator = i; + break; + } + } + + if (lastSeparator != i) { + for (--i; i >= stop; --i) { + if (m_filePath[i].unicode() == '.') + firstDotInFileName = i; + else if (m_filePath[i].unicode() == '/') { + lastSeparator = i; + break; + } + } + } + + m_lastSeparator = lastSeparator; + m_firstDotInFileName = firstDotInFileName == -1 ? -1 : firstDotInFileName - lastSeparator; + m_lastDotInFileName = lastDotInFileName == -1 ? -1 : lastDotInFileName - firstDotInFileName - lastSeparator; + } +} diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index 3e67174..1812b9f 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -67,20 +67,29 @@ class QFileSystemEntry QString filePath() const; QString fileName() const; QByteArray nativeFileName() const; + QString suffix() const; + QString completeSuffix() const; + bool isAbsolute() const; + bool isRelative() const { + return !isAbsolute(); + } private: // creates the QString version out of the bytearray version void resolveFilePath() const; // creates the bytearray version out of the QString version void resolveNativeFilePath() const; + // resolves the separator void findLastSeparator() const; + /// resolves the dots and the separator + void findFileNameSeparators() const; mutable QString m_filePath; // always has slashes as separator mutable QByteArray m_nativeFilePath; // native encoding and separators - mutable int m_lastSeparator : 16; - - int dummy : 16; + mutable int m_lastSeparator : 16; // index in m_filePath of last separator + mutable int m_firstDotInFileName : 11; // index after m_filePath for first dot (.) + mutable int m_lastDotInFileName : 5; // index after m_firstDotInFileName for last dot (.) }; QT_END_NAMESPACE -- cgit v0.12 From e6ad5637e5a482e81461166170d8327f896bcbc6 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 24 Aug 2010 14:47:41 +0200 Subject: Move QFileInfoPrivate methods to QFileInfoPrivate::Data (1st Round) Reviewed-by: Joao --- src/corelib/io/qfileinfo.cpp | 154 ++++++++++++++++++++++--------------------- src/corelib/io/qfileinfo_p.h | 25 ++++--- 2 files changed, 90 insertions(+), 89 deletions(-) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 61f7180..4671d8c 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -64,46 +64,45 @@ QFileInfoPrivate::~QFileInfoPrivate() data = 0; } -void QFileInfoPrivate::initFileEngine(const QString &file) +void QFileInfoPrivate::Data::initFileEngine(const QString &file) { - detach(); - delete data->fileEngine; - data->fileEngine = 0; - data->clear(); - data->fileEngine = QAbstractFileEngine::create(file); - data->fileName = file; + delete fileEngine; + fileEngine = 0; + clear(); + fileEngine = QAbstractFileEngine::create(file); + fileName = file; } -void QFileInfoPrivate::detach() +void QFileInfoPrivate::Data::detach(QFileInfoPrivate::Data *&data) { qAtomicDetach(data); } -QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const +QString QFileInfoPrivate::Data::getFileName(QAbstractFileEngine::FileName name) const { - if (data->cache_enabled && !data->fileNames[(int)name].isNull()) - return data->fileNames[(int)name]; - QString ret = data->fileEngine->fileName(name); + if (cache_enabled && !fileNames[(int)name].isNull()) + return fileNames[(int)name]; + QString ret = fileEngine->fileName(name); if (ret.isNull()) ret = QLatin1String(""); - if (data->cache_enabled) - data->fileNames[(int)name] = ret; + if (cache_enabled) + fileNames[(int)name] = ret; return ret; } -QString QFileInfoPrivate::getFileOwner(QAbstractFileEngine::FileOwner own) const +QString QFileInfoPrivate::Data::getFileOwner(QAbstractFileEngine::FileOwner own) const { - if (data->cache_enabled && !data->fileOwners[(int)own].isNull()) - return data->fileOwners[(int)own]; - QString ret = data->fileEngine->owner(own); + if (cache_enabled && !fileOwners[(int)own].isNull()) + return fileOwners[(int)own]; + QString ret = fileEngine->owner(own); if (ret.isNull()) ret = QLatin1String(""); - if (data->cache_enabled) - data->fileOwners[(int)own] = ret; + if (cache_enabled) + fileOwners[(int)own] = ret; return ret; } -uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) const +uint QFileInfoPrivate::Data::getFileFlags(QAbstractFileEngine::FileFlags request) const { // We split the testing into tests for for LinkType, BundleType, PermsMask // and the rest. @@ -118,7 +117,7 @@ uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) cons uint cachedFlags = 0; if (request & (QAbstractFileEngine::FlagsMask | QAbstractFileEngine::TypesMask)) { - if (!data->getCachedFlag(CachedFileFlags)) { + if (!getCachedFlag(CachedFileFlags)) { req |= QAbstractFileEngine::FlagsMask; req |= QAbstractFileEngine::TypesMask; req &= (~QAbstractFileEngine::LinkType); @@ -128,14 +127,14 @@ uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) cons } if (request & QAbstractFileEngine::LinkType) { - if (!data->getCachedFlag(CachedLinkTypeFlag)) { + if (!getCachedFlag(CachedLinkTypeFlag)) { req |= QAbstractFileEngine::LinkType; cachedFlags |= CachedLinkTypeFlag; } } if (request & QAbstractFileEngine::BundleType) { - if (!data->getCachedFlag(CachedBundleTypeFlag)) { + if (!getCachedFlag(CachedBundleTypeFlag)) { req |= QAbstractFileEngine::BundleType; cachedFlags |= CachedBundleTypeFlag; } @@ -143,30 +142,30 @@ uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) cons } if (request & QAbstractFileEngine::PermsMask) { - if (!data->getCachedFlag(CachedPerms)) { + if (!getCachedFlag(CachedPerms)) { req |= QAbstractFileEngine::PermsMask; cachedFlags |= CachedPerms; } } if (req) { - if (data->cache_enabled) + if (cache_enabled) req &= (~QAbstractFileEngine::Refresh); else req |= QAbstractFileEngine::Refresh; - QAbstractFileEngine::FileFlags flags = data->fileEngine->fileFlags(req); - data->fileFlags |= uint(flags); - data->setCachedFlag(cachedFlags); + QAbstractFileEngine::FileFlags flags = fileEngine->fileFlags(req); + fileFlags |= uint(flags); + setCachedFlag(cachedFlags); } - return data->fileFlags & request; + return fileFlags & request; } -QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) const +QDateTime &QFileInfoPrivate::Data::getFileTime(QAbstractFileEngine::FileTime request) const { - if (!data->cache_enabled) - data->clearFlags(); + if (!cache_enabled) + clearFlags(); uint cf; if (request == QAbstractFileEngine::CreationTime) cf = CachedCTime; @@ -174,11 +173,11 @@ QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) cf = CachedMTime; else cf = CachedATime; - if (!data->getCachedFlag(cf)) { - data->fileTimes[request] = data->fileEngine->fileTime(request); - data->setCachedFlag(cf); + if (!getCachedFlag(cf)) { + fileTimes[request] = fileEngine->fileTime(request); + setCachedFlag(cf); } - return data->fileTimes[request]; + return fileTimes[request]; } //************* QFileInfo @@ -287,7 +286,8 @@ QFileInfo::QFileInfo() : d_ptr(new QFileInfoPrivate()) */ QFileInfo::QFileInfo(const QString &file) : d_ptr(new QFileInfoPrivate()) { - d_ptr->initFileEngine(file); + QFileInfoPrivate::Data::detach(d_ptr->data); + d_ptr->data->initFileEngine(file); } /*! @@ -301,7 +301,8 @@ QFileInfo::QFileInfo(const QString &file) : d_ptr(new QFileInfoPrivate()) */ QFileInfo::QFileInfo(const QFile &file) : d_ptr(new QFileInfoPrivate()) { - d_ptr->initFileEngine(file.fileName()); + QFileInfoPrivate::Data::detach(d_ptr->data); + d_ptr->data->initFileEngine(file.fileName()); } /*! @@ -318,7 +319,8 @@ QFileInfo::QFileInfo(const QFile &file) : d_ptr(new QFileInfoPrivate()) */ QFileInfo::QFileInfo(const QDir &dir, const QString &file) : d_ptr(new QFileInfoPrivate()) { - d_ptr->initFileEngine(dir.filePath(file)); + QFileInfoPrivate::Data::detach(d_ptr->data); + d_ptr->data->initFileEngine(dir.filePath(file)); } /*! @@ -490,7 +492,7 @@ QString QFileInfo::absoluteFilePath() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QLatin1String(""); - return d->getFileName(QAbstractFileEngine::AbsoluteName); + return d->data->getFileName(QAbstractFileEngine::AbsoluteName); } /*! @@ -507,7 +509,7 @@ QString QFileInfo::canonicalFilePath() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QLatin1String(""); - return d->getFileName(QAbstractFileEngine::CanonicalName); + return d->data->getFileName(QAbstractFileEngine::CanonicalName); } @@ -538,7 +540,7 @@ QString QFileInfo::absolutePath() const qWarning("QFileInfo::absolutePath: Constructed with empty filename"); return QLatin1String(""); } - return d->getFileName(QAbstractFileEngine::AbsolutePathName); + return d->data->getFileName(QAbstractFileEngine::AbsolutePathName); } /*! @@ -554,7 +556,7 @@ QString QFileInfo::canonicalPath() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QLatin1String(""); - return d->getFileName(QAbstractFileEngine::CanonicalPathName); + return d->data->getFileName(QAbstractFileEngine::CanonicalPathName); } /*! @@ -571,7 +573,7 @@ QString QFileInfo::path() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QLatin1String(""); - return d->getFileName(QAbstractFileEngine::PathName); + return d->data->getFileName(QAbstractFileEngine::PathName); } /*! @@ -610,8 +612,9 @@ bool QFileInfo::makeAbsolute() Q_D(QFileInfo); if (!d->data->fileEngine || !d->data->fileEngine->isRelativePath()) return false; - QString absFileName = d->getFileName(QAbstractFileEngine::AbsoluteName); - d->initFileEngine(absFileName); + QString absFileName = d->data->getFileName(QAbstractFileEngine::AbsoluteName); + QFileInfoPrivate::Data::detach(d_ptr->data); + d->data->initFileEngine(absFileName); return true; } @@ -626,7 +629,7 @@ bool QFileInfo::exists() const Q_D(const QFileInfo); if (!d->data->fileEngine) return false; - return d->getFileFlags(QAbstractFileEngine::ExistsFlag); + return d->data->getFileFlags(QAbstractFileEngine::ExistsFlag); } /*! @@ -639,7 +642,8 @@ bool QFileInfo::exists() const void QFileInfo::refresh() { Q_D(QFileInfo); - d->reset(); + QFileInfoPrivate::Data::detach(d->data); + d->data->clear(); } /*! @@ -653,7 +657,7 @@ QString QFileInfo::filePath() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QLatin1String(""); - return d->getFileName(QAbstractFileEngine::DefaultName); + return d->data->getFileName(QAbstractFileEngine::DefaultName); } /*! @@ -672,7 +676,7 @@ QString QFileInfo::fileName() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QLatin1String(""); - return d->getFileName(QAbstractFileEngine::BaseName); + return d->data->getFileName(QAbstractFileEngine::BaseName); } /*! @@ -692,7 +696,7 @@ QString QFileInfo::bundleName() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QLatin1String(""); - return d->getFileName(QAbstractFileEngine::BundleName); + return d->data->getFileName(QAbstractFileEngine::BundleName); } /*! @@ -716,7 +720,7 @@ QString QFileInfo::baseName() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QLatin1String(""); - return d->getFileName(QAbstractFileEngine::BaseName).section(QLatin1Char('.'), 0, 0); + return d->data->getFileName(QAbstractFileEngine::BaseName).section(QLatin1Char('.'), 0, 0); } /*! @@ -735,7 +739,7 @@ QString QFileInfo::completeBaseName() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QLatin1String(""); - QString name = d->getFileName(QAbstractFileEngine::BaseName); + QString name = d->data->getFileName(QAbstractFileEngine::BaseName); int index = name.lastIndexOf(QLatin1Char('.')); return (index == -1) ? name : name.left(index); } @@ -756,7 +760,7 @@ QString QFileInfo::completeSuffix() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QLatin1String(""); - QString fileName = d->getFileName(QAbstractFileEngine::BaseName); + QString fileName = d->data->getFileName(QAbstractFileEngine::BaseName); int firstDot = fileName.indexOf(QLatin1Char('.')); if (firstDot == -1) return QLatin1String(""); @@ -783,7 +787,7 @@ QString QFileInfo::suffix() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QLatin1String(""); - QString fileName = d->getFileName(QAbstractFileEngine::BaseName); + QString fileName = d->data->getFileName(QAbstractFileEngine::BaseName); int lastDot = fileName.lastIndexOf(QLatin1Char('.')); if (lastDot == -1) return QLatin1String(""); @@ -848,7 +852,7 @@ bool QFileInfo::isReadable() const Q_D(const QFileInfo); if (!d->data->fileEngine) return false; - return d->getFileFlags(QAbstractFileEngine::ReadUserPerm); + return d->data->getFileFlags(QAbstractFileEngine::ReadUserPerm); } /*! @@ -861,7 +865,7 @@ bool QFileInfo::isWritable() const Q_D(const QFileInfo); if (!d->data->fileEngine) return false; - return d->getFileFlags(QAbstractFileEngine::WriteUserPerm); + return d->data->getFileFlags(QAbstractFileEngine::WriteUserPerm); } /*! @@ -874,7 +878,7 @@ bool QFileInfo::isExecutable() const Q_D(const QFileInfo); if (!d->data->fileEngine) return false; - return d->getFileFlags(QAbstractFileEngine::ExeUserPerm); + return d->data->getFileFlags(QAbstractFileEngine::ExeUserPerm); } /*! @@ -888,7 +892,7 @@ bool QFileInfo::isHidden() const Q_D(const QFileInfo); if (!d->data->fileEngine) return false; - return d->getFileFlags(QAbstractFileEngine::HiddenFlag); + return d->data->getFileFlags(QAbstractFileEngine::HiddenFlag); } /*! @@ -903,7 +907,7 @@ bool QFileInfo::isFile() const Q_D(const QFileInfo); if (!d->data->fileEngine) return false; - return d->getFileFlags(QAbstractFileEngine::FileType); + return d->data->getFileFlags(QAbstractFileEngine::FileType); } /*! @@ -917,7 +921,7 @@ bool QFileInfo::isDir() const Q_D(const QFileInfo); if (!d->data->fileEngine) return false; - return d->getFileFlags(QAbstractFileEngine::DirectoryType); + return d->data->getFileFlags(QAbstractFileEngine::DirectoryType); } @@ -933,7 +937,7 @@ bool QFileInfo::isBundle() const Q_D(const QFileInfo); if (!d->data->fileEngine) return false; - return d->getFileFlags(QAbstractFileEngine::BundleType); + return d->data->getFileFlags(QAbstractFileEngine::BundleType); } /*! @@ -958,7 +962,7 @@ bool QFileInfo::isSymLink() const Q_D(const QFileInfo); if (!d->data->fileEngine) return false; - return d->getFileFlags(QAbstractFileEngine::LinkType); + return d->data->getFileFlags(QAbstractFileEngine::LinkType); } /*! @@ -971,7 +975,7 @@ bool QFileInfo::isRoot() const Q_D(const QFileInfo); if (!d->data->fileEngine) return true; - return d->getFileFlags(QAbstractFileEngine::RootFlag); + return d->data->getFileFlags(QAbstractFileEngine::RootFlag); } /*! @@ -999,7 +1003,7 @@ QString QFileInfo::readLink() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QLatin1String(""); - return d->getFileName(QAbstractFileEngine::LinkName); + return d->data->getFileName(QAbstractFileEngine::LinkName); } /*! @@ -1017,7 +1021,7 @@ QString QFileInfo::owner() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QLatin1String(""); - return d->getFileOwner(QAbstractFileEngine::OwnerUser); + return d->data->getFileOwner(QAbstractFileEngine::OwnerUser); } /*! @@ -1051,7 +1055,7 @@ QString QFileInfo::group() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QLatin1String(""); - return d->getFileOwner(QAbstractFileEngine::OwnerGroup); + return d->data->getFileOwner(QAbstractFileEngine::OwnerGroup); } /*! @@ -1088,7 +1092,7 @@ bool QFileInfo::permission(QFile::Permissions permissions) const Q_D(const QFileInfo); if (!d->data->fileEngine) return false; - return d->getFileFlags(QAbstractFileEngine::FileFlags((int)permissions)) == (uint)permissions; + return d->data->getFileFlags(QAbstractFileEngine::FileFlags((int)permissions)) == (uint)permissions; } /*! @@ -1100,7 +1104,7 @@ QFile::Permissions QFileInfo::permissions() const Q_D(const QFileInfo); if (!d->data->fileEngine) return 0; - return QFile::Permissions(d->getFileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask); + return QFile::Permissions(d->data->getFileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask); } @@ -1140,7 +1144,7 @@ QDateTime QFileInfo::created() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QDateTime(); - return d->getFileTime(QAbstractFileEngine::CreationTime); + return d->data->getFileTime(QAbstractFileEngine::CreationTime); } /*! @@ -1153,7 +1157,7 @@ QDateTime QFileInfo::lastModified() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QDateTime(); - return d->getFileTime(QAbstractFileEngine::ModificationTime); + return d->data->getFileTime(QAbstractFileEngine::ModificationTime); } /*! @@ -1169,7 +1173,7 @@ QDateTime QFileInfo::lastRead() const Q_D(const QFileInfo); if (!d->data->fileEngine) return QDateTime(); - return d->getFileTime(QAbstractFileEngine::AccessTime); + return d->data->getFileTime(QAbstractFileEngine::AccessTime); } /*! \internal @@ -1178,7 +1182,7 @@ QDateTime QFileInfo::lastRead() const void QFileInfo::detach() { Q_D(QFileInfo); - d->detach(); + QFileInfoPrivate::Data::detach(d->data); } /*! @@ -1207,7 +1211,7 @@ bool QFileInfo::caching() const void QFileInfo::setCaching(bool enable) { Q_D(QFileInfo); - detach(); + QFileInfoPrivate::Data::detach(d->data); d->data->cache_enabled = enable; } diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h index 306ffe1..a1f5419 100644 --- a/src/corelib/io/qfileinfo_p.h +++ b/src/corelib/io/qfileinfo_p.h @@ -66,13 +66,6 @@ public: QFileInfoPrivate(const QFileInfo *copy=0); ~QFileInfoPrivate(); - void initFileEngine(const QString &); - - uint getFileFlags(QAbstractFileEngine::FileFlags) const; - QDateTime &getFileTime(QAbstractFileEngine::FileTime) const; - QString getFileName(QAbstractFileEngine::FileName) const; - QString getFileOwner(QAbstractFileEngine::FileOwner own) const; - enum { CachedFileFlags=0x01, CachedLinkTypeFlag=0x02, CachedBundleTypeFlag=0x04, CachedMTime=0x10, CachedCTime=0x20, CachedATime=0x40, CachedSize =0x08, CachedPerms=0x80 }; @@ -87,7 +80,7 @@ public: cachedFlags(0), cache_enabled(copy.cache_enabled), fileFlags(0), fileSize(0) {} inline ~Data() { delete fileEngine; } - inline void clearFlags() { + inline void clearFlags() const { fileFlags = 0; cachedFlags = 0; if (fileEngine) @@ -100,6 +93,15 @@ public: fileOwners[1].clear(); fileOwners[0].clear(); } + void initFileEngine(const QString &); + + uint getFileFlags(QAbstractFileEngine::FileFlags) const; + QDateTime &getFileTime(QAbstractFileEngine::FileTime) const; + QString getFileName(QAbstractFileEngine::FileName) const; + QString getFileOwner(QAbstractFileEngine::FileOwner own) const; + + static void detach(QFileInfoPrivate::Data *&data); + mutable QAtomicInt ref; QAbstractFileEngine *fileEngine; @@ -114,14 +116,9 @@ public: mutable QDateTime fileTimes[3]; inline bool getCachedFlag(uint c) const { return cache_enabled ? (cachedFlags & c) : 0; } - inline void setCachedFlag(uint c) + inline void setCachedFlag(uint c) const { if (cache_enabled) cachedFlags |= c; } } *data; - inline void reset() { - detach(); - data->clear(); - } - void detach(); }; QT_END_NAMESPACE -- cgit v0.12 From 46237ec0e73ce11bb55086a4917c2138ba529c58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 24 Aug 2010 14:32:43 +0200 Subject: Refactoring QDirPrivate::Data There was an unnecessary split of QDir's private data between QDirPrivate and QDirPrivate::Data. As a stepping stone towards merging the two, this moves everything into QDirPrivate::Data. Reviewed-by: Thomas Zander --- src/corelib/io/qdir.cpp | 182 ++++++++++++++++++++++++++---------------------- 1 file changed, 98 insertions(+), 84 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index ed51c5d..5d56529 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -89,46 +89,73 @@ public: QDirPrivate(const QDir *copy = 0); ~QDirPrivate(); - void updateFileLists() const; - void sortFileList(QDir::SortFlags, QFileInfoList &, QStringList *, QFileInfoList *) const; - -#ifdef QT3_SUPPORT - QChar filterSepChar; - bool matchAllDirs; -#endif - static inline QChar getFilterSepChar(const QString &nameFilter) - { - QChar sep(QLatin1Char(';')); - int i = nameFilter.indexOf(sep, 0); - if (i == -1 && nameFilter.indexOf(QLatin1Char(' '), 0) != -1) - sep = QChar(QLatin1Char(' ')); - return sep; - } - static inline QStringList splitFilters(const QString &nameFilter, QChar sep = 0) { - if (sep == 0) - sep = getFilterSepChar(nameFilter); - QStringList ret = nameFilter.split(sep); - for (int i = 0; i < ret.count(); ++i) - ret[i] = ret[i].trimmed(); - return ret; - } - struct Data { inline Data() - : ref(1), fileEngine(0), listsDirty(1) + : ref(1), +#ifdef QT3_SUPPORT + filterSepChar(0), matchAllDirs(false), +#endif + fileEngine(0), listsDirty(1) {} inline Data(const Data ©) : ref(1), path(copy.path), nameFilters(copy.nameFilters), sort(copy.sort), - filters(copy.filters), fileEngine(0), listsDirty(1) + filters(copy.filters), +#ifdef QT3_SUPPORT + filterSepChar(copy.filterSepChar), matchAllDirs(copy.matchAllDirs), +#endif + fileEngine(0), listsDirty(1) {} inline ~Data() { delete fileEngine; } + void updateFileLists() const; + static void sortFileList(QDir::SortFlags, QFileInfoList &, QStringList *, QFileInfoList *); + + static inline QChar getFilterSepChar(const QString &nameFilter) + { + QChar sep(QLatin1Char(';')); + int i = nameFilter.indexOf(sep, 0); + if (i == -1 && nameFilter.indexOf(QLatin1Char(' '), 0) != -1) + sep = QChar(QLatin1Char(' ')); + return sep; + } + + static inline QStringList splitFilters(const QString &nameFilter, QChar sep = 0) + { + if (sep == 0) + sep = getFilterSepChar(nameFilter); + QStringList ret = nameFilter.split(sep); + for (int i = 0; i < ret.count(); ++i) + ret[i] = ret[i].trimmed(); + return ret; + } + + static void detach(QDirPrivate::Data *&data, bool createFileEngine = true); + + inline void setPath(QString p) + { + if ((p.endsWith(QLatin1Char('/')) || p.endsWith(QLatin1Char('\\'))) + && p.length() > 1) { +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + if (!(p.length() == 3 && p.at(1) == QLatin1Char(':'))) +#endif + p.truncate(p.length() - 1); + } + + delete fileEngine; + fileEngine = QAbstractFileEngine::create(p); + + // set the path to be the qt friendly version so then we can operate on it using just / + path = fileEngine->fileName(QAbstractFileEngine::DefaultName); + clear(); + } + inline void clear() { listsDirty = 1; files.clear(); fileInfos.clear(); } + mutable QAtomicInt ref; QString path; @@ -136,42 +163,20 @@ public: QDir::SortFlags sort; QDir::Filters filters; +#ifdef QT3_SUPPORT + QChar filterSepChar; + bool matchAllDirs; +#endif mutable QAbstractFileEngine *fileEngine; mutable uint listsDirty : 1; mutable QStringList files; mutable QFileInfoList fileInfos; } *data; - inline void setPath(const QString &p) - { - detach(false); - QString path = p; - if ((path.endsWith(QLatin1Char('/')) || path.endsWith(QLatin1Char('\\'))) - && path.length() > 1) { -#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) - if (!(path.length() == 3 && path.at(1) == QLatin1Char(':'))) -#endif - path.truncate(path.length() - 1); - } - - delete data->fileEngine; - data->fileEngine = QAbstractFileEngine::create(path); - // set the path to be the qt friendly version so then we can operate on it using just / - data->path = data->fileEngine->fileName(QAbstractFileEngine::DefaultName); - data->clear(); - } - inline void reset() { - detach(); - data->clear(); - } - void detach(bool createFileEngine = true); }; QDirPrivate::QDirPrivate(const QDir *copy) -#ifdef QT3_SUPPORT - : filterSepChar(0), matchAllDirs(false) -#endif { if (copy) { copy->d_func()->data->ref.ref(); @@ -268,8 +273,8 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt return r < 0; } -inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l, - QStringList *names, QFileInfoList *infos) const +inline void QDirPrivate::Data::sortFileList(QDir::SortFlags sort, QFileInfoList &l, + QStringList *names, QFileInfoList *infos) { // names and infos are always empty lists or 0 here int n = l.size(); @@ -299,21 +304,21 @@ inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l, } } -inline void QDirPrivate::updateFileLists() const +inline void QDirPrivate::Data::updateFileLists() const { - if (data->listsDirty) { + if (listsDirty) { QFileInfoList l; - QDirIterator it(data->path, data->nameFilters, data->filters); + QDirIterator it(path, nameFilters, filters); while (it.hasNext()) { it.next(); l.append(it.fileInfo()); } - sortFileList(data->sort, l, &data->files, &data->fileInfos); - data->listsDirty = 0; + sortFileList(sort, l, &files, &fileInfos); + listsDirty = 0; } } -void QDirPrivate::detach(bool createFileEngine) +void QDirPrivate::Data::detach(QDirPrivate::Data *&data, bool createFileEngine) { qAtomicDetach(data); if (createFileEngine) { @@ -507,7 +512,8 @@ void QDirPrivate::detach(bool createFileEngine) QDir::QDir(const QString &path) : d_ptr(new QDirPrivate) { Q_D(QDir); - d->setPath(path.isEmpty() ? QString::fromLatin1(".") : path); + QDirPrivate::Data::detach(d->data, false); + d->data->setPath(path.isEmpty() ? QString::fromLatin1(".") : path); d->data->nameFilters = QStringList(QString::fromLatin1("*")); d->data->filters = AllEntries; d->data->sort = SortFlags(Name | IgnoreCase); @@ -535,7 +541,8 @@ QDir::QDir(const QString &path, const QString &nameFilter, SortFlags sort, Filters filters) : d_ptr(new QDirPrivate) { Q_D(QDir); - d->setPath(path.isEmpty() ? QString::fromLatin1(".") : path); + QDirPrivate::Data::detach(d->data, false); + d->data->setPath(path.isEmpty() ? QString::fromLatin1(".") : path); d->data->nameFilters = QDir::nameFiltersFromString(nameFilter); bool empty = d->data->nameFilters.isEmpty(); if (!empty) { @@ -590,7 +597,8 @@ QDir::~QDir() void QDir::setPath(const QString &path) { Q_D(QDir); - d->setPath(path); + QDirPrivate::Data::detach(d->data, false); + d->data->setPath(path); } /*! @@ -954,7 +962,8 @@ void QDir::setNameFilters(const QStringList &nameFilters) { Q_D(QDir); - d->reset(); + QDirPrivate::Data::detach(d->data); + d->data->clear(); d->data->nameFilters = nameFilters; } @@ -1143,7 +1152,8 @@ void QDir::setFilter(Filters filters) { Q_D(QDir); - d->reset(); + QDirPrivate::Data::detach(d->data); + d->data->clear(); d->data->filters = filters; } @@ -1201,7 +1211,8 @@ void QDir::setSorting(SortFlags sort) { Q_D(QDir); - d->reset(); + QDirPrivate::Data::detach(d->data); + d->data->clear(); d->data->sort = sort; } @@ -1216,7 +1227,7 @@ uint QDir::count() const { Q_D(const QDir); - d->updateFileLists(); + d->data->updateFileLists(); return d->data->files.count(); } @@ -1231,7 +1242,7 @@ QString QDir::operator[](int pos) const { Q_D(const QDir); - d->updateFileLists(); + d->data->updateFileLists(); return d->data->files[pos]; } @@ -1309,14 +1320,14 @@ QStringList QDir::entryList(const QStringList &nameFilters, Filters filters, if (filters == NoFilter) filters = d->data->filters; #ifdef QT3_SUPPORT - if (d->matchAllDirs) + if (d->data->matchAllDirs) filters |= AllDirs; #endif if (sort == NoSort) sort = d->data->sort; if (filters == d->data->filters && sort == d->data->sort && nameFilters == d->data->nameFilters) { - d->updateFileLists(); + d->data->updateFileLists(); return d->data->files; } @@ -1327,7 +1338,7 @@ QStringList QDir::entryList(const QStringList &nameFilters, Filters filters, l.append(it.fileInfo()); } QStringList ret; - d->sortFileList(sort, l, &ret, 0); + d->data->sortFileList(sort, l, &ret, 0); return ret; } @@ -1355,14 +1366,14 @@ QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filter if (filters == NoFilter) filters = d->data->filters; #ifdef QT3_SUPPORT - if (d->matchAllDirs) + if (d->data->matchAllDirs) filters |= AllDirs; #endif if (sort == NoSort) sort = d->data->sort; if (filters == d->data->filters && sort == d->data->sort && nameFilters == d->data->nameFilters) { - d->updateFileLists(); + d->data->updateFileLists(); return d->data->fileInfos; } @@ -1373,7 +1384,7 @@ QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filter l.append(it.fileInfo()); } QFileInfoList ret; - d->sortFileList(sort, l, 0, &ret); + d->data->sortFileList(sort, l, 0, &ret); return ret; } @@ -1595,7 +1606,7 @@ bool QDir::makeAbsolute() // ### What do the return values signify? QString absolutePath = d->data->fileEngine->fileName(QAbstractFileEngine::AbsoluteName); if (QDir::isRelativePath(absolutePath)) return false; - d->detach(); + QDirPrivate::Data::detach(d->data); d->data->path = absolutePath; d->data->fileEngine->setFileName(absolutePath); if (!(d->data->fileEngine->fileFlags(QAbstractFileEngine::TypesMask) & QAbstractFileEngine::DirectoryType)) @@ -1661,7 +1672,8 @@ QDir &QDir::operator=(const QString &path) { Q_D(QDir); - d->setPath(path); + QDirPrivate::Data::detach(d->data, false); + d->data->setPath(path); return *this; } @@ -2153,7 +2165,8 @@ void QDir::refresh() const { Q_D(const QDir); - const_cast(d)->reset(); + QDirPrivate::Data::detach(const_cast(d)->data); + d->data->clear(); } /*! @@ -2165,7 +2178,7 @@ void QDir::refresh() const */ QStringList QDir::nameFiltersFromString(const QString &nameFilter) { - return QDirPrivate::splitFilters(nameFilter); + return QDirPrivate::Data::splitFilters(nameFilter); } /*! @@ -2230,7 +2243,7 @@ QStringList QDir::nameFiltersFromString(const QString &nameFilter) bool QDir::matchAllDirs() const { Q_D(const QDir); - return d->matchAllDirs; + return d->data->matchAllDirs; } @@ -2243,8 +2256,9 @@ void QDir::setMatchAllDirs(bool on) { Q_D(QDir); - d->reset(); - d->matchAllDirs = on; + QDirPrivate::Data::detach(d->data); + d->data->clear(); + d->data->matchAllDirs = on; } /*! @@ -2254,7 +2268,7 @@ QString QDir::nameFilter() const { Q_D(const QDir); - return nameFilters().join(QString(d->filterSepChar)); + return nameFilters().join(QString(d->data->filterSepChar)); } /*! @@ -2281,8 +2295,8 @@ void QDir::setNameFilter(const QString &nameFilter) { Q_D(QDir); - d->filterSepChar = QDirPrivate::getFilterSepChar(nameFilter); - setNameFilters(QDirPrivate::splitFilters(nameFilter, d->filterSepChar)); + d->data->filterSepChar = QDirPrivate::Data::getFilterSepChar(nameFilter); + setNameFilters(QDirPrivate::Data::splitFilters(nameFilter, d->data->filterSepChar)); } /*! -- cgit v0.12 From dba66b94d255c7cd0d3c9d2717f250194e4edac9 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 25 Aug 2010 10:30:39 +0200 Subject: Add unit test for qfilesystementry Reviewed-by: Joao --- src/corelib/io/qfilesystementry.cpp | 11 +- src/corelib/io/qfilesystementry_p.h | 3 +- tests/auto/corelib.pro | 1 + tests/auto/qfilesystementry/qfilesystementry.pro | 7 + .../auto/qfilesystementry/tst_qfilesystementry.cpp | 154 +++++++++++++++++++++ 5 files changed, 172 insertions(+), 4 deletions(-) create mode 100644 tests/auto/qfilesystementry/qfilesystementry.pro create mode 100644 tests/auto/qfilesystementry/tst_qfilesystementry.cpp diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index 3e8b8b2..d3b3225 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -73,7 +73,7 @@ QString QFileSystemEntry::filePath() const return m_filePath; } -QByteArray QFileSystemEntry::nativeFileName() const +QByteArray QFileSystemEntry::nativeFilePath() const { resolveNativeFilePath(); return m_nativeFilePath; @@ -106,7 +106,7 @@ QString QFileSystemEntry::suffix() const if (m_lastDotInFileName == -1) return QString(); - return m_filePath.mid(m_lastSeparator + m_lastDotInFileName + 1); + return m_filePath.mid(m_lastSeparator + m_firstDotInFileName + m_lastDotInFileName + 1); } QString QFileSystemEntry::completeSuffix() const @@ -180,6 +180,11 @@ void QFileSystemEntry::findFileNameSeparators() const m_lastSeparator = lastSeparator; m_firstDotInFileName = firstDotInFileName == -1 ? -1 : firstDotInFileName - lastSeparator; - m_lastDotInFileName = lastDotInFileName == -1 ? -1 : lastDotInFileName - firstDotInFileName - lastSeparator; + if (lastDotInFileName == -1) + m_lastDotInFileName = -1; + else if (firstDotInFileName == lastDotInFileName) + m_lastDotInFileName = 0; + else + m_lastDotInFileName = firstDotInFileName - lastSeparator; } } diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index 1812b9f..68af24d 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -60,13 +60,14 @@ QT_BEGIN_NAMESPACE class QFileSystemEntry { +public: QFileSystemEntry(const QString &filePath); QFileSystemEntry(const QByteArray &nativeFilePath); QFileSystemEntry(const QByteArray &nativeFilePath, const QString &filePath); QString filePath() const; QString fileName() const; - QByteArray nativeFileName() const; + QByteArray nativeFilePath() const; QString suffix() const; QString completeSuffix() const; bool isAbsolute() const; diff --git a/tests/auto/corelib.pro b/tests/auto/corelib.pro index d1d0940..5ac0c81 100644 --- a/tests/auto/corelib.pro +++ b/tests/auto/corelib.pro @@ -101,6 +101,7 @@ SUBDIRS=\ qwritelocker \ selftests \ utf8 \ + qfilesystementry \ symbian:SUBDIRS -= \ qtconcurrentfilter \ diff --git a/tests/auto/qfilesystementry/qfilesystementry.pro b/tests/auto/qfilesystementry/qfilesystementry.pro new file mode 100644 index 0000000..9f75388 --- /dev/null +++ b/tests/auto/qfilesystementry/qfilesystementry.pro @@ -0,0 +1,7 @@ +load(qttest_p4) + +SOURCES += tst_qfilesystementry.cpp \ + ../../../src/corelib/io/qfilesystementry.cpp +HEADERS += ../../../src/corelib/io/qfilesystementry_p.h +QT = core + diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp new file mode 100644 index 0000000..081beb6 --- /dev/null +++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** 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 + +#include + +#if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX) || defined(Q_OS_SYMBIAN) +# define WIN_STUFF +#endif + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QFileSystemEntry : public QObject +{ + Q_OBJECT + +private slots: + void getSetCheck_data(); + void getSetCheck(); +}; + +void tst_QFileSystemEntry::getSetCheck_data() +{ + QTest::addColumn("nativeFilePath"); + QTest::addColumn("filepath"); + QTest::addColumn("filename"); + QTest::addColumn("suffix"); + QTest::addColumn("completeSuffix"); + QTest::addColumn("absolute"); + + QTest::newRow("simple") +#if defined(WIN_STUFF) + << QByteArray("A:\\home\\qt\\in\\a\\dir.tar.gz") + << "A:/home/qt/in/a/dir.tar.gz" +#else + << QByteArray("/home/qt/in/a/dir.tar.gz") + << "/home/qt/in/a/dir.tar.gz" +#endif + << "dir.tar.gz" << "gz" << "tar.gz" << true; + + QTest::newRow("relative") +#if defined(WIN_STUFF) + << QByteArray("\\in\\a\\dir.tar.gz") + << "/in/a/dir.tar.gz" +#else + << QByteArray("in/a/dir.tar.gz") + << "in/a/dir.tar.gz" +#endif + << "dir.tar.gz" << "gz" << "tar.gz" << false; + + QTest::newRow("noSuffix") +#if defined(WIN_STUFF) + << QByteArray("myDir\\myfile") +#else + << QByteArray("myDir/myfile") +#endif + << "myDir/myfile" << "myfile" << "" << "" << false; + + QTest::newRow("noLongSuffix") +#if defined(WIN_STUFF) + << QByteArray("myDir\\myfile.txt") +#else + << QByteArray("myDir/myfile.txt") +#endif + << "myDir/myfile.txt" << "myfile.txt" << "txt" << "txt" << false; + + QTest::newRow("endingSlash") +#if defined(WIN_STUFF) + << QByteArray("myDir\\myfile.bla\\") +#else + << QByteArray("myDir/myfile.bla/") +#endif + << "myDir/myfile.bla/" << "" << "" << "" << false; + +#if defined(WIN_STUFF) + QTest::newRow("absolutePath") + << QByteArray("A:dir\\without\\leading\\backslash.bat") + << "A:dir/without/leading/backslash.bat" << "backslash.bat" << "bat" << "bat" << true; +#else + QTest::newRow("relativePath") + << QByteArray("A:dir/without/leading/backslash.bat") + << "A:dir/without/leading/backslash.bat" << "backslash.bat" << "bat" << "bat" << false; +#endif +} + +void tst_QFileSystemEntry::getSetCheck() +{ + QFETCH(QByteArray, nativeFilePath); + QFETCH(QString, filepath); + QFETCH(QString, filename); + QFETCH(QString, suffix); + QFETCH(QString, completeSuffix); + QFETCH(bool, absolute); + + QFileSystemEntry entry1(filepath); + QCOMPARE(entry1.filePath(), filepath); + QCOMPARE(entry1.nativeFilePath(), nativeFilePath); + QCOMPARE(entry1.fileName(), filename); + QCOMPARE(entry1.suffix(), suffix); + QCOMPARE(entry1.completeSuffix(), completeSuffix); + QCOMPARE(entry1.isAbsolute(), absolute); + QCOMPARE(entry1.isRelative(), !absolute); + + QFileSystemEntry entry2(nativeFilePath); + QCOMPARE(entry2.suffix(), suffix); + QCOMPARE(entry2.completeSuffix(), completeSuffix); + QCOMPARE(entry2.isAbsolute(), absolute); + QCOMPARE(entry2.isRelative(), !absolute); + QCOMPARE(entry2.filePath(), filepath); + QCOMPARE(entry2.nativeFilePath(), nativeFilePath); + QCOMPARE(entry2.fileName(), filename); +} + +QTEST_MAIN(tst_QFileSystemEntry) +#include -- cgit v0.12 From 931d47db10ca8b8ebf564c4b6537e31370b7f53c Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 25 Aug 2010 13:19:32 +0200 Subject: Fix the unit test on Windows --- src/corelib/io/qfilesystementry.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index d3b3225..2d6740e 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -121,7 +121,14 @@ QString QFileSystemEntry::completeSuffix() const bool QFileSystemEntry::isAbsolute() const { resolveFilePath(); - return !m_filePath.isEmpty() && (m_filePath[0].unicode() == '/' /*|| hasScheme()*/); + return (!m_filePath.isEmpty() && (m_filePath[0].unicode() == '/') +#if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX) || defined(Q_OS_SYMBIAN) + || (m_filePath.length() >= 2 + && ((m_filePath[0].isLetter() && m_filePath[1] == QLatin1Char(':')) + || (m_filePath.at(0) == QLatin1Char('/') && m_filePath.at(1) == QLatin1Char('/')))) +#endif + ); + } // private methods -- cgit v0.12 From f9b040556368001b367731e7ea65227956952e25 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 25 Aug 2010 13:43:10 +0200 Subject: Fix QFileSystemEntry autotests for Windows Reviewed-by: Thomas Zander --- src/corelib/io/qfilesystementry.cpp | 2 +- tests/auto/qfilesystementry/tst_qfilesystementry.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index 2d6740e..bed5435 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -122,7 +122,7 @@ bool QFileSystemEntry::isAbsolute() const { resolveFilePath(); return (!m_filePath.isEmpty() && (m_filePath[0].unicode() == '/') -#if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX) || defined(Q_OS_SYMBIAN) +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) || (m_filePath.length() >= 2 && ((m_filePath[0].isLetter() && m_filePath[1] == QLatin1Char(':')) || (m_filePath.at(0) == QLatin1Char('/') && m_filePath.at(1) == QLatin1Char('/')))) diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp index 081beb6..58b7c6f 100644 --- a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp +++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp @@ -42,7 +42,7 @@ #include -#if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX) || defined(Q_OS_SYMBIAN) +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) # define WIN_STUFF #endif @@ -79,8 +79,8 @@ void tst_QFileSystemEntry::getSetCheck_data() QTest::newRow("relative") #if defined(WIN_STUFF) - << QByteArray("\\in\\a\\dir.tar.gz") - << "/in/a/dir.tar.gz" + << QByteArray("in\\a\\dir.tar.gz") + << "in/a/dir.tar.gz" #else << QByteArray("in/a/dir.tar.gz") << "in/a/dir.tar.gz" -- cgit v0.12 From c31cd0ecb46f1005d212a528ab74e16f2d138331 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 25 Aug 2010 14:35:10 +0200 Subject: Refactor QFileInfoPrivate::Data (Round 2) The QFileInfoPrivate::Data member class is removed now. All the methods moved to QFileInfoPrivate. QFileInfoPrivate becomes a QSharedData type. Reviewed-by: Joao --- src/corelib/io/qfileinfo.cpp | 223 ++++++++++++++------------------- src/corelib/io/qfileinfo.h | 16 ++- src/corelib/io/qfileinfo_p.h | 100 ++++++++------- tests/auto/qfileinfo/tst_qfileinfo.cpp | 17 +-- 4 files changed, 170 insertions(+), 186 deletions(-) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 4671d8c..fe557d0 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -47,24 +47,7 @@ QT_BEGIN_NAMESPACE -QFileInfoPrivate::QFileInfoPrivate(const QFileInfo *copy) -{ - if (copy) { - copy->d_func()->data->ref.ref(); - data = copy->d_func()->data; - } else { - data = new QFileInfoPrivate::Data; - } -} - -QFileInfoPrivate::~QFileInfoPrivate() -{ - if (!data->ref.deref()) - delete data; - data = 0; -} - -void QFileInfoPrivate::Data::initFileEngine(const QString &file) +void QFileInfoPrivate::initFileEngine(const QString &file) { delete fileEngine; fileEngine = 0; @@ -73,12 +56,7 @@ void QFileInfoPrivate::Data::initFileEngine(const QString &file) fileName = file; } -void QFileInfoPrivate::Data::detach(QFileInfoPrivate::Data *&data) -{ - qAtomicDetach(data); -} - -QString QFileInfoPrivate::Data::getFileName(QAbstractFileEngine::FileName name) const +QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const { if (cache_enabled && !fileNames[(int)name].isNull()) return fileNames[(int)name]; @@ -90,7 +68,7 @@ QString QFileInfoPrivate::Data::getFileName(QAbstractFileEngine::FileName name) return ret; } -QString QFileInfoPrivate::Data::getFileOwner(QAbstractFileEngine::FileOwner own) const +QString QFileInfoPrivate::getFileOwner(QAbstractFileEngine::FileOwner own) const { if (cache_enabled && !fileOwners[(int)own].isNull()) return fileOwners[(int)own]; @@ -102,7 +80,7 @@ QString QFileInfoPrivate::Data::getFileOwner(QAbstractFileEngine::FileOwner own) return ret; } -uint QFileInfoPrivate::Data::getFileFlags(QAbstractFileEngine::FileFlags request) const +uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) const { // We split the testing into tests for for LinkType, BundleType, PermsMask // and the rest. @@ -162,7 +140,7 @@ uint QFileInfoPrivate::Data::getFileFlags(QAbstractFileEngine::FileFlags request return fileFlags & request; } -QDateTime &QFileInfoPrivate::Data::getFileTime(QAbstractFileEngine::FileTime request) const +QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) const { if (!cache_enabled) clearFlags(); @@ -284,10 +262,8 @@ QFileInfo::QFileInfo() : d_ptr(new QFileInfoPrivate()) \sa setFile(), isRelative(), QDir::setCurrent(), QDir::isRelativePath() */ -QFileInfo::QFileInfo(const QString &file) : d_ptr(new QFileInfoPrivate()) +QFileInfo::QFileInfo(const QString &file) : d_ptr(new QFileInfoPrivate(file)) { - QFileInfoPrivate::Data::detach(d_ptr->data); - d_ptr->data->initFileEngine(file); } /*! @@ -299,10 +275,8 @@ QFileInfo::QFileInfo(const QString &file) : d_ptr(new QFileInfoPrivate()) \sa isRelative() */ -QFileInfo::QFileInfo(const QFile &file) : d_ptr(new QFileInfoPrivate()) +QFileInfo::QFileInfo(const QFile &file) : d_ptr(new QFileInfoPrivate(file.fileName())) { - QFileInfoPrivate::Data::detach(d_ptr->data); - d_ptr->data->initFileEngine(file.fileName()); } /*! @@ -317,16 +291,16 @@ QFileInfo::QFileInfo(const QFile &file) : d_ptr(new QFileInfoPrivate()) \sa isRelative() */ -QFileInfo::QFileInfo(const QDir &dir, const QString &file) : d_ptr(new QFileInfoPrivate()) +QFileInfo::QFileInfo(const QDir &dir, const QString &file) + : d_ptr(new QFileInfoPrivate(dir.filePath(file))) { - QFileInfoPrivate::Data::detach(d_ptr->data); - d_ptr->data->initFileEngine(dir.filePath(file)); } /*! Constructs a new QFileInfo that is a copy of the given \a fileinfo. */ -QFileInfo::QFileInfo(const QFileInfo &fileinfo) : d_ptr(new QFileInfoPrivate(&fileinfo)) +QFileInfo::QFileInfo(const QFileInfo &fileinfo) + : d_ptr(fileinfo.d_ptr) { } @@ -361,17 +335,17 @@ bool QFileInfo::operator==(const QFileInfo &fileinfo) const Q_D(const QFileInfo); // ### Qt 5: understand long and short file names on Windows // ### (GetFullPathName()). - if (fileinfo.d_func()->data == d->data) + if (fileinfo.d_ptr == d_ptr) return true; - if (!d->data->fileEngine || !fileinfo.d_func()->data->fileEngine) + if (!d->fileEngine || !fileinfo.d_ptr->fileEngine) return false; - if (d->data->fileEngine->caseSensitive() != fileinfo.d_func()->data->fileEngine->caseSensitive()) + if (d->fileEngine->caseSensitive() != fileinfo.d_ptr->fileEngine->caseSensitive()) return false; if (fileinfo.size() == size()) { //if the size isn't the same... QString file1 = canonicalFilePath(), file2 = fileinfo.canonicalFilePath(); if (file1.length() == file2.length()) { - if (!fileinfo.d_func()->data->fileEngine->caseSensitive()) { + if (!fileinfo.d_ptr->fileEngine->caseSensitive()) { for (int i = 0; i < file1.length(); i++) { if (file1.at(i).toLower() != file2.at(i).toLower()) return false; @@ -409,8 +383,7 @@ bool QFileInfo::operator==(const QFileInfo &fileinfo) */ QFileInfo &QFileInfo::operator=(const QFileInfo &fileinfo) { - Q_D(QFileInfo); - qAtomicAssign(d->data, fileinfo.d_func()->data); + d_ptr = fileinfo.d_ptr; return *this; } @@ -490,9 +463,9 @@ void QFileInfo::setFile(const QDir &dir, const QString &file) QString QFileInfo::absoluteFilePath() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - return d->data->getFileName(QAbstractFileEngine::AbsoluteName); + return d->getFileName(QAbstractFileEngine::AbsoluteName); } /*! @@ -507,9 +480,9 @@ QString QFileInfo::absoluteFilePath() const QString QFileInfo::canonicalFilePath() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - return d->data->getFileName(QAbstractFileEngine::CanonicalName); + return d->getFileName(QAbstractFileEngine::CanonicalName); } @@ -534,13 +507,13 @@ QString QFileInfo::absolutePath() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) { + if (!d->fileEngine) { return QLatin1String(""); - } else if (d->data->fileName.isEmpty()) { + } else if (d->fileName.isEmpty()) { qWarning("QFileInfo::absolutePath: Constructed with empty filename"); return QLatin1String(""); } - return d->data->getFileName(QAbstractFileEngine::AbsolutePathName); + return d->getFileName(QAbstractFileEngine::AbsolutePathName); } /*! @@ -554,9 +527,9 @@ QString QFileInfo::absolutePath() const QString QFileInfo::canonicalPath() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - return d->data->getFileName(QAbstractFileEngine::CanonicalPathName); + return d->getFileName(QAbstractFileEngine::CanonicalPathName); } /*! @@ -571,9 +544,9 @@ QString QFileInfo::canonicalPath() const QString QFileInfo::path() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - return d->data->getFileName(QAbstractFileEngine::PathName); + return d->getFileName(QAbstractFileEngine::PathName); } /*! @@ -595,9 +568,9 @@ QString QFileInfo::path() const bool QFileInfo::isRelative() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return true; - return d->data->fileEngine->isRelativePath(); + return d->fileEngine->isRelativePath(); } /*! @@ -609,12 +582,11 @@ bool QFileInfo::isRelative() const */ bool QFileInfo::makeAbsolute() { - Q_D(QFileInfo); - if (!d->data->fileEngine || !d->data->fileEngine->isRelativePath()) + if (!d_ptr.constData()->fileEngine || !d_ptr.constData()->fileEngine->isRelativePath()) return false; - QString absFileName = d->data->getFileName(QAbstractFileEngine::AbsoluteName); - QFileInfoPrivate::Data::detach(d_ptr->data); - d->data->initFileEngine(absFileName); + QString absFileName = d_ptr.constData()->getFileName(QAbstractFileEngine::AbsoluteName); + // QSharedDataPointer::operator->() will detach. + d_ptr->initFileEngine(absFileName); return true; } @@ -627,9 +599,9 @@ bool QFileInfo::makeAbsolute() bool QFileInfo::exists() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return false; - return d->data->getFileFlags(QAbstractFileEngine::ExistsFlag); + return d->getFileFlags(QAbstractFileEngine::ExistsFlag); } /*! @@ -642,8 +614,7 @@ bool QFileInfo::exists() const void QFileInfo::refresh() { Q_D(QFileInfo); - QFileInfoPrivate::Data::detach(d->data); - d->data->clear(); + d->clear(); } /*! @@ -655,9 +626,9 @@ void QFileInfo::refresh() QString QFileInfo::filePath() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - return d->data->getFileName(QAbstractFileEngine::DefaultName); + return d->getFileName(QAbstractFileEngine::DefaultName); } /*! @@ -674,9 +645,9 @@ QString QFileInfo::filePath() const QString QFileInfo::fileName() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - return d->data->getFileName(QAbstractFileEngine::BaseName); + return d->getFileName(QAbstractFileEngine::BaseName); } /*! @@ -694,9 +665,9 @@ QString QFileInfo::fileName() const QString QFileInfo::bundleName() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - return d->data->getFileName(QAbstractFileEngine::BundleName); + return d->getFileName(QAbstractFileEngine::BundleName); } /*! @@ -718,9 +689,9 @@ QString QFileInfo::bundleName() const QString QFileInfo::baseName() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - return d->data->getFileName(QAbstractFileEngine::BaseName).section(QLatin1Char('.'), 0, 0); + return d->getFileName(QAbstractFileEngine::BaseName).section(QLatin1Char('.'), 0, 0); } /*! @@ -737,9 +708,9 @@ QString QFileInfo::baseName() const QString QFileInfo::completeBaseName() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - QString name = d->data->getFileName(QAbstractFileEngine::BaseName); + QString name = d->getFileName(QAbstractFileEngine::BaseName); int index = name.lastIndexOf(QLatin1Char('.')); return (index == -1) ? name : name.left(index); } @@ -758,9 +729,9 @@ QString QFileInfo::completeBaseName() const QString QFileInfo::completeSuffix() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - QString fileName = d->data->getFileName(QAbstractFileEngine::BaseName); + QString fileName = d->getFileName(QAbstractFileEngine::BaseName); int firstDot = fileName.indexOf(QLatin1Char('.')); if (firstDot == -1) return QLatin1String(""); @@ -785,9 +756,9 @@ QString QFileInfo::completeSuffix() const QString QFileInfo::suffix() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - QString fileName = d->data->getFileName(QAbstractFileEngine::BaseName); + QString fileName = d->getFileName(QAbstractFileEngine::BaseName); int lastDot = fileName.lastIndexOf(QLatin1Char('.')); if (lastDot == -1) return QLatin1String(""); @@ -850,9 +821,9 @@ QDir QFileInfo::dir(bool absPath) const bool QFileInfo::isReadable() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return false; - return d->data->getFileFlags(QAbstractFileEngine::ReadUserPerm); + return d->getFileFlags(QAbstractFileEngine::ReadUserPerm); } /*! @@ -863,9 +834,9 @@ bool QFileInfo::isReadable() const bool QFileInfo::isWritable() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return false; - return d->data->getFileFlags(QAbstractFileEngine::WriteUserPerm); + return d->getFileFlags(QAbstractFileEngine::WriteUserPerm); } /*! @@ -876,9 +847,9 @@ bool QFileInfo::isWritable() const bool QFileInfo::isExecutable() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return false; - return d->data->getFileFlags(QAbstractFileEngine::ExeUserPerm); + return d->getFileFlags(QAbstractFileEngine::ExeUserPerm); } /*! @@ -890,9 +861,9 @@ bool QFileInfo::isExecutable() const bool QFileInfo::isHidden() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return false; - return d->data->getFileFlags(QAbstractFileEngine::HiddenFlag); + return d->getFileFlags(QAbstractFileEngine::HiddenFlag); } /*! @@ -905,9 +876,9 @@ bool QFileInfo::isHidden() const bool QFileInfo::isFile() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return false; - return d->data->getFileFlags(QAbstractFileEngine::FileType); + return d->getFileFlags(QAbstractFileEngine::FileType); } /*! @@ -919,9 +890,9 @@ bool QFileInfo::isFile() const bool QFileInfo::isDir() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return false; - return d->data->getFileFlags(QAbstractFileEngine::DirectoryType); + return d->getFileFlags(QAbstractFileEngine::DirectoryType); } @@ -935,9 +906,9 @@ bool QFileInfo::isDir() const bool QFileInfo::isBundle() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return false; - return d->data->getFileFlags(QAbstractFileEngine::BundleType); + return d->getFileFlags(QAbstractFileEngine::BundleType); } /*! @@ -960,9 +931,9 @@ bool QFileInfo::isBundle() const bool QFileInfo::isSymLink() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return false; - return d->data->getFileFlags(QAbstractFileEngine::LinkType); + return d->getFileFlags(QAbstractFileEngine::LinkType); } /*! @@ -973,9 +944,9 @@ bool QFileInfo::isSymLink() const bool QFileInfo::isRoot() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return true; - return d->data->getFileFlags(QAbstractFileEngine::RootFlag); + return d->getFileFlags(QAbstractFileEngine::RootFlag); } /*! @@ -1001,9 +972,9 @@ bool QFileInfo::isRoot() const QString QFileInfo::readLink() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - return d->data->getFileName(QAbstractFileEngine::LinkName); + return d->getFileName(QAbstractFileEngine::LinkName); } /*! @@ -1019,9 +990,9 @@ QString QFileInfo::readLink() const QString QFileInfo::owner() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - return d->data->getFileOwner(QAbstractFileEngine::OwnerUser); + return d->getFileOwner(QAbstractFileEngine::OwnerUser); } /*! @@ -1035,9 +1006,9 @@ QString QFileInfo::owner() const uint QFileInfo::ownerId() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return 0; - return d->data->fileEngine->ownerId(QAbstractFileEngine::OwnerUser); + return d->fileEngine->ownerId(QAbstractFileEngine::OwnerUser); } /*! @@ -1053,9 +1024,9 @@ uint QFileInfo::ownerId() const QString QFileInfo::group() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - return d->data->getFileOwner(QAbstractFileEngine::OwnerGroup); + return d->getFileOwner(QAbstractFileEngine::OwnerGroup); } /*! @@ -1069,9 +1040,9 @@ QString QFileInfo::group() const uint QFileInfo::groupId() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return 0; - return d->data->fileEngine->ownerId(QAbstractFileEngine::OwnerGroup); + return d->fileEngine->ownerId(QAbstractFileEngine::OwnerGroup); } /*! @@ -1090,9 +1061,9 @@ uint QFileInfo::groupId() const bool QFileInfo::permission(QFile::Permissions permissions) const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return false; - return d->data->getFileFlags(QAbstractFileEngine::FileFlags((int)permissions)) == (uint)permissions; + return d->getFileFlags(QAbstractFileEngine::FileFlags((int)permissions)) == (uint)permissions; } /*! @@ -1102,9 +1073,9 @@ bool QFileInfo::permission(QFile::Permissions permissions) const QFile::Permissions QFileInfo::permissions() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return 0; - return QFile::Permissions(d->data->getFileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask); + return QFile::Permissions(d->getFileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask); } @@ -1117,13 +1088,13 @@ QFile::Permissions QFileInfo::permissions() const qint64 QFileInfo::size() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return 0; - if (!d->data->getCachedFlag(QFileInfoPrivate::CachedSize)) { - d->data->setCachedFlag(QFileInfoPrivate::CachedSize); - d->data->fileSize = d->data->fileEngine->size(); + if (!d->getCachedFlag(QFileInfoPrivate::CachedSize)) { + d->setCachedFlag(QFileInfoPrivate::CachedSize); + d->fileSize = d->fileEngine->size(); } - return d->data->fileSize; + return d->fileSize; } /*! @@ -1142,9 +1113,9 @@ qint64 QFileInfo::size() const QDateTime QFileInfo::created() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QDateTime(); - return d->data->getFileTime(QAbstractFileEngine::CreationTime); + return d->getFileTime(QAbstractFileEngine::CreationTime); } /*! @@ -1155,9 +1126,9 @@ QDateTime QFileInfo::created() const QDateTime QFileInfo::lastModified() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QDateTime(); - return d->data->getFileTime(QAbstractFileEngine::ModificationTime); + return d->getFileTime(QAbstractFileEngine::ModificationTime); } /*! @@ -1171,9 +1142,9 @@ QDateTime QFileInfo::lastModified() const QDateTime QFileInfo::lastRead() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (!d->fileEngine) return QDateTime(); - return d->data->getFileTime(QAbstractFileEngine::AccessTime); + return d->getFileTime(QAbstractFileEngine::AccessTime); } /*! \internal @@ -1181,8 +1152,7 @@ QDateTime QFileInfo::lastRead() const */ void QFileInfo::detach() { - Q_D(QFileInfo); - QFileInfoPrivate::Data::detach(d->data); + d_ptr.detach(); } /*! @@ -1193,7 +1163,7 @@ void QFileInfo::detach() bool QFileInfo::caching() const { Q_D(const QFileInfo); - return d->data->cache_enabled; + return d->cache_enabled; } /*! @@ -1211,8 +1181,7 @@ bool QFileInfo::caching() const void QFileInfo::setCaching(bool enable) { Q_D(QFileInfo); - QFileInfoPrivate::Data::detach(d->data); - d->data->cache_enabled = enable; + d->cache_enabled = enable; } /*! diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index 7e82aed..f0128b1 100644 --- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -44,7 +44,7 @@ #include #include -#include +#include QT_BEGIN_HEADER @@ -166,10 +166,20 @@ public: #endif protected: - QScopedPointer d_ptr; + QSharedDataPointer d_ptr; private: - Q_DECLARE_PRIVATE(QFileInfo) + inline QFileInfoPrivate* d_func() + { + detach(); + return const_cast(d_ptr.constData()); + } + + inline const QFileInfoPrivate* d_func() const + { + return d_ptr.constData(); + } }; + Q_DECLARE_TYPEINFO(QFileInfo, Q_MOVABLE_TYPE); #ifdef QT3_SUPPORT diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h index a1f5419..138116e 100644 --- a/src/corelib/io/qfileinfo_p.h +++ b/src/corelib/io/qfileinfo_p.h @@ -57,68 +57,72 @@ #include "qabstractfileengine.h" #include "qdatetime.h" #include "qatomic.h" +#include "qshareddata.h" QT_BEGIN_NAMESPACE -class QFileInfoPrivate +class QFileInfoPrivate : public QSharedData { public: - QFileInfoPrivate(const QFileInfo *copy=0); - ~QFileInfoPrivate(); enum { CachedFileFlags=0x01, CachedLinkTypeFlag=0x02, CachedBundleTypeFlag=0x04, CachedMTime=0x10, CachedCTime=0x20, CachedATime=0x40, CachedSize =0x08, CachedPerms=0x80 }; - struct Data { - inline Data() - : ref(1), fileEngine(0), - cachedFlags(0), cache_enabled(1), fileFlags(0), fileSize(0) - {} - inline Data(const Data ©) - : ref(1), fileEngine(QAbstractFileEngine::create(copy.fileName)), - fileName(copy.fileName), - cachedFlags(0), cache_enabled(copy.cache_enabled), fileFlags(0), fileSize(0) - {} - inline ~Data() { delete fileEngine; } - inline void clearFlags() const { - fileFlags = 0; - cachedFlags = 0; - if (fileEngine) - (void)fileEngine->fileFlags(QAbstractFileEngine::Refresh); - } - inline void clear() { - clearFlags(); - for (int i = QAbstractFileEngine::NFileNames - 1 ; i >= 0 ; --i) - fileNames[i].clear(); - fileOwners[1].clear(); - fileOwners[0].clear(); - } - void initFileEngine(const QString &); - uint getFileFlags(QAbstractFileEngine::FileFlags) const; - QDateTime &getFileTime(QAbstractFileEngine::FileTime) const; - QString getFileName(QAbstractFileEngine::FileName) const; - QString getFileOwner(QAbstractFileEngine::FileOwner own) const; + inline QFileInfoPrivate() + : QSharedData(), fileEngine(0), + cachedFlags(0), cache_enabled(1), fileFlags(0), fileSize(0) + {} + inline QFileInfoPrivate(const QFileInfoPrivate ©) + : QSharedData(copy), fileEngine(QAbstractFileEngine::create(copy.fileName)), + fileName(copy.fileName), + cachedFlags(0), cache_enabled(copy.cache_enabled), fileFlags(0), fileSize(0) + {} + inline QFileInfoPrivate(const QString &file) + : QSharedData(), fileEngine(0), + cachedFlags(0), cache_enabled(1), fileFlags(0), fileSize(0) + { + initFileEngine(file); + } + inline ~QFileInfoPrivate() + { + delete fileEngine; + } + void initFileEngine(const QString &); - static void detach(QFileInfoPrivate::Data *&data); + inline void clearFlags() const { + fileFlags = 0; + cachedFlags = 0; + if (fileEngine) + (void)fileEngine->fileFlags(QAbstractFileEngine::Refresh); + } + inline void clear() { + clearFlags(); + for (int i = QAbstractFileEngine::NFileNames - 1 ; i >= 0 ; --i) + fileNames[i].clear(); + fileOwners[1].clear(); + fileOwners[0].clear(); + } - mutable QAtomicInt ref; + uint getFileFlags(QAbstractFileEngine::FileFlags) const; + QDateTime &getFileTime(QAbstractFileEngine::FileTime) const; + QString getFileName(QAbstractFileEngine::FileName) const; + QString getFileOwner(QAbstractFileEngine::FileOwner own) const; - QAbstractFileEngine *fileEngine; - mutable QString fileName; - mutable QString fileNames[QAbstractFileEngine::NFileNames]; - mutable QString fileOwners[2]; + QAbstractFileEngine *fileEngine; + mutable QString fileName; + mutable QString fileNames[QAbstractFileEngine::NFileNames]; + mutable QString fileOwners[2]; - mutable uint cachedFlags : 31; - mutable uint cache_enabled : 1; - mutable uint fileFlags; - mutable qint64 fileSize; - mutable QDateTime fileTimes[3]; - inline bool getCachedFlag(uint c) const - { return cache_enabled ? (cachedFlags & c) : 0; } - inline void setCachedFlag(uint c) const - { if (cache_enabled) cachedFlags |= c; } - } *data; + mutable uint cachedFlags : 31; + mutable uint cache_enabled : 1; + mutable uint fileFlags; + mutable qint64 fileSize; + mutable QDateTime fileTimes[3]; + inline bool getCachedFlag(uint c) const + { return cache_enabled ? (cachedFlags & c) : 0; } + inline void setCachedFlag(uint c) const + { if (cache_enabled) cachedFlags |= c; } }; QT_END_NAMESPACE diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index a074f4b..32aa671 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -247,13 +247,13 @@ void tst_QFileInfo::copy() QFileInfo info2(info); QFileInfoPrivate *privateInfo = getPrivate(info); QFileInfoPrivate *privateInfo2 = getPrivate(info2); - QCOMPARE(privateInfo->data, privateInfo2->data); + QCOMPARE(privateInfo, privateInfo2); //operator = QFileInfo info3 = info; QFileInfoPrivate *privateInfo3 = getPrivate(info3); - QCOMPARE(privateInfo->data, privateInfo3->data); - QCOMPARE(privateInfo2->data, privateInfo3->data); + QCOMPARE(privateInfo, privateInfo3); + QCOMPARE(privateInfo2, privateInfo3); //refreshing info3 will detach it QFile file(info.absoluteFilePath()); @@ -275,9 +275,10 @@ void tst_QFileInfo::copy() QTest::qWait(5000); #endif info3.refresh(); - QVERIFY(privateInfo->data != privateInfo3->data); - QVERIFY(privateInfo2->data != privateInfo3->data); - QCOMPARE(privateInfo->data, privateInfo2->data); + privateInfo3 = getPrivate(info3); + QVERIFY(privateInfo != privateInfo3); + QVERIFY(privateInfo2 != privateInfo3); + QCOMPARE(privateInfo, privateInfo2); } void tst_QFileInfo::isFile_data() @@ -1241,8 +1242,8 @@ void tst_QFileInfo::isLocalFs() QFileInfo info(path); QFileInfoPrivate *privateInfo = getPrivate(info); - QVERIFY(privateInfo->data->fileEngine); - QCOMPARE(bool(privateInfo->data->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag) + QVERIFY(privateInfo->fileEngine); + QCOMPARE(bool(privateInfo->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag) & QAbstractFileEngine::LocalDiskFlag), isLocalFs); } -- cgit v0.12 From c4181bf7422a6b6c58d87b449a7066ae9e65e87a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 25 Aug 2010 13:38:32 +0200 Subject: Removed QDirPrivate layer of indirection Merged QDirPrivate with QDirPrivate::Data, as QDirPrivate served no purpose by itself, only adding an additional layer of indirection to the potentially shared private data, and an unnecessary allocation. Now, QDir holds a QSharedDataPointer to its private data. Private data will be shared among copied instances with COW semantics. Still, this sharing is very limited as plenty of regular use cases will cause the shared data to detach, such as refreshing the file lists. As the use QSharedDataPointer breaks usage of the Q_DECLARE_PRIVATE macro, we manually define the d_func'tions. Non-const d_func detaches on shared data. A detach function was added to the public interface to support this. (On a side note, QFileInfo already exposes a similar detach function). As much as possible, detach is handled implicitly inside the Q_D macro, through the d_func() non-const overload. On the other hand, implicit creation of file engines through detach was made explicit with a call to a new initFileEngine function. Reviewed-by: Thomas Zander --- src/corelib/io/qdir.cpp | 427 +++++++++++++++++++++++------------------------- src/corelib/io/qdir.h | 18 +- 2 files changed, 216 insertions(+), 229 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 5d56529..3e64de9 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -82,117 +82,105 @@ static QString driveSpec(const QString &path) //************* QDirPrivate class QDirPrivate + : public QSharedData { - friend struct QScopedPointerDeleter; - public: - QDirPrivate(const QDir *copy = 0); - ~QDirPrivate(); - - struct Data { - inline Data() - : ref(1), + QDirPrivate() + : QSharedData() #ifdef QT3_SUPPORT - filterSepChar(0), matchAllDirs(false), + , filterSepChar(0) + , matchAllDirs(false) #endif - fileEngine(0), listsDirty(1) - {} - inline Data(const Data ©) - : ref(1), path(copy.path), nameFilters(copy.nameFilters), sort(copy.sort), - filters(copy.filters), + , fileEngine(0) + , listsDirty(1) + { + } + + QDirPrivate(const QDirPrivate ©) + : QSharedData(copy) + , path(copy.path) + , nameFilters(copy.nameFilters) + , sort(copy.sort) + , filters(copy.filters) #ifdef QT3_SUPPORT - filterSepChar(copy.filterSepChar), matchAllDirs(copy.matchAllDirs), + , filterSepChar(copy.filterSepChar) + , matchAllDirs(copy.matchAllDirs) #endif - fileEngine(0), listsDirty(1) - {} - inline ~Data() - { delete fileEngine; } - - void updateFileLists() const; - static void sortFileList(QDir::SortFlags, QFileInfoList &, QStringList *, QFileInfoList *); - - static inline QChar getFilterSepChar(const QString &nameFilter) - { - QChar sep(QLatin1Char(';')); - int i = nameFilter.indexOf(sep, 0); - if (i == -1 && nameFilter.indexOf(QLatin1Char(' '), 0) != -1) - sep = QChar(QLatin1Char(' ')); - return sep; - } + , fileEngine(0) + , listsDirty(1) + { + } - static inline QStringList splitFilters(const QString &nameFilter, QChar sep = 0) - { - if (sep == 0) - sep = getFilterSepChar(nameFilter); - QStringList ret = nameFilter.split(sep); - for (int i = 0; i < ret.count(); ++i) - ret[i] = ret[i].trimmed(); - return ret; - } + ~QDirPrivate() + { + delete fileEngine; + } - static void detach(QDirPrivate::Data *&data, bool createFileEngine = true); + void initFileEngine(); + void updateFileLists() const; - inline void setPath(QString p) - { - if ((p.endsWith(QLatin1Char('/')) || p.endsWith(QLatin1Char('\\'))) - && p.length() > 1) { -#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) - if (!(p.length() == 3 && p.at(1) == QLatin1Char(':'))) -#endif - p.truncate(p.length() - 1); - } + static void sortFileList(QDir::SortFlags, QFileInfoList &, QStringList *, QFileInfoList *); - delete fileEngine; - fileEngine = QAbstractFileEngine::create(p); + static inline QChar getFilterSepChar(const QString &nameFilter) + { + QChar sep(QLatin1Char(';')); + int i = nameFilter.indexOf(sep, 0); + if (i == -1 && nameFilter.indexOf(QLatin1Char(' '), 0) != -1) + sep = QChar(QLatin1Char(' ')); + return sep; + } - // set the path to be the qt friendly version so then we can operate on it using just / - path = fileEngine->fileName(QAbstractFileEngine::DefaultName); - clear(); - } + static inline QStringList splitFilters(const QString &nameFilter, QChar sep = 0) + { + if (sep == 0) + sep = getFilterSepChar(nameFilter); + QStringList ret = nameFilter.split(sep); + for (int i = 0; i < ret.count(); ++i) + ret[i] = ret[i].trimmed(); + return ret; + } - inline void clear() { - listsDirty = 1; - files.clear(); - fileInfos.clear(); + inline void setPath(QString p) + { + if ((p.endsWith(QLatin1Char('/')) || p.endsWith(QLatin1Char('\\'))) + && p.length() > 1) { +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + if (!(p.length() == 3 && p.at(1) == QLatin1Char(':'))) +#endif + p.truncate(p.length() - 1); } - mutable QAtomicInt ref; + delete fileEngine; + fileEngine = QAbstractFileEngine::create(p); + + // set the path to be the qt friendly version so then we can operate on it using just / + path = fileEngine->fileName(QAbstractFileEngine::DefaultName); + clear(); + } - QString path; - QStringList nameFilters; - QDir::SortFlags sort; - QDir::Filters filters; + inline void clear() { + listsDirty = 1; + files.clear(); + fileInfos.clear(); + } + + QString path; + QStringList nameFilters; + QDir::SortFlags sort; + QDir::Filters filters; #ifdef QT3_SUPPORT - QChar filterSepChar; - bool matchAllDirs; + QChar filterSepChar; + bool matchAllDirs; #endif - mutable QAbstractFileEngine *fileEngine; - mutable uint listsDirty : 1; - mutable QStringList files; - mutable QFileInfoList fileInfos; - } *data; + QAbstractFileEngine *fileEngine; + mutable uint listsDirty : 1; + mutable QStringList files; + mutable QFileInfoList fileInfos; }; -QDirPrivate::QDirPrivate(const QDir *copy) -{ - if (copy) { - copy->d_func()->data->ref.ref(); - data = copy->d_func()->data; - } else { - data = new QDirPrivate::Data; - } -} - -QDirPrivate::~QDirPrivate() -{ - if (!data->ref.deref()) - delete data; - data = 0; -} - /* For sorting */ struct QDirSortItem { @@ -273,7 +261,7 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt return r < 0; } -inline void QDirPrivate::Data::sortFileList(QDir::SortFlags sort, QFileInfoList &l, +inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l, QStringList *names, QFileInfoList *infos) { // names and infos are always empty lists or 0 here @@ -304,7 +292,7 @@ inline void QDirPrivate::Data::sortFileList(QDir::SortFlags sort, QFileInfoList } } -inline void QDirPrivate::Data::updateFileLists() const +inline void QDirPrivate::updateFileLists() const { if (listsDirty) { QFileInfoList l; @@ -318,14 +306,11 @@ inline void QDirPrivate::Data::updateFileLists() const } } -void QDirPrivate::Data::detach(QDirPrivate::Data *&data, bool createFileEngine) +void QDirPrivate::initFileEngine() { - qAtomicDetach(data); - if (createFileEngine) { - QAbstractFileEngine *newFileEngine = QAbstractFileEngine::create(data->path); - delete data->fileEngine; - data->fileEngine = newFileEngine; - } + QAbstractFileEngine *newFileEngine = QAbstractFileEngine::create(path); + delete fileEngine; + fileEngine = newFileEngine; } /*! @@ -512,11 +497,10 @@ void QDirPrivate::Data::detach(QDirPrivate::Data *&data, bool createFileEngine) QDir::QDir(const QString &path) : d_ptr(new QDirPrivate) { Q_D(QDir); - QDirPrivate::Data::detach(d->data, false); - d->data->setPath(path.isEmpty() ? QString::fromLatin1(".") : path); - d->data->nameFilters = QStringList(QString::fromLatin1("*")); - d->data->filters = AllEntries; - d->data->sort = SortFlags(Name | IgnoreCase); + d->setPath(path.isEmpty() ? QString::fromLatin1(".") : path); + d->nameFilters = QStringList(QString::fromLatin1("*")); + d->filters = AllEntries; + d->sort = SortFlags(Name | IgnoreCase); } /*! @@ -541,23 +525,22 @@ QDir::QDir(const QString &path, const QString &nameFilter, SortFlags sort, Filters filters) : d_ptr(new QDirPrivate) { Q_D(QDir); - QDirPrivate::Data::detach(d->data, false); - d->data->setPath(path.isEmpty() ? QString::fromLatin1(".") : path); - d->data->nameFilters = QDir::nameFiltersFromString(nameFilter); - bool empty = d->data->nameFilters.isEmpty(); + d->setPath(path.isEmpty() ? QString::fromLatin1(".") : path); + d->nameFilters = QDir::nameFiltersFromString(nameFilter); + bool empty = d->nameFilters.isEmpty(); if (!empty) { empty = true; - for (int i = 0; i < d->data->nameFilters.size(); ++i) { - if (!d->data->nameFilters.at(i).isEmpty()) { + for (int i = 0; i < d->nameFilters.size(); ++i) { + if (!d->nameFilters.at(i).isEmpty()) { empty = false; break; } } } if (empty) - d->data->nameFilters = QStringList(QString::fromLatin1("*")); - d->data->sort = sort; - d->data->filters = filters; + d->nameFilters = QStringList(QString::fromLatin1("*")); + d->sort = sort; + d->filters = filters; } /*! @@ -566,7 +549,8 @@ QDir::QDir(const QString &path, const QString &nameFilter, \sa operator=() */ -QDir::QDir(const QDir &dir) : d_ptr(new QDirPrivate(&dir)) +QDir::QDir(const QDir &dir) + : d_ptr(dir.d_ptr) { } @@ -578,6 +562,11 @@ QDir::~QDir() { } +void QDir::detach() +{ + d_ptr.detach(); +} + /*! Sets the path of the directory to \a path. The path is cleaned of redundant ".", ".." and of multiple separators. No check is made @@ -596,9 +585,7 @@ QDir::~QDir() */ void QDir::setPath(const QString &path) { - Q_D(QDir); - QDirPrivate::Data::detach(d->data, false); - d->data->setPath(path); + d_ptr->setPath(path); } /*! @@ -614,7 +601,7 @@ void QDir::setPath(const QString &path) QString QDir::path() const { Q_D(const QDir); - return d->data->path; + return d->path; } /*! @@ -628,7 +615,7 @@ QString QDir::path() const QString QDir::absolutePath() const { Q_D(const QDir); - QString ret = d->data->path; + QString ret = d->path; if (QDir::isRelativePath(ret)) ret = absoluteFilePath(QString::fromLatin1("")); return cleanPath(ret); @@ -654,9 +641,9 @@ QString QDir::canonicalPath() const { Q_D(const QDir); - if (!d->data->fileEngine) + if (!d->fileEngine) return QLatin1String(""); - return cleanPath(d->data->fileEngine->fileName(QAbstractFileEngine::CanonicalName)); + return cleanPath(d->fileEngine->fileName(QAbstractFileEngine::CanonicalName)); } /*! @@ -673,10 +660,10 @@ QString QDir::canonicalPath() const QString QDir::dirName() const { Q_D(const QDir); - int pos = d->data->path.lastIndexOf(QLatin1Char('/')); + int pos = d->path.lastIndexOf(QLatin1Char('/')); if (pos == -1) - return d->data->path; - return d->data->path.mid(pos + 1); + return d->path; + return d->path.mid(pos + 1); } /*! @@ -694,7 +681,7 @@ QString QDir::filePath(const QString &fileName) const if (isAbsolutePath(fileName)) return QString(fileName); - QString ret = d->data->path; + QString ret = d->path; if (!fileName.isEmpty()) { if (!ret.isEmpty() && ret[(int)ret.length()-1] != QLatin1Char('/') && fileName[0] != QLatin1Char('/')) ret += QLatin1Char('/'); @@ -716,18 +703,18 @@ QString QDir::absoluteFilePath(const QString &fileName) const Q_D(const QDir); if (isAbsolutePath(fileName)) return fileName; - if (!d->data->fileEngine) + if (!d->fileEngine) return fileName; QString ret; #ifndef QT_NO_FSFILEENGINE - if (isRelativePath(d->data->path)) //get pwd + if (isRelativePath(d->path)) //get pwd ret = QFSFileEngine::currentPath(fileName); #endif - if (!d->data->path.isEmpty() && d->data->path != QLatin1String(".")) { + if (!d->path.isEmpty() && d->path != QLatin1String(".")) { if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) ret += QLatin1Char('/'); - ret += d->data->path; + ret += d->path; } if (!fileName.isEmpty()) { if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) @@ -875,11 +862,12 @@ QString QDir::fromNativeSeparators(const QString &pathName) */ bool QDir::cd(const QString &dirName) { - Q_D(QDir); + // Don't detach just yet. + const QDirPrivate * const d = d_ptr.constData(); if (dirName.isEmpty() || dirName == QLatin1String(".")) return true; - QString newPath = d->data->path; + QString newPath = d->path; if (isAbsolutePath(dirName)) { newPath = cleanPath(dirName); } else { @@ -892,7 +880,7 @@ bool QDir::cd(const QString &dirName) newPath += dirName; if (dirName.indexOf(QLatin1Char('/')) >= 0 - || d->data->path == QLatin1String(".") + || d->path == QLatin1String(".") || dirName == QLatin1String("..")) { newPath = cleanPath(newPath); /* @@ -939,8 +927,7 @@ bool QDir::cdUp() QStringList QDir::nameFilters() const { Q_D(const QDir); - - return d->data->nameFilters; + return d->nameFilters; } /*! @@ -961,10 +948,10 @@ QStringList QDir::nameFilters() const void QDir::setNameFilters(const QStringList &nameFilters) { Q_D(QDir); + d->initFileEngine(); + d->clear(); - QDirPrivate::Data::detach(d->data); - d->data->clear(); - d->data->nameFilters = nameFilters; + d->nameFilters = nameFilters; } /*! @@ -1068,8 +1055,7 @@ QStringList QDir::searchPaths(const QString &prefix) QDir::Filters QDir::filter() const { Q_D(const QDir); - - return d->data->filters; + return d->filters; } /*! @@ -1151,10 +1137,10 @@ QDir::Filters QDir::filter() const void QDir::setFilter(Filters filters) { Q_D(QDir); + d->initFileEngine(); + d->clear(); - QDirPrivate::Data::detach(d->data); - d->data->clear(); - d->data->filters = filters; + d->filters = filters; } /*! @@ -1165,8 +1151,7 @@ void QDir::setFilter(Filters filters) QDir::SortFlags QDir::sorting() const { Q_D(const QDir); - - return d->data->sort; + return d->sort; } /*! @@ -1210,10 +1195,10 @@ QDir::SortFlags QDir::sorting() const void QDir::setSorting(SortFlags sort) { Q_D(QDir); + d->initFileEngine(); + d->clear(); - QDirPrivate::Data::detach(d->data); - d->data->clear(); - d->data->sort = sort; + d->sort = sort; } /*! @@ -1226,9 +1211,8 @@ void QDir::setSorting(SortFlags sort) uint QDir::count() const { Q_D(const QDir); - - d->data->updateFileLists(); - return d->data->files.count(); + d->updateFileLists(); + return d->files.count(); } /*! @@ -1241,9 +1225,8 @@ uint QDir::count() const QString QDir::operator[](int pos) const { Q_D(const QDir); - - d->data->updateFileLists(); - return d->data->files[pos]; + d->updateFileLists(); + return d->files[pos]; } /*! @@ -1268,8 +1251,7 @@ QString QDir::operator[](int pos) const QStringList QDir::entryList(Filters filters, SortFlags sort) const { Q_D(const QDir); - - return entryList(d->data->nameFilters, filters, sort); + return entryList(d->nameFilters, filters, sort); } @@ -1292,8 +1274,7 @@ QStringList QDir::entryList(Filters filters, SortFlags sort) const QFileInfoList QDir::entryInfoList(Filters filters, SortFlags sort) const { Q_D(const QDir); - - return entryInfoList(d->data->nameFilters, filters, sort); + return entryInfoList(d->nameFilters, filters, sort); } /*! @@ -1318,27 +1299,27 @@ QStringList QDir::entryList(const QStringList &nameFilters, Filters filters, Q_D(const QDir); if (filters == NoFilter) - filters = d->data->filters; + filters = d->filters; #ifdef QT3_SUPPORT - if (d->data->matchAllDirs) + if (d->matchAllDirs) filters |= AllDirs; #endif if (sort == NoSort) - sort = d->data->sort; + sort = d->sort; - if (filters == d->data->filters && sort == d->data->sort && nameFilters == d->data->nameFilters) { - d->data->updateFileLists(); - return d->data->files; + if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) { + d->updateFileLists(); + return d->files; } QFileInfoList l; - QDirIterator it(d->data->path, nameFilters, filters); + QDirIterator it(d->path, nameFilters, filters); while (it.hasNext()) { it.next(); l.append(it.fileInfo()); } QStringList ret; - d->data->sortFileList(sort, l, &ret, 0); + d->sortFileList(sort, l, &ret, 0); return ret; } @@ -1364,27 +1345,27 @@ QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filter Q_D(const QDir); if (filters == NoFilter) - filters = d->data->filters; + filters = d->filters; #ifdef QT3_SUPPORT - if (d->data->matchAllDirs) + if (d->matchAllDirs) filters |= AllDirs; #endif if (sort == NoSort) - sort = d->data->sort; + sort = d->sort; - if (filters == d->data->filters && sort == d->data->sort && nameFilters == d->data->nameFilters) { - d->data->updateFileLists(); - return d->data->fileInfos; + if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) { + d->updateFileLists(); + return d->fileInfos; } QFileInfoList l; - QDirIterator it(d->data->path, nameFilters, filters); + QDirIterator it(d->path, nameFilters, filters); while (it.hasNext()) { it.next(); l.append(it.fileInfo()); } QFileInfoList ret; - d->data->sortFileList(sort, l, 0, &ret); + d->sortFileList(sort, l, 0, &ret); return ret; } @@ -1403,11 +1384,11 @@ bool QDir::mkdir(const QString &dirName) const qWarning("QDir::mkdir: Empty or null file name(s)"); return false; } - if (!d->data->fileEngine) + if (!d->fileEngine) return false; QString fn = filePath(dirName); - return d->data->fileEngine->mkdir(fn, false); + return d->fileEngine->mkdir(fn, false); } /*! @@ -1427,11 +1408,11 @@ bool QDir::rmdir(const QString &dirName) const qWarning("QDir::rmdir: Empty or null file name(s)"); return false; } - if (!d->data->fileEngine) + if (!d->fileEngine) return false; QString fn = filePath(dirName); - return d->data->fileEngine->rmdir(fn, false); + return d->fileEngine->rmdir(fn, false); } /*! @@ -1452,11 +1433,11 @@ bool QDir::mkpath(const QString &dirPath) const qWarning("QDir::mkpath: Empty or null file name(s)"); return false; } - if (!d->data->fileEngine) + if (!d->fileEngine) return false; QString fn = filePath(dirPath); - return d->data->fileEngine->mkdir(fn, true); + return d->fileEngine->mkdir(fn, true); } /*! @@ -1478,11 +1459,11 @@ bool QDir::rmpath(const QString &dirPath) const qWarning("QDir::rmpath: Empty or null file name(s)"); return false; } - if (!d->data->fileEngine) + if (!d->fileEngine) return false; QString fn = filePath(dirPath); - return d->data->fileEngine->rmdir(fn, true); + return d->fileEngine->rmdir(fn, true); } /*! @@ -1498,10 +1479,10 @@ bool QDir::isReadable() const { Q_D(const QDir); - if (!d->data->fileEngine) + if (!d->fileEngine) return false; const QAbstractFileEngine::FileFlags info = - d->data->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType + d->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType | QAbstractFileEngine::PermsMask); if (!(info & QAbstractFileEngine::DirectoryType)) return false; @@ -1523,10 +1504,10 @@ bool QDir::exists() const { Q_D(const QDir); - if (!d->data->fileEngine) + if (!d->fileEngine) return false; const QAbstractFileEngine::FileFlags info = - d->data->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType + d->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType | QAbstractFileEngine::ExistsFlag | QAbstractFileEngine::Refresh); if (!(info & QAbstractFileEngine::DirectoryType)) @@ -1550,9 +1531,9 @@ bool QDir::isRoot() const { Q_D(const QDir); - if (!d->data->fileEngine) + if (!d->fileEngine) return true; - return d->data->fileEngine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::RootFlag; + return d->fileEngine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::RootFlag; } /*! @@ -1584,9 +1565,9 @@ bool QDir::isRelative() const { Q_D(const QDir); - if (!d->data->fileEngine) + if (!d->fileEngine) return false; - return d->data->fileEngine->isRelativePath(); + return d->fileEngine->isRelativePath(); } @@ -1599,17 +1580,19 @@ bool QDir::isRelative() const */ bool QDir::makeAbsolute() // ### What do the return values signify? { - Q_D(QDir); - - if (!d->data->fileEngine) + if (!d_ptr.constData()->fileEngine) return false; - QString absolutePath = d->data->fileEngine->fileName(QAbstractFileEngine::AbsoluteName); + QString absolutePath = d_ptr.constData()->fileEngine->fileName(QAbstractFileEngine::AbsoluteName); if (QDir::isRelativePath(absolutePath)) return false; - QDirPrivate::Data::detach(d->data); - d->data->path = absolutePath; - d->data->fileEngine->setFileName(absolutePath); - if (!(d->data->fileEngine->fileFlags(QAbstractFileEngine::TypesMask) & QAbstractFileEngine::DirectoryType)) + + Q_D(QDir); + + d->path = absolutePath; + d->initFileEngine(); + d->clear(); + + if (!(d->fileEngine->fileFlags(QAbstractFileEngine::TypesMask) & QAbstractFileEngine::DirectoryType)) return false; return true; } @@ -1628,16 +1611,16 @@ bool QDir::operator==(const QDir &dir) const const QDirPrivate *d = d_func(); const QDirPrivate *other = dir.d_func(); - if (d->data == other->data) + if (d == other) return true; - Q_ASSERT(d->data->fileEngine && other->data->fileEngine); - if (d->data->fileEngine->caseSensitive() != other->data->fileEngine->caseSensitive()) + Q_ASSERT(d->fileEngine && other->fileEngine); + if (d->fileEngine->caseSensitive() != other->fileEngine->caseSensitive()) return false; - if (d->data->filters == other->data->filters - && d->data->sort == other->data->sort - && d->data->nameFilters == other->data->nameFilters) { + if (d->filters == other->filters + && d->sort == other->sort + && d->nameFilters == other->nameFilters) { QString dir1 = absolutePath(), dir2 = dir.absolutePath(); - if (!other->data->fileEngine->caseSensitive()) + if (!other->fileEngine->caseSensitive()) return (dir1.toLower() == dir2.toLower()); return (dir1 == dir2); @@ -1655,8 +1638,7 @@ QDir &QDir::operator=(const QDir &dir) if (this == &dir) return *this; - Q_D(QDir); - qAtomicAssign(d->data, dir.d_func()->data); + d_ptr = dir.d_ptr; return *this; } @@ -1670,10 +1652,7 @@ QDir &QDir::operator=(const QDir &dir) */ QDir &QDir::operator=(const QString &path) { - Q_D(QDir); - - QDirPrivate::Data::detach(d->data, false); - d->data->setPath(path); + d_ptr->setPath(path); return *this; } @@ -1717,13 +1696,12 @@ bool QDir::remove(const QString &fileName) */ bool QDir::rename(const QString &oldName, const QString &newName) { - Q_D(QDir); - if (oldName.isEmpty() || newName.isEmpty()) { qWarning("QDir::rename: Empty or null file name(s)"); return false; } - if (!d->data->fileEngine) + + if (!d_ptr.constData()->fileEngine) return false; QFile file(filePath(oldName)); @@ -2163,10 +2141,9 @@ bool QDir::isRelativePath(const QString &path) */ void QDir::refresh() const { - Q_D(const QDir); - - QDirPrivate::Data::detach(const_cast(d)->data); - d->data->clear(); + QDirPrivate *d = const_cast(this)->d_func(); + d->initFileEngine(); + d->clear(); } /*! @@ -2178,7 +2155,7 @@ void QDir::refresh() const */ QStringList QDir::nameFiltersFromString(const QString &nameFilter) { - return QDirPrivate::Data::splitFilters(nameFilter); + return QDirPrivate::splitFilters(nameFilter); } /*! @@ -2243,7 +2220,7 @@ QStringList QDir::nameFiltersFromString(const QString &nameFilter) bool QDir::matchAllDirs() const { Q_D(const QDir); - return d->data->matchAllDirs; + return d->matchAllDirs; } @@ -2255,10 +2232,10 @@ bool QDir::matchAllDirs() const void QDir::setMatchAllDirs(bool on) { Q_D(QDir); + d->initFileEngine(); + d->clear(); - QDirPrivate::Data::detach(d->data); - d->data->clear(); - d->data->matchAllDirs = on; + d->matchAllDirs = on; } /*! @@ -2267,8 +2244,7 @@ void QDir::setMatchAllDirs(bool on) QString QDir::nameFilter() const { Q_D(const QDir); - - return nameFilters().join(QString(d->data->filterSepChar)); + return nameFilters().join(QString(d->filterSepChar)); } /*! @@ -2294,9 +2270,8 @@ QString QDir::nameFilter() const void QDir::setNameFilter(const QString &nameFilter) { Q_D(QDir); - - d->data->filterSepChar = QDirPrivate::Data::getFilterSepChar(nameFilter); - setNameFilters(QDirPrivate::Data::splitFilters(nameFilter, d->data->filterSepChar)); + d->filterSepChar = QDirPrivate::getFilterSepChar(nameFilter); + setNameFilters(QDirPrivate::splitFilters(nameFilter, d->filterSepChar)); } /*! diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h index 28da271..abfe387 100644 --- a/src/corelib/io/qdir.h +++ b/src/corelib/io/qdir.h @@ -45,7 +45,7 @@ #include #include #include -#include +#include QT_BEGIN_HEADER @@ -58,9 +58,19 @@ class QDirPrivate; class Q_CORE_EXPORT QDir { protected: - QScopedPointer d_ptr; + QSharedDataPointer d_ptr; private: - Q_DECLARE_PRIVATE(QDir) + inline QDirPrivate* d_func() + { + detach(); + return const_cast(d_ptr.constData()); + } + + inline const QDirPrivate* d_func() const + { + return d_ptr.constData(); + } + public: enum Filter { Dirs = 0x001, Files = 0x002, @@ -130,6 +140,8 @@ public: QDir &operator=(const QDir &); QDir &operator=(const QString &path); + void detach(); + void setPath(const QString &path); QString path() const; QString absolutePath() const; -- cgit v0.12 From 84373eb1c5f78874cf44b6e63cbffd4d49820f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 25 Aug 2010 14:18:03 +0200 Subject: QDirPrivate refactoring Moved common initialization code from QDir ctor to QDirPrivate. Reviewed-by: Thomas Zander --- src/corelib/io/qdir.cpp | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 3e64de9..02f0e06 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -85,8 +85,14 @@ class QDirPrivate : public QSharedData { public: - QDirPrivate() + QDirPrivate(const QString &path, + const QStringList &nameFilters_ = QStringList(), + QDir::SortFlags sort_ = QDir::SortFlags(QDir::Name | QDir::IgnoreCase), + QDir::Filters filters_ = QDir::AllEntries) : QSharedData() + , nameFilters(nameFilters_) + , sort(sort_) + , filters(filters_) #ifdef QT3_SUPPORT , filterSepChar(0) , matchAllDirs(false) @@ -94,6 +100,20 @@ public: , fileEngine(0) , listsDirty(1) { + setPath(path.isEmpty() ? QString::fromLatin1(".") : path); + + bool empty = nameFilters.isEmpty(); + if (!empty) { + empty = true; + for (int i = 0; i < nameFilters.size(); ++i) { + if (!nameFilters.at(i).isEmpty()) { + empty = false; + break; + } + } + } + if (empty) + nameFilters = QStringList(QString::fromLatin1("*")); } QDirPrivate(const QDirPrivate ©) @@ -494,13 +514,8 @@ void QDirPrivate::initFileEngine() \sa currentPath() */ -QDir::QDir(const QString &path) : d_ptr(new QDirPrivate) +QDir::QDir(const QString &path) : d_ptr(new QDirPrivate(path)) { - Q_D(QDir); - d->setPath(path.isEmpty() ? QString::fromLatin1(".") : path); - d->nameFilters = QStringList(QString::fromLatin1("*")); - d->filters = AllEntries; - d->sort = SortFlags(Name | IgnoreCase); } /*! @@ -522,25 +537,9 @@ QDir::QDir(const QString &path) : d_ptr(new QDirPrivate) \sa exists(), setPath(), setNameFilter(), setFilter(), setSorting() */ QDir::QDir(const QString &path, const QString &nameFilter, - SortFlags sort, Filters filters) : d_ptr(new QDirPrivate) + SortFlags sort, Filters filters) + : d_ptr(new QDirPrivate(path, QDir::nameFiltersFromString(nameFilter), sort, filters)) { - Q_D(QDir); - d->setPath(path.isEmpty() ? QString::fromLatin1(".") : path); - d->nameFilters = QDir::nameFiltersFromString(nameFilter); - bool empty = d->nameFilters.isEmpty(); - if (!empty) { - empty = true; - for (int i = 0; i < d->nameFilters.size(); ++i) { - if (!d->nameFilters.at(i).isEmpty()) { - empty = false; - break; - } - } - } - if (empty) - d->nameFilters = QStringList(QString::fromLatin1("*")); - d->sort = sort; - d->filters = filters; } /*! -- cgit v0.12 From 72b00f0b6285aed47009067be4d92869d128856e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 25 Aug 2010 15:16:51 +0200 Subject: QDirPrivate refactoring Some renaming to make intent clearer and improve consistency: listsDirty => listsInitialized (logic inverted) updateFileLists => initFileLists clear => clearFileLists Also note that initializing file lists shouldn't trigger detach, because no previous version of the cached data has been seen. Reviewed-by: Thomas Zander --- src/corelib/io/qdir.cpp | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 02f0e06..a88b284 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -98,7 +98,7 @@ public: , matchAllDirs(false) #endif , fileEngine(0) - , listsDirty(1) + , fileListsInitialized(false) { setPath(path.isEmpty() ? QString::fromLatin1(".") : path); @@ -127,7 +127,7 @@ public: , matchAllDirs(copy.matchAllDirs) #endif , fileEngine(0) - , listsDirty(1) + , fileListsInitialized(false) { } @@ -137,7 +137,7 @@ public: } void initFileEngine(); - void updateFileLists() const; + void initFileLists() const; static void sortFileList(QDir::SortFlags, QFileInfoList &, QStringList *, QFileInfoList *); @@ -175,11 +175,11 @@ public: // set the path to be the qt friendly version so then we can operate on it using just / path = fileEngine->fileName(QAbstractFileEngine::DefaultName); - clear(); + clearFileLists(); } - inline void clear() { - listsDirty = 1; + inline void clearFileLists() { + fileListsInitialized = false; files.clear(); fileInfos.clear(); } @@ -196,7 +196,7 @@ public: QAbstractFileEngine *fileEngine; - mutable uint listsDirty : 1; + mutable bool fileListsInitialized; mutable QStringList files; mutable QFileInfoList fileInfos; }; @@ -312,9 +312,9 @@ inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l, } } -inline void QDirPrivate::updateFileLists() const +inline void QDirPrivate::initFileLists() const { - if (listsDirty) { + if (!fileListsInitialized) { QFileInfoList l; QDirIterator it(path, nameFilters, filters); while (it.hasNext()) { @@ -322,7 +322,7 @@ inline void QDirPrivate::updateFileLists() const l.append(it.fileInfo()); } sortFileList(sort, l, &files, &fileInfos); - listsDirty = 0; + fileListsInitialized = true; } } @@ -948,7 +948,7 @@ void QDir::setNameFilters(const QStringList &nameFilters) { Q_D(QDir); d->initFileEngine(); - d->clear(); + d->clearFileLists(); d->nameFilters = nameFilters; } @@ -1137,7 +1137,7 @@ void QDir::setFilter(Filters filters) { Q_D(QDir); d->initFileEngine(); - d->clear(); + d->clearFileLists(); d->filters = filters; } @@ -1195,7 +1195,7 @@ void QDir::setSorting(SortFlags sort) { Q_D(QDir); d->initFileEngine(); - d->clear(); + d->clearFileLists(); d->sort = sort; } @@ -1210,7 +1210,7 @@ void QDir::setSorting(SortFlags sort) uint QDir::count() const { Q_D(const QDir); - d->updateFileLists(); + d->initFileLists(); return d->files.count(); } @@ -1224,7 +1224,7 @@ uint QDir::count() const QString QDir::operator[](int pos) const { Q_D(const QDir); - d->updateFileLists(); + d->initFileLists(); return d->files[pos]; } @@ -1307,7 +1307,7 @@ QStringList QDir::entryList(const QStringList &nameFilters, Filters filters, sort = d->sort; if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) { - d->updateFileLists(); + d->initFileLists(); return d->files; } @@ -1353,7 +1353,7 @@ QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filter sort = d->sort; if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) { - d->updateFileLists(); + d->initFileLists(); return d->fileInfos; } @@ -1589,7 +1589,7 @@ bool QDir::makeAbsolute() // ### What do the return values signify? d->path = absolutePath; d->initFileEngine(); - d->clear(); + d->clearFileLists(); if (!(d->fileEngine->fileFlags(QAbstractFileEngine::TypesMask) & QAbstractFileEngine::DirectoryType)) return false; @@ -2142,7 +2142,7 @@ void QDir::refresh() const { QDirPrivate *d = const_cast(this)->d_func(); d->initFileEngine(); - d->clear(); + d->clearFileLists(); } /*! @@ -2232,7 +2232,7 @@ void QDir::setMatchAllDirs(bool on) { Q_D(QDir); d->initFileEngine(); - d->clear(); + d->clearFileLists(); d->matchAllDirs = on; } -- cgit v0.12 From 1218e1ecfee17aec798d73e469fea292b93f2246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 25 Aug 2010 15:25:22 +0200 Subject: QDirPrivate refactoring While refactoring, a bug was introduced where shared data would be updated before detaching in setNameFilter. Further refactoring turned this into a double-detach, instead. Now the issue is fixed by adding the appropriate initFileEngine and nameFilters assignment, instead of calling setNameFilters to finish the job. Reviewed-by: Thomas Zander --- src/corelib/io/qdir.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index a88b284..64eea23 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -2269,8 +2269,10 @@ QString QDir::nameFilter() const void QDir::setNameFilter(const QString &nameFilter) { Q_D(QDir); + d->initFileEngine(); + d->filterSepChar = QDirPrivate::getFilterSepChar(nameFilter); - setNameFilters(QDirPrivate::splitFilters(nameFilter, d->filterSepChar)); + d->nameFilters = QDirPrivate::splitFilters(nameFilter, d->filterSepChar); } /*! -- cgit v0.12 From 852be4c69f8dd4a890d78f9ea7210ecc9e44254a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 26 Aug 2010 11:40:52 +0200 Subject: Begin defining the interface for file engines NG New file engine API is meant to be a thin layer of abstraction over native file system APIs. Stateless and static for the time being. Platform-specific implementations will follow. Reviewed-by: Thomas Zander Reviewed-by: Prasanth Ullattil --- src/corelib/io/qfilesystemengine_p.h | 27 +++++++++++++++++++++++++++ src/corelib/io/qfilesystemmetadata_p.h | 6 ++++++ 2 files changed, 33 insertions(+) diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 817f925..c1bb3b4 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -53,10 +53,37 @@ // We mean it. // +#include "qfile.h" +#include "qfilesystementry_p.h" +#include "qfilesystemmetadata_p.h" + QT_BEGIN_NAMESPACE class QFileSystemEngine { +public: + static bool isCaseSensitive(); + + static QFileSystemEntry getLinkTarget(const QFileSystemEntry &link); + static QFileSystemEntry canonicalName(const QFileSystemEntry &entry); + static QFileSystemEntry absoluteName(const QFileSystemEntry &entry); + + static QString bundleName(const QFileSystemEntry &entry); + + static bool fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, + QFileSystemMetaData::FileFlags what); + + static bool createDirectory(const QFileSystemEntry &entry, bool createParents); + static bool removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents); + + static bool createLink(const QFileSystemEntry &source, const QFileSystemEntry &target); + + static bool copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target); + static bool renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target); + static bool removeFile(const QFileSystemEntry &entry); + + static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, + QFileSystemMetaData *data = 0); }; QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index c051bc5..9664177 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -53,10 +53,16 @@ // We mean it. // +#include + QT_BEGIN_NAMESPACE class QFileSystemMetaData { +public: + enum FileFlag { + }; + Q_DECLARE_FLAGS(FileFlags, FileFlag); }; QT_END_NAMESPACE -- cgit v0.12 From 9367d50311640c1765a05b744de2ac796311fac7 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Thu, 26 Aug 2010 13:56:53 +0200 Subject: Add empty implementations of each of the filesystemengines --- src/corelib/io/io.pri | 4 + src/corelib/io/qfilesystemengine_mac.cpp | 119 ++++++++++++++++++++++++++++++ src/corelib/io/qfilesystemengine_unix.cpp | 119 ++++++++++++++++++++++++++++++ src/corelib/io/qfilesystemengine_win.cpp | 119 ++++++++++++++++++++++++++++++ 4 files changed, 361 insertions(+) create mode 100644 src/corelib/io/qfilesystemengine_mac.cpp create mode 100644 src/corelib/io/qfilesystemengine_unix.cpp create mode 100644 src/corelib/io/qfilesystemengine_win.cpp diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 0334534..d3fddaf 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -68,6 +68,7 @@ win32 { HEADERS += io/qfilesystemwatcher_win_p.h HEADERS += io/qwindowspipewriter_p.h SOURCES += io/qwindowspipewriter.cpp + SOURCES += io/qfilesystemengine_win.cpp } else:unix { SOURCES += io/qfsfileengine_unix.cpp SOURCES += io/qfsfileengine_iterator_unix.cpp @@ -76,6 +77,9 @@ win32 { macx-*: { HEADERS += io/qfilesystemwatcher_fsevents_p.h SOURCES += io/qsettings_mac.cpp io/qfilesystemwatcher_fsevents.cpp + SOURCES += io/qfilesystemengine_mac.cpp + } else { + SOURCES += io/qfilesystemengine_unix.cpp } linux-*:!symbian { diff --git a/src/corelib/io/qfilesystemengine_mac.cpp b/src/corelib/io/qfilesystemengine_mac.cpp new file mode 100644 index 0000000..ac71f0e --- /dev/null +++ b/src/corelib/io/qfilesystemengine_mac.cpp @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "qfilesystemengine_p.h" + +bool QFileSystemEngine::isCaseSensitive() +{ + return true; +} + +//static +QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link) +{ + return link; // TODO implement +} + +//static +QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) +{ + return entry; // TODO implement; +} + +//static +QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) +{ + return entry; // TODO implement; +} + +//static +QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) +{ + return QString(); // TODO implement; +} + +//static +bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::FileFlags what) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QFileSystemMetaData *data) +{ + return false; // TODO implement; +} diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp new file mode 100644 index 0000000..ac71f0e --- /dev/null +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "qfilesystemengine_p.h" + +bool QFileSystemEngine::isCaseSensitive() +{ + return true; +} + +//static +QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link) +{ + return link; // TODO implement +} + +//static +QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) +{ + return entry; // TODO implement; +} + +//static +QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) +{ + return entry; // TODO implement; +} + +//static +QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) +{ + return QString(); // TODO implement; +} + +//static +bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::FileFlags what) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QFileSystemMetaData *data) +{ + return false; // TODO implement; +} diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp new file mode 100644 index 0000000..ac71f0e --- /dev/null +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "qfilesystemengine_p.h" + +bool QFileSystemEngine::isCaseSensitive() +{ + return true; +} + +//static +QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link) +{ + return link; // TODO implement +} + +//static +QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) +{ + return entry; // TODO implement; +} + +//static +QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) +{ + return entry; // TODO implement; +} + +//static +QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) +{ + return QString(); // TODO implement; +} + +//static +bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::FileFlags what) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QFileSystemMetaData *data) +{ + return false; // TODO implement; +} -- cgit v0.12 From 710258ee0ab068bb713edc8d952293cf810a206d Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Fri, 27 Aug 2010 10:34:01 +0200 Subject: Move absoluteName to new fileSystemEngine for unix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the code for determining the absolute path on unix from the qfsfileengine_unix.cpp to the new qfilesystemengine_unix.cpp which is a static, stateless class. Made sure that the old qfsfileengine_unix.cpp keeps on working by calling into the new one. Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemengine_unix.cpp | 30 +++++++++++++++++++++++++++++- src/corelib/io/qfsfileengine_unix.cpp | 19 +++++-------------- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index ac71f0e..bcd75fc 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qfilesystemengine_p.h" +#include "qfsfileengine.h" bool QFileSystemEngine::isCaseSensitive() { @@ -61,7 +62,34 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) //static QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) { - return entry; // TODO implement; + if (entry.isAbsolute()) + return entry; + + QByteArray orig = entry.nativeFilePath(); + QByteArray result; + if (orig.isEmpty() || !orig.startsWith('/')) { + QFileSystemEntry cur(QFSFileEngine::currentPath()); + result = cur.nativeFilePath(); + } + if (!orig.isEmpty() && !(orig.length() == 1 && orig[0] == '.')) { + if (!result.isEmpty() && !result.endsWith('/')) + result.append('/'); + result.append(orig); + } + + if (result.length() == 1 && result[0] == '/') + return QFileSystemEntry(result); + const bool isDir = result.endsWith('/'); + + /* as long as QDir::cleanPath() operates on a QString we have to convert to a string here. + * ideally we never convert to a string since that loses information. Please fix after + * we get a QByteArray version of QDir::cleanPath() + */ + QFileSystemEntry resultingEntry(result); + QString stringVersion = QDir::cleanPath(resultingEntry.filePath()); + if (isDir) + stringVersion.append(QLatin1Char('/')); + return QFileSystemEntry(stringVersion); } //static diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 774932a..5fecb5d 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -43,6 +43,8 @@ #include "qabstractfileengine.h" #include "private/qfsfileengine_p.h" #include "private/qcore_unix_p.h" +#include "qfilesystementry_p.h" +#include "qfilesystemengine_p.h" #ifndef QT_NO_FSFILEENGINE @@ -1046,20 +1048,9 @@ QString QFSFileEngine::fileName(FileName file) const return QLatin1String("/"); return d->filePath.left(slash); } else if (file == AbsoluteName || file == AbsolutePathName) { - QString ret; - if (d->filePath.isEmpty() || !d->filePath.startsWith(QLatin1Char('/'))) - ret = QDir::currentPath(); - if (!d->filePath.isEmpty() && d->filePath != QLatin1String(".")) { - if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) - ret += QLatin1Char('/'); - ret += d->filePath; - } - if (ret == QLatin1String("/")) - return ret; - bool isDir = ret.endsWith(QLatin1Char('/')); - ret = QDir::cleanPath(ret); - if (isDir) - ret += QLatin1Char('/'); + QFileSystemEntry entry(d->filePath); + entry = QFileSystemEngine::absoluteName(entry); + QString ret = entry.filePath(); if (file == AbsolutePathName) { int slash = ret.lastIndexOf(QLatin1Char('/')); if (slash == -1) -- cgit v0.12 From 1b201e0857d8232eeb1c25942c4fad9360cc11c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 26 Aug 2010 13:47:33 +0200 Subject: QDir::operator= simplification With the recent changes to QDirPrivate and how d_ptr is now a QSharedDataPointer, we no longer need to worry about self-assignment, as that is already handled by the d_ptr. Simplifying code here. Reviewed-by: Prasanth Ullattil --- src/corelib/io/qdir.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 64eea23..3587243 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1634,9 +1634,6 @@ bool QDir::operator==(const QDir &dir) const */ QDir &QDir::operator=(const QDir &dir) { - if (this == &dir) - return *this; - d_ptr = dir.d_ptr; return *this; } -- cgit v0.12 From fdec31a2e57c7da48be741c14bedaaff4b95e7af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 26 Aug 2010 13:49:31 +0200 Subject: QDir::makeAbsolute could self-destruct on failure makeAbsolute would return false if the newly constructed file engine reported it wasn't referencing a directory. At this point, the private data has already been updated, rendering the instance unusable. Instead, we now create a separate QDir instance and reset our private data only on success. Similarly to what's done in QDir::cd. Reviewed-by: Prasanth Ullattil --- src/corelib/io/qdir.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 3587243..1da4f82 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1585,14 +1585,11 @@ bool QDir::makeAbsolute() // ### What do the return values signify? if (QDir::isRelativePath(absolutePath)) return false; - Q_D(QDir); - - d->path = absolutePath; - d->initFileEngine(); - d->clearFileLists(); - - if (!(d->fileEngine->fileFlags(QAbstractFileEngine::TypesMask) & QAbstractFileEngine::DirectoryType)) + QDir dir(absolutePath); + if (!(dir.d_ptr.constData()->fileEngine->fileFlags(QAbstractFileEngine::TypesMask) & QAbstractFileEngine::DirectoryType)) return false; + + *this = dir; return true; } -- cgit v0.12 From eeae8a7479cdb0b716b28ad502abed69dbf339b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 26 Aug 2010 14:03:36 +0200 Subject: Simplify QDir::cd Copy constructing a QDir instance from this and then detaching it in setPath doesn't get us anything so we might as well do it all in one go. Reviewed-by: Prasanth Ullattil --- src/corelib/io/qdir.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 1da4f82..9ebfce5 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -896,8 +896,7 @@ bool QDir::cd(const QString &dirName) } } - QDir dir(*this); - dir.setPath(newPath); + QDir dir(newPath); if (!dir.exists()) return false; -- cgit v0.12 From e2eeb1b2410d32b629c675b63dd84c9dcb976546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 30 Aug 2010 10:01:42 +0200 Subject: Adding QFileSystemEntry and QFileSystemEngine to build system Since we're refactoring code out of QFSFileEngine the new internal classes have to be compiled in together with the old engines. For the time being, we'll assume Mac uses the unix version of the engine. We'll fork those only if and as needed. --- qmake/Makefile.unix | 8 ++++++++ qmake/Makefile.win32 | 10 ++++++++++ qmake/Makefile.win32-g++ | 8 ++++++++ qmake/Makefile.win32-g++-sh | 8 ++++++++ qmake/qmake.pri | 5 +++-- src/corelib/io/io.pri | 4 +--- src/tools/bootstrap/bootstrap.pro | 7 +++++-- tools/configure/configure.pro | 8 ++++++-- tools/qtestlib/wince/cetest/bootstrapped.pri | 2 ++ 9 files changed, 51 insertions(+), 9 deletions(-) diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 8d56fc8..8c1ac6d 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -16,6 +16,7 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \ #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \ qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfile.o \ + qfilesystementry.o qfilesystemengine_unix.o \ qfsfileengine_unix.o qfsfileengine_iterator_unix.o qfsfileengine.o \ qfsfileengine_iterator.o qregexp.o qvector.o qbitarray.o qdir.o qdiriterator.o quuid.o qhash.o \ qfileinfo.o qdatetime.o qstringlist.o qabstractfileengine.o qtemporaryfile.o \ @@ -44,6 +45,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge $(SOURCE_PATH)/src/corelib/global/qglobal.cpp $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp \ $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp \ $(SOURCE_PATH)/src/corelib/io/qdatastream.cpp $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp \ + $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine_unix.cpp $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator_unix.cpp $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp $(SOURCE_PATH)/src/corelib/tools/qlist.cpp \ @@ -160,6 +162,12 @@ qlist.o: $(SOURCE_PATH)/src/corelib/tools/qlist.cpp qfile.o: $(SOURCE_PATH)/src/corelib/io/qfile.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfile.cpp +qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp + +qfilesystemengine_unix.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp + qfsfileengine.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index b58757c..b76348b 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -88,6 +88,8 @@ QTOBJS= \ qbitarray.obj \ qbuffer.obj \ qcryptographichash.obj \ + qfilesystementry.obj \ + qfilesystemengine_win.obj \ qfsfileengine.obj \ qfsfileengine_iterator.obj \ qbytearray.obj \ @@ -141,6 +143,8 @@ clean:: -del qbuffer.obj -del qcryptographichash.obj -del qlinkedlist.obj + -del qfilesystementry.obj + -del qfilesystemengine_win.obj -del qfsfileengine.obj -del qfsfileengine_iterator.obj -del qbytearray.obj @@ -310,6 +314,12 @@ qfile.obj: $(SOURCE_PATH)\src\corelib\io\qfile.cpp qtemporaryfile.obj: $(SOURCE_PATH)\src\corelib\io\qtemporaryfile.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qtemporaryfile.cpp +qfilesystementry.obj: $(SOURCE_PATH)\src\corelib\io\qfilesystementry.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfilesystementry.cpp + +qfilesystemengine_win.obj: $(SOURCE_PATH)\src\corelib\io\qfilesystemengine_win.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfilesystemengine_win.cpp + qfsfileengine_win.obj: $(SOURCE_PATH)\src\corelib\io\qfsfileengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfsfileengine_win.cpp diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index e52b8c6..c692731 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -61,6 +61,8 @@ QTOBJS= \ qtemporaryfile.o \ qfileinfo.o \ qabstractfileengine.o \ + qfilesystementry.o \ + qfilesystemengine_win.o \ qfsfileengine.o \ qfsfileengine_iterator.o \ qfsfileengine_win.o \ @@ -192,6 +194,12 @@ qtemporaryfile.o: $(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp qabstractfileengine.o: $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp +qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp + +qfilesystemengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp + qfsfileengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index e4e2e6a..cc256e9 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -61,6 +61,8 @@ QTOBJS= \ qtemporaryfile.o \ qfileinfo.o \ qabstractfileengine.o \ + qfilesystementry.o \ + qfilesystemengine_win.o \ qfsfileengine.o \ qfsfileengine_iterator.o \ qfsfileengine_win.o \ @@ -191,6 +193,12 @@ qtemporaryfile.o: $(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp qabstractfileengine.o: $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp +qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp + +qfilesystemengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp + qfsfileengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp diff --git a/qmake/qmake.pri b/qmake/qmake.pri index a7e0ab1..4d78c8b 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -57,6 +57,7 @@ bootstrap { #Qt code qfile.cpp \ qabstractfileengine.cpp \ qfileinfo.cpp \ + qfilesystementry.cpp \ qfsfileengine.cpp \ qfsfileengine_iterator.cpp \ qglobal.cpp \ @@ -125,14 +126,14 @@ bootstrap { #Qt code qxmlutils.h unix { - SOURCES += qfsfileengine_unix.cpp qfsfileengine_iterator_unix.cpp + SOURCES += qfilesystemengine_unix.cpp qfsfileengine_unix.cpp qfsfileengine_iterator_unix.cpp mac { SOURCES += qcore_mac.cpp qsettings_mac.cpp QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 #enables weak linking for 10.4 (exported) LIBS += -framework ApplicationServices } } else:win32 { - SOURCES += qfsfileengine_win.cpp qfsfileengine_iterator_win.cpp qsettings_win.cpp + SOURCES += qfilesystemengine_win.cpp qfsfileengine_win.cpp qfsfileengine_iterator_win.cpp qsettings_win.cpp win32-msvc*:LIBS += ole32.lib advapi32.lib win32-g++*:LIBS += -lole32 -luuid } diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index d3fddaf..3bde2de 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -70,6 +70,7 @@ win32 { SOURCES += io/qwindowspipewriter.cpp SOURCES += io/qfilesystemengine_win.cpp } else:unix { + SOURCES += io/qfilesystemengine_unix.cpp SOURCES += io/qfsfileengine_unix.cpp SOURCES += io/qfsfileengine_iterator_unix.cpp symbian:SOURCES += io/qprocess_symbian.cpp @@ -77,9 +78,6 @@ win32 { macx-*: { HEADERS += io/qfilesystemwatcher_fsevents_p.h SOURCES += io/qsettings_mac.cpp io/qfilesystemwatcher_fsevents.cpp - SOURCES += io/qfilesystemengine_mac.cpp - } else { - SOURCES += io/qfilesystemengine_unix.cpp } linux-*:!symbian { diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index a74c9c1..bec1329 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -57,6 +57,7 @@ SOURCES += \ ../../corelib/io/qdiriterator.cpp \ ../../corelib/io/qfile.cpp \ ../../corelib/io/qfileinfo.cpp \ + ../../corelib/io/qfilesystementry.cpp \ ../../corelib/io/qfsfileengine.cpp \ ../../corelib/io/qfsfileengine_iterator.cpp \ ../../corelib/io/qiodevice.cpp \ @@ -83,10 +84,12 @@ SOURCES += \ ../../xml/dom/qdom.cpp \ ../../xml/sax/qxml.cpp -unix:SOURCES += ../../corelib/io/qfsfileengine_unix.cpp \ +unix:SOURCES += ../../corelib/io/qfilesystemengine_unix.cpp \ + ../../corelib/io/qfsfileengine_unix.cpp \ ../../corelib/io/qfsfileengine_iterator_unix.cpp -win32:SOURCES += ../../corelib/io/qfsfileengine_win.cpp \ +win32:SOURCES += ../../corelib/io/qfilesystemengine_win.cpp \ + ../../corelib/io/qfsfileengine_win.cpp \ ../../corelib/io/qfsfileengine_iterator_win.cpp macx: { diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index 73f3317..9e52f81 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -48,6 +48,9 @@ HEADERS = configureapp.h environment.h tools.h\ $$QT_SOURCE_TREE/src/corelib/io/qdiriterator.h \ $$QT_SOURCE_TREE/src/corelib/io/qfile.h \ $$QT_SOURCE_TREE/src/corelib/io/qfileinfo.h \ + $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry_p.h \ + $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine_p.h \ + $$QT_SOURCE_TREE/src/corelib/io/qfilesystemmetadata_p.h \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.h \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_iterator_p.h \ $$QT_SOURCE_TREE/src/corelib/io/qiodevice.h \ @@ -86,7 +89,10 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfile.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfileinfo.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qabstractfileengine.cpp \ + $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry.cpp \ + $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.cpp \ + $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_iterator.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_iterator_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qiodevice.cpp \ @@ -114,8 +120,6 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/tools/shared/symbian/epocroot.cpp \ $$QT_SOURCE_TREE/tools/shared/windows/registry.cpp -win32:SOURCES += $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_win.cpp - DEFINES += COMMERCIAL_VERSION INCLUDEPATH += $$QT_SOURCE_TREE/src/corelib/arch/generic \ diff --git a/tools/qtestlib/wince/cetest/bootstrapped.pri b/tools/qtestlib/wince/cetest/bootstrapped.pri index b9c4b2b..0af5c94 100644 --- a/tools/qtestlib/wince/cetest/bootstrapped.pri +++ b/tools/qtestlib/wince/cetest/bootstrapped.pri @@ -4,6 +4,8 @@ SOURCES += \ $$QT_SOURCE_TREE/src/corelib/tools/qstringlist.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfile.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qdir.cpp \ + $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry.cpp \ + $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qabstractfileengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_win.cpp \ -- cgit v0.12 From b56fad9c12615ac135a36a468c020906f383a0d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 30 Aug 2010 10:36:30 +0200 Subject: Added missing QT_BEGIN/END_NAMESPACE to implementation files in new QFileSystem* API. --- src/corelib/io/qfilesystemengine_mac.cpp | 4 ++++ src/corelib/io/qfilesystemengine_unix.cpp | 4 ++++ src/corelib/io/qfilesystemengine_win.cpp | 4 ++++ src/corelib/io/qfilesystementry.cpp | 7 ++++++- 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_mac.cpp b/src/corelib/io/qfilesystemengine_mac.cpp index ac71f0e..942415c 100644 --- a/src/corelib/io/qfilesystemengine_mac.cpp +++ b/src/corelib/io/qfilesystemengine_mac.cpp @@ -41,6 +41,8 @@ #include "qfilesystemengine_p.h" +QT_BEGIN_NAMESPACE + bool QFileSystemEngine::isCaseSensitive() { return true; @@ -117,3 +119,5 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per { return false; // TODO implement; } + +QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index bcd75fc..2274e69 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -42,6 +42,8 @@ #include "qfilesystemengine_p.h" #include "qfsfileengine.h" +QT_BEGIN_NAMESPACE + bool QFileSystemEngine::isCaseSensitive() { return true; @@ -145,3 +147,5 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per { return false; // TODO implement; } + +QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index ac71f0e..942415c 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -41,6 +41,8 @@ #include "qfilesystemengine_p.h" +QT_BEGIN_NAMESPACE + bool QFileSystemEngine::isCaseSensitive() { return true; @@ -117,3 +119,5 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per { return false; // TODO implement; } + +QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index bed5435..5858ab3 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -40,7 +40,10 @@ ****************************************************************************/ #include "qfilesystementry_p.h" -#include "qdir.h" + +#include + +QT_BEGIN_NAMESPACE QFileSystemEntry::QFileSystemEntry(const QString &filePath) : m_filePath(filePath), @@ -195,3 +198,5 @@ void QFileSystemEntry::findFileNameSeparators() const m_lastDotInFileName = firstDotInFileName - lastSeparator; } } + +QT_END_NAMESPACE -- cgit v0.12 From 5dfcf2c6778e6852b3d1a2f9c6cc4c9e7c8a5d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 30 Aug 2010 11:36:05 +0200 Subject: Small changes to QFileSystemEntry * Added default constructor. * Made single-argument constructors explicit * Converted bit-field data to "proper" variables - the bit-fields may have been premature optimization and it may even turn out to not relevant to keep this cache. Reviewed-by: Thomas Zander --- src/corelib/io/qfilesystementry.cpp | 7 +++++++ src/corelib/io/qfilesystementry_p.h | 11 ++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index 5858ab3..04ad388 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -45,6 +45,13 @@ QT_BEGIN_NAMESPACE +QFileSystemEntry::QFileSystemEntry() + : m_lastSeparator(0), + m_firstDotInFileName(0), + m_lastDotInFileName(0) +{ +} + QFileSystemEntry::QFileSystemEntry(const QString &filePath) : m_filePath(filePath), m_lastSeparator(-2), diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index 68af24d..ae2071a 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -61,8 +61,9 @@ QT_BEGIN_NAMESPACE class QFileSystemEntry { public: - QFileSystemEntry(const QString &filePath); - QFileSystemEntry(const QByteArray &nativeFilePath); + QFileSystemEntry(); + explicit QFileSystemEntry(const QString &filePath); + explicit QFileSystemEntry(const QByteArray &nativeFilePath); QFileSystemEntry(const QByteArray &nativeFilePath, const QString &filePath); QString filePath() const; @@ -88,9 +89,9 @@ private: mutable QString m_filePath; // always has slashes as separator mutable QByteArray m_nativeFilePath; // native encoding and separators - mutable int m_lastSeparator : 16; // index in m_filePath of last separator - mutable int m_firstDotInFileName : 11; // index after m_filePath for first dot (.) - mutable int m_lastDotInFileName : 5; // index after m_firstDotInFileName for last dot (.) + mutable qint16 m_lastSeparator; // index in m_filePath of last separator + mutable qint16 m_firstDotInFileName; // index after m_filePath for first dot (.) + mutable qint16 m_lastDotInFileName; // index after m_firstDotInFileName for last dot (.) }; QT_END_NAMESPACE -- cgit v0.12 From 1d52b8a0643dca077de432d841df5f49f472352a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 30 Aug 2010 12:02:39 +0200 Subject: Removed native file path handling from QFSFileEngine Moved it into QFileSystemEntry, instead. For the time being, QFileSystemEntry may look like an unnecessary extra layer of indirection. For the time being, this allows us to do some code cleanup and de-duplication. It is also a stepping stone to becoming completely independent of the current file engine abstraction. Changes to QFileSystemEntry: - native file path on Windows is now a QString, instead of a QByteArray. Accordingly, constructors taking a QByteArray were removed for these platforms. - Encoding/decoding of file names uses QFile::encode/decodeName API, instead of assuming local 8 bit. On Windows, UTF-16 is used for native, as was being done in QFSFileEngine. - new functions isRoot(), isDriveRoot() [Windows/Symbian], and path() - convenience functions clear() and isEmpty() added to facilitate porting. Changes to QFSFileEngine (Windows): - removed QFSFileEnginePrivate::sizeFdFh(): the function was broken and never used, so might as well not get compiled in. - repeated pattern for use of FindFirstFile/FindClose hidden away in a static inline function. - repeated and inconsistent conversions from QString to native file paths reduced through the use of QFileSystemEntry. Done-with: Prasanth Ullattil Done-with: Thomas Zander --- src/corelib/io/qfilesystementry.cpp | 107 ++++++++++++- src/corelib/io/qfilesystementry_p.h | 23 +++ src/corelib/io/qfsfileengine.cpp | 23 ++- src/corelib/io/qfsfileengine_p.h | 7 +- src/corelib/io/qfsfileengine_unix.cpp | 158 ++++++++----------- src/corelib/io/qfsfileengine_win.cpp | 283 +++++++++++----------------------- src/corelib/io/qtemporaryfile.cpp | 19 +-- 7 files changed, 302 insertions(+), 318 deletions(-) diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index 04ad388..a32e22f 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -42,9 +42,38 @@ #include "qfilesystementry_p.h" #include +#include +#include +#ifdef Q_OS_WIN +#include +#endif QT_BEGIN_NAMESPACE +#ifdef Q_OS_WIN +static bool isUncRoot(const QString &server) +{ + QString localPath = QDir::toNativeSeparators(server); + if (!localPath.startsWith(QLatin1String("\\\\"))) + return false; + + int idx = localPath.indexOf(QLatin1Char('\\'), 2); + if (idx == -1 || idx + 1 == localPath.length()) + return true; + + localPath = localPath.right(localPath.length() - idx - 1).trimmed(); + return localPath.isEmpty(); +} + +static inline QString fixIfRelativeUncPath(const QString &path) +{ + QString currentPath = QDir::currentPath(); + if (currentPath.startsWith(QLatin1String("//"))) + return currentPath % QChar(QLatin1Char('/')) % path; + return path; +} +#endif + QFileSystemEntry::QFileSystemEntry() : m_lastSeparator(0), m_firstDotInFileName(0), @@ -60,6 +89,7 @@ QFileSystemEntry::QFileSystemEntry(const QString &filePath) { } +#ifndef Q_OS_WIN QFileSystemEntry::QFileSystemEntry(const QByteArray &nativeFilePath) : m_nativeFilePath(nativeFilePath), m_lastSeparator(-2), @@ -76,6 +106,7 @@ QFileSystemEntry::QFileSystemEntry(const QByteArray &nativeFilePath, const QStri m_lastDotInFileName(0) { } +#endif QString QFileSystemEntry::filePath() const { @@ -83,7 +114,11 @@ QString QFileSystemEntry::filePath() const return m_filePath; } +#ifndef Q_OS_WIN QByteArray QFileSystemEntry::nativeFilePath() const +#else +QString QFileSystemEntry::nativeFilePath() const +#endif { resolveNativeFilePath(); return m_nativeFilePath; @@ -92,23 +127,59 @@ QByteArray QFileSystemEntry::nativeFilePath() const void QFileSystemEntry::resolveFilePath() const { if (m_filePath.isEmpty() && !m_nativeFilePath.isEmpty()) { - m_filePath = QDir::fromNativeSeparators(QString::fromLocal8Bit(m_nativeFilePath)); +#ifdef Q_OS_WIN + m_filePath = QDir::fromNativeSeparators(m_nativeFilePath); +#else + m_filePath = QDir::fromNativeSeparators(QFile::decodeName(m_nativeFilePath)); +#endif } } void QFileSystemEntry::resolveNativeFilePath() const { if (!m_filePath.isEmpty() && m_nativeFilePath.isEmpty()) { - m_nativeFilePath = QDir::toNativeSeparators(m_filePath).toLocal8Bit(); +#ifdef Q_OS_WIN + QString filePath = m_filePath; + if (isRelative()) + filePath = fixIfRelativeUncPath(m_filePath); + m_nativeFilePath = QFSFileEnginePrivate::longFileName(QDir::toNativeSeparators(filePath)); +#else + m_nativeFilePath = QFile::encodeName(QDir::toNativeSeparators(m_filePath)); +#endif } } QString QFileSystemEntry::fileName() const { findLastSeparator(); +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + if (m_lastSeparator == -1) { + if (m_filePath.length() >= 2 && m_filePath.at(1) == QLatin1Char(':')) + return m_filePath.mid(2); + } +#endif return m_filePath.mid(m_lastSeparator + 1); } +QString QFileSystemEntry::path() const +{ + findLastSeparator(); + if (m_lastSeparator == -1) { +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + if (m_filePath.length() >= 2 && m_filePath.at(1) == QLatin1Char(':')) + return m_filePath.left(2); +#endif + return QString(QLatin1Char('.')); + } + if (m_lastSeparator == 0) + return QString(QLatin1Char('/')); +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + if (m_lastSeparator == 2 && m_filePath.at(1) == QLatin1Char(':')) + return m_filePath.left(m_lastSeparator + 1); +#endif + return m_filePath.left(m_lastSeparator); +} + QString QFileSystemEntry::suffix() const { findFileNameSeparators(); @@ -141,6 +212,38 @@ bool QFileSystemEntry::isAbsolute() const } +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) +bool QFileSystemEntry::isDriveRoot() const +{ + resolveFilePath(); + return (m_filePath.length() == 3 + && m_filePath.at(0).isLetter() && m_filePath.at(1) == QLatin1Char(':') + && m_filePath.at(2) == QLatin1Char('/')); +} +#endif + +bool QFileSystemEntry::isRoot() const +{ + resolveFilePath(); + if (m_filePath == QLatin1String("/") +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + || isDriveRoot() +#if defined(Q_OS_WIN) + || isUncRoot(m_filePath) +#endif +#endif + ) + return true; + + return false; +} + +bool QFileSystemEntry::isEmpty() const +{ + resolveNativeFilePath(); + return m_nativeFilePath.isEmpty(); +} + // private methods void QFileSystemEntry::findLastSeparator() const diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index ae2071a..3e49f2c 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -63,12 +63,19 @@ class QFileSystemEntry public: QFileSystemEntry(); explicit QFileSystemEntry(const QString &filePath); +#ifndef Q_OS_WIN explicit QFileSystemEntry(const QByteArray &nativeFilePath); QFileSystemEntry(const QByteArray &nativeFilePath, const QString &filePath); +#endif QString filePath() const; QString fileName() const; + QString path() const; +#ifndef Q_OS_WIN QByteArray nativeFilePath() const; +#else + QString nativeFilePath() const; +#endif QString suffix() const; QString completeSuffix() const; bool isAbsolute() const; @@ -76,6 +83,17 @@ public: return !isAbsolute(); } +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + bool isDriveRoot() const; +#endif + bool isRoot() const; + + bool isEmpty() const; + void clear() + { + *this = QFileSystemEntry(); + } + private: // creates the QString version out of the bytearray version void resolveFilePath() const; @@ -87,7 +105,12 @@ private: void findFileNameSeparators() const; mutable QString m_filePath; // always has slashes as separator + +#ifdef Q_OS_WIN + mutable QString m_nativeFilePath; // native encoding and separators +#else mutable QByteArray m_nativeFilePath; // native encoding and separators +#endif mutable qint16 m_lastSeparator; // index in m_filePath of last separator mutable qint16 m_firstDotInFileName; // index after m_filePath for first dot (.) diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 511a1a6..75f82a6 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -239,11 +239,11 @@ QString QFSFileEnginePrivate::canonicalized(const QString &path) /*! Constructs a QFSFileEngine for the file name \a file. */ -QFSFileEngine::QFSFileEngine(const QString &file) : QAbstractFileEngine(*new QFSFileEnginePrivate) +QFSFileEngine::QFSFileEngine(const QString &file) + : QAbstractFileEngine(*new QFSFileEnginePrivate) { Q_D(QFSFileEngine); - d->filePath = QDir::fromNativeSeparators(file); - d->nativeInitFileName(); + d->fileEntry = QFileSystemEntry(QDir::fromNativeSeparators(file)); } /*! @@ -292,8 +292,7 @@ void QFSFileEngine::setFileName(const QString &file) { Q_D(QFSFileEngine); d->init(); - d->filePath = QDir::fromNativeSeparators(file); - d->nativeInitFileName(); + d->fileEntry = QFileSystemEntry(QDir::fromNativeSeparators(file)); } /*! @@ -302,7 +301,7 @@ void QFSFileEngine::setFileName(const QString &file) bool QFSFileEngine::open(QIODevice::OpenMode openMode) { Q_D(QFSFileEngine); - if (d->filePath.isEmpty()) { + if (d->fileEntry.isEmpty()) { qWarning("QFSFileEngine::open: No file name specified"); setError(QFile::OpenError, QLatin1String("No file name specified")); return false; @@ -344,8 +343,7 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, FILE *fh) d->openMode = openMode; d->lastFlushFailed = false; d->closeFileHandle = false; - d->nativeFilePath.clear(); - d->filePath.clear(); + d->fileEntry.clear(); d->tried_stat = 0; d->fd = -1; @@ -401,8 +399,7 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd) d->openMode = openMode; d->lastFlushFailed = false; d->closeFileHandle = false; - d->nativeFilePath.clear(); - d->filePath.clear(); + d->fileEntry.clear(); d->fh = 0; d->fd = -1; d->tried_stat = 0; @@ -549,6 +546,7 @@ qint64 QFSFileEngine::size() const /*! \internal */ +#ifndef Q_OS_WIN qint64 QFSFileEnginePrivate::sizeFdFh() const { Q_Q(const QFSFileEngine); @@ -556,13 +554,13 @@ qint64 QFSFileEnginePrivate::sizeFdFh() const QT_STATBUF st; int ret = 0; const_cast(q)->flush(); - if (fh && nativeFilePath.isEmpty()) { + if (fh && fileEntry.isEmpty()) { // Buffered stdlib mode. // ### This should really be an ftell ret = QT_FSTAT(QT_FILENO(fh), &st); } else if (fd == -1) { // Stateless stat. - ret = QT_STAT(nativeFilePath.constData(), &st); + ret = QT_STAT(fileEntry.nativeFilePath().constData(), &st); } else { // Unbuffered stdio mode. ret = QT_FSTAT(fd, &st); @@ -571,6 +569,7 @@ qint64 QFSFileEnginePrivate::sizeFdFh() const return 0; return st.st_size; } +#endif /*! \reimp diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index e9e55f3..74cbca3 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -56,6 +56,7 @@ #include "qplatformdefs.h" #include "QtCore/qfsfileengine.h" #include "private/qabstractfileengine_p.h" +#include "private/qfilesystementry_p.h" #include #ifndef QT_NO_FSFILEENGINE @@ -76,11 +77,9 @@ public: #endif static QString canonicalized(const QString &path); - QString filePath; - QByteArray nativeFilePath; + QFileSystemEntry fileEntry; QIODevice::OpenMode openMode; - void nativeInitFileName(); bool nativeOpen(QIODevice::OpenMode openMode); bool openFh(QIODevice::OpenMode flags, FILE *fh); bool openFd(QIODevice::OpenMode flags, int fd); @@ -89,7 +88,9 @@ public: bool nativeFlush(); bool flushFh(); qint64 nativeSize() const; +#ifndef Q_OS_WIN qint64 sizeFdFh() const; +#endif qint64 nativePos() const; qint64 posFdFh() const; bool nativeSeek(qint64); diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 5fecb5d..3daf7f6 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -200,14 +200,6 @@ static inline bool setCloseOnExec(int fd) /*! \internal */ -void QFSFileEnginePrivate::nativeInitFileName() -{ - nativeFilePath = QFile::encodeName(filePath); -} - -/*! - \internal -*/ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) { Q_Q(QFSFileEngine); @@ -217,7 +209,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) // Try to open the file in unbuffered mode. do { - fd = QT_OPEN(nativeFilePath.constData(), flags, 0666); + fd = QT_OPEN(fileEntry.nativeFilePath().constData(), flags, 0666); } while (fd == -1 && errno == EINTR); // On failure, return and report the error. @@ -256,11 +248,11 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) fh = 0; } else { - QByteArray fopenMode = openModeToFopenMode(openMode, nativeFilePath.constData()); + QByteArray fopenMode = openModeToFopenMode(openMode, fileEntry.nativeFilePath().constData()); // Try to open the file in buffered mode. do { - fh = QT_FOPEN(nativeFilePath.constData(), fopenMode.constData()); + fh = QT_FOPEN(fileEntry.nativeFilePath().constData(), fopenMode.constData()); } while (!fh && errno == EINTR); // On failure, return and report the error. @@ -435,7 +427,7 @@ bool QFSFileEnginePrivate::nativeIsSequential() const bool QFSFileEngine::remove() { Q_D(QFSFileEngine); - bool ret = unlink(d->nativeFilePath.constData()) == 0; + bool ret = unlink(d->fileEntry.nativeFilePath().constData()) == 0; if (!ret) setError(QFile::RemoveError, qt_error_string(errno)); return ret; @@ -447,7 +439,7 @@ bool QFSFileEngine::copy(const QString &newName) Q_D(QFSFileEngine); RFs rfs = qt_s60GetRFs(); CFileMan* fm = NULL; - QString oldNative(QDir::toNativeSeparators(d->filePath)); + QString oldNative(QDir::toNativeSeparators(d->fileEntry.filePath())); TPtrC oldPtr(qt_QString2TPtrC(oldNative)); QFileInfo fi(newName); QString absoluteNewName = fi.absoluteFilePath(); @@ -478,7 +470,7 @@ bool QFSFileEngine::copy(const QString &newName) bool QFSFileEngine::rename(const QString &newName) { Q_D(QFSFileEngine); - bool ret = ::rename(d->nativeFilePath.constData(), QFile::encodeName(newName).constData()) == 0; + bool ret = ::rename(d->fileEntry.nativeFilePath().constData(), QFile::encodeName(newName).constData()) == 0; if (!ret) setError(QFile::RenameError, qt_error_string(errno)); return ret; @@ -487,7 +479,7 @@ bool QFSFileEngine::rename(const QString &newName) bool QFSFileEngine::link(const QString &newName) { Q_D(QFSFileEngine); - bool ret = ::symlink(d->nativeFilePath.constData(), QFile::encodeName(newName).constData()) == 0; + bool ret = ::symlink(d->fileEntry.nativeFilePath().constData(), QFile::encodeName(newName).constData()) == 0; if (!ret) setError(QFile::RenameError, qt_error_string(errno)); return ret; @@ -691,7 +683,7 @@ bool QFSFileEnginePrivate::doStat() const tried_stat = true; could_stat = false; - if (fh && nativeFilePath.isEmpty()) { + if (fh && fileEntry.isEmpty()) { // ### actually covers two cases: d->fh and when the file is not open could_stat = (QT_FSTAT(QT_FILENO(fh), &st) == 0); } else if (fd == -1) { @@ -701,12 +693,12 @@ bool QFSFileEnginePrivate::doStat() const // When the filename is not a link, lstat will return the same info as stat, but this also removes // any need for a further call to lstat to check if the file is a link. need_lstat = false; - could_stat = (QT_LSTAT(nativeFilePath.constData(), &st) == 0); + could_stat = (QT_LSTAT(fileEntry.nativeFilePath().constData(), &st) == 0); is_link = could_stat ? S_ISLNK(st.st_mode) : false; // if it turns out this was a link, we can call stat too. if (is_link) #endif - could_stat = (QT_STAT(nativeFilePath.constData(), &st) == 0); + could_stat = (QT_STAT(fileEntry.nativeFilePath().constData(), &st) == 0); } else { could_stat = (QT_FSTAT(fd, &st) == 0); } @@ -720,7 +712,7 @@ bool QFSFileEnginePrivate::isSymlink() const need_lstat = false; QT_STATBUF st; // don't clobber our main one - is_link = (QT_LSTAT(nativeFilePath.constData(), &st) == 0) ? S_ISLNK(st.st_mode) : false; + is_link = (QT_LSTAT(fileEntry.nativeFilePath().constData(), &st) == 0) ? S_ISLNK(st.st_mode) : false; } return is_link; } @@ -789,15 +781,15 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions(QAbstractFil // calculate user permissions if (type & QAbstractFileEngine::ReadUserPerm) { - if (QT_ACCESS(nativeFilePath.constData(), R_OK) == 0) + if (QT_ACCESS(fileEntry.nativeFilePath().constData(), R_OK) == 0) ret |= QAbstractFileEngine::ReadUserPerm; } if (type & QAbstractFileEngine::WriteUserPerm) { - if (QT_ACCESS(nativeFilePath.constData(), W_OK) == 0) + if (QT_ACCESS(fileEntry.nativeFilePath().constData(), W_OK) == 0) ret |= QAbstractFileEngine::WriteUserPerm; } if (type & QAbstractFileEngine::ExeUserPerm) { - if (QT_ACCESS(nativeFilePath.constData(), X_OK) == 0) + if (QT_ACCESS(fileEntry.nativeFilePath().constData(), X_OK) == 0) ret |= QAbstractFileEngine::ExeUserPerm; } @@ -830,7 +822,7 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const bool foundAlias = false; { FSRef fref; - if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->filePath)).data(), + if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->fileEntry.filePath())).data(), &fref, NULL) == noErr) { Boolean isAlias, isFolder; if (FSIsAliasFile(&fref, &isAlias, &isFolder) == noErr && isAlias) { @@ -850,7 +842,7 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const ret |= DirectoryType; #if !defined(QWS) && defined(Q_OS_MAC) if ((ret & DirectoryType) && (type & BundleType)) { - QCFType url = CFURLCreateWithFileSystemPath(0, QCFString(d->filePath), + QCFType url = CFURLCreateWithFileSystemPath(0, QCFString(d->fileEntry.filePath()), kCFURLPOSIXPathStyle, true); UInt32 type, creator; if (CFBundleGetPackageInfoInDirectory(url, &type, &creator)) @@ -862,35 +854,29 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const if (type & FlagsMask) { if (exists) ret |= ExistsFlag; -#if defined(Q_OS_SYMBIAN) - if (d->filePath == QLatin1String("/") - || (d->filePath.length() == 3 && d->filePath.at(0).isLetter() - && d->filePath.at(1) == QLatin1Char(':') && d->filePath.at(2) == QLatin1Char('/'))) { + if (d->fileEntry.isRoot()) { ret |= RootFlag; } else { +#if defined(Q_OS_SYMBIAN) // In Symbian, all symlinks have hidden attribute for some reason; // lets make them visible for better compatibility with other platforms. // If somebody actually wants a hidden link, then they are out of luck. - if (!d->isSymlink() && _q_isSymbianHidden(d->filePath, ret & DirectoryType)) + if (!d->isSymlink() && _q_isSymbianHidden(d->fileEntry.filePath(), ret & DirectoryType)) ret |= HiddenFlag; - } #else - if (d->filePath == QLatin1String("/")) { - ret |= RootFlag; - } else { QString baseName = fileName(BaseName); if ((baseName.size() > 0 && baseName.at(0) == QLatin1Char('.')) # if !defined(QWS) && defined(Q_OS_MAC) - || _q_isMacHidden(d->filePath) + || _q_isMacHidden(d->fileEntry.filePath()) # if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - || d->st.st_flags & UF_HIDDEN + || d->st.st_flags & UF_HIDDEN # endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 # endif ) { ret |= HiddenFlag; } - } #endif + } } return ret; } @@ -901,50 +887,50 @@ QString QFSFileEngine::fileName(FileName file) const Q_D(const QFSFileEngine); const QLatin1Char slashChar('/'); if(file == BaseName) { - int slash = d->filePath.lastIndexOf(slashChar); + int slash = d->fileEntry.filePath().lastIndexOf(slashChar); if(slash == -1) { - int colon = d->filePath.lastIndexOf(QLatin1Char(':')); + int colon = d->fileEntry.filePath().lastIndexOf(QLatin1Char(':')); if(colon != -1) - return d->filePath.mid(colon + 1); - return d->filePath; + return d->fileEntry.filePath().mid(colon + 1); + return d->fileEntry.filePath(); } - return d->filePath.mid(slash + 1); + return d->fileEntry.filePath().mid(slash + 1); } else if(file == PathName) { - if(!d->filePath.size()) - return d->filePath; + if(!d->fileEntry.filePath().size()) + return d->fileEntry.filePath(); - int slash = d->filePath.lastIndexOf(slashChar); + int slash = d->fileEntry.filePath().lastIndexOf(slashChar); if(slash == -1) { - if(d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':')) - return d->filePath.left(2); + if(d->fileEntry.filePath().length() >= 2 && d->fileEntry.filePath().at(1) == QLatin1Char(':')) + return d->fileEntry.filePath().left(2); return QLatin1String("."); } else { if(!slash) return QLatin1String("/"); - if(slash == 2 && d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':')) + if(slash == 2 && d->fileEntry.filePath().length() >= 2 && d->fileEntry.filePath().at(1) == QLatin1Char(':')) slash++; - return d->filePath.left(slash); + return d->fileEntry.filePath().left(slash); } } else if(file == AbsoluteName || file == AbsolutePathName) { QString ret; - if (!isRelativePathSymbian(d->filePath)) { - if (d->filePath.size() > 2 && d->filePath.at(1) == QLatin1Char(':') - && d->filePath.at(2) != slashChar){ + if (!isRelativePathSymbian(d->fileEntry.filePath())) { + if (d->fileEntry.filePath().size() > 2 && d->fileEntry.filePath().at(1) == QLatin1Char(':') + && d->fileEntry.filePath().at(2) != slashChar){ // It's a drive-relative path, so C:a.txt -> C:/currentpath/a.txt, // or if it's different drive than current, Z:a.txt -> Z:/a.txt QString currentPath = QDir::currentPath(); - if (0 == currentPath.left(1).compare(d->filePath.left(1), Qt::CaseInsensitive)) - ret = currentPath + slashChar + d->filePath.mid(2); + if (0 == currentPath.left(1).compare(d->fileEntry.filePath().left(1), Qt::CaseInsensitive)) + ret = currentPath + slashChar + d->fileEntry.filePath().mid(2); else - ret = d->filePath.left(2) + slashChar + d->filePath.mid(2); - } else if (d->filePath.startsWith(slashChar)) { + ret = d->fileEntry.filePath().left(2) + slashChar + d->fileEntry.filePath().mid(2); + } else if (d->fileEntry.filePath().startsWith(slashChar)) { // It's a absolute path to the current drive, so /a.txt -> C:/a.txt - ret = QDir::currentPath().left(2) + d->filePath; + ret = QDir::currentPath().left(2) + d->fileEntry.filePath(); } else { - ret = d->filePath; + ret = d->fileEntry.filePath(); } } else { - ret = QDir::currentPath() + slashChar + d->filePath; + ret = QDir::currentPath() + slashChar + d->fileEntry.filePath(); } // The path should be absolute at this point. @@ -993,14 +979,14 @@ QString QFSFileEngine::fileName(FileName file) const } else if(file == LinkName) { if (d->isSymlink()) { char s[PATH_MAX+1]; - int len = readlink(d->nativeFilePath.constData(), s, PATH_MAX); + int len = readlink(d->fileEntry.nativeFilePath().constData(), s, PATH_MAX); if (len > 0) { s[len] = '\0'; QString ret = QFile::decodeName(QByteArray(s)); if (isRelativePathSymbian(ret)) { - if (!isRelativePathSymbian(d->filePath)) { - ret.prepend(d->filePath.left(d->filePath.lastIndexOf(slashChar)) + if (!isRelativePathSymbian(d->fileEntry.filePath())) { + ret.prepend(d->fileEntry.filePath().left(d->fileEntry.filePath().lastIndexOf(slashChar)) + slashChar); } else { ret.prepend(QDir::currentPath() + slashChar); @@ -1016,7 +1002,7 @@ QString QFSFileEngine::fileName(FileName file) const } else if(file == BundleName) { return QString(); } - return d->filePath; + return d->fileEntry.filePath(); } #else @@ -1026,7 +1012,7 @@ QString QFSFileEngine::fileName(FileName file) const Q_D(const QFSFileEngine); if (file == BundleName) { #if !defined(QWS) && defined(Q_OS_MAC) - QCFType url = CFURLCreateWithFileSystemPath(0, QCFString(d->filePath), + QCFType url = CFURLCreateWithFileSystemPath(0, QCFString(d->fileEntry.filePath()), kCFURLPOSIXPathStyle, true); if (QCFType dict = CFBundleCopyInfoDictionaryForURL(url)) { if (CFTypeRef name = (CFTypeRef)CFDictionaryGetValue(dict, kCFBundleNameKey)) { @@ -1037,29 +1023,15 @@ QString QFSFileEngine::fileName(FileName file) const #endif return QString(); } else if (file == BaseName) { - int slash = d->filePath.lastIndexOf(QLatin1Char('/')); - if (slash != -1) - return d->filePath.mid(slash + 1); + return d->fileEntry.fileName(); } else if (file == PathName) { - int slash = d->filePath.lastIndexOf(QLatin1Char('/')); - if (slash == -1) - return QLatin1String("."); - else if (!slash) - return QLatin1String("/"); - return d->filePath.left(slash); + return d->fileEntry.path(); } else if (file == AbsoluteName || file == AbsolutePathName) { - QFileSystemEntry entry(d->filePath); - entry = QFileSystemEngine::absoluteName(entry); - QString ret = entry.filePath(); + QFileSystemEntry entry = QFileSystemEngine::absoluteName(d->fileEntry); if (file == AbsolutePathName) { - int slash = ret.lastIndexOf(QLatin1Char('/')); - if (slash == -1) - return QDir::currentPath(); - else if (!slash) - return QLatin1String("/"); - return ret.left(slash); + return entry.path(); } - return ret; + return entry.filePath(); } else if (file == CanonicalName || file == CanonicalPathName) { if (!(fileFlags(ExistsFlag) & ExistsFlag)) return QString(); @@ -1085,7 +1057,7 @@ QString QFSFileEngine::fileName(FileName file) const while (1) { s = (char *) ::realloc(s, size); Q_CHECK_PTR(s); - len = ::readlink(d->nativeFilePath.constData(), s, size); + len = ::readlink(d->fileEntry.nativeFilePath().constData(), s, size); if (len < 0) { ::free(s); break; @@ -1097,12 +1069,12 @@ QString QFSFileEngine::fileName(FileName file) const } #else char s[PATH_MAX+1]; - int len = readlink(d->nativeFilePath.constData(), s, PATH_MAX); + int len = readlink(d->fileEntry.nativeFilePath().constData(), s, PATH_MAX); #endif if (len > 0) { QString ret; if (d->doStat() && S_ISDIR(d->st.st_mode) && s[0] != '/') { - QDir parent(d->filePath); + QDir parent(d->fileEntry.filePath()); parent.cdUp(); ret = parent.path(); if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) @@ -1115,8 +1087,8 @@ QString QFSFileEngine::fileName(FileName file) const #endif if (!ret.startsWith(QLatin1Char('/'))) { - if (d->filePath.startsWith(QLatin1Char('/'))) { - ret.prepend(d->filePath.left(d->filePath.lastIndexOf(QLatin1Char('/'))) + if (d->fileEntry.filePath().startsWith(QLatin1Char('/'))) { + ret.prepend(d->fileEntry.filePath().left(d->fileEntry.filePath().lastIndexOf(QLatin1Char('/'))) + QLatin1Char('/')); } else { ret.prepend(QDir::currentPath() + QLatin1Char('/')); @@ -1131,7 +1103,7 @@ QString QFSFileEngine::fileName(FileName file) const #if !defined(QWS) && defined(Q_OS_MAC) { FSRef fref; - if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->filePath)).data(), &fref, 0) == noErr) { + if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->fileEntry.filePath())).data(), &fref, 0) == noErr) { Boolean isAlias, isFolder; if (FSResolveAliasFile(&fref, true, &isFolder, &isAlias) == noErr && isAlias) { AliasHandle alias; @@ -1146,7 +1118,7 @@ QString QFSFileEngine::fileName(FileName file) const #endif return QString(); } - return d->filePath; + return d->fileEntry.filePath(); } #endif // Q_OS_SYMBIAN @@ -1154,9 +1126,9 @@ bool QFSFileEngine::isRelativePath() const { Q_D(const QFSFileEngine); #if defined(Q_OS_SYMBIAN) - return isRelativePathSymbian(d->filePath); + return isRelativePathSymbian(d->fileEntry.filePath()); #else - return d->filePath.length() ? d->filePath[0] != QLatin1Char('/') : true; + return d->fileEntry.filePath().length() ? d->fileEntry.filePath()[0] != QLatin1Char('/') : true; #endif } @@ -1253,7 +1225,7 @@ bool QFSFileEngine::setPermissions(uint perms) if (d->fd != -1) ret = fchmod(d->fd, mode) == 0; else - ret = ::chmod(d->nativeFilePath.constData(), mode) == 0; + ret = ::chmod(d->fileEntry.nativeFilePath().constData(), mode) == 0; if (!ret) setError(QFile::PermissionsError, qt_error_string(errno)); return ret; @@ -1268,7 +1240,7 @@ bool QFSFileEngine::setSize(qint64 size) else if (d->fh) ret = QT_FTRUNCATE(QT_FILENO(d->fh), size) == 0; else - ret = QT_TRUNCATE(d->nativeFilePath.constData(), size) == 0; + ret = QT_TRUNCATE(d->fileEntry.nativeFilePath().constData(), size) == 0; if (!ret) setError(QFile::ResizeError, qt_error_string(errno)); return ret; diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 84120b4..6f81652 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -128,7 +128,7 @@ typedef struct _REPARSE_DATA_BUFFER { QT_BEGIN_NAMESPACE -static QString readLink(const QString &link); +static QString readLink(const QFileSystemEntry &link); Q_CORE_EXPORT int qt_ntfs_permission_lookup = 0; @@ -279,20 +279,6 @@ bool QFSFileEnginePrivate::uncListSharesOnServer(const QString &server, QStringL return false; } -static bool isUncRoot(const QString &server) -{ - QString localPath = QDir::toNativeSeparators(server); - if (!localPath.startsWith(QLatin1String("\\\\"))) - return false; - - int idx = localPath.indexOf(QLatin1Char('\\'), 2); - if (idx == -1 || idx + 1 == localPath.length()) - return true; - - localPath = localPath.right(localPath.length() - idx - 1).trimmed(); - return localPath.isEmpty(); -} - #if !defined(Q_OS_WINCE) static inline bool isUncPath(const QString &path) { @@ -302,25 +288,6 @@ static inline bool isUncPath(const QString &path) } #endif -static inline bool isRelativePath(const QString &path) -{ - // drive, e.g. "a:", or UNC root, e.q. "//" - return !(path.startsWith(QLatin1Char('/')) - || (path.length() >= 2 - && ((path.at(0).isLetter() && path.at(1) == QLatin1Char(':')) - || (path.at(0) == QLatin1Char('/') && path.at(1) == QLatin1Char('/'))))); -} - -static QString fixIfRelativeUncPath(const QString &path) -{ - if (isRelativePath(path)) { - QString currentPath = QDir::currentPath() + QLatin1Char('/'); - if (currentPath.startsWith(QLatin1String("//"))) - return QString(path).prepend(currentPath); - } - return path; -} - // can be //server or //server/share static bool uncShareExists(const QString &server) { @@ -333,13 +300,6 @@ static bool uncShareExists(const QString &server) return false; } -static inline bool isDriveRoot(const QString &path) -{ - return (path.length() == 3 - && path.at(0).isLetter() && path.at(1) == QLatin1Char(':') - && path.at(2) == QLatin1Char('/')); -} - static QString nativeAbsoluteFilePath(const QString &path) { QString absPath; @@ -390,13 +350,22 @@ QString QFSFileEnginePrivate::longFileName(const QString &path) #endif } -/* - \internal -*/ -void QFSFileEnginePrivate::nativeInitFileName() +static inline bool getFindData(QString path, WIN32_FIND_DATA &findData) { - QString path = longFileName(QDir::toNativeSeparators(fixIfRelativeUncPath(filePath))); - nativeFilePath = QByteArray((const char *)path.utf16(), path.size() * 2 + 1); + // path should not end with a trailing slash + while (path.endsWith(QLatin1Char('\\'))) + path.chop(1); + + // can't handle drives + if (!path.endsWith(QLatin1Char(':'))) { + HANDLE hFind = ::FindFirstFile((wchar_t*)path.utf16(), &findData); + if (hFind != INVALID_HANDLE_VALUE) { + ::FindClose(hFind); + return true; + } + } + + return false; } /* @@ -421,7 +390,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) DWORD creationDisp = (openMode & QIODevice::WriteOnly) ? OPEN_ALWAYS : OPEN_EXISTING; // Create the file handle. - fileHandle = CreateFile((const wchar_t*)nativeFilePath.constData(), + fileHandle = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(), accessRights, shareMode, &securityAtts, @@ -538,31 +507,18 @@ qint64 QFSFileEnginePrivate::nativeSize() const // Not-open mode, where the file name is known: We'll check the // file system directly. - if (openMode == QIODevice::NotOpen && !nativeFilePath.isEmpty()) { + if (openMode == QIODevice::NotOpen && !fileEntry.isEmpty()) { WIN32_FILE_ATTRIBUTE_DATA attribData; - bool ok = ::GetFileAttributesEx((const wchar_t*)nativeFilePath.constData(), + bool ok = ::GetFileAttributesEx((const wchar_t*)fileEntry.nativeFilePath().utf16(), GetFileExInfoStandard, &attribData); if (!ok) { int errorCode = GetLastError(); if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) { - QByteArray path = nativeFilePath; - // path for the FindFirstFile should not end with a trailing slash - while (!path.isEmpty() && reinterpret_cast( - path.constData() + path.length())[-1] == '\\') - path.chop(2); - - // FindFirstFile can not handle drives - if (!path.isEmpty() && reinterpret_cast( - path.constData() + path.length())[-1] != ':') { - WIN32_FIND_DATA findData; - HANDLE hFind = ::FindFirstFile((const wchar_t*)path.constData(), - &findData); - if (hFind != INVALID_HANDLE_VALUE) { - ::FindClose(hFind); - ok = true; - attribData.nFileSizeHigh = findData.nFileSizeHigh; - attribData.nFileSizeLow = findData.nFileSizeLow; - } + WIN32_FIND_DATA findData; + if (getFindData(fileEntry.nativeFilePath(), findData)) { + ok = true; + attribData.nFileSizeHigh = findData.nFileSizeHigh; + attribData.nFileSizeLow = findData.nFileSizeLow; } } } @@ -831,7 +787,7 @@ bool QFSFileEnginePrivate::nativeIsSequential() const bool QFSFileEngine::remove() { Q_D(QFSFileEngine); - bool ret = ::DeleteFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16()) != 0; + bool ret = ::DeleteFile((wchar_t*)d->fileEntry.nativeFilePath().utf16()) != 0; if (!ret) setError(QFile::RemoveError, qt_error_string()); return ret; @@ -840,8 +796,10 @@ bool QFSFileEngine::remove() bool QFSFileEngine::copy(const QString ©Name) { Q_D(QFSFileEngine); - bool ret = ::CopyFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(), - (wchar_t*)QFSFileEnginePrivate::longFileName(copyName).utf16(), true) != 0; + + QFileSystemEntry target(copyName); + bool ret = ::CopyFile((wchar_t*)d->fileEntry.nativeFilePath().utf16(), + (wchar_t*)target.nativeFilePath().utf16(), true) != 0; if (!ret) setError(QFile::CopyError, qt_error_string()); return ret; @@ -850,8 +808,9 @@ bool QFSFileEngine::copy(const QString ©Name) bool QFSFileEngine::rename(const QString &newName) { Q_D(QFSFileEngine); - bool ret = ::MoveFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(), - (wchar_t*)QFSFileEnginePrivate::longFileName(newName).utf16()) != 0; + QFileSystemEntry target(newName); + bool ret = ::MoveFile((wchar_t*)d->fileEntry.nativeFilePath().utf16(), + (wchar_t*)target.nativeFilePath().utf16()) != 0; if (!ret) setError(QFile::RenameError, qt_error_string()); return ret; @@ -896,20 +855,9 @@ static bool isDirPath(const QString &dirPath, bool *existed) if (fileAttrib == INVALID_FILE_ATTRIBUTES) { int errorCode = GetLastError(); if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) { - // path for the FindFirstFile should not end with a trailing slash - while (path.endsWith(QLatin1Char('\\'))) - path.chop(1); - - // FindFirstFile can not handle drives - if (!path.endsWith(QLatin1Char(':'))) { - WIN32_FIND_DATA findData; - HANDLE hFind = ::FindFirstFile((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), - &findData); - if (hFind != INVALID_HANDLE_VALUE) { - ::FindClose(hFind); - fileAttrib = findData.dwFileAttributes; - } - } + WIN32_FIND_DATA findData; + if (getFindData(QFSFileEnginePrivate::longFileName(path), findData)) + fileAttrib = findData.dwFileAttributes; } } @@ -1164,19 +1112,17 @@ bool QFSFileEnginePrivate::doStat() const tried_stat = true; could_stat = false; - if (filePath.isEmpty()) + if (fileEntry.isEmpty()) return could_stat; - QString fname; - if(filePath.endsWith(QLatin1String(".lnk"))) { - fname = readLink(filePath); + QFileSystemEntry fname; + if(fileEntry.filePath().endsWith(QLatin1String(".lnk"))) { + fname = QFileSystemEntry(readLink(fileEntry)); if(fname.isEmpty()) return could_stat; } else - fname = filePath; - - fname = fixIfRelativeUncPath(fname); + fname = fileEntry; UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); @@ -1191,48 +1137,37 @@ bool QFSFileEnginePrivate::doStat() const } } #else - DWORD tmpAttributes = GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(fname).utf16()); + DWORD tmpAttributes = GetFileAttributes((wchar_t*)fname.nativeFilePath().utf16()); if (tmpAttributes != -1) { fileAttrib = tmpAttributes; could_stat = true; } #endif } else { - fileAttrib = GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(fname).utf16()); + fileAttrib = GetFileAttributes((wchar_t*)fname.nativeFilePath().utf16()); if (fileAttrib == INVALID_FILE_ATTRIBUTES) { int errorCode = GetLastError(); if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) { - QString path = QDir::toNativeSeparators(fname); - // path for the FindFirstFile should not end with a trailing slash - while (path.endsWith(QLatin1Char('\\'))) - path.chop(1); - - // FindFirstFile can not handle drives - if (!path.endsWith(QLatin1Char(':'))) { - WIN32_FIND_DATA findData; - HANDLE hFind = ::FindFirstFile((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), - &findData); - if (hFind != INVALID_HANDLE_VALUE) { - ::FindClose(hFind); - fileAttrib = findData.dwFileAttributes; - } + WIN32_FIND_DATA findData; + if (getFindData(fname.nativeFilePath(), findData)) { + fileAttrib = findData.dwFileAttributes; } } } could_stat = fileAttrib != INVALID_FILE_ATTRIBUTES; if (!could_stat) { #if !defined(Q_OS_WINCE) - if (isDriveRoot(fname)) { + if (fname.isDriveRoot()) { // a valid drive ?? DWORD drivesBitmask = ::GetLogicalDrives(); - int drivebit = 1 << (fname.at(0).toUpper().unicode() - QLatin1Char('A').unicode()); + int drivebit = 1 << (fname.filePath().at(0).toUpper().unicode() - QLatin1Char('A').unicode()); if (drivesBitmask & drivebit) { fileAttrib = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM; could_stat = true; } } else { #endif - QString path = QDir::toNativeSeparators(fname); + const QString &path = fname.nativeFilePath(); bool is_dir = false; if (path.startsWith(QLatin1String("\\\\"))) { // UNC - stat doesn't work for all cases (Windows bug) @@ -1274,11 +1209,11 @@ bool QFSFileEnginePrivate::doStat() const } -static QString readSymLink(const QString &link) +static QString readSymLink(const QFileSystemEntry &link) { QString result; #if !defined(Q_OS_WINCE) - HANDLE handle = CreateFile((wchar_t*)QFSFileEnginePrivate::longFileName(link).utf16(), + HANDLE handle = CreateFile((wchar_t*)link.nativeFilePath().utf16(), FILE_READ_EA, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, @@ -1328,7 +1263,7 @@ static QString readSymLink(const QString &link) return result; } -static QString readLink(const QString &link) +static QString readLink(const QFileSystemEntry &link) { #if !defined(Q_OS_WINCE) #if !defined(QT_NO_LIBRARY) && !defined(Q_CC_MWERKS) @@ -1352,7 +1287,7 @@ static QString readLink(const QString &link) IPersistFile *ppf; hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf); if (SUCCEEDED(hres)) { - hres = ppf->Load((LPOLESTR)link.utf16(), STGM_READ); + hres = ppf->Load((LPOLESTR)link.nativeFilePath().utf16(), STGM_READ); //The original path of the link is retrieved. If the file/folder //was moved, the return value still have the old path. if (SUCCEEDED(hres)) { @@ -1374,7 +1309,7 @@ static QString readLink(const QString &link) #else wchar_t target[MAX_PATH]; QString result; - if (SHGetShortcutTarget((wchar_t*)QFileInfo(link).absoluteFilePath().replace(QLatin1Char('/'),QLatin1Char('\\')).utf16(), target, MAX_PATH)) { + if (SHGetShortcutTarget((wchar_t*)QFileInfo(link.filePath()).absoluteFilePath().replace(QLatin1Char('/'),QLatin1Char('\\')).utf16(), target, MAX_PATH)) { result = QString::fromWCharArray(target); if (result.startsWith(QLatin1Char('"'))) result.remove(0,1); @@ -1458,7 +1393,7 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions(QAbstractFil if(ptrGetNamedSecurityInfoW && ptrBuildTrusteeWithSidW && ptrGetEffectiveRightsFromAclW) { enum { ReadMask = 0x00000001, WriteMask = 0x00000002, ExecMask = 0x00000020 }; - QString fname = filePath.endsWith(QLatin1String(".lnk")) ? readLink(filePath) : filePath; + QString fname = fileEntry.filePath().endsWith(QLatin1String(".lnk")) ? readLink(fileEntry) : fileEntry.filePath(); PSID pOwner = 0; PSID pGroup = 0; PACL pDacl; @@ -1528,7 +1463,7 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions(QAbstractFil | QAbstractFileEngine::WriteOtherPerm; } - QString fname = filePath.endsWith(QLatin1String(".lnk")) ? readLink(filePath) : filePath; + QString fname = fileEntry.filePath().endsWith(QLatin1String(".lnk")) ? readLink(fileEntry) : fileEntry.filePath(); QString ext = fname.right(4).toLower(); if ((fileAttrib & FILE_ATTRIBUTE_DIRECTORY) || ext == QLatin1String(".exe") || ext == QLatin1String(".com") || ext == QLatin1String(".bat") || @@ -1561,16 +1496,8 @@ bool QFSFileEnginePrivate::isSymlink() const is_link = false; if (fileAttrib & FILE_ATTRIBUTE_REPARSE_POINT) { - QString path = QDir::toNativeSeparators(filePath); - // path for the FindFirstFile should not end with a trailing slash - while (path.endsWith(QLatin1Char('\\'))) - path.chop(1); - WIN32_FIND_DATA findData; - HANDLE hFind = ::FindFirstFile((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), - &findData); - if (hFind != INVALID_HANDLE_VALUE) { - ::FindClose(hFind); + if (getFindData(fileEntry.nativeFilePath(), findData)) { if ((findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK || findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) { is_link = true; @@ -1606,9 +1533,9 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil } } if (type & TypesMask) { - if (d->filePath.endsWith(QLatin1String(".lnk"))) { + if (d->fileEntry.filePath().endsWith(QLatin1String(".lnk"))) { ret |= LinkType; - QString l = readLink(d->filePath); + QString l = readLink(d->fileEntry); if (!l.isEmpty()) { bool existed = false; if (isDirPath(l, &existed) && existed) @@ -1630,7 +1557,7 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil ret |= LocalDiskFlag; if (d->doStat()) { ret |= ExistsFlag; - if (d->filePath == QLatin1String("/") || isDriveRoot(d->filePath) || isUncRoot(d->filePath)) + if (d->fileEntry.isRoot()) ret |= RootFlag; else if (d->fileAttrib & FILE_ATTRIBUTE_HIDDEN) ret |= HiddenFlag; @@ -1643,50 +1570,26 @@ QString QFSFileEngine::fileName(FileName file) const { Q_D(const QFSFileEngine); if (file == BaseName) { - int slash = d->filePath.lastIndexOf(QLatin1Char('/')); - if (slash == -1) { - int colon = d->filePath.lastIndexOf(QLatin1Char(':')); - if (colon != -1) - return d->filePath.mid(colon + 1); - return d->filePath; - } - return d->filePath.mid(slash + 1); + return d->fileEntry.fileName(); } else if (file == PathName) { - if (!d->filePath.size()) - return d->filePath; - - int slash = d->filePath.lastIndexOf(QLatin1Char('/')); - if (slash == -1) { - if (d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':')) - return d->filePath.left(2); - return QString(QLatin1Char('.')); - } else { - if (!slash) - return QString(QLatin1Char('/')); - if (slash == 2 && d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':')) - slash++; - return d->filePath.left(slash); - } + return d->fileEntry.path(); } else if (file == AbsoluteName || file == AbsolutePathName) { QString ret; if (!isRelativePath()) { #if !defined(Q_OS_WINCE) - if (d->filePath.startsWith(QLatin1Char('/')) || // It's a absolute path to the current drive, so \a.txt -> Z:\a.txt - d->filePath.size() == 2 || // It's a drive letter that needs to get a working dir appended - (d->filePath.size() > 2 && d->filePath.at(2) != QLatin1Char('/')) || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt - d->filePath.contains(QLatin1String("/../")) || d->filePath.contains(QLatin1String("/./")) || - d->filePath.endsWith(QLatin1String("/..")) || d->filePath.endsWith(QLatin1String("/."))) + if (d->fileEntry.filePath().startsWith(QLatin1Char('/')) || // It's a absolute path to the current drive, so \a.txt -> Z:\a.txt + d->fileEntry.filePath().size() == 2 || // It's a drive letter that needs to get a working dir appended + (d->fileEntry.filePath().size() > 2 && d->fileEntry.filePath().at(2) != QLatin1Char('/')) || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt + d->fileEntry.filePath().contains(QLatin1String("/../")) || d->fileEntry.filePath().contains(QLatin1String("/./")) || + d->fileEntry.filePath().endsWith(QLatin1String("/..")) || d->fileEntry.filePath().endsWith(QLatin1String("/."))) { - ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(d->filePath)); - } else { - ret = d->filePath; + ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(d->fileEntry.filePath())); } -#else - ret = d->filePath; #endif + ret = d->fileEntry.filePath(); } else { - ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + d->filePath); + ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + d->fileEntry.filePath()); } // The path should be absolute at this point. @@ -1728,25 +1631,22 @@ QString QFSFileEngine::fileName(FileName file) const return ret; } else if (file == LinkName) { QString ret; - if (d->filePath.endsWith(QLatin1String(".lnk"))) - ret = readLink(d->filePath); + if (d->fileEntry.filePath().endsWith(QLatin1String(".lnk"))) + ret = readLink(d->fileEntry); else if (d->doStat() && d->isSymlink()) - ret = readSymLink(d->filePath); + ret = readSymLink(d->fileEntry); return QDir::fromNativeSeparators(ret); } else if (file == BundleName) { return QString(); } - return d->filePath; + return d->fileEntry.filePath(); } bool QFSFileEngine::isRelativePath() const { Q_D(const QFSFileEngine); // drive, e.g. "a:", or UNC root, e.q. "//" - return !(d->filePath.startsWith(QLatin1Char('/')) - || (d->filePath.length() >= 2 - && ((d->filePath.at(0).isLetter() && d->filePath.at(1) == QLatin1Char(':')) - || (d->filePath.at(0) == QLatin1Char('/') && d->filePath.at(1) == QLatin1Char('/'))))); + return d->fileEntry.isRelative(); } uint QFSFileEngine::ownerId(FileOwner /*own*/) const @@ -1765,7 +1665,7 @@ QString QFSFileEngine::owner(FileOwner own) const if (ptrGetNamedSecurityInfoW && ptrLookupAccountSidW) { PSID pOwner = 0; PSECURITY_DESCRIPTOR pSD; - if (ptrGetNamedSecurityInfoW((wchar_t*)d->filePath.utf16(), SE_FILE_OBJECT, + if (ptrGetNamedSecurityInfoW((wchar_t*)d->fileEntry.nativeFilePath().utf16(), SE_FILE_OBJECT, own == OwnerGroup ? GROUP_SECURITY_INFORMATION : OWNER_SECURITY_INFORMATION, own == OwnerUser ? &pOwner : 0, own == OwnerGroup ? &pOwner : 0, 0, 0, &pSD) == ERROR_SUCCESS) { @@ -1817,7 +1717,7 @@ bool QFSFileEngine::setPermissions(uint perms) if (mode == 0) // not supported return false; - ret = ::_wchmod((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(), mode) == 0; + ret = ::_wchmod((wchar_t*)d->fileEntry.nativeFilePath().utf16(), mode) == 0; if (!ret) setError(QFile::PermissionsError, qt_error_string(errno)); return ret; @@ -1847,9 +1747,9 @@ bool QFSFileEngine::setSize(qint64 size) return false; } - if (!d->nativeFilePath.isEmpty()) { + if (!d->fileEntry.isEmpty()) { // resize file on disk - QFile file(d->filePath); + QFile file(d->fileEntry.filePath()); if (file.open(QFile::ReadWrite)) { bool ret = file.resize(size); if (!ret) @@ -1915,27 +1815,16 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const #endif } else { WIN32_FILE_ATTRIBUTE_DATA attribData; - bool ok = ::GetFileAttributesEx((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(), GetFileExInfoStandard, &attribData); + bool ok = ::GetFileAttributesEx((wchar_t*)QFSFileEnginePrivate::longFileName(d->fileEntry.filePath()).utf16(), GetFileExInfoStandard, &attribData); if (!ok) { int errorCode = GetLastError(); if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) { - QString path = QDir::toNativeSeparators(d->filePath); - // path for the FindFirstFile should not end with a trailing slash - while (path.endsWith(QLatin1Char('\\'))) - path.chop(1); - - // FindFirstFile can not handle drives - if (!path.endsWith(QLatin1Char(':'))) { - WIN32_FIND_DATA findData; - HANDLE hFind = ::FindFirstFile((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), - &findData); - if (hFind != INVALID_HANDLE_VALUE) { - ::FindClose(hFind); - ok = true; - attribData.ftCreationTime = findData.ftCreationTime; - attribData.ftLastWriteTime = findData.ftLastWriteTime; - attribData.ftLastAccessTime = findData.ftLastAccessTime; - } + WIN32_FIND_DATA findData; + if (getFindData(d->fileEntry.nativeFilePath(), findData)) { + ok = true; + attribData.ftCreationTime = findData.ftCreationTime; + attribData.ftLastWriteTime = findData.ftLastWriteTime; + attribData.ftLastAccessTime = findData.ftLastAccessTime; } } } @@ -1977,7 +1866,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, #ifdef Q_USE_DEPRECATED_MAP_API nativeClose(); // handle automatically closed by kernel with mapHandle (below). - handle = ::CreateFileForMapping((const wchar_t*)nativeFilePath.constData(), + handle = ::CreateFileForMapping((const wchar_t*)fileEntry.nativeFilePath().utf16(), GENERIC_READ | (openMode & QIODevice::WriteOnly ? GENERIC_WRITE : 0), 0, NULL, diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index c34c4a4..a0d3176 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -295,7 +295,7 @@ public: : QFSFileEngine(), filePathIsTemplate(fileIsTemplate) { Q_D(QFSFileEngine); - d->filePath = file; + d->fileEntry = QFileSystemEntry(file); if (!filePathIsTemplate) QFSFileEngine::setFileName(file); @@ -346,7 +346,7 @@ void QTemporaryFileEngine::setFileTemplate(const QString &fileTemplate) { Q_D(QFSFileEngine); if (filePathIsTemplate) - d->filePath = fileTemplate; + d->fileEntry = QFileSystemEntry(fileTemplate); } bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) @@ -359,7 +359,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) if (!filePathIsTemplate) return QFSFileEngine::open(openMode); - QString qfilename = d->filePath; + QString qfilename = d->fileEntry.filePath(); if(!qfilename.contains(QLatin1String("XXXXXX"))) qfilename += QLatin1String(".XXXXXX"); @@ -377,9 +377,8 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) d->closeFileHandle = true; // Restore the file names (open() resets them). - d->filePath = QString::fromLocal8Bit(filename); //changed now! + d->fileEntry = QFileSystemEntry(QByteArray(filename)); //changed now! filePathIsTemplate = false; - d->nativeInitFileName(); delete [] filename; return true; } @@ -395,9 +394,8 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) return false; } - QString template_ = d->filePath; - d->filePath = QString::fromLocal8Bit(filename); - d->nativeInitFileName(); + QString template_ = d->fileEntry.filePath(); + d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(filename)); delete [] filename; if (QFSFileEngine::open(openMode)) { @@ -405,8 +403,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) return true; } - d->filePath = template_; - d->nativeFilePath.clear(); + d->fileEntry = QFileSystemEntry(template_); return false; #endif } @@ -418,7 +415,7 @@ bool QTemporaryFileEngine::remove() // we must explicitly call QFSFileEngine::close() before we remove it. QFSFileEngine::close(); if (QFSFileEngine::remove()) { - d->filePath.clear(); + d->fileEntry.clear(); return true; } return false; -- cgit v0.12 From 3fed8517dc34b77707a42eb1f43a4e7199f105c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 30 Aug 2010 13:57:31 +0200 Subject: QFileSystemEngine::isCaseSensitive for Symbian and Windows --- src/corelib/io/qfilesystemengine_unix.cpp | 4 ++++ src/corelib/io/qfilesystemengine_win.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 2274e69..68cc154 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -46,7 +46,11 @@ QT_BEGIN_NAMESPACE bool QFileSystemEngine::isCaseSensitive() { +#if defined(Q_OS_SYMBIAN) + return false; +#else return true; +#endif } //static diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 942415c..40df120 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE bool QFileSystemEngine::isCaseSensitive() { - return true; + return false; } //static -- cgit v0.12 From 1bdc1dfda903426e7a0bd844c48e67ff9e6b6a94 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Mon, 30 Aug 2010 17:41:37 +0200 Subject: Fix the tst_QFileInfo::absolutePath() autotests on Windows Reviewed-by: Joao --- src/corelib/io/qfsfileengine_win.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 6f81652..9f33af5 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1585,9 +1585,11 @@ QString QFSFileEngine::fileName(FileName file) const d->fileEntry.filePath().endsWith(QLatin1String("/..")) || d->fileEntry.filePath().endsWith(QLatin1String("/."))) { ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(d->fileEntry.filePath())); - } + } else #endif - ret = d->fileEntry.filePath(); + { + ret = d->fileEntry.filePath(); + } } else { ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + d->fileEntry.filePath()); } -- cgit v0.12 From 900eb656849d4fa3ff119305c08b631c76fae75e Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Mon, 30 Aug 2010 17:28:02 +0200 Subject: Move canonicalPath() to the new qfilesystemengine_unix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: João Abecasis --- qmake/Makefile.unix | 6 +- qmake/Makefile.win32 | 5 ++ qmake/Makefile.win32-g++ | 4 + qmake/qmake.pri | 1 + src/corelib/io/io.pri | 3 +- src/corelib/io/qfilesystemengine.cpp | 113 +++++++++++++++++++++++++++ src/corelib/io/qfilesystemengine_p.h | 2 + src/corelib/io/qfilesystemengine_unix.cpp | 21 ++++- src/corelib/io/qfsfileengine.cpp | 57 +------------- src/corelib/io/qfsfileengine_unix.cpp | 19 ++--- src/tools/bootstrap/bootstrap.pro | 1 + tools/configure/configure.pro | 1 + tools/qtestlib/wince/cetest/bootstrapped.pri | 1 + 13 files changed, 162 insertions(+), 72 deletions(-) create mode 100644 src/corelib/io/qfilesystemengine.cpp diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 8c1ac6d..4eba3f5 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -16,7 +16,7 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \ #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \ qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfile.o \ - qfilesystementry.o qfilesystemengine_unix.o \ + qfilesystementry.o qfilesystemengine_unix.o qfilesystemengine.o \ qfsfileengine_unix.o qfsfileengine_iterator_unix.o qfsfileengine.o \ qfsfileengine_iterator.o qregexp.o qvector.o qbitarray.o qdir.o qdiriterator.o quuid.o qhash.o \ qfileinfo.o qdatetime.o qstringlist.o qabstractfileengine.o qtemporaryfile.o \ @@ -46,6 +46,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp \ $(SOURCE_PATH)/src/corelib/io/qdatastream.cpp $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp \ $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp \ + $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine_unix.cpp $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator_unix.cpp $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp $(SOURCE_PATH)/src/corelib/tools/qlist.cpp \ @@ -165,6 +166,9 @@ qfile.o: $(SOURCE_PATH)/src/corelib/io/qfile.cpp qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp +qfilesystemengine.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp + qfilesystemengine_unix.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index b76348b..ec64fa9 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -89,6 +89,7 @@ QTOBJS= \ qbuffer.obj \ qcryptographichash.obj \ qfilesystementry.obj \ + qfilesystemengine.obj \ qfilesystemengine_win.obj \ qfsfileengine.obj \ qfsfileengine_iterator.obj \ @@ -144,6 +145,7 @@ clean:: -del qcryptographichash.obj -del qlinkedlist.obj -del qfilesystementry.obj + -del qfilesystemengine.obj -del qfilesystemengine_win.obj -del qfsfileengine.obj -del qfsfileengine_iterator.obj @@ -317,6 +319,9 @@ qtemporaryfile.obj: $(SOURCE_PATH)\src\corelib\io\qtemporaryfile.cpp qfilesystementry.obj: $(SOURCE_PATH)\src\corelib\io\qfilesystementry.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfilesystementry.cpp +qfilesystemengine.obj: $(SOURCE_PATH)\src\corelib\io\qfilesystemengine.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfilesystemengine.cpp + qfilesystemengine_win.obj: $(SOURCE_PATH)\src\corelib\io\qfilesystemengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfilesystemengine_win.cpp diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index c692731..f2f8386 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -62,6 +62,7 @@ QTOBJS= \ qfileinfo.o \ qabstractfileengine.o \ qfilesystementry.o \ + qfilesystemengine.o \ qfilesystemengine_win.o \ qfsfileengine.o \ qfsfileengine_iterator.o \ @@ -197,6 +198,9 @@ qabstractfileengine.o: $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp +qfilesystemengine.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp + qfilesystemengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp diff --git a/qmake/qmake.pri b/qmake/qmake.pri index 4d78c8b..be6a909 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -58,6 +58,7 @@ bootstrap { #Qt code qabstractfileengine.cpp \ qfileinfo.cpp \ qfilesystementry.cpp \ + qfilesystemengine.cpp \ qfsfileengine.cpp \ qfsfileengine_iterator.cpp \ qglobal.cpp \ diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 3bde2de..7a34275 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -56,7 +56,8 @@ SOURCES += \ io/qfsfileengine.cpp \ io/qfsfileengine_iterator.cpp \ io/qfilesystemwatcher.cpp \ - io/qfilesystementry.cpp + io/qfilesystementry.cpp \ + io/qfilesystemengine.cpp win32 { SOURCES += io/qsettings_win.cpp diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp new file mode 100644 index 0000000..04e53ce --- /dev/null +++ b/src/corelib/io/qfilesystemengine.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "qfilesystemengine_p.h" +#include +#include + +/*! + \internal + + Returns the canonicalized form of \a path (i.e., with all symlinks + resolved, and all redundant path elements removed. +*/ +QString QFileSystemEngine::slowCanonicalized(const QString &path) +{ + if (path.isEmpty()) + return path; + + QFileInfo fi; + const QChar slash(QLatin1Char('/')); + QString tmpPath = path; + int separatorPos = 0; + QSet nonSymlinks; + QSet known; + + known.insert(path); + do { +#ifdef Q_OS_WIN + if (separatorPos == 0) { + if (tmpPath.size() >= 2 && tmpPath.at(0) == slash && tmpPath.at(1) == slash) { + // UNC, skip past the first two elements + separatorPos = tmpPath.indexOf(slash, 2); + } else if (tmpPath.size() >= 3 && tmpPath.at(1) == QLatin1Char(':') && tmpPath.at(2) == slash) { + // volume root, skip since it can not be a symlink + separatorPos = 2; + } + } + if (separatorPos != -1) +#endif + separatorPos = tmpPath.indexOf(slash, separatorPos + 1); + QString prefix = separatorPos == -1 ? tmpPath : tmpPath.left(separatorPos); + if ( +#ifdef Q_OS_SYMBIAN + // Symbian doesn't support directory symlinks, so do not check for link unless we + // are handling the last path element. This not only slightly improves performance, + // but also saves us from lot of unnecessary platform security check failures + // when dealing with files under *:/private directories. + separatorPos == -1 && +#endif + !nonSymlinks.contains(prefix)) { + fi.setFile(prefix); + if (fi.isSymLink()) { + QString target = fi.symLinkTarget(); + if(QFileInfo(target).isRelative()) + target = fi.absolutePath() + slash + target; + if (separatorPos != -1) { + if (fi.isDir() && !target.endsWith(slash)) + target.append(slash); + target.append(tmpPath.mid(separatorPos)); + } + tmpPath = QDir::cleanPath(target); + separatorPos = 0; + + if (known.contains(tmpPath)) + return QString(); + known.insert(tmpPath); + } else { + nonSymlinks.insert(prefix); + } + } + } while (separatorPos != -1); + + return QDir::cleanPath(tmpPath); +} + diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index c1bb3b4..61ca085 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -84,6 +84,8 @@ public: static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QFileSystemMetaData *data = 0); + + static QString slowCanonicalized(const QString &path); }; QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 68cc154..283c787 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -42,6 +42,9 @@ #include "qfilesystemengine_p.h" #include "qfsfileengine.h" +#include // for realpath() +#include + QT_BEGIN_NAMESPACE bool QFileSystemEngine::isCaseSensitive() @@ -62,7 +65,23 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link) //static QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) { - return entry; // TODO implement; + if (entry.isEmpty() || entry.isRoot()) + return entry; + +#ifdef __UCLIBC__ + return QFileSystemEntry::slowCanonicalName(entry); +#else + + char *ret = realpath(entry.nativeFilePath().constData(), (char*)0); + if (ret) { + QString canonicalPath = QDir::cleanPath(QString::fromLocal8Bit(ret)); + free(ret); + return QFileSystemEntry(canonicalPath); + } else if (errno == ENOENT) { // file doesn't exist + return QFileSystemEntry(); + } + return entry; +#endif } //static diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 75f82a6..665d23e 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -41,6 +41,7 @@ #include "qfsfileengine_p.h" #include "qfsfileengine_iterator_p.h" +#include "qfilesystemengine_p.h" #include "qdatetime.h" #include "qdiriterator.h" #include "qset.h" @@ -179,61 +180,7 @@ QString QFSFileEnginePrivate::canonicalized(const QString &path) #endif #endif - QFileInfo fi; - const QChar slash(QLatin1Char('/')); - QString tmpPath = path; - int separatorPos = 0; - QSet nonSymlinks; - QSet known; - - known.insert(path); - do { -#ifdef Q_OS_WIN - if (separatorPos == 0) { - if (tmpPath.size() >= 2 && tmpPath.at(0) == slash && tmpPath.at(1) == slash) { - // UNC, skip past the first two elements - separatorPos = tmpPath.indexOf(slash, 2); - } else if (tmpPath.size() >= 3 && tmpPath.at(1) == QLatin1Char(':') && tmpPath.at(2) == slash) { - // volume root, skip since it can not be a symlink - separatorPos = 2; - } - } - if (separatorPos != -1) -#endif - separatorPos = tmpPath.indexOf(slash, separatorPos + 1); - QString prefix = separatorPos == -1 ? tmpPath : tmpPath.left(separatorPos); - if ( -#ifdef Q_OS_SYMBIAN - // Symbian doesn't support directory symlinks, so do not check for link unless we - // are handling the last path element. This not only slightly improves performance, - // but also saves us from lot of unnecessary platform security check failures - // when dealing with files under *:/private directories. - separatorPos == -1 && -#endif - !nonSymlinks.contains(prefix)) { - fi.setFile(prefix); - if (fi.isSymLink()) { - QString target = fi.symLinkTarget(); - if(QFileInfo(target).isRelative()) - target = fi.absolutePath() + slash + target; - if (separatorPos != -1) { - if (fi.isDir() && !target.endsWith(slash)) - target.append(slash); - target.append(tmpPath.mid(separatorPos)); - } - tmpPath = QDir::cleanPath(target); - separatorPos = 0; - - if (known.contains(tmpPath)) - return QString(); - known.insert(tmpPath); - } else { - nonSymlinks.insert(prefix); - } - } - } while (separatorPos != -1); - - return QDir::cleanPath(tmpPath); + return QFileSystemEngine::slowCanonicalized(path); } /*! diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 3daf7f6..29491f5 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -1027,25 +1027,16 @@ QString QFSFileEngine::fileName(FileName file) const } else if (file == PathName) { return d->fileEntry.path(); } else if (file == AbsoluteName || file == AbsolutePathName) { - QFileSystemEntry entry = QFileSystemEngine::absoluteName(d->fileEntry); + QFileSystemEntry entry(QFileSystemEngine::absoluteName(d->fileEntry)); if (file == AbsolutePathName) { return entry.path(); } return entry.filePath(); } else if (file == CanonicalName || file == CanonicalPathName) { - if (!(fileFlags(ExistsFlag) & ExistsFlag)) - return QString(); - - QString ret = QFSFileEnginePrivate::canonicalized(fileName(AbsoluteName)); - if (file == CanonicalPathName && !ret.isEmpty()) { - int slash = ret.lastIndexOf(QLatin1Char('/')); - if (slash == -1) - ret = QDir::currentPath(); - else if (slash == 0) - ret = QLatin1String("/"); - ret = ret.left(slash); - } - return ret; + QFileSystemEntry entry(QFileSystemEngine::canonicalName(d->fileEntry)); + if (file == CanonicalPathName) + return entry.path(); + return entry.filePath(); } else if (file == LinkName) { if (d->isSymlink()) { #if defined(__GLIBC__) && !defined(PATH_MAX) diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index bec1329..9adba9c 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -58,6 +58,7 @@ SOURCES += \ ../../corelib/io/qfile.cpp \ ../../corelib/io/qfileinfo.cpp \ ../../corelib/io/qfilesystementry.cpp \ + ../../corelib/io/qfilesystemengine.cpp \ ../../corelib/io/qfsfileengine.cpp \ ../../corelib/io/qfsfileengine_iterator.cpp \ ../../corelib/io/qiodevice.cpp \ diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index 9e52f81..854a0e4 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -90,6 +90,7 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfileinfo.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qabstractfileengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry.cpp \ + $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_win.cpp \ diff --git a/tools/qtestlib/wince/cetest/bootstrapped.pri b/tools/qtestlib/wince/cetest/bootstrapped.pri index 0af5c94..f33dde8 100644 --- a/tools/qtestlib/wince/cetest/bootstrapped.pri +++ b/tools/qtestlib/wince/cetest/bootstrapped.pri @@ -5,6 +5,7 @@ SOURCES += \ $$QT_SOURCE_TREE/src/corelib/io/qfile.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qdir.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry.cpp \ + $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qabstractfileengine.cpp \ -- cgit v0.12 From c2df86d23477573ef664a20b47b19a42e4a2e6c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 30 Aug 2010 15:02:29 +0200 Subject: Removed QFileInfoPrivate::initFileEngine As it served no real purpose. Instead, the relevant bits were inlined in the constructor that used it and makeAbsolute was adapted to use operator=. Reviewed-by: Thomas Zander --- src/corelib/io/qfileinfo.cpp | 12 ++---------- src/corelib/io/qfileinfo_p.h | 5 ++--- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index fe557d0..ccfc9c2 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -47,15 +47,6 @@ QT_BEGIN_NAMESPACE -void QFileInfoPrivate::initFileEngine(const QString &file) -{ - delete fileEngine; - fileEngine = 0; - clear(); - fileEngine = QAbstractFileEngine::create(file); - fileName = file; -} - QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const { if (cache_enabled && !fileNames[(int)name].isNull()) @@ -586,7 +577,8 @@ bool QFileInfo::makeAbsolute() return false; QString absFileName = d_ptr.constData()->getFileName(QAbstractFileEngine::AbsoluteName); // QSharedDataPointer::operator->() will detach. - d_ptr->initFileEngine(absFileName); + + *this = QFileInfo(absFileName); return true; } diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h index 138116e..f23ae53 100644 --- a/src/corelib/io/qfileinfo_p.h +++ b/src/corelib/io/qfileinfo_p.h @@ -79,16 +79,15 @@ public: cachedFlags(0), cache_enabled(copy.cache_enabled), fileFlags(0), fileSize(0) {} inline QFileInfoPrivate(const QString &file) - : QSharedData(), fileEngine(0), + : QSharedData(), fileEngine(QAbstractFileEngine::create(file)), + fileName(file), cachedFlags(0), cache_enabled(1), fileFlags(0), fileSize(0) { - initFileEngine(file); } inline ~QFileInfoPrivate() { delete fileEngine; } - void initFileEngine(const QString &); inline void clearFlags() const { fileFlags = 0; -- cgit v0.12 From 7a8cdcac068898697f9f0f75c410ea673d6f0d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 30 Aug 2010 16:59:20 +0200 Subject: Adding minimal QFileSystemIterator API Only stubs, for now, but it's a start. Reviewed-by: Thomas Zander --- qmake/Makefile.unix | 7 ++- qmake/Makefile.win32 | 5 ++ qmake/Makefile.win32-g++ | 4 ++ qmake/Makefile.win32-g++-sh | 4 ++ qmake/qmake.pri | 4 +- src/corelib/io/io.pri | 5 +- src/corelib/io/qfilesystemiterator_p.h | 78 ++++++++++++++++++++++++++++ src/corelib/io/qfilesystemiterator_unix.cpp | 61 ++++++++++++++++++++++ src/corelib/io/qfilesystemiterator_win.cpp | 61 ++++++++++++++++++++++ src/tools/bootstrap/bootstrap.pro | 2 + tools/configure/configure.pro | 2 + tools/qtestlib/wince/cetest/bootstrapped.pri | 1 + 12 files changed, 229 insertions(+), 5 deletions(-) create mode 100644 src/corelib/io/qfilesystemiterator_p.h create mode 100644 src/corelib/io/qfilesystemiterator_unix.cpp create mode 100644 src/corelib/io/qfilesystemiterator_win.cpp diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 4eba3f5..e8e96fd 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -16,7 +16,7 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \ #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \ qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfile.o \ - qfilesystementry.o qfilesystemengine_unix.o qfilesystemengine.o \ + qfilesystementry.o qfilesystemengine_unix.o qfilesystemengine.o qfilesystemiterator_unix.o \ qfsfileengine_unix.o qfsfileengine_iterator_unix.o qfsfileengine.o \ qfsfileengine_iterator.o qregexp.o qvector.o qbitarray.o qdir.o qdiriterator.o quuid.o qhash.o \ qfileinfo.o qdatetime.o qstringlist.o qabstractfileengine.o qtemporaryfile.o \ @@ -46,7 +46,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp \ $(SOURCE_PATH)/src/corelib/io/qdatastream.cpp $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp \ $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp \ - $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp \ + $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_unix.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine_unix.cpp $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator_unix.cpp $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp $(SOURCE_PATH)/src/corelib/tools/qlist.cpp \ @@ -172,6 +172,9 @@ qfilesystemengine.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp qfilesystemengine_unix.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp +qfilesystemiterator_unix.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_unix.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_unix.cpp + qfsfileengine.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index ec64fa9..fa17b9d 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -91,6 +91,7 @@ QTOBJS= \ qfilesystementry.obj \ qfilesystemengine.obj \ qfilesystemengine_win.obj \ + qfilesystemiterator_win.obj \ qfsfileengine.obj \ qfsfileengine_iterator.obj \ qbytearray.obj \ @@ -147,6 +148,7 @@ clean:: -del qfilesystementry.obj -del qfilesystemengine.obj -del qfilesystemengine_win.obj + -del qfilesystemiterator_win.obj -del qfsfileengine.obj -del qfsfileengine_iterator.obj -del qbytearray.obj @@ -325,6 +327,9 @@ qfilesystemengine.obj: $(SOURCE_PATH)\src\corelib\io\qfilesystemengine.cpp qfilesystemengine_win.obj: $(SOURCE_PATH)\src\corelib\io\qfilesystemengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfilesystemengine_win.cpp +qfilesystemiterator_win.obj: $(SOURCE_PATH)\src\corelib\io\qfilesystemiterator_win.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfilesystemiterator_win.cpp + qfsfileengine_win.obj: $(SOURCE_PATH)\src\corelib\io\qfsfileengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfsfileengine_win.cpp diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index f2f8386..57ea3d5 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -64,6 +64,7 @@ QTOBJS= \ qfilesystementry.o \ qfilesystemengine.o \ qfilesystemengine_win.o \ + qfilesystemiterator_win.o \ qfsfileengine.o \ qfsfileengine_iterator.o \ qfsfileengine_win.o \ @@ -204,6 +205,9 @@ qfilesystemengine.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp qfilesystemengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp +qfilesystemiterator_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_win.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_win.cpp + qfsfileengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index cc256e9..33deb01 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -63,6 +63,7 @@ QTOBJS= \ qabstractfileengine.o \ qfilesystementry.o \ qfilesystemengine_win.o \ + qfilesystemiterator_win.o \ qfsfileengine.o \ qfsfileengine_iterator.o \ qfsfileengine_win.o \ @@ -199,6 +200,9 @@ qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp qfilesystemengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp +qfilesystemiterator_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_win.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_win.cpp + qfsfileengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp diff --git a/qmake/qmake.pri b/qmake/qmake.pri index be6a909..7226b12 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -127,14 +127,14 @@ bootstrap { #Qt code qxmlutils.h unix { - SOURCES += qfilesystemengine_unix.cpp qfsfileengine_unix.cpp qfsfileengine_iterator_unix.cpp + SOURCES += qfilesystemengine_unix.cpp qfilesystemiterator_unix.cpp qfsfileengine_unix.cpp qfsfileengine_iterator_unix.cpp mac { SOURCES += qcore_mac.cpp qsettings_mac.cpp QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 #enables weak linking for 10.4 (exported) LIBS += -framework ApplicationServices } } else:win32 { - SOURCES += qfilesystemengine_win.cpp qfsfileengine_win.cpp qfsfileengine_iterator_win.cpp qsettings_win.cpp + SOURCES += qfilesystemengine_win.cpp qfsfileengine_win.cpp qfilesystemiterator_win.cpp qfsfileengine_iterator_win.cpp qsettings_win.cpp win32-msvc*:LIBS += ole32.lib advapi32.lib win32-g++*:LIBS += -lole32 -luuid } diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 7a34275..5d10216 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -32,7 +32,8 @@ HEADERS += \ io/qfilesystemwatcher_p.h \ io/qfilesystementry_p.h \ io/qfilesystemengine_p.h \ - io/qfilesystemmetadata_p.h + io/qfilesystemmetadata_p.h \ + io/qfilesystemiterator_p.h SOURCES += \ io/qabstractfileengine.cpp \ @@ -70,8 +71,10 @@ win32 { HEADERS += io/qwindowspipewriter_p.h SOURCES += io/qwindowspipewriter.cpp SOURCES += io/qfilesystemengine_win.cpp + SOURCES += io/qfilesystemiterator_win.cpp } else:unix { SOURCES += io/qfilesystemengine_unix.cpp + SOURCES += io/qfilesystemiterator_unix.cpp SOURCES += io/qfsfileengine_unix.cpp SOURCES += io/qfsfileengine_iterator_unix.cpp symbian:SOURCES += io/qprocess_symbian.cpp diff --git a/src/corelib/io/qfilesystemiterator_p.h b/src/corelib/io/qfilesystemiterator_p.h new file mode 100644 index 0000000..436ff7e --- /dev/null +++ b/src/corelib/io/qfilesystemiterator_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef QFILESYSTEMITERATOR_P_H_INCLUDED +#define QFILESYSTEMITERATOR_P_H_INCLUDED + +// +// 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 +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +class QFileSystemIterator +{ +public: + QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, const QStringList &nameFilters); + + bool advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData); + +private: + Q_DISABLE_COPY(QFileSystemIterator) +}; + +QT_END_NAMESPACE + +#endif // include guard diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp new file mode 100644 index 0000000..3ee344b --- /dev/null +++ b/src/corelib/io/qfilesystemiterator_unix.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "qfilesystemiterator_p.h" + +QT_BEGIN_NAMESPACE + +QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, + const QStringList &nameFilters) +{ + Q_UNUSED(entry) + Q_UNUSED(filters) + Q_UNUSED(nameFilters) +} + +bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData) +{ + Q_UNUSED(fileEntry) + Q_UNUSED(metaData) + return false; +} + +QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp new file mode 100644 index 0000000..3ee344b --- /dev/null +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "qfilesystemiterator_p.h" + +QT_BEGIN_NAMESPACE + +QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, + const QStringList &nameFilters) +{ + Q_UNUSED(entry) + Q_UNUSED(filters) + Q_UNUSED(nameFilters) +} + +bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData) +{ + Q_UNUSED(fileEntry) + Q_UNUSED(metaData) + return false; +} + +QT_END_NAMESPACE diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 9adba9c..6d2f760 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -86,10 +86,12 @@ SOURCES += \ ../../xml/sax/qxml.cpp unix:SOURCES += ../../corelib/io/qfilesystemengine_unix.cpp \ + ../../corelib/io/qfilesystemiterator_unix.cpp \ ../../corelib/io/qfsfileengine_unix.cpp \ ../../corelib/io/qfsfileengine_iterator_unix.cpp win32:SOURCES += ../../corelib/io/qfilesystemengine_win.cpp \ + ../../corelib/io/qfilesystemiterator_win.cpp \ ../../corelib/io/qfsfileengine_win.cpp \ ../../corelib/io/qfsfileengine_iterator_win.cpp diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index 854a0e4..fe1b028 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -51,6 +51,7 @@ HEADERS = configureapp.h environment.h tools.h\ $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry_p.h \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine_p.h \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystemmetadata_p.h \ + $$QT_SOURCE_TREE/src/corelib/io/qfilesystemiterator_p.h \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.h \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_iterator_p.h \ $$QT_SOURCE_TREE/src/corelib/io/qiodevice.h \ @@ -92,6 +93,7 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine_win.cpp \ + $$QT_SOURCE_TREE/src/corelib/io/qfilesystemiterator_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_iterator.cpp \ diff --git a/tools/qtestlib/wince/cetest/bootstrapped.pri b/tools/qtestlib/wince/cetest/bootstrapped.pri index f33dde8..76245b0 100644 --- a/tools/qtestlib/wince/cetest/bootstrapped.pri +++ b/tools/qtestlib/wince/cetest/bootstrapped.pri @@ -7,6 +7,7 @@ SOURCES += \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine_win.cpp \ + $$QT_SOURCE_TREE/src/corelib/io/qfilesystemiterator_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qabstractfileengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_win.cpp \ -- cgit v0.12 From e074824409dae5d2e242c3a6904329826a708c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 30 Aug 2010 17:40:11 +0200 Subject: QFileInfo: Prepare for engine-less implementation The absence of a file engine was being interpreted as a synonym for a default constructed instance (or failed engine creation with QT_NO_FSFILEENGINE). By having an explicit flag, we open the door for bypassing file engine creation. Reviewed-by: Thomas Zander --- src/corelib/io/qfileinfo.cpp | 73 ++++++++++++++++++++++---------------------- src/corelib/io/qfileinfo_p.h | 32 +++++++++++++------ 2 files changed, 59 insertions(+), 46 deletions(-) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index ccfc9c2..248b83d 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -328,7 +328,7 @@ bool QFileInfo::operator==(const QFileInfo &fileinfo) const // ### (GetFullPathName()). if (fileinfo.d_ptr == d_ptr) return true; - if (!d->fileEngine || !fileinfo.d_ptr->fileEngine) + if (d->isDefaultConstructed || fileinfo.d_ptr->isDefaultConstructed) return false; if (d->fileEngine->caseSensitive() != fileinfo.d_ptr->fileEngine->caseSensitive()) return false; @@ -454,7 +454,7 @@ void QFileInfo::setFile(const QDir &dir, const QString &file) QString QFileInfo::absoluteFilePath() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::AbsoluteName); } @@ -471,7 +471,7 @@ QString QFileInfo::absoluteFilePath() const QString QFileInfo::canonicalFilePath() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::CanonicalName); } @@ -498,7 +498,7 @@ QString QFileInfo::absolutePath() const { Q_D(const QFileInfo); - if (!d->fileEngine) { + if (d->isDefaultConstructed) { return QLatin1String(""); } else if (d->fileName.isEmpty()) { qWarning("QFileInfo::absolutePath: Constructed with empty filename"); @@ -518,7 +518,7 @@ QString QFileInfo::absolutePath() const QString QFileInfo::canonicalPath() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::CanonicalPathName); } @@ -535,7 +535,7 @@ QString QFileInfo::canonicalPath() const QString QFileInfo::path() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::PathName); } @@ -559,7 +559,7 @@ QString QFileInfo::path() const bool QFileInfo::isRelative() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return true; return d->fileEngine->isRelativePath(); } @@ -573,7 +573,8 @@ bool QFileInfo::isRelative() const */ bool QFileInfo::makeAbsolute() { - if (!d_ptr.constData()->fileEngine || !d_ptr.constData()->fileEngine->isRelativePath()) + if (d_ptr.constData()->isDefaultConstructed + || !d_ptr.constData()->fileEngine->isRelativePath()) return false; QString absFileName = d_ptr.constData()->getFileName(QAbstractFileEngine::AbsoluteName); // QSharedDataPointer::operator->() will detach. @@ -591,7 +592,7 @@ bool QFileInfo::makeAbsolute() bool QFileInfo::exists() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::ExistsFlag); } @@ -618,7 +619,7 @@ void QFileInfo::refresh() QString QFileInfo::filePath() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::DefaultName); } @@ -637,7 +638,7 @@ QString QFileInfo::filePath() const QString QFileInfo::fileName() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::BaseName); } @@ -657,7 +658,7 @@ QString QFileInfo::fileName() const QString QFileInfo::bundleName() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::BundleName); } @@ -681,7 +682,7 @@ QString QFileInfo::bundleName() const QString QFileInfo::baseName() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::BaseName).section(QLatin1Char('.'), 0, 0); } @@ -700,7 +701,7 @@ QString QFileInfo::baseName() const QString QFileInfo::completeBaseName() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); QString name = d->getFileName(QAbstractFileEngine::BaseName); int index = name.lastIndexOf(QLatin1Char('.')); @@ -721,7 +722,7 @@ QString QFileInfo::completeBaseName() const QString QFileInfo::completeSuffix() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); QString fileName = d->getFileName(QAbstractFileEngine::BaseName); int firstDot = fileName.indexOf(QLatin1Char('.')); @@ -748,7 +749,7 @@ QString QFileInfo::completeSuffix() const QString QFileInfo::suffix() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); QString fileName = d->getFileName(QAbstractFileEngine::BaseName); int lastDot = fileName.lastIndexOf(QLatin1Char('.')); @@ -813,7 +814,7 @@ QDir QFileInfo::dir(bool absPath) const bool QFileInfo::isReadable() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::ReadUserPerm); } @@ -826,7 +827,7 @@ bool QFileInfo::isReadable() const bool QFileInfo::isWritable() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::WriteUserPerm); } @@ -839,7 +840,7 @@ bool QFileInfo::isWritable() const bool QFileInfo::isExecutable() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::ExeUserPerm); } @@ -853,7 +854,7 @@ bool QFileInfo::isExecutable() const bool QFileInfo::isHidden() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::HiddenFlag); } @@ -868,7 +869,7 @@ bool QFileInfo::isHidden() const bool QFileInfo::isFile() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::FileType); } @@ -882,7 +883,7 @@ bool QFileInfo::isFile() const bool QFileInfo::isDir() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::DirectoryType); } @@ -898,7 +899,7 @@ bool QFileInfo::isDir() const bool QFileInfo::isBundle() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::BundleType); } @@ -923,7 +924,7 @@ bool QFileInfo::isBundle() const bool QFileInfo::isSymLink() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::LinkType); } @@ -936,7 +937,7 @@ bool QFileInfo::isSymLink() const bool QFileInfo::isRoot() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return true; return d->getFileFlags(QAbstractFileEngine::RootFlag); } @@ -964,7 +965,7 @@ bool QFileInfo::isRoot() const QString QFileInfo::readLink() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::LinkName); } @@ -982,7 +983,7 @@ QString QFileInfo::readLink() const QString QFileInfo::owner() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileOwner(QAbstractFileEngine::OwnerUser); } @@ -998,7 +999,7 @@ QString QFileInfo::owner() const uint QFileInfo::ownerId() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return 0; return d->fileEngine->ownerId(QAbstractFileEngine::OwnerUser); } @@ -1016,7 +1017,7 @@ uint QFileInfo::ownerId() const QString QFileInfo::group() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileOwner(QAbstractFileEngine::OwnerGroup); } @@ -1032,7 +1033,7 @@ QString QFileInfo::group() const uint QFileInfo::groupId() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return 0; return d->fileEngine->ownerId(QAbstractFileEngine::OwnerGroup); } @@ -1053,7 +1054,7 @@ uint QFileInfo::groupId() const bool QFileInfo::permission(QFile::Permissions permissions) const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::FileFlags((int)permissions)) == (uint)permissions; } @@ -1065,7 +1066,7 @@ bool QFileInfo::permission(QFile::Permissions permissions) const QFile::Permissions QFileInfo::permissions() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return 0; return QFile::Permissions(d->getFileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask); } @@ -1080,7 +1081,7 @@ QFile::Permissions QFileInfo::permissions() const qint64 QFileInfo::size() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return 0; if (!d->getCachedFlag(QFileInfoPrivate::CachedSize)) { d->setCachedFlag(QFileInfoPrivate::CachedSize); @@ -1105,7 +1106,7 @@ qint64 QFileInfo::size() const QDateTime QFileInfo::created() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QDateTime(); return d->getFileTime(QAbstractFileEngine::CreationTime); } @@ -1118,7 +1119,7 @@ QDateTime QFileInfo::created() const QDateTime QFileInfo::lastModified() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QDateTime(); return d->getFileTime(QAbstractFileEngine::ModificationTime); } @@ -1134,7 +1135,7 @@ QDateTime QFileInfo::lastModified() const QDateTime QFileInfo::lastRead() const { Q_D(const QFileInfo); - if (!d->fileEngine) + if (d->isDefaultConstructed) return QDateTime(); return d->getFileTime(QAbstractFileEngine::AccessTime); } diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h index f23ae53..b9b1092 100644 --- a/src/corelib/io/qfileinfo_p.h +++ b/src/corelib/io/qfileinfo_p.h @@ -71,23 +71,33 @@ public: inline QFileInfoPrivate() : QSharedData(), fileEngine(0), - cachedFlags(0), cache_enabled(1), fileFlags(0), fileSize(0) + cachedFlags(0), + isDefaultConstructed(true), + cache_enabled(true), fileFlags(0), fileSize(0) {} inline QFileInfoPrivate(const QFileInfoPrivate ©) : QSharedData(copy), fileEngine(QAbstractFileEngine::create(copy.fileName)), fileName(copy.fileName), - cachedFlags(0), cache_enabled(copy.cache_enabled), fileFlags(0), fileSize(0) + cachedFlags(0), +#ifndef QT_NO_FSFILEENGINE + isDefaultConstructed(false), +#else + isDefaultConstructed(!fileEngine), +#endif + cache_enabled(copy.cache_enabled), fileFlags(0), fileSize(0) {} inline QFileInfoPrivate(const QString &file) : QSharedData(), fileEngine(QAbstractFileEngine::create(file)), fileName(file), - cachedFlags(0), cache_enabled(1), fileFlags(0), fileSize(0) + cachedFlags(0), +#ifndef QT_NO_FSFILEENGINE + isDefaultConstructed(false), +#else + isDefaultConstructed(!fileEngine), +#endif + cache_enabled(true), fileFlags(0), fileSize(0) { } - inline ~QFileInfoPrivate() - { - delete fileEngine; - } inline void clearFlags() const { fileFlags = 0; @@ -108,13 +118,15 @@ public: QString getFileName(QAbstractFileEngine::FileName) const; QString getFileOwner(QAbstractFileEngine::FileOwner own) const; - QAbstractFileEngine *fileEngine; + QScopedPointer const fileEngine; + mutable QString fileName; mutable QString fileNames[QAbstractFileEngine::NFileNames]; mutable QString fileOwners[2]; - mutable uint cachedFlags : 31; - mutable uint cache_enabled : 1; + mutable uint cachedFlags : 30; + bool const isDefaultConstructed : 1; // QFileInfo is a default constructed instance + bool cache_enabled : 1; mutable uint fileFlags; mutable qint64 fileSize; mutable QDateTime fileTimes[3]; -- cgit v0.12 From 50db9fb1bf4944d4b8e3077e0a9d30afb4495c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 30 Aug 2010 18:47:13 +0200 Subject: Reverting QDir::detach introduced earlier From the client API it is a broken concept, because it could leave the user with an uninitialized file engine. Fixing to initialize the file engine, would mean it is useless for internal use where file engines are initialized separately. In the end, removing both the QDir::detach introduced earlier and throwing away the private d_func'tions altogether is a binary-compatible change that should allow us to push this change in a patch release (fingers crossed!) Reviewed-by: Thiago Macieira --- src/corelib/io/qdir.cpp | 71 +++++++++++++++++++++++-------------------------- src/corelib/io/qdir.h | 13 --------- 2 files changed, 33 insertions(+), 51 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 9ebfce5..b355f62 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -561,11 +561,6 @@ QDir::~QDir() { } -void QDir::detach() -{ - d_ptr.detach(); -} - /*! Sets the path of the directory to \a path. The path is cleaned of redundant ".", ".." and of multiple separators. No check is made @@ -599,7 +594,7 @@ void QDir::setPath(const QString &path) */ QString QDir::path() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); return d->path; } @@ -613,7 +608,7 @@ QString QDir::path() const */ QString QDir::absolutePath() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); QString ret = d->path; if (QDir::isRelativePath(ret)) ret = absoluteFilePath(QString::fromLatin1("")); @@ -638,7 +633,7 @@ QString QDir::absolutePath() const */ QString QDir::canonicalPath() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (!d->fileEngine) return QLatin1String(""); @@ -658,7 +653,7 @@ QString QDir::canonicalPath() const */ QString QDir::dirName() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); int pos = d->path.lastIndexOf(QLatin1Char('/')); if (pos == -1) return d->path; @@ -676,7 +671,7 @@ QString QDir::dirName() const */ QString QDir::filePath(const QString &fileName) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (isAbsolutePath(fileName)) return QString(fileName); @@ -699,7 +694,7 @@ QString QDir::filePath(const QString &fileName) const */ QString QDir::absoluteFilePath(const QString &fileName) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (isAbsolutePath(fileName)) return fileName; if (!d->fileEngine) @@ -924,7 +919,7 @@ bool QDir::cdUp() */ QStringList QDir::nameFilters() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); return d->nameFilters; } @@ -945,7 +940,7 @@ QStringList QDir::nameFilters() const */ void QDir::setNameFilters(const QStringList &nameFilters) { - Q_D(QDir); + QDirPrivate* d = d_ptr.data(); d->initFileEngine(); d->clearFileLists(); @@ -1052,7 +1047,7 @@ QStringList QDir::searchPaths(const QString &prefix) */ QDir::Filters QDir::filter() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); return d->filters; } @@ -1134,7 +1129,7 @@ QDir::Filters QDir::filter() const */ void QDir::setFilter(Filters filters) { - Q_D(QDir); + QDirPrivate* d = d_ptr.data(); d->initFileEngine(); d->clearFileLists(); @@ -1148,7 +1143,7 @@ void QDir::setFilter(Filters filters) */ QDir::SortFlags QDir::sorting() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); return d->sort; } @@ -1192,7 +1187,7 @@ QDir::SortFlags QDir::sorting() const */ void QDir::setSorting(SortFlags sort) { - Q_D(QDir); + QDirPrivate* d = d_ptr.data(); d->initFileEngine(); d->clearFileLists(); @@ -1208,7 +1203,7 @@ void QDir::setSorting(SortFlags sort) */ uint QDir::count() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); d->initFileLists(); return d->files.count(); } @@ -1222,7 +1217,7 @@ uint QDir::count() const */ QString QDir::operator[](int pos) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); d->initFileLists(); return d->files[pos]; } @@ -1248,7 +1243,7 @@ QString QDir::operator[](int pos) const */ QStringList QDir::entryList(Filters filters, SortFlags sort) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); return entryList(d->nameFilters, filters, sort); } @@ -1271,7 +1266,7 @@ QStringList QDir::entryList(Filters filters, SortFlags sort) const */ QFileInfoList QDir::entryInfoList(Filters filters, SortFlags sort) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); return entryInfoList(d->nameFilters, filters, sort); } @@ -1294,7 +1289,7 @@ QFileInfoList QDir::entryInfoList(Filters filters, SortFlags sort) const QStringList QDir::entryList(const QStringList &nameFilters, Filters filters, SortFlags sort) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (filters == NoFilter) filters = d->filters; @@ -1340,7 +1335,7 @@ QStringList QDir::entryList(const QStringList &nameFilters, Filters filters, QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filters, SortFlags sort) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (filters == NoFilter) filters = d->filters; @@ -1376,7 +1371,7 @@ QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filter */ bool QDir::mkdir(const QString &dirName) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (dirName.isEmpty()) { qWarning("QDir::mkdir: Empty or null file name(s)"); @@ -1400,7 +1395,7 @@ bool QDir::mkdir(const QString &dirName) const */ bool QDir::rmdir(const QString &dirName) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (dirName.isEmpty()) { qWarning("QDir::rmdir: Empty or null file name(s)"); @@ -1425,7 +1420,7 @@ bool QDir::rmdir(const QString &dirName) const */ bool QDir::mkpath(const QString &dirPath) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (dirPath.isEmpty()) { qWarning("QDir::mkpath: Empty or null file name(s)"); @@ -1451,7 +1446,7 @@ bool QDir::mkpath(const QString &dirPath) const */ bool QDir::rmpath(const QString &dirPath) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (dirPath.isEmpty()) { qWarning("QDir::rmpath: Empty or null file name(s)"); @@ -1475,7 +1470,7 @@ bool QDir::rmpath(const QString &dirPath) const */ bool QDir::isReadable() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (!d->fileEngine) return false; @@ -1500,7 +1495,7 @@ bool QDir::isReadable() const */ bool QDir::exists() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (!d->fileEngine) return false; @@ -1527,7 +1522,7 @@ bool QDir::exists() const */ bool QDir::isRoot() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (!d->fileEngine) return true; @@ -1561,7 +1556,7 @@ bool QDir::isRoot() const */ bool QDir::isRelative() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (!d->fileEngine) return false; @@ -1603,8 +1598,8 @@ bool QDir::makeAbsolute() // ### What do the return values signify? */ bool QDir::operator==(const QDir &dir) const { - const QDirPrivate *d = d_func(); - const QDirPrivate *other = dir.d_func(); + const QDirPrivate *d = d_ptr.constData(); + const QDirPrivate *other = dir.d_ptr.constData(); if (d == other) return true; @@ -2133,7 +2128,7 @@ bool QDir::isRelativePath(const QString &path) */ void QDir::refresh() const { - QDirPrivate *d = const_cast(this)->d_func(); + QDirPrivate *d = const_cast(this)->d_ptr.data(); d->initFileEngine(); d->clearFileLists(); } @@ -2211,7 +2206,7 @@ QStringList QDir::nameFiltersFromString(const QString &nameFilter) */ bool QDir::matchAllDirs() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); return d->matchAllDirs; } @@ -2223,7 +2218,7 @@ bool QDir::matchAllDirs() const */ void QDir::setMatchAllDirs(bool on) { - Q_D(QDir); + QDirPrivate* d = d_ptr.data(); d->initFileEngine(); d->clearFileLists(); @@ -2235,7 +2230,7 @@ void QDir::setMatchAllDirs(bool on) */ QString QDir::nameFilter() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); return nameFilters().join(QString(d->filterSepChar)); } @@ -2261,7 +2256,7 @@ QString QDir::nameFilter() const */ void QDir::setNameFilter(const QString &nameFilter) { - Q_D(QDir); + QDirPrivate* d = d_ptr.data(); d->initFileEngine(); d->filterSepChar = QDirPrivate::getFilterSepChar(nameFilter); diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h index abfe387..7e5fbac 100644 --- a/src/corelib/io/qdir.h +++ b/src/corelib/io/qdir.h @@ -59,17 +59,6 @@ class Q_CORE_EXPORT QDir { protected: QSharedDataPointer d_ptr; -private: - inline QDirPrivate* d_func() - { - detach(); - return const_cast(d_ptr.constData()); - } - - inline const QDirPrivate* d_func() const - { - return d_ptr.constData(); - } public: enum Filter { Dirs = 0x001, @@ -140,8 +129,6 @@ public: QDir &operator=(const QDir &); QDir &operator=(const QString &path); - void detach(); - void setPath(const QString &path); QString path() const; QString absolutePath() const; -- cgit v0.12 From 7a9f84eb0563355aab76c0b56db44382c516cf35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 30 Aug 2010 19:02:26 +0200 Subject: Another bug-o introduced in fixing QDirPrivate refactoring Must clear file lists when changing the name filters. --- src/corelib/io/qdir.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index b355f62..70b00a0 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -2258,6 +2258,7 @@ void QDir::setNameFilter(const QString &nameFilter) { QDirPrivate* d = d_ptr.data(); d->initFileEngine(); + d->clearFileLists(); d->filterSepChar = QDirPrivate::getFilterSepChar(nameFilter); d->nameFilters = QDirPrivate::splitFilters(nameFilter, d->filterSepChar); -- cgit v0.12 From c14c0a61bbd8466b00f5600707bc0aedbbf260af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 31 Aug 2010 09:56:27 +0200 Subject: QDir and QFileInfo shouldn't lose properties when detaching For QFileInfo, the caching state was being lost on the different setFile overloads. QDir::cd and ::makeAbsolute were losing filters and sorting flags. QDir issues were introduced with these patches: "Simplify QDir::cd" "QDir::makeAbsolute could self-destruct on failure" Reviewed-by: Prasanth Ullattil --- src/corelib/io/qdir.cpp | 41 ++++++++------ src/corelib/io/qfileinfo.cpp | 8 +-- tests/auto/qdir/tst_qdir.cpp | 99 ++++++++++++++++++++++++++++++++++ tests/auto/qfileinfo/tst_qfileinfo.cpp | 48 +++++++++++++++++ 4 files changed, 176 insertions(+), 20 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 70b00a0..7d5c070 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -136,6 +136,19 @@ public: delete fileEngine; } + bool exists() const + { + if (!fileEngine) + return false; + const QAbstractFileEngine::FileFlags info = + fileEngine->fileFlags(QAbstractFileEngine::DirectoryType + | QAbstractFileEngine::ExistsFlag + | QAbstractFileEngine::Refresh); + if (!(info & QAbstractFileEngine::DirectoryType)) + return false; + return info & QAbstractFileEngine::ExistsFlag; + } + void initFileEngine(); void initFileLists() const; @@ -891,11 +904,13 @@ bool QDir::cd(const QString &dirName) } } - QDir dir(newPath); - if (!dir.exists()) + QScopedPointer dir(new QDirPrivate(*d_ptr.constData())); + dir->setPath(newPath); + + if (!dir->exists()) return false; - *this = dir; + d_ptr = dir.take(); return true; } @@ -1495,17 +1510,7 @@ bool QDir::isReadable() const */ bool QDir::exists() const { - const QDirPrivate* d = d_ptr.constData(); - - if (!d->fileEngine) - return false; - const QAbstractFileEngine::FileFlags info = - d->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType - | QAbstractFileEngine::ExistsFlag - | QAbstractFileEngine::Refresh); - if (!(info & QAbstractFileEngine::DirectoryType)) - return false; - return info & QAbstractFileEngine::ExistsFlag; + return d_ptr->exists(); } /*! @@ -1579,11 +1584,13 @@ bool QDir::makeAbsolute() // ### What do the return values signify? if (QDir::isRelativePath(absolutePath)) return false; - QDir dir(absolutePath); - if (!(dir.d_ptr.constData()->fileEngine->fileFlags(QAbstractFileEngine::TypesMask) & QAbstractFileEngine::DirectoryType)) + QScopedPointer dir(new QDirPrivate(*d_ptr.constData())); + dir->setPath(absolutePath); + + if (!(dir->fileEngine->fileFlags(QAbstractFileEngine::TypesMask) & QAbstractFileEngine::DirectoryType)) return false; - *this = dir; + d_ptr = dir.take(); return true; } diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 248b83d..7eca212 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -395,7 +395,9 @@ QFileInfo &QFileInfo::operator=(const QFileInfo &fileinfo) */ void QFileInfo::setFile(const QString &file) { + bool caching = d_ptr.constData()->cache_enabled; *this = QFileInfo(file); + d_ptr->cache_enabled = caching; } /*! @@ -411,7 +413,7 @@ void QFileInfo::setFile(const QString &file) */ void QFileInfo::setFile(const QFile &file) { - *this = QFileInfo(file.fileName()); + setFile(file.fileName()); } /*! @@ -427,7 +429,7 @@ void QFileInfo::setFile(const QFile &file) */ void QFileInfo::setFile(const QDir &dir, const QString &file) { - *this = QFileInfo(dir.filePath(file)); + setFile(dir.filePath(file)); } /*! @@ -579,7 +581,7 @@ bool QFileInfo::makeAbsolute() QString absFileName = d_ptr.constData()->getFileName(QAbstractFileEngine::AbsoluteName); // QSharedDataPointer::operator->() will detach. - *this = QFileInfo(absFileName); + setFile(absFileName); return true; } diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 661a4c7..9678868 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -173,6 +173,8 @@ private slots: void updateFileLists(); + void detachingOperations(); + #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) void isRoot_data(); void isRoot(); @@ -1561,6 +1563,103 @@ void tst_QDir::updateFileLists() QCOMPARE(dir.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "file1.txt"); } +void tst_QDir::detachingOperations() +{ + QString const defaultPath("."); + QStringList const defaultNameFilters = QStringList("*"); + QDir::SortFlags const defaultSorting = QDir::Name | QDir::IgnoreCase; + QDir::Filters const defaultFilter = QDir::AllEntries; + + QString const path1(".."); + QString const path2("./foo"); + QStringList const nameFilters = QStringList(QString("*.txt")); + QDir::SortFlags const sorting = QDir::Name | QDir::DirsLast | QDir::Reversed; + QDir::Filters const filter = QDir::Writable; + + QDir dir1; + + QCOMPARE(dir1.path(), defaultPath); + QCOMPARE(dir1.filter(), defaultFilter); + QCOMPARE(dir1.nameFilters(), defaultNameFilters); + QCOMPARE(dir1.sorting(), defaultSorting); + + dir1.setPath(path1); + QCOMPARE(dir1.path(), path1); + QCOMPARE(dir1.filter(), defaultFilter); + QCOMPARE(dir1.nameFilters(), defaultNameFilters); + QCOMPARE(dir1.sorting(), defaultSorting); + + dir1.setFilter(filter); + QCOMPARE(dir1.path(), path1); + QCOMPARE(dir1.filter(), filter); + QCOMPARE(dir1.nameFilters(), defaultNameFilters); + QCOMPARE(dir1.sorting(), defaultSorting); + + dir1.setNameFilters(nameFilters); + QCOMPARE(dir1.path(), path1); + QCOMPARE(dir1.filter(), filter); + QCOMPARE(dir1.nameFilters(), nameFilters); + QCOMPARE(dir1.sorting(), defaultSorting); + + dir1.setSorting(sorting); + QCOMPARE(dir1.path(), path1); + QCOMPARE(dir1.filter(), filter); + QCOMPARE(dir1.nameFilters(), nameFilters); + QCOMPARE(dir1.sorting(), sorting); + + dir1.setPath(path2); + QCOMPARE(dir1.path(), path2); + QCOMPARE(dir1.filter(), filter); + QCOMPARE(dir1.nameFilters(), nameFilters); + QCOMPARE(dir1.sorting(), sorting); + + { + QDir dir2(dir1); + QCOMPARE(dir2.path(), path2); + QCOMPARE(dir2.filter(), filter); + QCOMPARE(dir2.nameFilters(), nameFilters); + QCOMPARE(dir2.sorting(), sorting); + } + + { + QDir dir2; + QCOMPARE(dir2.path(), defaultPath); + QCOMPARE(dir2.filter(), defaultFilter); + QCOMPARE(dir2.nameFilters(), defaultNameFilters); + QCOMPARE(dir2.sorting(), defaultSorting); + + dir2 = dir1; + QCOMPARE(dir2.path(), path2); + QCOMPARE(dir2.filter(), filter); + QCOMPARE(dir2.nameFilters(), nameFilters); + QCOMPARE(dir2.sorting(), sorting); + + dir2 = path1; + QCOMPARE(dir2.path(), path1); + QCOMPARE(dir2.filter(), filter); + QCOMPARE(dir2.nameFilters(), nameFilters); + QCOMPARE(dir2.sorting(), sorting); + } + + dir1.refresh(); + QCOMPARE(dir1.path(), path2); + QCOMPARE(dir1.filter(), filter); + QCOMPARE(dir1.nameFilters(), nameFilters); + QCOMPARE(dir1.sorting(), sorting); + + QString const currentPath = QDir::currentPath(); + QVERIFY(dir1.cd(currentPath)); + QCOMPARE(dir1.path(), currentPath); + QCOMPARE(dir1.filter(), filter); + QCOMPARE(dir1.nameFilters(), nameFilters); + QCOMPARE(dir1.sorting(), sorting); + + QVERIFY(dir1.cdUp()); + QCOMPARE(dir1.filter(), filter); + QCOMPARE(dir1.nameFilters(), nameFilters); + QCOMPARE(dir1.sorting(), sorting); +} + #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) void tst_QDir::isRoot_data() { diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 32aa671..7659a75 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -181,6 +181,8 @@ private slots: void equalOperator() const; void equalOperatorWithDifferentSlashes() const; void notEqualOperator() const; + + void detachingOperations(); }; tst_QFileInfo::tst_QFileInfo() @@ -1545,5 +1547,51 @@ void tst_QFileInfo::notEqualOperator() const QVERIFY(QFileInfo() != QFileInfo()); } +void tst_QFileInfo::detachingOperations() +{ + QFileInfo info1; + QVERIFY(info1.caching()); + info1.setCaching(false); + + { + QFileInfo info2 = info1; + + QVERIFY(!info1.caching()); + QVERIFY(!info2.caching()); + + info2.setCaching(true); + QVERIFY(info2.caching()); + + info1.setFile("foo"); + QVERIFY(!info1.caching()); + } + + { + QFile file("foo"); + info1.setFile(file); + QVERIFY(!info1.caching()); + } + + info1.setFile(QDir(), "foo"); + QVERIFY(!info1.caching()); + + { + QFileInfo info3; + QVERIFY(info3.caching()); + + info3 = info1; + QVERIFY(!info3.caching()); + } + + info1.refresh(); + QVERIFY(!info1.caching()); + + QVERIFY(info1.makeAbsolute()); + QVERIFY(!info1.caching()); + + info1.detach(); + QVERIFY(!info1.caching()); +} + QTEST_MAIN(tst_QFileInfo) #include "tst_qfileinfo.moc" -- cgit v0.12 From 5e1196c2c98b5331c0ccdbfa2aea26b35fb4a3c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 31 Aug 2010 13:17:15 +0200 Subject: QDir: Removed checks for existance of fileEngine Directly or indirectly, all instances of QDir call QDirPrivate::setPath, which allocates a file engine and dereferences it. Any failures there should already lead to a crash or a bad_alloc exception being thrown in case of failure. Given that, QDir may be (and was) broken when compiling Qt with QT_NO_FSFILEENGINE, if no custom file engine and handler are provided. This being the case, it's pointless to check fileEngine for null all over the place. This simplifies the code and should allow for easier transition to file-engine-less implementation. Reviewed-by: Thomas Zander --- src/corelib/io/qdir.cpp | 57 +++++++------------------------------------------ 1 file changed, 8 insertions(+), 49 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 7d5c070..8c99226 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -97,7 +97,6 @@ public: , filterSepChar(0) , matchAllDirs(false) #endif - , fileEngine(0) , fileListsInitialized(false) { setPath(path.isEmpty() ? QString::fromLatin1(".") : path); @@ -126,20 +125,12 @@ public: , filterSepChar(copy.filterSepChar) , matchAllDirs(copy.matchAllDirs) #endif - , fileEngine(0) , fileListsInitialized(false) { } - ~QDirPrivate() - { - delete fileEngine; - } - bool exists() const { - if (!fileEngine) - return false; const QAbstractFileEngine::FileFlags info = fileEngine->fileFlags(QAbstractFileEngine::DirectoryType | QAbstractFileEngine::ExistsFlag @@ -183,8 +174,8 @@ public: p.truncate(p.length() - 1); } - delete fileEngine; - fileEngine = QAbstractFileEngine::create(p); + path = p; + initFileEngine(); // set the path to be the qt friendly version so then we can operate on it using just / path = fileEngine->fileName(QAbstractFileEngine::DefaultName); @@ -207,7 +198,7 @@ public: bool matchAllDirs; #endif - QAbstractFileEngine *fileEngine; + QScopedPointer fileEngine; mutable bool fileListsInitialized; mutable QStringList files; @@ -339,11 +330,9 @@ inline void QDirPrivate::initFileLists() const } } -void QDirPrivate::initFileEngine() +inline void QDirPrivate::initFileEngine() { - QAbstractFileEngine *newFileEngine = QAbstractFileEngine::create(path); - delete fileEngine; - fileEngine = newFileEngine; + fileEngine.reset(QAbstractFileEngine::create(path)); } /*! @@ -646,11 +635,7 @@ QString QDir::absolutePath() const */ QString QDir::canonicalPath() const { - const QDirPrivate* d = d_ptr.constData(); - - if (!d->fileEngine) - return QLatin1String(""); - return cleanPath(d->fileEngine->fileName(QAbstractFileEngine::CanonicalName)); + return cleanPath(d_ptr->fileEngine->fileName(QAbstractFileEngine::CanonicalName)); } /*! @@ -710,8 +695,6 @@ QString QDir::absoluteFilePath(const QString &fileName) const const QDirPrivate* d = d_ptr.constData(); if (isAbsolutePath(fileName)) return fileName; - if (!d->fileEngine) - return fileName; QString ret; #ifndef QT_NO_FSFILEENGINE @@ -1392,8 +1375,6 @@ bool QDir::mkdir(const QString &dirName) const qWarning("QDir::mkdir: Empty or null file name(s)"); return false; } - if (!d->fileEngine) - return false; QString fn = filePath(dirName); return d->fileEngine->mkdir(fn, false); @@ -1416,8 +1397,6 @@ bool QDir::rmdir(const QString &dirName) const qWarning("QDir::rmdir: Empty or null file name(s)"); return false; } - if (!d->fileEngine) - return false; QString fn = filePath(dirName); return d->fileEngine->rmdir(fn, false); @@ -1441,8 +1420,6 @@ bool QDir::mkpath(const QString &dirPath) const qWarning("QDir::mkpath: Empty or null file name(s)"); return false; } - if (!d->fileEngine) - return false; QString fn = filePath(dirPath); return d->fileEngine->mkdir(fn, true); @@ -1467,8 +1444,6 @@ bool QDir::rmpath(const QString &dirPath) const qWarning("QDir::rmpath: Empty or null file name(s)"); return false; } - if (!d->fileEngine) - return false; QString fn = filePath(dirPath); return d->fileEngine->rmdir(fn, true); @@ -1487,8 +1462,6 @@ bool QDir::isReadable() const { const QDirPrivate* d = d_ptr.constData(); - if (!d->fileEngine) - return false; const QAbstractFileEngine::FileFlags info = d->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType | QAbstractFileEngine::PermsMask); @@ -1527,11 +1500,7 @@ bool QDir::exists() const */ bool QDir::isRoot() const { - const QDirPrivate* d = d_ptr.constData(); - - if (!d->fileEngine) - return true; - return d->fileEngine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::RootFlag; + return d_ptr->fileEngine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::RootFlag; } /*! @@ -1561,11 +1530,7 @@ bool QDir::isRoot() const */ bool QDir::isRelative() const { - const QDirPrivate* d = d_ptr.constData(); - - if (!d->fileEngine) - return false; - return d->fileEngine->isRelativePath(); + return d_ptr->fileEngine->isRelativePath(); } @@ -1578,8 +1543,6 @@ bool QDir::isRelative() const */ bool QDir::makeAbsolute() // ### What do the return values signify? { - if (!d_ptr.constData()->fileEngine) - return false; QString absolutePath = d_ptr.constData()->fileEngine->fileName(QAbstractFileEngine::AbsoluteName); if (QDir::isRelativePath(absolutePath)) return false; @@ -1610,7 +1573,6 @@ bool QDir::operator==(const QDir &dir) const if (d == other) return true; - Q_ASSERT(d->fileEngine && other->fileEngine); if (d->fileEngine->caseSensitive() != other->fileEngine->caseSensitive()) return false; if (d->filters == other->filters @@ -1695,9 +1657,6 @@ bool QDir::rename(const QString &oldName, const QString &newName) return false; } - if (!d_ptr.constData()->fileEngine) - return false; - QFile file(filePath(oldName)); if (!file.exists()) return false; -- cgit v0.12 From d3b152ba1e3cd38dd675c801474105d518bacb44 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 1 Sep 2010 13:33:12 +0200 Subject: Finish canonicalized for all platforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QFSFileEnginePrivate::canonicalized is now removed and spread out over the qfsfileengine_unix.cpp and qfsfileengine.cpp Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemengine_unix.cpp | 27 +++++++++++++++-- src/corelib/io/qfilesystemengine_win.cpp | 2 +- src/corelib/io/qfsfileengine.cpp | 50 ------------------------------- src/corelib/io/qfsfileengine_p.h | 1 - src/corelib/io/qfsfileengine_unix.cpp | 17 +++-------- src/corelib/io/qfsfileengine_win.cpp | 15 ++++------ 6 files changed, 35 insertions(+), 77 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 283c787..62fb1b3 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -45,6 +45,10 @@ #include // for realpath() #include +#if defined(Q_OS_MAC) +# include +#endif + QT_BEGIN_NAMESPACE bool QFileSystemEngine::isCaseSensitive() @@ -71,8 +75,27 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) #ifdef __UCLIBC__ return QFileSystemEntry::slowCanonicalName(entry); #else - - char *ret = realpath(entry.nativeFilePath().constData(), (char*)0); + char *ret = 0; +# if defined(Q_OS_MAC) + // Mac OS X 10.5.x doesn't support the realpath(X,0) extension we use here. + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) { + ret = realpath(entry.nativeFilePath().constData(), (char*)0); + } else { + // on 10.5 we can use FSRef to resolve the file path. + QString path = QDir::cleanPath(entry.filePath()); + FSRef fsref; + if (FSPathMakeRef((const UInt8 *)path.toUtf8().data(), &fsref, 0) == noErr) { + CFURLRef urlref = CFURLCreateFromFSRef(NULL, &fsref); + CFStringRef canonicalPath = CFURLCopyFileSystemPath(urlref, kCFURLPOSIXPathStyle); + QString ret = QCFString::toQString(canonicalPath); + CFRelease(canonicalPath); + CFRelease(urlref); + return QFileSystemEntry(ret); + } + } +# else + ret = realpath(entry.nativeFilePath().constData(), (char*)0); +# endif if (ret) { QString canonicalPath = QDir::cleanPath(QString::fromLocal8Bit(ret)); free(ret); diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 40df120..aa6d2b1 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -57,7 +57,7 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link) //static QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) { - return entry; // TODO implement; + return QFileSystemEntry(slowCanonicalized(entry.filePath())); } //static diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 665d23e..5d7b354 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -134,56 +134,6 @@ void QFSFileEnginePrivate::init() } /*! - \internal - - Returns the canonicalized form of \a path (i.e., with all symlinks - resolved, and all redundant path elements removed. -*/ -QString QFSFileEnginePrivate::canonicalized(const QString &path) -{ - if (path.isEmpty()) - return path; - - // FIXME let's see if this stuff works, then we might be able to remove some of the other code. -#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) - if (path.size() == 1 && path.at(0) == QLatin1Char('/')) - return path; -#endif -#if defined(Q_OS_LINUX) || defined(Q_OS_SYMBIAN) || defined(Q_OS_MAC) - // ... but Linux with uClibc does not have it -#if !defined(__UCLIBC__) - char *ret = 0; -#if defined(Q_OS_MAC) - // Mac OS X 10.5.x doesn't support the realpath(X,0) extension we use here. - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) { - ret = realpath(path.toLocal8Bit().constData(), (char*)0); - } else { - // on 10.5 we can use FSRef to resolve the file path. - FSRef fsref; - if (FSPathMakeRef((const UInt8 *)QDir::cleanPath(path).toUtf8().data(), &fsref, 0) == noErr) { - CFURLRef urlref = CFURLCreateFromFSRef(NULL, &fsref); - CFStringRef canonicalPath = CFURLCopyFileSystemPath(urlref, kCFURLPOSIXPathStyle); - QString ret = QCFString::toQString(canonicalPath); - CFRelease(canonicalPath); - CFRelease(urlref); - return ret; - } - } -#else - ret = realpath(path.toLocal8Bit().constData(), (char*)0); -#endif - if (ret) { - QString canonicalPath = QDir::cleanPath(QString::fromLocal8Bit(ret)); - free(ret); - return canonicalPath; - } -#endif -#endif - - return QFileSystemEngine::slowCanonicalized(path); -} - -/*! Constructs a QFSFileEngine for the file name \a file. */ QFSFileEngine::QFSFileEngine(const QString &file) diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 74cbca3..9eaf6fd 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -75,7 +75,6 @@ public: #ifdef Q_WS_WIN static QString longFileName(const QString &path); #endif - static QString canonicalized(const QString &path); QFileSystemEntry fileEntry; QIODevice::OpenMode openMode; diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 29491f5..0b73a7b 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -963,19 +963,10 @@ QString QFSFileEngine::fileName(FileName file) const } return ret; } else if(file == CanonicalName || file == CanonicalPathName) { - if (!(fileFlags(ExistsFlag) & ExistsFlag)) - return QString(); - - QString ret = QFSFileEnginePrivate::canonicalized(fileName(AbsoluteName)); - if (file == CanonicalPathName && !ret.isEmpty()) { - int slash = ret.lastIndexOf(slashChar); - if (slash == -1) - ret = QDir::fromNativeSeparators(QDir::currentPath()); - else if (slash == 0) - ret = QLatin1String("/"); - ret = ret.left(slash); - } - return ret; + QFileSystemEntry entry(QFileSystemEngine::canonicalName(d->fileEntry)); + if (file == CanonicalPathName) + return entry.path(); + return entry.filePath(); } else if(file == LinkName) { if (d->isSymlink()) { char s[PATH_MAX+1]; diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 9f33af5..bc88776 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -43,6 +43,7 @@ #include "qplatformdefs.h" #include "qabstractfileengine.h" #include "private/qfsfileengine_p.h" +#include "qfilesystemengine_p.h" #include #include "qfile.h" @@ -1620,17 +1621,11 @@ QString QFSFileEngine::fileName(FileName file) const } else if (file == CanonicalName || file == CanonicalPathName) { if (!(fileFlags(ExistsFlag) & ExistsFlag)) return QString(); + QFileSystemEngine entry(QFileSystemEngine::slowCanonicalized(fileName(AbsoluteName))); - QString ret = QFSFileEnginePrivate::canonicalized(fileName(AbsoluteName)); - if (!ret.isEmpty() && file == CanonicalPathName) { - int slash = ret.lastIndexOf(QLatin1Char('/')); - if (slash == -1) - ret = QDir::currentPath(); - else if (slash == 0) - ret = QString(QLatin1Char('/')); - ret = ret.left(slash); - } - return ret; + if (file == CanonicalPathName) + return entry.path(); + return entry.filePath(); } else if (file == LinkName) { QString ret; if (d->fileEntry.filePath().endsWith(QLatin1String(".lnk"))) -- cgit v0.12 From 88ae6dc40e6f725a3dc15056a0b9e8f00d727c09 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 1 Sep 2010 12:53:04 +0200 Subject: Breaking changes to QFileSystemEntry's constructors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we are using a QString for the native file path on windows, the constructors we had on other platforms didn't make sense: we can't have two constructors taking a single QString parameter, and it would be error prone to have the two argument constructor (taking two QString parameters, on Windows) change the meaning of the first argument. This patch introduces a typedef for the NativePath type being used; the constructor taking the native path now requires a dummy parameter that makes the intent expliciti; and the order of the arguments on the constructor taking both native and Qt paths had the order switched. Done-with: João Abecasis --- src/corelib/io/qfilesystemengine_unix.cpp | 4 +-- src/corelib/io/qfilesystementry.cpp | 12 +++------ src/corelib/io/qfilesystementry_p.h | 30 ++++++++++------------ src/corelib/io/qtemporaryfile.cpp | 2 +- .../auto/qfilesystementry/tst_qfilesystementry.cpp | 2 +- 5 files changed, 21 insertions(+), 29 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 62fb1b3..b7fe8e0 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -126,14 +126,14 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) } if (result.length() == 1 && result[0] == '/') - return QFileSystemEntry(result); + return QFileSystemEntry(result, QFileSystemEntry::FromNativePath()); const bool isDir = result.endsWith('/'); /* as long as QDir::cleanPath() operates on a QString we have to convert to a string here. * ideally we never convert to a string since that loses information. Please fix after * we get a QByteArray version of QDir::cleanPath() */ - QFileSystemEntry resultingEntry(result); + QFileSystemEntry resultingEntry(result, QFileSystemEntry::FromNativePath()); QString stringVersion = QDir::cleanPath(resultingEntry.filePath()); if (isDir) stringVersion.append(QLatin1Char('/')); diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index a32e22f..c3ada48 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -89,8 +89,7 @@ QFileSystemEntry::QFileSystemEntry(const QString &filePath) { } -#ifndef Q_OS_WIN -QFileSystemEntry::QFileSystemEntry(const QByteArray &nativeFilePath) +QFileSystemEntry::QFileSystemEntry(const NativePath &nativeFilePath, FromNativePath /* dummy */) : m_nativeFilePath(nativeFilePath), m_lastSeparator(-2), m_firstDotInFileName(-2), @@ -98,7 +97,7 @@ QFileSystemEntry::QFileSystemEntry(const QByteArray &nativeFilePath) { } -QFileSystemEntry::QFileSystemEntry(const QByteArray &nativeFilePath, const QString &filePath) +QFileSystemEntry::QFileSystemEntry(const QString &filePath, const NativePath &nativeFilePath) : m_filePath(filePath), m_nativeFilePath(nativeFilePath), m_lastSeparator(-2), @@ -106,7 +105,6 @@ QFileSystemEntry::QFileSystemEntry(const QByteArray &nativeFilePath, const QStri m_lastDotInFileName(0) { } -#endif QString QFileSystemEntry::filePath() const { @@ -114,11 +112,7 @@ QString QFileSystemEntry::filePath() const return m_filePath; } -#ifndef Q_OS_WIN -QByteArray QFileSystemEntry::nativeFilePath() const -#else -QString QFileSystemEntry::nativeFilePath() const -#endif +QFileSystemEntry::NativePath QFileSystemEntry::nativeFilePath() const { resolveNativeFilePath(); return m_nativeFilePath; diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index 3e49f2c..3786bb3 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -61,21 +61,24 @@ QT_BEGIN_NAMESPACE class QFileSystemEntry { public: - QFileSystemEntry(); - explicit QFileSystemEntry(const QString &filePath); + #ifndef Q_OS_WIN - explicit QFileSystemEntry(const QByteArray &nativeFilePath); - QFileSystemEntry(const QByteArray &nativeFilePath, const QString &filePath); + typedef QByteArray NativePath; +#else + typedef QString NativePath; #endif + struct FromNativePath{}; + + QFileSystemEntry(); + explicit QFileSystemEntry(const QString &filePath); + + QFileSystemEntry(const NativePath &nativeFilePath, FromNativePath dummy); + QFileSystemEntry(const QString &filePath, const NativePath &nativeFilePath); QString filePath() const; QString fileName() const; QString path() const; -#ifndef Q_OS_WIN - QByteArray nativeFilePath() const; -#else - QString nativeFilePath() const; -#endif + NativePath nativeFilePath() const; QString suffix() const; QString completeSuffix() const; bool isAbsolute() const; @@ -101,16 +104,11 @@ private: void resolveNativeFilePath() const; // resolves the separator void findLastSeparator() const; - /// resolves the dots and the separator + // resolves the dots and the separator void findFileNameSeparators() const; mutable QString m_filePath; // always has slashes as separator - -#ifdef Q_OS_WIN - mutable QString m_nativeFilePath; // native encoding and separators -#else - mutable QByteArray m_nativeFilePath; // native encoding and separators -#endif + mutable NativePath m_nativeFilePath; // native encoding and separators mutable qint16 m_lastSeparator; // index in m_filePath of last separator mutable qint16 m_firstDotInFileName; // index after m_filePath for first dot (.) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index a0d3176..479ea20 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -377,7 +377,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) d->closeFileHandle = true; // Restore the file names (open() resets them). - d->fileEntry = QFileSystemEntry(QByteArray(filename)); //changed now! + d->fileEntry = QFileSystemEntry(QByteArray(filename), QFileSystemEntry::FromNativePath()); //changed now! filePathIsTemplate = false; delete [] filename; return true; diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp index 58b7c6f..35389b4 100644 --- a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp +++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp @@ -140,7 +140,7 @@ void tst_QFileSystemEntry::getSetCheck() QCOMPARE(entry1.isAbsolute(), absolute); QCOMPARE(entry1.isRelative(), !absolute); - QFileSystemEntry entry2(nativeFilePath); + QFileSystemEntry entry2(nativeFilePath, QFileSystemEntry::FromNativePath()); QCOMPARE(entry2.suffix(), suffix); QCOMPARE(entry2.completeSuffix(), completeSuffix); QCOMPARE(entry2.isAbsolute(), absolute); -- cgit v0.12 From a543c044234f2854a53f9a659e9004f4aa536bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 30 Aug 2010 13:58:26 +0200 Subject: Expanding the stub QFileSystemMetaData Renamed FileFlags to MetaDataFlags. Added barebones structure and enum values to be shared across different implementations, with placeholders for platform-specific #includes and data members. Reviewed-by: Thomas Zander --- src/corelib/io/qfilesystemengine_mac.cpp | 2 +- src/corelib/io/qfilesystemengine_p.h | 2 +- src/corelib/io/qfilesystemengine_unix.cpp | 2 +- src/corelib/io/qfilesystemengine_win.cpp | 2 +- src/corelib/io/qfilesystemmetadata_p.h | 75 +++++++++++++++++++++++++++++-- 5 files changed, 75 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_mac.cpp b/src/corelib/io/qfilesystemengine_mac.cpp index 942415c..c915a2c 100644 --- a/src/corelib/io/qfilesystemengine_mac.cpp +++ b/src/corelib/io/qfilesystemengine_mac.cpp @@ -73,7 +73,7 @@ QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) } //static -bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::FileFlags what) +bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) { return false; // TODO implement; } diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 61ca085..982b782 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -71,7 +71,7 @@ public: static QString bundleName(const QFileSystemEntry &entry); static bool fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, - QFileSystemMetaData::FileFlags what); + QFileSystemMetaData::MetaDataFlags what); static bool createDirectory(const QFileSystemEntry &entry, bool createParents); static bool removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents); diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index b7fe8e0..d4759c8 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -147,7 +147,7 @@ QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) } //static -bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::FileFlags what) +bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) { return false; // TODO implement; } diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index aa6d2b1..dd6467a 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -73,7 +73,7 @@ QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) } //static -bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::FileFlags what) +bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) { return false; // TODO implement; } diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 9664177..40bad9e 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -55,14 +55,81 @@ #include +// Platform-specific includes +#if defined(Q_OS_WIN) +#else +#endif + QT_BEGIN_NAMESPACE -class QFileSystemMetaData +class QFileSystemEngine; + +struct QFileSystemMetaData { -public: - enum FileFlag { + QFileSystemMetaData() + : cachedFlags(0) + { + } + + enum MetaDataFlag { + // Permissions, overlaps with QFile::Permissions + OtherReadPermission = 0x00000004, OtherWritePermission = 0x00000002, OtherExecutePermission = 0x00000001, + GroupReadPermission = 0x00000040, GroupWritePermission = 0x00000020, GroupExecutePermission = 0x00000010, + UserReadPermission = 0x00000400, UserWritePermission = 0x00000200, UserExecutePermission = 0x00000100, + OwnerReadPermission = 0x00004000, OwnerWritePermission = 0x00002000, OwnerExecutePermission = 0x00001000, + + OtherPermissions = 0x0000000F, + GroupPermissions = 0x000000F0, + UserPermissions = 0x00000F00, + OwnerPermissions = 0x0000F000, + + Permissions = 0x0000FFFF, + + // Type + LinkType = 0x00010000, + FileType = 0x00020000, + DirectoryType = 0x00040000, + BundleType = 0x00080000, + + Type = 0x000F0000, + + // Attributes + HiddenAttribute = 0x00100000, + LocalDiskAttribute = 0x00200000, + ExistsAttribute = 0x00400000, + SizeAttribute = 0x00800000, // Note: overlaps with QAbstractFileEngine::RootFlag + + Attributes = 0x00F00000, + + // Times + CreationTime = 0x01000000, // Note: overlaps with QAbstractFileEngine::Refresh + ModificationTime = 0x02000000, + AccessTime = 0x04000000, + + Times = 0x07000000 }; - Q_DECLARE_FLAGS(FileFlags, FileFlag); + Q_DECLARE_FLAGS(MetaDataFlags, MetaDataFlag) + + bool hasFlags(MetaDataFlags flags) const + { + return ((cachedFlags & flags) == flags); + } + + void clear() + { + cachedFlags = 0; + } + +private: + friend class QFileSystemEngine; + + MetaDataFlags cachedFlags; + + // Platform-specific data goes here: +#if defined(Q_OS_WIN) +#else +#endif + }; QT_END_NAMESPACE -- cgit v0.12 From 9e31072524f496493c9b9b799c4f9520f77cf7c5 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 1 Sep 2010 14:59:43 +0200 Subject: Make QFileSystemEngine::slowCanonicalized private --- src/corelib/io/qfilesystemengine_p.h | 1 + src/corelib/io/qfsfileengine_win.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 982b782..f50701e 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -85,6 +85,7 @@ public: static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QFileSystemMetaData *data = 0); +private: static QString slowCanonicalized(const QString &path); }; diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index bc88776..7262129 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1621,7 +1621,7 @@ QString QFSFileEngine::fileName(FileName file) const } else if (file == CanonicalName || file == CanonicalPathName) { if (!(fileFlags(ExistsFlag) & ExistsFlag)) return QString(); - QFileSystemEngine entry(QFileSystemEngine::slowCanonicalized(fileName(AbsoluteName))); + QFileSystemEntry entry(QFileSystemEngine::canonicalName(d->fileEntry)); if (file == CanonicalPathName) return entry.path(); -- cgit v0.12 From 111886749d2cc6a94de382e454916446052dd355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 1 Sep 2010 14:59:59 +0200 Subject: QFileSystemIterator: added destructor and placeholder for data Reviewed-by: Prasanth Ullattil --- src/corelib/io/qfilesystemiterator_p.h | 7 +++++++ src/corelib/io/qfilesystemiterator_unix.cpp | 4 ++++ src/corelib/io/qfilesystemiterator_win.cpp | 4 ++++ 3 files changed, 15 insertions(+) diff --git a/src/corelib/io/qfilesystemiterator_p.h b/src/corelib/io/qfilesystemiterator_p.h index 436ff7e..21ad70a 100644 --- a/src/corelib/io/qfilesystemiterator_p.h +++ b/src/corelib/io/qfilesystemiterator_p.h @@ -66,10 +66,17 @@ class QFileSystemIterator { public: QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, const QStringList &nameFilters); + ~QFileSystemIterator(); bool advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData); private: + + // Platform-specific data +#if defined(Q_OS_WIN) +#else +#endif + Q_DISABLE_COPY(QFileSystemIterator) }; diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp index 3ee344b..1a6bf87 100644 --- a/src/corelib/io/qfilesystemiterator_unix.cpp +++ b/src/corelib/io/qfilesystemiterator_unix.cpp @@ -51,6 +51,10 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi Q_UNUSED(nameFilters) } +QFileSystemIterator::~QFileSystemIterator() +{ +} + bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData) { Q_UNUSED(fileEntry) diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 3ee344b..1a6bf87 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -51,6 +51,10 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi Q_UNUSED(nameFilters) } +QFileSystemIterator::~QFileSystemIterator() +{ +} + bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData) { Q_UNUSED(fileEntry) -- cgit v0.12 From f6e118d7ec781a97e8648145d4dfdb40516b13b4 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 1 Sep 2010 16:21:14 +0200 Subject: Fix tst_QFileSystemEntry auto tests on windows While resolving the native path, Windows implementation saves it as long absolute path. The tests are updated for this. This patch also splits the windows & unix code paths. Reviewed-by: Joao --- .../auto/qfilesystementry/tst_qfilesystementry.cpp | 112 +++++++++++++++------ 1 file changed, 83 insertions(+), 29 deletions(-) diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp index 35389b4..f4def8d 100644 --- a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp +++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp @@ -58,68 +58,121 @@ private slots: void getSetCheck(); }; +#if defined(WIN_STUFF) void tst_QFileSystemEntry::getSetCheck_data() { - QTest::addColumn("nativeFilePath"); + QTest::addColumn("nativeFilePath"); + QTest::addColumn("internalnativeFilePath"); QTest::addColumn("filepath"); QTest::addColumn("filename"); QTest::addColumn("suffix"); QTest::addColumn("completeSuffix"); QTest::addColumn("absolute"); + QString absPrefix = QLatin1String("\\\\?\\"); + QString relPrefix = absPrefix + + QDir::toNativeSeparators(QDir::currentPath()) + + QLatin1String("\\"); + QTest::newRow("simple") -#if defined(WIN_STUFF) - << QByteArray("A:\\home\\qt\\in\\a\\dir.tar.gz") - << "A:/home/qt/in/a/dir.tar.gz" + << QString("A:\\home\\qt\\in\\a\\dir.tar.gz") + << absPrefix + QString("A:\\home\\qt\\in\\a\\dir.tar.gz") + << "A:/home/qt/in/a/dir.tar.gz" + << "dir.tar.gz" << "gz" << "tar.gz" << true; + + QTest::newRow("relative") + << QString("in\\a\\dir.tar.gz") + << relPrefix + QString("in\\a\\dir.tar.gz") + << "in/a/dir.tar.gz" + << "dir.tar.gz" << "gz" << "tar.gz" << false; + + QTest::newRow("noSuffix") + << QString("myDir\\myfile") + << relPrefix + QString("myDir\\myfile") + << "myDir/myfile" << "myfile" << "" << "" << false; + + QTest::newRow("noLongSuffix") + << QString("myDir\\myfile.txt") + << relPrefix + QString("myDir\\myfile.txt") + << "myDir/myfile.txt" << "myfile.txt" << "txt" << "txt" << false; + + QTest::newRow("endingSlash") + << QString("myDir\\myfile.bla\\") + << relPrefix + QString("myDir\\myfile.bla\\") + << "myDir/myfile.bla/" << "" << "" << "" << false; + + QTest::newRow("absolutePath") + << QString("A:dir\\without\\leading\\backslash.bat") + << absPrefix + QString("A:\\dir\\without\\leading\\backslash.bat") + << "A:dir/without/leading/backslash.bat" << "backslash.bat" << "bat" << "bat" << true; +} + +void tst_QFileSystemEntry::getSetCheck() +{ + QFETCH(QString, nativeFilePath); + QFETCH(QString, internalnativeFilePath); + QFETCH(QString, filepath); + QFETCH(QString, filename); + QFETCH(QString, suffix); + QFETCH(QString, completeSuffix); + QFETCH(bool, absolute); + + QFileSystemEntry entry1(filepath); + QCOMPARE(entry1.filePath(), filepath); + QCOMPARE(entry1.nativeFilePath().toLower(), internalnativeFilePath.toLower()); + QCOMPARE(entry1.fileName(), filename); + QCOMPARE(entry1.suffix(), suffix); + QCOMPARE(entry1.completeSuffix(), completeSuffix); + QCOMPARE(entry1.isAbsolute(), absolute); + QCOMPARE(entry1.isRelative(), !absolute); + + QFileSystemEntry entry2(nativeFilePath, QFileSystemEntry::FromNativePath()); + QCOMPARE(entry2.suffix(), suffix); + QCOMPARE(entry2.completeSuffix(), completeSuffix); + QCOMPARE(entry2.isAbsolute(), absolute); + QCOMPARE(entry2.isRelative(), !absolute); + QCOMPARE(entry2.filePath(), filepath); + // This is entry was created using the native file path, + // so it should use that without any changes. + QCOMPARE(entry2.nativeFilePath(), nativeFilePath); + QCOMPARE(entry2.fileName(), filename); +} + #else + +void tst_QFileSystemEntry::getSetCheck_data() +{ + QTest::addColumn("nativeFilePath"); + QTest::addColumn("filepath"); + QTest::addColumn("filename"); + QTest::addColumn("suffix"); + QTest::addColumn("completeSuffix"); + QTest::addColumn("absolute"); + + QTest::newRow("simple") << QByteArray("/home/qt/in/a/dir.tar.gz") << "/home/qt/in/a/dir.tar.gz" -#endif << "dir.tar.gz" << "gz" << "tar.gz" << true; - QTest::newRow("relative") -#if defined(WIN_STUFF) - << QByteArray("in\\a\\dir.tar.gz") - << "in/a/dir.tar.gz" -#else << QByteArray("in/a/dir.tar.gz") << "in/a/dir.tar.gz" -#endif << "dir.tar.gz" << "gz" << "tar.gz" << false; QTest::newRow("noSuffix") -#if defined(WIN_STUFF) - << QByteArray("myDir\\myfile") -#else << QByteArray("myDir/myfile") -#endif << "myDir/myfile" << "myfile" << "" << "" << false; QTest::newRow("noLongSuffix") -#if defined(WIN_STUFF) - << QByteArray("myDir\\myfile.txt") -#else << QByteArray("myDir/myfile.txt") -#endif << "myDir/myfile.txt" << "myfile.txt" << "txt" << "txt" << false; QTest::newRow("endingSlash") -#if defined(WIN_STUFF) - << QByteArray("myDir\\myfile.bla\\") -#else << QByteArray("myDir/myfile.bla/") -#endif << "myDir/myfile.bla/" << "" << "" << "" << false; -#if defined(WIN_STUFF) - QTest::newRow("absolutePath") - << QByteArray("A:dir\\without\\leading\\backslash.bat") - << "A:dir/without/leading/backslash.bat" << "backslash.bat" << "bat" << "bat" << true; -#else QTest::newRow("relativePath") << QByteArray("A:dir/without/leading/backslash.bat") << "A:dir/without/leading/backslash.bat" << "backslash.bat" << "bat" << "bat" << false; -#endif } void tst_QFileSystemEntry::getSetCheck() @@ -149,6 +202,7 @@ void tst_QFileSystemEntry::getSetCheck() QCOMPARE(entry2.nativeFilePath(), nativeFilePath); QCOMPARE(entry2.fileName(), filename); } +#endif QTEST_MAIN(tst_QFileSystemEntry) #include -- cgit v0.12 From 34d8b4f0fa7f039504b62f2bbf84668f5345b643 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 1 Sep 2010 16:25:43 +0200 Subject: Updated comment in tst_QFileSystemEntry autotest --- tests/auto/qfilesystementry/tst_qfilesystementry.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp index f4def8d..5194c02 100644 --- a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp +++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp @@ -132,8 +132,8 @@ void tst_QFileSystemEntry::getSetCheck() QCOMPARE(entry2.isAbsolute(), absolute); QCOMPARE(entry2.isRelative(), !absolute); QCOMPARE(entry2.filePath(), filepath); - // This is entry was created using the native file path, - // so it should use that without any changes. + // Since this entry was created using the native path, + // the object shouldnot change nativeFilePath. QCOMPARE(entry2.nativeFilePath(), nativeFilePath); QCOMPARE(entry2.fileName(), filename); } -- cgit v0.12 From c7784c70b865792a5f09fc83e9a50cc327864a22 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Fri, 3 Sep 2010 09:35:45 +0200 Subject: Implement bundleName() in QFileSystemEngine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the code from the qfsfileengine_unix.cpp to the new place and make the old place just call the new one. Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemengine_unix.cpp | 12 +++++++++++- src/corelib/io/qfilesystemengine_win.cpp | 2 +- src/corelib/io/qfsfileengine_unix.cpp | 12 +----------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index d4759c8..4b1932d 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -143,7 +143,17 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) //static QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) { - return QString(); // TODO implement; +#if !defined(QWS) && defined(Q_OS_MAC) + QCFType url = CFURLCreateWithFileSystemPath(0, QCFString(entry.filePath()), + kCFURLPOSIXPathStyle, true); + if (QCFType dict = CFBundleCopyInfoDictionaryForURL(url)) { + if (CFTypeRef name = (CFTypeRef)CFDictionaryGetValue(dict, kCFBundleNameKey)) { + if (CFGetTypeID(name) == CFStringGetTypeID()) + return QCFString::toQString((CFStringRef)name); + } + } +#endif + return QString(); } //static diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index dd6467a..ef47fe5 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -69,7 +69,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) //static QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) { - return QString(); // TODO implement; + return QString(); } //static diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 0b73a7b..9ca195b 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -1002,17 +1002,7 @@ QString QFSFileEngine::fileName(FileName file) const { Q_D(const QFSFileEngine); if (file == BundleName) { -#if !defined(QWS) && defined(Q_OS_MAC) - QCFType url = CFURLCreateWithFileSystemPath(0, QCFString(d->fileEntry.filePath()), - kCFURLPOSIXPathStyle, true); - if (QCFType dict = CFBundleCopyInfoDictionaryForURL(url)) { - if (CFTypeRef name = (CFTypeRef)CFDictionaryGetValue(dict, kCFBundleNameKey)) { - if (CFGetTypeID(name) == CFStringGetTypeID()) - return QCFString::toQString((CFStringRef)name); - } - } -#endif - return QString(); + return QFileSystemEngine::bundleName(d->fileEntry); } else if (file == BaseName) { return d->fileEntry.fileName(); } else if (file == PathName) { -- cgit v0.12 From e6747da757b4daba1fc17db9902a9c39b426455f Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Fri, 3 Sep 2010 09:37:14 +0200 Subject: Move mkdir code to createDirectory for unix' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit migrate the QFSFileEngine::mkdir code to QFileSystemEngine::createDirectory and make the former call the latter. Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemengine_unix.cpp | 33 ++++++++++++++++++++++++++++++- src/corelib/io/qfsfileengine_unix.cpp | 32 +----------------------------- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 4b1932d..469abfe 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qfilesystemengine_p.h" +#include "qplatformdefs.h" #include "qfsfileengine.h" #include // for realpath() @@ -165,7 +166,37 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM //static bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents) { - return false; // TODO implement; + QString dirName = entry.filePath(); + if (createParents) { + dirName = QDir::cleanPath(dirName); +#if defined(Q_OS_SYMBIAN) + dirName = QDir::toNativeSeparators(dirName); +#endif + for (int oldslash = -1, slash=0; slash != -1; oldslash = slash) { + slash = dirName.indexOf(QDir::separator(), oldslash+1); + if (slash == -1) { + if (oldslash == dirName.length()) + break; + slash = dirName.length(); + } + if (slash) { + QByteArray chunk = QFile::encodeName(dirName.left(slash)); + QT_STATBUF st; + if (QT_STAT(chunk, &st) != -1) { + if ((st.st_mode & S_IFMT) != S_IFDIR) + return false; + } else if (QT_MKDIR(chunk, 0777) != 0) { + return false; + } + } + } + return true; + } +#if defined(Q_OS_DARWIN) // Mac X doesn't support trailing /'s + if (dirName.endsWith(QLatin1Char('/'))) + dirName.chop(1); +#endif + return (QT_MKDIR(QFile::encodeName(dirName), 0777) == 0); } //static diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 9ca195b..c20d6ae 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -492,37 +492,7 @@ qint64 QFSFileEnginePrivate::nativeSize() const bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const { - QString dirName = name; - if (createParentDirectories) { - dirName = QDir::cleanPath(dirName); -#if defined(Q_OS_SYMBIAN) - dirName = QDir::toNativeSeparators(dirName); -#endif - for(int oldslash = -1, slash=0; slash != -1; oldslash = slash) { - slash = dirName.indexOf(QDir::separator(), oldslash+1); - if (slash == -1) { - if (oldslash == dirName.length()) - break; - slash = dirName.length(); - } - if (slash) { - QByteArray chunk = QFile::encodeName(dirName.left(slash)); - QT_STATBUF st; - if (QT_STAT(chunk, &st) != -1) { - if ((st.st_mode & S_IFMT) != S_IFDIR) - return false; - } else if (QT_MKDIR(chunk, 0777) != 0) { - return false; - } - } - } - return true; - } -#if defined(Q_OS_DARWIN) // Mac X doesn't support trailing /'s - if (dirName.endsWith(QLatin1Char('/'))) - dirName.chop(1); -#endif - return (QT_MKDIR(QFile::encodeName(dirName), 0777) == 0); + return QFileSystemEngine::createDirectory(QFileSystemEntry(name), createParentDirectories); } bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const -- cgit v0.12 From 5b76ea63f5dba0a6b427d9d4dbcb7be6d7afeeec Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Fri, 3 Sep 2010 09:37:43 +0200 Subject: Move rmdir code to createDirectory for unix' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit migrate the QFSFileEngine::rmdir code to QFileSystemEngine::removeDirectory and make the former call the latter. Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemengine_unix.cpp | 22 +++++++++++++++++++++- src/corelib/io/qfsfileengine_unix.cpp | 23 +---------------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 469abfe..7c72782 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -202,7 +202,27 @@ bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea //static bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents) { - return false; // TODO implement; + if (removeEmptyParents) { + QString dirName = QDir::cleanPath(entry.filePath()); +#if defined(Q_OS_SYMBIAN) + dirName = QDir::toNativeSeparators(dirName); +#endif + for (int oldslash = 0, slash=dirName.length(); slash > 0; oldslash = slash) { + QByteArray chunk = QFile::encodeName(dirName.left(slash)); + QT_STATBUF st; + if (QT_STAT(chunk, &st) != -1) { + if ((st.st_mode & S_IFMT) != S_IFDIR) + return false; + if (::rmdir(chunk) != 0) + return oldslash != 0; + } else { + return false; + } + slash = dirName.lastIndexOf(QDir::separator(), oldslash-1); + } + return true; + } + return rmdir(QFile::encodeName(entry.filePath())) == 0; } //static diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index c20d6ae..50b18fc 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -497,28 +497,7 @@ bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) con bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const { - QString dirName = name; - if (recurseParentDirectories) { - dirName = QDir::cleanPath(dirName); -#if defined(Q_OS_SYMBIAN) - dirName = QDir::toNativeSeparators(dirName); -#endif - for(int oldslash = 0, slash=dirName.length(); slash > 0; oldslash = slash) { - QByteArray chunk = QFile::encodeName(dirName.left(slash)); - QT_STATBUF st; - if (QT_STAT(chunk, &st) != -1) { - if ((st.st_mode & S_IFMT) != S_IFDIR) - return false; - if (::rmdir(chunk) != 0) - return oldslash != 0; - } else { - return false; - } - slash = dirName.lastIndexOf(QDir::separator(), oldslash-1); - } - return true; - } - return ::rmdir(QFile::encodeName(dirName)) == 0; + return QFileSystemEngine::removeDirectory(QFileSystemEntry(name), recurseParentDirectories); } bool QFSFileEngine::caseSensitive() const -- cgit v0.12 From 33634cd85233b75d8c24ef8ed67ff054d709b6e9 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 3 Sep 2010 19:04:12 +0100 Subject: Port over QFileSystemIterator for Symbian OS Also added the QDirIterator::IteratorFlags iteratorFlags as a parameter for QFileSystemIterator, as it impacts what kind of filtering we can do via the OS. i.e. filename filtering isn't compatible with recursive iteration. Reviewed-By: joao --- src/corelib/io/qfilesystemiterator_p.h | 15 ++- src/corelib/io/qfilesystemiterator_symbian.cpp | 134 +++++++++++++++++++++++++ src/corelib/io/qfilesystemiterator_unix.cpp | 3 +- src/corelib/io/qfilesystemiterator_win.cpp | 3 +- 4 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 src/corelib/io/qfilesystemiterator_symbian.cpp diff --git a/src/corelib/io/qfilesystemiterator_p.h b/src/corelib/io/qfilesystemiterator_p.h index 21ad70a..ed1ef5e 100644 --- a/src/corelib/io/qfilesystemiterator_p.h +++ b/src/corelib/io/qfilesystemiterator_p.h @@ -55,17 +55,25 @@ #include #include +#include #include #include #include +// Platform-specific headers +#if defined(Q_OS_WIN) +#elif defined (Q_OS_SYMBIAN) +#include +#else +#endif + QT_BEGIN_NAMESPACE class QFileSystemIterator { public: - QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, const QStringList &nameFilters); + QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, const QStringList &nameFilters, QDirIterator::IteratorFlags flags); ~QFileSystemIterator(); bool advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData); @@ -74,6 +82,11 @@ private: // Platform-specific data #if defined(Q_OS_WIN) +#elif defined (Q_OS_SYMBIAN) + RDir dirHandle; + TEntryArray entries; + TInt lastError; + TInt entryIndex; #else #endif diff --git a/src/corelib/io/qfilesystemiterator_symbian.cpp b/src/corelib/io/qfilesystemiterator_symbian.cpp new file mode 100644 index 0000000..9093599 --- /dev/null +++ b/src/corelib/io/qfilesystemiterator_symbian.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "qfilesystemiterator_p.h" +#include "qfilesystemengine_p.h" +#include "qcore_symbian_p.h" + +QT_BEGIN_NAMESPACE + +QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &path, QDir::Filters filters, + const QStringList &nameFilters, QDirIterator::IteratorFlags iteratorFlags) + : lastError(KErrNone), entryIndex(-1) +{ + RFs& fs = qt_s60GetRFs(); + + TFileName symbianPath; + QString abspath = QFileSystemEngine::absoluteName(path).nativeFilePath(); + + if (!abspath.endsWith(QLatin1Char('\\'))) + abspath.append(QLatin1Char('\\')); + + int pathLen = abspath.length(); + if (pathLen > symbianPath.MaxLength()) { + lastError = KErrBadName; + return; + } + symbianPath.Copy(qt_QString2TPtrC(abspath)); + + //set up server side filtering to reduce IPCs + //RDir won't accept all valid name filters e.g. "*. bar" + if (nameFilters.count() == 1 && !(filters & QDir::AllDirs) && iteratorFlags + == QDirIterator::NoIteratorFlags && pathLen + nameFilters[0].length() + <= symbianPath.MaxLength()) { + //server side supports one mask - skip this for recursive mode or if only files should be filtered + symbianPath.Append(qt_QString2TPtrC(nameFilters[0])); + } + + TUint symbianMask = 0; + if ((filters & QDir::Dirs) || (filters & QDir::AllDirs) || (iteratorFlags + & QDirIterator::Subdirectories)) + symbianMask |= KEntryAttDir; //include directories + if (filters & QDir::Hidden) + symbianMask |= KEntryAttHidden; + if (filters & QDir::System) + symbianMask |= KEntryAttSystem; + if (((filters & QDir::Files) == 0) && symbianMask == KEntryAttDir) + symbianMask |= KEntryAttMatchExclusive; //exclude non-directories + else if (symbianMask == 0) { + if ((filters & QDir::PermissionMask) == QDir::Writable) + symbianMask = KEntryAttMatchExclude | KEntryAttReadOnly; + else if ((filters & QDir::PermissionMask) == QDir::Readable) + symbianMask = KEntryAttMatchExclusive | KEntryAttReadOnly; + } + + lastError = dirHandle.Open(fs, symbianPath, symbianMask); +} + +QFileSystemIterator::~QFileSystemIterator() +{ + dirHandle.Close(); +} + +static void createFileSystemMetaDataHelper(const TEntry &entry, QFileSystemMetaData &metaData) +{ + //placeholder + //TODO: adapt from QFileInfoPrivate::fromTEntry(entries[entryIndex], path()); + //or add this functionality to QFileSystemMetaData +} + +bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData) +{ + //1st time, lastError is result of dirHandle.Open(), entries.Count() is 0 and entryIndex is -1 so initial read is triggered + //subsequent times, read is triggered each time we reach the end of the entry list + //final time, lastError is KErrEof so we don't need to read anymore. + ++entryIndex; + if (lastError == KErrNone && entryIndex >= entries.Count()) { + lastError = dirHandle.Read(entries); + entryIndex = 0; + } + + //each call to advance() gets the next entry from the entry list. + //from the final (or only) read call, KErrEof is returned together with a full buffer so we still need to go through the list + if ((lastError == KErrNone || lastError == KErrEof) && entryIndex < entries.Count()) { + Q_ASSERT(entryIndex >= 0); + const TEntry &entry(entries[entryIndex]); + fileEntry = QFileSystemEntry(qt_TDesC2QString(entry.iName), QFileSystemEntry::FromNativePath()); + createFileSystemMetaDataHelper(entry, metaData); + return true; + } + + //TODO: error reporting, to allow user to distinguish empty directory from error condition. + + return false; +} + +QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp index 1a6bf87..3c73496 100644 --- a/src/corelib/io/qfilesystemiterator_unix.cpp +++ b/src/corelib/io/qfilesystemiterator_unix.cpp @@ -44,11 +44,12 @@ QT_BEGIN_NAMESPACE QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, - const QStringList &nameFilters) + const QStringList &nameFilters, QDirIterator::IteratorFlags flags) { Q_UNUSED(entry) Q_UNUSED(filters) Q_UNUSED(nameFilters) + Q_UNUSED(flags) } QFileSystemIterator::~QFileSystemIterator() diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 1a6bf87..3c73496 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -44,11 +44,12 @@ QT_BEGIN_NAMESPACE QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, - const QStringList &nameFilters) + const QStringList &nameFilters, QDirIterator::IteratorFlags flags) { Q_UNUSED(entry) Q_UNUSED(filters) Q_UNUSED(nameFilters) + Q_UNUSED(flags) } QFileSystemIterator::~QFileSystemIterator() -- cgit v0.12 From 00bcd42c9ec6cb723fdccb08bb969eef0e5f1f0f Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 3 Sep 2010 19:17:46 +0100 Subject: Implementation of QFileSystemEngine for Symbian OS Code comes from QFile, QDir and QFileInfo in the native IO branch Reviewed-By: joao --- src/corelib/io/qfilesystemengine_symbian.cpp | 213 +++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 src/corelib/io/qfilesystemengine_symbian.cpp diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp new file mode 100644 index 0000000..2798bdf --- /dev/null +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -0,0 +1,213 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "qfilesystemengine_p.h" +#include "qfsfileengine.h" +#include "qcore_symbian_p.h" + +#include + +QT_BEGIN_NAMESPACE + +bool QFileSystemEngine::isCaseSensitive() +{ + return false; +} + +//static +QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link) +{ + return link; // TODO implement +} + +//static +QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) +{ + if (entry.isEmpty() || entry.isRoot()) + return entry; + + QFileSystemEntry result = absoluteName(entry); + RFs& fs(qt_s60GetRFs()); + TUint e; + //Att is faster than Entry for determining if a file exists, due to smaller IPC + TInt r = fs.Att(qt_QString2TPtrC(result.nativeFilePath()), e); + + if (r == KErrNone) { + return result; + } else { // file doesn't exist + return QFileSystemEntry(); + } +} + +//static +QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) +{ + if (entry.isAbsolute()) + return entry; + + QString orig = entry.filePath(); + QString result; + if (orig.isEmpty() || !orig.startsWith('/')) { + QFileSystemEntry cur(QFSFileEngine::currentPath()); + result = cur.filePath(); + } + if (!orig.isEmpty() && !(orig.length() == 1 && orig[0] == '.')) { + if (!result.isEmpty() && !result.endsWith('/')) + result.append('/'); + result.append(orig); + } + + if (result.length() == 1 && result[0] == '/') + return QFileSystemEntry(result); + const bool isDir = result.endsWith('/'); + + result = QDir::cleanPath(result); + if (isDir) + result.append(QLatin1Char('/')); + return QFileSystemEntry(result); +} + +//static +QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) +{ + return QString(); // TODO implement; +} + +//static +bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) +{ + return false; // TODO implement; +} + +//static +bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents) +{ + QString abspath = absoluteName(entry).nativeFilePath(); + if (!abspath.endsWith(QLatin1Char('\\'))) + abspath.append(QLatin1Char('\\')); + TInt r; + if (createParents) + r = qt_s60GetRFs().MkDirAll(qt_QString2TPtrC(abspath)); + else + r = qt_s60GetRFs().MkDir(qt_QString2TPtrC(abspath)); + return (r == KErrNone || r == KErrAlreadyExists); +} + +//static +bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents) +{ + QString abspath = absoluteName(entry).nativeFilePath(); + if (!abspath.endsWith(QLatin1Char('\\'))) + abspath.append(QLatin1Char('\\')); + TPtrC dir(qt_QString2TPtrC(abspath)); + RFs& fs = qt_s60GetRFs(); + bool ok = false; + //behaviour of FS file engine: + //returns true if the directory could be removed + //success/failure of removing parent directories does not matter + while (KErrNone == fs.RmDir(dir)) { + ok = true; + if (!removeEmptyParents) + break; + //RFs::RmDir treats "c:\foo\bar" and "c:\foo\" the same, so it is sufficient to remove the last \ to the end + dir.Set(dir.Left(dir.LocateReverse(TChar('\\')))); + } + return ok; +} + +//static +bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target) +{ + Q_UNUSED(source) + Q_UNUSED(target) + return false; +} + +//static +bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target) +{ + //TODO: review - should this be a singleton? + CFileMan *fm = 0; + TRAPD(err, fm = CFileMan::NewL(qt_s60GetRFs())); + if(err == KErrNone) { + err = fm->Copy(qt_QString2TPtrC(source.nativeFilePath()), qt_QString2TPtrC(target.nativeFilePath()), 0); + delete fm; + return true; + } + //TODO: error reporting d->setSymbianError(err, QFile::CopyError); + return false; +} + +//static +bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target) +{ + QString sourcepath = absoluteName(source).nativeFilePath(); + QString targetpath = absoluteName(target).nativeFilePath(); + RFs& fs(qt_s60GetRFs()); + TInt err = fs.Rename(qt_QString2TPtrC(sourcepath), qt_QString2TPtrC(targetpath)); + return err == KErrNone; // TODO error reporting; +} + +//static +bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry) +{ + QString targetpath = absoluteName(entry).nativeFilePath(); + RFs& fs(qt_s60GetRFs()); + TInt err = fs.Delete(qt_QString2TPtrC(targetpath)); + return false; // TODO error reporting; +} + +//static +bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QFileSystemMetaData *data) +{ + QString targetpath = absoluteName(entry).nativeFilePath(); + TUint setmask = 0; + TUint clearmask = 0; + RFs& fs(qt_s60GetRFs()); + if (permissions & (QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther)) + clearmask = KEntryAttReadOnly; + else + setmask = KEntryAttReadOnly; + TInt err = fs.SetAtt(qt_QString2TPtrC(targetpath), setmask, clearmask); + return err != KErrNone; // TODO error reporting, metadata update; +} + +QT_END_NAMESPACE -- cgit v0.12 From c4606e7fc8eeb52cd8966d317a77e4a69b0f2359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 3 Sep 2010 11:31:43 +0200 Subject: QFileSystemEngine/Mac: keep it empty until needed Added qfilesystemengine_mac to the build system, but hollowed it out. This way, it is ready for immediate use without having unnecessary stubs that can be found in the _unix version already. --- qmake/Makefile.unix | 4 ++ qmake/qmake.pri | 1 + src/corelib/io/io.pri | 1 + src/corelib/io/qfilesystemengine_mac.cpp | 77 +------------------------------- src/tools/bootstrap/bootstrap.pro | 1 + 5 files changed, 8 insertions(+), 76 deletions(-) diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index e8e96fd..d248831 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -46,6 +46,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp \ $(SOURCE_PATH)/src/corelib/io/qdatastream.cpp $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp \ $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp \ + $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_mac.cpp \ $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_unix.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine_unix.cpp $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator_unix.cpp $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp \ @@ -172,6 +173,9 @@ qfilesystemengine.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp qfilesystemengine_unix.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp +qfilesystemengine_mac.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_mac.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_mac.cpp + qfilesystemiterator_unix.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_unix.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_unix.cpp diff --git a/qmake/qmake.pri b/qmake/qmake.pri index 7226b12..ae31eca 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -129,6 +129,7 @@ bootstrap { #Qt code unix { SOURCES += qfilesystemengine_unix.cpp qfilesystemiterator_unix.cpp qfsfileengine_unix.cpp qfsfileengine_iterator_unix.cpp mac { + SOURCES += qfilesystemengine_mac.cpp SOURCES += qcore_mac.cpp qsettings_mac.cpp QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 #enables weak linking for 10.4 (exported) LIBS += -framework ApplicationServices diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 5d10216..7c3712e 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -81,6 +81,7 @@ win32 { else:SOURCES += io/qprocess_unix.cpp macx-*: { HEADERS += io/qfilesystemwatcher_fsevents_p.h + SOURCES += io/qfilesystemengine_mac.cpp SOURCES += io/qsettings_mac.cpp io/qfilesystemwatcher_fsevents.cpp } diff --git a/src/corelib/io/qfilesystemengine_mac.cpp b/src/corelib/io/qfilesystemengine_mac.cpp index c915a2c..30d7fa5 100644 --- a/src/corelib/io/qfilesystemengine_mac.cpp +++ b/src/corelib/io/qfilesystemengine_mac.cpp @@ -43,81 +43,6 @@ QT_BEGIN_NAMESPACE -bool QFileSystemEngine::isCaseSensitive() -{ - return true; -} - -//static -QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link) -{ - return link; // TODO implement -} - -//static -QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) -{ - return entry; // TODO implement; -} - -//static -QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) -{ - return entry; // TODO implement; -} - -//static -QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) -{ - return QString(); // TODO implement; -} - -//static -bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) -{ - return false; // TODO implement; -} - -//static -bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents) -{ - return false; // TODO implement; -} - -//static -bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents) -{ - return false; // TODO implement; -} - -//static -bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target) -{ - return false; // TODO implement; -} - -//static -bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target) -{ - return false; // TODO implement; -} - -//static -bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target) -{ - return false; // TODO implement; -} - -//static -bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry) -{ - return false; // TODO implement; -} - -//static -bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QFileSystemMetaData *data) -{ - return false; // TODO implement; -} +// Mac-specific implementations only! QT_END_NAMESPACE diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 6d2f760..016fdc0 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -97,6 +97,7 @@ win32:SOURCES += ../../corelib/io/qfilesystemengine_win.cpp \ macx: { QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 #enables weak linking for 10.4 (exported) + SOURCES += ../../corelib/io/qfilesystemengine_mac.cpp SOURCES += ../../corelib/kernel/qcore_mac.cpp LIBS += -framework CoreServices } -- cgit v0.12 From 81b302d06c93b77127a2bd6ee527aeefadffbf64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 3 Sep 2010 13:43:33 +0200 Subject: QFileSystemMetaData: filling up Changes to QFileSystemMetaData resulting from implementing QFileSystemEngine::fillMetaData on Unix -- commit to follow. * Added missing operators for MetaDataFlags * Tentatively sharing entryFlags and size across platforms; times and owner IDs are candidates * Flags definition simplified and made stricter; unused bits are no longer set in masks, either * New AliasType for Mac; AliasType and BundleType on other platforms are 0 so they can be optimized out * New SequentialType for files that are not regular files * LocalDiskAttribute (LocalDiskFlag in QAbstractFileEngine) was only used to flag the use of a native file engine, so it's useless here * New flags for querying owner IDs * New method: missingFlags, to help with incremental queries * Added accessors for known data * New method to fill metaData from struct stat --- src/corelib/io/qfilesystemengine_unix.cpp | 51 ++++++++++- src/corelib/io/qfilesystemmetadata_p.h | 136 +++++++++++++++++++++++++++--- 2 files changed, 172 insertions(+), 15 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 7c72782..3011aa0 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qplatformdefs.h" #include "qfilesystemengine_p.h" #include "qplatformdefs.h" #include "qfsfileengine.h" @@ -47,11 +48,59 @@ #include #if defined(Q_OS_MAC) -# include +# include #endif QT_BEGIN_NAMESPACE +void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) +{ + // Permissions + if (statBuffer.st_mode & S_IRUSR) + entryFlags |= QFileSystemMetaData::OwnerReadPermission; + if (statBuffer.st_mode & S_IWUSR) + entryFlags |= QFileSystemMetaData::OwnerWritePermission; + if (statBuffer.st_mode & S_IXUSR) + entryFlags |= QFileSystemMetaData::OwnerExecutePermission; + + if (statBuffer.st_mode & S_IRGRP) + entryFlags |= QFileSystemMetaData::GroupReadPermission; + if (statBuffer.st_mode & S_IWGRP) + entryFlags |= QFileSystemMetaData::GroupWritePermission; + if (statBuffer.st_mode & S_IXGRP) + entryFlags |= QFileSystemMetaData::GroupExecutePermission; + + if (statBuffer.st_mode & S_IROTH) + entryFlags |= QFileSystemMetaData::OtherReadPermission; + if (statBuffer.st_mode & S_IWOTH) + entryFlags |= QFileSystemMetaData::OtherWritePermission; + if (statBuffer.st_mode & S_IXOTH) + entryFlags |= QFileSystemMetaData::OtherExecutePermission; + + // Type + if ((statBuffer.st_mode & S_IFMT) == S_IFREG) + entryFlags |= QFileSystemMetaData::FileType; + else if ((statBuffer.st_mode & S_IFMT) == S_IFDIR) + entryFlags |= QFileSystemMetaData::DirectoryType; + else + entryFlags |= QFileSystemMetaData::SequentialType; + + // Attributes + entryFlags |= QFileSystemMetaData::ExistsAttribute; + size_ = statBuffer.st_size; +#if !defined(QWS) && defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if (statBuffer.st_flags & UF_HIDDEN) { + entryFlags |= QFileSystemMetaData::HiddenAttribute; + knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; + } +#endif + + // Times + creationTime_ = statBuffer.st_ctime ? statBuffer.st_ctime : statBuffer.st_mtime; + modificationTime_ = statBuffer.st_mtime; + accessTime_ = statBuffer.st_atime; +} + bool QFileSystemEngine::isCaseSensitive() { #if defined(Q_OS_SYMBIAN) diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 40bad9e..5914eb3 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -53,7 +53,10 @@ // We mean it. // +#include "qplatformdefs.h" #include +#include +#include // Platform-specific includes #if defined(Q_OS_WIN) @@ -67,7 +70,7 @@ class QFileSystemEngine; struct QFileSystemMetaData { QFileSystemMetaData() - : cachedFlags(0) + : knownFlagsMask(0) { } @@ -78,60 +81,165 @@ struct QFileSystemMetaData UserReadPermission = 0x00000400, UserWritePermission = 0x00000200, UserExecutePermission = 0x00000100, OwnerReadPermission = 0x00004000, OwnerWritePermission = 0x00002000, OwnerExecutePermission = 0x00001000, - OtherPermissions = 0x0000000F, - GroupPermissions = 0x000000F0, - UserPermissions = 0x00000F00, - OwnerPermissions = 0x0000F000, + OtherPermissions = OtherReadPermission | OtherWritePermission | OtherExecutePermission, + GroupPermissions = GroupReadPermission | GroupWritePermission | GroupExecutePermission, + UserPermissions = UserReadPermission | UserWritePermission | UserExecutePermission, + OwnerPermissions = OwnerReadPermission | OwnerWritePermission | OwnerExecutePermission, - Permissions = 0x0000FFFF, + Permissions = OtherPermissions | GroupPermissions | UserPermissions | OwnerPermissions, // Type LinkType = 0x00010000, FileType = 0x00020000, DirectoryType = 0x00040000, +#if !defined(QWS) && defined(Q_OS_MAC) BundleType = 0x00080000, + AliasType = 0x08000000, +#else + BundleType = 0x0, + AliasType = 0x0, +#endif + SequentialType = 0x00800000, // Note: overlaps with QAbstractFileEngine::RootFlag - Type = 0x000F0000, + Type = LinkType | FileType | DirectoryType | BundleType | SequentialType | AliasType, // Attributes HiddenAttribute = 0x00100000, - LocalDiskAttribute = 0x00200000, + SizeAttribute = 0x00200000, // Note: overlaps with QAbstractFileEngine::LocalDiskFlag ExistsAttribute = 0x00400000, - SizeAttribute = 0x00800000, // Note: overlaps with QAbstractFileEngine::RootFlag - Attributes = 0x00F00000, + Attributes = HiddenAttribute | SizeAttribute | ExistsAttribute, // Times CreationTime = 0x01000000, // Note: overlaps with QAbstractFileEngine::Refresh ModificationTime = 0x02000000, AccessTime = 0x04000000, - Times = 0x07000000 + Times = CreationTime | ModificationTime | AccessTime, + + // Owner IDs + UserId = 0x10000000, + GroupId = 0x20000000, + + OwnerIds = UserId | GroupId, + + PosixStatFlags = QFileSystemMetaData::OtherPermissions + | QFileSystemMetaData::GroupPermissions + | QFileSystemMetaData::OwnerPermissions + | QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::SequentialType +#if !defined(QWS) && defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + // Mac OS >= 10.5: st_flags & UF_HIDDEN + | QFileSystemMetaData::HiddenAttribute +#endif + | QFileSystemMetaData::SizeAttribute + | QFileSystemMetaData::Times + | QFileSystemMetaData::OwnerIds, + + AllMetaDataFlags = 0xFFFFFFFF + }; Q_DECLARE_FLAGS(MetaDataFlags, MetaDataFlag) bool hasFlags(MetaDataFlags flags) const { - return ((cachedFlags & flags) == flags); + return ((knownFlagsMask & flags) == flags); + } + + MetaDataFlags missingFlags(MetaDataFlags flags) + { + return flags & ~knownFlagsMask; } void clear() { - cachedFlags = 0; + knownFlagsMask = 0; + } + + void clearFlags(MetaDataFlags flags = AllMetaDataFlags) + { + knownFlagsMask &= ~flags; + } + + bool exists() const { return (entryFlags & ExistsAttribute); } + + bool isLink() const { return (entryFlags & LinkType); } + bool isFile() const { return (entryFlags & FileType); } + bool isDirectory() const { return (entryFlags & DirectoryType); } +#if !defined(QWS) && defined(Q_OS_MAC) + bool isBundle() const { return (entryFlags & BundleType); } + bool isAlias() const { return (entryFlags & AliasType); } +#else + bool isBundle() const { return false; } + bool isAlias() const { return false; } +#endif + bool isSequential() const { return (entryFlags & SequentialType); } + bool isHidden() const { return (entryFlags & HiddenAttribute); } + + qint64 size() const { return size_; } + + QFile::Permissions permissions() const { return QFile::Permissions(Permissions & entryFlags); } + +#if defined(Q_OS_UNIX) + QDateTime creationTime() const { return QDateTime::fromTime_t(creationTime_); } + QDateTime modificationTime() const { return QDateTime::fromTime_t(modificationTime_); } + QDateTime accessTime() const { return QDateTime::fromTime_t(accessTime_); } + + QDateTime fileTime(QAbstractFileEngine::FileTime time) const + { + switch (time) + { + case QAbstractFileEngine::ModificationTime: + return modificationTime(); + + case QAbstractFileEngine::AccessTime: + return accessTime(); + + case QAbstractFileEngine::CreationTime: + return creationTime(); + } + + return QDateTime(); + } + + uint userId() const { return userId_; } + uint groupId() const { return groupId_; } + + uint ownerId(QAbstractFileEngine::FileOwner owner) const + { + if (owner == QAbstractFileEngine::OwnerUser) + return userId(); + else + return groupId(); } + void fillFromStatBuf(const QT_STATBUF &statBuffer); +#endif + private: friend class QFileSystemEngine; - MetaDataFlags cachedFlags; + MetaDataFlags knownFlagsMask; + MetaDataFlags entryFlags; + + qint64 size_; // Platform-specific data goes here: #if defined(Q_OS_WIN) #else + time_t creationTime_; + time_t modificationTime_; + time_t accessTime_; + + uint userId_; + uint groupId_; #endif }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QFileSystemMetaData::MetaDataFlags) + QT_END_NAMESPACE #endif // include guard -- cgit v0.12 From 4fd2aced96d9095254d89f9da9c911bd88f15245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 3 Sep 2010 20:17:35 +0200 Subject: QFileSystemEngine::fillMetaData for Unix platforms This shuffles a lot of code out of QFSFileEngine. fillMetaData, however is almost a reimplementation of the logic. Goals for this function are to maximize data gathered and minimize file system queries. Symbian had an optimization to lstat first and only stat again on links, having noticed a lot of lstat were being done that weren't really necessary. That optimization was also made in the new fillMetaData function and extended to all platforms, whenever the LinkType attribute is requested (QFSFileEngine will now typically request this in reply to a fileFlags request). We now try to cache all meta data we get from the file system, while still requesting "refreshes" as often as we did before. Client code going straight to QFileSystemEngine API can choose it's behaviour by clearing and querying specific flags in the QFileSystemMetaData instance. Reviewed-by: Prasanth Ullattil --- src/corelib/io/qfilesystemengine_p.h | 3 + src/corelib/io/qfilesystemengine_unix.cpp | 209 ++++++++++++++++++++- src/corelib/io/qfsfileengine.cpp | 33 +--- src/corelib/io/qfsfileengine_p.h | 14 +- src/corelib/io/qfsfileengine_unix.cpp | 300 +++++++++--------------------- 5 files changed, 324 insertions(+), 235 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index f50701e..182ccd6 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -72,6 +72,9 @@ public: static bool fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what); +#if defined(Q_OS_UNIX) + static bool fillMetaData(int fd, QFileSystemMetaData &data); // what = PosixStatFlags +#endif static bool createDirectory(const QFileSystemEntry &entry, bool createParents); static bool removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents); diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 3011aa0..6b3c157 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -47,12 +47,64 @@ #include // for realpath() #include +#if defined(Q_OS_SYMBIAN) +# include +# include +# include +# include +#endif + #if defined(Q_OS_MAC) # include #endif QT_BEGIN_NAMESPACE +#if defined(Q_OS_SYMBIAN) +static bool _q_isSymbianHidden(const QFileSystemEntry &entry, bool isDir) +{ + RFs rfs = qt_s60GetRFs(); + + QFileSystemEntry absoluteEntry = QFileSystemEngine::absoluteName(entry); + QString absolutePath = absoluteEntry.filePath(); + + if (isDir && !absolutePath.endsWith(QLatin1Char('/'))) + absolutePath.append(QLatin1Char('/')); + + TPtrC ptr(qt_QString2TPtrC(absolutePath)); + TUint attributes; + TInt err = rfs.Att(ptr, attributes); + return (err == KErrNone && (attributes & KEntryAttHidden)); +} +#endif + +#if !defined(QWS) && defined(Q_OS_MAC) +static inline bool _q_isMacHidden(const char *nativePath) +{ + OSErr err; + + FSRef fsRef; + err = FSPathMakeRefWithOptions(reinterpret_cast(nativePath), + kFSPathMakeRefDoNotFollowLeafSymlink, &fsRef, 0); + if (err != noErr) + return false; + + FSCatalogInfo catInfo; + err = FSGetCatalogInfo(&fsRef, kFSCatInfoFinderInfo, &catInfo, NULL, NULL, NULL); + if (err != noErr) + return false; + + FileInfo * const fileInfo = reinterpret_cast(&catInfo.finderInfo); + return (fileInfo->finderFlags & kIsInvisible); +} +#else +static inline bool _q_isMacHidden(const char *nativePath) +{ + // no-op + return false; +} +#endif + void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) { // Permissions @@ -207,9 +259,162 @@ QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) } //static -bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) +bool QFileSystemEngine::fillMetaData(int fd, QFileSystemMetaData &data) { - return false; // TODO implement; + data.entryFlags &= ~QFileSystemMetaData::PosixStatFlags; + data.knownFlagsMask |= QFileSystemMetaData::PosixStatFlags; + + QT_STATBUF statBuffer; + if (QT_FSTAT(fd, &statBuffer) == 0) { + data.fillFromStatBuf(statBuffer); + return true; + } + + return false; +} + +//static +bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, + QFileSystemMetaData::MetaDataFlags what) +{ +#if !defined(QWS) && defined(Q_OS_MAC) + if (what & QFileSystemMetaData::BundleType) { + if (!data.hasFlags(QFileSystemMetaData::DirectoryType)) + what |= QFileSystemMetaData::DirectoryType; + } +#endif + +#if defined(Q_OS_SYMBIAN) + if (what & QFileSystemMetaData::HiddenAttribute) { + if (!data.hasFlags(QFileSystemMetaData::LinkType | QFileSystemMetaData::DirectoryType)) + what |= QFileSystemMetaData::LinkType | QFileSystemMetaData::DirectoryType; + } +#endif + + if (what & QFileSystemMetaData::PosixStatFlags) + what |= QFileSystemMetaData::PosixStatFlags; + + if (what & QFileSystemMetaData::ExistsAttribute) { + // FIXME: Would other queries being performed provide this bit? + what |= QFileSystemMetaData::PosixStatFlags; + } + + data.entryFlags &= ~what; + + const char * nativeFilePath; + int nativeFilePathLength; + { + const QByteArray &path = entry.nativeFilePath(); + nativeFilePath = path.constData(); + nativeFilePathLength = path.size(); + } + + bool entryExists = true; // innocent until proven otherwise + + QT_STATBUF statBuffer; + bool statBufferValid = false; + if (what & QFileSystemMetaData::LinkType) { + if (QT_LSTAT(nativeFilePath, &statBuffer) == 0) { + if (S_ISLNK(statBuffer.st_mode)) { + data.entryFlags |= QFileSystemMetaData::LinkType; + } else { + statBufferValid = true; + data.entryFlags &= ~QFileSystemMetaData::PosixStatFlags; + } + } else { + entryExists = false; + } + + data.knownFlagsMask |= QFileSystemMetaData::LinkType; + } + + if (statBufferValid || (what & QFileSystemMetaData::PosixStatFlags)) { + if (entryExists && !statBufferValid) + statBufferValid = (QT_STAT(nativeFilePath, &statBuffer) == 0); + + if (statBufferValid) + data.fillFromStatBuf(statBuffer); + else + entryExists = false; + + // reset the mask + data.knownFlagsMask |= QFileSystemMetaData::PosixStatFlags + | QFileSystemMetaData::ExistsAttribute; + } + +#if !defined(QWS) && defined(Q_OS_MAC) + if (what & QFileSystemMetaData::AliasType) + { + if (entryExists) { + FSRef fref; + if (FSPathMakeRef((const UInt8 *)nativeFilePath, &fref, NULL) == noErr) { + Boolean isAlias, isFolder; + if (FSIsAliasFile(&fref, &isAlias, &isFolder) == noErr) { + if (isAlias) + data.entryFlags |= QFileSystemMetaData::AliasType; + } + } + } + data.knownFlagsMask |= QFileSystemMetaData::AliasType; + } +#endif + + if (what & QFileSystemMetaData::UserPermissions) { + // calculate user permissions + + if (entryExists) { + if (what & QFileSystemMetaData::UserReadPermission) { + if (QT_ACCESS(nativeFilePath, R_OK) == 0) + data.entryFlags |= QFileSystemMetaData::UserReadPermission; + } + if (what & QFileSystemMetaData::UserWritePermission) { + if (QT_ACCESS(nativeFilePath, W_OK) == 0) + data.entryFlags |= QFileSystemMetaData::UserWritePermission; + } + if (what & QFileSystemMetaData::UserExecutePermission) { + if (QT_ACCESS(nativeFilePath, X_OK) == 0) + data.entryFlags |= QFileSystemMetaData::UserExecutePermission; + } + } + data.knownFlagsMask |= (what & QFileSystemMetaData::UserPermissions); + } + + if (what & QFileSystemMetaData::HiddenAttribute + && !data.isHidden()) { +#if defined(Q_OS_SYMBIAN) + // In Symbian, all symlinks have hidden attribute for some reason; + // lets make them visible for better compatibility with other platforms. + // If somebody actually wants a hidden link, then they are out of luck. + if (entryExists && !data.isLink() && _q_isSymbianHidden(entry, data.isDirectory())) + data.entryFlags |= QFileSystemMetaData::HiddenAttribute; +#else + QString fileName = entry.fileName(); + if ((fileName.size() > 0 && fileName.at(0) == QLatin1Char('.')) + || (entryExists && _q_isMacHidden(nativeFilePath))) + data.entryFlags |= QFileSystemMetaData::HiddenAttribute; +#endif + data.knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; + } + +#if !defined(QWS) && defined(Q_OS_MAC) + if (what & QFileSystemMetaData::BundleType) { + if (entryExists && data.isDirectory()) { + QCFType path = CFStringCreateWithBytes(0, + (const UInt8*)nativeFilePath, nativeFilePathLength, + kCFStringEncodingUTF8, false); + QCFType url = CFURLCreateWithFileSystemPath(0, path, + kCFURLPOSIXPathStyle, true); + + UInt32 type, creator; + if (CFBundleGetPackageInfoInDirectory(url, &type, &creator)) + data.entryFlags |= QFileSystemMetaData::BundleType; + } + + data.knownFlagsMask |= QFileSystemMetaData::BundleType; + } +#endif + + return data.hasFlags(what); } //static diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 5d7b354..1b0a28c 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -447,24 +447,13 @@ qint64 QFSFileEngine::size() const qint64 QFSFileEnginePrivate::sizeFdFh() const { Q_Q(const QFSFileEngine); - // ### Fix this function, it should not stat unless the file is closed. - QT_STATBUF st; - int ret = 0; const_cast(q)->flush(); - if (fh && fileEntry.isEmpty()) { - // Buffered stdlib mode. - // ### This should really be an ftell - ret = QT_FSTAT(QT_FILENO(fh), &st); - } else if (fd == -1) { - // Stateless stat. - ret = QT_STAT(fileEntry.nativeFilePath().constData(), &st); - } else { - // Unbuffered stdio mode. - ret = QT_FSTAT(fd, &st); - } - if (ret == -1) + + tried_stat = 0; + metaData.clearFlags(QFileSystemMetaData::SizeAttribute); + if (!doStat(QFileSystemMetaData::SizeAttribute)) return 0; - return st.st_size; + return metaData.size(); } #endif @@ -773,18 +762,14 @@ bool QFSFileEngine::isSequential() const /*! \internal */ +#ifdef Q_OS_UNIX bool QFSFileEnginePrivate::isSequentialFdFh() const { - if (!tried_stat) - doStat(); - if (could_stat) { -#ifdef Q_OS_UNIX - return (st.st_mode & S_IFMT) != S_IFREG; - // ### WINDOWS! -#endif - } + if (doStat(QFileSystemMetaData::SequentialType)) + return metaData.isSequential(); return true; } +#endif /*! \reimp diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 9eaf6fd..6e5f30e 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -56,7 +56,8 @@ #include "qplatformdefs.h" #include "QtCore/qfsfileengine.h" #include "private/qabstractfileengine_p.h" -#include "private/qfilesystementry_p.h" +#include +#include #include #ifndef QT_NO_FSFILEENGINE @@ -102,11 +103,17 @@ public: qint64 writeFdFh(const char *data, qint64 len); int nativeHandle() const; bool nativeIsSequential() const; +#ifndef Q_OS_WIN bool isSequentialFdFh() const; +#endif uchar *map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags); bool unmap(uchar *ptr); +#if defined(Q_OS_UNIX) + mutable QFileSystemMetaData metaData; +#endif + FILE *fh; #ifdef Q_WS_WIN HANDLE fileHandle; @@ -120,7 +127,6 @@ public: mutable DWORD fileAttrib; #else QHash > maps; - mutable QT_STATBUF st; #endif int fd; @@ -142,7 +148,11 @@ public: mutable uint is_link : 1; #endif +#if defined(Q_OS_WIN) bool doStat() const; +#else + bool doStat(QFileSystemMetaData::MetaDataFlags flags = QFileSystemMetaData::PosixStatFlags) const; +#endif bool isSymlink() const; #if defined(Q_OS_WIN32) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 50b18fc..71a604a 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -69,7 +69,6 @@ QT_BEGIN_NAMESPACE - #if defined(Q_OS_SYMBIAN) /*! \internal @@ -124,16 +123,17 @@ void QFSFileEnginePrivate::setSymbianError(int symbianError, QFile::FileError de Returns the stdlib open string corresponding to a QIODevice::OpenMode. */ -static inline QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QByteArray &fileName) +static inline QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QFileSystemEntry &fileEntry, + QFileSystemMetaData &metaData) { QByteArray mode; if ((flags & QIODevice::ReadOnly) && !(flags & QIODevice::Truncate)) { mode = "rb"; if (flags & QIODevice::WriteOnly) { - QT_STATBUF statBuf; - if (!fileName.isEmpty() - && QT_STAT(fileName, &statBuf) == 0 - && (statBuf.st_mode & S_IFMT) == S_IFREG) { + metaData.clearFlags(QFileSystemMetaData::FileType); + if (!fileEntry.isEmpty() + && QFileSystemEngine::fillMetaData(fileEntry, metaData, QFileSystemMetaData::FileType) + && metaData.isFile()) { mode += '+'; } else { mode = "wb+"; @@ -222,13 +222,11 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) if (!(openMode & QIODevice::WriteOnly)) { // we don't need this check if we tried to open for writing because then // we had received EISDIR anyway. - QT_STATBUF statBuf; - if (QT_FSTAT(fd, &statBuf) != -1) { - if ((statBuf.st_mode & S_IFMT) == S_IFDIR) { - q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); - QT_CLOSE(fd); - return false; - } + if (QFileSystemEngine::fillMetaData(fd, metaData) + && metaData.isDirectory()) { + q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); + QT_CLOSE(fd); + return false; } } @@ -248,7 +246,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) fh = 0; } else { - QByteArray fopenMode = openModeToFopenMode(openMode, fileEntry.nativeFilePath().constData()); + QByteArray fopenMode = openModeToFopenMode(openMode, fileEntry, metaData); // Try to open the file in buffered mode. do { @@ -265,13 +263,11 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) if (!(openMode & QIODevice::WriteOnly)) { // we don't need this check if we tried to open for writing because then // we had received EISDIR anyway. - QT_STATBUF statBuf; - if (QT_FSTAT(fileno(fh), &statBuf) != -1) { - if ((statBuf.st_mode & S_IFMT) == S_IFDIR) { - q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); - fclose(fh); - return false; - } + if (QFileSystemEngine::fillMetaData(QT_FILENO(fh), metaData) + && metaData.isDirectory()) { + q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); + fclose(fh); + return false; } } @@ -626,123 +622,30 @@ QFileInfoList QFSFileEngine::drives() return ret; } -bool QFSFileEnginePrivate::doStat() const +bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) const { - if (!tried_stat) { - tried_stat = true; - could_stat = false; - - if (fh && fileEntry.isEmpty()) { - // ### actually covers two cases: d->fh and when the file is not open - could_stat = (QT_FSTAT(QT_FILENO(fh), &st) == 0); - } else if (fd == -1) { - // ### actually covers two cases: d->fh and when the file is not open -#if defined(Q_OS_SYMBIAN) - // Optimisation for Symbian where fileFlags() calls both doStat() and isSymlink(), but rarely on real links. - // When the filename is not a link, lstat will return the same info as stat, but this also removes - // any need for a further call to lstat to check if the file is a link. - need_lstat = false; - could_stat = (QT_LSTAT(fileEntry.nativeFilePath().constData(), &st) == 0); - is_link = could_stat ? S_ISLNK(st.st_mode) : false; - // if it turns out this was a link, we can call stat too. - if (is_link) -#endif - could_stat = (QT_STAT(fileEntry.nativeFilePath().constData(), &st) == 0); - } else { - could_stat = (QT_FSTAT(fd, &st) == 0); - } - } - return could_stat; -} + if (!tried_stat || !metaData.hasFlags(flags)) { + tried_stat = 1; -bool QFSFileEnginePrivate::isSymlink() const -{ - if (need_lstat) { - need_lstat = false; + int localFd = fd; + if (fh && fileEntry.isEmpty()) + localFd = QT_FILENO(fh); + if (localFd != -1) + QFileSystemEngine::fillMetaData(localFd, metaData); - QT_STATBUF st; // don't clobber our main one - is_link = (QT_LSTAT(fileEntry.nativeFilePath().constData(), &st) == 0) ? S_ISLNK(st.st_mode) : false; + if (metaData.missingFlags(flags) && !fileEntry.isEmpty()) + QFileSystemEngine::fillMetaData(fileEntry, metaData, metaData.missingFlags(flags)); } - return is_link; -} -#if defined(Q_OS_SYMBIAN) -static bool _q_isSymbianHidden(const QString &path, bool isDir) -{ - RFs rfs = qt_s60GetRFs(); - QFileInfo fi(path); - QString absPath = fi.absoluteFilePath(); - if (isDir && !absPath.endsWith(QLatin1Char('/'))) - absPath.append(QLatin1Char('/')); - QString native(QDir::toNativeSeparators(absPath)); - TPtrC ptr(qt_QString2TPtrC(native)); - TUint attributes; - TInt err = rfs.Att(ptr, attributes); - return (err == KErrNone && (attributes & KEntryAttHidden)); + return metaData.exists(); } -#endif -#if !defined(QWS) && defined(Q_OS_MAC) -static bool _q_isMacHidden(const QString &path) -{ - OSErr err = noErr; - - FSRef fsRef; - - err = FSPathMakeRefWithOptions(reinterpret_cast(QFile::encodeName(QDir::cleanPath(path)).constData()), - kFSPathMakeRefDoNotFollowLeafSymlink, &fsRef, 0); - if (err != noErr) - return false; - - FSCatalogInfo catInfo; - err = FSGetCatalogInfo(&fsRef, kFSCatInfoFinderInfo, &catInfo, NULL, NULL, NULL); - if (err != noErr) - return false; - - FileInfo * const fileInfo = reinterpret_cast(&catInfo.finderInfo); - bool result = (fileInfo->finderFlags & kIsInvisible); - return result; -} -#endif - -QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions(QAbstractFileEngine::FileFlags type) const +bool QFSFileEnginePrivate::isSymlink() const { - QAbstractFileEngine::FileFlags ret = 0; + if (!metaData.hasFlags(QFileSystemMetaData::LinkType)) + QFileSystemEngine::fillMetaData(fileEntry, metaData, QFileSystemMetaData::LinkType); - if (st.st_mode & S_IRUSR) - ret |= QAbstractFileEngine::ReadOwnerPerm; - if (st.st_mode & S_IWUSR) - ret |= QAbstractFileEngine::WriteOwnerPerm; - if (st.st_mode & S_IXUSR) - ret |= QAbstractFileEngine::ExeOwnerPerm; - if (st.st_mode & S_IRGRP) - ret |= QAbstractFileEngine::ReadGroupPerm; - if (st.st_mode & S_IWGRP) - ret |= QAbstractFileEngine::WriteGroupPerm; - if (st.st_mode & S_IXGRP) - ret |= QAbstractFileEngine::ExeGroupPerm; - if (st.st_mode & S_IROTH) - ret |= QAbstractFileEngine::ReadOtherPerm; - if (st.st_mode & S_IWOTH) - ret |= QAbstractFileEngine::WriteOtherPerm; - if (st.st_mode & S_IXOTH) - ret |= QAbstractFileEngine::ExeOtherPerm; - - // calculate user permissions - if (type & QAbstractFileEngine::ReadUserPerm) { - if (QT_ACCESS(fileEntry.nativeFilePath().constData(), R_OK) == 0) - ret |= QAbstractFileEngine::ReadUserPerm; - } - if (type & QAbstractFileEngine::WriteUserPerm) { - if (QT_ACCESS(fileEntry.nativeFilePath().constData(), W_OK) == 0) - ret |= QAbstractFileEngine::WriteUserPerm; - } - if (type & QAbstractFileEngine::ExeUserPerm) { - if (QT_ACCESS(fileEntry.nativeFilePath().constData(), X_OK) == 0) - ret |= QAbstractFileEngine::ExeUserPerm; - } - - return ret; + return metaData.isLink(); } /*! @@ -751,82 +654,71 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions(QAbstractFil QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const { Q_D(const QFSFileEngine); - // Force a stat, so that we're guaranteed to get up-to-date results - if (type & Refresh) { - d->tried_stat = 0; - d->need_lstat = 1; - } + + if (type & Refresh) + d->metaData.clear(); QAbstractFileEngine::FileFlags ret = 0; + if (type & FlagsMask) ret |= LocalDiskFlag; - bool exists = d->doStat(); - if (!exists && !d->isSymlink()) + + bool exists; + { + QFileSystemMetaData::MetaDataFlags queryFlags = 0; + + queryFlags |= QFileSystemMetaData::MetaDataFlags(uint(type)) + & QFileSystemMetaData::Permissions; + + if (type & TypesMask) + queryFlags |= QFileSystemMetaData::AliasType + | QFileSystemMetaData::LinkType + | QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::BundleType; + + if (type & FlagsMask) + queryFlags |= QFileSystemMetaData::HiddenAttribute + | QFileSystemMetaData::ExistsAttribute; + + queryFlags |= QFileSystemMetaData::LinkType; + + exists = d->doStat(queryFlags); + } + + if (!exists && !d->metaData.isLink()) return ret; if (exists && (type & PermsMask)) - ret |= d->getPermissions(type); + ret |= FileFlags(uint(d->metaData.permissions())); + if (type & TypesMask) { -#if !defined(QWS) && defined(Q_OS_MAC) - bool foundAlias = false; - { - FSRef fref; - if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->fileEntry.filePath())).data(), - &fref, NULL) == noErr) { - Boolean isAlias, isFolder; - if (FSIsAliasFile(&fref, &isAlias, &isFolder) == noErr && isAlias) { - foundAlias = true; - ret |= LinkType; - } - } - } - if (!foundAlias) -#endif - { - if ((type & LinkType) && d->isSymlink()) + if (d->metaData.isAlias()) { + ret |= LinkType; + } else { + if ((type & LinkType) && d->metaData.isLink()) ret |= LinkType; - if (exists && (d->st.st_mode & S_IFMT) == S_IFREG) - ret |= FileType; - else if (exists && (d->st.st_mode & S_IFMT) == S_IFDIR) - ret |= DirectoryType; -#if !defined(QWS) && defined(Q_OS_MAC) - if ((ret & DirectoryType) && (type & BundleType)) { - QCFType url = CFURLCreateWithFileSystemPath(0, QCFString(d->fileEntry.filePath()), - kCFURLPOSIXPathStyle, true); - UInt32 type, creator; - if (CFBundleGetPackageInfoInDirectory(url, &type, &creator)) - ret |= BundleType; + if (exists) { + if (d->metaData.isFile()) { + ret |= FileType; + } else if (d->metaData.isDirectory()) { + ret |= DirectoryType; + if ((type & BundleType) && d->metaData.isBundle()) + ret |= BundleType; + } } -#endif } } + if (type & FlagsMask) { if (exists) ret |= ExistsFlag; - if (d->fileEntry.isRoot()) { + if (d->fileEntry.isRoot()) ret |= RootFlag; - } else { -#if defined(Q_OS_SYMBIAN) - // In Symbian, all symlinks have hidden attribute for some reason; - // lets make them visible for better compatibility with other platforms. - // If somebody actually wants a hidden link, then they are out of luck. - if (!d->isSymlink() && _q_isSymbianHidden(d->fileEntry.filePath(), ret & DirectoryType)) - ret |= HiddenFlag; -#else - QString baseName = fileName(BaseName); - if ((baseName.size() > 0 && baseName.at(0) == QLatin1Char('.')) -# if !defined(QWS) && defined(Q_OS_MAC) - || _q_isMacHidden(d->fileEntry.filePath()) -# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - || d->st.st_flags & UF_HIDDEN -# endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 -# endif - ) { - ret |= HiddenFlag; - } -#endif - } + else if (d->metaData.isHidden()) + ret |= HiddenFlag; } + return ret; } @@ -994,7 +886,8 @@ QString QFSFileEngine::fileName(FileName file) const #endif if (len > 0) { QString ret; - if (d->doStat() && S_ISDIR(d->st.st_mode) && s[0] != '/') { + if (d->doStat(QFileSystemMetaData::DirectoryType) + && d->metaData.isDirectory() && s[0] != '/') { QDir parent(d->fileEntry.filePath()); parent.cdUp(); ret = parent.path(); @@ -1057,12 +950,10 @@ uint QFSFileEngine::ownerId(FileOwner own) const { Q_D(const QFSFileEngine); static const uint nobodyID = (uint) -2; - if (d->doStat()) { - if (own == OwnerUser) - return d->st.st_uid; - else - return d->st.st_gid; - } + + if (d->doStat(QFileSystemMetaData::OwnerIds)) + return d->metaData.ownerId(own); + return nobodyID; } @@ -1170,16 +1061,11 @@ bool QFSFileEngine::setSize(qint64 size) QDateTime QFSFileEngine::fileTime(FileTime time) const { Q_D(const QFSFileEngine); - QDateTime ret; - if (d->doStat()) { - if (time == CreationTime) - ret.setTime_t(d->st.st_ctime ? d->st.st_ctime : d->st.st_mtime); - else if (time == ModificationTime) - ret.setTime_t(d->st.st_mtime); - else if (time == AccessTime) - ret.setTime_t(d->st.st_atime); - } - return ret; + + if (d->doStat(QFileSystemMetaData::Times)) + return d->metaData.fileTime(time); + + return QDateTime(); } uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) @@ -1199,8 +1085,8 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla // If we know the mapping will extend beyond EOF, fail early to avoid // undefined behavior. Otherwise, let mmap have its say. - if (doStat() - && (QT_OFF_T(size) > st.st_size - QT_OFF_T(offset))) + if (doStat(QFileSystemMetaData::SizeAttribute) + && (QT_OFF_T(size) > metaData.size() - QT_OFF_T(offset))) qWarning("QFSFileEngine::map: Mapping a file beyond its size is not portable"); int access = 0; -- cgit v0.12 From a59924437dadf4ea3b972a528f449ebb2b760d81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 3 Sep 2010 10:32:20 +0200 Subject: QAbstractFileEngine: Exposing custom file engine handlers So we can invoke custom handlers from QFileSystemEngine. --- src/corelib/io/qabstractfileengine.cpp | 35 ++++++++++++++++++++++++---------- src/corelib/io/qabstractfileengine_p.h | 2 ++ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp index 37a093c..e055e7b 100644 --- a/src/corelib/io/qabstractfileengine.cpp +++ b/src/corelib/io/qabstractfileengine.cpp @@ -149,6 +149,29 @@ QAbstractFileEngineHandler::~QAbstractFileEngineHandler() } } +/* + \ìnternal + + Handles calls to custom file engine handlers. +*/ +QAbstractFileEngine *qt_custom_file_engine_handler_create(const QString &path) +{ + QAbstractFileEngine *engine = 0; + + if (qt_file_engine_handlers_in_use) { + QReadLocker locker(fileEngineHandlerMutex()); + + // check for registered handlers that can load the file + QAbstractFileEngineHandlerList *handlers = fileEngineHandlers(); + for (int i = 0; i < handlers->size(); i++) { + if ((engine = handlers->at(i)->create(path))) + break; + } + } + + return engine; +} + /*! \fn QAbstractFileEngine *QAbstractFileEngineHandler::create(const QString &fileName) const @@ -177,16 +200,8 @@ QAbstractFileEngineHandler::~QAbstractFileEngineHandler() */ QAbstractFileEngine *QAbstractFileEngine::create(const QString &fileName) { - if (qt_file_engine_handlers_in_use) { - QReadLocker locker(fileEngineHandlerMutex()); - - // check for registered handlers that can load the file - QAbstractFileEngineHandlerList *handlers = fileEngineHandlers(); - for (int i = 0; i < handlers->size(); i++) { - if (QAbstractFileEngine *ret = handlers->at(i)->create(fileName)) - return ret; - } - } + if (QAbstractFileEngine *engine = qt_custom_file_engine_handler_create(filePath)) + return engine; #ifdef QT_BUILD_CORE_LIB for (int prefixSeparator = 0; prefixSeparator < fileName.size(); ++prefixSeparator) { diff --git a/src/corelib/io/qabstractfileengine_p.h b/src/corelib/io/qabstractfileengine_p.h index e1eba30..075ec81 100644 --- a/src/corelib/io/qabstractfileengine_p.h +++ b/src/corelib/io/qabstractfileengine_p.h @@ -74,6 +74,8 @@ public: Q_DECLARE_PUBLIC(QAbstractFileEngine) }; +QAbstractFileEngine *qt_custom_file_engine_handler_create(const QString &path); + QT_END_NAMESPACE #endif // QABSTRACTFILEENGINE_P_H -- cgit v0.12 From 367514db5f041de7cd5d36fa0a260dcadcc54a50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 3 Sep 2010 19:33:52 +0200 Subject: Split QAbstractFileEngine::create The new, ugly-named resolveEntryAndCreateLegacyEngine will never instantiate QFSFileEngine and uses the QFileSystemEngine API to check if files exist, when necessary. This way, we reduce allocations of QFSFileEngine when resolving paths. Clients of the QAbstractFileEngine API will be able to opt-out of using QFSFileEngine altogether. Reviewed-by: Thomas Zander --- src/corelib/io/qabstractfileengine.cpp | 54 +++++---------------- src/corelib/io/qfilesystemengine.cpp | 87 ++++++++++++++++++++++++++++++++++ src/corelib/io/qfilesystemengine_p.h | 2 + 3 files changed, 102 insertions(+), 41 deletions(-) diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp index e055e7b..67109aa 100644 --- a/src/corelib/io/qabstractfileengine.cpp +++ b/src/corelib/io/qabstractfileengine.cpp @@ -52,6 +52,10 @@ #include "qdiriterator.h" #include "qstringbuilder.h" +#include +#include +#include + QT_BEGIN_NAMESPACE /*! @@ -200,49 +204,17 @@ QAbstractFileEngine *qt_custom_file_engine_handler_create(const QString &path) */ QAbstractFileEngine *QAbstractFileEngine::create(const QString &fileName) { - if (QAbstractFileEngine *engine = qt_custom_file_engine_handler_create(filePath)) - return engine; - -#ifdef QT_BUILD_CORE_LIB - for (int prefixSeparator = 0; prefixSeparator < fileName.size(); ++prefixSeparator) { - QChar const ch = fileName[prefixSeparator]; - if (ch == QLatin1Char('/')) - break; - - if (ch == QLatin1Char(':')) { - if (prefixSeparator == 0) - return new QResourceFileEngine(fileName); - - if (prefixSeparator == 1) - break; - - const QStringList &paths = QDir::searchPaths(fileName.left(prefixSeparator)); - for (int i = 0; i < paths.count(); i++) { - QAbstractFileEngine *engine = create(paths.at(i) % QLatin1Char('/') % fileName.mid(prefixSeparator + 1)); - if (engine && (engine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::ExistsFlag)) { - return engine; - } - delete engine; - } - - break; - } - - // There's no need to fully validate the prefix here. Consulting the - // unicode tables could be expensive and validation is already - // performed in QDir::setSearchPaths. - // - // if (!ch.isLetterOrNumber()) - // break; - } + QFileSystemEntry entry(fileName); + QFileSystemMetaData metaData; + QAbstractFileEngine *engine = QFileSystemEngine::resolveEntryAndCreateLegacyEngine(entry, metaData); + +#ifndef QT_NO_FSFILEENGINE + if (!engine) + // fall back to regular file engine + return new QFSFileEngine(entry.filePath()); #endif -#ifdef QT_NO_FSFILEENGINE - return 0; -#else - // fall back to regular file engine - return new QFSFileEngine(fileName); -#endif + return engine; } /*! diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index 04e53ce..a6c226e 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -42,6 +42,12 @@ #include "qfilesystemengine_p.h" #include #include +#include +#ifdef QT_BUILD_CORE_LIB +#include +#endif + +QT_BEGIN_NAMESPACE /*! \internal @@ -111,3 +117,84 @@ QString QFileSystemEngine::slowCanonicalized(const QString &path) return QDir::cleanPath(tmpPath); } +static bool _q_resolveEntryAndCreateLegacyEngine_recursive(QFileSystemEntry &entry, QFileSystemMetaData &data, + QAbstractFileEngine *&engine) +{ + QString const &filePath = entry.filePath(); + if ((engine = qt_custom_file_engine_handler_create(filePath))) + return true; + +#if defined(QT_BUILD_CORE_LIB) + for (int prefixSeparator = 0; prefixSeparator < filePath.size(); ++prefixSeparator) { + QChar const ch = filePath[prefixSeparator]; + if (ch == QLatin1Char('/')) + break; + + if (ch == QLatin1Char(':')) { + if (prefixSeparator == 0) { + engine = new QResourceFileEngine(filePath); + return true; + } + + if (prefixSeparator == 1) + break; + + const QStringList &paths = QDir::searchPaths(filePath.left(prefixSeparator)); + for (int i = 0; i < paths.count(); i++) { + entry = QFileSystemEntry(paths.at(i) % QLatin1Char('/') % filePath.mid(prefixSeparator + 1)); + // Recurse! + if (_q_resolveEntryAndCreateLegacyEngine_recursive(entry, data, engine)) { + // FIXME: This will over-stat if we recurse + if (engine) { + if (engine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::ExistsFlag) + return true; + delete engine; + engine = 0; + } else if (QFileSystemEngine::fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute) + && data.exists()) { + return true; + } + } + } + + // entry may have been clobbered at this point. + return false; + } + + // There's no need to fully validate the prefix here. Consulting the + // unicode tables could be expensive and validation is already + // performed in QDir::setSearchPaths. + // + // if (!ch.isLetterOrNumber()) + // break; + } +#endif // defined(QT_BUILD_CORE_LIB) + + return true; +} + +/*! + \internal + + Resolves the \a entry (see QDir::searchPaths) and returns an engine for + it, but never a QFSFileEngine. + + \returns a file engine that can be used to access the entry. Returns 0 if + QFileSystemEngine API should be used to query and interact with the file + system object. +*/ +QAbstractFileEngine *QFileSystemEngine::resolveEntryAndCreateLegacyEngine( + QFileSystemEntry &entry, QFileSystemMetaData &data) { + QFileSystemEntry copy = entry; + QAbstractFileEngine *engine = 0; + + if (_q_resolveEntryAndCreateLegacyEngine_recursive(copy, data, engine)) + // Reset entry to resolved copy. + entry = copy; + else + data.clear(); + + return engine; +} + +QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 182ccd6..990a5ff 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -88,6 +88,8 @@ public: static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QFileSystemMetaData *data = 0); + static QAbstractFileEngine *resolveEntryAndCreateLegacyEngine(QFileSystemEntry &entry, + QFileSystemMetaData &data); private: static QString slowCanonicalized(const QString &path); }; -- cgit v0.12 From d1e1f1e83142f18d75c323b44a094d4df6762a3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 6 Sep 2010 10:42:02 +0200 Subject: Fix over-stating in QAbstractFileEngine::create With recursive entry resolution, we might end up querying the engine for an entry once per recursion level. There was also the possibility that stale data would remain in the meta data instance. When resolving an entry, we now check for its existence at the leaf level and handle clean-up right away. Reviewed-by: Thomas Zander --- src/corelib/io/qfilesystemengine.cpp | 48 ++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index a6c226e..8f5b98a 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -117,12 +117,38 @@ QString QFileSystemEngine::slowCanonicalized(const QString &path) return QDir::cleanPath(tmpPath); } +static inline bool _q_checkEntry(QFileSystemEntry &entry, QFileSystemMetaData &data, bool resolvingEntry) +{ + if (resolvingEntry) { + if (!QFileSystemEngine::fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute) + || !data.exists()) { + data.clear(); + return false; + } + } + + return true; +} + +static inline bool _q_checkEntry(QAbstractFileEngine *&engine, bool resolvingEntry) +{ + if (resolvingEntry) { + if (!engine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::ExistsFlag) { + delete engine; + engine = 0; + return false; + } + } + + return true; +} + static bool _q_resolveEntryAndCreateLegacyEngine_recursive(QFileSystemEntry &entry, QFileSystemMetaData &data, - QAbstractFileEngine *&engine) + QAbstractFileEngine *&engine, bool resolvingEntry = false) { QString const &filePath = entry.filePath(); if ((engine = qt_custom_file_engine_handler_create(filePath))) - return true; + return _q_checkEntry(engine, resolvingEntry); #if defined(QT_BUILD_CORE_LIB) for (int prefixSeparator = 0; prefixSeparator < filePath.size(); ++prefixSeparator) { @@ -133,7 +159,7 @@ static bool _q_resolveEntryAndCreateLegacyEngine_recursive(QFileSystemEntry &ent if (ch == QLatin1Char(':')) { if (prefixSeparator == 0) { engine = new QResourceFileEngine(filePath); - return true; + return _q_checkEntry(engine, resolvingEntry); } if (prefixSeparator == 1) @@ -143,18 +169,8 @@ static bool _q_resolveEntryAndCreateLegacyEngine_recursive(QFileSystemEntry &ent for (int i = 0; i < paths.count(); i++) { entry = QFileSystemEntry(paths.at(i) % QLatin1Char('/') % filePath.mid(prefixSeparator + 1)); // Recurse! - if (_q_resolveEntryAndCreateLegacyEngine_recursive(entry, data, engine)) { - // FIXME: This will over-stat if we recurse - if (engine) { - if (engine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::ExistsFlag) - return true; - delete engine; - engine = 0; - } else if (QFileSystemEngine::fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute) - && data.exists()) { - return true; - } - } + if (_q_resolveEntryAndCreateLegacyEngine_recursive(entry, data, engine, true)) + return true; } // entry may have been clobbered at this point. @@ -170,7 +186,7 @@ static bool _q_resolveEntryAndCreateLegacyEngine_recursive(QFileSystemEntry &ent } #endif // defined(QT_BUILD_CORE_LIB) - return true; + return _q_checkEntry(entry, data, resolvingEntry); } /*! -- cgit v0.12 From 8f6f2adc2a8eee620bfe342f211035948a3fedc8 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Fri, 3 Sep 2010 15:27:58 +0200 Subject: Move resolving a symlink to the qfilesystemengine_unix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemengine_p.h | 2 +- src/corelib/io/qfilesystemengine_unix.cpp | 74 ++++++++++++++++++++++++++++++- src/corelib/io/qfilesystemengine_win.cpp | 2 +- src/corelib/io/qfsfileengine_unix.cpp | 70 +---------------------------- 4 files changed, 76 insertions(+), 72 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 990a5ff..94fb4e5 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -64,7 +64,7 @@ class QFileSystemEngine public: static bool isCaseSensitive(); - static QFileSystemEntry getLinkTarget(const QFileSystemEntry &link); + static QFileSystemEntry getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data); static QFileSystemEntry canonicalName(const QFileSystemEntry &entry); static QFileSystemEntry absoluteName(const QFileSystemEntry &entry); diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 6b3c157..755298d 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -163,9 +163,79 @@ bool QFileSystemEngine::isCaseSensitive() } //static -QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link) +QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) { - return link; // TODO implement +#if defined(__GLIBC__) && !defined(PATH_MAX) +#define PATH_CHUNK_SIZE 256 + char *s = 0; + int len = -1; + int size = PATH_CHUNK_SIZE; + + while (1) { + s = (char *) ::realloc(s, size); + Q_CHECK_PTR(s); + len = ::readlink(link.nativeFilePath().constData(), s, size); + if (len < 0) { + ::free(s); + break; + } + if (len < size) { + break; + } + size *= 2; + } +#else + char s[PATH_MAX+1]; + int len = readlink(link.nativeFilePath().constData(), s, PATH_MAX); +#endif + if (len > 0) { + QString ret; + if (!data.hasFlags(QFileSystemMetaData::DirectoryType)) + fillMetaData(link, data, QFileSystemMetaData::DirectoryType); + if (data.isDirectory() && s[0] != '/') { + QDir parent(link.filePath()); + parent.cdUp(); + ret = parent.path(); + if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) + ret += QLatin1Char('/'); + } + s[len] = '\0'; + ret += QFile::decodeName(QByteArray(s)); +#if defined(__GLIBC__) && !defined(PATH_MAX) + ::free(s); +#endif + + if (!ret.startsWith(QLatin1Char('/'))) { + if (link.filePath().startsWith(QLatin1Char('/'))) { + ret.prepend(link.filePath().left(link.filePath().lastIndexOf(QLatin1Char('/'))) + + QLatin1Char('/')); + } else { + ret.prepend(QDir::currentPath() + QLatin1Char('/')); + } + } + ret = QDir::cleanPath(ret); + if (ret.size() > 1 && ret.endsWith(QLatin1Char('/'))) + ret.chop(1); + return QFileSystemEntry(ret); + } +#if !defined(QWS) && defined(Q_OS_MAC) + { + FSRef fref; + if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(link.filePath())).data(), &fref, 0) == noErr) { + // TODO get the meta data info from the QFileSystemMetaData object + Boolean isAlias, isFolder; + if (FSResolveAliasFile(&fref, true, &isFolder, &isAlias) == noErr && isAlias) { + AliasHandle alias; + if (FSNewAlias(0, &fref, &alias) == noErr && alias) { + QCFString cfstr; + if (FSCopyAliasInfo(alias, 0, 0, &cfstr, 0, 0) == noErr) + return QFileSystemEntry(QCFString::toQString(cfstr)); + } + } + } + } +#endif + return QFileSystemEntry(); } //static diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index ef47fe5..8572506 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -49,7 +49,7 @@ bool QFileSystemEngine::isCaseSensitive() } //static -QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link) +QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) { return link; // TODO implement } diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 71a604a..c7df5ed 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -861,75 +861,9 @@ QString QFSFileEngine::fileName(FileName file) const return entry.filePath(); } else if (file == LinkName) { if (d->isSymlink()) { -#if defined(__GLIBC__) && !defined(PATH_MAX) -#define PATH_CHUNK_SIZE 256 - char *s = 0; - int len = -1; - int size = PATH_CHUNK_SIZE; - - while (1) { - s = (char *) ::realloc(s, size); - Q_CHECK_PTR(s); - len = ::readlink(d->fileEntry.nativeFilePath().constData(), s, size); - if (len < 0) { - ::free(s); - break; - } - if (len < size) { - break; - } - size *= 2; - } -#else - char s[PATH_MAX+1]; - int len = readlink(d->fileEntry.nativeFilePath().constData(), s, PATH_MAX); -#endif - if (len > 0) { - QString ret; - if (d->doStat(QFileSystemMetaData::DirectoryType) - && d->metaData.isDirectory() && s[0] != '/') { - QDir parent(d->fileEntry.filePath()); - parent.cdUp(); - ret = parent.path(); - if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) - ret += QLatin1Char('/'); - } - s[len] = '\0'; - ret += QFile::decodeName(QByteArray(s)); -#if defined(__GLIBC__) && !defined(PATH_MAX) - ::free(s); -#endif - - if (!ret.startsWith(QLatin1Char('/'))) { - if (d->fileEntry.filePath().startsWith(QLatin1Char('/'))) { - ret.prepend(d->fileEntry.filePath().left(d->fileEntry.filePath().lastIndexOf(QLatin1Char('/'))) - + QLatin1Char('/')); - } else { - ret.prepend(QDir::currentPath() + QLatin1Char('/')); - } - } - ret = QDir::cleanPath(ret); - if (ret.size() > 1 && ret.endsWith(QLatin1Char('/'))) - ret.chop(1); - return ret; - } + QFileSystemEntry entry = QFileSystemEngine::getLinkTarget(d->fileEntry, d->metaData); + return entry.filePath(); } -#if !defined(QWS) && defined(Q_OS_MAC) - { - FSRef fref; - if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->fileEntry.filePath())).data(), &fref, 0) == noErr) { - Boolean isAlias, isFolder; - if (FSResolveAliasFile(&fref, true, &isFolder, &isAlias) == noErr && isAlias) { - AliasHandle alias; - if (FSNewAlias(0, &fref, &alias) == noErr && alias) { - QCFString cfstr; - if (FSCopyAliasInfo(alias, 0, 0, &cfstr, 0, 0) == noErr) - return QCFString::toQString(cfstr); - } - } - } - } -#endif return QString(); } return d->fileEntry.filePath(); -- cgit v0.12 From 309f0d3d1f4bcc42249e738bae544750fe8cdb6a Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 7 Sep 2010 11:11:29 +0100 Subject: Helper functions for converting Symbian OS TTime convert to/from QDateTime convert to/from time_t These functions are required for dealing with timestamps in native files, however they are generally useful for Qt/Symbian port as well. Reviewed-By: joao --- src/corelib/tools/qdatetime.cpp | 35 +++++++++++++++++++++++++++++++++++ src/corelib/tools/qdatetime_p.h | 6 ++++++ 2 files changed, 41 insertions(+) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index ab7530d..f21aa2e 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -5837,6 +5837,41 @@ bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::S return (s1.type == s2.type) && (s1.pos == s2.pos) && (s1.count == s2.count); } +#ifdef Q_OS_SYMBIAN +const static TTime UnixEpochOffset(I64LIT(0xdcddb30f2f8000)); +const static TInt64 MinimumMillisecondTime(KMinTInt64 / 1000); +const static TInt64 MaximumMillisecondTime(KMaxTInt64 / 1000); +QDateTime qt_symbian_TTime_To_QDateTime(const TTime& time) +{ + TTimeIntervalMicroSeconds absolute = time.MicroSecondsFrom(UnixEpochOffset); + + return QDateTime::fromMSecsSinceEpoch(absolute.Int64() / 1000); +} + +TTime qt_symbian_QDateTime_To_TTime(const QDateTime& datetime) +{ + qint64 absolute = datetime.toMSecsSinceEpoch(); + if(absolute > MaximumMillisecondTime) + return TTime(KMaxTInt64); + if(absolute < MinimumMillisecondTime) + return TTime(KMinTInt64); + return TTime(absolute * 1000); +} + +time_t qt_symbian_TTime_To_time_t(const TTime& time) +{ + TTimeIntervalSeconds interval; + TInt err = time.SecondsFrom(UnixEpochOffset, interval); + if (err || interval.Int() < 0) + return (time_t) 0; + return (time_t) interval.Int(); +} + +TTime qt_symbian_time_t_To_TTime(time_t time) +{ + return UnixEpochOffset + TTimeIntervalSeconds(time); +} +#endif //Q_OS_SYMBIAN #endif // QT_BOOTSTRAPPED diff --git a/src/corelib/tools/qdatetime_p.h b/src/corelib/tools/qdatetime_p.h index f10785e..8355ef7 100644 --- a/src/corelib/tools/qdatetime_p.h +++ b/src/corelib/tools/qdatetime_p.h @@ -275,6 +275,12 @@ Q_CORE_EXPORT bool operator==(const QDateTimeParser::SectionNode &s1, const QDat Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeParser::Sections) Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeParser::FieldInfo) +#ifdef Q_OS_SYMBIAN +QDateTime qt_symbian_TTime_To_QDateTime(const TTime& time); +TTime qt_symbian_QDateTime_To_TTime(const QDateTime& datetime); +time_t qt_symbian_TTime_To_time_t(const TTime& time); +TTime qt_symbian_time_t_To_TTime(time_t time); +#endif //Q_OS_SYMBIAN #endif // QT_BOOTSTRAPPED -- cgit v0.12 From a6611da5a67f2689586fd9367405dec2429f9cde Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 7 Sep 2010 11:50:51 +0100 Subject: Symbian OS implementation for QFileSystemMetaData There are three possible sources for metadata: RFs::Entry() - for files or directories in the filesystem (except roots) RFs::Volume() - for mounted drives (used for root directory) ::fstat() - for Open C file handles adopted via QFile::open(int, OpenMode) As a result of the ::fstat requirement, the code dealing with stat buffers is moved from qfilesystemengine_unix.cpp to the common qfilesystemengine.cpp Reviewed-By: joao --- src/corelib/io/qfilesystemengine.cpp | 72 +++++++++++++++++++++++++++ src/corelib/io/qfilesystemengine_symbian.cpp | 74 ++++++++++++++++++++++++++-- src/corelib/io/qfilesystemengine_unix.cpp | 63 ----------------------- src/corelib/io/qfilesystemmetadata_p.h | 46 ++++++++++++++++- 4 files changed, 187 insertions(+), 68 deletions(-) diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index 8f5b98a..0563a15 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -213,4 +213,76 @@ QAbstractFileEngine *QFileSystemEngine::resolveEntryAndCreateLegacyEngine( return engine; } +//these unix functions are in this file, because they are shared by symbian port +//for open C file handles. +#ifdef Q_OS_UNIX +//static +bool QFileSystemEngine::fillMetaData(int fd, QFileSystemMetaData &data) +{ + data.entryFlags &= ~QFileSystemMetaData::PosixStatFlags; + data.knownFlagsMask |= QFileSystemMetaData::PosixStatFlags; + + QT_STATBUF statBuffer; + if (QT_FSTAT(fd, &statBuffer) == 0) { + data.fillFromStatBuf(statBuffer); + return true; + } + + return false; +} + +void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) +{ + // Permissions + if (statBuffer.st_mode & S_IRUSR) + entryFlags |= QFileSystemMetaData::OwnerReadPermission; + if (statBuffer.st_mode & S_IWUSR) + entryFlags |= QFileSystemMetaData::OwnerWritePermission; + if (statBuffer.st_mode & S_IXUSR) + entryFlags |= QFileSystemMetaData::OwnerExecutePermission; + + if (statBuffer.st_mode & S_IRGRP) + entryFlags |= QFileSystemMetaData::GroupReadPermission; + if (statBuffer.st_mode & S_IWGRP) + entryFlags |= QFileSystemMetaData::GroupWritePermission; + if (statBuffer.st_mode & S_IXGRP) + entryFlags |= QFileSystemMetaData::GroupExecutePermission; + + if (statBuffer.st_mode & S_IROTH) + entryFlags |= QFileSystemMetaData::OtherReadPermission; + if (statBuffer.st_mode & S_IWOTH) + entryFlags |= QFileSystemMetaData::OtherWritePermission; + if (statBuffer.st_mode & S_IXOTH) + entryFlags |= QFileSystemMetaData::OtherExecutePermission; + + // Type + if ((statBuffer.st_mode & S_IFMT) == S_IFREG) + entryFlags |= QFileSystemMetaData::FileType; + else if ((statBuffer.st_mode & S_IFMT) == S_IFDIR) + entryFlags |= QFileSystemMetaData::DirectoryType; + else + entryFlags |= QFileSystemMetaData::SequentialType; + + // Attributes + entryFlags |= QFileSystemMetaData::ExistsAttribute; + size_ = statBuffer.st_size; +#if !defined(QWS) && defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if (statBuffer.st_flags & UF_HIDDEN) { + entryFlags |= QFileSystemMetaData::HiddenAttribute; + knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; + } +#endif + + // Times +#ifdef Q_OS_SYMBIAN + modificationTime_ = qt_symbian_time_t_To_TTime(statBuffer.st_mtime); +#else + creationTime_ = statBuffer.st_ctime ? statBuffer.st_ctime : statBuffer.st_mtime; + modificationTime_ = statBuffer.st_mtime; + accessTime_ = statBuffer.st_atime; +#endif +} + +#endif + QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 2798bdf..19f149a 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -108,13 +108,76 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) //static QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) { - return QString(); // TODO implement; + Q_UNUSED(entry); + return QString(); +} + +void QFileSystemMetaData::fillFromTEntry(const TEntry& entry) +{ + //Symbian doesn't have unix type file permissions + entryFlags |= QFileSystemMetaData::Permissions; + if(entry.IsReadOnly()) { + entryFlags &= ~(QFileSystemMetaData::WritePermissions); + } + //set the type + if(entry.IsDir()) + entryFlags |= QFileSystemMetaData::DirectoryType; + else + entryFlags |= QFileSystemMetaData::FileType; + + //set the attributes + entryFlags |= QFileSystemMetaData::ExistsAttribute; + if(entry.IsHidden()) + entryFlags |= QFileSystemMetaData::HiddenAttribute; + +#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API + size_ = entry.FileSize(); +#else + size_ = (TUint)(entry.iSize); +#endif + + modificationTime_ = entry.iModified; +} + +void QFileSystemMetaData::fillFromVolumeInfo(const TVolumeInfo& info) +{ + entryFlags |= QFileSystemMetaData::ExistsAttribute; + entryFlags |= QFileSystemMetaData::Permissions; + if(info.iDrive.iDriveAtt & KDriveAttRom) { + entryFlags &= ~(QFileSystemMetaData::WritePermissions); + } + entryFlags |= QFileSystemMetaData::DirectoryType; + size_ = info.iSize; + modificationTime_ = qt_symbian_time_t_To_TTime(0); } //static bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) { - return false; // TODO implement; + if (what & QFileSystemMetaData::SymbianTEntryFlags) { + RFs& fs(qt_s60GetRFs()); + TInt err; + data.entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags); + if (entry.isRoot()) { + //Root directories don't have an entry, and Entry() returns KErrBadName. + //Therefore get information about the volume instead. + TInt drive; + err = RFs::CharToDrive(TChar(entry.nativeFilePath().at(0).unicode()), drive); + if (!err) { + TVolumeInfo info; + err = fs.Volume(info, drive); + if (!err) + data.fillFromVolumeInfo(info); + } + } else { + TEntry ent; + err = fs.Entry(qt_QString2TPtrC(absoluteName(entry).nativeFilePath()), ent); + if (!err) + data.fillFromTEntry(ent); + } + data.knownFlagsMask |= QFileSystemMetaData::SymbianTEntryFlags; + } + return data.hasFlags(what); } //static @@ -207,7 +270,12 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per else setmask = KEntryAttReadOnly; TInt err = fs.SetAtt(qt_QString2TPtrC(targetpath), setmask, clearmask); - return err != KErrNone; // TODO error reporting, metadata update; + if (data && !err) { + data->entryFlags &= ~QFileSystemMetaData::Permissions; + data->entryFlags |= QFileSystemMetaData::MetaDataFlag(uint(permissions)); + data->knownFlagsMask |= QFileSystemMetaData::Permissions; + } + return err != KErrNone; // TODO error reporting } QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 755298d..f26a8c0 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -105,54 +105,6 @@ static inline bool _q_isMacHidden(const char *nativePath) } #endif -void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) -{ - // Permissions - if (statBuffer.st_mode & S_IRUSR) - entryFlags |= QFileSystemMetaData::OwnerReadPermission; - if (statBuffer.st_mode & S_IWUSR) - entryFlags |= QFileSystemMetaData::OwnerWritePermission; - if (statBuffer.st_mode & S_IXUSR) - entryFlags |= QFileSystemMetaData::OwnerExecutePermission; - - if (statBuffer.st_mode & S_IRGRP) - entryFlags |= QFileSystemMetaData::GroupReadPermission; - if (statBuffer.st_mode & S_IWGRP) - entryFlags |= QFileSystemMetaData::GroupWritePermission; - if (statBuffer.st_mode & S_IXGRP) - entryFlags |= QFileSystemMetaData::GroupExecutePermission; - - if (statBuffer.st_mode & S_IROTH) - entryFlags |= QFileSystemMetaData::OtherReadPermission; - if (statBuffer.st_mode & S_IWOTH) - entryFlags |= QFileSystemMetaData::OtherWritePermission; - if (statBuffer.st_mode & S_IXOTH) - entryFlags |= QFileSystemMetaData::OtherExecutePermission; - - // Type - if ((statBuffer.st_mode & S_IFMT) == S_IFREG) - entryFlags |= QFileSystemMetaData::FileType; - else if ((statBuffer.st_mode & S_IFMT) == S_IFDIR) - entryFlags |= QFileSystemMetaData::DirectoryType; - else - entryFlags |= QFileSystemMetaData::SequentialType; - - // Attributes - entryFlags |= QFileSystemMetaData::ExistsAttribute; - size_ = statBuffer.st_size; -#if !defined(QWS) && defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - if (statBuffer.st_flags & UF_HIDDEN) { - entryFlags |= QFileSystemMetaData::HiddenAttribute; - knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; - } -#endif - - // Times - creationTime_ = statBuffer.st_ctime ? statBuffer.st_ctime : statBuffer.st_mtime; - modificationTime_ = statBuffer.st_mtime; - accessTime_ = statBuffer.st_atime; -} - bool QFileSystemEngine::isCaseSensitive() { #if defined(Q_OS_SYMBIAN) @@ -329,21 +281,6 @@ QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) } //static -bool QFileSystemEngine::fillMetaData(int fd, QFileSystemMetaData &data) -{ - data.entryFlags &= ~QFileSystemMetaData::PosixStatFlags; - data.knownFlagsMask |= QFileSystemMetaData::PosixStatFlags; - - QT_STATBUF statBuffer; - if (QT_FSTAT(fd, &statBuffer) == 0) { - data.fillFromStatBuf(statBuffer); - return true; - } - - return false; -} - -//static bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) { diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 5914eb3..f140319 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -60,6 +60,9 @@ // Platform-specific includes #if defined(Q_OS_WIN) +#elif defined(Q_OS_SYMBIAN) +#include +#include "qdatetime_p.h" #else #endif @@ -86,10 +89,18 @@ struct QFileSystemMetaData UserPermissions = UserReadPermission | UserWritePermission | UserExecutePermission, OwnerPermissions = OwnerReadPermission | OwnerWritePermission | OwnerExecutePermission, + ReadPermissions = OtherReadPermission | GroupReadPermission | UserReadPermission | OwnerReadPermission, + WritePermissions = OtherWritePermission | GroupWritePermission | UserWritePermission | OwnerWritePermission, + ExecutePermissions = OtherExecutePermission | GroupExecutePermission | UserExecutePermission | OwnerExecutePermission, + Permissions = OtherPermissions | GroupPermissions | UserPermissions | OwnerPermissions, // Type +#ifdef Q_OS_SYMBIAN + LinkType = 0, +#else LinkType = 0x00010000, +#endif FileType = 0x00020000, DirectoryType = 0x00040000, #if !defined(QWS) && defined(Q_OS_MAC) @@ -137,6 +148,13 @@ struct QFileSystemMetaData | QFileSystemMetaData::Times | QFileSystemMetaData::OwnerIds, + SymbianTEntryFlags = QFileSystemMetaData::Permissions + | QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::SequentialType + | QFileSystemMetaData::Attributes + | QFileSystemMetaData::Times, + AllMetaDataFlags = 0xFFFFFFFF }; @@ -181,7 +199,7 @@ struct QFileSystemMetaData QFile::Permissions permissions() const { return QFile::Permissions(Permissions & entryFlags); } -#if defined(Q_OS_UNIX) +#if defined(Q_OS_UNIX) && !defined (Q_OS_SYMBIAN) QDateTime creationTime() const { return QDateTime::fromTime_t(creationTime_); } QDateTime modificationTime() const { return QDateTime::fromTime_t(modificationTime_); } QDateTime accessTime() const { return QDateTime::fromTime_t(accessTime_); } @@ -213,9 +231,31 @@ struct QFileSystemMetaData else return groupId(); } - +#endif +#ifdef Q_OS_UNIX void fillFromStatBuf(const QT_STATBUF &statBuffer); #endif +#ifdef Q_OS_SYMBIAN + QDateTime creationTime() const { return modificationTime(); } + QDateTime modificationTime() const { return qt_symbian_TTime_To_QDateTime(modificationTime_); } + QDateTime accessTime() const { return modificationTime(); } + + QDateTime fileTime(QAbstractFileEngine::FileTime time) const + { + Q_UNUSED(time); + return modificationTime(); + } + uint userId() const { return (uint) -2; } + uint groupId() const { return (uint) -2; } + uint ownerId(QAbstractFileEngine::FileOwner owner) const + { + Q_UNUSED(owner); + return (uint) -2; + } + + void fillFromTEntry(const TEntry& entry); + void fillFromVolumeInfo(const TVolumeInfo& info); +#endif private: friend class QFileSystemEngine; @@ -227,6 +267,8 @@ private: // Platform-specific data goes here: #if defined(Q_OS_WIN) +#elif defined(Q_OS_SYMBIAN) + TTime modificationTime_; #else time_t creationTime_; time_t modificationTime_; -- cgit v0.12 From bbbe13b676d297f0f5bfb754cdfe5ff1848c67b7 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 7 Sep 2010 16:47:02 +0100 Subject: Add missing function parameter to implementation To fix compile error due to header changes upstream Reviewed-By: Trust Me --- src/corelib/io/qfilesystemengine_symbian.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 19f149a..45c3c10 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -53,7 +53,7 @@ bool QFileSystemEngine::isCaseSensitive() } //static -QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link) +QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) { return link; // TODO implement } -- cgit v0.12 From 0b662bd90347d152bf7371f1554e7bd2175704d8 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 8 Sep 2010 14:02:19 +0100 Subject: Implement QFileSystemEngine::absoluteName for symbian OS Updated this function so that it passes the QFileInfo autotests. Now deals with raw drives "x:" Drive relative paths "x:foo.txt" Absolute paths missing a drive letter "/sys" Dirty absolute paths "c:/bar/../foo" Reviewed-By: joao --- src/corelib/io/qfilesystemengine_symbian.cpp | 31 +++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 45c3c10..3638196 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -80,23 +80,40 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) //static QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) { - if (entry.isAbsolute()) + QString orig = entry.filePath(); + const bool needsDrive = (!orig.isEmpty() && orig.at(0).unicode() == '/'); + const bool isDriveLetter = (orig.size() == 2 && orig.at(1).unicode() == ':'); + const bool isDriveRelative = (orig.size() > 2 && orig.at(1).unicode() == ':' && orig.at(2).unicode() != '/'); + const bool isDirty = (orig.contains(QLatin1String("/../")) || orig.contains(QLatin1String("/./")) || + orig.endsWith(QLatin1String("/..")) || orig.endsWith(QLatin1String("/."))); + const bool isAbsolute = entry.isAbsolute(); + if (isAbsolute && + !(needsDrive || isDriveLetter || isDriveRelative || isDirty)) return entry; - QString orig = entry.filePath(); QString result; - if (orig.isEmpty() || !orig.startsWith('/')) { + if (needsDrive || isDriveLetter || isDriveRelative || !isAbsolute || orig.isEmpty()) { QFileSystemEntry cur(QFSFileEngine::currentPath()); - result = cur.filePath(); + if(needsDrive) + result = cur.filePath().left(2); + else if(isDriveRelative && cur.filePath().at(0) != orig.at(0)) + result = orig.left(2); // for BC, see tst_QFileInfo::absolutePath(:my.dll) + else + result = cur.filePath(); + if(isDriveLetter) { + result[0] = orig.at(0); //copy drive letter + orig.clear(); + } + if(isDriveRelative) { + orig = orig.mid(2); //discard the drive specifier from orig + } } - if (!orig.isEmpty() && !(orig.length() == 1 && orig[0] == '.')) { + if (!orig.isEmpty() && !(orig.length() == 1 && orig.at(0).unicode() == '.')) { if (!result.isEmpty() && !result.endsWith('/')) result.append('/'); result.append(orig); } - if (result.length() == 1 && result[0] == '/') - return QFileSystemEntry(result); const bool isDir = result.endsWith('/'); result = QDir::cleanPath(result); -- cgit v0.12 From f906303e7aa9a7b68f469d81e6bdac8499120338 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 8 Sep 2010 14:08:13 +0100 Subject: Disable tst_qfileinfo symlink tests on symbian Reviewed-By: joao --- tests/auto/qfileinfo/tst_qfileinfo.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 7659a75..9ec0572 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -72,6 +72,7 @@ #if defined(Q_OS_SYMBIAN) # define SRCDIR "" +# define NO_SYMLINKS #endif //TESTED_CLASS= @@ -1081,6 +1082,7 @@ void tst_QFileInfo::fileTimes_oldFile() void tst_QFileInfo::isSymLink_data() { +#ifndef NO_SYMLINKS QFile::remove("link.lnk"); QFile::remove("brokenlink.lnk"); QFile::remove("dummyfile"); @@ -1100,10 +1102,12 @@ void tst_QFileInfo::isSymLink_data() QTest::newRow("existent file") << SRCDIR "tst_qfileinfo.cpp" << false << ""; QTest::newRow("link") << "link.lnk" << true << QFileInfo(SRCDIR "tst_qfileinfo.cpp").absoluteFilePath(); QTest::newRow("broken link") << "brokenlink.lnk" << true << QFileInfo("dummyfile").absoluteFilePath(); +#endif } void tst_QFileInfo::isSymLink() { +#ifndef NO_SYMLINKS QFETCH(QString, path); QFETCH(bool, isSymLink); QFETCH(QString, linkTarget); @@ -1111,6 +1115,9 @@ void tst_QFileInfo::isSymLink() QFileInfo fi(path); QCOMPARE(fi.isSymLink(), isSymLink); QCOMPARE(fi.symLinkTarget(), linkTarget); +#else + QSKIP("no symbolic link support on this platform", SkipAll); +#endif } void tst_QFileInfo::isHidden_data() -- cgit v0.12 From e4de050cc8e819a2751f94ac0429a0d7fe64e64a Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 8 Sep 2010 15:15:45 +0100 Subject: Enable symbian IO code in the build This patch contains several changes that needed to be done atomically. The native file path im QFileSystemEntry is changed from 8 bit to 16 bit character set. QFsFileEngine has some new symbian specific code (as the unix code does not compile with the above change), and forwards more calls to the new QFileSystemEngine. Unix implementations of link, rename and remove are moved to the unix version of this class, so less ifdef'ing is needed. Finally, io.pri now selects the _symbian.cpp source files instead of the _unix.cpp equivalents when building for symbian. --- src/corelib/io/io.pri | 15 +- src/corelib/io/qfilesystemengine_unix.cpp | 8 +- src/corelib/io/qfilesystementry.cpp | 7 +- src/corelib/io/qfilesystementry_p.h | 6 +- src/corelib/io/qfsfileengine.cpp | 6 + src/corelib/io/qfsfileengine_p.h | 28 +++ src/corelib/io/qfsfileengine_unix.cpp | 343 +++++++++++++++++------------- 7 files changed, 250 insertions(+), 163 deletions(-) diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 7c3712e..4a20dfa 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -73,12 +73,17 @@ win32 { SOURCES += io/qfilesystemengine_win.cpp SOURCES += io/qfilesystemiterator_win.cpp } else:unix { - SOURCES += io/qfilesystemengine_unix.cpp - SOURCES += io/qfilesystemiterator_unix.cpp - SOURCES += io/qfsfileengine_unix.cpp SOURCES += io/qfsfileengine_iterator_unix.cpp - symbian:SOURCES += io/qprocess_symbian.cpp - else:SOURCES += io/qprocess_unix.cpp + SOURCES += io/qfsfileengine_unix.cpp + symbian { + SOURCES += io/qfilesystemengine_symbian.cpp + SOURCES += io/qprocess_symbian.cpp + SOURCES += io/qfilesystemiterator_symbian.cpp + } else { + SOURCES += io/qfilesystemengine_unix.cpp + SOURCES += io/qprocess_unix.cpp + SOURCES += io/qfilesystemiterator_unix.cpp + } macx-*: { HEADERS += io/qfilesystemwatcher_fsevents_p.h SOURCES += io/qfilesystemengine_mac.cpp diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index f26a8c0..8d77963 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -45,6 +45,8 @@ #include "qfsfileengine.h" #include // for realpath() +#include +#include #include #if defined(Q_OS_SYMBIAN) @@ -489,7 +491,7 @@ bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool remo //static bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target) { - return false; // TODO implement; + return (::symlink(source.nativeFilePath().constData(), target.nativeFilePath().constData()) == 0); } //static @@ -501,13 +503,13 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst //static bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target) { - return false; // TODO implement; + return (::rename(source.nativeFilePath().constData(), target.nativeFilePath().constData()) == 0); } //static bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry) { - return false; // TODO implement; + return (unlink(entry.nativeFilePath().constData()) == 0); } //static diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index c3ada48..f5009b4 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -121,7 +121,7 @@ QFileSystemEntry::NativePath QFileSystemEntry::nativeFilePath() const void QFileSystemEntry::resolveFilePath() const { if (m_filePath.isEmpty() && !m_nativeFilePath.isEmpty()) { -#ifdef Q_OS_WIN +#ifdef QFILESYSTEMENTRY_NATIVE_PATH_IS_UTF16 m_filePath = QDir::fromNativeSeparators(m_nativeFilePath); #else m_filePath = QDir::fromNativeSeparators(QFile::decodeName(m_nativeFilePath)); @@ -137,6 +137,8 @@ void QFileSystemEntry::resolveNativeFilePath() const if (isRelative()) filePath = fixIfRelativeUncPath(m_filePath); m_nativeFilePath = QFSFileEnginePrivate::longFileName(QDir::toNativeSeparators(filePath)); +#elif defined(QFILESYSTEMENTRY_NATIVE_PATH_IS_UTF16) + m_nativeFilePath = QDir::toNativeSeparators(m_filePath); #else m_nativeFilePath = QFile::encodeName(QDir::toNativeSeparators(m_filePath)); #endif @@ -199,11 +201,10 @@ bool QFileSystemEntry::isAbsolute() const return (!m_filePath.isEmpty() && (m_filePath[0].unicode() == '/') #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) || (m_filePath.length() >= 2 - && ((m_filePath[0].isLetter() && m_filePath[1] == QLatin1Char(':')) + && ((m_filePath[0].isLetter() && m_filePath[1].unicode() == ':') || (m_filePath.at(0) == QLatin1Char('/') && m_filePath.at(1) == QLatin1Char('/')))) #endif ); - } #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index 3786bb3..6b2cedd 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -56,13 +56,17 @@ #include #include +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) +#define QFILESYSTEMENTRY_NATIVE_PATH_IS_UTF16 +#endif + QT_BEGIN_NAMESPACE class QFileSystemEntry { public: -#ifndef Q_OS_WIN +#ifndef QFILESYSTEMENTRY_NATIVE_PATH_IS_UTF16 typedef QByteArray NativePath; #else typedef QString NativePath; diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 1b0a28c..089f1a1 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -364,6 +364,12 @@ bool QFSFileEnginePrivate::closeFdFh() if (closeFileHandle) { int ret; do { +#ifdef Q_OS_SYMBIAN + if (symbianFile.SubSessionHandle()) { + symbianFile.Close(); + ret = 0; + } else +#endif if (fh) { // Close buffered file. ret = fclose(fh) != 0 ? -1 : 0; diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 6e5f30e..a3733d8 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -60,6 +60,10 @@ #include #include +#ifdef Q_OS_SYMBIAN +#include +#endif + #ifndef QT_NO_FSFILEENGINE QT_BEGIN_NAMESPACE @@ -115,6 +119,30 @@ public: #endif FILE *fh; +#ifdef Q_OS_SYMBIAN +#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API + RFile64 symbianFile; + TInt64 symbianFilePos; +#else + RFile symbianFile; + + /** + * The cursor position in the underlying file. This differs + * from devicePos because the latter is updated on calls to + * writeData, even if no data was physically transferred to + * the file, but instead stored in the write buffer. + * + * iFilePos is updated on calls to RFile::Read and + * RFile::Write. It is also updated on calls to seek() but + * RFile::Seek is not called when that happens because + * Symbian supports positioned reads and writes, saving a file + * server call, and because Symbian does not support seeking + * past the end of a file. + */ + TInt symbianFilePos; +#endif +#endif + #ifdef Q_WS_WIN HANDLE fileHandle; HANDLE mapHandle; diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index c7df5ed..048aa1b 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -197,6 +197,90 @@ static inline bool setCloseOnExec(int fd) return fd != -1 && fcntl(fd, F_SETFD, FD_CLOEXEC) != -1; } +#ifdef Q_OS_SYMBIAN +/*! + \internal +*/ +bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) +{ + Q_Q(QFSFileEngine); + + fh = 0; + fd = -1; + + QString fn(QFileSystemEngine::absoluteName(fileEntry).nativeFilePath()); + RFs& fs = qt_s60GetRFs(); + + TUint symbianMode = 0; + + if(openMode & QIODevice::ReadOnly) + symbianMode |= EFileRead; + if(openMode & QIODevice::WriteOnly) + symbianMode |= EFileWrite; + if(openMode & QIODevice::Text) + symbianMode |= EFileStreamText; + + // pre Symbian 9.4, file I/O is always unbuffered, and the enum values don't exist + if(QSysInfo::symbianVersion() >= QSysInfo::SV_9_4) { + if (openMode & QFile::Unbuffered) { + if (openMode & QIODevice::WriteOnly) + symbianMode |= 0x00001000; //EFileWriteDirectIO; + if (openMode & QIODevice::ReadOnly) + symbianMode |= 0x00004000; //EFileReadDirectIO; + } else { + if (openMode & QIODevice::WriteOnly) + symbianMode |= 0x00000800; //EFileWriteBuffered; + // use implementation defaults for read buffering + } + } + + // Until Qt supports file sharing, we can't support EFileShareReadersOrWriters safely, + // but Qt does this on other platforms and autotests rely on it. + // The reason is that Unix locks are only advisory - the application needs to test the + // lock after opening the file. Symbian and Windows locks are mandatory - opening a + // locked file will fail. + symbianMode |= EFileShareReadersOrWriters; + + TInt r; + //note QIODevice::Truncate only has meaning for read/write access + //write-only files are always truncated unless append is specified + //reference openModeToOpenFlags in qfsfileengine_unix.cpp + if ((openMode & QIODevice::Truncate) || (!(openMode & QIODevice::ReadOnly) && !(openMode & QIODevice::Append))) { + r = symbianFile.Replace(fs, qt_QString2TPtrC(fn), symbianMode); + } else { + r = symbianFile.Open(fs, qt_QString2TPtrC(fn), symbianMode); + if (r == KErrNotFound && (openMode & QIODevice::WriteOnly)) { + r = symbianFile.Create(fs, qt_QString2TPtrC(fn), symbianMode); + } + } + + if (r == KErrNone) { +#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API + TInt64 size; +#else + TInt size; +#endif + r = symbianFile.Size(size); + if (r==KErrNone) { + if (openMode & QIODevice::Append) + symbianFilePos = size; + else + symbianFilePos = 0; + //TODO: port this (QFileSystemMetaData in open?) + //cachedSize = size; + } + } + + if (r != KErrNone) { + setSymbianError(r, QFile::OpenError, QLatin1String("open error")); + symbianFile.Close(); + return false; + } + + closeFileHandle = true; + return true; +} +#else /*! \internal */ @@ -293,6 +377,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) closeFileHandle = true; return true; } +#endif /*! \internal @@ -423,61 +508,64 @@ bool QFSFileEnginePrivate::nativeIsSequential() const bool QFSFileEngine::remove() { Q_D(QFSFileEngine); - bool ret = unlink(d->fileEntry.nativeFilePath().constData()) == 0; - if (!ret) + bool ret = QFileSystemEngine::removeFile(d->fileEntry); + if (!ret) { +#ifdef Q_OS_SYMBIAN + //TODO: error reporting + d->setSymbianError(KErrGeneral, QFile::RemoveError, QLatin1String("remove error")); +#else setError(QFile::RemoveError, qt_error_string(errno)); +#endif + } return ret; } bool QFSFileEngine::copy(const QString &newName) { -#if defined(Q_OS_SYMBIAN) Q_D(QFSFileEngine); - RFs rfs = qt_s60GetRFs(); - CFileMan* fm = NULL; - QString oldNative(QDir::toNativeSeparators(d->fileEntry.filePath())); - TPtrC oldPtr(qt_QString2TPtrC(oldNative)); - QFileInfo fi(newName); - QString absoluteNewName = fi.absoluteFilePath(); - QString newNative(QDir::toNativeSeparators(absoluteNewName)); - TPtrC newPtr(qt_QString2TPtrC(newNative)); - TRAPD (err, - fm = CFileMan::NewL(rfs); - RFile rfile; - err = rfile.Open(rfs, oldPtr, EFileShareReadersOrWriters); - if (err == KErrNone) { - err = fm->Copy(rfile, newPtr); - rfile.Close(); - } - ) // End TRAP - delete fm; - if (err == KErrNone) - return true; - d->setSymbianError(err, QFile::CopyError, QLatin1String("copy error")); - return false; + bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(newName)); + if (!ret) { +#ifdef Q_OS_SYMBIAN + //TODO: error reporting + d->setSymbianError(KErrGeneral, QFile::CopyError, QLatin1String("copy error")); #else - Q_UNUSED(newName); - // ### Add copy code for Unix here - setError(QFile::UnspecifiedError, QLatin1String("Not implemented!")); - return false; + // ### Add copy code for Unix to the filesystem engine + setError(QFile::UnspecifiedError, QLatin1String("Not implemented!")); + //setError(QFile::CopyError, qt_error_string(errno)); #endif + } + return ret; } bool QFSFileEngine::rename(const QString &newName) { Q_D(QFSFileEngine); - bool ret = ::rename(d->fileEntry.nativeFilePath().constData(), QFile::encodeName(newName).constData()) == 0; - if (!ret) + bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName)); + + if (!ret) { +#ifdef Q_OS_SYMBIAN + //TODO: error reporting + d->setSymbianError(KErrGeneral, QFile::RenameError, QLatin1String("rename error")); +#else setError(QFile::RenameError, qt_error_string(errno)); +#endif + } + return ret; } bool QFSFileEngine::link(const QString &newName) { Q_D(QFSFileEngine); - bool ret = ::symlink(d->fileEntry.nativeFilePath().constData(), QFile::encodeName(newName).constData()) == 0; - if (!ret) + bool ret = QFileSystemEngine::createLink(d->fileEntry, QFileSystemEntry(newName)); + if (!ret) { +#ifdef Q_OS_SYMBIAN + //TODO: error reporting + d->setSymbianError(KErrNotSupported, QFile::RenameError, QLatin1String("not supported")); +#else setError(QFile::RenameError, qt_error_string(errno)); +#endif + } return ret; } @@ -722,123 +810,6 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const return ret; } -#if defined(Q_OS_SYMBIAN) -QString QFSFileEngine::fileName(FileName file) const -{ - Q_D(const QFSFileEngine); - const QLatin1Char slashChar('/'); - if(file == BaseName) { - int slash = d->fileEntry.filePath().lastIndexOf(slashChar); - if(slash == -1) { - int colon = d->fileEntry.filePath().lastIndexOf(QLatin1Char(':')); - if(colon != -1) - return d->fileEntry.filePath().mid(colon + 1); - return d->fileEntry.filePath(); - } - return d->fileEntry.filePath().mid(slash + 1); - } else if(file == PathName) { - if(!d->fileEntry.filePath().size()) - return d->fileEntry.filePath(); - - int slash = d->fileEntry.filePath().lastIndexOf(slashChar); - if(slash == -1) { - if(d->fileEntry.filePath().length() >= 2 && d->fileEntry.filePath().at(1) == QLatin1Char(':')) - return d->fileEntry.filePath().left(2); - return QLatin1String("."); - } else { - if(!slash) - return QLatin1String("/"); - if(slash == 2 && d->fileEntry.filePath().length() >= 2 && d->fileEntry.filePath().at(1) == QLatin1Char(':')) - slash++; - return d->fileEntry.filePath().left(slash); - } - } else if(file == AbsoluteName || file == AbsolutePathName) { - QString ret; - if (!isRelativePathSymbian(d->fileEntry.filePath())) { - if (d->fileEntry.filePath().size() > 2 && d->fileEntry.filePath().at(1) == QLatin1Char(':') - && d->fileEntry.filePath().at(2) != slashChar){ - // It's a drive-relative path, so C:a.txt -> C:/currentpath/a.txt, - // or if it's different drive than current, Z:a.txt -> Z:/a.txt - QString currentPath = QDir::currentPath(); - if (0 == currentPath.left(1).compare(d->fileEntry.filePath().left(1), Qt::CaseInsensitive)) - ret = currentPath + slashChar + d->fileEntry.filePath().mid(2); - else - ret = d->fileEntry.filePath().left(2) + slashChar + d->fileEntry.filePath().mid(2); - } else if (d->fileEntry.filePath().startsWith(slashChar)) { - // It's a absolute path to the current drive, so /a.txt -> C:/a.txt - ret = QDir::currentPath().left(2) + d->fileEntry.filePath(); - } else { - ret = d->fileEntry.filePath(); - } - } else { - ret = QDir::currentPath() + slashChar + d->fileEntry.filePath(); - } - - // The path should be absolute at this point. - // From the docs : - // Absolute paths begin with the directory separator "/" - // (optionally preceded by a drive specification under Windows). - if (ret.at(0) != slashChar) { - Q_ASSERT(ret.length() >= 2); - Q_ASSERT(ret.at(0).isLetter()); - Q_ASSERT(ret.at(1) == QLatin1Char(':')); - - // Force uppercase drive letters. - ret[0] = ret.at(0).toUpper(); - } - - // Clean up the path - bool isDir = ret.endsWith(slashChar); - ret = QDir::cleanPath(ret); - if (isDir && !ret.endsWith(slashChar)) - ret += slashChar; - - if (file == AbsolutePathName) { - int slash = ret.lastIndexOf(slashChar); - if (slash < 0) - return ret; - else if (ret.at(0) != slashChar && slash == 2) - return ret.left(3); // include the slash - else - return ret.left(slash > 0 ? slash : 1); - } - return ret; - } else if(file == CanonicalName || file == CanonicalPathName) { - QFileSystemEntry entry(QFileSystemEngine::canonicalName(d->fileEntry)); - if (file == CanonicalPathName) - return entry.path(); - return entry.filePath(); - } else if(file == LinkName) { - if (d->isSymlink()) { - char s[PATH_MAX+1]; - int len = readlink(d->fileEntry.nativeFilePath().constData(), s, PATH_MAX); - if (len > 0) { - s[len] = '\0'; - QString ret = QFile::decodeName(QByteArray(s)); - - if (isRelativePathSymbian(ret)) { - if (!isRelativePathSymbian(d->fileEntry.filePath())) { - ret.prepend(d->fileEntry.filePath().left(d->fileEntry.filePath().lastIndexOf(slashChar)) - + slashChar); - } else { - ret.prepend(QDir::currentPath() + slashChar); - } - } - ret = QDir::cleanPath(ret); - if (ret.size() > 1 && ret.endsWith(slashChar)) - ret.chop(1); - return ret; - } - } - return QString(); - } else if(file == BundleName) { - return QString(); - } - return d->fileEntry.filePath(); -} - -#else - QString QFSFileEngine::fileName(FileName file) const { Q_D(const QFSFileEngine); @@ -868,7 +839,6 @@ QString QFSFileEngine::fileName(FileName file) const } return d->fileEntry.filePath(); } -#endif // Q_OS_SYMBIAN bool QFSFileEngine::isRelativePath() const { @@ -939,6 +909,51 @@ QString QFSFileEngine::owner(FileOwner own) const return QString(); } +#ifdef Q_OS_SYMBIAN +bool QFSFileEngine::setPermissions(uint perms) +{ + Q_D(QFSFileEngine); + //TODO: connect up error reporting properly + if (!QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), 0)) { + setError(QFile::PermissionsError, QString()); + return false; + } + return true; +} + +bool QFSFileEngine::setSize(qint64 size) +{ + Q_D(QFSFileEngine); + bool ret = false; + TInt err = KErrNone; + if (d->symbianFile.SubSessionHandle()) { + TInt err = d->symbianFile.SetSize(size); + ret = (err == KErrNone); + } + if (d->fd != -1) + ret = QT_FTRUNCATE(d->fd, size) == 0; + else if (d->fh) + ret = QT_FTRUNCATE(QT_FILENO(d->fh), size) == 0; + else { + RFile tmp; + QString symbianFilename(d->fileEntry.nativeFilePath()); + err = tmp.Open(qt_s60GetRFs(), qt_QString2TPtrC(symbianFilename), EFileWrite); + if (err == KErrNone) + { + err = tmp.SetSize(size); + tmp.Close(); + } + ret = (err == KErrNone); + } + if (!ret) { + if (err) + d->setSymbianError(err, QFile::ResizeError, QString()); + else + setError(QFile::ResizeError, qt_error_string(errno)); + } + return ret; +} +#else bool QFSFileEngine::setPermissions(uint perms) { Q_D(QFSFileEngine); @@ -991,6 +1006,7 @@ bool QFSFileEngine::setSize(qint64 size) setError(QFile::ResizeError, qt_error_string(errno)); return ret; } +#endif QDateTime QFSFileEngine::fileTime(FileTime time) const { @@ -1002,6 +1018,30 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const return QDateTime(); } +#ifdef Q_OS_SYMBIAN +uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) +{ + //Q_Q(QFSFileEngine); + Q_UNUSED(flags) + Q_UNUSED(offset) + Q_UNUSED(size) + return 0; + //TODO: use RFileMap when available in symbian^4 +} + +bool QFSFileEnginePrivate::unmap(uchar *ptr) +{ + //TODO: RFileMap as the value in maps, unmap it here when API is available... + //Q_Q(QFSFileEngine); + //if (!maps.contains(ptr)) { + // q->setError(QFile::PermissionsError, qt_error_string(EACCES)); + // return false; + //} + Q_UNUSED(ptr) + + return false; +} +#else uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) { Q_Q(QFSFileEngine); @@ -1092,6 +1132,7 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr) maps.remove(ptr); return true; } +#endif QT_END_NAMESPACE -- cgit v0.12 From 97e8a289380202da7041e40574d58b08a91e0fd0 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 8 Sep 2010 20:20:12 +0100 Subject: Fixes for tst_qfileinfo Use case insensitive comparison on symbian/windows for the absFilePath test. - it expected "c:\\home\\andy\\tmp.txt" to resolve to "C:/home/andy/tmp.txt" - but there is no reason for the drive letter to be changed to uppercase - however it's not wrong either since the FS is case insensitive. Enable isWritable test on symbian - it was skipped for no good reason Reviewed-By: joao --- tests/auto/qfileinfo/tst_qfileinfo.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 9ec0572..08cb68d 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -514,7 +514,11 @@ void tst_QFileInfo::absFilePath() QFETCH(QString, expected); QFileInfo fi(file); +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + QVERIFY(QString::compare(fi.absoluteFilePath(), expected, Qt::CaseInsensitive) == 0); +#else QCOMPARE(fi.absoluteFilePath(), expected); +#endif } void tst_QFileInfo::canonicalPath() @@ -1432,10 +1436,6 @@ void tst_QFileInfo::brokenShortcut() void tst_QFileInfo::isWritable() { -#ifdef Q_OS_SYMBIAN - QSKIP("Currently skipped on Symbian OS, but surely there is a writeable file somewhere???", SkipAll); -#endif - QFile tempfile("tempfile.txt"); tempfile.open(QIODevice::WriteOnly); tempfile.write("This file is generated by the QFileInfo autotest."); @@ -1453,7 +1453,7 @@ void tst_QFileInfo::isWritable() QVERIFY(fi.exists()); QVERIFY(!fi.isWritable()); #endif -#ifdef Q_OS_UNIX +#if defined (Q_OS_UNIX) && !defined (Q_OS_SYMBIAN) if (::getuid() == 0) QVERIFY(QFileInfo("/etc/passwd").isWritable()); else -- cgit v0.12 From 927469d518afa64d8ec8dc54e6169fa43b54cd96 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 8 Sep 2010 20:24:45 +0100 Subject: Fixes for isRoot() on symbian Because "/" is considered to be a root directory, root paths must be converted to absolute paths before volume info can be retrieved. Also special handling in absoluteName is needed to avoid creating "c://" Reviewed-By: joao --- src/corelib/io/qfilesystemengine_symbian.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 3638196..1205274 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -115,9 +115,10 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) } const bool isDir = result.endsWith('/'); + const bool isRoot = entry.isRoot(); result = QDir::cleanPath(result); - if (isDir) + if (isDir && !isRoot) result.append(QLatin1Char('/')); return QFileSystemEntry(result); } @@ -175,11 +176,12 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM RFs& fs(qt_s60GetRFs()); TInt err; data.entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags); - if (entry.isRoot()) { + QFileSystemEntry absentry(absoluteName(entry)); + if (absentry.isRoot()) { //Root directories don't have an entry, and Entry() returns KErrBadName. //Therefore get information about the volume instead. TInt drive; - err = RFs::CharToDrive(TChar(entry.nativeFilePath().at(0).unicode()), drive); + err = RFs::CharToDrive(TChar(absentry.nativeFilePath().at(0).unicode()), drive); if (!err) { TVolumeInfo info; err = fs.Volume(info, drive); @@ -188,7 +190,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM } } else { TEntry ent; - err = fs.Entry(qt_QString2TPtrC(absoluteName(entry).nativeFilePath()), ent); + err = fs.Entry(qt_QString2TPtrC(absentry.nativeFilePath()), ent); if (!err) data.fillFromTEntry(ent); } -- cgit v0.12 From d95b3bf38b9c25a38ade7c92fd434e42346729bd Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 8 Sep 2010 20:28:17 +0100 Subject: Implement basic symbian native file IO to QFsFileEngine Enough functionality to be able to read/write files for the tst_qfileinfo autotest to pass. Reviewed-By: joao --- src/corelib/io/qfsfileengine.cpp | 6 ++- src/corelib/io/qfsfileengine_unix.cpp | 95 +++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 089f1a1..9c8df39 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -352,7 +352,11 @@ bool QFSFileEngine::close() bool QFSFileEnginePrivate::closeFdFh() { Q_Q(QFSFileEngine); - if (fd == -1 && !fh) + if (fd == -1 && !fh +#ifdef Q_OS_SYMBIAN + && !symbianFile.SubSessionHandle() +#endif + ) return false; // Flush the file if it's buffered, and if the last flush didn't fail. diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 048aa1b..e4c6f09 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -393,6 +393,10 @@ bool QFSFileEnginePrivate::nativeClose() */ bool QFSFileEnginePrivate::nativeFlush() { +#ifdef Q_OS_SYMBIAN + if (symbianFile.SubSessionHandle()) + return (KErrNone == symbianFile.Flush()); +#endif return fh ? flushFh() : fd != -1; } @@ -403,6 +407,23 @@ qint64 QFSFileEnginePrivate::nativeRead(char *data, qint64 len) { Q_Q(QFSFileEngine); +#ifdef Q_OS_SYMBIAN + if (symbianFile.SubSessionHandle()) { + if(len > KMaxTInt) { + //this check is more likely to catch a corrupt length, since it isn't possible to allocate 2GB buffers (yet..) + q->setError(QFile::ReadError, QLatin1String("Maximum 2GB in single read on this platform")); + return -1; + } + TPtr8 ptr(reinterpret_cast(data), static_cast(len)); + TInt r = symbianFile.Read(ptr); + if (r != KErrNone) + { + setSymbianError(r, QFile::ReadError, QLatin1String("read error")); + return -1; + } + return qint64(ptr.Length()); + } +#endif if (fh && nativeIsSequential()) { size_t readBytes = 0; int oldFlags = fcntl(QT_FILENO(fh), F_GETFL); @@ -470,6 +491,24 @@ qint64 QFSFileEnginePrivate::nativeReadLine(char *data, qint64 maxlen) */ qint64 QFSFileEnginePrivate::nativeWrite(const char *data, qint64 len) { + Q_Q(QFSFileEngine); +#ifdef Q_OS_SYMBIAN + if (symbianFile.SubSessionHandle()) { + if(len > KMaxTInt) { + //this check is more likely to catch a corrupt length, since it isn't possible to allocate 2GB buffers (yet..) + q->setError(QFile::WriteError, QLatin1String("Maximum 2GB in single write on this platform")); + return -1; + } + const TPtrC8 ptr(reinterpret_cast(data), static_cast(len)); + TInt r = symbianFile.Write(ptr); + if (r != KErrNone) + { + setSymbianError(r, QFile::WriteError, QLatin1String("write error")); + return -1; + } + return len; + } +#endif return writeFdFh(data, len); } @@ -478,6 +517,22 @@ qint64 QFSFileEnginePrivate::nativeWrite(const char *data, qint64 len) */ qint64 QFSFileEnginePrivate::nativePos() const { +#ifdef Q_OS_SYMBIAN + if (symbianFile.SubSessionHandle()) { +#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API + qint64 pos; +#else + TInt pos; +#endif + TInt err = symbianFile.Seek(ESeekCurrent, pos); + if(err != KErrNone) { + //TODO: error reporting + //setSymbianError(err, QFile::PositionError, QLatin1String("seek failed")); + return -1; + } + return pos; + } +#endif return posFdFh(); } @@ -486,6 +541,27 @@ qint64 QFSFileEnginePrivate::nativePos() const */ bool QFSFileEnginePrivate::nativeSeek(qint64 pos) { +#ifdef Q_OS_SYMBIAN + Q_Q(QFSFileEngine); + if (symbianFile.SubSessionHandle()) { +#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API + TInt r = symbianFile.Seek(ESeekStart, pos); +#else + if(pos > KMaxTInt) { + q->setError(QFile::PositionError, QLatin1String("Maximum 2GB file position on this platform")); + return false; + } + TInt pos32(pos); + TInt r = symbianFile.Seek(ESeekStart, pos32); +#endif + if (r != KErrNone) + { + setSymbianError(r, QFile::PositionError, QLatin1String("seek failed")); + return false; + } + return true; + } +#endif return seekFdFh(pos); } @@ -502,6 +578,10 @@ int QFSFileEnginePrivate::nativeHandle() const */ bool QFSFileEnginePrivate::nativeIsSequential() const { +#ifdef Q_OS_SYMBIAN + if (symbianFile.SubSessionHandle()) + return false; +#endif return isSequentialFdFh(); } @@ -571,6 +651,21 @@ bool QFSFileEngine::link(const QString &newName) qint64 QFSFileEnginePrivate::nativeSize() const { +#ifdef Q_OS_SYMBIAN + if (symbianFile.SubSessionHandle()) { +#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API + qint64 size; +#else + TInt size; +#endif + TInt err = symbianFile.Size(size); + if(err != KErrNone) { + //TODO: error reporting + return 0; + } + return size; + } +#endif return sizeFdFh(); } -- cgit v0.12 From 311f346e49f6d033121840f8740710666c920640 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 9 Sep 2010 11:11:02 +0100 Subject: Update Symbian DEF files To allow file-engines-refactor branch to build. Reviewed-By: Trust Me --- src/s60installs/bwins/QtCoreu.def | 54 +++++++++++++++++++++++++++++++++---- src/s60installs/bwins/QtGuiu.def | 57 ++++++++++++++++++++++++++++++++++++--- src/s60installs/eabi/QtCoreu.def | 46 ++++++++++++++++++++++++++++--- src/s60installs/eabi/QtGuiu.def | 56 +++++++++++++++++++++++++++++++++++--- 4 files changed, 197 insertions(+), 16 deletions(-) diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def index 1a79f63..052ec9a 100644 --- a/src/s60installs/bwins/QtCoreu.def +++ b/src/s60installs/bwins/QtCoreu.def @@ -59,7 +59,7 @@ EXPORTS ??0QChildEvent@@QAE@W4Type@QEvent@@PAVQObject@@@Z @ 58 NONAME ; QChildEvent::QChildEvent(enum QEvent::Type, class QObject *) ??0QCoreApplication@@IAE@AAVQCoreApplicationPrivate@@@Z @ 59 NONAME ; QCoreApplication::QCoreApplication(class QCoreApplicationPrivate &) ??0QCoreApplication@@QAE@AAHPAPAD@Z @ 60 NONAME ; QCoreApplication::QCoreApplication(int &, char * *) - ??0QCoreApplicationPrivate@@QAE@AAHPAPAD@Z @ 61 NONAME ; QCoreApplicationPrivate::QCoreApplicationPrivate(int &, char * *) + ??0QCoreApplicationPrivate@@QAE@AAHPAPAD@Z @ 61 NONAME ABSENT ; QCoreApplicationPrivate::QCoreApplicationPrivate(int &, char * *) ??0QCryptographicHash@@QAE@W4Algorithm@0@@Z @ 62 NONAME ; QCryptographicHash::QCryptographicHash(enum QCryptographicHash::Algorithm) ??0QDataStream@@QAE@ABVQByteArray@@@Z @ 63 NONAME ; QDataStream::QDataStream(class QByteArray const &) ??0QDataStream@@QAE@PAVQByteArray@@V?$QFlags@W4OpenModeFlag@QIODevice@@@@@Z @ 64 NONAME ; QDataStream::QDataStream(class QByteArray *, class QFlags) @@ -1440,8 +1440,8 @@ EXPORTS ?d_func@QBuffer@@ABEPBVQBufferPrivate@@XZ @ 1439 NONAME ; class QBufferPrivate const * QBuffer::d_func(void) const ?d_func@QCoreApplication@@AAEPAVQCoreApplicationPrivate@@XZ @ 1440 NONAME ; class QCoreApplicationPrivate * QCoreApplication::d_func(void) ?d_func@QCoreApplication@@ABEPBVQCoreApplicationPrivate@@XZ @ 1441 NONAME ; class QCoreApplicationPrivate const * QCoreApplication::d_func(void) const - ?d_func@QDir@@AAEPAVQDirPrivate@@XZ @ 1442 NONAME ; class QDirPrivate * QDir::d_func(void) - ?d_func@QDir@@ABEPBVQDirPrivate@@XZ @ 1443 NONAME ; class QDirPrivate const * QDir::d_func(void) const + ?d_func@QDir@@AAEPAVQDirPrivate@@XZ @ 1442 NONAME ABSENT ; class QDirPrivate * QDir::d_func(void) + ?d_func@QDir@@ABEPBVQDirPrivate@@XZ @ 1443 NONAME ABSENT ; class QDirPrivate const * QDir::d_func(void) const ?d_func@QEventDispatcherSymbian@@AAEPAVQAbstractEventDispatcherPrivate@@XZ @ 1444 NONAME ; class QAbstractEventDispatcherPrivate * QEventDispatcherSymbian::d_func(void) ?d_func@QEventDispatcherSymbian@@ABEPBVQAbstractEventDispatcherPrivate@@XZ @ 1445 NONAME ; class QAbstractEventDispatcherPrivate const * QEventDispatcherSymbian::d_func(void) const ?d_func@QEventLoop@@AAEPAVQEventLoopPrivate@@XZ @ 1446 NONAME ; class QEventLoopPrivate * QEventLoop::d_func(void) @@ -3123,7 +3123,7 @@ EXPORTS ?reset@QMetaProperty@@QBE_NPAVQObject@@@Z @ 3122 NONAME ; bool QMetaProperty::reset(class QObject *) const ?reset@QTextStream@@QAEXXZ @ 3123 NONAME ; void QTextStream::reset(void) ?resetCurrentSender@QObjectPrivate@@SAXPAVQObject@@PAUSender@1@1@Z @ 3124 NONAME ; void QObjectPrivate::resetCurrentSender(class QObject *, struct QObjectPrivate::Sender *, struct QObjectPrivate::Sender *) - ?resetDeleteWatch@QObjectPrivate@@SAXPAV1@PAHH@Z @ 3125 NONAME ; void QObjectPrivate::resetDeleteWatch(class QObjectPrivate *, int *, int) + ?resetDeleteWatch@QObjectPrivate@@SAXPAV1@PAHH@Z @ 3125 NONAME ABSENT ; void QObjectPrivate::resetDeleteWatch(class QObjectPrivate *, int *, int) ?resetStatus@QDataStream@@QAEXXZ @ 3126 NONAME ; void QDataStream::resetStatus(void) ?resetStatus@QTextStream@@QAEXXZ @ 3127 NONAME ; void QTextStream::resetStatus(void) ?resize@QBitArray@@QAEXH@Z @ 3128 NONAME ; void QBitArray::resize(int) @@ -3296,7 +3296,7 @@ EXPORTS ?setDefault@QLocale@@SAXABV1@@Z @ 3295 NONAME ; void QLocale::setDefault(class QLocale const &) ?setDefaultFormat@QSettings@@SAXW4Format@1@@Z @ 3296 NONAME ; void QSettings::setDefaultFormat(enum QSettings::Format) ?setDefaultState@QHistoryState@@QAEXPAVQAbstractState@@@Z @ 3297 NONAME ; void QHistoryState::setDefaultState(class QAbstractState *) - ?setDeleteWatch@QObjectPrivate@@SAPAHPAV1@PAH@Z @ 3298 NONAME ; int * QObjectPrivate::setDeleteWatch(class QObjectPrivate *, int *) + ?setDeleteWatch@QObjectPrivate@@SAPAHPAV1@PAH@Z @ 3298 NONAME ABSENT ; int * QObjectPrivate::setDeleteWatch(class QObjectPrivate *, int *) ?setDevice@QDataStream@@QAEXPAVQIODevice@@@Z @ 3299 NONAME ; void QDataStream::setDevice(class QIODevice *) ?setDevice@QTextStream@@QAEXPAVQIODevice@@@Z @ 3300 NONAME ; void QTextStream::setDevice(class QIODevice *) ?setDevice@QXmlStreamReader@@QAEXPAVQIODevice@@@Z @ 3301 NONAME ; void QXmlStreamReader::setDevice(class QIODevice *) @@ -4482,4 +4482,48 @@ EXPORTS ?textDirection@QLocale@@QBE?AW4LayoutDirection@Qt@@XZ @ 4481 NONAME ; enum Qt::LayoutDirection QLocale::textDirection(void) const ?msecsSinceReference@QElapsedTimer@@QBE_JXZ @ 4482 NONAME ; long long QElapsedTimer::msecsSinceReference(void) const ?selectThread@QEventDispatcherSymbian@@AAEAAVQSelectThread@@XZ @ 4483 NONAME ; class QSelectThread & QEventDispatcherSymbian::selectThread(void) + ??0QCoreApplication@@QAE@AAHPAPADH@Z @ 4484 NONAME ; QCoreApplication::QCoreApplication(int &, char * *, int) + ??0QCoreApplicationPrivate@@QAE@AAHPAPADI@Z @ 4485 NONAME ; QCoreApplicationPrivate::QCoreApplicationPrivate(int &, char * *, unsigned int) + ?connect@QObject@@SA_NPBV1@ABVQMetaMethod@@01W4ConnectionType@Qt@@@Z @ 4486 NONAME ; bool QObject::connect(class QObject const *, class QMetaMethod const &, class QObject const *, class QMetaMethod const &, enum Qt::ConnectionType) + ?contains@QString@@QBE?AVQBool@@ABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4487 NONAME ; class QBool QString::contains(class QStringRef const &, enum Qt::CaseSensitivity) const + ?contains@QStringRef@@QBE?AVQBool@@ABV1@W4CaseSensitivity@Qt@@@Z @ 4488 NONAME ; class QBool QStringRef::contains(class QStringRef const &, enum Qt::CaseSensitivity) const + ?contains@QStringRef@@QBE?AVQBool@@ABVQString@@W4CaseSensitivity@Qt@@@Z @ 4489 NONAME ; class QBool QStringRef::contains(class QString const &, enum Qt::CaseSensitivity) const + ?contains@QStringRef@@QBE?AVQBool@@VQChar@@W4CaseSensitivity@Qt@@@Z @ 4490 NONAME ; class QBool QStringRef::contains(class QChar, enum Qt::CaseSensitivity) const + ?contains@QStringRef@@QBE?AVQBool@@VQLatin1String@@W4CaseSensitivity@Qt@@@Z @ 4491 NONAME ; class QBool QStringRef::contains(class QLatin1String, enum Qt::CaseSensitivity) const + ?count@QString@@QBEHABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4492 NONAME ; int QString::count(class QStringRef const &, enum Qt::CaseSensitivity) const + ?count@QStringRef@@QBEHABV1@W4CaseSensitivity@Qt@@@Z @ 4493 NONAME ; int QStringRef::count(class QStringRef const &, enum Qt::CaseSensitivity) const + ?count@QStringRef@@QBEHABVQString@@W4CaseSensitivity@Qt@@@Z @ 4494 NONAME ; int QStringRef::count(class QString const &, enum Qt::CaseSensitivity) const + ?count@QStringRef@@QBEHVQChar@@W4CaseSensitivity@Qt@@@Z @ 4495 NONAME ; int QStringRef::count(class QChar, enum Qt::CaseSensitivity) const + ?disconnect@QObject@@SA_NPBV1@ABVQMetaMethod@@01@Z @ 4496 NONAME ; bool QObject::disconnect(class QObject const *, class QMetaMethod const &, class QObject const *, class QMetaMethod const &) + ?endsWith@QString@@QBE_NABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4497 NONAME ; bool QString::endsWith(class QStringRef const &, enum Qt::CaseSensitivity) const + ?endsWith@QStringRef@@QBE_NABV1@W4CaseSensitivity@Qt@@@Z @ 4498 NONAME ; bool QStringRef::endsWith(class QStringRef const &, enum Qt::CaseSensitivity) const + ?endsWith@QStringRef@@QBE_NABVQString@@W4CaseSensitivity@Qt@@@Z @ 4499 NONAME ; bool QStringRef::endsWith(class QString const &, enum Qt::CaseSensitivity) const + ?endsWith@QStringRef@@QBE_NVQChar@@W4CaseSensitivity@Qt@@@Z @ 4500 NONAME ; bool QStringRef::endsWith(class QChar, enum Qt::CaseSensitivity) const + ?endsWith@QStringRef@@QBE_NVQLatin1String@@W4CaseSensitivity@Qt@@@Z @ 4501 NONAME ; bool QStringRef::endsWith(class QLatin1String, enum Qt::CaseSensitivity) const + ?indexOf@QString@@QBEHABVQStringRef@@HW4CaseSensitivity@Qt@@@Z @ 4502 NONAME ; int QString::indexOf(class QStringRef const &, int, enum Qt::CaseSensitivity) const + ?indexOf@QStringRef@@QBEHABV1@HW4CaseSensitivity@Qt@@@Z @ 4503 NONAME ; int QStringRef::indexOf(class QStringRef const &, int, enum Qt::CaseSensitivity) const + ?indexOf@QStringRef@@QBEHABVQString@@HW4CaseSensitivity@Qt@@@Z @ 4504 NONAME ; int QStringRef::indexOf(class QString const &, int, enum Qt::CaseSensitivity) const + ?indexOf@QStringRef@@QBEHVQChar@@HW4CaseSensitivity@Qt@@@Z @ 4505 NONAME ; int QStringRef::indexOf(class QChar, int, enum Qt::CaseSensitivity) const + ?indexOf@QStringRef@@QBEHVQLatin1String@@HW4CaseSensitivity@Qt@@@Z @ 4506 NONAME ; int QStringRef::indexOf(class QLatin1String, int, enum Qt::CaseSensitivity) const + ?isLocalFile@QUrl@@QBE_NXZ @ 4507 NONAME ; bool QUrl::isLocalFile(void) const + ?lastIndexOf@QString@@QBEHABVQStringRef@@HW4CaseSensitivity@Qt@@@Z @ 4508 NONAME ; int QString::lastIndexOf(class QStringRef const &, int, enum Qt::CaseSensitivity) const + ?lastIndexOf@QStringRef@@QBEHABV1@HW4CaseSensitivity@Qt@@@Z @ 4509 NONAME ; int QStringRef::lastIndexOf(class QStringRef const &, int, enum Qt::CaseSensitivity) const + ?lastIndexOf@QStringRef@@QBEHABVQString@@HW4CaseSensitivity@Qt@@@Z @ 4510 NONAME ; int QStringRef::lastIndexOf(class QString const &, int, enum Qt::CaseSensitivity) const + ?lastIndexOf@QStringRef@@QBEHVQChar@@HW4CaseSensitivity@Qt@@@Z @ 4511 NONAME ; int QStringRef::lastIndexOf(class QChar, int, enum Qt::CaseSensitivity) const + ?lastIndexOf@QStringRef@@QBEHVQLatin1String@@HW4CaseSensitivity@Qt@@@Z @ 4512 NONAME ; int QStringRef::lastIndexOf(class QLatin1String, int, enum Qt::CaseSensitivity) const + ?lockInline@QMutex@@QAEXXZ @ 4513 NONAME ; void QMutex::lockInline(void) + ?lockInternal@QMutex@@AAEXXZ @ 4514 NONAME ; void QMutex::lockInternal(void) + ?nativeKey@QSharedMemory@@QBE?AVQString@@XZ @ 4515 NONAME ; class QString QSharedMemory::nativeKey(void) const + ?senderSignalIndex@QObject@@IBEHXZ @ 4516 NONAME ; int QObject::senderSignalIndex(void) const + ?setNativeKey@QSharedMemory@@QAEXABVQString@@@Z @ 4517 NONAME ; void QSharedMemory::setNativeKey(class QString const &) + ?startsWith@QString@@QBE_NABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4518 NONAME ; bool QString::startsWith(class QStringRef const &, enum Qt::CaseSensitivity) const + ?startsWith@QStringRef@@QBE_NABV1@W4CaseSensitivity@Qt@@@Z @ 4519 NONAME ; bool QStringRef::startsWith(class QStringRef const &, enum Qt::CaseSensitivity) const + ?startsWith@QStringRef@@QBE_NABVQString@@W4CaseSensitivity@Qt@@@Z @ 4520 NONAME ; bool QStringRef::startsWith(class QString const &, enum Qt::CaseSensitivity) const + ?startsWith@QStringRef@@QBE_NVQChar@@W4CaseSensitivity@Qt@@@Z @ 4521 NONAME ; bool QStringRef::startsWith(class QChar, enum Qt::CaseSensitivity) const + ?startsWith@QStringRef@@QBE_NVQLatin1String@@W4CaseSensitivity@Qt@@@Z @ 4522 NONAME ; bool QStringRef::startsWith(class QLatin1String, enum Qt::CaseSensitivity) const + ?tryLockInline@QMutex@@QAE_NXZ @ 4523 NONAME ; bool QMutex::tryLockInline(void) + ?unlockInline@QMutex@@QAEXXZ @ 4524 NONAME ; void QMutex::unlockInline(void) + ?unlockInternal@QMutex@@AAEXXZ @ 4525 NONAME ; void QMutex::unlockInternal(void) + ?waitForDone@QThreadPool@@QAE_NH@Z @ 4526 NONAME ; bool QThreadPool::waitForDone(int) + ?app_compile_version@QCoreApplicationPrivate@@2HA @ 4527 NONAME ; int QCoreApplicationPrivate::app_compile_version diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 90c0878..b2ac45e 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -35,7 +35,7 @@ EXPORTS ??0QApplication@@QAE@AAHPAPADW4Type@0@H@Z @ 34 NONAME ; QApplication::QApplication(int &, char * *, enum QApplication::Type, int) ??0QApplication@@QAE@AAHPAPAD_NH@Z @ 35 NONAME ; QApplication::QApplication(int &, char * *, bool, int) ??0QApplication@@QAE@P6APAVCApaApplication@@XZAAHPAPADH@Z @ 36 NONAME ; QApplication::QApplication(class CApaApplication * (*)(void), int &, char * *, int) - ??0QApplicationPrivate@@QAE@AAHPAPADW4Type@QApplication@@@Z @ 37 NONAME ; QApplicationPrivate::QApplicationPrivate(int &, char * *, enum QApplication::Type) + ??0QApplicationPrivate@@QAE@AAHPAPADW4Type@QApplication@@@Z @ 37 NONAME ABSENT ; QApplicationPrivate::QApplicationPrivate(int &, char * *, enum QApplication::Type) ??0QBitmap@@QAE@ABVQPixmap@@@Z @ 38 NONAME ; QBitmap::QBitmap(class QPixmap const &) ??0QBitmap@@QAE@ABVQSize@@@Z @ 39 NONAME ; QBitmap::QBitmap(class QSize const &) ??0QBitmap@@QAE@ABVQString@@PBD@Z @ 40 NONAME ; QBitmap::QBitmap(class QString const &, char const *) @@ -4148,7 +4148,7 @@ EXPORTS ?ensureSceneTransformRecursive@QGraphicsItemPrivate@@QAEXPAPAVQGraphicsItem@@@Z @ 4147 NONAME ; void QGraphicsItemPrivate::ensureSceneTransformRecursive(class QGraphicsItem * *) ?ensureSequentialSiblingIndex@QGraphicsItemPrivate@@QAEXXZ @ 4148 NONAME ; void QGraphicsItemPrivate::ensureSequentialSiblingIndex(void) ?ensureSortedChildren@QGraphicsItemPrivate@@QAEXXZ @ 4149 NONAME ; void QGraphicsItemPrivate::ensureSortedChildren(void) - ?ensureSpace@QTextEngine@@QBEXH@Z @ 4150 NONAME ; void QTextEngine::ensureSpace(int) const + ?ensureSpace@QTextEngine@@QBEXH@Z @ 4150 NONAME ABSENT ; void QTextEngine::ensureSpace(int) const ?ensureVisible@QGraphicsItem@@QAEXABVQRectF@@HH@Z @ 4151 NONAME ; void QGraphicsItem::ensureVisible(class QRectF const &, int, int) ?ensureVisible@QGraphicsItem@@QAEXMMMMHH@Z @ 4152 NONAME ; void QGraphicsItem::ensureVisible(float, float, float, float, int, int) ?ensureVisible@QGraphicsView@@QAEXABVQRectF@@HH@Z @ 4153 NONAME ; void QGraphicsView::ensureVisible(class QRectF const &, int, int) @@ -12511,7 +12511,7 @@ EXPORTS ?staticMetaObject@QFileSystemModel@@2UQMetaObject@@B @ 12510 NONAME ; struct QMetaObject const QFileSystemModel::staticMetaObject ?staticMetaObject@QKeyEventTransition@@2UQMetaObject@@B @ 12511 NONAME ; struct QMetaObject const QKeyEventTransition::staticMetaObject ?staticMetaObject@QLayout@@2UQMetaObject@@B @ 12512 NONAME ; struct QMetaObject const QLayout::staticMetaObject - ?app_compile_version@QApplicationPrivate@@2HA @ 12513 NONAME ; int QApplicationPrivate::app_compile_version + ?app_compile_version@QApplicationPrivate@@2HA @ 12513 NONAME ABSENT ; int QApplicationPrivate::app_compile_version ?spacerItemFactoryMethod@QLayoutPrivate@@2P6APAVQSpacerItem@@PBVQLayout@@HHW4Policy@QSizePolicy@@1@ZA @ 12514 NONAME ; class QSpacerItem * (*QLayoutPrivate::spacerItemFactoryMethod)(class QLayout const *, int, int, enum QSizePolicy::Policy, enum QSizePolicy::Policy) ?allWidgets@QWidgetPrivate@@2PAV?$QSet@PAVQWidget@@@@A @ 12515 NONAME ; class QSet * QWidgetPrivate::allWidgets ?effectiveFocusWidget@QWidgetPrivate@@QAEPAVQWidget@@XZ @ 12516 NONAME ; class QWidget * QWidgetPrivate::effectiveFocusWidget(void) @@ -12522,7 +12522,7 @@ EXPORTS ?addCacheData@QVectorPath@@QBEPAUCacheEntry@1@PAVQPaintEngineEx@@PAXP6AX01@Z@Z @ 12521 NONAME ; struct QVectorPath::CacheEntry * QVectorPath::addCacheData(class QPaintEngineEx *, void *, void (*)(class QPaintEngineEx *, void *)) const ?discardUpdateRequest@QGraphicsItemPrivate@@QBE_N_N00@Z @ 12522 NONAME ; bool QGraphicsItemPrivate::discardUpdateRequest(bool, bool, bool) const ?makeCacheable@QVectorPath@@QBEXXZ @ 12523 NONAME ; void QVectorPath::makeCacheable(void) const - ??0Tab@QTextOption@@QAE@ABU01@@Z @ 12524 NONAME ; QTextOption::Tab::Tab(struct QTextOption::Tab const &) + ??0Tab@QTextOption@@QAE@ABU01@@Z @ 12524 NONAME ABSENT ; QTextOption::Tab::Tab(struct QTextOption::Tab const &) ?effectiveBoundingRect@QGraphicsItemPrivate@@QBE?AVQRectF@@ABV2@@Z @ 12525 NONAME ; class QRectF QGraphicsItemPrivate::effectiveBoundingRect(class QRectF const &) const ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@PAXW4Type@2@ABVQTransform@@@Z @ 12526 NONAME ; class QFontEngineGlyphCache * QFontEngine::glyphCache(void *, enum QFontEngineGlyphCache::Type, class QTransform const &) const ?qt_blurImage@@YAXAAVQImage@@M_NH@Z @ 12527 NONAME ; void qt_blurImage(class QImage &, float, bool, int) @@ -12886,4 +12886,53 @@ EXPORTS ?zScaleChanged@QGraphicsScale@@IAEXXZ @ 12885 NONAME ; void QGraphicsScale::zScaleChanged(void) ?xScaleChanged@QGraphicsScale@@IAEXXZ @ 12886 NONAME ; void QGraphicsScale::xScaleChanged(void) ?yScaleChanged@QGraphicsScale@@IAEXXZ @ 12887 NONAME ; void QGraphicsScale::yScaleChanged(void) + ??0QApplicationPrivate@@QAE@AAHPAPADW4Type@QApplication@@H@Z @ 12888 NONAME ; QApplicationPrivate::QApplicationPrivate(int &, char * *, enum QApplication::Type, int) + ??0QGlyphs@@QAE@ABV0@@Z @ 12889 NONAME ; QGlyphs::QGlyphs(class QGlyphs const &) + ??0QGlyphs@@QAE@XZ @ 12890 NONAME ; QGlyphs::QGlyphs(void) + ??1QGlyphs@@QAE@XZ @ 12891 NONAME ; QGlyphs::~QGlyphs(void) + ??4QGlyphs@@QAEAAV0@ABV0@@Z @ 12892 NONAME ; class QGlyphs & QGlyphs::operator=(class QGlyphs const &) + ??8QGlyphs@@QBE_NABV0@@Z @ 12893 NONAME ; bool QGlyphs::operator==(class QGlyphs const &) const + ??9QGlyphs@@QBE_NABV0@@Z @ 12894 NONAME ; bool QGlyphs::operator!=(class QGlyphs const &) const + ??HQGlyphs@@ABE?AV0@ABV0@@Z @ 12895 NONAME ; class QGlyphs QGlyphs::operator+(class QGlyphs const &) const + ??MQItemSelectionRange@@QBE_NABV0@@Z @ 12896 NONAME ; bool QItemSelectionRange::operator<(class QItemSelectionRange const &) const + ??YQGlyphs@@AAEAAV0@ABV0@@Z @ 12897 NONAME ; class QGlyphs & QGlyphs::operator+=(class QGlyphs const &) + ?_q_aboutToQuit@QApplicationPrivate@@QAEXXZ @ 12898 NONAME ; void QApplicationPrivate::_q_aboutToQuit(void) + ?buddy@QAbstractProxyModel@@UBE?AVQModelIndex@@ABV2@@Z @ 12899 NONAME ; class QModelIndex QAbstractProxyModel::buddy(class QModelIndex const &) const + ?canFetchMore@QAbstractProxyModel@@UBE_NABVQModelIndex@@@Z @ 12900 NONAME ; bool QAbstractProxyModel::canFetchMore(class QModelIndex const &) const + ?clear@QGlyphs@@QAEXXZ @ 12901 NONAME ; void QGlyphs::clear(void) + ?clipBoundingRect@QPainter@@QBE?AVQRectF@@XZ @ 12902 NONAME ; class QRectF QPainter::clipBoundingRect(void) const + ?createExplicitFont@QFontEngine@@UBE?AVQFont@@XZ @ 12903 NONAME ; class QFont QFontEngine::createExplicitFont(void) const + ?createExplicitFontWithName@QFontEngine@@IBE?AVQFont@@ABVQString@@@Z @ 12904 NONAME ; class QFont QFontEngine::createExplicitFontWithName(class QString const &) const + ?detach@QGlyphs@@AAEXXZ @ 12905 NONAME ; void QGlyphs::detach(void) + ?drawGlyphs@QPainter@@QAEXABVQPointF@@ABVQGlyphs@@@Z @ 12906 NONAME ; void QPainter::drawGlyphs(class QPointF const &, class QGlyphs const &) + ?ensureSpace@QTextEngine@@QBE_NH@Z @ 12907 NONAME ; bool QTextEngine::ensureSpace(int) const + ?fetchMore@QAbstractProxyModel@@UAEXABVQModelIndex@@@Z @ 12908 NONAME ; void QAbstractProxyModel::fetchMore(class QModelIndex const &) + ?fill@QImage@@QAEXABVQColor@@@Z @ 12909 NONAME ; void QImage::fill(class QColor const &) + ?fill@QImage@@QAEXW4GlobalColor@Qt@@@Z @ 12910 NONAME ; void QImage::fill(enum Qt::GlobalColor) + ?fillInPendingGlyphs@QTextureGlyphCache@@QAEXXZ @ 12911 NONAME ; void QTextureGlyphCache::fillInPendingGlyphs(void) + ?font@QGlyphs@@QBE?AVQFont@@XZ @ 12912 NONAME ; class QFont QGlyphs::font(void) const + ?get@QFontPrivate@@SAPAV1@ABVQFont@@@Z @ 12913 NONAME ; class QFontPrivate * QFontPrivate::get(class QFont const &) + ?glyphIndexes@QGlyphs@@QBE?AV?$QVector@I@@XZ @ 12914 NONAME ; class QVector QGlyphs::glyphIndexes(void) const + ?glyphs@QTextFragment@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 12915 NONAME ; class QList QTextFragment::glyphs(void) const + ?glyphs@QTextLayout@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 12916 NONAME ; class QList QTextLayout::glyphs(void) const + ?glyphs@QTextLine@@ABE?AV?$QList@VQGlyphs@@@@HH@Z @ 12917 NONAME ; class QList QTextLine::glyphs(int, int) const + ?hasChildren@QAbstractProxyModel@@UBE_NABVQModelIndex@@@Z @ 12918 NONAME ; bool QAbstractProxyModel::hasChildren(class QModelIndex const &) const + ?hasHeightForWidth@QWidgetPrivate@@UBE_NXZ @ 12919 NONAME ; bool QWidgetPrivate::hasHeightForWidth(void) const + ?heightForWidth@QTabWidget@@UBEHH@Z @ 12920 NONAME ; int QTabWidget::heightForWidth(int) const + ?inFontUcs4@QFontMetrics@@QBE_NI@Z @ 12921 NONAME ; bool QFontMetrics::inFontUcs4(unsigned int) const + ?inFontUcs4@QFontMetricsF@@QBE_NI@Z @ 12922 NONAME ; bool QFontMetricsF::inFontUcs4(unsigned int) const + ?mimeData@QAbstractProxyModel@@UBEPAVQMimeData@@ABV?$QList@VQModelIndex@@@@@Z @ 12923 NONAME ; class QMimeData * QAbstractProxyModel::mimeData(class QList const &) const + ?mimeTypes@QAbstractProxyModel@@UBE?AVQStringList@@XZ @ 12924 NONAME ; class QStringList QAbstractProxyModel::mimeTypes(void) const + ?minimumSizeHint@QCheckBox@@UBE?AVQSize@@XZ @ 12925 NONAME ; class QSize QCheckBox::minimumSizeHint(void) const + ?minimumSizeHint@QRadioButton@@UBE?AVQSize@@XZ @ 12926 NONAME ; class QSize QRadioButton::minimumSizeHint(void) const + ?positions@QGlyphs@@QBE?AV?$QVector@VQPointF@@@@XZ @ 12927 NONAME ; class QVector QGlyphs::positions(void) const + ?removeItem@QGraphicsGridLayout@@QAEXPAVQGraphicsLayoutItem@@@Z @ 12928 NONAME ; void QGraphicsGridLayout::removeItem(class QGraphicsLayoutItem *) + ?resizeCache@QTextureGlyphCache@@QAEXHH@Z @ 12929 NONAME ; void QTextureGlyphCache::resizeCache(int, int) + ?setFont@QGlyphs@@QAEXABVQFont@@@Z @ 12930 NONAME ; void QGlyphs::setFont(class QFont const &) + ?setGlyphIndexes@QGlyphs@@QAEXABV?$QVector@I@@@Z @ 12931 NONAME ; void QGlyphs::setGlyphIndexes(class QVector const &) + ?setItemData@QAbstractProxyModel@@UAE_NABVQModelIndex@@ABV?$QMap@HVQVariant@@@@@Z @ 12932 NONAME ; bool QAbstractProxyModel::setItemData(class QModelIndex const &, class QMap const &) + ?setPositions@QGlyphs@@QAEXABV?$QVector@VQPointF@@@@@Z @ 12933 NONAME ; void QGlyphs::setPositions(class QVector const &) + ?sort@QAbstractProxyModel@@UAEXHW4SortOrder@Qt@@@Z @ 12934 NONAME ; void QAbstractProxyModel::sort(int, enum Qt::SortOrder) + ?span@QAbstractProxyModel@@UBE?AVQSize@@ABVQModelIndex@@@Z @ 12935 NONAME ; class QSize QAbstractProxyModel::span(class QModelIndex const &) const + ?supportedDropActions@QAbstractProxyModel@@UBE?AV?$QFlags@W4DropAction@Qt@@@@XZ @ 12936 NONAME ; class QFlags QAbstractProxyModel::supportedDropActions(void) const diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index 46c4885..b1b3b65 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -620,8 +620,8 @@ EXPORTS _ZN14QObjectPrivate11clearGuardsEP7QObject @ 619 NONAME _ZN14QObjectPrivate13addConnectionEiPNS_10ConnectionE @ 620 NONAME _ZN14QObjectPrivate14deleteChildrenEv @ 621 NONAME - _ZN14QObjectPrivate14setDeleteWatchEPS_Pi @ 622 NONAME - _ZN14QObjectPrivate16resetDeleteWatchEPS_Pii @ 623 NONAME + _ZN14QObjectPrivate14setDeleteWatchEPS_Pi @ 622 NONAME ABSENT + _ZN14QObjectPrivate16resetDeleteWatchEPS_Pii @ 623 NONAME ABSENT _ZN14QObjectPrivate16setCurrentSenderEP7QObjectPNS_6SenderE @ 624 NONAME ABSENT _ZN14QObjectPrivate16setParent_helperEP7QObject @ 625 NONAME _ZN14QObjectPrivate18resetCurrentSenderEP7QObjectPNS_6SenderES3_ @ 626 NONAME ABSENT @@ -1274,8 +1274,8 @@ EXPORTS _ZN23QCoreApplicationPrivate34sendThroughApplicationEventFiltersEP7QObjectP6QEvent @ 1273 NONAME _ZN23QCoreApplicationPrivate35appendApplicationPathToLibraryPathsEv @ 1274 NONAME _ZN23QCoreApplicationPrivate7attribsE @ 1275 NONAME DATA 4 - _ZN23QCoreApplicationPrivateC1ERiPPc @ 1276 NONAME - _ZN23QCoreApplicationPrivateC2ERiPPc @ 1277 NONAME + _ZN23QCoreApplicationPrivateC1ERiPPc @ 1276 NONAME ABSENT + _ZN23QCoreApplicationPrivateC2ERiPPc @ 1277 NONAME ABSENT _ZN23QCoreApplicationPrivateD0Ev @ 1278 NONAME _ZN23QCoreApplicationPrivateD1Ev @ 1279 NONAME _ZN23QCoreApplicationPrivateD2Ev @ 1280 NONAME @@ -3711,4 +3711,42 @@ EXPORTS _ZN16QIODevicePrivate4peekEx @ 3710 NONAME _ZN8QProcess18setNativeArgumentsERK7QString @ 3711 NONAME _ZNK8QProcess15nativeArgumentsEv @ 3712 NONAME + _ZN11QThreadPool11waitForDoneEi @ 3713 NONAME + _ZN13QSharedMemory12setNativeKeyERK7QString @ 3714 NONAME + _ZN16QCoreApplicationC1ERiPPci @ 3715 NONAME + _ZN16QCoreApplicationC2ERiPPci @ 3716 NONAME + _ZN23QCoreApplicationPrivate19app_compile_versionE @ 3717 NONAME DATA 4 + _ZN23QCoreApplicationPrivateC1ERiPPcj @ 3718 NONAME + _ZN23QCoreApplicationPrivateC2ERiPPcj @ 3719 NONAME + _ZN6QMutex12lockInternalEv @ 3720 NONAME + _ZN6QMutex14unlockInternalEv @ 3721 NONAME + _ZN7QObject10disconnectEPKS_RK11QMetaMethodS1_S4_ @ 3722 NONAME + _ZN7QObject7connectEPKS_RK11QMetaMethodS1_S4_N2Qt14ConnectionTypeE @ 3723 NONAME + _ZNK10QStringRef10startsWithE13QLatin1StringN2Qt15CaseSensitivityE @ 3724 NONAME + _ZNK10QStringRef10startsWithE5QCharN2Qt15CaseSensitivityE @ 3725 NONAME + _ZNK10QStringRef10startsWithERK7QStringN2Qt15CaseSensitivityE @ 3726 NONAME + _ZNK10QStringRef10startsWithERKS_N2Qt15CaseSensitivityE @ 3727 NONAME + _ZNK10QStringRef11lastIndexOfE13QLatin1StringiN2Qt15CaseSensitivityE @ 3728 NONAME + _ZNK10QStringRef11lastIndexOfE5QChariN2Qt15CaseSensitivityE @ 3729 NONAME + _ZNK10QStringRef11lastIndexOfERK7QStringiN2Qt15CaseSensitivityE @ 3730 NONAME + _ZNK10QStringRef11lastIndexOfERKS_iN2Qt15CaseSensitivityE @ 3731 NONAME + _ZNK10QStringRef5countE5QCharN2Qt15CaseSensitivityE @ 3732 NONAME + _ZNK10QStringRef5countERK7QStringN2Qt15CaseSensitivityE @ 3733 NONAME + _ZNK10QStringRef5countERKS_N2Qt15CaseSensitivityE @ 3734 NONAME + _ZNK10QStringRef7indexOfE13QLatin1StringiN2Qt15CaseSensitivityE @ 3735 NONAME + _ZNK10QStringRef7indexOfE5QChariN2Qt15CaseSensitivityE @ 3736 NONAME + _ZNK10QStringRef7indexOfERK7QStringiN2Qt15CaseSensitivityE @ 3737 NONAME + _ZNK10QStringRef7indexOfERKS_iN2Qt15CaseSensitivityE @ 3738 NONAME + _ZNK10QStringRef8endsWithE13QLatin1StringN2Qt15CaseSensitivityE @ 3739 NONAME + _ZNK10QStringRef8endsWithE5QCharN2Qt15CaseSensitivityE @ 3740 NONAME + _ZNK10QStringRef8endsWithERK7QStringN2Qt15CaseSensitivityE @ 3741 NONAME + _ZNK10QStringRef8endsWithERKS_N2Qt15CaseSensitivityE @ 3742 NONAME + _ZNK13QSharedMemory9nativeKeyEv @ 3743 NONAME + _ZNK4QUrl11isLocalFileEv @ 3744 NONAME + _ZNK7QObject17senderSignalIndexEv @ 3745 NONAME + _ZNK7QString10startsWithERK10QStringRefN2Qt15CaseSensitivityE @ 3746 NONAME + _ZNK7QString11lastIndexOfERK10QStringRefiN2Qt15CaseSensitivityE @ 3747 NONAME + _ZNK7QString5countERK10QStringRefN2Qt15CaseSensitivityE @ 3748 NONAME + _ZNK7QString7indexOfERK10QStringRefiN2Qt15CaseSensitivityE @ 3749 NONAME + _ZNK7QString8endsWithERK10QStringRefN2Qt15CaseSensitivityE @ 3750 NONAME diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index d8e86bf..6f26918 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -4324,7 +4324,7 @@ EXPORTS _ZN19QApplicationPrivate18dispatchEnterLeaveEP7QWidgetS1_ @ 4323 NONAME _ZN19QApplicationPrivate18resolveS60ScanCodeEij @ 4324 NONAME _ZN19QApplicationPrivate18wheel_scroll_linesE @ 4325 NONAME DATA 4 - _ZN19QApplicationPrivate19app_compile_versionE @ 4326 NONAME DATA 4 + _ZN19QApplicationPrivate19app_compile_versionE @ 4326 NONAME DATA 4 ABSENT _ZN19QApplicationPrivate19hidden_focus_widgetE @ 4327 NONAME DATA 4 _ZN19QApplicationPrivate19keyboard_input_timeE @ 4328 NONAME DATA 4 _ZN19QApplicationPrivate20emitLastWindowClosedEv @ 4329 NONAME @@ -4356,8 +4356,8 @@ EXPORTS _ZN19QApplicationPrivate9constructEv @ 4355 NONAME _ZN19QApplicationPrivate9fade_menuE @ 4356 NONAME DATA 1 _ZN19QApplicationPrivate9openPopupEP7QWidget @ 4357 NONAME - _ZN19QApplicationPrivateC1ERiPPcN12QApplication4TypeE @ 4358 NONAME - _ZN19QApplicationPrivateC2ERiPPcN12QApplication4TypeE @ 4359 NONAME + _ZN19QApplicationPrivateC1ERiPPcN12QApplication4TypeE @ 4358 NONAME ABSENT + _ZN19QApplicationPrivateC2ERiPPcN12QApplication4TypeE @ 4359 NONAME ABSENT _ZN19QApplicationPrivateD0Ev @ 4360 NONAME _ZN19QApplicationPrivateD1Ev @ 4361 NONAME _ZN19QApplicationPrivateD2Ev @ 4362 NONAME @@ -12091,4 +12091,54 @@ EXPORTS _ZN14QGraphicsScale13xScaleChangedEv @ 12090 NONAME _ZN14QGraphicsScale13yScaleChangedEv @ 12091 NONAME _ZN14QGraphicsScale13zScaleChangedEv @ 12092 NONAME + _ZN18QTextureGlyphCache19fillInPendingGlyphsEv @ 12093 NONAME + _ZN19QAbstractProxyModel11setItemDataERK11QModelIndexRK4QMapIi8QVariantE @ 12094 NONAME + _ZN19QAbstractProxyModel4sortEiN2Qt9SortOrderE @ 12095 NONAME + _ZN19QAbstractProxyModel9fetchMoreERK11QModelIndex @ 12096 NONAME + _ZN19QApplicationPrivate14_q_aboutToQuitEv @ 12097 NONAME + _ZN19QApplicationPrivateC1ERiPPcN12QApplication4TypeEi @ 12098 NONAME + _ZN19QApplicationPrivateC2ERiPPcN12QApplication4TypeEi @ 12099 NONAME + _ZN19QGraphicsGridLayout10removeItemEP19QGraphicsLayoutItem @ 12100 NONAME + _ZN6QImage4fillEN2Qt11GlobalColorE @ 12101 NONAME + _ZN6QImage4fillERK6QColor @ 12102 NONAME + _ZN7QGlyphs12setPositionsERK7QVectorI7QPointFE @ 12103 NONAME + _ZN7QGlyphs15setGlyphIndexesERK7QVectorIjE @ 12104 NONAME + _ZN7QGlyphs5clearEv @ 12105 NONAME + _ZN7QGlyphs6detachEv @ 12106 NONAME + _ZN7QGlyphs7setFontERK5QFont @ 12107 NONAME + _ZN7QGlyphsC1ERKS_ @ 12108 NONAME + _ZN7QGlyphsC1Ev @ 12109 NONAME + _ZN7QGlyphsC2ERKS_ @ 12110 NONAME + _ZN7QGlyphsC2Ev @ 12111 NONAME + _ZN7QGlyphsD1Ev @ 12112 NONAME + _ZN7QGlyphsD2Ev @ 12113 NONAME + _ZN7QGlyphsaSERKS_ @ 12114 NONAME + _ZN7QGlyphspLERKS_ @ 12115 NONAME + _ZN8QPainter10drawGlyphsERK7QPointFRK7QGlyphs @ 12116 NONAME + _ZNK10QTabWidget14heightForWidthEi @ 12117 NONAME + _ZNK11QFontEngine18createExplicitFontEv @ 12118 NONAME + _ZNK11QFontEngine26createExplicitFontWithNameERK7QString @ 12119 NONAME + _ZNK11QTextLayout6glyphsEv @ 12120 NONAME + _ZNK12QFontMetrics10inFontUcs4Ej @ 12121 NONAME + _ZNK12QRadioButton15minimumSizeHintEv @ 12122 NONAME + _ZNK13QFontMetricsF10inFontUcs4Ej @ 12123 NONAME + _ZNK13QTextFragment6glyphsEv @ 12124 NONAME + _ZNK14QWidgetPrivate17hasHeightForWidthEv @ 12125 NONAME + _ZNK16QFileSystemModel5rmdirERK11QModelIndex @ 12126 NONAME + _ZNK19QAbstractProxyModel11hasChildrenERK11QModelIndex @ 12127 NONAME + _ZNK19QAbstractProxyModel12canFetchMoreERK11QModelIndex @ 12128 NONAME + _ZNK19QAbstractProxyModel20supportedDropActionsEv @ 12129 NONAME + _ZNK19QAbstractProxyModel4spanERK11QModelIndex @ 12130 NONAME + _ZNK19QAbstractProxyModel5buddyERK11QModelIndex @ 12131 NONAME + _ZNK19QAbstractProxyModel8mimeDataERK5QListI11QModelIndexE @ 12132 NONAME + _ZNK19QAbstractProxyModel9mimeTypesEv @ 12133 NONAME + _ZNK7QGlyphs12glyphIndexesEv @ 12134 NONAME + _ZNK7QGlyphs4fontEv @ 12135 NONAME + _ZNK7QGlyphs9positionsEv @ 12136 NONAME + _ZNK7QGlyphseqERKS_ @ 12137 NONAME + _ZNK7QGlyphsneERKS_ @ 12138 NONAME + _ZNK7QGlyphsplERKS_ @ 12139 NONAME + _ZNK8QPainter16clipBoundingRectEv @ 12140 NONAME + _ZNK9QCheckBox15minimumSizeHintEv @ 12141 NONAME + _ZNK9QTextLine6glyphsEii @ 12142 NONAME -- cgit v0.12 From 050fa9f6cc1145f5a835420b9974a6b0e261b062 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Tue, 7 Sep 2010 16:51:55 +0200 Subject: Add baseName and completeBaseName getters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using the definition of the concepts from QFileInfo, allow us to use the already calculated indexes to fetch the baseName and the completeBaseName on a QFileSystemEntry. Reviewed-by: João Abecasis --- src/corelib/io/qfilesystementry.cpp | 26 +++++++++++--- src/corelib/io/qfilesystementry_p.h | 2 ++ .../auto/qfilesystementry/tst_qfilesystementry.cpp | 40 +++++++++++++++------- 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index f5009b4..6f04c21 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -149,10 +149,8 @@ QString QFileSystemEntry::fileName() const { findLastSeparator(); #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) - if (m_lastSeparator == -1) { - if (m_filePath.length() >= 2 && m_filePath.at(1) == QLatin1Char(':')) - return m_filePath.mid(2); - } + if (m_lastSeparator == -1 && m_filePath.length() >= 2 && m_filePath.at(1) == QLatin1Char(':')) + return m_filePath.mid(2); #endif return m_filePath.mid(m_lastSeparator + 1); } @@ -176,6 +174,26 @@ QString QFileSystemEntry::path() const return m_filePath.left(m_lastSeparator); } +QString QFileSystemEntry::baseName() const +{ + findFileNameSeparators(); +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + if (m_lastSeparator == -1 && m_filePath.length() >= 2 && m_filePath.at(1) == QLatin1Char(':')) + return m_filePath.mid(2); +#endif + return m_filePath.mid(m_lastSeparator + 1, m_firstDotInFileName == -1 ?-1 : m_firstDotInFileName - 1); +} + +QString QFileSystemEntry::completeBaseName() const +{ + findFileNameSeparators(); +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + if (m_lastSeparator == -1 && m_filePath.length() >= 2 && m_filePath.at(1) == QLatin1Char(':')) + return m_filePath.mid(2); +#endif + return m_filePath.mid(m_lastSeparator + 1, m_firstDotInFileName == -1 ?-1 : m_firstDotInFileName + m_lastDotInFileName - 1); +} + QString QFileSystemEntry::suffix() const { findFileNameSeparators(); diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index 6b2cedd..5a41782 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -83,6 +83,8 @@ public: QString fileName() const; QString path() const; NativePath nativeFilePath() const; + QString baseName() const; + QString completeBaseName() const; QString suffix() const; QString completeSuffix() const; bool isAbsolute() const; diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp index 5194c02..0fa63b5 100644 --- a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp +++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp @@ -65,6 +65,8 @@ void tst_QFileSystemEntry::getSetCheck_data() QTest::addColumn("internalnativeFilePath"); QTest::addColumn("filepath"); QTest::addColumn("filename"); + QTest::addColumn("baseName"); + QTest::addColumn("completeBasename"); QTest::addColumn("suffix"); QTest::addColumn("completeSuffix"); QTest::addColumn("absolute"); @@ -78,33 +80,33 @@ void tst_QFileSystemEntry::getSetCheck_data() << QString("A:\\home\\qt\\in\\a\\dir.tar.gz") << absPrefix + QString("A:\\home\\qt\\in\\a\\dir.tar.gz") << "A:/home/qt/in/a/dir.tar.gz" - << "dir.tar.gz" << "gz" << "tar.gz" << true; + << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << true; QTest::newRow("relative") << QString("in\\a\\dir.tar.gz") << relPrefix + QString("in\\a\\dir.tar.gz") << "in/a/dir.tar.gz" - << "dir.tar.gz" << "gz" << "tar.gz" << false; + << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << false; QTest::newRow("noSuffix") << QString("myDir\\myfile") << relPrefix + QString("myDir\\myfile") - << "myDir/myfile" << "myfile" << "" << "" << false; + << "myDir/myfile" << "myfile" << "myfile" << "myfile" << "" << "" << false; QTest::newRow("noLongSuffix") << QString("myDir\\myfile.txt") << relPrefix + QString("myDir\\myfile.txt") - << "myDir/myfile.txt" << "myfile.txt" << "txt" << "txt" << false; + << "myDir/myfile.txt" << "myfile.txt" << "myfile" << "myfile" << "txt" << "txt" << false; QTest::newRow("endingSlash") << QString("myDir\\myfile.bla\\") << relPrefix + QString("myDir\\myfile.bla\\") - << "myDir/myfile.bla/" << "" << "" << "" << false; + << "myDir/myfile.bla/" << "" << "" << "" << "" << "" << false; QTest::newRow("absolutePath") << QString("A:dir\\without\\leading\\backslash.bat") << absPrefix + QString("A:\\dir\\without\\leading\\backslash.bat") - << "A:dir/without/leading/backslash.bat" << "backslash.bat" << "bat" << "bat" << true; + << "A:dir/without/leading/backslash.bat" << "backslash.bat" << << "backslash" << "backslash" << "bat" << "bat" << true; } void tst_QFileSystemEntry::getSetCheck() @@ -113,6 +115,8 @@ void tst_QFileSystemEntry::getSetCheck() QFETCH(QString, internalnativeFilePath); QFETCH(QString, filepath); QFETCH(QString, filename); + QFETCH(QString, basename); + QFETCH(QString, completeBasename); QFETCH(QString, suffix); QFETCH(QString, completeSuffix); QFETCH(bool, absolute); @@ -125,6 +129,8 @@ void tst_QFileSystemEntry::getSetCheck() QCOMPARE(entry1.completeSuffix(), completeSuffix); QCOMPARE(entry1.isAbsolute(), absolute); QCOMPARE(entry1.isRelative(), !absolute); + QCOMPARE(entry1.baseName(), basename); + QCOMPARE(entry1.completeBaseName(), completeBasename); QFileSystemEntry entry2(nativeFilePath, QFileSystemEntry::FromNativePath()); QCOMPARE(entry2.suffix(), suffix); @@ -136,6 +142,8 @@ void tst_QFileSystemEntry::getSetCheck() // the object shouldnot change nativeFilePath. QCOMPARE(entry2.nativeFilePath(), nativeFilePath); QCOMPARE(entry2.fileName(), filename); + QCOMPARE(entry2.baseName(), basename); + QCOMPARE(entry2.completeBaseName(), completeBasename); } #else @@ -145,6 +153,8 @@ void tst_QFileSystemEntry::getSetCheck_data() QTest::addColumn("nativeFilePath"); QTest::addColumn("filepath"); QTest::addColumn("filename"); + QTest::addColumn("basename"); + QTest::addColumn("completeBasename"); QTest::addColumn("suffix"); QTest::addColumn("completeSuffix"); QTest::addColumn("absolute"); @@ -152,27 +162,27 @@ void tst_QFileSystemEntry::getSetCheck_data() QTest::newRow("simple") << QByteArray("/home/qt/in/a/dir.tar.gz") << "/home/qt/in/a/dir.tar.gz" - << "dir.tar.gz" << "gz" << "tar.gz" << true; + << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << true; QTest::newRow("relative") << QByteArray("in/a/dir.tar.gz") << "in/a/dir.tar.gz" - << "dir.tar.gz" << "gz" << "tar.gz" << false; + << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << false; QTest::newRow("noSuffix") << QByteArray("myDir/myfile") - << "myDir/myfile" << "myfile" << "" << "" << false; + << "myDir/myfile" << "myfile" << "myfile" << "myfile" << "" << "" << false; QTest::newRow("noLongSuffix") << QByteArray("myDir/myfile.txt") - << "myDir/myfile.txt" << "myfile.txt" << "txt" << "txt" << false; + << "myDir/myfile.txt" << "myfile.txt" << "myfile" << "myfile" << "txt" << "txt" << false; QTest::newRow("endingSlash") << QByteArray("myDir/myfile.bla/") - << "myDir/myfile.bla/" << "" << "" << "" << false; + << "myDir/myfile.bla/" << "" << "" << "" << "" << "" << false; QTest::newRow("relativePath") << QByteArray("A:dir/without/leading/backslash.bat") - << "A:dir/without/leading/backslash.bat" << "backslash.bat" << "bat" << "bat" << false; + << "A:dir/without/leading/backslash.bat" << "backslash.bat" << "backslash" << "backslash" << "bat" << "bat" << false; } void tst_QFileSystemEntry::getSetCheck() @@ -180,6 +190,8 @@ void tst_QFileSystemEntry::getSetCheck() QFETCH(QByteArray, nativeFilePath); QFETCH(QString, filepath); QFETCH(QString, filename); + QFETCH(QString, basename); + QFETCH(QString, completeBasename); QFETCH(QString, suffix); QFETCH(QString, completeSuffix); QFETCH(bool, absolute); @@ -192,6 +204,8 @@ void tst_QFileSystemEntry::getSetCheck() QCOMPARE(entry1.completeSuffix(), completeSuffix); QCOMPARE(entry1.isAbsolute(), absolute); QCOMPARE(entry1.isRelative(), !absolute); + QCOMPARE(entry1.baseName(), basename); + QCOMPARE(entry1.completeBaseName(), completeBasename); QFileSystemEntry entry2(nativeFilePath, QFileSystemEntry::FromNativePath()); QCOMPARE(entry2.suffix(), suffix); @@ -201,6 +215,8 @@ void tst_QFileSystemEntry::getSetCheck() QCOMPARE(entry2.filePath(), filepath); QCOMPARE(entry2.nativeFilePath(), nativeFilePath); QCOMPARE(entry2.fileName(), filename); + QCOMPARE(entry2.baseName(), basename); + QCOMPARE(entry2.completeBaseName(), completeBasename); } #endif -- cgit v0.12 From e34c6ac1146d7bb97da88805764d9fa90763b6b5 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Tue, 7 Sep 2010 17:36:04 +0200 Subject: Various fixes in suffix and other entry methods. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added lots of unit tests (inspired from qfileinfo) and found plenty of bugs that I fixed. Reviewed-by: João Abecasis --- src/corelib/io/qfilesystementry.cpp | 25 ++-- .../auto/qfilesystementry/tst_qfilesystementry.cpp | 132 +++++++++++++++++++++ 2 files changed, 150 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index 6f04c21..733a226 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -181,7 +181,13 @@ QString QFileSystemEntry::baseName() const if (m_lastSeparator == -1 && m_filePath.length() >= 2 && m_filePath.at(1) == QLatin1Char(':')) return m_filePath.mid(2); #endif - return m_filePath.mid(m_lastSeparator + 1, m_firstDotInFileName == -1 ?-1 : m_firstDotInFileName - 1); + int length = -1; + if (m_firstDotInFileName >= 0) { + length = m_firstDotInFileName; + if (m_lastSeparator != -1) // avoid off by one + length--; + } + return m_filePath.mid(m_lastSeparator + 1, length); } QString QFileSystemEntry::completeBaseName() const @@ -191,7 +197,13 @@ QString QFileSystemEntry::completeBaseName() const if (m_lastSeparator == -1 && m_filePath.length() >= 2 && m_filePath.at(1) == QLatin1Char(':')) return m_filePath.mid(2); #endif - return m_filePath.mid(m_lastSeparator + 1, m_firstDotInFileName == -1 ?-1 : m_firstDotInFileName + m_lastDotInFileName - 1); + int length = -1; + if (m_firstDotInFileName >= 0) { + length = m_firstDotInFileName + m_lastDotInFileName; + if (m_lastSeparator != -1) // avoid off by one + length--; + } + return m_filePath.mid(m_lastSeparator + 1, length); } QString QFileSystemEntry::suffix() const @@ -201,7 +213,7 @@ QString QFileSystemEntry::suffix() const if (m_lastDotInFileName == -1) return QString(); - return m_filePath.mid(m_lastSeparator + m_firstDotInFileName + m_lastDotInFileName + 1); + return m_filePath.mid(qMax((qint16)0, m_lastSeparator) + m_firstDotInFileName + m_lastDotInFileName + 1); } QString QFileSystemEntry::completeSuffix() const @@ -210,7 +222,7 @@ QString QFileSystemEntry::completeSuffix() const if (m_firstDotInFileName == -1) return QString(); - return m_filePath.mid(m_lastSeparator + m_firstDotInFileName + 1); + return m_filePath.mid(qMax((qint16)0, m_lastSeparator) + m_firstDotInFileName + 1); } bool QFileSystemEntry::isAbsolute() const @@ -310,15 +322,14 @@ void QFileSystemEntry::findFileNameSeparators() const } } } - m_lastSeparator = lastSeparator; - m_firstDotInFileName = firstDotInFileName == -1 ? -1 : firstDotInFileName - lastSeparator; + m_firstDotInFileName = firstDotInFileName == -1 ? -1 : firstDotInFileName - qMax(0, lastSeparator); if (lastDotInFileName == -1) m_lastDotInFileName = -1; else if (firstDotInFileName == lastDotInFileName) m_lastDotInFileName = 0; else - m_lastDotInFileName = firstDotInFileName - lastSeparator; + m_lastDotInFileName = lastDotInFileName - firstDotInFileName; } } diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp index 0fa63b5..267fa8c 100644 --- a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp +++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp @@ -56,6 +56,14 @@ class tst_QFileSystemEntry : public QObject private slots: void getSetCheck_data(); void getSetCheck(); + void suffix_data(); + void suffix(); + void completeSuffix_data(); + void completeSuffix(); + void baseName_data(); + void baseName(); + void completeBaseName_data(); + void completeBaseName(); }; #if defined(WIN_STUFF) @@ -220,5 +228,129 @@ void tst_QFileSystemEntry::getSetCheck() } #endif +void tst_QFileSystemEntry::suffix_data() +{ + QTest::addColumn("file"); + QTest::addColumn("expected"); + + QTest::newRow("noextension0") << "file" << ""; + QTest::newRow("noextension1") << "/path/to/file" << ""; + QTest::newRow("data0") << "file.tar" << "tar"; + QTest::newRow("data1") << "file.tar.gz" << "gz"; + QTest::newRow("data2") << "/path/file/file.tar.gz" << "gz"; + QTest::newRow("data3") << "/path/file.tar" << "tar"; + QTest::newRow("hidden1") << ".ext1" << "ext1"; + QTest::newRow("hidden1") << ".ext" << "ext"; + QTest::newRow("hidden1") << ".ex" << "ex"; + QTest::newRow("hidden1") << ".e" << "e"; + QTest::newRow("hidden2") << ".ext1.ext2" << "ext2"; + QTest::newRow("hidden2") << ".ext.ext2" << "ext2"; + QTest::newRow("hidden2") << ".ex.ext2" << "ext2"; + QTest::newRow("hidden2") << ".e.ext2" << "ext2"; + QTest::newRow("hidden2") << "..ext2" << "ext2"; + QTest::newRow("dots") << "/path/file.with.dots/file..ext2" << "ext2"; + QTest::newRow("dots2") << "/path/file.with.dots/.file..ext2" << "ext2"; +} + +void tst_QFileSystemEntry::suffix() +{ + QFETCH(QString, file); + QFETCH(QString, expected); + + QFileSystemEntry fe(file); + QCOMPARE(fe.suffix(), expected); + + QFileSystemEntry fi2(file); + // first resolve the last slash + (void) fi2.path(); + QCOMPARE(fi2.suffix(), expected); +} + +void tst_QFileSystemEntry::completeSuffix_data() +{ + QTest::addColumn("file"); + QTest::addColumn("expected"); + + QTest::newRow("noextension0") << "file" << ""; + QTest::newRow("noextension1") << "/path/to/file" << ""; + QTest::newRow("data0") << "file.tar" << "tar"; + QTest::newRow("data1") << "file.tar.gz" << "tar.gz"; + QTest::newRow("data2") << "/path/file/file.tar.gz" << "tar.gz"; + QTest::newRow("data3") << "/path/file.tar" << "tar"; + QTest::newRow("dots") << "/path/file.with.dots/file..ext2" << ".ext2"; + QTest::newRow("dots2") << "/path/file.with.dots/.file..ext2" << "file..ext2"; +} + +void tst_QFileSystemEntry::completeSuffix() +{ + QFETCH(QString, file); + QFETCH(QString, expected); + + QFileSystemEntry fi(file); + QCOMPARE(fi.completeSuffix(), expected); + + QFileSystemEntry fi2(file); + // first resolve the last slash + (void) fi2.path(); + QCOMPARE(fi2.completeSuffix(), expected); +} + +void tst_QFileSystemEntry::baseName_data() +{ + QTest::addColumn("file"); + QTest::addColumn("expected"); + + QTest::newRow("data0") << "file.tar" << "file"; + QTest::newRow("data1") << "file.tar.gz" << "file"; + QTest::newRow("data2") << "/path/file/file.tar.gz" << "file"; + QTest::newRow("data3") << "/path/file.tar" << "file"; + QTest::newRow("data4") << "/path/file" << "file"; + QTest::newRow("dots") << "/path/file.with.dots/file..ext2" << "file"; + QTest::newRow("dots2") << "/path/file.with.dots/.file..ext2" << ""; +} + +void tst_QFileSystemEntry::baseName() +{ + QFETCH(QString, file); + QFETCH(QString, expected); + + QFileSystemEntry fi(file); + QCOMPARE(fi.baseName(), expected); + + QFileSystemEntry fi2(file); + // first resolve the last slash + (void) fi2.path(); + QCOMPARE(fi2.baseName(), expected); +} + +void tst_QFileSystemEntry::completeBaseName_data() +{ + QTest::addColumn("file"); + QTest::addColumn("expected"); + + QTest::newRow("data0") << "file.tar" << "file"; + QTest::newRow("data1") << "file.tar.gz" << "file.tar"; + QTest::newRow("data2") << "/path/file/file.tar.gz" << "file.tar"; + QTest::newRow("data3") << "/path/file.tar" << "file"; + QTest::newRow("data4") << "/path/file" << "file"; + QTest::newRow("dots") << "/path/file.with.dots/file..ext2" << "file."; + QTest::newRow("dots2") << "/path/file.with.dots/.file..ext2" << ".file."; +} + +void tst_QFileSystemEntry::completeBaseName() +{ + QFETCH(QString, file); + QFETCH(QString, expected); + + QFileSystemEntry fi(file); + QCOMPARE(fi.completeBaseName(), expected); + + QFileSystemEntry fi2(file); + // first resolve the last slash + (void) fi2.path(); + QCOMPARE(fi2.completeBaseName(), expected); +} + + QTEST_MAIN(tst_QFileSystemEntry) #include -- cgit v0.12 From 881b7547c2be0dc2b7e223175b8c43e4bda78991 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 8 Sep 2010 14:38:06 +0200 Subject: Make QFileInfo use the new filesystemengine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The creation of a QAbstractFileEngine derived class will now be avoided if the file we are watching is on the native file system and from then on all access will be through the direct API Notice that for QFileInfo::path, isRelative, filePath, fileName, baseName, completeBaseName, completeSuffix and suffix we now use the QFileSystemEntry instead of asking the engine. This means that some buggy or just weird user provided engines no longer get used and as such we might not be bug compatible. Reviewed-by: João Abecasis --- src/corelib/io/qfileinfo.cpp | 213 ++++++++++++++++++++++++++------- src/corelib/io/qfileinfo_p.h | 19 ++- src/corelib/io/qfilesystemmetadata_p.h | 6 + tests/auto/qfileinfo/tst_qfileinfo.cpp | 7 +- 4 files changed, 195 insertions(+), 50 deletions(-) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 7eca212..232a32e 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -51,7 +51,47 @@ QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const { if (cache_enabled && !fileNames[(int)name].isNull()) return fileNames[(int)name]; - QString ret = fileEngine->fileName(name); + + QString ret; + if (fileEngine == 0) { // local file; use the QFileSystemEngine directly + switch (name) { + case QAbstractFileEngine::CanonicalName: + case QAbstractFileEngine::CanonicalPathName: { + QFileSystemEntry entry = QFileSystemEngine::canonicalName(fileEntry); + if (cache_enabled) { // be smart and store both + fileNames[QAbstractFileEngine::CanonicalName] = entry.filePath(); + fileNames[QAbstractFileEngine::CanonicalPathName] = entry.path(); + } + if (name == QAbstractFileEngine::CanonicalName) + ret = entry.filePath(); + else + ret = entry.path(); + break; + } + case QAbstractFileEngine::LinkName: + ret = QFileSystemEngine::getLinkTarget(fileEntry, metaData).filePath(); + break; + case QAbstractFileEngine::BundleName: + ret = QFileSystemEngine::bundleName(fileEntry); + break; + case QAbstractFileEngine::AbsoluteName: + case QAbstractFileEngine::AbsolutePathName: { + QFileSystemEntry entry = QFileSystemEngine::absoluteName(fileEntry); + if (cache_enabled) { // be smart and store both + fileNames[QAbstractFileEngine::AbsoluteName] = entry.filePath(); + fileNames[QAbstractFileEngine::AbsolutePathName] = entry.path(); + } + if (name == QAbstractFileEngine::AbsoluteName) + ret = entry.filePath(); + else + ret = entry.path(); + break; + } + default: break; + } + } else { + ret = fileEngine->fileName(name); + } if (ret.isNull()) ret = QLatin1String(""); if (cache_enabled) @@ -61,6 +101,7 @@ QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const QString QFileInfoPrivate::getFileOwner(QAbstractFileEngine::FileOwner own) const { + Q_ASSERT(fileEngine); // should never be called when using the native FS if (cache_enabled && !fileOwners[(int)own].isNull()) return fileOwners[(int)own]; QString ret = fileEngine->owner(own); @@ -73,6 +114,7 @@ QString QFileInfoPrivate::getFileOwner(QAbstractFileEngine::FileOwner own) const uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) const { + Q_ASSERT(fileEngine); // should never be called when using the native FS // We split the testing into tests for for LinkType, BundleType, PermsMask // and the rest. // Tests for file permissions on Windows can be slow, expecially on network @@ -133,6 +175,7 @@ uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) cons QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) const { + Q_ASSERT(fileEngine); // should never be called when using the native FS if (!cache_enabled) clearFlags(); uint cf; @@ -330,23 +373,23 @@ bool QFileInfo::operator==(const QFileInfo &fileinfo) const return true; if (d->isDefaultConstructed || fileinfo.d_ptr->isDefaultConstructed) return false; - if (d->fileEngine->caseSensitive() != fileinfo.d_ptr->fileEngine->caseSensitive()) - return false; - if (fileinfo.size() == size()) { //if the size isn't the same... - QString file1 = canonicalFilePath(), - file2 = fileinfo.canonicalFilePath(); - if (file1.length() == file2.length()) { - if (!fileinfo.d_ptr->fileEngine->caseSensitive()) { - for (int i = 0; i < file1.length(); i++) { - if (file1.at(i).toLower() != file2.at(i).toLower()) - return false; - } - return true; - } - return (file1 == file2); - } + Qt::CaseSensitivity sensitive; + if (d->fileEngine == 0 || fileinfo.d_ptr->fileEngine == 0) { + if (d->fileEngine != fileinfo.d_ptr->fileEngine) // one is native, the other is a custom file-engine + return false; + + sensitive = QFileSystemEngine::isCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive; + // if both are native just compare the canonicalFilePath of both. + } else { + if (d->fileEngine->caseSensitive() != fileinfo.d_ptr->fileEngine->caseSensitive()) + return false; + sensitive = d->fileEngine->caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive; } - return false; + + if (fileinfo.size() != size()) //if the size isn't the same... + return false; + + return canonicalFilePath().compare(fileinfo.canonicalFilePath(), sensitive) == 0; } /*! @@ -502,7 +545,7 @@ QString QFileInfo::absolutePath() const if (d->isDefaultConstructed) { return QLatin1String(""); - } else if (d->fileName.isEmpty()) { + } else if (d->fileEntry.isEmpty()) { qWarning("QFileInfo::absolutePath: Constructed with empty filename"); return QLatin1String(""); } @@ -539,7 +582,7 @@ QString QFileInfo::path() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return QLatin1String(""); - return d->getFileName(QAbstractFileEngine::PathName); + return d->fileEntry.path(); } /*! @@ -563,7 +606,7 @@ bool QFileInfo::isRelative() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return true; - return d->fileEngine->isRelativePath(); + return d->fileEntry.isRelative(); } /*! @@ -576,12 +619,10 @@ bool QFileInfo::isRelative() const bool QFileInfo::makeAbsolute() { if (d_ptr.constData()->isDefaultConstructed - || !d_ptr.constData()->fileEngine->isRelativePath()) + || !d_ptr.constData()->fileEntry.isRelative()) return false; - QString absFileName = d_ptr.constData()->getFileName(QAbstractFileEngine::AbsoluteName); - // QSharedDataPointer::operator->() will detach. - setFile(absFileName); + setFile(absoluteFilePath()); return true; } @@ -596,6 +637,11 @@ bool QFileInfo::exists() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return false; + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::ExistsAttribute)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::ExistsAttribute); + return d->metaData.exists(); + } return d->getFileFlags(QAbstractFileEngine::ExistsFlag); } @@ -623,7 +669,7 @@ QString QFileInfo::filePath() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return QLatin1String(""); - return d->getFileName(QAbstractFileEngine::DefaultName); + return d->fileEntry.filePath(); } /*! @@ -642,7 +688,7 @@ QString QFileInfo::fileName() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return QLatin1String(""); - return d->getFileName(QAbstractFileEngine::BaseName); + return d->fileEntry.fileName(); } /*! @@ -686,7 +732,7 @@ QString QFileInfo::baseName() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return QLatin1String(""); - return d->getFileName(QAbstractFileEngine::BaseName).section(QLatin1Char('.'), 0, 0); + return d->fileEntry.baseName(); } /*! @@ -705,9 +751,7 @@ QString QFileInfo::completeBaseName() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return QLatin1String(""); - QString name = d->getFileName(QAbstractFileEngine::BaseName); - int index = name.lastIndexOf(QLatin1Char('.')); - return (index == -1) ? name : name.left(index); + return d->fileEntry.completeBaseName(); } /*! @@ -726,11 +770,7 @@ QString QFileInfo::completeSuffix() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return QLatin1String(""); - QString fileName = d->getFileName(QAbstractFileEngine::BaseName); - int firstDot = fileName.indexOf(QLatin1Char('.')); - if (firstDot == -1) - return QLatin1String(""); - return fileName.mid(firstDot + 1); + return d->fileEntry.completeSuffix(); } /*! @@ -753,11 +793,7 @@ QString QFileInfo::suffix() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return QLatin1String(""); - QString fileName = d->getFileName(QAbstractFileEngine::BaseName); - int lastDot = fileName.lastIndexOf(QLatin1Char('.')); - if (lastDot == -1) - return QLatin1String(""); - return fileName.mid(lastDot + 1); + return d->fileEntry.suffix(); } @@ -781,8 +817,9 @@ QString QFileInfo::suffix() const */ QDir QFileInfo::dir() const { + Q_D(const QFileInfo); // ### Qt5: Maybe rename this to parentDirectory(), considering what it actually do? - return QDir(path()); + return QDir(d->fileEntry.path()); } /*! @@ -818,6 +855,11 @@ bool QFileInfo::isReadable() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return false; + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::UserReadPermission)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::UserReadPermission); + return (d->metaData.permissions() & QFile::ReadUser) != 0; + } return d->getFileFlags(QAbstractFileEngine::ReadUserPerm); } @@ -831,6 +873,11 @@ bool QFileInfo::isWritable() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return false; + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::UserWritePermission)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::UserWritePermission); + return (d->metaData.permissions() & QFile::WriteUser) != 0; + } return d->getFileFlags(QAbstractFileEngine::WriteUserPerm); } @@ -844,6 +891,11 @@ bool QFileInfo::isExecutable() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return false; + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::UserExecutePermission)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::UserExecutePermission); + return (d->metaData.permissions() & QFile::ExeUser) != 0; + } return d->getFileFlags(QAbstractFileEngine::ExeUserPerm); } @@ -858,6 +910,11 @@ bool QFileInfo::isHidden() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return false; + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::HiddenAttribute)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::HiddenAttribute); + return d->metaData.isHidden(); + } return d->getFileFlags(QAbstractFileEngine::HiddenFlag); } @@ -873,6 +930,11 @@ bool QFileInfo::isFile() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return false; + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::FileType)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::FileType); + return d->metaData.isFile(); + } return d->getFileFlags(QAbstractFileEngine::FileType); } @@ -887,6 +949,11 @@ bool QFileInfo::isDir() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return false; + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::DirectoryType)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::DirectoryType); + return d->metaData.isDirectory(); + } return d->getFileFlags(QAbstractFileEngine::DirectoryType); } @@ -903,6 +970,11 @@ bool QFileInfo::isBundle() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return false; + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::BundleType)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::BundleType); + return d->metaData.isBundle(); + } return d->getFileFlags(QAbstractFileEngine::BundleType); } @@ -928,6 +1000,11 @@ bool QFileInfo::isSymLink() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return false; + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::LinkType)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::LinkType); + return d->metaData.isLink(); + } return d->getFileFlags(QAbstractFileEngine::LinkType); } @@ -941,6 +1018,8 @@ bool QFileInfo::isRoot() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return true; + if (d->fileEngine == 0) + return d->fileEntry.isRoot(); return d->getFileFlags(QAbstractFileEngine::RootFlag); } @@ -987,6 +1066,11 @@ QString QFileInfo::owner() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return QLatin1String(""); + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::UserName)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::UserName); + return d->metaData.user(); + } return d->getFileOwner(QAbstractFileEngine::OwnerUser); } @@ -1003,6 +1087,11 @@ uint QFileInfo::ownerId() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return 0; + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::UserId)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::UserId); + return d->metaData.userId(); + } return d->fileEngine->ownerId(QAbstractFileEngine::OwnerUser); } @@ -1021,6 +1110,11 @@ QString QFileInfo::group() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return QLatin1String(""); + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::GroupName)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::GroupName); + return d->metaData.group(); + } return d->getFileOwner(QAbstractFileEngine::OwnerGroup); } @@ -1037,6 +1131,11 @@ uint QFileInfo::groupId() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return 0; + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::GroupId)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::GroupId); + return d->metaData.groupId(); + } return d->fileEngine->ownerId(QAbstractFileEngine::OwnerGroup); } @@ -1058,6 +1157,13 @@ bool QFileInfo::permission(QFile::Permissions permissions) const Q_D(const QFileInfo); if (d->isDefaultConstructed) return false; + if (d->fileEngine == 0) { + // the QFileSystemMetaData::MetaDataFlag and QFile::Permissions overlap, so just static cast. + QFileSystemMetaData::MetaDataFlag permissionFlags = static_cast((int)permissions); + if (!d->cache_enabled || !d->metaData.hasFlags(permissionFlags)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, permissionFlags); + return (d->metaData.permissions() & permissions) == permissions; + } return d->getFileFlags(QAbstractFileEngine::FileFlags((int)permissions)) == (uint)permissions; } @@ -1070,6 +1176,11 @@ QFile::Permissions QFileInfo::permissions() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return 0; + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::Permissions)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::Permissions); + return d->metaData.permissions(); + } return QFile::Permissions(d->getFileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask); } @@ -1085,6 +1196,11 @@ qint64 QFileInfo::size() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return 0; + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::SizeAttribute)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::SizeAttribute); + return d->metaData.size(); + } if (!d->getCachedFlag(QFileInfoPrivate::CachedSize)) { d->setCachedFlag(QFileInfoPrivate::CachedSize); d->fileSize = d->fileEngine->size(); @@ -1110,6 +1226,11 @@ QDateTime QFileInfo::created() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return QDateTime(); + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::CreationTime)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::CreationTime); + return d->metaData.creationTime(); + } return d->getFileTime(QAbstractFileEngine::CreationTime); } @@ -1123,6 +1244,11 @@ QDateTime QFileInfo::lastModified() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return QDateTime(); + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::ModificationTime)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::ModificationTime); + return d->metaData.modificationTime(); + } return d->getFileTime(QAbstractFileEngine::ModificationTime); } @@ -1139,6 +1265,11 @@ QDateTime QFileInfo::lastRead() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return QDateTime(); + if (d->fileEngine == 0) { + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::AccessTime)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::AccessTime); + return d->metaData.accessTime(); + } return d->getFileTime(QAbstractFileEngine::AccessTime); } diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h index b9b1092..a97d4d3 100644 --- a/src/corelib/io/qfileinfo_p.h +++ b/src/corelib/io/qfileinfo_p.h @@ -58,13 +58,14 @@ #include "qdatetime.h" #include "qatomic.h" #include "qshareddata.h" +#include "qfilesystementry_p.h" +#include "qfilesystemengine_p.h" QT_BEGIN_NAMESPACE class QFileInfoPrivate : public QSharedData { public: - enum { CachedFileFlags=0x01, CachedLinkTypeFlag=0x02, CachedBundleTypeFlag=0x04, CachedMTime=0x10, CachedCTime=0x20, CachedATime=0x40, CachedSize =0x08, CachedPerms=0x80 }; @@ -76,8 +77,10 @@ public: cache_enabled(true), fileFlags(0), fileSize(0) {} inline QFileInfoPrivate(const QFileInfoPrivate ©) - : QSharedData(copy), fileEngine(QAbstractFileEngine::create(copy.fileName)), - fileName(copy.fileName), + : QSharedData(copy), + fileEntry(copy.fileEntry), + metaData(copy.metaData), + fileEngine(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)), cachedFlags(0), #ifndef QT_NO_FSFILEENGINE isDefaultConstructed(false), @@ -87,8 +90,8 @@ public: cache_enabled(copy.cache_enabled), fileFlags(0), fileSize(0) {} inline QFileInfoPrivate(const QString &file) - : QSharedData(), fileEngine(QAbstractFileEngine::create(file)), - fileName(file), + : fileEntry(file), + fileEngine(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)), cachedFlags(0), #ifndef QT_NO_FSFILEENGINE isDefaultConstructed(false), @@ -106,6 +109,7 @@ public: (void)fileEngine->fileFlags(QAbstractFileEngine::Refresh); } inline void clear() { + metaData.clear(); clearFlags(); for (int i = QAbstractFileEngine::NFileNames - 1 ; i >= 0 ; --i) fileNames[i].clear(); @@ -118,9 +122,11 @@ public: QString getFileName(QAbstractFileEngine::FileName) const; QString getFileOwner(QAbstractFileEngine::FileOwner own) const; + QFileSystemEntry fileEntry; + mutable QFileSystemMetaData metaData; + QScopedPointer const fileEngine; - mutable QString fileName; mutable QString fileNames[QAbstractFileEngine::NFileNames]; mutable QString fileOwners[2]; @@ -134,6 +140,7 @@ public: { return cache_enabled ? (cachedFlags & c) : 0; } inline void setCachedFlag(uint c) const { if (cache_enabled) cachedFlags |= c; } + }; QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index f140319..a506fa4 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -134,6 +134,9 @@ struct QFileSystemMetaData OwnerIds = UserId | GroupId, + UserName = 0x40000000, + GroupName = 0x80000000, + PosixStatFlags = QFileSystemMetaData::OtherPermissions | QFileSystemMetaData::GroupPermissions | QFileSystemMetaData::OwnerPermissions @@ -224,6 +227,9 @@ struct QFileSystemMetaData uint userId() const { return userId_; } uint groupId() const { return groupId_; } + QString user() const { return QString(); /* TODO */ } + QString group() const { return QString(); /* TODO */ } + uint ownerId(QAbstractFileEngine::FileOwner owner) const { if (owner == QAbstractFileEngine::OwnerUser) diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 08cb68d..cced207 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -1255,9 +1255,10 @@ void tst_QFileInfo::isLocalFs() QFileInfo info(path); QFileInfoPrivate *privateInfo = getPrivate(info); - QVERIFY(privateInfo->fileEngine); - QCOMPARE(bool(privateInfo->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag) - & QAbstractFileEngine::LocalDiskFlag), isLocalFs); + QCOMPARE((privateInfo->fileEngine == 0), isLocalFs); + if (privateInfo->fileEngine) + QCOMPARE(bool(privateInfo->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag) + & QAbstractFileEngine::LocalDiskFlag), isLocalFs); } void tst_QFileInfo::refresh() -- cgit v0.12 From 2e0ccea933efa503607f455450ce5d7374ecc395 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Thu, 9 Sep 2010 12:18:36 +0200 Subject: Fix warning of unused variable on non-symbian --- src/corelib/io/qfsfileengine_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index e4c6f09..c6e7300 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -491,8 +491,8 @@ qint64 QFSFileEnginePrivate::nativeReadLine(char *data, qint64 maxlen) */ qint64 QFSFileEnginePrivate::nativeWrite(const char *data, qint64 len) { - Q_Q(QFSFileEngine); #ifdef Q_OS_SYMBIAN + Q_Q(QFSFileEngine); if (symbianFile.SubSessionHandle()) { if(len > KMaxTInt) { //this check is more likely to catch a corrupt length, since it isn't possible to allocate 2GB buffers (yet..) -- cgit v0.12 From 99cc67240494e06297df3876163b40f79b861c36 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Thu, 9 Sep 2010 13:25:06 +0200 Subject: Make compile on symbian / armcc --- src/corelib/io/qfilesystemengine_symbian.cpp | 2 +- src/corelib/io/qfilesystemiterator_symbian.cpp | 2 +- src/corelib/io/qfilesystemmetadata_p.h | 4 +++- tests/auto/qfilesystementry/tst_qfilesystementry.cpp | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 1205274..759aafd 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -41,7 +41,7 @@ #include "qfilesystemengine_p.h" #include "qfsfileengine.h" -#include "qcore_symbian_p.h" +#include #include diff --git a/src/corelib/io/qfilesystemiterator_symbian.cpp b/src/corelib/io/qfilesystemiterator_symbian.cpp index 9093599..106eda9 100644 --- a/src/corelib/io/qfilesystemiterator_symbian.cpp +++ b/src/corelib/io/qfilesystemiterator_symbian.cpp @@ -41,7 +41,7 @@ #include "qfilesystemiterator_p.h" #include "qfilesystemengine_p.h" -#include "qcore_symbian_p.h" +#include QT_BEGIN_NAMESPACE diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index a506fa4..1164d42 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -62,7 +62,7 @@ #if defined(Q_OS_WIN) #elif defined(Q_OS_SYMBIAN) #include -#include "qdatetime_p.h" +#include #else #endif @@ -253,6 +253,8 @@ struct QFileSystemMetaData } uint userId() const { return (uint) -2; } uint groupId() const { return (uint) -2; } + QString user() const { return QString(); } + QString group() const { return QString(); } uint ownerId(QAbstractFileEngine::FileOwner owner) const { Q_UNUSED(owner); diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp index 267fa8c..e00a214 100644 --- a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp +++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp @@ -114,7 +114,7 @@ void tst_QFileSystemEntry::getSetCheck_data() QTest::newRow("absolutePath") << QString("A:dir\\without\\leading\\backslash.bat") << absPrefix + QString("A:\\dir\\without\\leading\\backslash.bat") - << "A:dir/without/leading/backslash.bat" << "backslash.bat" << << "backslash" << "backslash" << "bat" << "bat" << true; + << "A:dir/without/leading/backslash.bat" << "backslash.bat" << "backslash" << "backslash" << "bat" << "bat" << true; } void tst_QFileSystemEntry::getSetCheck() -- cgit v0.12 From 5baa2d0da807ec5b4635c891ec27125769bade2d Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 9 Sep 2010 11:28:11 +0100 Subject: Fix tst_qdiriterator for symbian Since 21e0423a, the directory structure for iteration is created by the test on initialisation. Furthermore the directory structure no longer exists in git, causing a build error at the deployment stage. Also, defined Q_NO_SYMLINKS to disable test cases related to symlinks Reviewed-By: joao --- tests/auto/qdiriterator/qdiriterator.pro | 5 ----- tests/auto/qdiriterator/tst_qdiriterator.cpp | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/auto/qdiriterator/qdiriterator.pro b/tests/auto/qdiriterator/qdiriterator.pro index d60b52d..0a154d6 100644 --- a/tests/auto/qdiriterator/qdiriterator.pro +++ b/tests/auto/qdiriterator/qdiriterator.pro @@ -3,10 +3,5 @@ SOURCES += tst_qdiriterator.cpp RESOURCES += qdiriterator.qrc QT = core -wince*|symbian: { - addFiles.sources = entrylist recursiveDirs foo - addFiles.path = . - DEPLOYMENT += addFiles wince*mips*|wincewm50smart-msvc200*: DEFINES += WINCE_BROKEN_ITERATE=1 -} diff --git a/tests/auto/qdiriterator/tst_qdiriterator.cpp b/tests/auto/qdiriterator/tst_qdiriterator.cpp index 1a873b8..f78ce34 100644 --- a/tests/auto/qdiriterator/tst_qdiriterator.cpp +++ b/tests/auto/qdiriterator/tst_qdiriterator.cpp @@ -53,7 +53,7 @@ #endif #if defined(Q_OS_SYMBIAN) -// Open C in Symbian doesn't support symbolic links to directories +#define Q_NO_SYMLINKS #define Q_NO_SYMLINKS_TO_DIRS #endif -- cgit v0.12 From 113a56eb0c88cdee3209dcf16af8bc51ccef080d Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 9 Sep 2010 14:54:47 +0100 Subject: backward compatibility fix for QFileInfo::isRoot() In the old system, QFileInfo("p:/").isRoot() would return false because the file engine first checks exists(). Assuming P: is not mounted that would return false. This change makes QFileInfo::isRoot() check the drive exists. Reviewed-By: joao --- src/corelib/io/qfileinfo.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 232a32e..5d632d3 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -1018,8 +1018,20 @@ bool QFileInfo::isRoot() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return true; - if (d->fileEngine == 0) - return d->fileEntry.isRoot(); + if (d->fileEngine == 0) { + if (d->fileEntry.isRoot()) { +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + //the path is a drive root, but the drive may not exist + //for backward compatibility, return true only if the drive exists + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::ExistsAttribute)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::ExistsAttribute); + return d->metaData.exists(); +#else + return true; +#endif + } + return false; + } return d->getFileFlags(QAbstractFileEngine::RootFlag); } -- cgit v0.12 From 87c150517b36ac89f17f2455494dc63fccdb5727 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 9 Sep 2010 16:13:21 +0100 Subject: Create QFileSystemEntry objects with / as directory separator It simplifies the code for users of QFileSystemEntry to assume that filePath() returns / seperated paths, and nativeFilePath returns paths using the native dir separator (e.g. \) Reviewed-By: joao --- src/corelib/io/qfileinfo_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h index a97d4d3..6db84c4 100644 --- a/src/corelib/io/qfileinfo_p.h +++ b/src/corelib/io/qfileinfo_p.h @@ -90,7 +90,7 @@ public: cache_enabled(copy.cache_enabled), fileFlags(0), fileSize(0) {} inline QFileInfoPrivate(const QString &file) - : fileEntry(file), + : fileEntry(QDir::fromNativeSeparators(file)), fileEngine(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)), cachedFlags(0), #ifndef QT_NO_FSFILEENGINE -- cgit v0.12 From e2f34f6b77c8ddb39a6983648818a25236ddeebb Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 9 Sep 2010 16:15:57 +0100 Subject: Set size and modification time to 0 if file does not exist Since we report the size and modification time as known in the knownFlags() for non existant files, they need to be set to something. In particular, size is used in QFileInfo comparisons. Reviewed-By: joao --- src/corelib/io/qfilesystemengine_symbian.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 759aafd..e725147 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -194,6 +194,10 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM if (!err) data.fillFromTEntry(ent); } + if (err) { + data.size_ = 0; + data.modificationTime_ = TTime(0); + } data.knownFlagsMask |= QFileSystemMetaData::SymbianTEntryFlags; } return data.hasFlags(what); -- cgit v0.12 From 30dcb614f31d64f052312b65bdd7720974b809d4 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 9 Sep 2010 17:05:33 +0100 Subject: Set file metadata variables to known values when stat fails For unix port, set file times and size to 0, and owner/group id to -2 (nobody) for files that don't exist. Also implemented saving owner and group ids in fillFromStatBuf, which was missing. Reviewed-by: joao --- src/corelib/io/qfilesystemengine.cpp | 2 ++ src/corelib/io/qfilesystemengine_unix.cpp | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index 0563a15..56072d4 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -280,6 +280,8 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) creationTime_ = statBuffer.st_ctime ? statBuffer.st_ctime : statBuffer.st_mtime; modificationTime_ = statBuffer.st_mtime; accessTime_ = statBuffer.st_atime; + userId_ = statBuffer.st_uid; + groupId_ = statBuffer.st_gid; #endif } diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 8d77963..65cb42f 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -343,8 +343,15 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM if (statBufferValid) data.fillFromStatBuf(statBuffer); - else + else { entryExists = false; + data.creationTime_ = 0; + data.modificationTime_ = 0; + data.accessTime_ = 0; + data.size_ = 0; + data.userId_ = (uint) -2; + data.groupId_ = (uint) -2; + } // reset the mask data.knownFlagsMask |= QFileSystemMetaData::PosixStatFlags -- cgit v0.12 From 1a3d4eaf52669eff4e48d2f8a2d62c41347bf8d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 10 Sep 2010 09:15:27 +0200 Subject: Fixing QDir/tree traverseDirectory benchmark Was missing counter initialization at the start of QBENCHMARK loop. --- tests/benchmarks/corelib/io/qdir/tree/bench_qdir_tree.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/benchmarks/corelib/io/qdir/tree/bench_qdir_tree.cpp b/tests/benchmarks/corelib/io/qdir/tree/bench_qdir_tree.cpp index ad5ae98..cbe931d 100644 --- a/tests/benchmarks/corelib/io/qdir/tree/bench_qdir_tree.cpp +++ b/tests/benchmarks/corelib/io/qdir/tree/bench_qdir_tree.cpp @@ -154,6 +154,7 @@ private slots: QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks); + count = 0; while (iterator.hasNext()) { iterator.next(); ++count; -- cgit v0.12 From 5f0e9b7666c689a8b7ea23eefa5a7a68b0a0ed78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 10 Sep 2010 09:46:56 +0200 Subject: Minor clean up on QDirIterator Removing unnecessary garbage, inlining a destructor. --- src/corelib/io/qdiriterator.cpp | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index fd4b9c1..3544d87 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -102,21 +102,17 @@ QT_BEGIN_NAMESPACE class QDirIteratorPrivateIteratorStack : public QStack { public: - ~QDirIteratorPrivateIteratorStack(); + ~QDirIteratorPrivateIteratorStack() + { + qDeleteAll(*this); + } }; -QDirIteratorPrivateIteratorStack::~QDirIteratorPrivateIteratorStack() -{ - qDeleteAll(*this); -} - - class QDirIteratorPrivate { public: QDirIteratorPrivate(const QString &path, const QStringList &nameFilters, QDir::Filters filters, QDirIterator::IteratorFlags flags); - ~QDirIteratorPrivate(); void advance(); @@ -141,8 +137,6 @@ public: // Loop protection QSet visitedLinks; - - QDirIterator *q; }; /*! @@ -173,13 +167,6 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList /*! \internal */ -QDirIteratorPrivate::~QDirIteratorPrivate() -{ -} - -/*! - \internal -*/ void QDirIteratorPrivate::pushDirectory(const QFileInfo &fileInfo) { QString path = fileInfo.filePath(); @@ -375,7 +362,6 @@ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInf QDirIterator::QDirIterator(const QDir &dir, IteratorFlags flags) : d(new QDirIteratorPrivate(dir.path(), dir.nameFilters(), dir.filter(), flags)) { - d->q = this; } /*! @@ -397,7 +383,6 @@ QDirIterator::QDirIterator(const QDir &dir, IteratorFlags flags) QDirIterator::QDirIterator(const QString &path, QDir::Filters filters, IteratorFlags flags) : d(new QDirIteratorPrivate(path, QStringList(), filters, flags)) { - d->q = this; } /*! @@ -415,7 +400,6 @@ QDirIterator::QDirIterator(const QString &path, QDir::Filters filters, IteratorF QDirIterator::QDirIterator(const QString &path, IteratorFlags flags) : d(new QDirIteratorPrivate(path, QStringList(), QDir::NoFilter, flags)) { - d->q = this; } /*! @@ -438,7 +422,6 @@ QDirIterator::QDirIterator(const QString &path, const QStringList &nameFilters, QDir::Filters filters, IteratorFlags flags) : d(new QDirIteratorPrivate(path, nameFilters, filters, flags)) { - d->q = this; } /*! -- cgit v0.12 From 4506d57fc0320234efcd4ab39e2fe9c2810b4d3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 10 Sep 2010 10:21:18 +0200 Subject: QFileinfo: fix isSymLink on Mac On Mac OS X, we also flag Alias Records as symbolic links. Since we now make the distinction in the engine, we need to query for it explicitly. Added a new type LegacyLinkType to QFileSystemMetaData to document this old behavior. --- src/corelib/io/qfileinfo.cpp | 6 +++--- src/corelib/io/qfilesystemmetadata_p.h | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 5d632d3..68f1f55 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -1001,9 +1001,9 @@ bool QFileInfo::isSymLink() const if (d->isDefaultConstructed) return false; if (d->fileEngine == 0) { - if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::LinkType)) - QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::LinkType); - return d->metaData.isLink(); + if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::LegacyLinkType)) + QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::LegacyLinkType); + return d->metaData.isLegacyLink(); } return d->getFileFlags(QAbstractFileEngine::LinkType); } diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 1164d42..9df762c 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -112,6 +112,8 @@ struct QFileSystemMetaData #endif SequentialType = 0x00800000, // Note: overlaps with QAbstractFileEngine::RootFlag + LegacyLinkType = LinkType | AliasType, + Type = LinkType | FileType | DirectoryType | BundleType | SequentialType | AliasType, // Attributes @@ -195,6 +197,7 @@ struct QFileSystemMetaData bool isBundle() const { return false; } bool isAlias() const { return false; } #endif + bool isLegacyLink() const { return (entryFlags & LegacyLinkType); } bool isSequential() const { return (entryFlags & SequentialType); } bool isHidden() const { return (entryFlags & HiddenAttribute); } -- cgit v0.12 From 529aa7d39f8eab70a954f02ac1ac5a6bac9889bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 10 Sep 2010 14:17:12 +0200 Subject: Fix QFileInfo::isHidden on Mac Having HiddenAttribute as part of PosixStatFlags, meant that we would assume we knew about it whenever we stat'ed, which wasn't the intent. As that is just one of the queries we do on Mac OS to determine if a file is considered hidden. Instead, we explicitly ask for a stat anytime the attribute is queried for. The proper fix will be to perform the cheap operations (e.g., file name begins with '.') first and only stat if we still haven't got an answer. --- src/corelib/io/qfilesystemengine_unix.cpp | 7 +++++++ src/corelib/io/qfilesystemmetadata_p.h | 4 ---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 65cb42f..eb6b9f1 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -300,6 +300,13 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM } #endif +#if !defined(QWS) && defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if (what & QFileSystemMetaData::HiddenAttribute) { + // Mac OS >= 10.5: st_flags & UF_HIDDEN + what |= QFileSystemMetaData::PosixStatFlags; + } +#endif + if (what & QFileSystemMetaData::PosixStatFlags) what |= QFileSystemMetaData::PosixStatFlags; diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 9df762c..c34cc1e 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -145,10 +145,6 @@ struct QFileSystemMetaData | QFileSystemMetaData::FileType | QFileSystemMetaData::DirectoryType | QFileSystemMetaData::SequentialType -#if !defined(QWS) && defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - // Mac OS >= 10.5: st_flags & UF_HIDDEN - | QFileSystemMetaData::HiddenAttribute -#endif | QFileSystemMetaData::SizeAttribute | QFileSystemMetaData::Times | QFileSystemMetaData::OwnerIds, -- cgit v0.12 From 69b8cf630e9cc83cd678814bf88495c7fbb438f4 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 10 Sep 2010 13:42:53 +0100 Subject: Move OS specific inlines outside of class declaration This makes it easier to read, as common functions with different implementations depending on the OS are only declared once in the class. Reviewed-By: joao --- src/corelib/io/qfilesystemmetadata_p.h | 140 +++++++++++++++++++-------------- 1 file changed, 79 insertions(+), 61 deletions(-) diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index c34cc1e..f7bc863 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -70,8 +70,9 @@ QT_BEGIN_NAMESPACE class QFileSystemEngine; -struct QFileSystemMetaData +class QFileSystemMetaData { +public: QFileSystemMetaData() : knownFlagsMask(0) { @@ -186,13 +187,8 @@ struct QFileSystemMetaData bool isLink() const { return (entryFlags & LinkType); } bool isFile() const { return (entryFlags & FileType); } bool isDirectory() const { return (entryFlags & DirectoryType); } -#if !defined(QWS) && defined(Q_OS_MAC) - bool isBundle() const { return (entryFlags & BundleType); } - bool isAlias() const { return (entryFlags & AliasType); } -#else - bool isBundle() const { return false; } - bool isAlias() const { return false; } -#endif + bool isBundle() const; + bool isAlias() const; bool isLegacyLink() const { return (entryFlags & LegacyLinkType); } bool isSequential() const { return (entryFlags & SequentialType); } bool isHidden() const { return (entryFlags & HiddenAttribute); } @@ -201,65 +197,21 @@ struct QFileSystemMetaData QFile::Permissions permissions() const { return QFile::Permissions(Permissions & entryFlags); } -#if defined(Q_OS_UNIX) && !defined (Q_OS_SYMBIAN) - QDateTime creationTime() const { return QDateTime::fromTime_t(creationTime_); } - QDateTime modificationTime() const { return QDateTime::fromTime_t(modificationTime_); } - QDateTime accessTime() const { return QDateTime::fromTime_t(accessTime_); } - - QDateTime fileTime(QAbstractFileEngine::FileTime time) const - { - switch (time) - { - case QAbstractFileEngine::ModificationTime: - return modificationTime(); - - case QAbstractFileEngine::AccessTime: - return accessTime(); - - case QAbstractFileEngine::CreationTime: - return creationTime(); - } - - return QDateTime(); - } - - uint userId() const { return userId_; } - uint groupId() const { return groupId_; } + QDateTime creationTime() const; + QDateTime modificationTime() const; + QDateTime accessTime() const; - QString user() const { return QString(); /* TODO */ } - QString group() const { return QString(); /* TODO */ } + QDateTime fileTime(QAbstractFileEngine::FileTime time) const; + uint userId() const; + uint groupId() const; + QString user() const; + QString group() const; + uint ownerId(QAbstractFileEngine::FileOwner owner) const; - uint ownerId(QAbstractFileEngine::FileOwner owner) const - { - if (owner == QAbstractFileEngine::OwnerUser) - return userId(); - else - return groupId(); - } -#endif #ifdef Q_OS_UNIX void fillFromStatBuf(const QT_STATBUF &statBuffer); #endif #ifdef Q_OS_SYMBIAN - QDateTime creationTime() const { return modificationTime(); } - QDateTime modificationTime() const { return qt_symbian_TTime_To_QDateTime(modificationTime_); } - QDateTime accessTime() const { return modificationTime(); } - - QDateTime fileTime(QAbstractFileEngine::FileTime time) const - { - Q_UNUSED(time); - return modificationTime(); - } - uint userId() const { return (uint) -2; } - uint groupId() const { return (uint) -2; } - QString user() const { return QString(); } - QString group() const { return QString(); } - uint ownerId(QAbstractFileEngine::FileOwner owner) const - { - Q_UNUSED(owner); - return (uint) -2; - } - void fillFromTEntry(const TEntry& entry); void fillFromVolumeInfo(const TVolumeInfo& info); #endif @@ -289,6 +241,72 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(QFileSystemMetaData::MetaDataFlags) +#if !defined(QWS) && defined(Q_OS_MAC) +inline bool QFileSystemMetaData::isBundle() const { return (entryFlags & BundleType); } +inline bool QFileSystemMetaData::isAlias() const { return (entryFlags & AliasType); } +#else +inline bool QFileSystemMetaData::isBundle() const { return false; } +inline bool QFileSystemMetaData::isAlias() const { return false; } +#endif + +#if defined(Q_OS_UNIX) && !defined (Q_OS_SYMBIAN) +inline QDateTime QFileSystemMetaData::creationTime() const { return QDateTime::fromTime_t(creationTime_); } +inline QDateTime QFileSystemMetaData::modificationTime() const { return QDateTime::fromTime_t(modificationTime_); } +inline QDateTime QFileSystemMetaData::accessTime() const { return QDateTime::fromTime_t(accessTime_); } + +inline QDateTime QFileSystemMetaData::fileTime(QAbstractFileEngine::FileTime time) const +{ + switch (time) + { + case QAbstractFileEngine::ModificationTime: + return modificationTime(); + + case QAbstractFileEngine::AccessTime: + return accessTime(); + + case QAbstractFileEngine::CreationTime: + return creationTime(); + } + + return QDateTime(); +} + +inline uint QFileSystemMetaData::userId() const { return userId_; } +inline uint QFileSystemMetaData::groupId() const { return groupId_; } + +inline QString QFileSystemMetaData::user() const { return QString(); /* TODO */ } +inline QString QFileSystemMetaData::group() const { return QString(); /* TODO */ } + +inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) const +{ + if (owner == QAbstractFileEngine::OwnerUser) + return userId(); + else + return groupId(); +} +#endif + +#ifdef Q_OS_SYMBIAN +inline QDateTime QFileSystemMetaData::creationTime() const { return modificationTime(); } +inline QDateTime QFileSystemMetaData::modificationTime() const { return qt_symbian_TTime_To_QDateTime(modificationTime_); } +inline QDateTime QFileSystemMetaData::accessTime() const { return modificationTime(); } + +inline QDateTime QFileSystemMetaData::fileTime(QAbstractFileEngine::FileTime time) const +{ + Q_UNUSED(time); + return modificationTime(); +} +inline uint QFileSystemMetaData::userId() const { return (uint) -2; } +inline uint QFileSystemMetaData::groupId() const { return (uint) -2; } +inline QString QFileSystemMetaData::user() const { return QString(); } +inline QString QFileSystemMetaData::group() const { return QString(); } +inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) const +{ + Q_UNUSED(owner); + return (uint) -2; +} +#endif + QT_END_NAMESPACE #endif // include guard -- cgit v0.12 From cc23ac99d68af5c9bf537e5451b7ee7c7698e954 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Fri, 10 Sep 2010 15:15:43 +0200 Subject: Move resolving of user/group name to the engine. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: João Abecasis --- src/corelib/io/qfileinfo.cpp | 25 +++++++++++++------------ src/corelib/io/qfilesystemengine.cpp | 16 ++++++++++++++++ src/corelib/io/qfilesystemengine_p.h | 4 ++++ src/corelib/io/qfilesystemengine_symbian.cpp | 12 ++++++++++++ src/corelib/io/qfilesystemengine_unix.cpp | 12 ++++++++++++ src/corelib/io/qfilesystemengine_win.cpp | 12 ++++++++++++ src/corelib/io/qfilesystemmetadata_p.h | 13 +------------ 7 files changed, 70 insertions(+), 24 deletions(-) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 68f1f55..d49ee74 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -101,10 +101,21 @@ QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const QString QFileInfoPrivate::getFileOwner(QAbstractFileEngine::FileOwner own) const { - Q_ASSERT(fileEngine); // should never be called when using the native FS if (cache_enabled && !fileOwners[(int)own].isNull()) return fileOwners[(int)own]; - QString ret = fileEngine->owner(own); + QString ret; + if (fileEngine == 0) { + switch (own) { + case QAbstractFileEngine::OwnerUser: + ret = QFileSystemEngine::resolveUserName(fileEntry, metaData); + break; + case QAbstractFileEngine::OwnerGroup: + ret = QFileSystemEngine::resolveGroupName(fileEntry, metaData); + break; + } + } else { + ret = fileEngine->owner(own); + } if (ret.isNull()) ret = QLatin1String(""); if (cache_enabled) @@ -1078,11 +1089,6 @@ QString QFileInfo::owner() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return QLatin1String(""); - if (d->fileEngine == 0) { - if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::UserName)) - QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::UserName); - return d->metaData.user(); - } return d->getFileOwner(QAbstractFileEngine::OwnerUser); } @@ -1122,11 +1128,6 @@ QString QFileInfo::group() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return QLatin1String(""); - if (d->fileEngine == 0) { - if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::GroupName)) - QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::GroupName); - return d->metaData.group(); - } return d->getFileOwner(QAbstractFileEngine::OwnerGroup); } diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index 56072d4..cbc4c42 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -287,4 +287,20 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) #endif +//static +QString QFileSystemEngine::resolveUserName(const QFileSystemEntry &entry, QFileSystemMetaData &metaData) +{ + if (!metaData.hasFlags(QFileSystemMetaData::UserId)) + QFileSystemEngine::fillMetaData(entry, metaData, QFileSystemMetaData::UserId); + return resolveGroupName(metaData.userId()); +} + +//static +QString QFileSystemEngine::resolveGroupName(const QFileSystemEntry &entry, QFileSystemMetaData &metaData) +{ + if (!metaData.hasFlags(QFileSystemMetaData::GroupId)) + QFileSystemEngine::fillMetaData(entry, metaData, QFileSystemMetaData::GroupId); + return resolveGroupName(metaData.groupId()); +} + QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 94fb4e5..94a8175 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -67,6 +67,10 @@ public: static QFileSystemEntry getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data); static QFileSystemEntry canonicalName(const QFileSystemEntry &entry); static QFileSystemEntry absoluteName(const QFileSystemEntry &entry); + static QString resolveUserName(const QFileSystemEntry &entry, QFileSystemMetaData &data); + static QString resolveUserName(uint userId); + static QString resolveGroupName(const QFileSystemEntry &entry, QFileSystemMetaData &data); + static QString resolveGroupName(uint groupId); static QString bundleName(const QFileSystemEntry &entry); diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index e725147..1ed4ee8 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -124,6 +124,18 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) } //static +QString QFileSystemEngine::resolveUserName(uint userId) +{ + return QString(); // TODO +} + +//static +QString QFileSystemEngine::resolveGroupName(uint groupId) +{ + return QString(); // TODO +} + +//static QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) { Q_UNUSED(entry); diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index eb6b9f1..fdb881f 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -267,6 +267,18 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) } //static +QString QFileSystemEngine::resolveUserName(uint userId) +{ + return QString(); // TODO +} + +//static +QString QFileSystemEngine::resolveGroupName(uint groupId) +{ + return QString(); // TODO +} + +//static QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) { #if !defined(QWS) && defined(Q_OS_MAC) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 8572506..28d5db4 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -67,6 +67,18 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) } //static +QString QFileSystemEngine::resolveUserName(uint userId) +{ + return QString(); // TODO +} + +//static +QString QFileSystemEngine::resolveGroupName(uint groupId) +{ + return QString(); // TODO +} + +//static QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) { return QString(); diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index f7bc863..ec25a0b 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -137,9 +137,6 @@ public: OwnerIds = UserId | GroupId, - UserName = 0x40000000, - GroupName = 0x80000000, - PosixStatFlags = QFileSystemMetaData::OtherPermissions | QFileSystemMetaData::GroupPermissions | QFileSystemMetaData::OwnerPermissions @@ -204,8 +201,6 @@ public: QDateTime fileTime(QAbstractFileEngine::FileTime time) const; uint userId() const; uint groupId() const; - QString user() const; - QString group() const; uint ownerId(QAbstractFileEngine::FileOwner owner) const; #ifdef Q_OS_UNIX @@ -256,8 +251,7 @@ inline QDateTime QFileSystemMetaData::accessTime() const { return QDa inline QDateTime QFileSystemMetaData::fileTime(QAbstractFileEngine::FileTime time) const { - switch (time) - { + switch (time) { case QAbstractFileEngine::ModificationTime: return modificationTime(); @@ -274,9 +268,6 @@ inline QDateTime QFileSystemMetaData::fileTime(QAbstractFileEngine::FileTime tim inline uint QFileSystemMetaData::userId() const { return userId_; } inline uint QFileSystemMetaData::groupId() const { return groupId_; } -inline QString QFileSystemMetaData::user() const { return QString(); /* TODO */ } -inline QString QFileSystemMetaData::group() const { return QString(); /* TODO */ } - inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) const { if (owner == QAbstractFileEngine::OwnerUser) @@ -298,8 +289,6 @@ inline QDateTime QFileSystemMetaData::fileTime(QAbstractFileEngine::FileTime tim } inline uint QFileSystemMetaData::userId() const { return (uint) -2; } inline uint QFileSystemMetaData::groupId() const { return (uint) -2; } -inline QString QFileSystemMetaData::user() const { return QString(); } -inline QString QFileSystemMetaData::group() const { return QString(); } inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) const { Q_UNUSED(owner); -- cgit v0.12 From 8f40161a7932e901a9f6fe59b5b3d2666c5482c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 10 Sep 2010 17:25:14 +0200 Subject: QDirIterator: Use new native iterators when possible Native iterators interface allows propagation of meta data gathered during directory traversal. Reviewed-by: Shane Kearns --- src/corelib/io/qdiriterator.cpp | 99 +++++++++++++++++++++++++++++++---------- src/corelib/io/qfileinfo.cpp | 7 +++ src/corelib/io/qfileinfo.h | 4 ++ src/corelib/io/qfileinfo_p.h | 14 +++++- 4 files changed, 100 insertions(+), 24 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 3544d87..2e67bfd 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -97,9 +97,17 @@ #include #include +#include +#include +#include +#include +#include +#include + QT_BEGIN_NAMESPACE -class QDirIteratorPrivateIteratorStack : public QStack +template +class QDirIteratorPrivateIteratorStack : public QStack { public: ~QDirIteratorPrivateIteratorStack() @@ -116,6 +124,7 @@ public: void advance(); + bool entryMatches(const QString & fileName, const QFileInfo &fileInfo); void pushDirectory(const QFileInfo &fileInfo); void checkAndPushDirectory(const QFileInfo &); bool matchesFilters(const QString &fileName, const QFileInfo &fi) const; @@ -131,7 +140,9 @@ public: QVector nameRegExps; #endif - QDirIteratorPrivateIteratorStack fileEngineIterators; + QDirIteratorPrivateIteratorStack fileEngineIterators; + QDirIteratorPrivateIteratorStack nativeIterators; + QFileInfo currentFileInfo; QFileInfo nextFileInfo; @@ -144,8 +155,7 @@ public: */ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList &nameFilters, QDir::Filters filters, QDirIterator::IteratorFlags flags) - : engine(QAbstractFileEngine::create(path)) - , path(path) + : path(path) , nameFilters(nameFilters.contains(QLatin1String("*")) ? QStringList() : nameFilters) , filters(QDir::NoFilter == filters ? QDir::AllEntries : filters) , iteratorFlags(flags) @@ -159,8 +169,19 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList QRegExp::Wildcard)); #endif +#ifdef Q_OS_UNIX + QFileSystemEntry fileEntry(path); + QFileSystemMetaData metaData; + + engine.reset(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)); + QFileInfo fileInfo(new QFileInfoPrivate(fileEntry, metaData)); +#else + engine.reset(QAbstractFileEngine::create(path)); + QFileInfo fileInfo(path); +#endif + // Populate fields for hasNext() and next() - pushDirectory(QFileInfo(path)); + pushDirectory(fileInfo); advance(); } @@ -188,34 +209,63 @@ void QDirIteratorPrivate::pushDirectory(const QFileInfo &fileInfo) } else { // No iterator; no entry list. } + } else { + QFileSystemIterator *it = new QFileSystemIterator(fileInfo.d_ptr->fileEntry, + filters, nameFilters, iteratorFlags); + nativeIterators << it; } } -/*! - \internal -*/ -void QDirIteratorPrivate::advance() +inline bool QDirIteratorPrivate::entryMatches(const QString & fileName, const QFileInfo &fileInfo) { - while (!fileEngineIterators.isEmpty()) { + checkAndPushDirectory(fileInfo); - // Find the next valid iterator that matches the filters. - while (fileEngineIterators.top()->hasNext()) { - QAbstractFileEngineIterator *it = fileEngineIterators.top(); - it->next(); + if (matchesFilters(fileName, fileInfo)) { + currentFileInfo = nextFileInfo; + nextFileInfo = fileInfo; - const QFileInfo info = it->currentFileInfo(); - checkAndPushDirectory(it->currentFileInfo()); + //We found a matching entry. + return true; + } - if (matchesFilters(it->currentFileName(), info)) { - currentFileInfo = nextFileInfo; - nextFileInfo = info; + return false; +} - //We found a matching entry. - return; +/*! + \internal +*/ +void QDirIteratorPrivate::advance() +{ + if (engine) { + while (!fileEngineIterators.isEmpty()) { + // Find the next valid iterator that matches the filters. + QAbstractFileEngineIterator *it; + while (it = fileEngineIterators.top(), it->hasNext()) { + it->next(); + if (entryMatches(it->currentFileName(), it->currentFileInfo())) + return; } + + fileEngineIterators.pop(); + delete it; } + } else { + QFileSystemEntry nextEntry; + QFileSystemMetaData nextMetaData; + + while (!nativeIterators.isEmpty()) { + // Find the next valid iterator that matches the filters. + QFileSystemIterator *it; + while (it = nativeIterators.top(), it->advance(nextEntry, nextMetaData)) { + QFileInfo info(new QFileInfoPrivate(nextEntry, nextMetaData)); + + if (entryMatches(nextEntry.fileName(), info)) + return; + } - delete fileEngineIterators.pop(); + nativeIterators.pop(); + delete it; + } } currentFileInfo = nextFileInfo; @@ -455,7 +505,10 @@ QString QDirIterator::next() */ bool QDirIterator::hasNext() const { - return !d->fileEngineIterators.isEmpty(); + if (d->engine) + return !d->fileEngineIterators.isEmpty(); + else + return !d->nativeIterators.isEmpty(); } /*! diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index d49ee74..83df26d 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -291,6 +291,13 @@ QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) */ /*! + \internal +*/ +QFileInfo::QFileInfo(QFileInfoPrivate *p) : d_ptr(p) +{ +} + +/*! Constructs an empty QFileInfo object. Note that an empty QFileInfo object contain no file reference. diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index f0128b1..273a5f7 100644 --- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -53,11 +53,15 @@ QT_BEGIN_NAMESPACE QT_MODULE(Core) class QDir; +class QDirIteratorPrivate; class QDateTime; class QFileInfoPrivate; class Q_CORE_EXPORT QFileInfo { + friend class QDirIteratorPrivate; + explicit QFileInfo(QFileInfoPrivate *d); + public: QFileInfo(); QFileInfo(const QString &file); diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h index 6db84c4..869a7a6 100644 --- a/src/corelib/io/qfileinfo_p.h +++ b/src/corelib/io/qfileinfo_p.h @@ -58,9 +58,11 @@ #include "qdatetime.h" #include "qatomic.h" #include "qshareddata.h" -#include "qfilesystementry_p.h" #include "qfilesystemengine_p.h" +#include +#include + QT_BEGIN_NAMESPACE class QFileInfoPrivate : public QSharedData @@ -102,6 +104,16 @@ public: { } + inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data) + : QSharedData(), + fileEntry(file), + metaData(data), + cachedFlags(0), + isDefaultConstructed(false), + cache_enabled(true), fileFlags(0), fileSize(0) + { + } + inline void clearFlags() const { fileFlags = 0; cachedFlags = 0; -- cgit v0.12 From ce74c076062c84f183f72947730db7b0e2d5ab54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 10 Sep 2010 17:43:23 +0200 Subject: Refactored QFSFileEngineIterator/Unix into new internal native iterators. QFSFileEngineIterator will use that internally, currently only on non-windows platforms. This implementation can be reused on Windows once the native iterators are in place there as well. Reviewed-by: Shane Kearns --- qmake/Makefile.unix | 7 +- qmake/qmake.pri | 2 +- src/corelib/io/io.pri | 1 - src/corelib/io/qfileinfo.h | 2 +- src/corelib/io/qfilesystemengine.cpp | 59 +++++++++++ src/corelib/io/qfilesystemiterator_p.h | 13 ++- src/corelib/io/qfilesystemiterator_unix.cpp | 53 +++++++++- src/corelib/io/qfilesystemmetadata_p.h | 1 + src/corelib/io/qfsfileengine_iterator.cpp | 45 ++++++++ src/corelib/io/qfsfileengine_iterator_p.h | 9 ++ src/corelib/io/qfsfileengine_iterator_unix.cpp | 140 ------------------------- src/tools/bootstrap/bootstrap.pro | 3 +- 12 files changed, 181 insertions(+), 154 deletions(-) delete mode 100644 src/corelib/io/qfsfileengine_iterator_unix.cpp diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index d248831..5ea023f 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -17,7 +17,7 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \ QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \ qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfile.o \ qfilesystementry.o qfilesystemengine_unix.o qfilesystemengine.o qfilesystemiterator_unix.o \ - qfsfileengine_unix.o qfsfileengine_iterator_unix.o qfsfileengine.o \ + qfsfileengine_unix.o qfsfileengine.o \ qfsfileengine_iterator.o qregexp.o qvector.o qbitarray.o qdir.o qdiriterator.o quuid.o qhash.o \ qfileinfo.o qdatetime.o qstringlist.o qabstractfileengine.o qtemporaryfile.o \ qmap.o qmetatype.o qsettings.o qlibraryinfo.o qvariant.o qvsnprintf.o \ @@ -49,7 +49,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_mac.cpp \ $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_unix.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine_unix.cpp $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp \ - $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator_unix.cpp $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp \ + $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp \ $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp $(SOURCE_PATH)/src/corelib/tools/qlist.cpp \ $(SOURCE_PATH)/src/corelib/tools/qvector.cpp $(SOURCE_PATH)/src/corelib/tools/qbitarray.cpp \ $(SOURCE_PATH)/src/corelib/io/qdiriterator.cpp \ @@ -188,9 +188,6 @@ qfsfileengine_iterator.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.c qfsfileengine_unix.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_unix.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_unix.cpp -qfsfileengine_iterator_unix.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator_unix.cpp - $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator_unix.cpp - qabstractfileengine.o: $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp diff --git a/qmake/qmake.pri b/qmake/qmake.pri index ae31eca..cd81c82 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -127,7 +127,7 @@ bootstrap { #Qt code qxmlutils.h unix { - SOURCES += qfilesystemengine_unix.cpp qfilesystemiterator_unix.cpp qfsfileengine_unix.cpp qfsfileengine_iterator_unix.cpp + SOURCES += qfilesystemengine_unix.cpp qfilesystemiterator_unix.cpp qfsfileengine_unix.cpp mac { SOURCES += qfilesystemengine_mac.cpp SOURCES += qcore_mac.cpp qsettings_mac.cpp diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 4a20dfa..4a2f042 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -73,7 +73,6 @@ win32 { SOURCES += io/qfilesystemengine_win.cpp SOURCES += io/qfilesystemiterator_win.cpp } else:unix { - SOURCES += io/qfsfileengine_iterator_unix.cpp SOURCES += io/qfsfileengine_unix.cpp symbian { SOURCES += io/qfilesystemengine_symbian.cpp diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index 273a5f7..92bea5e 100644 --- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -60,9 +60,9 @@ class QFileInfoPrivate; class Q_CORE_EXPORT QFileInfo { friend class QDirIteratorPrivate; +public: explicit QFileInfo(QFileInfoPrivate *d); -public: QFileInfo(); QFileInfo(const QString &file); QFileInfo(const QFile &file); diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index cbc4c42..4791dfc 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -285,6 +285,65 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) #endif } +void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry) +{ + // ### This will clear all entry flags and knownFlagsMask + switch (entry.d_type) + { + case DT_DIR: + knownFlagsMask = QFileSystemMetaData::LinkType + | QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::SequentialType + | QFileSystemMetaData::ExistsAttribute; + + entryFlags = QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::ExistsAttribute; + + break; + + case DT_BLK: + case DT_CHR: + case DT_FIFO: + case DT_SOCK: + // ### System attribute + knownFlagsMask = QFileSystemMetaData::LinkType + | QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::BundleType + | QFileSystemMetaData::AliasType + | QFileSystemMetaData::SequentialType + | QFileSystemMetaData::ExistsAttribute; + + entryFlags = QFileSystemMetaData::SequentialType + | QFileSystemMetaData::ExistsAttribute; + + break; + + case DT_LNK: + knownFlagsMask = QFileSystemMetaData::LinkType; + entryFlags = QFileSystemMetaData::LinkType; + break; + + case DT_REG: + knownFlagsMask = QFileSystemMetaData::LinkType + | QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::BundleType + | QFileSystemMetaData::SequentialType + | QFileSystemMetaData::ExistsAttribute; + + entryFlags = QFileSystemMetaData::FileType + | QFileSystemMetaData::ExistsAttribute; + + break; + + case DT_UNKNOWN: + default: + clear(); + } +} + #endif //static diff --git a/src/corelib/io/qfilesystemiterator_p.h b/src/corelib/io/qfilesystemiterator_p.h index ed1ef5e..d3b195d 100644 --- a/src/corelib/io/qfilesystemiterator_p.h +++ b/src/corelib/io/qfilesystemiterator_p.h @@ -66,6 +66,7 @@ #elif defined (Q_OS_SYMBIAN) #include #else +#include #endif QT_BEGIN_NAMESPACE @@ -73,12 +74,15 @@ QT_BEGIN_NAMESPACE class QFileSystemIterator { public: - QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, const QStringList &nameFilters, QDirIterator::IteratorFlags flags); + QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, + const QStringList &nameFilters, QDirIterator::IteratorFlags flags + = QDirIterator::FollowSymlinks | QDirIterator::Subdirectories); ~QFileSystemIterator(); bool advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData); private: + QFileSystemEntry::NativePath nativePath; // Platform-specific data #if defined(Q_OS_WIN) @@ -88,6 +92,13 @@ private: TInt lastError; TInt entryIndex; #else + QT_DIR *dir; + QT_DIRENT *dirEntry; +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) + // for readdir_r + QScopedPointer mt_file; +#endif + int lastError; #endif Q_DISABLE_COPY(QFileSystemIterator) diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp index 3c73496..00ccd41 100644 --- a/src/corelib/io/qfilesystemiterator_unix.cpp +++ b/src/corelib/io/qfilesystemiterator_unix.cpp @@ -39,27 +39,74 @@ ** ****************************************************************************/ +#include "qplatformdefs.h" #include "qfilesystemiterator_p.h" +#include +#include + QT_BEGIN_NAMESPACE QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, const QStringList &nameFilters, QDirIterator::IteratorFlags flags) + : nativePath(entry.nativeFilePath()) + , dir(0) + , dirEntry(0) + , lastError(0) { - Q_UNUSED(entry) Q_UNUSED(filters) Q_UNUSED(nameFilters) Q_UNUSED(flags) + + if ((dir = QT_OPENDIR(nativePath.constData())) == 0) { + lastError = errno; + } else { + + if (!nativePath.endsWith('/')) + nativePath.append('/'); + +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) + // ### Race condition; we should use fpathconf and dirfd(). + size_t maxPathName = ::pathconf(nativePath.constData(), _PC_NAME_MAX); + if (maxPathName == size_t(-1)) + maxPathName = FILENAME_MAX; + maxPathName += sizeof(QT_DIRENT) + 1; + + QT_DIRENT *p = reinterpret_cast(::malloc(maxPathName)); + Q_CHECK_PTR(p); + + mt_file.reset(p); +#endif + } } QFileSystemIterator::~QFileSystemIterator() { + if (dir) + QT_CLOSEDIR(dir); } bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData) { - Q_UNUSED(fileEntry) - Q_UNUSED(metaData) + if (!dir) + return false; + +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) + lastError = QT_READDIR_R(dir, mt_file.data(), &dirEntry); + if (lastError) + return false; +#else + // ### add local lock to prevent breaking reentrancy + dirEntry = QT_READDIR(dir); +#endif // _POSIX_THREAD_SAFE_FUNCTIONS + + if (dirEntry) { + fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name), QFileSystemEntry::FromNativePath()); + metaData.fillFromDirEnt(*dirEntry); + return true; + } + + lastError = errno; return false; } diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index ec25a0b..e45c5dc 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -205,6 +205,7 @@ public: #ifdef Q_OS_UNIX void fillFromStatBuf(const QT_STATBUF &statBuffer); + void fillFromDirEnt(const QT_DIRENT &statBuffer); #endif #ifdef Q_OS_SYMBIAN void fillFromTEntry(const TEntry& entry); diff --git a/src/corelib/io/qfsfileengine_iterator.cpp b/src/corelib/io/qfsfileengine_iterator.cpp index 7e7d70a..4617f49 100644 --- a/src/corelib/io/qfsfileengine_iterator.cpp +++ b/src/corelib/io/qfsfileengine_iterator.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qfsfileengine_iterator_p.h" +#include "qfileinfo_p.h" #include "qvariant.h" #ifndef QT_NO_FSFILEENGINE @@ -48,15 +49,35 @@ QT_BEGIN_NAMESPACE QFSFileEngineIterator::QFSFileEngineIterator(QDir::Filters filters, const QStringList &filterNames) : QAbstractFileEngineIterator(filters, filterNames) +#ifdef Q_OS_UNIX + , done(false) +#endif { +#ifndef Q_OS_UNIX newPlatformSpecifics(); +#endif } QFSFileEngineIterator::~QFSFileEngineIterator() { +#ifndef Q_OS_UNIX deletePlatformSpecifics(); +#endif } +#ifdef Q_OS_UNIX +bool QFSFileEngineIterator::hasNext() const +{ + if (!done && !nativeIterator) { + nativeIterator.reset(new QFileSystemIterator(QFileSystemEntry(path()), + filters(), nameFilters())); + advance(); + } + + return !done; +} +#endif + QString QFSFileEngineIterator::next() { if (!hasNext()) @@ -66,14 +87,38 @@ QString QFSFileEngineIterator::next() return currentFilePath(); } +#ifdef Q_OS_UNIX +void QFSFileEngineIterator::advance() const +{ + currentInfo = nextInfo; + + QFileSystemEntry entry; + QFileSystemMetaData data; + if (nativeIterator->advance(entry, data)) { + nextInfo = QFileInfo(new QFileInfoPrivate(entry, data)); + } else { + done = true; + nativeIterator.reset(); + } +} +#endif + QString QFSFileEngineIterator::currentFileName() const { +#ifdef Q_OS_UNIX + return currentInfo.fileName(); +#else return currentEntry; +#endif } QFileInfo QFSFileEngineIterator::currentFileInfo() const { +#ifdef Q_OS_UNIX + return currentInfo; +#else return QAbstractFileEngineIterator::currentFileInfo(); +#endif } QT_END_NAMESPACE diff --git a/src/corelib/io/qfsfileengine_iterator_p.h b/src/corelib/io/qfsfileengine_iterator_p.h index be670e0..7940fbd 100644 --- a/src/corelib/io/qfsfileengine_iterator_p.h +++ b/src/corelib/io/qfsfileengine_iterator_p.h @@ -54,6 +54,7 @@ // #include "qabstractfileengine.h" +#include "qfilesystemiterator_p.h" #include "qdir.h" #ifndef QT_NO_FSFILEENGINE @@ -76,6 +77,13 @@ public: QFileInfo currentFileInfo() const; private: +#ifdef Q_OS_UNIX + void advance() const; + mutable QScopedPointer nativeIterator; + mutable QFileInfo currentInfo; + mutable QFileInfo nextInfo; + mutable bool done; +#else QFSFileEngineIteratorPlatformSpecificData *platform; friend class QFSFileEngineIteratorPlatformSpecificData; void newPlatformSpecifics(); @@ -83,6 +91,7 @@ private: void advance(); QString currentEntry; +#endif }; QT_END_NAMESPACE diff --git a/src/corelib/io/qfsfileengine_iterator_unix.cpp b/src/corelib/io/qfsfileengine_iterator_unix.cpp deleted file mode 100644 index bfdb03e..0000000 --- a/src/corelib/io/qfsfileengine_iterator_unix.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -** -** 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 QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the 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 "qplatformdefs.h" -#include "qfsfileengine_iterator_p.h" - -#include - -#ifndef QT_NO_FSFILEENGINE - -QT_BEGIN_NAMESPACE - -class QFSFileEngineIteratorPlatformSpecificData -{ -public: - inline QFSFileEngineIteratorPlatformSpecificData() - : dir(0), dirEntry(0), done(false) -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) && !defined(Q_OS_SYMBIAN) - , mt_file(0) -#endif - {} - - QT_DIR *dir; - QT_DIRENT *dirEntry; - bool done; - -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) && !defined(Q_OS_SYMBIAN) - // for readdir_r - QT_DIRENT *mt_file; -#endif -}; - -void QFSFileEngineIterator::advance() -{ - currentEntry = platform->dirEntry ? QFile::decodeName(QByteArray(platform->dirEntry->d_name)) : QString(); - - if (!platform->dir) - return; - -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) && !defined(Q_OS_SYMBIAN) - if (QT_READDIR_R(platform->dir, platform->mt_file, &platform->dirEntry) != 0) - platform->done = true; -#else - // ### add local lock to prevent breaking reentrancy - platform->dirEntry = QT_READDIR(platform->dir); -#endif // _POSIX_THREAD_SAFE_FUNCTIONS - if (!platform->dirEntry) { - QT_CLOSEDIR(platform->dir); - platform->dir = 0; - platform->done = true; -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) && !defined(Q_OS_SYMBIAN) - delete [] platform->mt_file; - platform->mt_file = 0; -#endif - } -} - -void QFSFileEngineIterator::newPlatformSpecifics() -{ - platform = new QFSFileEngineIteratorPlatformSpecificData; -} - -void QFSFileEngineIterator::deletePlatformSpecifics() -{ - if (platform->dir) { - QT_CLOSEDIR(platform->dir); -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) && !defined(Q_OS_SYMBIAN) - delete [] platform->mt_file; - platform->mt_file = 0; -#endif - } - delete platform; - platform = 0; -} - -bool QFSFileEngineIterator::hasNext() const -{ - if (!platform->done && !platform->dir) { - QFSFileEngineIterator *that = const_cast(this); - if ((that->platform->dir = QT_OPENDIR(QFile::encodeName(path()).data())) == 0) { - that->platform->done = true; - } else { - // ### Race condition; we should use fpathconf and dirfd(). - long maxPathName = ::pathconf(QFile::encodeName(path()).data(), _PC_NAME_MAX); - if ((int) maxPathName == -1) - maxPathName = FILENAME_MAX; - maxPathName += sizeof(QT_DIRENT) + 1; -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) && !defined(Q_OS_SYMBIAN) - if (that->platform->mt_file) - delete [] that->platform->mt_file; - that->platform->mt_file = (QT_DIRENT *)new char[maxPathName]; -#endif - - that->advance(); - } - } - return !platform->done; -} - -QT_END_NAMESPACE - -#endif // QT_NO_FSFILEENGINE diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 016fdc0..81b785a 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -87,8 +87,7 @@ SOURCES += \ unix:SOURCES += ../../corelib/io/qfilesystemengine_unix.cpp \ ../../corelib/io/qfilesystemiterator_unix.cpp \ - ../../corelib/io/qfsfileengine_unix.cpp \ - ../../corelib/io/qfsfileengine_iterator_unix.cpp + ../../corelib/io/qfsfileengine_unix.cpp win32:SOURCES += ../../corelib/io/qfilesystemengine_win.cpp \ ../../corelib/io/qfilesystemiterator_win.cpp \ -- cgit v0.12 From a12e4996b8316badd7784b204ea8f22b7986f032 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 13 Sep 2010 12:04:57 +0100 Subject: Fix Symbian's root path Change the root path to return the root of the system drive, e.g. "c:/" instead of the PhoneMemoryRootPath() "c:/data/". The PhoneMemoryRootPath() matched Qt's concept of the home path, and will continue to be returned for that function. Reviewed-By: Thomas Zander --- src/corelib/io/qfsfileengine_unix.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index c6e7300..a6cf7fc 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -744,7 +744,7 @@ QString QFSFileEngine::currentPath(const QString &) QString QFSFileEngine::homePath() { #if defined(Q_OS_SYMBIAN) - QString home = rootPath(); + QString home = QDir::cleanPath(QDir::fromNativeSeparators(qt_TDesC2QString(PathInfo::PhoneMemoryRootPath()))); #else QString home = QFile::decodeName(qgetenv("HOME")); if (home.isNull()) @@ -756,8 +756,10 @@ QString QFSFileEngine::homePath() QString QFSFileEngine::rootPath() { #if defined(Q_OS_SYMBIAN) - TFileName symbianPath = PathInfo::PhoneMemoryRootPath(); - return QDir::cleanPath(QDir::fromNativeSeparators(qt_TDesC2QString(symbianPath))); + TChar drive; + TInt err = RFs::DriveToChar(RFs::GetSystemDrive(), drive); //RFs::GetSystemDriveChar not supported on S60 3.1 + Q_ASSERT(err == KErrNone); //RFs::GetSystemDrive() shall always return a convertible drive number on a valid OS configuration + return QString(QChar(drive)).append(QLatin1String(":/")); #else return QLatin1String("/"); #endif -- cgit v0.12 From 7f5417353bd71a63e962851ba598f1e2631f4a25 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 13 Sep 2010 14:57:08 +0100 Subject: Fix setPermissions in symbian In error, it was checking the read permissions to set the read-only file attribute, when it should have been checking the write permissions. read-only = !writable. Reviewed-By: Thomas Zander --- src/corelib/io/qfilesystemengine_symbian.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 1ed4ee8..6bad860 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -290,7 +290,7 @@ bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry) QString targetpath = absoluteName(entry).nativeFilePath(); RFs& fs(qt_s60GetRFs()); TInt err = fs.Delete(qt_QString2TPtrC(targetpath)); - return false; // TODO error reporting; + return err == KErrNone; // TODO error reporting; } //static @@ -300,8 +300,8 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per TUint setmask = 0; TUint clearmask = 0; RFs& fs(qt_s60GetRFs()); - if (permissions & (QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther)) - clearmask = KEntryAttReadOnly; + if (permissions & (QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther)) + clearmask = KEntryAttReadOnly; //if anyone can write, it's not read-only else setmask = KEntryAttReadOnly; TInt err = fs.SetAtt(qt_QString2TPtrC(targetpath), setmask, clearmask); @@ -310,7 +310,7 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per data->entryFlags |= QFileSystemMetaData::MetaDataFlag(uint(permissions)); data->knownFlagsMask |= QFileSystemMetaData::Permissions; } - return err != KErrNone; // TODO error reporting + return err == KErrNone; // TODO error reporting } QT_END_NAMESPACE -- cgit v0.12 From 9bdc685da9d1e1aac165711197e3b7b887e19da3 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 13 Sep 2010 15:34:27 +0100 Subject: Integrate symbian file system iterator Store the relative path in nativeFilePath and prepend it to results, this behaviour was previously provided by the base class. Some refactoring to avoid needing to allocate a TFileName on the stack, and to set the known metadata flags inside the fillFromXXX functions. Reviewed-By: Thomas Zander Reviewed-By: mread --- src/corelib/io/qfilesystemengine_symbian.cpp | 6 +++-- src/corelib/io/qfilesystemiterator_symbian.cpp | 33 +++++++++++--------------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 6bad860..c339dc4 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -144,6 +144,8 @@ QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) void QFileSystemMetaData::fillFromTEntry(const TEntry& entry) { + entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags); + knownFlagsMask |= QFileSystemMetaData::SymbianTEntryFlags; //Symbian doesn't have unix type file permissions entryFlags |= QFileSystemMetaData::Permissions; if(entry.IsReadOnly()) { @@ -171,6 +173,8 @@ void QFileSystemMetaData::fillFromTEntry(const TEntry& entry) void QFileSystemMetaData::fillFromVolumeInfo(const TVolumeInfo& info) { + entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags); + knownFlagsMask |= QFileSystemMetaData::SymbianTEntryFlags; entryFlags |= QFileSystemMetaData::ExistsAttribute; entryFlags |= QFileSystemMetaData::Permissions; if(info.iDrive.iDriveAtt & KDriveAttRom) { @@ -187,7 +191,6 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM if (what & QFileSystemMetaData::SymbianTEntryFlags) { RFs& fs(qt_s60GetRFs()); TInt err; - data.entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags); QFileSystemEntry absentry(absoluteName(entry)); if (absentry.isRoot()) { //Root directories don't have an entry, and Entry() returns KErrBadName. @@ -210,7 +213,6 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM data.size_ = 0; data.modificationTime_ = TTime(0); } - data.knownFlagsMask |= QFileSystemMetaData::SymbianTEntryFlags; } return data.hasFlags(what); } diff --git a/src/corelib/io/qfilesystemiterator_symbian.cpp b/src/corelib/io/qfilesystemiterator_symbian.cpp index 106eda9..e316526 100644 --- a/src/corelib/io/qfilesystemiterator_symbian.cpp +++ b/src/corelib/io/qfilesystemiterator_symbian.cpp @@ -51,26 +51,28 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &path, QDir::Fil { RFs& fs = qt_s60GetRFs(); - TFileName symbianPath; - QString abspath = QFileSystemEngine::absoluteName(path).nativeFilePath(); + nativePath = path.nativeFilePath(); + if (!nativePath.endsWith(QLatin1Char('\\'))) + nativePath.append(QLatin1Char('\\')); - if (!abspath.endsWith(QLatin1Char('\\'))) - abspath.append(QLatin1Char('\\')); + QString absPath = QFileSystemEngine::absoluteName(path).nativeFilePath(); - int pathLen = abspath.length(); - if (pathLen > symbianPath.MaxLength()) { + if (!absPath.endsWith(QLatin1Char('\\'))) + absPath.append(QLatin1Char('\\')); + + int pathLen = absPath.length(); + if (pathLen > KMaxFileName) { lastError = KErrBadName; return; } - symbianPath.Copy(qt_QString2TPtrC(abspath)); //set up server side filtering to reduce IPCs //RDir won't accept all valid name filters e.g. "*. bar" if (nameFilters.count() == 1 && !(filters & QDir::AllDirs) && iteratorFlags == QDirIterator::NoIteratorFlags && pathLen + nameFilters[0].length() - <= symbianPath.MaxLength()) { + <= KMaxFileName) { //server side supports one mask - skip this for recursive mode or if only files should be filtered - symbianPath.Append(qt_QString2TPtrC(nameFilters[0])); + absPath.append(nameFilters[0]); } TUint symbianMask = 0; @@ -90,7 +92,7 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &path, QDir::Fil symbianMask = KEntryAttMatchExclusive | KEntryAttReadOnly; } - lastError = dirHandle.Open(fs, symbianPath, symbianMask); + lastError = dirHandle.Open(fs, qt_QString2TPtrC(absPath), symbianMask); } QFileSystemIterator::~QFileSystemIterator() @@ -98,13 +100,6 @@ QFileSystemIterator::~QFileSystemIterator() dirHandle.Close(); } -static void createFileSystemMetaDataHelper(const TEntry &entry, QFileSystemMetaData &metaData) -{ - //placeholder - //TODO: adapt from QFileInfoPrivate::fromTEntry(entries[entryIndex], path()); - //or add this functionality to QFileSystemMetaData -} - bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData) { //1st time, lastError is result of dirHandle.Open(), entries.Count() is 0 and entryIndex is -1 so initial read is triggered @@ -121,8 +116,8 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa if ((lastError == KErrNone || lastError == KErrEof) && entryIndex < entries.Count()) { Q_ASSERT(entryIndex >= 0); const TEntry &entry(entries[entryIndex]); - fileEntry = QFileSystemEntry(qt_TDesC2QString(entry.iName), QFileSystemEntry::FromNativePath()); - createFileSystemMetaDataHelper(entry, metaData); + fileEntry = QFileSystemEntry(nativePath + qt_TDesC2QString(entry.iName), QFileSystemEntry::FromNativePath()); + metaData.fillFromTEntry(entry); return true; } -- cgit v0.12 From 71d1d710d5e25be4b74af10a8dfcc3c53bd42ef1 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 13 Sep 2010 16:27:32 +0100 Subject: Fixes for canonicalPath and exists on symbian QDir::cleanPath does not do what we need for some types of path, for example c:/../. However, changing the cleanPath() function isn't easy because so many places rely on the current behaviour. RFs::Att() doesn't work for root directories, so instead to check whether a file exists, we now use the normal fillMetaData() function. Also fixed some compiler warnings in the file. Reviewed-By: mread --- src/corelib/io/qfilesystemengine_symbian.cpp | 61 +++++++++++++++++++--------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index c339dc4..dc7fcbf 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -52,6 +52,36 @@ bool QFileSystemEngine::isCaseSensitive() return false; } +//TODO: resolve this with QDir::cleanPath, without breaking the behaviour of that +//function which is documented only by autotest +//input: a dirty absolute path, e.g. c:/../../foo/./ +//output: a clean absolute path, e.g. c:/foo/ +static QString symbianCleanAbsolutePath(const QString& path) +{ + bool isDir = path.endsWith(QLatin1Char('/')); + //using SkipEmptyParts flag to eliminate duplicated slashes + QStringList components = path.split(QLatin1Char('/'), QString::SkipEmptyParts); + int cdups = 0; + for(int i=components.count() - 1; i>=0; --i) { + if(components.at(i) == QLatin1String("..")) { + components.removeAt(i); + cdups++; + } + else if(components.at(i) == QLatin1String(".")) { + components.removeAt(i); + } + else if(cdups && i > 0) { + --cdups; + components.removeAt(i); + } + } + QString result = components.join(QLatin1String("/")); + if ((isDir&& !result.endsWith(QLatin1Char('/'))) + || (result.length() == 2 && result.at(1).unicode() == ':')) + result.append(QLatin1Char('/')); + return result; +} + //static QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) { @@ -65,15 +95,12 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) return entry; QFileSystemEntry result = absoluteName(entry); - RFs& fs(qt_s60GetRFs()); - TUint e; - //Att is faster than Entry for determining if a file exists, due to smaller IPC - TInt r = fs.Att(qt_QString2TPtrC(result.nativeFilePath()), e); - - if (r == KErrNone) { - return result; - } else { // file doesn't exist + QFileSystemMetaData meta; + if (!fillMetaData(result, meta, QFileSystemMetaData::ExistsAttribute) || !meta.exists()) { + // file doesn't exist return QFileSystemEntry(); + } else { + return result; } } @@ -109,30 +136,26 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) } } if (!orig.isEmpty() && !(orig.length() == 1 && orig.at(0).unicode() == '.')) { - if (!result.isEmpty() && !result.endsWith('/')) - result.append('/'); + if (!result.isEmpty() && !result.endsWith(QLatin1Char('/'))) + result.append(QLatin1Char('/')); result.append(orig); } - const bool isDir = result.endsWith('/'); - const bool isRoot = entry.isRoot(); - - result = QDir::cleanPath(result); - if (isDir && !isRoot) - result.append(QLatin1Char('/')); - return QFileSystemEntry(result); + return symbianCleanAbsolutePath(result); } //static QString QFileSystemEngine::resolveUserName(uint userId) { - return QString(); // TODO + Q_UNUSED(userId) + return QString(); // no users or groups on symbian } //static QString QFileSystemEngine::resolveGroupName(uint groupId) { - return QString(); // TODO + Q_UNUSED(groupId) + return QString(); // no users or groups on symbian } //static -- cgit v0.12 From c76b30f79c08499c2d9d4329c72639f80ff872b2 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Thu, 9 Sep 2010 15:49:26 +0200 Subject: QFileSystemEngine: Fix stupid bug-o in engine creation Reviewed-by: Joao --- src/corelib/io/qfilesystemengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index 4791dfc..9bfd382 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -133,7 +133,7 @@ static inline bool _q_checkEntry(QFileSystemEntry &entry, QFileSystemMetaData &d static inline bool _q_checkEntry(QAbstractFileEngine *&engine, bool resolvingEntry) { if (resolvingEntry) { - if (!engine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::ExistsFlag) { + if (!(engine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::ExistsFlag)) { delete engine; engine = 0; return false; -- cgit v0.12 From 59ad6b33ac73b5981c9b3a9ba87374d33fb17228 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Sat, 11 Sep 2010 00:13:12 +0200 Subject: Make QFSFileEngine & QFileInfo use the new filesystemengine on Windows QFSFileEngine now uses the QFileSystemEngine static functions to implement most of the file system related quries. All the Win32 specific code is now moved from the QFSFileEngine to QFileSystemEngine. This implements all the fillMetaData and filename query functions. These new functions behave exactly like their previous implementations in QFSFileEngine. Following optimizations are done with this. * GetFileAttributesEx() instead of GetFileAttibutes(). * GetFileInformationByHandle() instead of POSIX functions. Reviewed-by: Joao --- src/corelib/io/qfilesystemengine_p.h | 23 +- src/corelib/io/qfilesystemengine_win.cpp | 1074 ++++++++++++++++++++++++- src/corelib/io/qfilesystemmetadata_p.h | 55 +- src/corelib/io/qfsfileengine_iterator_win.cpp | 3 +- src/corelib/io/qfsfileengine_p.h | 10 +- src/corelib/io/qfsfileengine_win.cpp | 1048 ++---------------------- 6 files changed, 1211 insertions(+), 1002 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 94a8175..1068e76 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -75,10 +75,24 @@ public: static QString bundleName(const QFileSystemEntry &entry); static bool fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, - QFileSystemMetaData::MetaDataFlags what); + QFileSystemMetaData::MetaDataFlags what); #if defined(Q_OS_UNIX) static bool fillMetaData(int fd, QFileSystemMetaData &data); // what = PosixStatFlags #endif +#if defined(Q_OS_WIN) + + static bool uncListSharesOnServer(const QString &server, QStringList *list); //Used also by QFSFileEngineIterator::hasNext() + static bool fillMetaData(int fd, QFileSystemMetaData &data, + QFileSystemMetaData::MetaDataFlags what); + static bool fillMetaData(HANDLE fHandle, QFileSystemMetaData &data, + QFileSystemMetaData::MetaDataFlags what); + static bool fillPermissions(const QFileSystemEntry &entry, QFileSystemMetaData &data, + QFileSystemMetaData::MetaDataFlags what); + static QString homePath(); + static QString rootPath(); + static QString owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own); + static QString nativeAbsoluteFilePath(const QString &path); +#endif static bool createDirectory(const QFileSystemEntry &entry, bool createParents); static bool removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents); @@ -90,12 +104,15 @@ public: static bool removeFile(const QFileSystemEntry &entry); static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, - QFileSystemMetaData *data = 0); + QFileSystemMetaData *data = 0); static QAbstractFileEngine *resolveEntryAndCreateLegacyEngine(QFileSystemEntry &entry, - QFileSystemMetaData &data); + QFileSystemMetaData &data); private: static QString slowCanonicalized(const QString &path); +#if defined(Q_OS_WIN) + static void clearWinStatData(QFileSystemMetaData &data); +#endif }; QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 28d5db4..550b522 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -41,29 +41,531 @@ #include "qfilesystemengine_p.h" +#define _POSIX_ +#include "qplatformdefs.h" +#include "qabstractfileengine.h" +#include "private/qfsfileengine_p.h" +#include "qfilesystemengine_p.h" +#include + +#include "qfile.h" +#include "qdir.h" +#include "private/qmutexpool_p.h" +#include "qvarlengtharray.h" +#include "qdatetime.h" +#include "qt_windows.h" + +#if !defined(Q_OS_WINCE) +# include +# include +# include +#else +# include +#endif +#include +#include +#include +#include +#include +#include +#define SECURITY_WIN32 +#include + +#ifndef _INTPTR_T_DEFINED +#ifdef _WIN64 +typedef __int64 intptr_t; +#else +#ifdef _W64 +typedef _W64 int intptr_t; +#else +typedef INT_PTR intptr_t; +#endif +#endif +#define _INTPTR_T_DEFINED +#endif + +#ifndef INVALID_FILE_ATTRIBUTES +# define INVALID_FILE_ATTRIBUTES (DWORD (-1)) +#endif + +#if !defined(Q_OS_WINCE) +# if !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) +typedef struct _REPARSE_DATA_BUFFER { + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union { + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + struct { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + }; +} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; +# define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) +# endif // !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) + +# ifndef MAXIMUM_REPARSE_DATA_BUFFER_SIZE +# define MAXIMUM_REPARSE_DATA_BUFFER_SIZE 16384 +# endif +# ifndef IO_REPARSE_TAG_SYMLINK +# define IO_REPARSE_TAG_SYMLINK (0xA000000CL) +# endif +# ifndef FSCTL_GET_REPARSE_POINT +# define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) +# endif +#endif // !defined(Q_OS_WINCE) + QT_BEGIN_NAMESPACE +Q_CORE_EXPORT int qt_ntfs_permission_lookup = 0; + +#if defined(Q_OS_WINCE) +static QString qfsPrivateCurrentDir = QLatin1String(""); +// As none of the functions we try to resolve do exist on Windows CE +// we use QT_NO_LIBRARY to shorten everything up a little bit. +#define QT_NO_LIBRARY 1 +#endif + +#if !defined(QT_NO_LIBRARY) +QT_BEGIN_INCLUDE_NAMESPACE +typedef DWORD (WINAPI *PtrGetNamedSecurityInfoW)(LPWSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION, PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*); +static PtrGetNamedSecurityInfoW ptrGetNamedSecurityInfoW = 0; +typedef BOOL (WINAPI *PtrLookupAccountSidW)(LPCWSTR, PSID, LPWSTR, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE); +static PtrLookupAccountSidW ptrLookupAccountSidW = 0; +typedef VOID (WINAPI *PtrBuildTrusteeWithSidW)(PTRUSTEE_W, PSID); +static PtrBuildTrusteeWithSidW ptrBuildTrusteeWithSidW = 0; +typedef DWORD (WINAPI *PtrGetEffectiveRightsFromAclW)(PACL, PTRUSTEE_W, OUT PACCESS_MASK); +static PtrGetEffectiveRightsFromAclW ptrGetEffectiveRightsFromAclW = 0; +static TRUSTEE_W currentUserTrusteeW; +static TRUSTEE_W worldTrusteeW; + +typedef BOOL (WINAPI *PtrGetUserProfileDirectoryW)(HANDLE, LPWSTR, LPDWORD); +static PtrGetUserProfileDirectoryW ptrGetUserProfileDirectoryW = 0; +typedef BOOL (WINAPI *PtrGetVolumePathNamesForVolumeNameW)(LPCWSTR,LPWSTR,DWORD,PDWORD); +static PtrGetVolumePathNamesForVolumeNameW ptrGetVolumePathNamesForVolumeNameW = 0; +QT_END_INCLUDE_NAMESPACE + + +static void resolveLibs() +{ + static bool triedResolve = false; + if (!triedResolve) { + // need to resolve the security info functions + + // protect initialization +#ifndef QT_NO_THREAD + QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve)); + // check triedResolve again, since another thread may have already + // done the initialization + if (triedResolve) { + // another thread did initialize the security function pointers, + // so we shouldn't do it again. + return; + } +#endif + + triedResolve = true; +#if !defined(Q_OS_WINCE) + HINSTANCE advapiHnd = LoadLibrary(L"advapi32"); + if (advapiHnd) { + ptrGetNamedSecurityInfoW = (PtrGetNamedSecurityInfoW)GetProcAddress(advapiHnd, "GetNamedSecurityInfoW"); + ptrLookupAccountSidW = (PtrLookupAccountSidW)GetProcAddress(advapiHnd, "LookupAccountSidW"); + ptrBuildTrusteeWithSidW = (PtrBuildTrusteeWithSidW)GetProcAddress(advapiHnd, "BuildTrusteeWithSidW"); + ptrGetEffectiveRightsFromAclW = (PtrGetEffectiveRightsFromAclW)GetProcAddress(advapiHnd, "GetEffectiveRightsFromAclW"); + } + if (ptrBuildTrusteeWithSidW) { + // Create TRUSTEE for current user + HANDLE hnd = ::GetCurrentProcess(); + HANDLE token = 0; + if (::OpenProcessToken(hnd, TOKEN_QUERY, &token)) { + TOKEN_USER tu; + DWORD retsize; + if (::GetTokenInformation(token, TokenUser, &tu, sizeof(tu), &retsize)) + ptrBuildTrusteeWithSidW(¤tUserTrusteeW, tu.User.Sid); + ::CloseHandle(token); + } + + typedef BOOL (WINAPI *PtrAllocateAndInitializeSid)(PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, PSID*); + PtrAllocateAndInitializeSid ptrAllocateAndInitializeSid = (PtrAllocateAndInitializeSid)GetProcAddress(advapiHnd, "AllocateAndInitializeSid"); + typedef PVOID (WINAPI *PtrFreeSid)(PSID); + PtrFreeSid ptrFreeSid = (PtrFreeSid)GetProcAddress(advapiHnd, "FreeSid"); + if (ptrAllocateAndInitializeSid && ptrFreeSid) { + // Create TRUSTEE for Everyone (World) + SID_IDENTIFIER_AUTHORITY worldAuth = { SECURITY_WORLD_SID_AUTHORITY }; + PSID pWorld = 0; + if (ptrAllocateAndInitializeSid(&worldAuth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pWorld)) + ptrBuildTrusteeWithSidW(&worldTrusteeW, pWorld); + ptrFreeSid(pWorld); + } + } + HINSTANCE userenvHnd = LoadLibrary(L"userenv"); + if (userenvHnd) + ptrGetUserProfileDirectoryW = (PtrGetUserProfileDirectoryW)GetProcAddress(userenvHnd, "GetUserProfileDirectoryW"); + HINSTANCE kernel32 = LoadLibrary(L"kernel32"); + if(kernel32) + ptrGetVolumePathNamesForVolumeNameW = (PtrGetVolumePathNamesForVolumeNameW)GetProcAddress(kernel32, "GetVolumePathNamesForVolumeNameW"); +#endif + } +} +#endif // QT_NO_LIBRARY + +typedef DWORD (WINAPI *PtrNetShareEnum)(LPWSTR, DWORD, LPBYTE*, DWORD, LPDWORD, LPDWORD, LPDWORD); +static PtrNetShareEnum ptrNetShareEnum = 0; +typedef DWORD (WINAPI *PtrNetApiBufferFree)(LPVOID); +static PtrNetApiBufferFree ptrNetApiBufferFree = 0; +typedef struct _SHARE_INFO_1 { + LPWSTR shi1_netname; + DWORD shi1_type; + LPWSTR shi1_remark; +} SHARE_INFO_1; + + +static bool resolveUNCLibs() +{ + static bool triedResolve = false; + if (!triedResolve) { +#ifndef QT_NO_THREAD + QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve)); + if (triedResolve) { + return ptrNetShareEnum && ptrNetApiBufferFree; + } +#endif + triedResolve = true; +#if !defined(Q_OS_WINCE) + HINSTANCE hLib = LoadLibrary(L"netapi32"); + if (hLib) { + ptrNetShareEnum = (PtrNetShareEnum)GetProcAddress(hLib, "NetShareEnum"); + if (ptrNetShareEnum) + ptrNetApiBufferFree = (PtrNetApiBufferFree)GetProcAddress(hLib, "NetApiBufferFree"); + } +#endif + } + return ptrNetShareEnum && ptrNetApiBufferFree; +} + +static QString readSymLink(const QFileSystemEntry &link) +{ + QString result; +#if !defined(Q_OS_WINCE) + HANDLE handle = CreateFile((wchar_t*)link.nativeFilePath().utf16(), + FILE_READ_EA, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + 0, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, + 0); + if (handle != INVALID_HANDLE_VALUE) { + DWORD bufsize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE; + REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER*)qMalloc(bufsize); + DWORD retsize = 0; + if (::DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, 0, 0, rdb, bufsize, &retsize, 0)) { + if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { + int length = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t); + int offset = rdb->MountPointReparseBuffer.SubstituteNameOffset / sizeof(wchar_t); + const wchar_t* PathBuffer = &rdb->MountPointReparseBuffer.PathBuffer[offset]; + result = QString::fromWCharArray(PathBuffer, length); + } else if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK) { + int length = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t); + int offset = rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t); + const wchar_t* PathBuffer = &rdb->SymbolicLinkReparseBuffer.PathBuffer[offset]; + result = QString::fromWCharArray(PathBuffer, length); + } + // cut-off "//?/" and "/??/" + if (result.size() > 4 && result.at(0) == QLatin1Char('\\') && result.at(2) == QLatin1Char('?') && result.at(3) == QLatin1Char('\\')) + result = result.mid(4); + } + qFree(rdb); + CloseHandle(handle); + +#if !defined(QT_NO_LIBRARY) + resolveLibs(); + if (ptrGetVolumePathNamesForVolumeNameW) { + QRegExp matchVolName(QLatin1String("^Volume\\{([a-z]|[0-9]|-)+\\}\\\\"), Qt::CaseInsensitive); + if(matchVolName.indexIn(result) == 0) { + DWORD len; + wchar_t buffer[MAX_PATH]; + QString volumeName = result.mid(0, matchVolName.matchedLength()).prepend(QLatin1String("\\\\?\\")); + if(ptrGetVolumePathNamesForVolumeNameW((wchar_t*)volumeName.utf16(), buffer, MAX_PATH, &len) != 0) + result.replace(0,matchVolName.matchedLength(), QString::fromWCharArray(buffer)); + } + } +#endif + } +#else + Q_UNUSED(link); +#endif // Q_OS_WINCE + return result; +} + +static QString readLink(const QFileSystemEntry &link) +{ +#if !defined(Q_OS_WINCE) +#if !defined(QT_NO_LIBRARY) && !defined(Q_CC_MWERKS) + QString ret; + + bool neededCoInit = false; + IShellLink *psl; // pointer to IShellLink i/f + WIN32_FIND_DATA wfd; + wchar_t szGotPath[MAX_PATH]; + + // Get pointer to the IShellLink interface. + HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&psl); + + if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized + neededCoInit = true; + CoInitialize(NULL); + hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + IID_IShellLink, (LPVOID *)&psl); + } + if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface. + IPersistFile *ppf; + hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf); + if (SUCCEEDED(hres)) { + hres = ppf->Load((LPOLESTR)link.nativeFilePath().utf16(), STGM_READ); + //The original path of the link is retrieved. If the file/folder + //was moved, the return value still have the old path. + if (SUCCEEDED(hres)) { + if (psl->GetPath(szGotPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY) == NOERROR) + ret = QString::fromWCharArray(szGotPath); + } + ppf->Release(); + } + psl->Release(); + } + if (neededCoInit) + CoUninitialize(); + + return ret; +#else + Q_UNUSED(link); + return QString(); +#endif // QT_NO_LIBRARY +#else + wchar_t target[MAX_PATH]; + QString result; + if (SHGetShortcutTarget((wchar_t*)QFileInfo(link.filePath()).absoluteFilePath().replace(QLatin1Char('/'),QLatin1Char('\\')).utf16(), target, MAX_PATH)) { + result = QString::fromWCharArray(target); + if (result.startsWith(QLatin1Char('"'))) + result.remove(0,1); + if (result.endsWith(QLatin1Char('"'))) + result.remove(result.size()-1,1); + } + return result; +#endif // Q_OS_WINCE +} + +static bool uncShareExists(const QString &server) +{ + // This code asumes the UNC path is always like \\?\UNC\server... + QStringList parts = server.split(QLatin1Char('\\'), QString::SkipEmptyParts); + if (parts.count() >= 3) { + QStringList shares; + if (QFileSystemEngine::uncListSharesOnServer(QLatin1String("\\\\") + parts.at(2), &shares)) + return parts.count() >= 4 ? shares.contains(parts.at(3), Qt::CaseInsensitive) : true; + } + return false; +} + +static inline bool getFindData(QString path, WIN32_FIND_DATA &findData) +{ + // path should not end with a trailing slash + while (path.endsWith(QLatin1Char('\\'))) + path.chop(1); + + // can't handle drives + if (!path.endsWith(QLatin1Char(':'))) { + HANDLE hFind = ::FindFirstFile((wchar_t*)path.utf16(), &findData); + if (hFind != INVALID_HANDLE_VALUE) { + ::FindClose(hFind); + return true; + } + } + + return false; +} + +bool QFileSystemEngine::uncListSharesOnServer(const QString &server, QStringList *list) +{ + if (resolveUNCLibs()) { + SHARE_INFO_1 *BufPtr, *p; + DWORD res; + DWORD er = 0, tr = 0, resume = 0, i; + do { + res = ptrNetShareEnum((wchar_t*)server.utf16(), 1, (LPBYTE *)&BufPtr, DWORD(-1), &er, &tr, &resume); + if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) { + p = BufPtr; + for (i = 1; i <= er; ++i) { + if (list && p->shi1_type == 0) + list->append(QString::fromWCharArray(p->shi1_netname)); + p++; + } + } + ptrNetApiBufferFree(BufPtr); + } while (res == ERROR_MORE_DATA); + return res == ERROR_SUCCESS; + } + return false; +} + +void QFileSystemMetaData::fillFromFileAttribute(DWORD fileAttribute,bool isDriveRoot) +{ + fileAttribute_ = fileAttribute; + // Ignore the hidden attribute for drives. + if (!isDriveRoot && (fileAttribute_ & FILE_ATTRIBUTE_HIDDEN)) + entryFlags |= HiddenAttribute; + entryFlags |= ((fileAttribute & FILE_ATTRIBUTE_DIRECTORY) ? DirectoryType: FileType); + entryFlags |= ExistsAttribute; + knownFlagsMask |= FileType | DirectoryType | HiddenAttribute | ExistsAttribute; +} + +void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType, bool isDriveRoot) +{ + fillFromFileAttribute(findData.dwFileAttributes, isDriveRoot); + creationTime_ = findData.ftCreationTime; + lastAccessTime_ = findData.ftLastAccessTime; + lastWriteTime_ = findData.ftLastWriteTime; + size_ = findData.nFileSizeHigh; + size_ <<= 32; + size_ += findData.nFileSizeLow; + knownFlagsMask |= Times | SizeAttribute; + if (setLinkType) { + knownFlagsMask |= LinkType; + entryFlags &= ~LinkType; + if ((fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT) + && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK + || findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) { + entryFlags |= LinkType; + } + + } +} + +void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo) +{ + fillFromFileAttribute(fileInfo.dwFileAttributes); + creationTime_ = fileInfo.ftCreationTime; + lastAccessTime_ = fileInfo.ftLastAccessTime; + lastWriteTime_ = fileInfo.ftLastWriteTime; + size_ = fileInfo.nFileSizeHigh; + size_ <<= 32; + size_ += fileInfo.nFileSizeLow; + knownFlagsMask |= Times | SizeAttribute; +} + +void QFileSystemEngine::clearWinStatData(QFileSystemMetaData &data) +{ + data.size_ = -1; + data.fileAttribute_ = 0; +} + bool QFileSystemEngine::isCaseSensitive() { return false; } //static -QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) +QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, + QFileSystemMetaData &data) { - return link; // TODO implement + if (data.missingFlags(QFileSystemMetaData::LinkType)) + QFileSystemEngine::fillMetaData(link, data, QFileSystemMetaData::LinkType); + + QString ret; + if (data.isLnkFile()) + ret = readLink(link); + else if (data.isLink()) + ret = readSymLink(link); + return QFileSystemEntry(QDir::fromNativeSeparators(ret)); } //static QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) { - return QFileSystemEntry(slowCanonicalized(entry.filePath())); + // The caller has to verify whether the file exists or not. + return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath())); +} + +//static +QString QFileSystemEngine::nativeAbsoluteFilePath(const QString &path) +{ + // can be //server or //server/share + QString absPath; +#if !defined(Q_OS_WINCE) + QVarLengthArray buf(qMax(MAX_PATH, path.size() + 1)); + wchar_t *fileName = 0; + DWORD retLen = GetFullPathName((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName); + if (retLen > (DWORD)buf.size()) { + buf.resize(retLen); + retLen = GetFullPathName((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName); + } + if (retLen != 0) + absPath = QString::fromWCharArray(buf.data(), retLen); +#else + if (path.startsWith(QLatin1Char('/')) || path.startsWith(QLatin1Char('\\'))) + absPath = QDir::toNativeSeparators(path); + else + absPath = QDir::toNativeSeparators(QDir::cleanPath(qfsPrivateCurrentDir + QLatin1Char('/') + path)); +#endif + // This is really ugly, but GetFullPathName strips off whitespace at the end. + // If you for instance write ". " in the lineedit of QFileDialog, + // (which is an invalid filename) this function will strip the space off and viola, + // the file is later reported as existing. Therefore, we re-add the whitespace that + // was at the end of path in order to keep the filename invalid. + if (!path.isEmpty() && path.at(path.size() - 1) == QLatin1Char(' ')) + absPath.append(QLatin1Char(' ')); + return absPath; } //static QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) { - return entry; // TODO implement; + QString ret; + + if (!entry.isRelative()) { +#if !defined(Q_OS_WINCE) + if (entry.filePath().startsWith(QLatin1Char('/')) || // It's a absolute path to the current drive, so \a.txt -> Z:\a.txt + entry.filePath().size() == 2 || // It's a drive letter that needs to get a working dir appended + (entry.filePath().size() > 2 && entry.filePath().at(2) != QLatin1Char('/')) || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt + entry.filePath().contains(QLatin1String("/../")) || entry.filePath().contains(QLatin1String("/./")) || + entry.filePath().endsWith(QLatin1String("/..")) || entry.filePath().endsWith(QLatin1String("/."))) + { + ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(entry.filePath())); + } else +#endif + { + ret = entry.filePath(); + } + } else { + ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + entry.filePath()); + } + + // The path should be absolute at this point. + // From the docs : + // Absolute paths begin with the directory separator "/" + // (optionally preceded by a drive specification under Windows). + if (ret.at(0) != QLatin1Char('/')) { + Q_ASSERT(ret.length() >= 2); + Q_ASSERT(ret.at(0).isLetter()); + Q_ASSERT(ret.at(1) == QLatin1Char(':')); + + // Force uppercase drive letters. + ret[0] = ret.at(0).toUpper(); + } + return QFileSystemEntry(ret); } //static @@ -81,25 +583,506 @@ QString QFileSystemEngine::resolveGroupName(uint groupId) //static QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) { + Q_UNUSED(entry); return QString(); } //static -bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) +QString QFileSystemEngine::owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own) { - return false; // TODO implement; + QString name; +#if !defined(QT_NO_LIBRARY) + extern int qt_ntfs_permission_lookup; + if((qt_ntfs_permission_lookup > 0) && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)) { + resolveLibs(); + if (ptrGetNamedSecurityInfoW && ptrLookupAccountSidW) { + PSID pOwner = 0; + PSECURITY_DESCRIPTOR pSD; + if (ptrGetNamedSecurityInfoW((wchar_t*)entry.nativeFilePath().utf16(), SE_FILE_OBJECT, + own == QAbstractFileEngine::OwnerGroup ? GROUP_SECURITY_INFORMATION : OWNER_SECURITY_INFORMATION, + own == QAbstractFileEngine::OwnerUser ? &pOwner : 0, own == QAbstractFileEngine::OwnerGroup ? &pOwner : 0, + 0, 0, &pSD) == ERROR_SUCCESS) { + DWORD lowner = 64; + DWORD ldomain = 64; + QVarLengthArray owner(lowner); + QVarLengthArray domain(ldomain); + SID_NAME_USE use = SidTypeUnknown; + // First call, to determine size of the strings (with '\0'). + if (!ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner.data(), &lowner, + (LPWSTR)domain.data(), &ldomain, (SID_NAME_USE*)&use)) { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + if (lowner > (DWORD)owner.size()) + owner.resize(lowner); + if (ldomain > (DWORD)domain.size()) + domain.resize(ldomain); + // Second call, try on resized buf-s + if (!ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner.data(), &lowner, + (LPWSTR)domain.data(), &ldomain, (SID_NAME_USE*)&use)) { + lowner = 0; + } + } else { + lowner = 0; + } + } + if (lowner != 0) + name = QString::fromWCharArray(owner.data()); + LocalFree(pSD); + } + } + } +#else + Q_UNUSED(own); +#endif + return name; +} + +//static +bool QFileSystemEngine::fillPermissions(const QFileSystemEntry &entry, QFileSystemMetaData &data, + QFileSystemMetaData::MetaDataFlags what) +{ + QAbstractFileEngine::FileFlags ret = 0; + +#if !defined(QT_NO_LIBRARY) + if((qt_ntfs_permission_lookup > 0) && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)) { + resolveLibs(); + if(ptrGetNamedSecurityInfoW && ptrBuildTrusteeWithSidW && ptrGetEffectiveRightsFromAclW) { + enum { ReadMask = 0x00000001, WriteMask = 0x00000002, ExecMask = 0x00000020 }; + + QString fname = entry.filePath(); + PSID pOwner = 0; + PSID pGroup = 0; + PACL pDacl; + PSECURITY_DESCRIPTOR pSD; + DWORD res = ptrGetNamedSecurityInfoW((wchar_t*)fname.utf16(), SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, + &pOwner, &pGroup, &pDacl, 0, &pSD); + if(res == ERROR_SUCCESS) { + ACCESS_MASK access_mask; + TRUSTEE_W trustee; + if (what & QFileSystemMetaData::UserPermissions) { // user + data.knownFlagsMask |= QFileSystemMetaData::UserPermissions; + if(ptrGetEffectiveRightsFromAclW(pDacl, ¤tUserTrusteeW, &access_mask) != ERROR_SUCCESS) + access_mask = (ACCESS_MASK)-1; + if(access_mask & ReadMask) + data.entryFlags |= QFileSystemMetaData::UserReadPermission; + if(access_mask & WriteMask) + data.entryFlags|= QFileSystemMetaData::UserWritePermission; + if(access_mask & ExecMask) + data.entryFlags|= QFileSystemMetaData::UserExecutePermission; + } + if (what & QFileSystemMetaData::OwnerPermissions) { // owner + data.knownFlagsMask |= QFileSystemMetaData::OwnerPermissions; + ptrBuildTrusteeWithSidW(&trustee, pOwner); + if(ptrGetEffectiveRightsFromAclW(pDacl, &trustee, &access_mask) != ERROR_SUCCESS) + access_mask = (ACCESS_MASK)-1; + if(access_mask & ReadMask) + data.entryFlags |= QFileSystemMetaData::OwnerReadPermission; + if(access_mask & WriteMask) + data.entryFlags |= QFileSystemMetaData::OwnerWritePermission; + if(access_mask & ExecMask) + data.entryFlags |= QFileSystemMetaData::OwnerExecutePermission; + } + if (what & QFileSystemMetaData::GroupPermissions) { // group + data.knownFlagsMask |= QFileSystemMetaData::GroupPermissions; + ptrBuildTrusteeWithSidW(&trustee, pGroup); + if(ptrGetEffectiveRightsFromAclW(pDacl, &trustee, &access_mask) != ERROR_SUCCESS) + access_mask = (ACCESS_MASK)-1; + if(access_mask & ReadMask) + data.entryFlags |= QFileSystemMetaData::GroupReadPermission; + if(access_mask & WriteMask) + data.entryFlags |= QFileSystemMetaData::GroupWritePermission; + if(access_mask & ExecMask) + data.entryFlags |= QFileSystemMetaData::GroupExecutePermission; + } + if (what & QFileSystemMetaData::OtherPermissions) { // other (world) + data.knownFlagsMask |= QFileSystemMetaData::OtherPermissions; + if(ptrGetEffectiveRightsFromAclW(pDacl, &worldTrusteeW, &access_mask) != ERROR_SUCCESS) + access_mask = (ACCESS_MASK)-1; // ### + if(access_mask & ReadMask) + data.entryFlags |= QFileSystemMetaData::OtherReadPermission; + if(access_mask & WriteMask) + data.entryFlags |= QFileSystemMetaData::OtherWritePermission; + if(access_mask & ExecMask) + data.entryFlags |= QFileSystemMetaData::OwnerExecutePermission; + } + LocalFree(pSD); + } + } + } else +#endif + { + //### what to do with permissions if we don't use NTFS + // for now just add all permissions and what about exe missions ?? + // also qt_ntfs_permission_lookup is now not set by default ... should it ? + data.entryFlags |= QFileSystemMetaData::OwnerReadPermission + | QFileSystemMetaData::GroupReadPermission + | QFileSystemMetaData::OtherReadPermission; + + if (!(data.fileAttribute_ & FILE_ATTRIBUTE_READONLY)) { + data.entryFlags |= QFileSystemMetaData::OwnerWritePermission + | QFileSystemMetaData::GroupWritePermission + | QFileSystemMetaData::OtherWritePermission; + } + + QString fname = entry.filePath(); + QString ext = fname.right(4).toLower(); + if (data.isDirectory() || + ext == QLatin1String(".exe") || ext == QLatin1String(".com") || ext == QLatin1String(".bat") || + ext == QLatin1String(".pif") || ext == QLatin1String(".cmd")) { + data.entryFlags |= QFileSystemMetaData::OwnerExecutePermission | QFileSystemMetaData::GroupExecutePermission + | QFileSystemMetaData::OtherExecutePermission | QFileSystemMetaData::UserExecutePermission; + } + data.knownFlagsMask |= QFileSystemMetaData::OwnerPermissions | QFileSystemMetaData::GroupPermissions + | QFileSystemMetaData::OtherPermissions | QFileSystemMetaData::UserExecutePermission; + // calculate user permissions + if (what & QFileSystemMetaData::UserReadPermission) { + if (::_waccess((wchar_t*)entry.nativeFilePath().utf16(), R_OK) == 0) + data.entryFlags |= QFileSystemMetaData::UserReadPermission; + data.knownFlagsMask |= QFileSystemMetaData::UserReadPermission; + } + if (what & QFileSystemMetaData::UserWritePermission) { + if (::_waccess((wchar_t*)entry.nativeFilePath().utf16(), W_OK) == 0) + data.entryFlags |= QFileSystemMetaData::UserWritePermission; + data.knownFlagsMask |= QFileSystemMetaData::UserReadPermission; + } + } + + return data.hasFlags(what); +} + +static bool tryDriveUNCFallback(const QFileSystemEntry &fname, QFileSystemMetaData &data) +{ + bool entryExists = false; + DWORD fileAttrib = 0; +#if !defined(Q_OS_WINCE) + if (fname.isDriveRoot()) { + // a valid drive ?? + DWORD drivesBitmask = ::GetLogicalDrives(); + int drivebit = 1 << (fname.filePath().at(0).toUpper().unicode() - QLatin1Char('A').unicode()); + if (drivesBitmask & drivebit) { + fileAttrib = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM; + entryExists = true; + } + } else { +#endif + const QString &path = fname.nativeFilePath(); + bool is_dir = false; + if (path.startsWith(QLatin1String("\\\\?\\UNC"))) { + // UNC - stat doesn't work for all cases (Windows bug) + int s = path.indexOf(path.at(0),7); + if (s > 0) { + // "\\?\UNC\server\..." + s = path.indexOf(path.at(0),s+1); + if (s > 0) { + // "\\?\UNC\server\share\..." + if (s == path.size() - 1) { + // "\\?\UNC\server\share\" + is_dir = true; + } else { + // "\\?\UNC\server\share\notfound" + } + } else { + // "\\?\UNC\server\share" + is_dir = true; + } + } else { + // "\\?\UNC\server" + is_dir = true; + } + } + if (is_dir && uncShareExists(path)) { + // looks like a UNC dir, is a dir. + fileAttrib = FILE_ATTRIBUTE_DIRECTORY; + entryExists = true; + } +#if !defined(Q_OS_WINCE) + } +#endif + if (entryExists) + data.fillFromFileAttribute(fileAttrib); + return entryExists; +} + +static bool tryFindFallback(const QFileSystemEntry &fname, QFileSystemMetaData &data) +{ + bool filledData = false; + // This assumes the last call to a Windows API failed. + int errorCode = GetLastError(); + if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) { + WIN32_FIND_DATA findData; + if (getFindData(fname.nativeFilePath(), findData) + && findData.dwFileAttributes != INVALID_FILE_ATTRIBUTES) { + data.fillFromFindData(findData, true, fname.isDriveRoot()); + filledData = true; + } + } + return filledData; +} + +#if !defined(Q_OS_WINCE) +//static +bool QFileSystemEngine::fillMetaData(int fd, QFileSystemMetaData &data, + QFileSystemMetaData::MetaDataFlags what) +{ + HANDLE fHandle = (HANDLE)_get_osfhandle(fd); + if (fHandle != INVALID_HANDLE_VALUE) { + return fillMetaData(fHandle, data, what); + } + return false; +} +#endif + +//static +bool QFileSystemEngine::fillMetaData(HANDLE fHandle, QFileSystemMetaData &data, + QFileSystemMetaData::MetaDataFlags what) +{ + data.entryFlags &= ~what; + clearWinStatData(data); + BY_HANDLE_FILE_INFORMATION fileInfo; + UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); + if (GetFileInformationByHandle(fHandle , &fileInfo)) { + data.fillFromFindInfo(fileInfo); + } + SetErrorMode(oldmode); + return data.hasFlags(what); +} + +//static +bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, + QFileSystemMetaData::MetaDataFlags what) +{ + what |= QFileSystemMetaData::WinLnkType | QFileSystemMetaData::WinStatFlags; + data.entryFlags &= ~what; + + QFileSystemEntry fname; + data.knownFlagsMask |= QFileSystemMetaData::WinLnkType; + if(entry.filePath().endsWith(QLatin1String(".lnk"))) { + data.entryFlags |= QFileSystemMetaData::WinLnkType; + fname = QFileSystemEntry(readLink(entry)); + } else { + fname = entry; + } + + if (fname.isEmpty()) { + data.knownFlagsMask |= what; + clearWinStatData(data); + return false; + } + + if (what & QFileSystemMetaData::WinStatFlags) { + UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); + clearWinStatData(data); + WIN32_FIND_DATA findData; + // The memory structure for WIN32_FIND_DATA is same as WIN32_FILE_ATTRIBUTE_DATA + // for all members used by fillFindData(). + bool ok = ::GetFileAttributesEx((wchar_t*)fname.nativeFilePath().utf16(), GetFileExInfoStandard, + reinterpret_cast(&findData)); + if (ok) { + data.fillFromFindData(findData, false, fname.isDriveRoot()); + } else { + if (!tryFindFallback(fname, data)) + tryDriveUNCFallback(fname, data); + } + SetErrorMode(oldmode); + } + + if (what & QFileSystemMetaData::Permissions) + fillPermissions(fname, data, what); + if ((what & QFileSystemMetaData::LinkType) + && data.missingFlags(QFileSystemMetaData::LinkType)) { + data.knownFlagsMask |= QFileSystemMetaData::LinkType; + if (data.fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT) { + WIN32_FIND_DATA findData; + if (getFindData(fname.nativeFilePath(), findData)) + data.fillFromFindData(findData, true); + } + } + data.knownFlagsMask |= what; + return data.hasFlags(what); +} + +static inline bool mkDir(const QString &path) +{ +#if defined(Q_OS_WINCE) + // Unfortunately CreateDirectory returns true for paths longer than + // 256, but does not create a directory. It starts to fail, when + // path length > MAX_PATH, which is 260 usually on CE. + // This only happens on a Windows Mobile device. Windows CE seems + // not to be affected by this. + static int platformId = 0; + if (platformId == 0) { + wchar_t platformString[64]; + if (SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(platformString)/sizeof(*platformString),platformString,0)) { + if (0 == wcscmp(platformString, L"PocketPC") || 0 == wcscmp(platformString, L"Smartphone")) + platformId = 1; + else + platformId = 2; + } + } + if (platformId == 1 && QFSFileEnginePrivate::longFileName(path).size() > 256) + return false; +#endif + return ::CreateDirectory((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), 0); +} + +static inline bool rmDir(const QString &path) +{ + return ::RemoveDirectory((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16()); +} + +static bool isDirPath(const QString &dirPath, bool *existed) +{ + QString path = dirPath; + if (path.length() == 2 && path.at(1) == QLatin1Char(':')) + path += QLatin1Char('\\'); + + DWORD fileAttrib = ::GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16()); + if (fileAttrib == INVALID_FILE_ATTRIBUTES) { + int errorCode = GetLastError(); + if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) { + WIN32_FIND_DATA findData; + if (getFindData(QFSFileEnginePrivate::longFileName(path), findData)) + fileAttrib = findData.dwFileAttributes; + } + } + + if (existed) + *existed = fileAttrib != INVALID_FILE_ATTRIBUTES; + + if (fileAttrib == INVALID_FILE_ATTRIBUTES) + return false; + + return fileAttrib & FILE_ATTRIBUTE_DIRECTORY; } //static bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents) { - return false; // TODO implement; + QString dirName = entry.filePath(); + if (createParents) { + dirName = QDir::toNativeSeparators(QDir::cleanPath(dirName)); + // We spefically search for / so \ would break it.. + int oldslash = -1; + if (dirName.startsWith(QLatin1String("\\\\"))) { + // Don't try to create the root path of a UNC path; + // CreateDirectory() will just return ERROR_INVALID_NAME. + for (int i = 0; i < dirName.size(); ++i) { + if (dirName.at(i) != QDir::separator()) { + oldslash = i; + break; + } + } + if (oldslash != -1) + oldslash = dirName.indexOf(QDir::separator(), oldslash); + } + for (int slash=0; slash != -1; oldslash = slash) { + slash = dirName.indexOf(QDir::separator(), oldslash+1); + if (slash == -1) { + if (oldslash == dirName.length()) + break; + slash = dirName.length(); + } + if (slash) { + QString chunk = dirName.left(slash); + bool existed = false; + if (!isDirPath(chunk, &existed)) { + if (!existed) { + if (!mkDir(chunk)) + return false; + } else { + return false; + } + } + } + } + return true; + } + return mkDir(entry.filePath()); } //static bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents) { - return false; // TODO implement; + QString dirName = entry.filePath(); + if (removeEmptyParents) { + dirName = QDir::toNativeSeparators(QDir::cleanPath(dirName)); + for (int oldslash = 0, slash=dirName.length(); slash > 0; oldslash = slash) { + QString chunk = dirName.left(slash); + if (chunk.length() == 2 && chunk.at(0).isLetter() && chunk.at(1) == QLatin1Char(':')) + break; + if (!isDirPath(chunk, 0)) + return false; + if (!rmDir(chunk)) + return oldslash != 0; + slash = dirName.lastIndexOf(QDir::separator(), oldslash-1); + } + return true; + } + return rmDir(entry.filePath()); +} + +//static +QString QFileSystemEngine::rootPath() +{ +#if defined(Q_OS_WINCE) + QString ret = QLatin1String("/"); +#elif defined(Q_FS_FAT) + QString ret = QString::fromLatin1(qgetenv("SystemDrive").constData()); + if (ret.isEmpty()) + ret = QLatin1String("c:"); + ret.append(QLatin1Char('/')); +#elif defined(Q_OS_OS2EMX) + char dir[4]; + _abspath(dir, QLatin1String("/"), _MAX_PATH); + QString ret(dir); +#endif + return ret; +} + +//static +QString QFileSystemEngine::homePath() +{ + QString ret; +#if !defined(QT_NO_LIBRARY) + resolveLibs(); + if (ptrGetUserProfileDirectoryW) { + HANDLE hnd = ::GetCurrentProcess(); + HANDLE token = 0; + BOOL ok = ::OpenProcessToken(hnd, TOKEN_QUERY, &token); + if (ok) { + DWORD dwBufferSize = 0; + // First call, to determine size of the strings (with '\0'). + ok = ptrGetUserProfileDirectoryW(token, NULL, &dwBufferSize); + if (!ok && dwBufferSize != 0) { // We got the required buffer size + wchar_t *userDirectory = new wchar_t[dwBufferSize]; + // Second call, now we can fill the allocated buffer. + ok = ptrGetUserProfileDirectoryW(token, userDirectory, &dwBufferSize); + if (ok) + ret = QString::fromWCharArray(userDirectory); + delete [] userDirectory; + } + ::CloseHandle(token); + } + } +#endif + if (ret.isEmpty() || !QFile::exists(ret)) { + ret = QString::fromLocal8Bit(qgetenv("USERPROFILE").constData()); + if (ret.isEmpty() || !QFile::exists(ret)) { + ret = QString::fromLocal8Bit(qgetenv("HOMEDRIVE").constData()) + + QString::fromLocal8Bit(qgetenv("HOMEPATH").constData()); + if (ret.isEmpty() || !QFile::exists(ret)) { + ret = QString::fromLocal8Bit(qgetenv("HOME").constData()); + if (ret.isEmpty() || !QFile::exists(ret)) { +#if defined(Q_OS_WINCE) + ret = QLatin1String("\\My Documents"); + if (!QFile::exists(ret)) +#endif + ret = rootPath(); + } + } + } + } + return QDir::fromNativeSeparators(ret); } //static @@ -111,25 +1094,90 @@ bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSy //static bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target) { - return false; // TODO implement; + bool ret = ::CopyFile((wchar_t*)source.nativeFilePath().utf16(), + (wchar_t*)target.nativeFilePath().utf16(), true) != 0; + return ret; } //static bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target) { - return false; // TODO implement; + bool ret = ::MoveFile((wchar_t*)source.nativeFilePath().utf16(), + (wchar_t*)target.nativeFilePath().utf16()) != 0; + return ret; } //static bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry) { - return false; // TODO implement; + bool ret = ::DeleteFile((wchar_t*)entry.nativeFilePath().utf16()) != 0; + return ret; } //static -bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QFileSystemMetaData *data) +bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, + QFileSystemMetaData *data) { - return false; // TODO implement; + Q_UNUSED(data); + int mode = 0; + + if (permissions & QFile::ReadOwner || permissions & QFile::ReadUser + || permissions & QFile::ReadGroup || permissions & QFile::ReadOther) + mode |= _S_IREAD; + if (permissions & QFile::WriteOwner || permissions & QFile::WriteUser + || permissions & QFile::WriteGroup || permissions & QFile::WriteOther) + mode |= _S_IWRITE; + + if (mode == 0) // not supported + return false; + + return ::_wchmod((wchar_t*)entry.nativeFilePath().utf16(), mode) == 0; +} + +static inline QDateTime fileTimeToQDateTime(const FILETIME *time) +{ + QDateTime ret; + +#if defined(Q_OS_WINCE) + SYSTEMTIME systime; + FILETIME ftime; + systime.wYear = 1970; + systime.wMonth = 1; + systime.wDay = 1; + systime.wHour = 0; + systime.wMinute = 0; + systime.wSecond = 0; + systime.wMilliseconds = 0; + systime.wDayOfWeek = 4; + SystemTimeToFileTime(&systime, &ftime); + unsigned __int64 acttime = (unsigned __int64)time->dwHighDateTime << 32 | time->dwLowDateTime; + FileTimeToSystemTime(time, &systime); + unsigned __int64 time1970 = (unsigned __int64)ftime.dwHighDateTime << 32 | ftime.dwLowDateTime; + unsigned __int64 difftime = acttime - time1970; + difftime /= 10000000; + ret.setTime_t((unsigned int)difftime); +#else + SYSTEMTIME sTime, lTime; + FileTimeToSystemTime(time, &sTime); + SystemTimeToTzSpecificLocalTime(0, &sTime, &lTime); + ret.setDate(QDate(lTime.wYear, lTime.wMonth, lTime.wDay)); + ret.setTime(QTime(lTime.wHour, lTime.wMinute, lTime.wSecond, lTime.wMilliseconds)); +#endif + + return ret; +} + +QDateTime QFileSystemMetaData::creationTime() const +{ + return fileTimeToQDateTime(&creationTime_); +} +QDateTime QFileSystemMetaData::modificationTime() const +{ + return fileTimeToQDateTime(&lastWriteTime_); +} +QDateTime QFileSystemMetaData::accessTime() const +{ + return fileTimeToQDateTime(&lastAccessTime_); } QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index e45c5dc..29ef987 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -111,9 +111,14 @@ public: BundleType = 0x0, AliasType = 0x0, #endif +#if defined(Q_OS_WIN) + WinLnkType = 0x08000000, // Note: Uses the same position for AliasType on Mac +#else + WinLnkType = 0x0, +#endif SequentialType = 0x00800000, // Note: overlaps with QAbstractFileEngine::RootFlag - LegacyLinkType = LinkType | AliasType, + LegacyLinkType = LinkType | AliasType | WinLnkType, Type = LinkType | FileType | DirectoryType | BundleType | SequentialType | AliasType, @@ -153,6 +158,14 @@ public: | QFileSystemMetaData::SequentialType | QFileSystemMetaData::Attributes | QFileSystemMetaData::Times, +#if defined(Q_OS_WIN) + WinStatFlags = QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::HiddenAttribute + | QFileSystemMetaData::ExistsAttribute + | QFileSystemMetaData::SizeAttribute + | QFileSystemMetaData::Times, +#endif AllMetaDataFlags = 0xFFFFFFFF @@ -181,7 +194,7 @@ public: bool exists() const { return (entryFlags & ExistsAttribute); } - bool isLink() const { return (entryFlags & LinkType); } + bool isLink() const { return (entryFlags & LinkType); } bool isFile() const { return (entryFlags & FileType); } bool isDirectory() const { return (entryFlags & DirectoryType); } bool isBundle() const; @@ -189,6 +202,11 @@ public: bool isLegacyLink() const { return (entryFlags & LegacyLinkType); } bool isSequential() const { return (entryFlags & SequentialType); } bool isHidden() const { return (entryFlags & HiddenAttribute); } +#if defined(Q_OS_WIN) + bool isLnkFile() const { return (entryFlags & WinLnkType); } +#else + bool isLnkFile() const { return false; } +#endif qint64 size() const { return size_; } @@ -212,6 +230,11 @@ public: void fillFromVolumeInfo(const TVolumeInfo& info); #endif +#if defined(Q_OS_WIN) + inline void fillFromFileAttribute(DWORD fileAttribute, bool isDriveRoot = false); + inline void fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType = false, bool isDriveRoot = false); + inline void fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo); +#endif private: friend class QFileSystemEngine; @@ -222,6 +245,10 @@ private: // Platform-specific data goes here: #if defined(Q_OS_WIN) + DWORD fileAttribute_; + FILETIME creationTime_; + FILETIME lastAccessTime_; + FILETIME lastWriteTime_; #elif defined(Q_OS_SYMBIAN) TTime modificationTime_; #else @@ -245,11 +272,7 @@ inline bool QFileSystemMetaData::isBundle() const { return fal inline bool QFileSystemMetaData::isAlias() const { return false; } #endif -#if defined(Q_OS_UNIX) && !defined (Q_OS_SYMBIAN) -inline QDateTime QFileSystemMetaData::creationTime() const { return QDateTime::fromTime_t(creationTime_); } -inline QDateTime QFileSystemMetaData::modificationTime() const { return QDateTime::fromTime_t(modificationTime_); } -inline QDateTime QFileSystemMetaData::accessTime() const { return QDateTime::fromTime_t(accessTime_); } - +#if (defined(Q_OS_UNIX) && !defined (Q_OS_SYMBIAN)) || defined (Q_OS_WIN) inline QDateTime QFileSystemMetaData::fileTime(QAbstractFileEngine::FileTime time) const { switch (time) { @@ -265,6 +288,12 @@ inline QDateTime QFileSystemMetaData::fileTime(QAbstractFileEngine::FileTime tim return QDateTime(); } +#endif + +#if defined(Q_OS_UNIX) && !defined (Q_OS_SYMBIAN) +inline QDateTime QFileSystemMetaData::creationTime() const { return QDateTime::fromTime_t(creationTime_); } +inline QDateTime QFileSystemMetaData::modificationTime() const { return QDateTime::fromTime_t(modificationTime_); } +inline QDateTime QFileSystemMetaData::accessTime() const { return QDateTime::fromTime_t(accessTime_); } inline uint QFileSystemMetaData::userId() const { return userId_; } inline uint QFileSystemMetaData::groupId() const { return groupId_; } @@ -297,6 +326,18 @@ inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) c } #endif +#if defined(Q_OS_WIN) +inline uint QFileSystemMetaData::userId() const { return (uint) -2; } +inline uint QFileSystemMetaData::groupId() const { return (uint) -2; } +inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) const +{ + if (owner == QAbstractFileEngine::OwnerUser) + return userId(); + else + return groupId(); +} +#endif + QT_END_NAMESPACE #endif // include guard diff --git a/src/corelib/io/qfsfileengine_iterator_win.cpp b/src/corelib/io/qfsfileengine_iterator_win.cpp index 7181025..d4e6f5a 100644 --- a/src/corelib/io/qfsfileengine_iterator_win.cpp +++ b/src/corelib/io/qfsfileengine_iterator_win.cpp @@ -41,6 +41,7 @@ #include "qfsfileengine_iterator_p.h" #include "qfsfileengine_p.h" +#include "qfilesystemengine_p.h" #include "qplatformdefs.h" #include @@ -135,7 +136,7 @@ bool QFSFileEngineIterator::hasNext() const // UNC QStringList parts = QDir::toNativeSeparators(path).split(QLatin1Char('\\'), QString::SkipEmptyParts); - if (parts.count() == 1 && QFSFileEnginePrivate::uncListSharesOnServer(QLatin1String("\\\\") + parts.at(0), + if (parts.count() == 1 && QFileSystemEngine::uncListSharesOnServer(QLatin1String("\\\\") + parts.at(0), &platform->uncShares)) { if (platform->uncShares.isEmpty()) { platform->done = true; diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index a3733d8..14a8938 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -114,9 +114,7 @@ public: uchar *map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags); bool unmap(uchar *ptr); -#if defined(Q_OS_UNIX) mutable QFileSystemMetaData metaData; -#endif FILE *fh; #ifdef Q_OS_SYMBIAN @@ -177,7 +175,7 @@ public: #endif #if defined(Q_OS_WIN) - bool doStat() const; + bool doStat(QFileSystemMetaData::MetaDataFlags flags) const; #else bool doStat(QFileSystemMetaData::MetaDataFlags flags = QFileSystemMetaData::PosixStatFlags) const; #endif @@ -187,12 +185,6 @@ public: int sysOpen(const QString &, int flags); #endif -#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) - static void resolveLibs(); - static bool resolveUNCLibs(); - static bool uncListSharesOnServer(const QString &server, QStringList *list); -#endif - #ifdef Q_OS_SYMBIAN void setSymbianError(int symbianError, QFile::FileError defaultError, QString defaultString); #endif diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 7262129..976207a 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -69,69 +69,9 @@ #define SECURITY_WIN32 #include -#ifndef _INTPTR_T_DEFINED -#ifdef _WIN64 -typedef __int64 intptr_t; -#else -#ifdef _W64 -typedef _W64 int intptr_t; -#else -typedef INT_PTR intptr_t; -#endif -#endif -#define _INTPTR_T_DEFINED -#endif - -#ifndef INVALID_FILE_ATTRIBUTES -# define INVALID_FILE_ATTRIBUTES (DWORD (-1)) -#endif - -#if !defined(Q_OS_WINCE) -# if !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) -typedef struct _REPARSE_DATA_BUFFER { - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union { - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - struct { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - }; -} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; -# define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) -# endif // !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) - -# ifndef MAXIMUM_REPARSE_DATA_BUFFER_SIZE -# define MAXIMUM_REPARSE_DATA_BUFFER_SIZE 16384 -# endif -# ifndef IO_REPARSE_TAG_SYMLINK -# define IO_REPARSE_TAG_SYMLINK (0xA000000CL) -# endif -# ifndef FSCTL_GET_REPARSE_POINT -# define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) -# endif -#endif // !defined(Q_OS_WINCE) - QT_BEGIN_NAMESPACE -static QString readLink(const QFileSystemEntry &link); -Q_CORE_EXPORT int qt_ntfs_permission_lookup = 0; #if defined(Q_OS_WINCE) static QString qfsPrivateCurrentDir = QLatin1String(""); @@ -140,146 +80,6 @@ static QString qfsPrivateCurrentDir = QLatin1String(""); #define QT_NO_LIBRARY 1 #endif -#if !defined(QT_NO_LIBRARY) -QT_BEGIN_INCLUDE_NAMESPACE -typedef DWORD (WINAPI *PtrGetNamedSecurityInfoW)(LPWSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION, PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*); -static PtrGetNamedSecurityInfoW ptrGetNamedSecurityInfoW = 0; -typedef BOOL (WINAPI *PtrLookupAccountSidW)(LPCWSTR, PSID, LPWSTR, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE); -static PtrLookupAccountSidW ptrLookupAccountSidW = 0; -typedef VOID (WINAPI *PtrBuildTrusteeWithSidW)(PTRUSTEE_W, PSID); -static PtrBuildTrusteeWithSidW ptrBuildTrusteeWithSidW = 0; -typedef DWORD (WINAPI *PtrGetEffectiveRightsFromAclW)(PACL, PTRUSTEE_W, OUT PACCESS_MASK); -static PtrGetEffectiveRightsFromAclW ptrGetEffectiveRightsFromAclW = 0; -static TRUSTEE_W currentUserTrusteeW; -static TRUSTEE_W worldTrusteeW; - -typedef BOOL (WINAPI *PtrGetUserProfileDirectoryW)(HANDLE, LPWSTR, LPDWORD); -static PtrGetUserProfileDirectoryW ptrGetUserProfileDirectoryW = 0; -typedef BOOL (WINAPI *PtrGetVolumePathNamesForVolumeNameW)(LPCWSTR,LPWSTR,DWORD,PDWORD); -static PtrGetVolumePathNamesForVolumeNameW ptrGetVolumePathNamesForVolumeNameW = 0; -QT_END_INCLUDE_NAMESPACE - - -void QFSFileEnginePrivate::resolveLibs() -{ - static bool triedResolve = false; - if (!triedResolve) { - // need to resolve the security info functions - - // protect initialization -#ifndef QT_NO_THREAD - QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve)); - // check triedResolve again, since another thread may have already - // done the initialization - if (triedResolve) { - // another thread did initialize the security function pointers, - // so we shouldn't do it again. - return; - } -#endif - - triedResolve = true; -#if !defined(Q_OS_WINCE) - HINSTANCE advapiHnd = LoadLibrary(L"advapi32"); - if (advapiHnd) { - ptrGetNamedSecurityInfoW = (PtrGetNamedSecurityInfoW)GetProcAddress(advapiHnd, "GetNamedSecurityInfoW"); - ptrLookupAccountSidW = (PtrLookupAccountSidW)GetProcAddress(advapiHnd, "LookupAccountSidW"); - ptrBuildTrusteeWithSidW = (PtrBuildTrusteeWithSidW)GetProcAddress(advapiHnd, "BuildTrusteeWithSidW"); - ptrGetEffectiveRightsFromAclW = (PtrGetEffectiveRightsFromAclW)GetProcAddress(advapiHnd, "GetEffectiveRightsFromAclW"); - } - if (ptrBuildTrusteeWithSidW) { - // Create TRUSTEE for current user - HANDLE hnd = ::GetCurrentProcess(); - HANDLE token = 0; - if (::OpenProcessToken(hnd, TOKEN_QUERY, &token)) { - TOKEN_USER tu; - DWORD retsize; - if (::GetTokenInformation(token, TokenUser, &tu, sizeof(tu), &retsize)) - ptrBuildTrusteeWithSidW(¤tUserTrusteeW, tu.User.Sid); - ::CloseHandle(token); - } - - typedef BOOL (WINAPI *PtrAllocateAndInitializeSid)(PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, PSID*); - PtrAllocateAndInitializeSid ptrAllocateAndInitializeSid = (PtrAllocateAndInitializeSid)GetProcAddress(advapiHnd, "AllocateAndInitializeSid"); - typedef PVOID (WINAPI *PtrFreeSid)(PSID); - PtrFreeSid ptrFreeSid = (PtrFreeSid)GetProcAddress(advapiHnd, "FreeSid"); - if (ptrAllocateAndInitializeSid && ptrFreeSid) { - // Create TRUSTEE for Everyone (World) - SID_IDENTIFIER_AUTHORITY worldAuth = { SECURITY_WORLD_SID_AUTHORITY }; - PSID pWorld = 0; - if (ptrAllocateAndInitializeSid(&worldAuth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pWorld)) - ptrBuildTrusteeWithSidW(&worldTrusteeW, pWorld); - ptrFreeSid(pWorld); - } - } - HINSTANCE userenvHnd = LoadLibrary(L"userenv"); - if (userenvHnd) - ptrGetUserProfileDirectoryW = (PtrGetUserProfileDirectoryW)GetProcAddress(userenvHnd, "GetUserProfileDirectoryW"); - HINSTANCE kernel32 = LoadLibrary(L"kernel32"); - if(kernel32) - ptrGetVolumePathNamesForVolumeNameW = (PtrGetVolumePathNamesForVolumeNameW)GetProcAddress(kernel32, "GetVolumePathNamesForVolumeNameW"); -#endif - } -} -#endif // QT_NO_LIBRARY - -typedef DWORD (WINAPI *PtrNetShareEnum)(LPWSTR, DWORD, LPBYTE*, DWORD, LPDWORD, LPDWORD, LPDWORD); -static PtrNetShareEnum ptrNetShareEnum = 0; -typedef DWORD (WINAPI *PtrNetApiBufferFree)(LPVOID); -static PtrNetApiBufferFree ptrNetApiBufferFree = 0; -typedef struct _SHARE_INFO_1 { - LPWSTR shi1_netname; - DWORD shi1_type; - LPWSTR shi1_remark; -} SHARE_INFO_1; - - -bool QFSFileEnginePrivate::resolveUNCLibs() -{ - static bool triedResolve = false; - if (!triedResolve) { -#ifndef QT_NO_THREAD - QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve)); - if (triedResolve) { - return ptrNetShareEnum && ptrNetApiBufferFree; - } -#endif - triedResolve = true; -#if !defined(Q_OS_WINCE) - HINSTANCE hLib = LoadLibrary(L"netapi32"); - if (hLib) { - ptrNetShareEnum = (PtrNetShareEnum)GetProcAddress(hLib, "NetShareEnum"); - if (ptrNetShareEnum) - ptrNetApiBufferFree = (PtrNetApiBufferFree)GetProcAddress(hLib, "NetApiBufferFree"); - } -#endif - } - return ptrNetShareEnum && ptrNetApiBufferFree; -} - -bool QFSFileEnginePrivate::uncListSharesOnServer(const QString &server, QStringList *list) -{ - if (resolveUNCLibs()) { - SHARE_INFO_1 *BufPtr, *p; - DWORD res; - DWORD er = 0, tr = 0, resume = 0, i; - do { - res = ptrNetShareEnum((wchar_t*)server.utf16(), 1, (LPBYTE *)&BufPtr, DWORD(-1), &er, &tr, &resume); - if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) { - p = BufPtr; - for (i = 1; i <= er; ++i) { - if (list && p->shi1_type == 0) - list->append(QString::fromWCharArray(p->shi1_netname)); - p++; - } - } - ptrNetApiBufferFree(BufPtr); - } while (res == ERROR_MORE_DATA); - return res == ERROR_SUCCESS; - } - return false; -} - #if !defined(Q_OS_WINCE) static inline bool isUncPath(const QString &path) { @@ -289,47 +89,6 @@ static inline bool isUncPath(const QString &path) } #endif -// can be //server or //server/share -static bool uncShareExists(const QString &server) -{ - QStringList parts = server.split(QLatin1Char('\\'), QString::SkipEmptyParts); - if (parts.count()) { - QStringList shares; - if (QFSFileEnginePrivate::uncListSharesOnServer(QLatin1String("\\\\") + parts.at(0), &shares)) - return parts.count() >= 2 ? shares.contains(parts.at(1), Qt::CaseInsensitive) : true; - } - return false; -} - -static QString nativeAbsoluteFilePath(const QString &path) -{ - QString absPath; -#if !defined(Q_OS_WINCE) - QVarLengthArray buf(qMax(MAX_PATH, path.size() + 1)); - wchar_t *fileName = 0; - DWORD retLen = GetFullPathName((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName); - if (retLen > (DWORD)buf.size()) { - buf.resize(retLen); - retLen = GetFullPathName((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName); - } - if (retLen != 0) - absPath = QString::fromWCharArray(buf.data(), retLen); -#else - if (path.startsWith(QLatin1Char('/')) || path.startsWith(QLatin1Char('\\'))) - absPath = QDir::toNativeSeparators(path); - else - absPath = QDir::toNativeSeparators(QDir::cleanPath(qfsPrivateCurrentDir + QLatin1Char('/') + path)); -#endif - // This is really ugly, but GetFullPathName strips off whitespace at the end. - // If you for instance write ". " in the lineedit of QFileDialog, - // (which is an invalid filename) this function will strip the space off and viola, - // the file is later reported as existing. Therefore, we re-add the whitespace that - // was at the end of path in order to keep the filename invalid. - if (!path.isEmpty() && path.at(path.size() - 1) == QLatin1Char(' ')) - absPath.append(QLatin1Char(' ')); - return absPath; -} - /*! \internal */ @@ -338,7 +97,7 @@ QString QFSFileEnginePrivate::longFileName(const QString &path) if (path.startsWith(QLatin1String("\\\\.\\"))) return path; - QString absPath = nativeAbsoluteFilePath(path); + QString absPath = QFileSystemEngine::nativeAbsoluteFilePath(path); #if !defined(Q_OS_WINCE) QString prefix = QLatin1String("\\\\?\\"); if (isUncPath(absPath)) { @@ -389,7 +148,6 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) // WriteOnly can create files, ReadOnly cannot. DWORD creationDisp = (openMode & QIODevice::WriteOnly) ? OPEN_ALWAYS : OPEN_EXISTING; - // Create the file handle. fileHandle = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(), accessRights, @@ -481,17 +239,9 @@ qint64 QFSFileEnginePrivate::nativeSize() const // ### Don't flush; for buffered files, we should get away with ftell. thatQ->flush(); -#if !defined(Q_OS_WINCE) - // stdlib/stdio mode. - if (fh || fd != -1) { - qint64 fileSize = _filelengthi64(fh ? QT_FILENO(fh) : fd); - if (fileSize == -1) { - fileSize = 0; - thatQ->setError(QFile::UnspecifiedError, qt_error_string(errno)); - } - return fileSize; - } -#else // Q_OS_WINCE + // Always retrive the current information + metaData.clearFlags(QFileSystemMetaData::SizeAttribute); +#if defined(Q_OS_WINCE) // Buffered stdlib mode. if (fh) { QT_OFF_T oldPos = QT_FTELL(fh); @@ -504,57 +254,23 @@ qint64 QFSFileEnginePrivate::nativeSize() const } return fileSize; } -#endif - - // Not-open mode, where the file name is known: We'll check the - // file system directly. - if (openMode == QIODevice::NotOpen && !fileEntry.isEmpty()) { - WIN32_FILE_ATTRIBUTE_DATA attribData; - bool ok = ::GetFileAttributesEx((const wchar_t*)fileEntry.nativeFilePath().utf16(), - GetFileExInfoStandard, &attribData); - if (!ok) { - int errorCode = GetLastError(); - if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) { - WIN32_FIND_DATA findData; - if (getFindData(fileEntry.nativeFilePath(), findData)) { - ok = true; - attribData.nFileSizeHigh = findData.nFileSizeHigh; - attribData.nFileSizeLow = findData.nFileSizeLow; - } - } - } - if (ok) { - qint64 size = attribData.nFileSizeHigh; - size <<= 32; - size += attribData.nFileSizeLow; - return size; - } - thatQ->setError(QFile::UnspecifiedError, qt_error_string()); - return 0; - } - -#if defined(Q_OS_WINCE) - // Unbuffed stdio mode if (fd != -1) { thatQ->setError(QFile::UnspecifiedError, QLatin1String("Not implemented!")); return 0; } #endif + bool filled = false; + if (fileHandle != INVALID_HANDLE_VALUE && openMode != QIODevice::NotOpen ) + filled = QFileSystemEngine::fillMetaData(fileHandle, metaData, + QFileSystemMetaData::SizeAttribute); + else + filled = doStat(QFileSystemMetaData::SizeAttribute); - // Windows native mode. - if (fileHandle == INVALID_HANDLE_VALUE) - return 0; - - BY_HANDLE_FILE_INFORMATION fileInfo; - if (!GetFileInformationByHandle(fileHandle, &fileInfo)) { - thatQ->setError(QFile::UnspecifiedError, qt_error_string()); + if (!filled || metaData.size() == -1) { + thatQ->setError(QFile::UnspecifiedError, qt_error_string(errno)); return 0; } - - qint64 size = fileInfo.nFileSizeHigh; - size <<= 32; - size += fileInfo.nFileSizeLow; - return size; + return metaData.size(); } /* @@ -788,7 +504,7 @@ bool QFSFileEnginePrivate::nativeIsSequential() const bool QFSFileEngine::remove() { Q_D(QFSFileEngine); - bool ret = ::DeleteFile((wchar_t*)d->fileEntry.nativeFilePath().utf16()) != 0; + bool ret = QFileSystemEngine::removeFile(d->fileEntry); if (!ret) setError(QFile::RemoveError, qt_error_string()); return ret; @@ -797,10 +513,7 @@ bool QFSFileEngine::remove() bool QFSFileEngine::copy(const QString ©Name) { Q_D(QFSFileEngine); - - QFileSystemEntry target(copyName); - bool ret = ::CopyFile((wchar_t*)d->fileEntry.nativeFilePath().utf16(), - (wchar_t*)target.nativeFilePath().utf16(), true) != 0; + bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(copyName)); if (!ret) setError(QFile::CopyError, qt_error_string()); return ret; @@ -809,130 +522,20 @@ bool QFSFileEngine::copy(const QString ©Name) bool QFSFileEngine::rename(const QString &newName) { Q_D(QFSFileEngine); - QFileSystemEntry target(newName); - bool ret = ::MoveFile((wchar_t*)d->fileEntry.nativeFilePath().utf16(), - (wchar_t*)target.nativeFilePath().utf16()) != 0; + bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName)); if (!ret) setError(QFile::RenameError, qt_error_string()); return ret; } -static inline bool mkDir(const QString &path) -{ -#if defined(Q_OS_WINCE) - // Unfortunately CreateDirectory returns true for paths longer than - // 256, but does not create a directory. It starts to fail, when - // path length > MAX_PATH, which is 260 usually on CE. - // This only happens on a Windows Mobile device. Windows CE seems - // not to be affected by this. - static int platformId = 0; - if (platformId == 0) { - wchar_t platformString[64]; - if (SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(platformString)/sizeof(*platformString),platformString,0)) { - if (0 == wcscmp(platformString, L"PocketPC") || 0 == wcscmp(platformString, L"Smartphone")) - platformId = 1; - else - platformId = 2; - } - } - if (platformId == 1 && QFSFileEnginePrivate::longFileName(path).size() > 256) - return false; -#endif - return ::CreateDirectory((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), 0); -} - -static inline bool rmDir(const QString &path) -{ - return ::RemoveDirectory((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16()); -} - -static bool isDirPath(const QString &dirPath, bool *existed) -{ - QString path = dirPath; - if (path.length() == 2 && path.at(1) == QLatin1Char(':')) - path += QLatin1Char('\\'); - - DWORD fileAttrib = ::GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16()); - if (fileAttrib == INVALID_FILE_ATTRIBUTES) { - int errorCode = GetLastError(); - if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) { - WIN32_FIND_DATA findData; - if (getFindData(QFSFileEnginePrivate::longFileName(path), findData)) - fileAttrib = findData.dwFileAttributes; - } - } - - if (existed) - *existed = fileAttrib != INVALID_FILE_ATTRIBUTES; - - if (fileAttrib == INVALID_FILE_ATTRIBUTES) - return false; - - return fileAttrib & FILE_ATTRIBUTE_DIRECTORY; -} - bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const { - QString dirName = name; - if (createParentDirectories) { - dirName = QDir::toNativeSeparators(QDir::cleanPath(dirName)); - // We spefically search for / so \ would break it.. - int oldslash = -1; - if (dirName.startsWith(QLatin1String("\\\\"))) { - // Don't try to create the root path of a UNC path; - // CreateDirectory() will just return ERROR_INVALID_NAME. - for (int i = 0; i < dirName.size(); ++i) { - if (dirName.at(i) != QDir::separator()) { - oldslash = i; - break; - } - } - if (oldslash != -1) - oldslash = dirName.indexOf(QDir::separator(), oldslash); - } - for (int slash=0; slash != -1; oldslash = slash) { - slash = dirName.indexOf(QDir::separator(), oldslash+1); - if (slash == -1) { - if (oldslash == dirName.length()) - break; - slash = dirName.length(); - } - if (slash) { - QString chunk = dirName.left(slash); - bool existed = false; - if (!isDirPath(chunk, &existed)) { - if (!existed) { - if (!mkDir(chunk)) - return false; - } else { - return false; - } - } - } - } - return true; - } - return mkDir(name); + return QFileSystemEngine::createDirectory(QFileSystemEntry(name), createParentDirectories); } bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const { - QString dirName = name; - if (recurseParentDirectories) { - dirName = QDir::toNativeSeparators(QDir::cleanPath(dirName)); - for (int oldslash = 0, slash=dirName.length(); slash > 0; oldslash = slash) { - QString chunk = dirName.left(slash); - if (chunk.length() == 2 && chunk.at(0).isLetter() && chunk.at(1) == QLatin1Char(':')) - break; - if (!isDirPath(chunk, 0)) - return false; - if (!rmDir(chunk)) - return oldslash != 0; - slash = dirName.lastIndexOf(QDir::separator(), oldslash-1); - } - return true; - } - return rmDir(name); + return QFileSystemEngine::removeDirectory(QFileSystemEntry(name), recurseParentDirectories); } bool QFSFileEngine::caseSensitive() const @@ -997,64 +600,12 @@ QString QFSFileEngine::currentPath(const QString &fileName) QString QFSFileEngine::homePath() { - QString ret; -#if !defined(QT_NO_LIBRARY) - QFSFileEnginePrivate::resolveLibs(); - if (ptrGetUserProfileDirectoryW) { - HANDLE hnd = ::GetCurrentProcess(); - HANDLE token = 0; - BOOL ok = ::OpenProcessToken(hnd, TOKEN_QUERY, &token); - if (ok) { - DWORD dwBufferSize = 0; - // First call, to determine size of the strings (with '\0'). - ok = ptrGetUserProfileDirectoryW(token, NULL, &dwBufferSize); - if (!ok && dwBufferSize != 0) { // We got the required buffer size - wchar_t *userDirectory = new wchar_t[dwBufferSize]; - // Second call, now we can fill the allocated buffer. - ok = ptrGetUserProfileDirectoryW(token, userDirectory, &dwBufferSize); - if (ok) - ret = QString::fromWCharArray(userDirectory); - - delete [] userDirectory; - } - ::CloseHandle(token); - } - } -#endif - if (ret.isEmpty() || !QFile::exists(ret)) { - ret = QString::fromLocal8Bit(qgetenv("USERPROFILE").constData()); - if (ret.isEmpty() || !QFile::exists(ret)) { - ret = QString::fromLocal8Bit(qgetenv("HOMEDRIVE").constData()) + QString::fromLocal8Bit(qgetenv("HOMEPATH").constData()); - if (ret.isEmpty() || !QFile::exists(ret)) { - ret = QString::fromLocal8Bit(qgetenv("HOME").constData()); - if (ret.isEmpty() || !QFile::exists(ret)) { -#if defined(Q_OS_WINCE) - ret = QLatin1String("\\My Documents"); - if (!QFile::exists(ret)) -#endif - ret = rootPath(); - } - } - } - } - return QDir::fromNativeSeparators(ret); + return QFileSystemEngine::homePath(); } QString QFSFileEngine::rootPath() { -#if defined(Q_OS_WINCE) - QString ret = QLatin1String("/"); -#elif defined(Q_FS_FAT) - QString ret = QString::fromLatin1(qgetenv("SystemDrive").constData()); - if (ret.isEmpty()) - ret = QLatin1String("c:"); - ret.append(QLatin1Char('/')); -#elif defined(Q_OS_OS2EMX) - char dir[4]; - _abspath(dir, QLatin1String("/"), _MAX_PATH); - QString ret(dir); -#endif - return ret; + return QFileSystemEngine::rootPath(); } QString QFSFileEngine::tempPath() @@ -1107,219 +658,25 @@ QFileInfoList QFSFileEngine::drives() #endif } -bool QFSFileEnginePrivate::doStat() const +bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) const { - if (!tried_stat) { + if (!tried_stat || !metaData.hasFlags(flags)) { tried_stat = true; - could_stat = false; - - if (fileEntry.isEmpty()) - return could_stat; - - QFileSystemEntry fname; - if(fileEntry.filePath().endsWith(QLatin1String(".lnk"))) { - fname = QFileSystemEntry(readLink(fileEntry)); - if(fname.isEmpty()) - return could_stat; - } - else - fname = fileEntry; - - UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); - if (fd != -1) { #if !defined(Q_OS_WINCE) - HANDLE fh = (HANDLE)_get_osfhandle(fd); - if (fh != INVALID_HANDLE_VALUE) { - BY_HANDLE_FILE_INFORMATION fileInfo; - if (GetFileInformationByHandle(fh, &fileInfo)) { - could_stat = true; - fileAttrib = fileInfo.dwFileAttributes; - } - } -#else - DWORD tmpAttributes = GetFileAttributes((wchar_t*)fname.nativeFilePath().utf16()); - if (tmpAttributes != -1) { - fileAttrib = tmpAttributes; - could_stat = true; - } -#endif - } else { - fileAttrib = GetFileAttributes((wchar_t*)fname.nativeFilePath().utf16()); - if (fileAttrib == INVALID_FILE_ATTRIBUTES) { - int errorCode = GetLastError(); - if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) { - WIN32_FIND_DATA findData; - if (getFindData(fname.nativeFilePath(), findData)) { - fileAttrib = findData.dwFileAttributes; - } - } - } - could_stat = fileAttrib != INVALID_FILE_ATTRIBUTES; - if (!could_stat) { -#if !defined(Q_OS_WINCE) - if (fname.isDriveRoot()) { - // a valid drive ?? - DWORD drivesBitmask = ::GetLogicalDrives(); - int drivebit = 1 << (fname.filePath().at(0).toUpper().unicode() - QLatin1Char('A').unicode()); - if (drivesBitmask & drivebit) { - fileAttrib = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM; - could_stat = true; - } - } else { -#endif - const QString &path = fname.nativeFilePath(); - bool is_dir = false; - if (path.startsWith(QLatin1String("\\\\"))) { - // UNC - stat doesn't work for all cases (Windows bug) - int s = path.indexOf(path.at(0),2); - if (s > 0) { - // "\\server\..." - s = path.indexOf(path.at(0),s+1); - if (s > 0) { - // "\\server\share\..." - if (s == path.size() - 1) { - // "\\server\share\" - is_dir = true; - } else { - // "\\server\share\notfound" - } - } else { - // "\\server\share" - is_dir = true; - } - } else { - // "\\server" - is_dir = true; - } - } - if (is_dir && uncShareExists(path)) { - // looks like a UNC dir, is a dir. - fileAttrib = FILE_ATTRIBUTE_DIRECTORY; - could_stat = true; - } -#if !defined(Q_OS_WINCE) - } + int localFd = fd; + if (fh && fileEntry.isEmpty()) + localFd = QT_FILENO(fh); + if (localFd != -1) + QFileSystemEngine::fillMetaData(localFd, metaData, flags); #endif - } - } - - SetErrorMode(oldmode); + if (metaData.missingFlags(flags) && !fileEntry.isEmpty()) + QFileSystemEngine::fillMetaData(fileEntry, metaData, metaData.missingFlags(flags)); } - return could_stat; -} - -static QString readSymLink(const QFileSystemEntry &link) -{ - QString result; -#if !defined(Q_OS_WINCE) - HANDLE handle = CreateFile((wchar_t*)link.nativeFilePath().utf16(), - FILE_READ_EA, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, - 0); - if (handle != INVALID_HANDLE_VALUE) { - DWORD bufsize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE; - REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER*)qMalloc(bufsize); - DWORD retsize = 0; - if (::DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, 0, 0, rdb, bufsize, &retsize, 0)) { - if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { - int length = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t); - int offset = rdb->MountPointReparseBuffer.SubstituteNameOffset / sizeof(wchar_t); - const wchar_t* PathBuffer = &rdb->MountPointReparseBuffer.PathBuffer[offset]; - result = QString::fromWCharArray(PathBuffer, length); - } else if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK) { - int length = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t); - int offset = rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t); - const wchar_t* PathBuffer = &rdb->SymbolicLinkReparseBuffer.PathBuffer[offset]; - result = QString::fromWCharArray(PathBuffer, length); - } - // cut-off "//?/" and "/??/" - if (result.size() > 4 && result.at(0) == QLatin1Char('\\') && result.at(2) == QLatin1Char('?') && result.at(3) == QLatin1Char('\\')) - result = result.mid(4); - } - qFree(rdb); - CloseHandle(handle); - -#if !defined(QT_NO_LIBRARY) - QFSFileEnginePrivate::resolveLibs(); - if (ptrGetVolumePathNamesForVolumeNameW) { - QRegExp matchVolName(QLatin1String("^Volume\\{([a-z]|[0-9]|-)+\\}\\\\"), Qt::CaseInsensitive); - if(matchVolName.indexIn(result) == 0) { - DWORD len; - wchar_t buffer[MAX_PATH]; - QString volumeName = result.mid(0, matchVolName.matchedLength()).prepend(QLatin1String("\\\\?\\")); - if(ptrGetVolumePathNamesForVolumeNameW((wchar_t*)volumeName.utf16(), buffer, MAX_PATH, &len) != 0) - result.replace(0,matchVolName.matchedLength(), QString::fromWCharArray(buffer)); - } - } -#endif - } -#else - Q_UNUSED(link); -#endif // Q_OS_WINCE - return result; + return metaData.exists(); } -static QString readLink(const QFileSystemEntry &link) -{ -#if !defined(Q_OS_WINCE) -#if !defined(QT_NO_LIBRARY) && !defined(Q_CC_MWERKS) - QString ret; - - bool neededCoInit = false; - IShellLink *psl; // pointer to IShellLink i/f - WIN32_FIND_DATA wfd; - wchar_t szGotPath[MAX_PATH]; - - // Get pointer to the IShellLink interface. - HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&psl); - - if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized - neededCoInit = true; - CoInitialize(NULL); - hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, - IID_IShellLink, (LPVOID *)&psl); - } - if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface. - IPersistFile *ppf; - hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf); - if (SUCCEEDED(hres)) { - hres = ppf->Load((LPOLESTR)link.nativeFilePath().utf16(), STGM_READ); - //The original path of the link is retrieved. If the file/folder - //was moved, the return value still have the old path. - if (SUCCEEDED(hres)) { - if (psl->GetPath(szGotPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY) == NOERROR) - ret = QString::fromWCharArray(szGotPath); - } - ppf->Release(); - } - psl->Release(); - } - if (neededCoInit) - CoUninitialize(); - - return ret; -#else - Q_UNUSED(link); - return QString(); -#endif // QT_NO_LIBRARY -#else - wchar_t target[MAX_PATH]; - QString result; - if (SHGetShortcutTarget((wchar_t*)QFileInfo(link.filePath()).absoluteFilePath().replace(QLatin1Char('/'),QLatin1Char('\\')).utf16(), target, MAX_PATH)) { - result = QString::fromWCharArray(target); - if (result.startsWith(QLatin1Char('"'))) - result.remove(0,1); - if (result.endsWith(QLatin1Char('"'))) - result.remove(result.size()-1,1); - } - return result; -#endif // Q_OS_WINCE -} bool QFSFileEngine::link(const QString &newName) { @@ -1384,183 +741,63 @@ bool QFSFileEngine::link(const QString &newName) #endif // Q_OS_WINCE } -QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions(QAbstractFileEngine::FileFlags type) const +/*! + \reimp +*/ +QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::FileFlags type) const { + Q_D(const QFSFileEngine); + + if (type & Refresh) + d->metaData.clear(); + QAbstractFileEngine::FileFlags ret = 0; -#if !defined(QT_NO_LIBRARY) - if((qt_ntfs_permission_lookup > 0) && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)) { - resolveLibs(); - if(ptrGetNamedSecurityInfoW && ptrBuildTrusteeWithSidW && ptrGetEffectiveRightsFromAclW) { - enum { ReadMask = 0x00000001, WriteMask = 0x00000002, ExecMask = 0x00000020 }; - - QString fname = fileEntry.filePath().endsWith(QLatin1String(".lnk")) ? readLink(fileEntry) : fileEntry.filePath(); - PSID pOwner = 0; - PSID pGroup = 0; - PACL pDacl; - PSECURITY_DESCRIPTOR pSD; - DWORD res = ptrGetNamedSecurityInfoW((wchar_t*)fname.utf16(), SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - &pOwner, &pGroup, &pDacl, 0, &pSD); - if(res == ERROR_SUCCESS) { - ACCESS_MASK access_mask; - TRUSTEE_W trustee; - if (type & 0x0700) { // user - if(ptrGetEffectiveRightsFromAclW(pDacl, ¤tUserTrusteeW, &access_mask) != ERROR_SUCCESS) - access_mask = (ACCESS_MASK)-1; - if(access_mask & ReadMask) - ret |= QAbstractFileEngine::ReadUserPerm; - if(access_mask & WriteMask) - ret |= QAbstractFileEngine::WriteUserPerm; - if(access_mask & ExecMask) - ret |= QAbstractFileEngine::ExeUserPerm; - } - if (type & 0x7000) { // owner - ptrBuildTrusteeWithSidW(&trustee, pOwner); - if(ptrGetEffectiveRightsFromAclW(pDacl, &trustee, &access_mask) != ERROR_SUCCESS) - access_mask = (ACCESS_MASK)-1; - if(access_mask & ReadMask) - ret |= QAbstractFileEngine::ReadOwnerPerm; - if(access_mask & WriteMask) - ret |= QAbstractFileEngine::WriteOwnerPerm; - if(access_mask & ExecMask) - ret |= QAbstractFileEngine::ExeOwnerPerm; - } - if (type & 0x0070) { // group - ptrBuildTrusteeWithSidW(&trustee, pGroup); - if(ptrGetEffectiveRightsFromAclW(pDacl, &trustee, &access_mask) != ERROR_SUCCESS) - access_mask = (ACCESS_MASK)-1; - if(access_mask & ReadMask) - ret |= QAbstractFileEngine::ReadGroupPerm; - if(access_mask & WriteMask) - ret |= QAbstractFileEngine::WriteGroupPerm; - if(access_mask & ExecMask) - ret |= QAbstractFileEngine::ExeGroupPerm; - } - if (type & 0x0007) { // other (world) - if(ptrGetEffectiveRightsFromAclW(pDacl, &worldTrusteeW, &access_mask) != ERROR_SUCCESS) - access_mask = (ACCESS_MASK)-1; // ### - if(access_mask & ReadMask) - ret |= QAbstractFileEngine::ReadOtherPerm; - if(access_mask & WriteMask) - ret |= QAbstractFileEngine::WriteOtherPerm; - if(access_mask & ExecMask) - ret |= QAbstractFileEngine::ExeOtherPerm; - } - LocalFree(pSD); - } - } - } else -#endif + if (type & FlagsMask) + ret |= LocalDiskFlag; + + bool exists; { - //### what to do with permissions if we don't use NTFS - // for now just add all permissions and what about exe missions ?? - // also qt_ntfs_permission_lookup is now not set by default ... should it ? - ret |= QAbstractFileEngine::ReadOwnerPerm | QAbstractFileEngine::ReadGroupPerm - | QAbstractFileEngine::ReadOtherPerm; - - if (!(fileAttrib & FILE_ATTRIBUTE_READONLY)) { - ret |= QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteGroupPerm - | QAbstractFileEngine::WriteOtherPerm; - } + QFileSystemMetaData::MetaDataFlags queryFlags = 0; - QString fname = fileEntry.filePath().endsWith(QLatin1String(".lnk")) ? readLink(fileEntry) : fileEntry.filePath(); - QString ext = fname.right(4).toLower(); - if ((fileAttrib & FILE_ATTRIBUTE_DIRECTORY) || - ext == QLatin1String(".exe") || ext == QLatin1String(".com") || ext == QLatin1String(".bat") || - ext == QLatin1String(".pif") || ext == QLatin1String(".cmd")) { - ret |= QAbstractFileEngine::ExeOwnerPerm | QAbstractFileEngine::ExeGroupPerm - | QAbstractFileEngine::ExeOtherPerm | QAbstractFileEngine::ExeUserPerm; - } + queryFlags |= QFileSystemMetaData::MetaDataFlags(uint(type)) + & QFileSystemMetaData::Permissions; - // calculate user permissions - if (type & QAbstractFileEngine::ReadUserPerm) { - if (::_waccess((wchar_t*)longFileName(fname).utf16(), R_OK) == 0) - ret |= QAbstractFileEngine::ReadUserPerm; - } - if (type & QAbstractFileEngine::WriteUserPerm) { - if (::_waccess((wchar_t*)longFileName(fname).utf16(), W_OK) == 0) - ret |= QAbstractFileEngine::WriteUserPerm; - } - } - return ret; -} + // AliasType and BundleType are 0x0 + if (type & TypesMask) + queryFlags |= QFileSystemMetaData::AliasType + | QFileSystemMetaData::LinkType + | QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::BundleType; -/*! - \internal -*/ -bool QFSFileEnginePrivate::isSymlink() const -{ -#if !defined(Q_OS_WINCE) - if (need_lstat) { - need_lstat = false; - is_link = false; - - if (fileAttrib & FILE_ATTRIBUTE_REPARSE_POINT) { - WIN32_FIND_DATA findData; - if (getFindData(fileEntry.nativeFilePath(), findData)) { - if ((findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) - && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK || findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) { - is_link = true; - } - } - } - } - return is_link; -#else - return false; -#endif // Q_OS_WINCE -} + if (type & FlagsMask) + queryFlags |= QFileSystemMetaData::HiddenAttribute + | QFileSystemMetaData::ExistsAttribute; -/*! - \reimp -*/ -QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::FileFlags type) const -{ - Q_D(const QFSFileEngine); - QAbstractFileEngine::FileFlags ret = 0; - // Force a stat, so that we're guaranteed to get up-to-date results - if (type & Refresh) { - d->tried_stat = 0; -#if !defined(Q_OS_WINCE) - d->need_lstat = 1; -#endif - } + queryFlags |= QFileSystemMetaData::LinkType; - if (type & PermsMask) { - if (d->doStat()) { - ret |= ExistsFlag; - ret |= d->getPermissions(type); - } + exists = d->doStat(queryFlags); } + + if (exists && (type & PermsMask)) + ret |= FileFlags(uint(d->metaData.permissions())); + if (type & TypesMask) { - if (d->fileEntry.filePath().endsWith(QLatin1String(".lnk"))) { + if ((type & LinkType) && d->metaData.isLegacyLink()) ret |= LinkType; - QString l = readLink(d->fileEntry); - if (!l.isEmpty()) { - bool existed = false; - if (isDirPath(l, &existed) && existed) - ret |= DirectoryType; - else if (existed) - ret |= FileType; - } - } else if (d->doStat()) { - if ((type & LinkType) && d->isSymlink()) - ret |= LinkType; - if (d->fileAttrib & FILE_ATTRIBUTE_DIRECTORY) { - ret |= DirectoryType; - } else { - ret |= FileType; - } + if (d->metaData.isDirectory()) { + ret |= DirectoryType; + } else { + ret |= FileType; } } if (type & FlagsMask) { - ret |= LocalDiskFlag; - if (d->doStat()) { + if (d->metaData.exists()) { ret |= ExistsFlag; if (d->fileEntry.isRoot()) ret |= RootFlag; - else if (d->fileAttrib & FILE_ATTRIBUTE_HIDDEN) + else if (d->metaData.isHidden()) ret |= HiddenFlag; } } @@ -1585,7 +822,7 @@ QString QFSFileEngine::fileName(FileName file) const d->fileEntry.filePath().contains(QLatin1String("/../")) || d->fileEntry.filePath().contains(QLatin1String("/./")) || d->fileEntry.filePath().endsWith(QLatin1String("/..")) || d->fileEntry.filePath().endsWith(QLatin1String("/."))) { - ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(d->fileEntry.filePath())); + ret = QDir::fromNativeSeparators(QFileSystemEngine::nativeAbsoluteFilePath(d->fileEntry.filePath())); } else #endif { @@ -1621,18 +858,13 @@ QString QFSFileEngine::fileName(FileName file) const } else if (file == CanonicalName || file == CanonicalPathName) { if (!(fileFlags(ExistsFlag) & ExistsFlag)) return QString(); - QFileSystemEntry entry(QFileSystemEngine::canonicalName(d->fileEntry)); + QFileSystemEntry entry(QFileSystemEngine::canonicalName(QFileSystemEntry(fileName(AbsoluteName)))); if (file == CanonicalPathName) return entry.path(); return entry.filePath(); } else if (file == LinkName) { - QString ret; - if (d->fileEntry.filePath().endsWith(QLatin1String(".lnk"))) - ret = readLink(d->fileEntry); - else if (d->doStat() && d->isSymlink()) - ret = readSymLink(d->fileEntry); - return QDir::fromNativeSeparators(ret); + QFileSystemEngine::getLinkTarget(d->fileEntry, d->metaData).filePath(); } else if (file == BundleName) { return QString(); } @@ -1654,67 +886,14 @@ uint QFSFileEngine::ownerId(FileOwner /*own*/) const QString QFSFileEngine::owner(FileOwner own) const { - QString name; -#if !defined(QT_NO_LIBRARY) Q_D(const QFSFileEngine); - if((qt_ntfs_permission_lookup > 0) && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)) { - QFSFileEnginePrivate::resolveLibs(); - if (ptrGetNamedSecurityInfoW && ptrLookupAccountSidW) { - PSID pOwner = 0; - PSECURITY_DESCRIPTOR pSD; - if (ptrGetNamedSecurityInfoW((wchar_t*)d->fileEntry.nativeFilePath().utf16(), SE_FILE_OBJECT, - own == OwnerGroup ? GROUP_SECURITY_INFORMATION : OWNER_SECURITY_INFORMATION, - own == OwnerUser ? &pOwner : 0, own == OwnerGroup ? &pOwner : 0, - 0, 0, &pSD) == ERROR_SUCCESS) { - DWORD lowner = 64; - DWORD ldomain = 64; - QVarLengthArray owner(lowner); - QVarLengthArray domain(ldomain); - SID_NAME_USE use = SidTypeUnknown; - // First call, to determine size of the strings (with '\0'). - if (!ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner.data(), &lowner, - (LPWSTR)domain.data(), &ldomain, (SID_NAME_USE*)&use)) { - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - if (lowner > (DWORD)owner.size()) - owner.resize(lowner); - if (ldomain > (DWORD)domain.size()) - domain.resize(ldomain); - // Second call, try on resized buf-s - if (!ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner.data(), &lowner, - (LPWSTR)domain.data(), &ldomain, (SID_NAME_USE*)&use)) { - lowner = 0; - } - } else { - lowner = 0; - } - } - if (lowner != 0) - name = QString::fromWCharArray(owner.data()); - LocalFree(pSD); - } - } - } -#else - Q_UNUSED(own); -#endif - return name; + return QFileSystemEngine::owner(d->fileEntry, own); } bool QFSFileEngine::setPermissions(uint perms) { Q_D(QFSFileEngine); - bool ret = false; - int mode = 0; - - if (perms & QFile::ReadOwner || perms & QFile::ReadUser || perms & QFile::ReadGroup || perms & QFile::ReadOther) - mode |= _S_IREAD; - if (perms & QFile::WriteOwner || perms & QFile::WriteUser || perms & QFile::WriteGroup || perms & QFile::WriteOther) - mode |= _S_IWRITE; - - if (mode == 0) // not supported - return false; - - ret = ::_wchmod((wchar_t*)d->fileEntry.nativeFilePath().utf16(), mode) == 0; + bool ret = QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms)); if (!ret) setError(QFile::PermissionsError, qt_error_string(errno)); return ret; @@ -1758,83 +937,14 @@ bool QFSFileEngine::setSize(qint64 size) } -static inline QDateTime fileTimeToQDateTime(const FILETIME *time) -{ - QDateTime ret; - -#if defined(Q_OS_WINCE) - SYSTEMTIME systime; - FILETIME ftime; - systime.wYear = 1970; - systime.wMonth = 1; - systime.wDay = 1; - systime.wHour = 0; - systime.wMinute = 0; - systime.wSecond = 0; - systime.wMilliseconds = 0; - systime.wDayOfWeek = 4; - SystemTimeToFileTime(&systime, &ftime); - unsigned __int64 acttime = (unsigned __int64)time->dwHighDateTime << 32 | time->dwLowDateTime; - FileTimeToSystemTime(time, &systime); - unsigned __int64 time1970 = (unsigned __int64)ftime.dwHighDateTime << 32 | ftime.dwLowDateTime; - unsigned __int64 difftime = acttime - time1970; - difftime /= 10000000; - ret.setTime_t((unsigned int)difftime); -#else - SYSTEMTIME sTime, lTime; - FileTimeToSystemTime(time, &sTime); - SystemTimeToTzSpecificLocalTime(0, &sTime, &lTime); - ret.setDate(QDate(lTime.wYear, lTime.wMonth, lTime.wDay)); - ret.setTime(QTime(lTime.wHour, lTime.wMinute, lTime.wSecond, lTime.wMilliseconds)); -#endif - - return ret; -} - QDateTime QFSFileEngine::fileTime(FileTime time) const { Q_D(const QFSFileEngine); - QDateTime ret; - if (d->fd != -1) { -#if !defined(Q_OS_WINCE) - HANDLE fh = (HANDLE)_get_osfhandle(d->fd); - if (fh != INVALID_HANDLE_VALUE) { - FILETIME creationTime, lastAccessTime, lastWriteTime; - if (GetFileTime(fh, &creationTime, &lastAccessTime, &lastWriteTime)) { - if(time == CreationTime) - ret = fileTimeToQDateTime(&creationTime); - else if(time == ModificationTime) - ret = fileTimeToQDateTime(&lastWriteTime); - else if(time == AccessTime) - ret = fileTimeToQDateTime(&lastAccessTime); - } - } -#endif - } else { - WIN32_FILE_ATTRIBUTE_DATA attribData; - bool ok = ::GetFileAttributesEx((wchar_t*)QFSFileEnginePrivate::longFileName(d->fileEntry.filePath()).utf16(), GetFileExInfoStandard, &attribData); - if (!ok) { - int errorCode = GetLastError(); - if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) { - WIN32_FIND_DATA findData; - if (getFindData(d->fileEntry.nativeFilePath(), findData)) { - ok = true; - attribData.ftCreationTime = findData.ftCreationTime; - attribData.ftLastWriteTime = findData.ftLastWriteTime; - attribData.ftLastAccessTime = findData.ftLastAccessTime; - } - } - } - if (ok) { - if(time == CreationTime) - ret = fileTimeToQDateTime(&attribData.ftCreationTime); - else if(time == ModificationTime) - ret = fileTimeToQDateTime(&attribData.ftLastWriteTime); - else if(time == AccessTime) - ret = fileTimeToQDateTime(&attribData.ftLastAccessTime); - } - } - return ret; + + if (d->doStat(QFileSystemMetaData::Times)) + return d->metaData.fileTime(time); + + return QDateTime(); } uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, -- cgit v0.12 From 15dbe69d9a174a85aed297b2e93d0d9fb79d12e8 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 14 Sep 2010 11:22:22 +0200 Subject: Fix the tst_QFileInfo::canonicalFilePath() on windows. This was trying to load a wrong Win32 function to test the symbolic links on windows. Some Win32 APIs have to be resolved against either a Wider Character version('W') or an ANSI version('A'), the function names without these character appended are usually '#define's in the header files. Reviewed-by: Zeno Albisser --- tests/auto/qfileinfo/tst_qfileinfo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index cced207..e4aa0d3 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -608,7 +608,7 @@ void tst_QFileInfo::canonicalFilePath() #ifdef Q_OS_WIN typedef BOOL (WINAPI *PtrCreateSymbolicLink)(LPTSTR, LPTSTR, DWORD); PtrCreateSymbolicLink ptrCreateSymbolicLink = - (PtrCreateSymbolicLink)QLibrary::resolve(QLatin1String("kernel32"), "CreateSymbolicLink"); + (PtrCreateSymbolicLink)QLibrary::resolve(QLatin1String("kernel32"), "CreateSymbolicLinkW"); if (!ptrCreateSymbolicLink || ptrCreateSymbolicLink((wchar_t*)QString("res").utf16(), (wchar_t*)QString("resources").utf16(), 1) == 0) { @@ -621,7 +621,7 @@ void tst_QFileInfo::canonicalFilePath() QCOMPARE(QFileInfo("file1").canonicalFilePath(), currentPath + "/resources/file1"); QCOMPARE(QDir::setCurrent(currentPath), true); - QFile::remove("res"); + QDir::current().rmdir("res"); #endif } -- cgit v0.12 From f2dbebdab183dfe5d18ab7a8fbd85983401dfa3c Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Tue, 14 Sep 2010 16:23:27 +0200 Subject: Make compile for symbian Reviewed-by: Shane Kearns --- src/corelib/io/qfilesystemengine_symbian.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index dc7fcbf..ca559da 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -141,7 +141,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) result.append(orig); } - return symbianCleanAbsolutePath(result); + return QFileSystemEntry(symbianCleanAbsolutePath(result)); } //static -- cgit v0.12 From 0299d30d5aa35d532df6bc018afc52df263651a0 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 14 Sep 2010 13:01:29 +0200 Subject: Test QDirIterator using UNC paths on Windows. Adding the test tst_QDirIterator::uncPaths(). Currently this traverses the shares & folders in test-server for all entries except '.' & '..' Reviewed-by: Denis --- tests/auto/qdiriterator/tst_qdiriterator.cpp | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/auto/qdiriterator/tst_qdiriterator.cpp b/tests/auto/qdiriterator/tst_qdiriterator.cpp index f78ce34..d93e91e 100644 --- a/tests/auto/qdiriterator/tst_qdiriterator.cpp +++ b/tests/auto/qdiriterator/tst_qdiriterator.cpp @@ -57,6 +57,10 @@ #define Q_NO_SYMLINKS_TO_DIRS #endif +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#include "../network-settings.h" +#endif + Q_DECLARE_METATYPE(QDirIterator::IteratorFlags) Q_DECLARE_METATYPE(QDir::Filters) @@ -118,6 +122,10 @@ private slots: void longPath(); void task185502_dirorder(); void relativePaths(); +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + void uncPaths_data(); + void uncPaths(); +#endif }; tst_QDirIterator::tst_QDirIterator() @@ -532,6 +540,28 @@ void tst_QDirIterator::relativePaths() } } +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +void tst_QDirIterator::uncPaths_data() +{ + QTest::addColumn("dirName"); + QTest::newRow("uncserver") + < Date: Mon, 13 Sep 2010 16:50:27 +0100 Subject: Pass QFileSystemMetaData reference into QFileSystemEngine::canonicalName On symbian, this allows us to use the cached ExistsAttribute On symbian and unix, this allows us to update the caller's knowledge of ExistsAttribute (potentially saving a stat later) Reviewed-By: joao --- src/corelib/io/qfileinfo.cpp | 2 +- src/corelib/io/qfilesystemengine_p.h | 2 +- src/corelib/io/qfilesystemengine_symbian.cpp | 7 ++++--- src/corelib/io/qfilesystemengine_unix.cpp | 6 +++++- src/corelib/io/qfilesystemengine_win.cpp | 2 +- src/corelib/io/qfsfileengine_unix.cpp | 2 +- src/corelib/io/qfsfileengine_win.cpp | 2 +- 7 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 83df26d..4f5a4ab 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -57,7 +57,7 @@ QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const switch (name) { case QAbstractFileEngine::CanonicalName: case QAbstractFileEngine::CanonicalPathName: { - QFileSystemEntry entry = QFileSystemEngine::canonicalName(fileEntry); + QFileSystemEntry entry = QFileSystemEngine::canonicalName(fileEntry, metaData); if (cache_enabled) { // be smart and store both fileNames[QAbstractFileEngine::CanonicalName] = entry.filePath(); fileNames[QAbstractFileEngine::CanonicalPathName] = entry.path(); diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 1068e76..b3bbd65 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -65,7 +65,7 @@ public: static bool isCaseSensitive(); static QFileSystemEntry getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data); - static QFileSystemEntry canonicalName(const QFileSystemEntry &entry); + static QFileSystemEntry canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data); static QFileSystemEntry absoluteName(const QFileSystemEntry &entry); static QString resolveUserName(const QFileSystemEntry &entry, QFileSystemMetaData &data); static QString resolveUserName(uint userId); diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index ca559da..9b81571 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -89,14 +89,15 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, } //static -QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) +QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data) { if (entry.isEmpty() || entry.isRoot()) return entry; QFileSystemEntry result = absoluteName(entry); - QFileSystemMetaData meta; - if (!fillMetaData(result, meta, QFileSystemMetaData::ExistsAttribute) || !meta.exists()) { + if (!data.hasFlags(QFileSystemMetaData::ExistsAttribute)) + fillMetaData(result, data, QFileSystemMetaData::ExistsAttribute); + if (!data.exists()) { // file doesn't exist return QFileSystemEntry(); } else { diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index fdb881f..6d8b3ff 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -193,7 +193,7 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, } //static -QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) +QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, , QFileSystemMetaData &data) { if (entry.isEmpty() || entry.isRoot()) return entry; @@ -223,10 +223,14 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) ret = realpath(entry.nativeFilePath().constData(), (char*)0); # endif if (ret) { + data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute; + data.entryFlags |= QFileSystemMetaData::ExistsAttribute; QString canonicalPath = QDir::cleanPath(QString::fromLocal8Bit(ret)); free(ret); return QFileSystemEntry(canonicalPath); } else if (errno == ENOENT) { // file doesn't exist + data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute; + data.entryFlags &= ~(QFileSystemMetaData::ExistsAttribute); return QFileSystemEntry(); } return entry; diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 550b522..2e9f94b 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -493,7 +493,7 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, } //static -QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry) +QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data) { // The caller has to verify whether the file exists or not. return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath())); diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index a6cf7fc..418506c 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -923,7 +923,7 @@ QString QFSFileEngine::fileName(FileName file) const } return entry.filePath(); } else if (file == CanonicalName || file == CanonicalPathName) { - QFileSystemEntry entry(QFileSystemEngine::canonicalName(d->fileEntry)); + QFileSystemEntry entry(QFileSystemEngine::canonicalName(d->fileEntry, d->metaData)); if (file == CanonicalPathName) return entry.path(); return entry.filePath(); diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 976207a..2bf377a 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -858,7 +858,7 @@ QString QFSFileEngine::fileName(FileName file) const } else if (file == CanonicalName || file == CanonicalPathName) { if (!(fileFlags(ExistsFlag) & ExistsFlag)) return QString(); - QFileSystemEntry entry(QFileSystemEngine::canonicalName(QFileSystemEntry(fileName(AbsoluteName)))); + QFileSystemEntry entry(QFileSystemEngine::canonicalName(QFileSystemEntry(fileName(AbsoluteName)), d->metaData)); if (file == CanonicalPathName) return entry.path(); -- cgit v0.12 From 3f5d522e7abe15abc97ef1aa27a33311d74f8312 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 13 Sep 2010 19:35:46 +0100 Subject: Fix for QFile::remove autotest After removing a file, invalidate the cached metadata to force any calls that require metadata to fetch it from the file system. Reviewed-By: joao --- src/corelib/io/qfsfileengine_unix.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 418506c..1d1baf9 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -589,6 +589,7 @@ bool QFSFileEngine::remove() { Q_D(QFSFileEngine); bool ret = QFileSystemEngine::removeFile(d->fileEntry); + d->metaData.clear(); if (!ret) { #ifdef Q_OS_SYMBIAN //TODO: error reporting -- cgit v0.12 From 108eb5b7d21e24e48f214ea8f171fa97c0087167 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 13 Sep 2010 19:39:20 +0100 Subject: Fixed QFile::setSize on symbian Reviewed-By: joao --- src/corelib/io/qfsfileengine_unix.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 1d1baf9..2e9d10c 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -520,9 +520,9 @@ qint64 QFSFileEnginePrivate::nativePos() const #ifdef Q_OS_SYMBIAN if (symbianFile.SubSessionHandle()) { #ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API - qint64 pos; + qint64 pos = 0; #else - TInt pos; + TInt pos = 0; #endif TInt err = symbianFile.Seek(ESeekCurrent, pos); if(err != KErrNone) { @@ -1028,7 +1028,7 @@ bool QFSFileEngine::setSize(qint64 size) TInt err = d->symbianFile.SetSize(size); ret = (err == KErrNone); } - if (d->fd != -1) + else if (d->fd != -1) ret = QT_FTRUNCATE(d->fd, size) == 0; else if (d->fh) ret = QT_FTRUNCATE(QT_FILENO(d->fh), size) == 0; -- cgit v0.12 From 3289a268d58181b22f7fe90669a7215bc2edc75a Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 14 Sep 2010 18:01:50 +0100 Subject: Don't compute canonical paths when not needed This optimisation saves 20% on symbian recursive iteration, and should help on other OS when the FollowSymlinks flag is not specified for directory iteration. Reviewed-By: joao --- src/corelib/io/qdiriterator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 2e67bfd..582fb85 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -299,7 +299,8 @@ void QDirIteratorPrivate::checkAndPushDirectory(const QFileInfo &fileInfo) return; // Stop link loops - if (visitedLinks.contains(fileInfo.canonicalFilePath())) + if (!visitedLinks.isEmpty() && + visitedLinks.contains(fileInfo.canonicalFilePath())) return; pushDirectory(fileInfo); -- cgit v0.12 From ff5946f056c52d7851106ef9ba93e40129349d8d Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 15 Sep 2010 11:42:51 +0100 Subject: Disable symlink and memory mapped files tests on symbian Reviewed-By: joao --- tests/auto/qdir/tst_qdir.cpp | 4 +++- tests/auto/qfile/tst_qfile.cpp | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 9678868..0ea67c9 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -69,7 +69,7 @@ #endif #if defined(Q_OS_SYMBIAN) -// Open C in Symbian doesn't support symbolic links to directories +#define Q_NO_SYMLINKS #define Q_NO_SYMLINKS_TO_DIRS #endif @@ -597,6 +597,7 @@ void tst_QDir::entryList() expected.removeAll(".."); #endif +#ifndef Q_NO_SYMLINKS #if defined(Q_OS_WIN) // ### Sadly, this is a platform difference right now. QFile::link(SRCDIR "entryList/file", SRCDIR "entrylist/linktofile.lnk"); @@ -651,6 +652,7 @@ void tst_QDir::entryList() QFile::link("directory", SRCDIR "entrylist/linktodirectory.lnk"); QFile::link("nothing", SRCDIR "entrylist/brokenlink.lnk"); #endif +#endif //Q_NO_SYMLINKS #ifdef Q_WS_MAC if (qstrcmp(QTest::currentDataTag(), "unprintablenames") == 0) diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index ee799f3..925bdec 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -1285,6 +1285,9 @@ static QString getWorkingDirectoryForLink(const QString &linkFileName) void tst_QFile::link() { +#if defined(Q_OS_SYMBIAN) + QSKIP("Symbian does not support links", SkipAll); +#endif QFile::remove("myLink.lnk"); QFileInfo info1("tst_qfile.cpp"); QVERIFY(QFile::link("tst_qfile.cpp", "myLink.lnk")); @@ -1324,6 +1327,9 @@ void tst_QFile::linkToDir() void tst_QFile::absolutePathLinkToRelativePath() { +#if defined(Q_OS_SYMBIAN) + QSKIP("Symbian does not support links", SkipAll); +#endif QFile::remove("myDir/test.txt"); QFile::remove("myDir/myLink.lnk"); QDir dir; @@ -1346,6 +1352,9 @@ void tst_QFile::absolutePathLinkToRelativePath() void tst_QFile::readBrokenLink() { +#if defined(Q_OS_SYMBIAN) + QSKIP("Symbian does not support links", SkipAll); +#endif QFile::remove("myLink2.lnk"); QFileInfo info1("file12"); #if defined(Q_OS_SYMBIAN) @@ -2753,6 +2762,10 @@ void tst_QFile::map() QFETCH(int, size); QFETCH(QFile::FileError, error); +#ifdef Q_OS_SYMBIAN + QSKIP("memory mapped files not supported on this platform", SkipAll); +#endif + QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile"; #ifdef Q_WS_WINCE @@ -2874,6 +2887,10 @@ void tst_QFile::mapResource() QFETCH(int, size); QFETCH(QFile::FileError, error); +#ifdef Q_OS_SYMBIAN + QSKIP("memory mapped files not supported on this platform", SkipAll); +#endif + QFile file(fileName); uchar *memory = file.map(offset, size); QCOMPARE(file.error(), error); @@ -2898,6 +2915,11 @@ void tst_QFile::mapOpenMode() { QFETCH(int, openMode); static const qint64 fileSize = 4096; + +#ifdef Q_OS_SYMBIAN + QSKIP("memory mapped files not supported on this platform", SkipAll); +#endif + QByteArray pattern(fileSize, 'A'); QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile"; -- cgit v0.12 From 55648bc7a197367e8bacb2334339025ffbb83647 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 15 Sep 2010 11:46:10 +0100 Subject: tst_qdir fixes 1. change the test case names in relativeFilePath_data so they are all unique. 2. enable the canonical path tests related to rootPath on all OS, which were previously added only for symbian/windows. Reviewed-By: joao --- tests/auto/qdir/tst_qdir.cpp | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 0ea67c9..554b685 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -815,11 +815,11 @@ void tst_QDir::canonicalPath_data() #endif QTest::newRow("nonexistant") << "testd" << QString(); + QTest::newRow("rootPath") << QDir::rootPath() << QDir::rootPath(); + QTest::newRow("rootPath + ./") << QDir::rootPath().append("./") << QDir::rootPath(); + QTest::newRow("rootPath + ../.. ") << QDir::rootPath().append("../..") << QDir::rootPath(); #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) - QTest::newRow("drive:/") << QDir::rootPath() << QDir::rootPath(); QTest::newRow("drive:\\") << QDir::toNativeSeparators(QDir::rootPath()) << QDir::rootPath(); - QTest::newRow("drive:/./") << QDir::rootPath().append("./") << QDir::rootPath(); - QTest::newRow("drive:/../.. ") << QDir::rootPath().append("../..") << QDir::rootPath(); QTest::newRow("drive:\\.\\") << QDir::toNativeSeparators(QDir::rootPath().append("./")) << QDir::rootPath(); QTest::newRow("drive:\\..\\..") << QDir::toNativeSeparators(QDir::rootPath().append("../..")) << QDir::rootPath(); QTest::newRow("drive:") << QDir().canonicalPath().left(2) << QDir().canonicalPath(); @@ -1106,24 +1106,24 @@ void tst_QDir::relativeFilePath_data() QTest::newRow("14") << "C:/foo/bar" << "/ding/dong" << "../../ding/dong"; QTest::newRow("15") << "C:/foo/bar" << "D:/ding/dong" << "D:/ding/dong"; QTest::newRow("16") << "C:" << "C:/ding/dong" << "ding/dong"; - QTest::newRow("16") << "C:/" << "C:/ding/dong" << "ding/dong"; - QTest::newRow("17") << "C:" << "C:" << ""; - QTest::newRow("18") << "C:/" << "C:" << ""; - QTest::newRow("19") << "C:" << "C:/" << ""; - QTest::newRow("20") << "C:/" << "C:/" << ""; - QTest::newRow("17") << "C:" << "C:file.txt" << "file.txt"; - QTest::newRow("18") << "C:/" << "C:file.txt" << "file.txt"; - QTest::newRow("19") << "C:" << "C:/file.txt" << "file.txt"; - QTest::newRow("20") << "C:/" << "C:/file.txt" << "file.txt"; - QTest::newRow("21") << "C:" << "D:" << "D:"; - QTest::newRow("22") << "C:" << "D:/" << "D:/"; - QTest::newRow("23") << "C:/" << "D:" << "D:"; - QTest::newRow("24") << "C:/" << "D:/" << "D:/"; + QTest::newRow("17") << "C:/" << "C:/ding/dong" << "ding/dong"; + QTest::newRow("18") << "C:" << "C:" << ""; + QTest::newRow("19") << "C:/" << "C:" << ""; + QTest::newRow("20") << "C:" << "C:/" << ""; + QTest::newRow("21") << "C:/" << "C:/" << ""; + QTest::newRow("22") << "C:" << "C:file.txt" << "file.txt"; + QTest::newRow("23") << "C:/" << "C:file.txt" << "file.txt"; + QTest::newRow("24") << "C:" << "C:/file.txt" << "file.txt"; + QTest::newRow("25") << "C:/" << "C:/file.txt" << "file.txt"; + QTest::newRow("26") << "C:" << "D:" << "D:"; + QTest::newRow("27") << "C:" << "D:/" << "D:/"; + QTest::newRow("28") << "C:/" << "D:" << "D:"; + QTest::newRow("29") << "C:/" << "D:/" << "D:/"; # if !defined(Q_OS_SYMBIAN) - QTest::newRow("25") << "C:/foo/bar" << "//anotherHost/foo/bar" << "//anotherHost/foo/bar"; - QTest::newRow("26") << "//anotherHost/foo" << "//anotherHost/foo/bar" << "bar"; - QTest::newRow("27") << "//anotherHost/foo" << "bar" << "bar"; - QTest::newRow("28") << "//anotherHost/foo" << "C:/foo/bar" << "C:/foo/bar"; + QTest::newRow("30") << "C:/foo/bar" << "//anotherHost/foo/bar" << "//anotherHost/foo/bar"; + QTest::newRow("31") << "//anotherHost/foo" << "//anotherHost/foo/bar" << "bar"; + QTest::newRow("32") << "//anotherHost/foo" << "bar" << "bar"; + QTest::newRow("33") << "//anotherHost/foo" << "C:/foo/bar" << "C:/foo/bar"; # endif #endif } -- cgit v0.12 From 864c19e036017c32db9bf55edb38b992d2a5f962 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 15 Sep 2010 11:54:36 +0100 Subject: Change handle related tests in tst_qfile for symbian Getting a posix file handle from a natively opened QFile isn't supported so that part of the test is skipped. Reviewed-By: joao --- tests/auto/qfile/tst_qfile.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 925bdec..2524e6e 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -2503,10 +2503,11 @@ void tst_QFile::standarderror() void tst_QFile::handle() { -#ifndef Q_OS_WINCE + int fd; +#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) QFile file(SRCDIR "tst_qfile.cpp"); QVERIFY(file.open(QIODevice::ReadOnly)); - int fd = int(file.handle()); + fd = int(file.handle()); QVERIFY(fd > 2); QCOMPARE(int(file.handle()), fd); char c = '\0'; @@ -2533,6 +2534,7 @@ void tst_QFile::handle() QCOMPARE(c, '*'); #endif + //test round trip of adopted stdio file handle QFile file2; FILE *fp = fopen(SRCDIR "tst_qfile.cpp", "r"); file2.open(fp, QIODevice::ReadOnly); @@ -2540,6 +2542,7 @@ void tst_QFile::handle() QCOMPARE(int(file2.handle()), int(fileno(fp))); fclose(fp); + //test round trip of adopted posix file handle #ifdef Q_OS_UNIX QFile file3; fd = QT_OPEN(SRCDIR "tst_qfile.cpp", QT_OPEN_RDONLY); @@ -2551,6 +2554,9 @@ void tst_QFile::handle() void tst_QFile::nativeHandleLeaks() { +#ifdef Q_OS_SYMBIAN + QSKIP("test assumptions invalid for symbian", SkipAll); +#else int fd1, fd2; #ifdef Q_OS_WIN @@ -2592,6 +2598,7 @@ void tst_QFile::nativeHandleLeaks() #ifdef Q_OS_WIN QCOMPARE( handle2, handle1 ); #endif +#endif } void tst_QFile::readEof_data() -- cgit v0.12 From 925194abd863057618f39dd1289e574dc2a34208 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 15 Sep 2010 13:38:12 +0200 Subject: Wrong size for directories on windows. We have to ignore the size returned by GetFileAttributeEx() for directories. Also dont use the size_ to check for error when stating for file size. Reviewed-by: Joao --- src/corelib/io/qfilesystemengine_win.cpp | 22 +++++++++++++++------- src/corelib/io/qfsfileengine_win.cpp | 3 +-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 2e9f94b..8526cf2 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -438,9 +438,13 @@ void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, bool setLi creationTime_ = findData.ftCreationTime; lastAccessTime_ = findData.ftLastAccessTime; lastWriteTime_ = findData.ftLastWriteTime; - size_ = findData.nFileSizeHigh; - size_ <<= 32; - size_ += findData.nFileSizeLow; + if (fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY) { + size_ = 0; + } else { + size_ = findData.nFileSizeHigh; + size_ <<= 32; + size_ += findData.nFileSizeLow; + } knownFlagsMask |= Times | SizeAttribute; if (setLinkType) { knownFlagsMask |= LinkType; @@ -460,15 +464,19 @@ void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo) creationTime_ = fileInfo.ftCreationTime; lastAccessTime_ = fileInfo.ftLastAccessTime; lastWriteTime_ = fileInfo.ftLastWriteTime; - size_ = fileInfo.nFileSizeHigh; - size_ <<= 32; - size_ += fileInfo.nFileSizeLow; + if (fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY) { + size_ = 0; + } else { + size_ = fileInfo.nFileSizeHigh; + size_ <<= 32; + size_ += fileInfo.nFileSizeLow; + } knownFlagsMask |= Times | SizeAttribute; } void QFileSystemEngine::clearWinStatData(QFileSystemMetaData &data) { - data.size_ = -1; + data.size_ = 0; data.fileAttribute_ = 0; } diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 2bf377a..dde499a 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -266,9 +266,8 @@ qint64 QFSFileEnginePrivate::nativeSize() const else filled = doStat(QFileSystemMetaData::SizeAttribute); - if (!filled || metaData.size() == -1) { + if (!filled) { thatQ->setError(QFile::UnspecifiedError, qt_error_string(errno)); - return 0; } return metaData.size(); } -- cgit v0.12 From fd4463c07f577d9df212388062028f9119e19add Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 15 Sep 2010 14:59:38 +0200 Subject: Fix tst_QFileSystemEntry::getSetCheck() on windows. Updated the name of the data field. Reviewed-by: Joao --- tests/auto/qfilesystementry/tst_qfilesystementry.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp index e00a214..49afab6 100644 --- a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp +++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp @@ -123,7 +123,7 @@ void tst_QFileSystemEntry::getSetCheck() QFETCH(QString, internalnativeFilePath); QFETCH(QString, filepath); QFETCH(QString, filename); - QFETCH(QString, basename); + QFETCH(QString, baseName); QFETCH(QString, completeBasename); QFETCH(QString, suffix); QFETCH(QString, completeSuffix); @@ -137,7 +137,7 @@ void tst_QFileSystemEntry::getSetCheck() QCOMPARE(entry1.completeSuffix(), completeSuffix); QCOMPARE(entry1.isAbsolute(), absolute); QCOMPARE(entry1.isRelative(), !absolute); - QCOMPARE(entry1.baseName(), basename); + QCOMPARE(entry1.baseName(), baseName); QCOMPARE(entry1.completeBaseName(), completeBasename); QFileSystemEntry entry2(nativeFilePath, QFileSystemEntry::FromNativePath()); @@ -150,7 +150,7 @@ void tst_QFileSystemEntry::getSetCheck() // the object shouldnot change nativeFilePath. QCOMPARE(entry2.nativeFilePath(), nativeFilePath); QCOMPARE(entry2.fileName(), filename); - QCOMPARE(entry2.baseName(), basename); + QCOMPARE(entry2.baseName(), baseName); QCOMPARE(entry2.completeBaseName(), completeBasename); } -- cgit v0.12 From 6bc165d0fbbc4704d87e59cc0795dc2769228dc3 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 15 Sep 2010 17:10:21 +0200 Subject: Implement QFileSystemIterator for windows. The search is implemented using FindFirstFileEx(). Following optimizations are done * Using large Fetch buffer on Windows 7 * Querying only the long file name * Querying for directories only, depending on QDir::Filters Reviewed-by: Joao --- qmake/Makefile.win32 | 5 - qmake/Makefile.win32-g++ | 4 - qmake/Makefile.win32-g++-sh | 4 - qmake/qmake.pri | 2 +- src/corelib/io/io.pri | 1 - src/corelib/io/qfilesystemiterator_p.h | 6 + src/corelib/io/qfilesystemiterator_win.cpp | 84 ++++++++++++- src/corelib/io/qfsfileengine_iterator.cpp | 20 ---- src/corelib/io/qfsfileengine_iterator_p.h | 10 -- src/corelib/io/qfsfileengine_iterator_win.cpp | 162 -------------------------- src/tools/bootstrap/bootstrap.pro | 1 - tools/configure/configure.pro | 1 - tools/qtestlib/wince/cetest/bootstrapped.pri | 1 - 13 files changed, 87 insertions(+), 214 deletions(-) delete mode 100644 src/corelib/io/qfsfileengine_iterator_win.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index fa17b9d..906d284 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -104,7 +104,6 @@ QTOBJS= \ qtemporaryfile.obj \ qabstractfileengine.obj \ qfsfileengine_win.obj \ - qfsfileengine_iterator_win.obj \ qfileinfo.obj \ qglobal.obj \ qhash.obj \ @@ -161,7 +160,6 @@ clean:: -del qtemporaryfile.obj -del qabstractfileengine.obj -del qfsfileengine_win.obj - -del qfsfileengine_iterator_win.obj -del qfileinfo.obj -del qglobal.obj -del qhash.obj @@ -333,9 +331,6 @@ qfilesystemiterator_win.obj: $(SOURCE_PATH)\src\corelib\io\qfilesystemiterator_w qfsfileengine_win.obj: $(SOURCE_PATH)\src\corelib\io\qfsfileengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfsfileengine_win.cpp -qfsfileengine_iterator_win.obj: $(SOURCE_PATH)\src\corelib\io\qfsfileengine_iterator_win.cpp - $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfsfileengine_iterator_win.cpp - qfsfileengine.obj: $(SOURCE_PATH)\src\corelib\io\qfsfileengine.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)\src\corelib\io\qfsfileengine.cpp diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index 57ea3d5..2bab255 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -68,7 +68,6 @@ QTOBJS= \ qfsfileengine.o \ qfsfileengine_iterator.o \ qfsfileengine_win.o \ - qfsfileengine_iterator_win.o \ qglobal.o \ qhash.o \ qiodevice.o \ @@ -211,9 +210,6 @@ qfilesystemiterator_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_win qfsfileengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp -qfsfileengine_iterator_win.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator_win.cpp - $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator_win.cpp - qfsfileengine.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index 33deb01..db78933 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -67,7 +67,6 @@ QTOBJS= \ qfsfileengine.o \ qfsfileengine_iterator.o \ qfsfileengine_win.o \ - qfsfileengine_iterator_win.o \ qglobal.o \ qhash.o \ qiodevice.o \ @@ -206,9 +205,6 @@ qfilesystemiterator_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_win qfsfileengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp -qfsfileengine_iterator_win.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator_win.cpp - $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator_win.cpp - qfsfileengine.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp diff --git a/qmake/qmake.pri b/qmake/qmake.pri index cd81c82..1d35183 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -135,7 +135,7 @@ bootstrap { #Qt code LIBS += -framework ApplicationServices } } else:win32 { - SOURCES += qfilesystemengine_win.cpp qfsfileengine_win.cpp qfilesystemiterator_win.cpp qfsfileengine_iterator_win.cpp qsettings_win.cpp + SOURCES += qfilesystemengine_win.cpp qfsfileengine_win.cpp qfilesystemiterator_win.cpp qsettings_win.cpp win32-msvc*:LIBS += ole32.lib advapi32.lib win32-g++*:LIBS += -lole32 -luuid } diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 4a2f042..9d209ea 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -65,7 +65,6 @@ win32 { SOURCES += io/qprocess_win.cpp SOURCES += io/qfsfileengine_win.cpp - SOURCES += io/qfsfileengine_iterator_win.cpp SOURCES += io/qfilesystemwatcher_win.cpp HEADERS += io/qfilesystemwatcher_win_p.h HEADERS += io/qwindowspipewriter_p.h diff --git a/src/corelib/io/qfilesystemiterator_p.h b/src/corelib/io/qfilesystemiterator_p.h index d3b195d..66f4b1e 100644 --- a/src/corelib/io/qfilesystemiterator_p.h +++ b/src/corelib/io/qfilesystemiterator_p.h @@ -86,6 +86,12 @@ private: // Platform-specific data #if defined(Q_OS_WIN) + QFileSystemEntry::NativePath dirPath; + HANDLE findFileHandle; + QStringList uncShares; + bool uncFallback; + int uncShareIndex; + bool onlyDirs; #elif defined (Q_OS_SYMBIAN) RDir dirHandle; TEntryArray entries; diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 3c73496..373a50a 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -40,26 +40,102 @@ ****************************************************************************/ #include "qfilesystemiterator_p.h" +#include "qfilesystemengine_p.h" +#include "qplatformdefs.h" QT_BEGIN_NAMESPACE +bool done = true; + QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, const QStringList &nameFilters, QDirIterator::IteratorFlags flags) + : nativePath(entry.nativeFilePath()) + , dirPath(entry.filePath()) + , findFileHandle(INVALID_HANDLE_VALUE) + , uncFallback(false) + , uncShareIndex(0) + , onlyDirs(false) { - Q_UNUSED(entry) - Q_UNUSED(filters) Q_UNUSED(nameFilters) Q_UNUSED(flags) + if (nativePath.endsWith(QLatin1String(".lnk"))) { + QFileSystemMetaData metaData; + QFileSystemEntry link = QFileSystemEngine::getLinkTarget(entry, metaData); + nativePath = link.nativeFilePath(); + } + if (!nativePath.endsWith(QLatin1Char('\\'))) + nativePath.append(QLatin1Char('\\')); + nativePath.append(QLatin1Char('*')); + if (!dirPath.endsWith(QLatin1Char('//'))) + dirPath.append(QLatin1Char('//')); + if ((filters & (QDir::Dirs|QDir::Drives)) && (!(filters & (QDir::Files)))) + onlyDirs = true; } QFileSystemIterator::~QFileSystemIterator() { + if (findFileHandle != INVALID_HANDLE_VALUE) + FindClose(findFileHandle); } bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData) { - Q_UNUSED(fileEntry) - Q_UNUSED(metaData) + bool haveData = false; + WIN32_FIND_DATA findData; + + if (findFileHandle == INVALID_HANDLE_VALUE && !uncFallback) { + haveData = true; + DWORD dwAdditionalFlags = 0; + if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) + dwAdditionalFlags = 2; // FIND_FIRST_EX_LARGE_FETCH + int searchOps = 0; // FindExSearchNameMatch + if (onlyDirs) + searchOps = 1 ; // FindExSearchLimitToDirectories +#if !defined(Q_OS_WINCE) + int infoLevel = 1 ; // FindExInfoBasic; +#else + int infoLevel = 0; // FindExInfoStandard; +#endif + findFileHandle = FindFirstFileEx((const wchar_t *)nativePath.utf16(), FINDEX_INFO_LEVELS(infoLevel), &findData, + FINDEX_SEARCH_OPS(searchOps), 0, dwAdditionalFlags); + if (findFileHandle == INVALID_HANDLE_VALUE) { + if (nativePath.startsWith(QLatin1String("\\\\?\\UNC\\"))) { + QStringList parts = nativePath.split(QLatin1Char('\\'), QString::SkipEmptyParts); + if (parts.count() == 4 && QFileSystemEngine::uncListSharesOnServer( + QLatin1String("\\\\") + parts.at(2), &uncShares)) { + if (uncShares.isEmpty()) + return false; // No shares found in the server + else + uncFallback = true; + } + } + } + } + if (findFileHandle == INVALID_HANDLE_VALUE && !uncFallback) + return false; + // Retrieve the new file information. + if (!haveData) { + if (uncFallback) { + if (++uncShareIndex >= uncShares.count()) + return false; + } else { + if (!FindNextFile(findFileHandle, &findData)) + return false; + } + } + // Create the new file system entry & meta data. + if (uncFallback) { + fileEntry = QFileSystemEntry(dirPath + uncShares.at(uncShareIndex)); + metaData.fillFromFileAttribute(FILE_ATTRIBUTE_DIRECTORY); + return true; + } else { + QString fileName = QString::fromWCharArray(findData.cFileName); + fileEntry = QFileSystemEntry(dirPath + fileName); + if (!fileName.endsWith(QLatin1String(".lnk"))) { + metaData.fillFromFindData(findData, true); + } + return true; + } return false; } diff --git a/src/corelib/io/qfsfileengine_iterator.cpp b/src/corelib/io/qfsfileengine_iterator.cpp index 4617f49..f6f08c7 100644 --- a/src/corelib/io/qfsfileengine_iterator.cpp +++ b/src/corelib/io/qfsfileengine_iterator.cpp @@ -49,23 +49,14 @@ QT_BEGIN_NAMESPACE QFSFileEngineIterator::QFSFileEngineIterator(QDir::Filters filters, const QStringList &filterNames) : QAbstractFileEngineIterator(filters, filterNames) -#ifdef Q_OS_UNIX , done(false) -#endif { -#ifndef Q_OS_UNIX - newPlatformSpecifics(); -#endif } QFSFileEngineIterator::~QFSFileEngineIterator() { -#ifndef Q_OS_UNIX - deletePlatformSpecifics(); -#endif } -#ifdef Q_OS_UNIX bool QFSFileEngineIterator::hasNext() const { if (!done && !nativeIterator) { @@ -76,7 +67,6 @@ bool QFSFileEngineIterator::hasNext() const return !done; } -#endif QString QFSFileEngineIterator::next() { @@ -87,7 +77,6 @@ QString QFSFileEngineIterator::next() return currentFilePath(); } -#ifdef Q_OS_UNIX void QFSFileEngineIterator::advance() const { currentInfo = nextInfo; @@ -101,24 +90,15 @@ void QFSFileEngineIterator::advance() const nativeIterator.reset(); } } -#endif QString QFSFileEngineIterator::currentFileName() const { -#ifdef Q_OS_UNIX return currentInfo.fileName(); -#else - return currentEntry; -#endif } QFileInfo QFSFileEngineIterator::currentFileInfo() const { -#ifdef Q_OS_UNIX return currentInfo; -#else - return QAbstractFileEngineIterator::currentFileInfo(); -#endif } QT_END_NAMESPACE diff --git a/src/corelib/io/qfsfileengine_iterator_p.h b/src/corelib/io/qfsfileengine_iterator_p.h index 7940fbd..ac9598d 100644 --- a/src/corelib/io/qfsfileengine_iterator_p.h +++ b/src/corelib/io/qfsfileengine_iterator_p.h @@ -77,21 +77,11 @@ public: QFileInfo currentFileInfo() const; private: -#ifdef Q_OS_UNIX void advance() const; mutable QScopedPointer nativeIterator; mutable QFileInfo currentInfo; mutable QFileInfo nextInfo; mutable bool done; -#else - QFSFileEngineIteratorPlatformSpecificData *platform; - friend class QFSFileEngineIteratorPlatformSpecificData; - void newPlatformSpecifics(); - void deletePlatformSpecifics(); - void advance(); - - QString currentEntry; -#endif }; QT_END_NAMESPACE diff --git a/src/corelib/io/qfsfileengine_iterator_win.cpp b/src/corelib/io/qfsfileengine_iterator_win.cpp deleted file mode 100644 index d4e6f5a..0000000 --- a/src/corelib/io/qfsfileengine_iterator_win.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************** -** -** 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 QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the 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 "qfsfileengine_iterator_p.h" -#include "qfsfileengine_p.h" -#include "qfilesystemengine_p.h" -#include "qplatformdefs.h" - -#include - -QT_BEGIN_NAMESPACE - -class QFSFileEngineIteratorPlatformSpecificData -{ -public: - inline QFSFileEngineIteratorPlatformSpecificData() - : uncShareIndex(-1), findFileHandle(INVALID_HANDLE_VALUE), - done(false), uncFallback(false) - {} - - QFSFileEngineIterator *it; - - QStringList uncShares; - int uncShareIndex; - - HANDLE findFileHandle; - WIN32_FIND_DATA findData; - bool done; - bool uncFallback; - - void saveCurrentFileName(); -}; - -void QFSFileEngineIteratorPlatformSpecificData::saveCurrentFileName() -{ - if (uncFallback) { - // Windows share / UNC path - it->currentEntry = uncShares.at(uncShareIndex - 1); - } else { - // Local directory - it->currentEntry = QString::fromWCharArray(findData.cFileName); - } -} - -void QFSFileEngineIterator::advance() -{ - platform->saveCurrentFileName(); - - if (platform->done) - return; - - if (platform->uncFallback) { - ++platform->uncShareIndex; - } else if (platform->findFileHandle != INVALID_HANDLE_VALUE) { - if (!FindNextFile(platform->findFileHandle, &platform->findData)) { - platform->done = true; - FindClose(platform->findFileHandle); - } - } -} - -void QFSFileEngineIterator::newPlatformSpecifics() -{ - platform = new QFSFileEngineIteratorPlatformSpecificData; - platform->it = this; -} - -void QFSFileEngineIterator::deletePlatformSpecifics() -{ - delete platform; - platform = 0; -} - -bool QFSFileEngineIterator::hasNext() const -{ - if (platform->done) - return false; - - if (platform->uncFallback) - return platform->uncShareIndex > 0 && platform->uncShareIndex <= platform->uncShares.size(); - - if (platform->findFileHandle == INVALID_HANDLE_VALUE) { - QString path = this->path(); - // Local directory - if (path.endsWith(QLatin1String(".lnk"))) - path = QFileInfo(path).readLink(); - - if (!path.endsWith(QLatin1Char('/'))) - path.append(QLatin1Char('/')); - path.append(QLatin1String("*.*")); - - QString fileName = QFSFileEnginePrivate::longFileName(path); - platform->findFileHandle = FindFirstFile((const wchar_t *)fileName.utf16(), &platform->findData); - - if (platform->findFileHandle == INVALID_HANDLE_VALUE) { - if (path.startsWith(QLatin1String("//"))) { - path = this->path(); - // UNC - QStringList parts = QDir::toNativeSeparators(path).split(QLatin1Char('\\'), QString::SkipEmptyParts); - - if (parts.count() == 1 && QFileSystemEngine::uncListSharesOnServer(QLatin1String("\\\\") + parts.at(0), - &platform->uncShares)) { - if (platform->uncShares.isEmpty()) { - platform->done = true; - } else { - platform->uncShareIndex = 1; - } - platform->uncFallback = true; - } else { - platform->done = true; - } - } else { - platform->done = true; - } - } - - if (!platform->done && (!platform->uncFallback || !platform->uncShares.isEmpty())) - platform->saveCurrentFileName(); - } - - return !platform->done; -} - -QT_END_NAMESPACE diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 81b785a..179cb0b 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -92,7 +92,6 @@ unix:SOURCES += ../../corelib/io/qfilesystemengine_unix.cpp \ win32:SOURCES += ../../corelib/io/qfilesystemengine_win.cpp \ ../../corelib/io/qfilesystemiterator_win.cpp \ ../../corelib/io/qfsfileengine_win.cpp \ - ../../corelib/io/qfsfileengine_iterator_win.cpp macx: { QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 #enables weak linking for 10.4 (exported) diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index fe1b028..6450038 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -97,7 +97,6 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_iterator.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_iterator_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qiodevice.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qtextstream.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qtemporaryfile.cpp \ diff --git a/tools/qtestlib/wince/cetest/bootstrapped.pri b/tools/qtestlib/wince/cetest/bootstrapped.pri index 76245b0..56c8ab7 100644 --- a/tools/qtestlib/wince/cetest/bootstrapped.pri +++ b/tools/qtestlib/wince/cetest/bootstrapped.pri @@ -12,7 +12,6 @@ SOURCES += \ $$QT_SOURCE_TREE/src/corelib/io/qabstractfileengine.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_iterator.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_iterator_win.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qfileinfo.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qtemporaryfile.cpp \ $$QT_SOURCE_TREE/src/corelib/io/qdiriterator.cpp \ -- cgit v0.12 From 5e2fc1468572098cd02df25061f277b60e9b35bd Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 15 Sep 2010 17:48:39 +0100 Subject: Integrate media use case performance tests to qdir tree benchmarks These tests measure the performance of QDirIterator across: - 1000 files in one directory (based on photos) - 1000 files as 100 directories each with 10 files (based on music albums) The test counts and totals the sizes of files, to make sure this isn't causing unwanted filesystem accesses. Reviewed-By: joao --- .../corelib/io/qdir/tree/bench_qdir_tree.cpp | 52 +++++++++++++++++++++- tests/shared/filesystem.h | 10 +++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/tests/benchmarks/corelib/io/qdir/tree/bench_qdir_tree.cpp b/tests/benchmarks/corelib/io/qdir/tree/bench_qdir_tree.cpp index cbe931d..81a1262 100644 --- a/tests/benchmarks/corelib/io/qdir/tree/bench_qdir_tree.cpp +++ b/tests/benchmarks/corelib/io/qdir/tree/bench_qdir_tree.cpp @@ -55,12 +55,20 @@ class bench_QDir_tree public: bench_QDir_tree() - : prefix("./test-tree/") + : prefix("./test-tree/"), + musicprefix(QLatin1String("music")), + photoprefix(QLatin1String("photos")), + musicsize(0), + photosize(0) { } private: QByteArray prefix; + QString musicprefix; + QString photoprefix; + qint64 musicsize; + qint64 photosize; private slots: void initTestCase() @@ -105,6 +113,23 @@ private slots: line.clear(); } + + //Use case: music collection - 10 files in 100 directories (albums) + QVERIFY(fs.createDirectory(musicprefix)); + for (int i=0;i<1000;i++) { + if ((i % 10) == 0) + QVERIFY(fs.createDirectory(QString("%1/directory%2").arg(musicprefix).arg(i/10))); + qint64 size = fs.createFileWithContent(QString("%1/directory%2/file%3").arg(musicprefix).arg(i/10).arg(i)); + QVERIFY(size > 0); + musicsize += size; + } + //Use case: photos - 1000 files in 1 directory + QVERIFY(fs.createDirectory(photoprefix)); + for (int i=0;i<1000;i++) { + qint64 size = fs.createFileWithContent(QString("%1/file%2").arg(photoprefix).arg(i)); + QVERIFY(size > 0); + photosize += size; + } } void fileSearch_data() const @@ -166,6 +191,31 @@ private slots: QCOMPARE(count, 11963); } + void thousandFiles_data() const + { + QTest::addColumn("dirName"); + QTest::addColumn("expectedSize"); + QTest::newRow("music") << musicprefix << musicsize; + QTest::newRow("photos") << photoprefix << photosize; + } + + void thousandFiles() const + { + QFETCH(QString, dirName); + QFETCH(qint64, expectedSize); + QBENCHMARK { + qint64 totalsize = 0; + int count = 0; + QDirIterator iter(dirName, QDir::Files, QDirIterator::Subdirectories); + while(iter.hasNext()) { + iter.next(); + count++; + totalsize += iter.fileInfo().size(); + } + QCOMPARE(count, 1000); + QCOMPARE(totalsize, expectedSize); + } + } private: FileSystem fs; }; diff --git a/tests/shared/filesystem.h b/tests/shared/filesystem.h index 079a6dc..8274346 100644 --- a/tests/shared/filesystem.h +++ b/tests/shared/filesystem.h @@ -87,6 +87,16 @@ struct FileSystem return false; } + qint64 createFileWithContent(const QString &fileName) + { + QFile file(fileName); + if (file.open(QIODevice::WriteOnly)) { + createdFiles << fileName; + return file.write(fileName.toUtf8()); + } + return -1; + } + bool createLink(const QString &destination, const QString &linkName) { if (QFile::link(destination, linkName)) { -- cgit v0.12 From 81c2b37cbcd2f0432d3036765d6b1d0cdaa4872a Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 15 Sep 2010 18:01:12 +0100 Subject: On symbian, set the "execute" permission for directories This is the same as the windows port does for non NTFS drives. For files, execute permission is set to false, as the /sys/bin directory is not listable by normal applications. Reviewed-By: joao --- src/corelib/io/qfilesystemengine_symbian.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 9b81571..02b4c48 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -171,13 +171,13 @@ void QFileSystemMetaData::fillFromTEntry(const TEntry& entry) entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags); knownFlagsMask |= QFileSystemMetaData::SymbianTEntryFlags; //Symbian doesn't have unix type file permissions - entryFlags |= QFileSystemMetaData::Permissions; - if(entry.IsReadOnly()) { - entryFlags &= ~(QFileSystemMetaData::WritePermissions); + entryFlags |= QFileSystemMetaData::ReadPermissions; + if(!entry.IsReadOnly()) { + entryFlags |= QFileSystemMetaData::WritePermissions; } //set the type if(entry.IsDir()) - entryFlags |= QFileSystemMetaData::DirectoryType; + entryFlags |= (QFileSystemMetaData::DirectoryType | QFileSystemMetaData::ExecutePermissions); else entryFlags |= QFileSystemMetaData::FileType; -- cgit v0.12 From 6437e4083bf088a3a67660d7b015de8647557609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 15 Sep 2010 19:28:48 +0200 Subject: Fix typo --- src/corelib/io/qfilesystemengine_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 6d8b3ff..6290d68 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -193,7 +193,7 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, } //static -QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, , QFileSystemMetaData &data) +QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data) { if (entry.isEmpty() || entry.isRoot()) return entry; -- cgit v0.12 From 6f716cbdc8a054d2bedc0ffa2bb3a48c12e24695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Sep 2010 11:31:19 +0200 Subject: Fix QSettings auto test to use QTRY_VERIFY ... instead of relying on qApp->processEvents. Reviewed-by: Olivier Goffart --- tests/auto/qsettings/tst_qsettings.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/auto/qsettings/tst_qsettings.cpp b/tests/auto/qsettings/tst_qsettings.cpp index 058a750..48c5fd1 100644 --- a/tests/auto/qsettings/tst_qsettings.cpp +++ b/tests/auto/qsettings/tst_qsettings.cpp @@ -51,6 +51,7 @@ #include #include #include +#include "../../shared/util.h" #if !defined(Q_OS_SYMBIAN) # include @@ -1719,26 +1720,22 @@ void tst_QSettings::testUpdateRequestEvent() settings1.setValue("key1", 1); QVERIFY(QFileInfo("foo").size() == 0); - qApp->processEvents(); - QVERIFY(QFileInfo("foo").size() > 0); + QTRY_VERIFY(QFileInfo("foo").size() > 0); settings1.remove("key1"); QVERIFY(QFileInfo("foo").size() > 0); - qApp->processEvents(); - QVERIFY(QFileInfo("foo").size() == 0); + QTRY_VERIFY(QFileInfo("foo").size() == 0); settings1.setValue("key2", 2); QVERIFY(QFileInfo("foo").size() == 0); - qApp->processEvents(); - QVERIFY(QFileInfo("foo").size() > 0); + QTRY_VERIFY(QFileInfo("foo").size() > 0); settings1.clear(); QVERIFY(QFileInfo("foo").size() > 0); - qApp->processEvents(); - QVERIFY(QFileInfo("foo").size() == 0); + QTRY_VERIFY(QFileInfo("foo").size() == 0); } const int NumIterations = 5; -- cgit v0.12 From 4d45a868536a235b33029115a70795119b8f3822 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 16 Sep 2010 11:34:23 +0100 Subject: integrate "source" use case to bench_qdir_tree Although there's already some real source (4.6.0 file list) in the test, we decided it's useful to still have this benchmark for a standard directory structure in the 1000 file test. The source benchmark is 10 directories, each containing 10 subdirectories, which each contain 10 files. --- .../corelib/io/qdir/tree/bench_qdir_tree.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/benchmarks/corelib/io/qdir/tree/bench_qdir_tree.cpp b/tests/benchmarks/corelib/io/qdir/tree/bench_qdir_tree.cpp index 81a1262..84922f6 100644 --- a/tests/benchmarks/corelib/io/qdir/tree/bench_qdir_tree.cpp +++ b/tests/benchmarks/corelib/io/qdir/tree/bench_qdir_tree.cpp @@ -58,8 +58,10 @@ public: : prefix("./test-tree/"), musicprefix(QLatin1String("music")), photoprefix(QLatin1String("photos")), + sourceprefix(QLatin1String("source")), musicsize(0), - photosize(0) + photosize(0), + sourcesize(0) { } @@ -67,8 +69,10 @@ private: QByteArray prefix; QString musicprefix; QString photoprefix; + QString sourceprefix; qint64 musicsize; qint64 photosize; + qint64 sourcesize; private slots: void initTestCase() @@ -130,6 +134,17 @@ private slots: QVERIFY(size > 0); photosize += size; } + //Use case: source - 10 files in 10 subdirectories in 10 directories (1000 total) + QVERIFY(fs.createDirectory(sourceprefix)); + for (int i=0;i<1000;i++) { + if ((i % 100) == 0) + QVERIFY(fs.createDirectory(QString("%1/directory%2").arg(sourceprefix).arg(i/100))); + if ((i % 10) == 0) + QVERIFY(fs.createDirectory(QString("%1/directory%2/subdirectory%3").arg(sourceprefix).arg(i/100).arg(i/10))); + qint64 size = fs.createFileWithContent(QString("%1/directory%2/subdirectory%3/file%4").arg(sourceprefix).arg(i/100).arg(i/10).arg(i)); + QVERIFY(size > 0); + sourcesize += size; + } } void fileSearch_data() const @@ -197,6 +212,7 @@ private slots: QTest::addColumn("expectedSize"); QTest::newRow("music") << musicprefix << musicsize; QTest::newRow("photos") << photoprefix << photosize; + QTest::newRow("src") << sourceprefix << sourcesize; } void thousandFiles() const -- cgit v0.12 From 186bcd5f6f65ce4d52b2e9cd0c25caba0ae66eda Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 15 Sep 2010 14:44:58 +0200 Subject: Remove stale comment --- src/corelib/io/qfileinfo.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 4f5a4ab..471da2e 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -397,7 +397,6 @@ bool QFileInfo::operator==(const QFileInfo &fileinfo) const return false; sensitive = QFileSystemEngine::isCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive; - // if both are native just compare the canonicalFilePath of both. } else { if (d->fileEngine->caseSensitive() != fileinfo.d_ptr->fileEngine->caseSensitive()) return false; -- cgit v0.12 From b9b55234a777c3b206332bafbe227e1355ca9186 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 15 Sep 2010 14:44:38 +0200 Subject: Make QDir use QFileSystemEngine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The creation of a QAbstractFileEngine derived class will now be avoided if the dir we are watching is on the native file system and from then on all access will be through the direct API Reviewed-by: João Abecasis --- src/corelib/io/qdir.cpp | 183 ++++++++++++++++++++++++++++++------------------ 1 file changed, 114 insertions(+), 69 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 8c99226..efc0ba9 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -53,6 +53,10 @@ #include "qvector.h" #include "qalgorithms.h" #include "qvarlengtharray.h" +#include "qfilesystementry_p.h" +#include "qfilesystemmetadata_p.h" +#include "qfilesystemengine_p.h" +#include #ifdef QT_BUILD_CORE_LIB # include "qresource.h" @@ -117,7 +121,6 @@ public: QDirPrivate(const QDirPrivate ©) : QSharedData(copy) - , path(copy.path) , nameFilters(copy.nameFilters) , sort(copy.sort) , filters(copy.filters) @@ -126,11 +129,19 @@ public: , matchAllDirs(copy.matchAllDirs) #endif , fileListsInitialized(false) + , dirEntry(copy.dirEntry) + , metaData(copy.metaData) { } bool exists() const { + if (fileEngine.isNull()) { + if (!metaData.hasFlags(QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType)) + QFileSystemEngine::fillMetaData(dirEntry, metaData, + QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); + return metaData.exists() && metaData.isDirectory(); + } const QAbstractFileEngine::FileFlags info = fileEngine->fileFlags(QAbstractFileEngine::DirectoryType | QAbstractFileEngine::ExistsFlag @@ -141,7 +152,7 @@ public: } void initFileEngine(); - void initFileLists() const; + void initFileLists(const QDir &dir) const; static void sortFileList(QDir::SortFlags, QFileInfoList &, QStringList *, QFileInfoList *); @@ -174,21 +185,32 @@ public: p.truncate(p.length() - 1); } - path = p; + dirEntry = QFileSystemEntry(p); initFileEngine(); - - // set the path to be the qt friendly version so then we can operate on it using just / - path = fileEngine->fileName(QAbstractFileEngine::DefaultName); clearFileLists(); + absoluteDirEntry = QFileSystemEntry(); } - inline void clearFileLists() { + inline void clearFileLists() + { fileListsInitialized = false; files.clear(); fileInfos.clear(); } - QString path; + inline void resolveAbsoluteEntry() const + { + if (!absoluteDirEntry.isEmpty() || dirEntry.isEmpty()) + return; + + if (dirEntry.isRelative()) { + QFileSystemEntry answer = QFileSystemEngine::absoluteName(dirEntry); + absoluteDirEntry = QFileSystemEntry(QDir::cleanPath(answer.filePath())); + } else { + absoluteDirEntry = dirEntry; + } + } + QStringList nameFilters; QDir::SortFlags sort; QDir::Filters filters; @@ -203,6 +225,10 @@ public: mutable bool fileListsInitialized; mutable QStringList files; mutable QFileInfoList fileInfos; + + QFileSystemEntry dirEntry; + mutable QFileSystemEntry absoluteDirEntry; + mutable QFileSystemMetaData metaData; }; /* For sorting */ @@ -316,11 +342,11 @@ inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l, } } -inline void QDirPrivate::initFileLists() const +inline void QDirPrivate::initFileLists(const QDir &dir) const { if (!fileListsInitialized) { QFileInfoList l; - QDirIterator it(path, nameFilters, filters); + QDirIterator it(dir); while (it.hasNext()) { it.next(); l.append(it.fileInfo()); @@ -332,7 +358,7 @@ inline void QDirPrivate::initFileLists() const inline void QDirPrivate::initFileEngine() { - fileEngine.reset(QAbstractFileEngine::create(path)); + fileEngine.reset(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(dirEntry, metaData)); } /*! @@ -597,7 +623,7 @@ void QDir::setPath(const QString &path) QString QDir::path() const { const QDirPrivate* d = d_ptr.constData(); - return d->path; + return d->dirEntry.filePath(); } /*! @@ -611,10 +637,8 @@ QString QDir::path() const QString QDir::absolutePath() const { const QDirPrivate* d = d_ptr.constData(); - QString ret = d->path; - if (QDir::isRelativePath(ret)) - ret = absoluteFilePath(QString::fromLatin1("")); - return cleanPath(ret); + d->resolveAbsoluteEntry(); + return d->absoluteDirEntry.filePath(); } /*! @@ -635,7 +659,12 @@ QString QDir::absolutePath() const */ QString QDir::canonicalPath() const { - return cleanPath(d_ptr->fileEngine->fileName(QAbstractFileEngine::CanonicalName)); + const QDirPrivate* d = d_ptr.constData(); + if (d->fileEngine.isNull()) { + QFileSystemEntry answer = QFileSystemEngine::canonicalName(d->dirEntry, d->metaData); + return answer.filePath(); + } + return d->fileEngine->fileName(QAbstractFileEngine::CanonicalName); } /*! @@ -652,10 +681,7 @@ QString QDir::canonicalPath() const QString QDir::dirName() const { const QDirPrivate* d = d_ptr.constData(); - int pos = d->path.lastIndexOf(QLatin1Char('/')); - if (pos == -1) - return d->path; - return d->path.mid(pos + 1); + return d->dirEntry.fileName(); } /*! @@ -673,7 +699,7 @@ QString QDir::filePath(const QString &fileName) const if (isAbsolutePath(fileName)) return QString(fileName); - QString ret = d->path; + QString ret = d->dirEntry.filePath(); if (!fileName.isEmpty()) { if (!ret.isEmpty() && ret[(int)ret.length()-1] != QLatin1Char('/') && fileName[0] != QLatin1Char('/')) ret += QLatin1Char('/'); @@ -696,22 +722,12 @@ QString QDir::absoluteFilePath(const QString &fileName) const if (isAbsolutePath(fileName)) return fileName; - QString ret; -#ifndef QT_NO_FSFILEENGINE - if (isRelativePath(d->path)) //get pwd - ret = QFSFileEngine::currentPath(fileName); -#endif - if (!d->path.isEmpty() && d->path != QLatin1String(".")) { - if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) - ret += QLatin1Char('/'); - ret += d->path; - } - if (!fileName.isEmpty()) { - if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) - ret += QLatin1Char('/'); - ret += fileName; - } - return ret; + d->resolveAbsoluteEntry(); + if (fileName.isEmpty()) + return d->absoluteDirEntry.filePath(); + if (!d->absoluteDirEntry.isRoot()) + return d->absoluteDirEntry.filePath() % QLatin1Char('/') % fileName; + return d->absoluteDirEntry.filePath() % fileName; } /*! @@ -857,21 +873,22 @@ bool QDir::cd(const QString &dirName) if (dirName.isEmpty() || dirName == QLatin1String(".")) return true; - QString newPath = d->path; + QString newPath; if (isAbsolutePath(dirName)) { newPath = cleanPath(dirName); } else { if (isRoot()) { if (dirName == QLatin1String("..")) return false; + newPath = d->dirEntry.filePath(); } else { - newPath += QLatin1Char('/'); + newPath = d->dirEntry.filePath() % QLatin1Char('/'); } newPath += dirName; if (dirName.indexOf(QLatin1Char('/')) >= 0 - || d->path == QLatin1String(".") - || dirName == QLatin1String("..")) { + || dirName == QLatin1String("..") + || d->dirEntry.filePath() == QLatin1String(".")) { newPath = cleanPath(newPath); /* If newPath starts with .., we convert it to absolute to @@ -889,7 +906,6 @@ bool QDir::cd(const QString &dirName) QScopedPointer dir(new QDirPrivate(*d_ptr.constData())); dir->setPath(newPath); - if (!dir->exists()) return false; @@ -1202,7 +1218,7 @@ void QDir::setSorting(SortFlags sort) uint QDir::count() const { const QDirPrivate* d = d_ptr.constData(); - d->initFileLists(); + d->initFileLists(*this); return d->files.count(); } @@ -1216,7 +1232,7 @@ uint QDir::count() const QString QDir::operator[](int pos) const { const QDirPrivate* d = d_ptr.constData(); - d->initFileLists(); + d->initFileLists(*this); return d->files[pos]; } @@ -1299,12 +1315,12 @@ QStringList QDir::entryList(const QStringList &nameFilters, Filters filters, sort = d->sort; if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) { - d->initFileLists(); + d->initFileLists(*this); return d->files; } QFileInfoList l; - QDirIterator it(d->path, nameFilters, filters); + QDirIterator it(d->dirEntry.filePath(), nameFilters, filters); while (it.hasNext()) { it.next(); l.append(it.fileInfo()); @@ -1345,12 +1361,12 @@ QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filter sort = d->sort; if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) { - d->initFileLists(); + d->initFileLists(*this); return d->fileInfos; } QFileInfoList l; - QDirIterator it(d->path, nameFilters, filters); + QDirIterator it(d->dirEntry.filePath(), nameFilters, filters); while (it.hasNext()) { it.next(); l.append(it.fileInfo()); @@ -1377,6 +1393,8 @@ bool QDir::mkdir(const QString &dirName) const } QString fn = filePath(dirName); + if (d->fileEngine.isNull()) + return QFileSystemEngine::createDirectory(QFileSystemEntry(fn), false); return d->fileEngine->mkdir(fn, false); } @@ -1399,6 +1417,9 @@ bool QDir::rmdir(const QString &dirName) const } QString fn = filePath(dirName); + if (d->fileEngine.isNull()) + return QFileSystemEngine::removeDirectory(QFileSystemEntry(fn), false); + return d->fileEngine->rmdir(fn, false); } @@ -1422,6 +1443,8 @@ bool QDir::mkpath(const QString &dirPath) const } QString fn = filePath(dirPath); + if (d->fileEngine.isNull()) + return QFileSystemEngine::createDirectory(QFileSystemEntry(fn), true); return d->fileEngine->mkdir(fn, true); } @@ -1446,6 +1469,8 @@ bool QDir::rmpath(const QString &dirPath) const } QString fn = filePath(dirPath); + if (d->fileEngine.isNull()) + return QFileSystemEngine::removeDirectory(QFileSystemEntry(fn), true); return d->fileEngine->rmdir(fn, true); } @@ -1462,6 +1487,13 @@ bool QDir::isReadable() const { const QDirPrivate* d = d_ptr.constData(); + if (d->fileEngine.isNull()) { + if (!d->metaData.hasFlags(QFileSystemMetaData::UserReadPermission)) + QFileSystemEngine::fillMetaData(d->dirEntry, d->metaData, QFileSystemMetaData::UserReadPermission); + + return (d->metaData.permissions() & QFile::ReadUser) != 0; + } + const QAbstractFileEngine::FileFlags info = d->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType | QAbstractFileEngine::PermsMask); @@ -1500,6 +1532,8 @@ bool QDir::exists() const */ bool QDir::isRoot() const { + if (d_ptr->fileEngine.isNull()) + return d_ptr->dirEntry.isRoot(); return d_ptr->fileEngine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::RootFlag; } @@ -1530,7 +1564,7 @@ bool QDir::isRoot() const */ bool QDir::isRelative() const { - return d_ptr->fileEngine->isRelativePath(); + return d_ptr->dirEntry.isRelative(); } @@ -1541,19 +1575,23 @@ bool QDir::isRelative() const \sa isAbsolute() isAbsolutePath() isRelative() cleanPath() */ -bool QDir::makeAbsolute() // ### What do the return values signify? +bool QDir::makeAbsolute() { - QString absolutePath = d_ptr.constData()->fileEngine->fileName(QAbstractFileEngine::AbsoluteName); - if (QDir::isRelativePath(absolutePath)) - return false; - - QScopedPointer dir(new QDirPrivate(*d_ptr.constData())); - dir->setPath(absolutePath); - - if (!(dir->fileEngine->fileFlags(QAbstractFileEngine::TypesMask) & QAbstractFileEngine::DirectoryType)) - return false; + const QDirPrivate *d = d_ptr.constData(); + QScopedPointer dir; + if (!d->fileEngine.isNull()) { + QString absolutePath = d->fileEngine->fileName(QAbstractFileEngine::AbsoluteName); + if (QDir::isRelativePath(absolutePath)) + return false; - d_ptr = dir.take(); + dir.reset(new QDirPrivate(*d_ptr.constData())); + dir->setPath(absolutePath); + } else { // native FS + d->resolveAbsoluteEntry(); + dir.reset(new QDirPrivate(*d_ptr.constData())); + dir->setPath(d->absoluteDirEntry.filePath()); + } + d_ptr = dir.take(); // actually detach return true; } @@ -1573,17 +1611,24 @@ bool QDir::operator==(const QDir &dir) const if (d == other) return true; - if (d->fileEngine->caseSensitive() != other->fileEngine->caseSensitive()) - return false; + Qt::CaseSensitivity sensitive; + if (d->fileEngine.isNull() || other->fileEngine.isNull()) { + if (d->fileEngine.data() != other->fileEngine.data()) // one is native, the other is a custom file-engine + return false; + + sensitive = QFileSystemEngine::isCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive; + } else { + if (d->fileEngine->caseSensitive() != other->fileEngine->caseSensitive()) + return false; + sensitive = d->fileEngine->caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive; + } + if (d->filters == other->filters && d->sort == other->sort && d->nameFilters == other->nameFilters) { - QString dir1 = absolutePath(), dir2 = dir.absolutePath(); - if (!other->fileEngine->caseSensitive()) - return (dir1.toLower() == dir2.toLower()); - - return (dir1 == dir2); - + d->resolveAbsoluteEntry(); + other->resolveAbsoluteEntry(); + return d->absoluteDirEntry.filePath().compare(other->absoluteDirEntry.filePath(), sensitive) == 0; } return false; } -- cgit v0.12 From 3df81c23e6ab7dae949315a4f0ca4e54469ab2bf Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 16 Sep 2010 16:02:01 +0100 Subject: Fix for QDir constructed with a path containing native separators. QFileSystemEntry's m_filePath should always contain a path with / as separator. Reviewed-By: Thomas Zander --- src/corelib/io/qdir.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index efc0ba9..a45c104 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -175,13 +175,15 @@ public: return ret; } - inline void setPath(QString p) + inline void setPath(const QString &path) { - if ((p.endsWith(QLatin1Char('/')) || p.endsWith(QLatin1Char('\\'))) - && p.length() > 1) { + QString p = QDir::fromNativeSeparators(path); + if (p.endsWith(QLatin1Char('/')) + && p.length() > 1 #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) - if (!(p.length() == 3 && p.at(1) == QLatin1Char(':'))) + && (!(p.length() == 3 && p.at(1).unicode() == ':' && p.at(0).isLetter())) #endif + ) { p.truncate(p.length() - 1); } -- cgit v0.12 From 206f49020bce11e142c4290b6655ac7c15592b43 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Fri, 17 Sep 2010 15:04:27 +0200 Subject: Differntiate different types of absolute paths on windows. QFileSystemEntry now differentiates between various types of absolute paths on Windows and Symbian. The new behavior is shown the table below. Anybody who uses this class should NOT treat that !isRelative() == isAbsolute(). The differentiation is puerly for internal use by the windows and symbian implementations of QFileSystemEngine. |============================================| |Filename isRelative isAbsolute | |============================================| | Somefile.txt 1 0 | | Some/file.txt 1 0 | | a:Somefile.txt 0 0 | | /Somefile.txt 0 0 | | a:/somefile.txt 0 1 | | //abc/somefile.txt 0 1 | |============================================| Reviewed-by: Joao Reviewed-by: Shane Kearns --- src/corelib/io/qfilesystemengine_symbian.cpp | 2 +- src/corelib/io/qfilesystemengine_win.cpp | 20 ++++----- src/corelib/io/qfilesystementry.cpp | 30 ++++++++++---- src/corelib/io/qfilesystementry_p.h | 4 +- .../auto/qfilesystementry/tst_qfilesystementry.cpp | 47 ++++++++++++++++++---- 5 files changed, 74 insertions(+), 29 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 02b4c48..b4f0f88 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -114,7 +114,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) const bool isDriveRelative = (orig.size() > 2 && orig.at(1).unicode() == ':' && orig.at(2).unicode() != '/'); const bool isDirty = (orig.contains(QLatin1String("/../")) || orig.contains(QLatin1String("/./")) || orig.endsWith(QLatin1String("/..")) || orig.endsWith(QLatin1String("/."))); - const bool isAbsolute = entry.isAbsolute(); + const bool isAbsolute = !entry.isRelative(); if (isAbsolute && !(needsDrive || isDriveLetter || isDriveRelative || isDirty)) return entry; diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 8526cf2..119ed7c 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -545,18 +545,18 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) if (!entry.isRelative()) { #if !defined(Q_OS_WINCE) - if (entry.filePath().startsWith(QLatin1Char('/')) || // It's a absolute path to the current drive, so \a.txt -> Z:\a.txt - entry.filePath().size() == 2 || // It's a drive letter that needs to get a working dir appended - (entry.filePath().size() > 2 && entry.filePath().at(2) != QLatin1Char('/')) || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt - entry.filePath().contains(QLatin1String("/../")) || entry.filePath().contains(QLatin1String("/./")) || - entry.filePath().endsWith(QLatin1String("/..")) || entry.filePath().endsWith(QLatin1String("/."))) - { - ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(entry.filePath())); - } else -#endif - { + if (entry.isAbsolute() + && !entry.filePath().contains(QLatin1String("/../")) + && !entry.filePath().contains(QLatin1String("/./")) + && !entry.filePath().endsWith(QLatin1String("/..")) + && !entry.filePath().endsWith(QLatin1String("/."))) { ret = entry.filePath(); + } else { + ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(entry.filePath())); } +#else + ret = entry.filePath(); +#endif } else { ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + entry.filePath()); } diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index 733a226..10b59fd 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -225,17 +225,33 @@ QString QFileSystemEntry::completeSuffix() const return m_filePath.mid(qMax((qint16)0, m_lastSeparator) + m_firstDotInFileName + 1); } +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) +bool QFileSystemEntry::isRelative() const +{ + resolveFilePath(); + return (m_filePath.isEmpty() || (!m_filePath.isEmpty() && (m_filePath[0].unicode() != '/') + && (!(m_filePath.length() >= 2 && m_filePath[1].unicode() == ':')))); +} + bool QFileSystemEntry::isAbsolute() const { resolveFilePath(); - return (!m_filePath.isEmpty() && (m_filePath[0].unicode() == '/') -#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) - || (m_filePath.length() >= 2 - && ((m_filePath[0].isLetter() && m_filePath[1].unicode() == ':') - || (m_filePath.at(0) == QLatin1Char('/') && m_filePath.at(1) == QLatin1Char('/')))) -#endif - ); + return (!m_filePath.isEmpty() && ((m_filePath.length() >= 3 + && (m_filePath[0].isLetter() && m_filePath[1].unicode() == ':' && m_filePath[2].unicode() == '/')) + || (m_filePath.length() >= 2 && (m_filePath.at(0) == QLatin1Char('/') && m_filePath.at(1) == QLatin1Char('/'))))); +} +#else +bool QFileSystemEntry::isRelative() const +{ + return !isAbsolute(); +} + +bool QFileSystemEntry::isAbsolute() const +{ + resolveFilePath(); + return (!m_filePath.isEmpty() && (m_filePath[0].unicode() == '/')); } +#endif #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) bool QFileSystemEntry::isDriveRoot() const diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index 5a41782..7a9c2a5 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -88,9 +88,7 @@ public: QString suffix() const; QString completeSuffix() const; bool isAbsolute() const; - bool isRelative() const { - return !isAbsolute(); - } + bool isRelative() const; #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) bool isDriveRoot() const; diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp index 49afab6..4375f99 100644 --- a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp +++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp @@ -64,6 +64,10 @@ private slots: void baseName(); void completeBaseName_data(); void completeBaseName(); +#if defined(WIN_STUFF) + void absoluteOrRelative_data(); + void absoluteOrRelative(); +#endif }; #if defined(WIN_STUFF) @@ -78,6 +82,7 @@ void tst_QFileSystemEntry::getSetCheck_data() QTest::addColumn("suffix"); QTest::addColumn("completeSuffix"); QTest::addColumn("absolute"); + QTest::addColumn("relative"); QString absPrefix = QLatin1String("\\\\?\\"); QString relPrefix = absPrefix @@ -88,33 +93,33 @@ void tst_QFileSystemEntry::getSetCheck_data() << QString("A:\\home\\qt\\in\\a\\dir.tar.gz") << absPrefix + QString("A:\\home\\qt\\in\\a\\dir.tar.gz") << "A:/home/qt/in/a/dir.tar.gz" - << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << true; + << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << true << false; QTest::newRow("relative") << QString("in\\a\\dir.tar.gz") << relPrefix + QString("in\\a\\dir.tar.gz") << "in/a/dir.tar.gz" - << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << false; + << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << false <("path"); + QTest::addColumn("isAbsolute"); + QTest::addColumn("isRelative"); + + QTest::newRow("data0") << "file.tar" << false << true; + QTest::newRow("data1") << "/path/file/file.tar.gz" << false << false; + QTest::newRow("data1") << "C:path/file/file.tar.gz" << false << false; + QTest::newRow("data3") << "C:/path/file" << true << false; + QTest::newRow("data3") << "//machine/share" << true << false; +} + +void tst_QFileSystemEntry::absoluteOrRelative() +{ + QFETCH(QString, path); + QFETCH(bool, isAbsolute); + QFETCH(bool, isRelative); + + QFileSystemEntry fi(path); + QCOMPARE(fi.isAbsolute(), isAbsolute); + QCOMPARE(fi.isRelative(), isRelative); +} +#endif QTEST_MAIN(tst_QFileSystemEntry) #include -- cgit v0.12 From 768009af920c642834b1730136d9c8b156277c1d Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Fri, 17 Sep 2010 16:04:35 +0200 Subject: Fix QDir autotest failures on windows The canonicalName now checks the file existance before it returns the path. It will also fill in the metadata in case the existance was never checked before. Reviewed-by: Joao --- src/corelib/io/qfilesystemengine_win.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 119ed7c..20b9b4d 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -503,8 +503,13 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, //static QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data) { - // The caller has to verify whether the file exists or not. - return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath())); + if (data.missingFlags(QFileSystemMetaData::ExistsAttribute)) + QFileSystemEngine::fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute); + + if (data.exists()) + return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath())); + else + return QFileSystemEntry(); } //static -- cgit v0.12 From 63d50fdfa59cd198f7bf87f37770960e1b93945d Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 17 Sep 2010 15:05:04 +0100 Subject: Move rootPath, homePath, tempPath, currentPath and setCurrentPath Moved these functions inside the QFilesystemEngine and redirected the QFSFileEngine copies. Reviewed-By: joao --- src/corelib/io/qdir.cpp | 31 ++--------- src/corelib/io/qfilesystemengine_p.h | 9 +++- src/corelib/io/qfilesystemengine_symbian.cpp | 67 ++++++++++++++++++++++- src/corelib/io/qfilesystemengine_unix.cpp | 57 +++++++++++++++++++- src/corelib/io/qfilesystemengine_win.cpp | 67 +++++++++++++++++++++++ src/corelib/io/qfilesystementry.cpp | 8 ++- src/corelib/io/qfsfileengine_unix.cpp | 79 ++-------------------------- src/corelib/io/qfsfileengine_win.cpp | 51 ++---------------- src/corelib/kernel/qcoreapplication.cpp | 7 +++ 9 files changed, 225 insertions(+), 151 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index a45c104..e65dc11 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1779,12 +1779,7 @@ QChar QDir::separator() */ bool QDir::setCurrent(const QString &path) { -#ifdef QT_NO_FSFILEENGINE - Q_UNUSED(path); - return false; -#else - return QFSFileEngine::setCurrentPath(path); -#endif + return QFileSystemEngine::setCurrentPath(QFileSystemEntry(fromNativeSeparators(path))); } /*! @@ -1805,11 +1800,7 @@ bool QDir::setCurrent(const QString &path) */ QString QDir::currentPath() { -#ifdef QT_NO_FSFILEENGINE - return QString(); -#else - return QFSFileEngine::currentPath(); -#endif + return QFileSystemEngine::currentPath().filePath(); } /*! @@ -1867,11 +1858,7 @@ QString QDir::currentPath() */ QString QDir::homePath() { -#ifdef QT_NO_FSFILEENGINE - return QString(); -#else - return cleanPath(QFSFileEngine::homePath()); -#endif + return QFileSystemEngine::homePath(); } /*! @@ -1910,11 +1897,7 @@ QString QDir::homePath() */ QString QDir::tempPath() { -#ifdef QT_NO_FSFILEENGINE - return QString(); -#else - return cleanPath(QFSFileEngine::tempPath()); -#endif + return QFileSystemEngine::tempPath(); } /*! @@ -1941,11 +1924,7 @@ QString QDir::tempPath() */ QString QDir::rootPath() { -#ifdef QT_NO_FSFILEENGINE - return QString(); -#else - return QFSFileEngine::rootPath(); -#endif + return QFileSystemEngine::rootPath(); } /*! diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index b3bbd65..20b664d 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -88,11 +88,13 @@ public: QFileSystemMetaData::MetaDataFlags what); static bool fillPermissions(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what); - static QString homePath(); - static QString rootPath(); static QString owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own); static QString nativeAbsoluteFilePath(const QString &path); #endif + //homePath, rootPath and tempPath shall return clean paths + static QString homePath(); + static QString rootPath(); + static QString tempPath(); static bool createDirectory(const QFileSystemEntry &entry, bool createParents); static bool removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents); @@ -106,6 +108,9 @@ public: static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QFileSystemMetaData *data = 0); + static bool setCurrentPath(const QFileSystemEntry &entry); + static QFileSystemEntry currentPath(); + static QAbstractFileEngine *resolveEntryAndCreateLegacyEngine(QFileSystemEntry &entry, QFileSystemMetaData &data); private: diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index b4f0f88..ce2166d 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -42,8 +42,11 @@ #include "qfilesystemengine_p.h" #include "qfsfileengine.h" #include +#include #include +#include +#include QT_BEGIN_NAMESPACE @@ -121,7 +124,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) QString result; if (needsDrive || isDriveLetter || isDriveRelative || !isAbsolute || orig.isEmpty()) { - QFileSystemEntry cur(QFSFileEngine::currentPath()); + QFileSystemEntry cur(currentPath()); if(needsDrive) result = cur.filePath().left(2); else if(isDriveRelative && cur.filePath().at(0) != orig.at(0)) @@ -339,4 +342,66 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per return err == KErrNone; // TODO error reporting } +QString QFileSystemEngine::homePath() +{ + QString home = QDir::fromNativeSeparators(qt_TDesC2QString(PathInfo::PhoneMemoryRootPath())); + if(home.endsWith(QLatin1Char('/'))) + home.chop(1); + return home; +} + +QString QFileSystemEngine::rootPath() +{ + TChar drive; + TInt err = RFs::DriveToChar(RFs::GetSystemDrive(), drive); //RFs::GetSystemDriveChar not supported on S60 3.1 + Q_ASSERT(err == KErrNone); //RFs::GetSystemDrive() shall always return a convertible drive number on a valid OS configuration + return QString(QChar(drive)).append(QLatin1String(":/")); +} + +QString QFileSystemEngine::tempPath() +{ + return rootPath().append(QLatin1String("system/temp")); +} + +//static +bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry) +{ + QFileSystemMetaData meta; + QFileSystemEntry absname = absoluteName(entry); + fillMetaData(absname, meta, QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); + if(!(meta.exists() && meta.isDirectory())) + return false; + + RFs& fs = qt_s60GetRFs(); + QString abspath = absname.nativeFilePath(); + if(!abspath.endsWith(QLatin1Char('\\'))) + abspath.append(QLatin1Char('\\')); + TInt r = fs.SetSessionPath(qt_QString2TPtrC(abspath)); + //SetSessionPath succeeds for non existant directory, which is why it's checked above + if (r == KErrNone) { + __ASSERT_COMPILE(sizeof(wchar_t) == sizeof(unsigned short)); + //attempt to set open C to the same path + r = ::wchdir(reinterpret_cast(absname.filePath().utf16())); + if (r < 0) + qWarning("failed to sync path to open C"); + return true; + } + return false; +} + +//static +QFileSystemEntry QFileSystemEngine::currentPath() +{ + TFileName fn; + QFileSystemEntry ret; + TInt r = qt_s60GetRFs().SessionPath(fn); + if(r == KErrNone) { + //remove terminating slash from non root paths (session path is clean, absolute and always ends in a \) + if(fn.Length() > 3 && fn[fn.Length() - 1] == '\\') + fn.SetLength(fn.Length() - 1); + ret = QFileSystemEntry(qt_TDesC2QString(fn), QFileSystemEntry::FromNativePath()); + } + return ret; +} + QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 6290d68..8724b15 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -246,7 +246,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) QByteArray orig = entry.nativeFilePath(); QByteArray result; if (orig.isEmpty() || !orig.startsWith('/')) { - QFileSystemEntry cur(QFSFileEngine::currentPath()); + QFileSystemEntry cur(currentPath()); result = cur.nativeFilePath(); } if (!orig.isEmpty() && !(orig.length() == 1 && orig[0] == '.')) { @@ -548,4 +548,59 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per return false; // TODO implement; } +QString QFileSystemEngine::homePath() +{ + QString home = QFile::decodeName(qgetenv("HOME")); + if (home.isNull()) + home = rootPath(); + return QDir::cleanPath(home); +} + +QString QFileSystemEngine::rootPath() +{ + return QLatin1String("/"); +} + +QString QFileSystemEngine::tempPath() +{ + QString temp = QFile::decodeName(qgetenv("TMPDIR")); + if (temp.isEmpty()) + temp = QLatin1String("/tmp/"); + return QDir::cleanPath(temp); +} + +bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &path) +{ + int r; + r = QT_CHDIR(path.nativeFilePath()); + return r >= 0; +} + +QFileSystemEntry QFileSystemEngine::currentPath() +{ + QFileSystemEntry result; + QT_STATBUF st; + if (QT_STAT(".", &st) == 0) { +#if defined(__GLIBC__) && !defined(PATH_MAX) + char *currentName = ::get_current_dir_name(); + if (currentName) { + result = QFile::decodeName(QByteArray(currentName)); + ::free(currentName); + } +#else + char currentName[PATH_MAX+1]; + if (::getcwd(currentName, PATH_MAX)) + result = QFileSystemEntry(QByteArray(currentName), QFileSystemEntry::FromNativePath()); +# if defined(QT_DEBUG) + if (result.isEmpty()) + qWarning("QFSFileEngine::currentPath: getcwd() failed"); +# endif +#endif + } else { +# if defined(QT_DEBUG) + qWarning("QFSFileEngine::currentPath: stat(\".\") failed"); +# endif + } + return result; +} QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 20b9b4d..cef7236 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1098,6 +1098,73 @@ QString QFileSystemEngine::homePath() return QDir::fromNativeSeparators(ret); } +QString QFileSystemEngine::tempPath() +{ + QString ret; + wchar_t tempPath[MAX_PATH]; + DWORD len = GetTempPath(MAX_PATH, tempPath); + if (len) + ret = QString::fromWCharArray(tempPath, len); + if (!ret.isEmpty()) { + while (ret.endsWith(QLatin1Char('\\'))) + ret.chop(1); + ret = QDir::fromNativeSeparators(ret); + } + if (ret.isEmpty()) { +#if !defined(Q_OS_WINCE) + ret = QLatin1String("c:/tmp"); +#else + ret = QLatin1String("/Temp"); +#endif + } + return ret; +} + +bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry) +{ + QFileSystemMetaData meta; + fillMetaData(entry, meta, QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); + if(!(meta.exists() && meta.isDirectory())) + return false; + +#if !defined(Q_OS_WINCE) + //TODO: this should really be using nativeFilePath(), but that returns a path in long format \\?\c:\foo + //which causes many problems later on when it's returned through currentPath() + return ::SetCurrentDirectory(reinterpret_cast(QDir::toNativeSeparators(entry.filePath()).utf16())) != 0; +#else + qfsPrivateCurrentDir = entry.filePath(); + return true; +#endif +} + +QFileSystemEntry QFileSystemEngine::currentPath() +{ + QString ret; +#if !defined(Q_OS_WINCE) + DWORD size = 0; + wchar_t currentName[PATH_MAX]; + size = ::GetCurrentDirectory(PATH_MAX, currentName); + if (size != 0) { + if (size > PATH_MAX) { + wchar_t *newCurrentName = new wchar_t[size]; + if (::GetCurrentDirectory(PATH_MAX, newCurrentName) != 0) + ret = QString::fromWCharArray(newCurrentName, size); + delete [] newCurrentName; + } else { + ret = QString::fromWCharArray(currentName, size); + } + } +#else + Q_UNUSED(fileName); + //TODO - a race condition exists when using currentPath / setCurrentPath from multiple threads + if (qfsPrivateCurrentDir.isEmpty()) + qfsPrivateCurrentDir = QCoreApplication::applicationDirPath(); + + ret = qfsPrivateCurrentDir; +#endif + return QFileSystemEntry(ret, QFileSystemEntry::FromNativePath()); +} + //static bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target) { diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index 10b59fd..12de135 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -121,8 +121,14 @@ QFileSystemEntry::NativePath QFileSystemEntry::nativeFilePath() const void QFileSystemEntry::resolveFilePath() const { if (m_filePath.isEmpty() && !m_nativeFilePath.isEmpty()) { -#ifdef QFILESYSTEMENTRY_NATIVE_PATH_IS_UTF16 +#if defined(QFILESYSTEMENTRY_NATIVE_PATH_IS_UTF16) m_filePath = QDir::fromNativeSeparators(m_nativeFilePath); +#ifdef Q_OS_WIN + if (m_filePath.startsWith(QLatin1String("//?/UNC/"))) + m_filePath = m_filePath.remove(2,6); + if (m_filePath.startsWith(QLatin1String("//?/"))) + m_filePath = m_filePath.remove(0,4); +#endif #else m_filePath = QDir::fromNativeSeparators(QFile::decodeName(m_nativeFilePath)); #endif diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 2e9d10c..84054d8 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -691,96 +691,27 @@ bool QFSFileEngine::caseSensitive() const bool QFSFileEngine::setCurrentPath(const QString &path) { - int r; - r = QT_CHDIR(QFile::encodeName(path)); - return r >= 0; + return QFileSystemEngine::setCurrentPath(QFileSystemEntry(QDir::fromNativeSeparators(path))); } QString QFSFileEngine::currentPath(const QString &) { - QString result; - QT_STATBUF st; -#if defined(Q_OS_SYMBIAN) - char nativeCurrentName[PATH_MAX+1]; - if (::getcwd(nativeCurrentName, PATH_MAX)) - result = QDir::fromNativeSeparators(QFile::decodeName(QByteArray(nativeCurrentName))); - if (result.isEmpty()) { -# if defined(QT_DEBUG) - qWarning("QFSFileEngine::currentPath: getcwd() failed"); -# endif - } else -#endif - if (QT_STAT(".", &st) == 0) { -#if defined(__GLIBC__) && !defined(PATH_MAX) - char *currentName = ::get_current_dir_name(); - if (currentName) { - result = QFile::decodeName(QByteArray(currentName)); - ::free(currentName); - } -#elif !defined(Q_OS_SYMBIAN) - char currentName[PATH_MAX+1]; - if (::getcwd(currentName, PATH_MAX)) - result = QFile::decodeName(QByteArray(currentName)); -# if defined(QT_DEBUG) - if (result.isNull()) - qWarning("QFSFileEngine::currentPath: getcwd() failed"); -# endif -#endif - } else { -#if defined(Q_OS_SYMBIAN) - // If current dir returned by Open C doesn't exist, - // try to create it (can happen with application private dirs) - // Ignore mkdir failures; we want to be consistent with Open C - // current path regardless. - QT_MKDIR(QFile::encodeName(QLatin1String(nativeCurrentName)), 0777); -#else -# if defined(QT_DEBUG) - qWarning("QFSFileEngine::currentPath: stat(\".\") failed"); -# endif -#endif - } - return result; + return QFileSystemEngine::currentPath().filePath(); } QString QFSFileEngine::homePath() { -#if defined(Q_OS_SYMBIAN) - QString home = QDir::cleanPath(QDir::fromNativeSeparators(qt_TDesC2QString(PathInfo::PhoneMemoryRootPath()))); -#else - QString home = QFile::decodeName(qgetenv("HOME")); - if (home.isNull()) - home = rootPath(); -#endif - return home; + return QFileSystemEngine::homePath(); } QString QFSFileEngine::rootPath() { -#if defined(Q_OS_SYMBIAN) - TChar drive; - TInt err = RFs::DriveToChar(RFs::GetSystemDrive(), drive); //RFs::GetSystemDriveChar not supported on S60 3.1 - Q_ASSERT(err == KErrNone); //RFs::GetSystemDrive() shall always return a convertible drive number on a valid OS configuration - return QString(QChar(drive)).append(QLatin1String(":/")); -#else - return QLatin1String("/"); -#endif + return QFileSystemEngine::rootPath(); } QString QFSFileEngine::tempPath() { -#if defined(Q_OS_SYMBIAN) - TFileName symbianPath = PathInfo::PhoneMemoryRootPath(); - QString temp = QDir::fromNativeSeparators(qt_TDesC2QString(symbianPath)); - temp += QLatin1String( "temp/"); - - // Just to verify that folder really exist on hardware - QT_MKDIR(QFile::encodeName(temp), 0777); -#else - QString temp = QFile::decodeName(qgetenv("TMPDIR")); - if (temp.isEmpty()) - temp = QLatin1String("/tmp/"); -#endif - return temp; + return QFileSystemEngine::tempPath(); } QFileInfoList QFSFileEngine::drives() diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index dde499a..b2009c3 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -544,15 +544,7 @@ bool QFSFileEngine::caseSensitive() const bool QFSFileEngine::setCurrentPath(const QString &path) { - if (!QDir(path).exists()) - return false; - -#if !defined(Q_OS_WINCE) - return ::SetCurrentDirectory((wchar_t*)path.utf16()) != 0; -#else - qfsPrivateCurrentDir = QFSFileEnginePrivate::longFileName(path); - return true; -#endif + return QFileSystemEngine::setCurrentPath(QFileSystemEntry(path)); } QString QFSFileEngine::currentPath(const QString &fileName) @@ -571,29 +563,14 @@ QString QFSFileEngine::currentPath(const QString &fileName) } if (ret.isEmpty()) { //just the pwd - DWORD size = 0; - wchar_t currentName[PATH_MAX]; - size = ::GetCurrentDirectory(PATH_MAX, currentName); - if (size != 0) { - if (size > PATH_MAX) { - wchar_t *newCurrentName = new wchar_t[size]; - if (::GetCurrentDirectory(PATH_MAX, newCurrentName) != 0) - ret = QString::fromWCharArray(newCurrentName); - delete [] newCurrentName; - } else { - ret = QString::fromWCharArray(currentName); - } - } + ret = QFileSystemEngine::currentPath().filePath(); } if (ret.length() >= 2 && ret[1] == QLatin1Char(':')) ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters. - return QDir::fromNativeSeparators(ret); + return ret; #else Q_UNUSED(fileName); - if (qfsPrivateCurrentDir.isEmpty()) - qfsPrivateCurrentDir = QCoreApplication::applicationDirPath(); - - return QDir::fromNativeSeparators(qfsPrivateCurrentDir); + return QFileSystemEngine::currentPath(); #endif } @@ -609,25 +586,7 @@ QString QFSFileEngine::rootPath() QString QFSFileEngine::tempPath() { - QString ret; - { - wchar_t tempPath[MAX_PATH]; - if (GetTempPath(MAX_PATH, tempPath)) - ret = QString::fromWCharArray(tempPath); - if (!ret.isEmpty()) { - while (ret.endsWith(QLatin1Char('\\'))) - ret.chop(1); - ret = QDir::fromNativeSeparators(ret); - } - } - if (ret.isEmpty()) { -#if !defined(Q_OS_WINCE) - ret = QLatin1String("c:/tmp"); -#else - ret = QLatin1String("/Temp"); -#endif - } - return ret; + return QFileSystemEngine::tempPath(); } QFileInfoList QFSFileEngine::drives() diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index ad645e3..d94cf6d 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -71,6 +71,7 @@ # include # include "qeventdispatcher_symbian_p.h" # include "private/qcore_symbian_p.h" +# include "private/qfilesystemengine_p.h" #elif defined(Q_OS_UNIX) # if !defined(QT_NO_GLIB) # include "qeventdispatcher_glib_p.h" @@ -568,6 +569,12 @@ void QCoreApplication::init() Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object"); QCoreApplication::self = this; +#ifdef Q_OS_SYMBIAN + //ensure temp and working directories exist + QFileSystemEngine::createDirectory(QFileSystemEntry(QFileSystemEngine::tempPath()), true); + QFileSystemEngine::createDirectory(QFileSystemEntry(QFileSystemEngine::currentPath()), true); +#endif + #ifndef QT_NO_THREAD QThread::initialize(); #endif -- cgit v0.12 From 883b223c2fc17e313c8a080c14055bba02ae655c Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 17 Sep 2010 18:13:50 +0100 Subject: Make use of new isRelative / isAbsolute functions Reviewed-By: joao --- src/corelib/io/qfilesystemengine_symbian.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index ce2166d..efb3539 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -112,16 +112,17 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) { QString orig = entry.filePath(); - const bool needsDrive = (!orig.isEmpty() && orig.at(0).unicode() == '/'); - const bool isDriveLetter = (orig.size() == 2 && orig.at(1).unicode() == ':'); - const bool isDriveRelative = (orig.size() > 2 && orig.at(1).unicode() == ':' && orig.at(2).unicode() != '/'); + const bool isAbsolute = entry.isAbsolute(); const bool isDirty = (orig.contains(QLatin1String("/../")) || orig.contains(QLatin1String("/./")) || orig.endsWith(QLatin1String("/..")) || orig.endsWith(QLatin1String("/."))); - const bool isAbsolute = !entry.isRelative(); - if (isAbsolute && - !(needsDrive || isDriveLetter || isDriveRelative || isDirty)) + if (isAbsolute && !isDirty) return entry; + const bool isRelative = entry.isRelative(); + const bool needsDrive = (!orig.isEmpty() && orig.at(0).unicode() == '/'); + const bool isDriveLetter = !needsDrive && !isAbsolute && !isRelative && orig.length() == 2; + const bool isDriveRelative = !needsDrive && !isAbsolute && !isRelative && orig.length() > 2; + QString result; if (needsDrive || isDriveLetter || isDriveRelative || !isAbsolute || orig.isEmpty()) { QFileSystemEntry cur(currentPath()); -- cgit v0.12 From 333b30dc2b3c065dec2c84cf9750a526c2636d34 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 17 Sep 2010 18:23:11 +0100 Subject: Remove UNC paths on symbian, it doesn't support UNC Reviewed-By: joao --- src/corelib/io/qfilesystementry.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index 12de135..bc7f121 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -244,7 +244,10 @@ bool QFileSystemEntry::isAbsolute() const resolveFilePath(); return (!m_filePath.isEmpty() && ((m_filePath.length() >= 3 && (m_filePath[0].isLetter() && m_filePath[1].unicode() == ':' && m_filePath[2].unicode() == '/')) - || (m_filePath.length() >= 2 && (m_filePath.at(0) == QLatin1Char('/') && m_filePath.at(1) == QLatin1Char('/'))))); +#ifdef Q_OS_WIN + || (m_filePath.length() >= 2 && (m_filePath.at(0) == QLatin1Char('/') && m_filePath.at(1) == QLatin1Char('/'))) +#endif + )); } #else bool QFileSystemEntry::isRelative() const -- cgit v0.12 From b22bc06f8dac7723026014ba39a108b198f16d66 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Tue, 21 Sep 2010 14:21:07 +0200 Subject: Make QDirIterator cheaper when constructed with a QDir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure we share the pre-calculated entry and avoid resolving the fileEngine if we know its a native FS based file. Reviewed-by: João Abecasis --- qmake/qmake.pri | 1 + src/corelib/io/io.pri | 1 + src/corelib/io/qdir.cpp | 226 +++++++++++++++++----------------------- src/corelib/io/qdir_p.h | 98 +++++++++++++++++ src/corelib/io/qdiriterator.cpp | 39 ++++--- 5 files changed, 216 insertions(+), 149 deletions(-) create mode 100644 src/corelib/io/qdir_p.h diff --git a/qmake/qmake.pri b/qmake/qmake.pri index 1d35183..889338f 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -98,6 +98,7 @@ bootstrap { #Qt code qdatetime.h \ qdatetime_p.h \ qdir.h \ + qdir_p.h \ qdiriterator.h \ qfile.h \ qabstractfileengine.h \ diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 9d209ea..f81ffaf 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -9,6 +9,7 @@ HEADERS += \ io/qdataurl_p.h \ io/qdebug.h \ io/qdir.h \ + io/qdir_p.h \ io/qdiriterator.h \ io/qfile.h \ io/qfileinfo.h \ diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index e65dc11..5c882fd 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -41,6 +41,7 @@ #include "qplatformdefs.h" #include "qdir.h" +#include "qdir_p.h" #include "qabstractfileengine.h" #ifndef QT_NO_DEBUG_STREAM #include "qdebug.h" @@ -85,153 +86,123 @@ static QString driveSpec(const QString &path) } //************* QDirPrivate -class QDirPrivate - : public QSharedData -{ -public: - QDirPrivate(const QString &path, - const QStringList &nameFilters_ = QStringList(), - QDir::SortFlags sort_ = QDir::SortFlags(QDir::Name | QDir::IgnoreCase), - QDir::Filters filters_ = QDir::AllEntries) - : QSharedData() - , nameFilters(nameFilters_) - , sort(sort_) - , filters(filters_) +QDirPrivate::QDirPrivate(const QString &path, const QStringList &nameFilters_, QDir::SortFlags sort_, QDir::Filters filters_) + : QSharedData() + , nameFilters(nameFilters_) + , sort(sort_) + , filters(filters_) #ifdef QT3_SUPPORT - , filterSepChar(0) - , matchAllDirs(false) + , filterSepChar(0) + , matchAllDirs(false) #endif - , fileListsInitialized(false) - { - setPath(path.isEmpty() ? QString::fromLatin1(".") : path); - - bool empty = nameFilters.isEmpty(); - if (!empty) { - empty = true; - for (int i = 0; i < nameFilters.size(); ++i) { - if (!nameFilters.at(i).isEmpty()) { - empty = false; - break; - } + , fileListsInitialized(false) +{ + setPath(path.isEmpty() ? QString::fromLatin1(".") : path); + + bool empty = nameFilters.isEmpty(); + if (!empty) { + empty = true; + for (int i = 0; i < nameFilters.size(); ++i) { + if (!nameFilters.at(i).isEmpty()) { + empty = false; + break; } } - if (empty) - nameFilters = QStringList(QString::fromLatin1("*")); } + if (empty) + nameFilters = QStringList(QString::fromLatin1("*")); +} - QDirPrivate(const QDirPrivate ©) - : QSharedData(copy) - , nameFilters(copy.nameFilters) - , sort(copy.sort) - , filters(copy.filters) +QDirPrivate::QDirPrivate(const QDirPrivate ©) + : QSharedData(copy) + , nameFilters(copy.nameFilters) + , sort(copy.sort) + , filters(copy.filters) #ifdef QT3_SUPPORT - , filterSepChar(copy.filterSepChar) - , matchAllDirs(copy.matchAllDirs) + , filterSepChar(copy.filterSepChar) + , matchAllDirs(copy.matchAllDirs) #endif - , fileListsInitialized(false) - , dirEntry(copy.dirEntry) - , metaData(copy.metaData) - { - } + , fileListsInitialized(false) + , dirEntry(copy.dirEntry) + , metaData(copy.metaData) +{ +} - bool exists() const - { - if (fileEngine.isNull()) { - if (!metaData.hasFlags(QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType)) - QFileSystemEngine::fillMetaData(dirEntry, metaData, - QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); - return metaData.exists() && metaData.isDirectory(); - } - const QAbstractFileEngine::FileFlags info = - fileEngine->fileFlags(QAbstractFileEngine::DirectoryType - | QAbstractFileEngine::ExistsFlag - | QAbstractFileEngine::Refresh); - if (!(info & QAbstractFileEngine::DirectoryType)) - return false; - return info & QAbstractFileEngine::ExistsFlag; +bool QDirPrivate::exists() const +{ + if (fileEngine.isNull()) { + if (!metaData.hasFlags(QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType)) + QFileSystemEngine::fillMetaData(dirEntry, metaData, + QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); + return metaData.exists() && metaData.isDirectory(); } + const QAbstractFileEngine::FileFlags info = + fileEngine->fileFlags(QAbstractFileEngine::DirectoryType + | QAbstractFileEngine::ExistsFlag + | QAbstractFileEngine::Refresh); + if (!(info & QAbstractFileEngine::DirectoryType)) + return false; + return info & QAbstractFileEngine::ExistsFlag; +} - void initFileEngine(); - void initFileLists(const QDir &dir) const; - - static void sortFileList(QDir::SortFlags, QFileInfoList &, QStringList *, QFileInfoList *); - - static inline QChar getFilterSepChar(const QString &nameFilter) - { - QChar sep(QLatin1Char(';')); - int i = nameFilter.indexOf(sep, 0); - if (i == -1 && nameFilter.indexOf(QLatin1Char(' '), 0) != -1) - sep = QChar(QLatin1Char(' ')); - return sep; - } +// static +inline QChar QDirPrivate::getFilterSepChar(const QString &nameFilter) +{ + QChar sep(QLatin1Char(';')); + int i = nameFilter.indexOf(sep, 0); + if (i == -1 && nameFilter.indexOf(QLatin1Char(' '), 0) != -1) + sep = QChar(QLatin1Char(' ')); + return sep; +} - static inline QStringList splitFilters(const QString &nameFilter, QChar sep = 0) - { - if (sep == 0) - sep = getFilterSepChar(nameFilter); - QStringList ret = nameFilter.split(sep); - for (int i = 0; i < ret.count(); ++i) - ret[i] = ret[i].trimmed(); - return ret; - } +// static +inline QStringList QDirPrivate::splitFilters(const QString &nameFilter, QChar sep) +{ + if (sep == 0) + sep = getFilterSepChar(nameFilter); + QStringList ret = nameFilter.split(sep); + for (int i = 0; i < ret.count(); ++i) + ret[i] = ret[i].trimmed(); + return ret; +} - inline void setPath(const QString &path) - { - QString p = QDir::fromNativeSeparators(path); - if (p.endsWith(QLatin1Char('/')) - && p.length() > 1 +inline void QDirPrivate::setPath(const QString &path) +{ + QString p = QDir::fromNativeSeparators(path); + if (p.endsWith(QLatin1Char('/')) + && p.length() > 1 #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) - && (!(p.length() == 3 && p.at(1).unicode() == ':' && p.at(0).isLetter())) + && (!(p.length() == 3 && p.at(1).unicode() == ':' && p.at(0).isLetter())) #endif - ) { - p.truncate(p.length() - 1); - } - - dirEntry = QFileSystemEntry(p); - initFileEngine(); - clearFileLists(); - absoluteDirEntry = QFileSystemEntry(); + ) { + p.truncate(p.length() - 1); } - inline void clearFileLists() - { - fileListsInitialized = false; - files.clear(); - fileInfos.clear(); - } - - inline void resolveAbsoluteEntry() const - { - if (!absoluteDirEntry.isEmpty() || dirEntry.isEmpty()) - return; - - if (dirEntry.isRelative()) { - QFileSystemEntry answer = QFileSystemEngine::absoluteName(dirEntry); - absoluteDirEntry = QFileSystemEntry(QDir::cleanPath(answer.filePath())); - } else { - absoluteDirEntry = dirEntry; - } - } - - QStringList nameFilters; - QDir::SortFlags sort; - QDir::Filters filters; - -#ifdef QT3_SUPPORT - QChar filterSepChar; - bool matchAllDirs; -#endif + dirEntry = QFileSystemEntry(p); + initFileEngine(); + clearFileLists(); + absoluteDirEntry = QFileSystemEntry(); +} - QScopedPointer fileEngine; +inline void QDirPrivate::clearFileLists() +{ + fileListsInitialized = false; + files.clear(); + fileInfos.clear(); +} - mutable bool fileListsInitialized; - mutable QStringList files; - mutable QFileInfoList fileInfos; +inline void QDirPrivate::resolveAbsoluteEntry() const +{ + if (!absoluteDirEntry.isEmpty() || dirEntry.isEmpty()) + return; - QFileSystemEntry dirEntry; - mutable QFileSystemEntry absoluteDirEntry; - mutable QFileSystemMetaData metaData; -}; + if (dirEntry.isRelative()) { + QFileSystemEntry answer = QFileSystemEngine::absoluteName(dirEntry); + absoluteDirEntry = QFileSystemEntry(QDir::cleanPath(answer.filePath())); + } else { + absoluteDirEntry = dirEntry; + } +} /* For sorting */ struct QDirSortItem @@ -343,7 +314,6 @@ inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l, } } } - inline void QDirPrivate::initFileLists(const QDir &dir) const { if (!fileListsInitialized) { diff --git a/src/corelib/io/qdir_p.h b/src/corelib/io/qdir_p.h new file mode 100644 index 0000000..5f97c1f --- /dev/null +++ b/src/corelib/io/qdir_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef QDIR_PRIVATE_H +#define QDIR_PRIVATE_H + +#include "qfilesystementry_p.h" +#include "qfilesystemmetadata_p.h" + +QT_BEGIN_NAMESPACE + +class QDirPrivate : public QSharedData +{ +public: + QDirPrivate(const QString &path, const QStringList &nameFilters_ = QStringList(), + QDir::SortFlags sort_ = QDir::SortFlags(QDir::Name | QDir::IgnoreCase), + QDir::Filters filters_ = QDir::AllEntries); + + QDirPrivate(const QDirPrivate ©); + + bool exists() const; + + void initFileEngine(); + void initFileLists(const QDir &dir) const; + + static void sortFileList(QDir::SortFlags, QFileInfoList &, QStringList *, QFileInfoList *); + + static inline QChar getFilterSepChar(const QString &nameFilter); + + static inline QStringList splitFilters(const QString &nameFilter, QChar sep = 0); + + inline void setPath(const QString &path); + + inline void clearFileLists(); + + inline void resolveAbsoluteEntry() const; + + QStringList nameFilters; + QDir::SortFlags sort; + QDir::Filters filters; + +#ifdef QT3_SUPPORT + QChar filterSepChar; + bool matchAllDirs; +#endif + + QScopedPointer fileEngine; + + mutable bool fileListsInitialized; + mutable QStringList files; + mutable QFileInfoList fileInfos; + + QFileSystemEntry dirEntry; + mutable QFileSystemEntry absoluteDirEntry; + mutable QFileSystemMetaData metaData; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 582fb85..a8192ea 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -90,6 +90,7 @@ */ #include "qdiriterator.h" +#include "qdir_p.h" #include "qabstractfileengine.h" @@ -119,8 +120,8 @@ public: class QDirIteratorPrivate { public: - QDirIteratorPrivate(const QString &path, const QStringList &nameFilters, - QDir::Filters filters, QDirIterator::IteratorFlags flags); + QDirIteratorPrivate(const QFileSystemEntry &entry, const QStringList &nameFilters, + QDir::Filters filters, QDirIterator::IteratorFlags flags, bool resolveEngine = true); void advance(); @@ -131,7 +132,7 @@ public: QScopedPointer engine; - const QString path; + QFileSystemEntry dirEntry; const QStringList nameFilters; const QDir::Filters filters; const QDirIterator::IteratorFlags iteratorFlags; @@ -153,9 +154,9 @@ public: /*! \internal */ -QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList &nameFilters, - QDir::Filters filters, QDirIterator::IteratorFlags flags) - : path(path) +QDirIteratorPrivate::QDirIteratorPrivate(const QFileSystemEntry &entry, const QStringList &nameFilters, + QDir::Filters filters, QDirIterator::IteratorFlags flags, bool resolveEngine) + : dirEntry(entry) , nameFilters(nameFilters.contains(QLatin1String("*")) ? QStringList() : nameFilters) , filters(QDir::NoFilter == filters ? QDir::AllEntries : filters) , iteratorFlags(flags) @@ -168,17 +169,10 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList (filters & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::Wildcard)); #endif - -#ifdef Q_OS_UNIX - QFileSystemEntry fileEntry(path); QFileSystemMetaData metaData; - - engine.reset(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)); - QFileInfo fileInfo(new QFileInfoPrivate(fileEntry, metaData)); -#else - engine.reset(QAbstractFileEngine::create(path)); - QFileInfo fileInfo(path); -#endif + if (resolveEngine) + engine.reset(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(dirEntry, metaData)); + QFileInfo fileInfo(new QFileInfoPrivate(dirEntry, metaData)); // Populate fields for hasNext() and next() pushDirectory(fileInfo); @@ -411,8 +405,11 @@ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInf \sa hasNext(), next(), IteratorFlags */ QDirIterator::QDirIterator(const QDir &dir, IteratorFlags flags) - : d(new QDirIteratorPrivate(dir.path(), dir.nameFilters(), dir.filter(), flags)) { + // little trick to get hold of the QDirPrivate while there is no API on QDir to give it to us + class MyQDir : public QDir { public: const QDirPrivate *priv() const { return d_ptr.constData(); } }; + const QDirPrivate *other = static_cast(&dir)->priv(); + d.reset(new QDirIteratorPrivate(other->dirEntry, other->nameFilters, other->filters, flags, !other->fileEngine.isNull())); } /*! @@ -432,7 +429,7 @@ QDirIterator::QDirIterator(const QDir &dir, IteratorFlags flags) \sa hasNext(), next(), IteratorFlags */ QDirIterator::QDirIterator(const QString &path, QDir::Filters filters, IteratorFlags flags) - : d(new QDirIteratorPrivate(path, QStringList(), filters, flags)) + : d(new QDirIteratorPrivate(QFileSystemEntry(path), QStringList(), filters, flags)) { } @@ -449,7 +446,7 @@ QDirIterator::QDirIterator(const QString &path, QDir::Filters filters, IteratorF \sa hasNext(), next(), IteratorFlags */ QDirIterator::QDirIterator(const QString &path, IteratorFlags flags) - : d(new QDirIteratorPrivate(path, QStringList(), QDir::NoFilter, flags)) + : d(new QDirIteratorPrivate(QFileSystemEntry(path), QStringList(), QDir::NoFilter, flags)) { } @@ -471,7 +468,7 @@ QDirIterator::QDirIterator(const QString &path, IteratorFlags flags) */ QDirIterator::QDirIterator(const QString &path, const QStringList &nameFilters, QDir::Filters filters, IteratorFlags flags) - : d(new QDirIteratorPrivate(path, nameFilters, filters, flags)) + : d(new QDirIteratorPrivate(QFileSystemEntry(path), nameFilters, filters, flags)) { } @@ -552,7 +549,7 @@ QFileInfo QDirIterator::fileInfo() const */ QString QDirIterator::path() const { - return d->path; + return d->dirEntry.filePath(); } QT_END_NAMESPACE -- cgit v0.12 From 49d5e73b52a8830f88041f0c1e726133e791f999 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 22 Sep 2010 11:32:15 +0200 Subject: Fix regression in QDir::cd() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On changing path we always have to clear the metadata as thats from the old directory and we need to re-stat for the new data. Reviewed-by: João Abecasis --- src/corelib/io/qdir.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 5c882fd..c7cf87f 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -179,6 +179,7 @@ inline void QDirPrivate::setPath(const QString &path) } dirEntry = QFileSystemEntry(p); + metaData.clear(); initFileEngine(); clearFileLists(); absoluteDirEntry = QFileSystemEntry(); -- cgit v0.12 From c798fc3bf3ed8551185d0914f25dc7ed6fd123dd Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 22 Sep 2010 12:45:32 +0200 Subject: Fix QDirIterator on Windows XP. The find option "FindExInfoBasic" which queries only the long file nmae is available only on Windows 7 and above. All other version have to use the "FindExInfoStandard" option which queries both short and long file names. Reviewed-by: Joao --- src/corelib/io/qfilesystemiterator_win.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 373a50a..4050199 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -85,17 +85,15 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa if (findFileHandle == INVALID_HANDLE_VALUE && !uncFallback) { haveData = true; + int infoLevel = 0 ; // FindExInfoStandard; DWORD dwAdditionalFlags = 0; - if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) + if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) { dwAdditionalFlags = 2; // FIND_FIRST_EX_LARGE_FETCH + infoLevel = 1 ; // FindExInfoBasic; + } int searchOps = 0; // FindExSearchNameMatch if (onlyDirs) searchOps = 1 ; // FindExSearchLimitToDirectories -#if !defined(Q_OS_WINCE) - int infoLevel = 1 ; // FindExInfoBasic; -#else - int infoLevel = 0; // FindExInfoStandard; -#endif findFileHandle = FindFirstFileEx((const wchar_t *)nativePath.utf16(), FINDEX_INFO_LEVELS(infoLevel), &findData, FINDEX_SEARCH_OPS(searchOps), 0, dwAdditionalFlags); if (findFileHandle == INVALID_HANDLE_VALUE) { -- cgit v0.12 From 9f2aee2a22d5a7c53480cc6c5794293bfe04cf8c Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 22 Sep 2010 13:14:16 +0200 Subject: Remove warnings --- src/corelib/io/qfilesystemengine_unix.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 8724b15..0672490 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -102,6 +102,7 @@ static inline bool _q_isMacHidden(const char *nativePath) #else static inline bool _q_isMacHidden(const char *nativePath) { + Q_UNUSED(nativePath); // no-op return false; } @@ -294,6 +295,8 @@ QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) return QCFString::toQString((CFStringRef)name); } } +#else + Q_UNUSED(entry); #endif return QString(); } -- cgit v0.12 From db9fb7195155f4ec929ae4ac73c5c5d4422e5aa6 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 22 Sep 2010 14:00:55 +0200 Subject: Implement unix permissions setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemengine_unix.cpp | 29 +++++++++++++++++- src/corelib/io/qfsfileengine_unix.cpp | 49 +++++-------------------------- 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 0672490..e85eb00 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -43,6 +43,7 @@ #include "qfilesystemengine_p.h" #include "qplatformdefs.h" #include "qfsfileengine.h" +#include "qfile.h" #include // for realpath() #include @@ -548,7 +549,33 @@ bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry) //static bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QFileSystemMetaData *data) { - return false; // TODO implement; + mode_t mode = 0; + if (permissions & QFile::ReadOwner) + mode |= S_IRUSR; + if (permissions & QFile::WriteOwner) + mode |= S_IWUSR; + if (permissions & QFile::ExeOwner) + mode |= S_IXUSR; + if (permissions & QFile::ReadUser) + mode |= S_IRUSR; + if (permissions & QFile::WriteUser) + mode |= S_IWUSR; + if (permissions & QFile::ExeUser) + mode |= S_IXUSR; + if (permissions & QFile::ReadGroup) + mode |= S_IRGRP; + if (permissions & QFile::WriteGroup) + mode |= S_IWGRP; + if (permissions & QFile::ExeGroup) + mode |= S_IXGRP; + if (permissions & QFile::ReadOther) + mode |= S_IROTH; + if (permissions & QFile::WriteOther) + mode |= S_IWOTH; + if (permissions & QFile::ExeOther) + mode |= S_IXOTH; + + return ::chmod(entry.nativeFilePath().constData(), mode) == 0; } QString QFileSystemEngine::homePath() diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 84054d8..7b7cd7f 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -938,18 +938,23 @@ QString QFSFileEngine::owner(FileOwner own) const return QString(); } -#ifdef Q_OS_SYMBIAN bool QFSFileEngine::setPermissions(uint perms) { Q_D(QFSFileEngine); - //TODO: connect up error reporting properly if (!QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), 0)) { - setError(QFile::PermissionsError, QString()); + setError(QFile::PermissionsError, +#ifdef Q_OS_SYMBIAN + //TODO: connect up error reporting properly + QString()); +#else + qt_error_string(errno)); +#endif return false; } return true; } +#ifdef Q_OS_SYMBIAN bool QFSFileEngine::setSize(qint64 size) { Q_D(QFSFileEngine); @@ -983,44 +988,6 @@ bool QFSFileEngine::setSize(qint64 size) return ret; } #else -bool QFSFileEngine::setPermissions(uint perms) -{ - Q_D(QFSFileEngine); - bool ret = false; - mode_t mode = 0; - if (perms & ReadOwnerPerm) - mode |= S_IRUSR; - if (perms & WriteOwnerPerm) - mode |= S_IWUSR; - if (perms & ExeOwnerPerm) - mode |= S_IXUSR; - if (perms & ReadUserPerm) - mode |= S_IRUSR; - if (perms & WriteUserPerm) - mode |= S_IWUSR; - if (perms & ExeUserPerm) - mode |= S_IXUSR; - if (perms & ReadGroupPerm) - mode |= S_IRGRP; - if (perms & WriteGroupPerm) - mode |= S_IWGRP; - if (perms & ExeGroupPerm) - mode |= S_IXGRP; - if (perms & ReadOtherPerm) - mode |= S_IROTH; - if (perms & WriteOtherPerm) - mode |= S_IWOTH; - if (perms & ExeOtherPerm) - mode |= S_IXOTH; - if (d->fd != -1) - ret = fchmod(d->fd, mode) == 0; - else - ret = ::chmod(d->fileEntry.nativeFilePath().constData(), mode) == 0; - if (!ret) - setError(QFile::PermissionsError, qt_error_string(errno)); - return ret; -} - bool QFSFileEngine::setSize(qint64 size) { Q_D(QFSFileEngine); -- cgit v0.12 From 43866e6a2709c8098de0dfb0e51177042f046c52 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 22 Sep 2010 15:16:02 +0200 Subject: Test 'QDir::cd' a bit better --- tests/auto/qdir/tst_qdir.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 554b685..2bb0a3e 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -937,6 +937,7 @@ void tst_QDir::cd() QFETCH(QString, newDir); QDir d = startDir; + bool notUsed = d.exists(); // make sure we cache this before so we can see if 'cd' fails to flush this QCOMPARE(d.cd(cdDir), successExpected); if (successExpected) QCOMPARE(d.absolutePath(), newDir); -- cgit v0.12 From ecd4dfd5edef036a87ecd354f21d81f3f0a40f0e Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 22 Sep 2010 17:47:38 +0200 Subject: Fix QDir autotests on Windows The QFileSystemMetaData is reused when enumerating directories. Clear this content before filling it with the WIN32_FIND_DATA. Reviewed-by: Joao --- src/corelib/io/qfilesystemiterator_win.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 4050199..0be6413 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -130,6 +130,7 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa QString fileName = QString::fromWCharArray(findData.cFileName); fileEntry = QFileSystemEntry(dirPath + fileName); if (!fileName.endsWith(QLatin1String(".lnk"))) { + metaData = QFileSystemMetaData(); metaData.fillFromFindData(findData, true); } return true; -- cgit v0.12 From 584416b0d95063b761c6b81dbeaae325818dd9af Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 22 Sep 2010 17:47:38 +0200 Subject: Fix QDir autotests on Windows The QFileSystemMetaData is reused when enumerating directories. Clear this content before filling it with the WIN32_FIND_DATA. Reviewed-by: Joao --- src/corelib/io/qfilesystemiterator_win.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 0be6413..5fc64e4 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -129,6 +129,7 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa } else { QString fileName = QString::fromWCharArray(findData.cFileName); fileEntry = QFileSystemEntry(dirPath + fileName); + metaData = QFileSystemMetaData(); if (!fileName.endsWith(QLatin1String(".lnk"))) { metaData = QFileSystemMetaData(); metaData.fillFromFindData(findData, true); -- cgit v0.12 From 0ad8e783a9a60c8a77ceb2648f54cdba79c328c5 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 22 Sep 2010 17:58:11 +0200 Subject: Remove an extra initialization Reviewed-by: Joao --- src/corelib/io/qfilesystemiterator_win.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 5fc64e4..62912a6 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -131,7 +131,6 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa fileEntry = QFileSystemEntry(dirPath + fileName); metaData = QFileSystemMetaData(); if (!fileName.endsWith(QLatin1String(".lnk"))) { - metaData = QFileSystemMetaData(); metaData.fillFromFindData(findData, true); } return true; -- cgit v0.12 From d7df693b54337ea5050391751ae3243cee2f9159 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Thu, 23 Sep 2010 10:05:33 +0200 Subject: Force uppercase for drive letters in QDir::currentPath() on Windows. This was done previously for helping file dialogs and other UI elements using the path. So we need to retain this old behavior. Reviewed-by: Joao --- src/corelib/io/qfilesystemengine_win.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index cef7236..1aba4a7 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1154,6 +1154,8 @@ QFileSystemEntry QFileSystemEngine::currentPath() ret = QString::fromWCharArray(currentName, size); } } + if (ret.length() >= 2 && ret[1] == QLatin1Char(':')) + ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters. #else Q_UNUSED(fileName); //TODO - a race condition exists when using currentPath / setCurrentPath from multiple threads -- cgit v0.12 From 52090d6e292c165bfb08140c28068b796e295b10 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Thu, 23 Sep 2010 11:14:01 +0200 Subject: Make setPermissions update meta MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in the unix QFileSystemEngine::setPermissions we now update the QFileSystemMetaData instance passed in on success, to avoid another stat later. Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemengine_unix.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index e85eb00..060cf25 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -575,7 +575,13 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per if (permissions & QFile::ExeOther) mode |= S_IXOTH; - return ::chmod(entry.nativeFilePath().constData(), mode) == 0; + bool success = ::chmod(entry.nativeFilePath().constData(), mode) == 0; + if (success && data) { + data->entryFlags &= ~QFileSystemMetaData::Permissions; + data->entryFlags |= QFileSystemMetaData::MetaDataFlag(uint(permissions)); + data->knownFlagsMask |= QFileSystemMetaData::Permissions; + } + return success; } QString QFileSystemEngine::homePath() -- cgit v0.12 From 59491b5cb9c7dc54f701ba19185fede58a7355db Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Thu, 23 Sep 2010 11:33:38 +0200 Subject: Mark the QFileSystemEngine::copyFile/unix done. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no native implementation for this (the old FSFilesystemEngine never had one either) so no code to move. Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemengine_unix.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 060cf25..c17d4c7 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -531,7 +531,10 @@ bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSy //static bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target) { - return false; // TODO implement; + Q_UNUSED(source); + Q_UNUSED(target); + // # we can implement this using sendfile(2) + return false; } //static -- cgit v0.12 From 2645784f05db7b1e631621c511e94c88fc5cd211 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Thu, 23 Sep 2010 16:10:46 +0200 Subject: Move resolving names to qfilesystemengine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve username and group names code is now in the QFileSystemEngine Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemengine_unix.cpp | 53 +++++++++++++++++++++++++++++-- src/corelib/io/qfsfileengine_unix.cpp | 47 ++------------------------- 2 files changed, 54 insertions(+), 46 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index c17d4c7..1dee09b 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -45,6 +45,8 @@ #include "qfsfileengine.h" #include "qfile.h" +#include + #include // for realpath() #include #include @@ -275,13 +277,60 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) //static QString QFileSystemEngine::resolveUserName(uint userId) { - return QString(); // TODO +#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) + int size_max = sysconf(_SC_GETPW_R_SIZE_MAX); + if (size_max == -1) + size_max = 1024; + QVarLengthArray buf(size_max); +#endif + + struct passwd *pw = 0; +#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) + struct passwd entry; + getpwuid_r(userId, &entry, buf.data(), buf.size(), &pw); +#else + pw = getpwuid(userId); +#endif + if (pw) + return QFile::decodeName(QByteArray(pw->pw_name)); + return QString(); } //static QString QFileSystemEngine::resolveGroupName(uint groupId) { - return QString(); // TODO +#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) + int size_max = sysconf(_SC_GETPW_R_SIZE_MAX); + if (size_max == -1) + size_max = 1024; + QVarLengthArray buf(size_max); +#endif + +#if !defined(Q_OS_SYMBIAN) + struct group *gr = 0; +#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) + size_max = sysconf(_SC_GETGR_R_SIZE_MAX); + if (size_max == -1) + size_max = 1024; + buf.resize(size_max); + struct group entry; + // Some large systems have more members than the POSIX max size + // Loop over by doubling the buffer size (upper limit 250k) + for (unsigned size = size_max; size < 256000; size += size) + { + buf.resize(size); + // ERANGE indicates that the buffer was too small + if (!getgrgid_r(groupId, &entry, buf.data(), buf.size(), &gr) + || errno != ERANGE) + break; + } +#else + gr = getgrgid(groupId); +#endif + if (gr) + return QFile::decodeName(QByteArray(gr->gr_name)); +#endif + return QString(); } //static diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 7b7cd7f..0845cb3 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -892,50 +892,9 @@ uint QFSFileEngine::ownerId(FileOwner own) const QString QFSFileEngine::owner(FileOwner own) const { -#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) - int size_max = sysconf(_SC_GETPW_R_SIZE_MAX); - if (size_max == -1) - size_max = 1024; - QVarLengthArray buf(size_max); -#endif - - if (own == OwnerUser) { - struct passwd *pw = 0; -#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) - struct passwd entry; - getpwuid_r(ownerId(own), &entry, buf.data(), buf.size(), &pw); -#else - pw = getpwuid(ownerId(own)); -#endif - if (pw) - return QFile::decodeName(QByteArray(pw->pw_name)); - } else if (own == OwnerGroup) { -#if !defined(Q_OS_SYMBIAN) - struct group *gr = 0; -#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) - size_max = sysconf(_SC_GETGR_R_SIZE_MAX); - if (size_max == -1) - size_max = 1024; - buf.resize(size_max); - struct group entry; - // Some large systems have more members than the POSIX max size - // Loop over by doubling the buffer size (upper limit 250k) - for (unsigned size = size_max; size < 256000; size += size) - { - buf.resize(size); - // ERANGE indicates that the buffer was too small - if (!getgrgid_r(ownerId(own), &entry, buf.data(), buf.size(), &gr) - || errno != ERANGE) - break; - } -#else - gr = getgrgid(ownerId(own)); -#endif - if (gr) - return QFile::decodeName(QByteArray(gr->gr_name)); -#endif - } - return QString(); + if (own == OwnerUser) + return QFileSystemEngine::resolveUserName(ownerId(own)); + return QFileSystemEngine::resolveGroupName(ownerId(own)); } bool QFSFileEngine::setPermissions(uint perms) -- cgit v0.12 From 838ed9c68aef4d5a4f0b4d4dbbc1c1f7797cde91 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 29 Sep 2010 12:05:50 +0200 Subject: Compile fixes for windows --- qmake/Makefile.win32 | 1 - src/corelib/io/qfilesystemengine_win.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 9b86215..4333d45 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -89,7 +89,6 @@ QTOBJS= \ qabstractfileengine.obj \ qfsfileengine_win.obj \ qsystemlibrary.obj \ - qfsfileengine_iterator_win.obj \ qfileinfo.obj \ qglobal.obj \ qhash.obj \ diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 8fd0919..b164044 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -45,7 +45,7 @@ #include "qplatformdefs.h" #include "qabstractfileengine.h" #include "private/qfsfileengine_p.h" -#include "qfilesystemengine_p.h" +#include #include #include "qfile.h" -- cgit v0.12 From 71f04c22f128a52353f0a53d6d118375c0e99e33 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Thu, 7 Oct 2010 12:50:21 +0200 Subject: Compile fixes for mingw --- qmake/Makefile.win32-g++-sh | 4 +++ src/corelib/io/qfilesystemengine_win.cpp | 53 ------------------------------ src/corelib/io/qfilesystemiterator_win.cpp | 4 +-- src/corelib/io/qfilesystemmetadata_p.h | 53 ++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 55 deletions(-) diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index 97be5b5..2530fe8 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -62,6 +62,7 @@ QTOBJS= \ qfileinfo.o \ qabstractfileengine.o \ qfilesystementry.o \ + qfilesystemengine.o \ qfilesystemengine_win.o \ qfilesystemiterator_win.o \ qfsfileengine.o \ @@ -197,6 +198,9 @@ qabstractfileengine.o: $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp +qfilesystemengine.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp + qfilesystemengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index b164044..1f7a9b9 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -421,59 +421,6 @@ bool QFileSystemEngine::uncListSharesOnServer(const QString &server, QStringList return false; } -void QFileSystemMetaData::fillFromFileAttribute(DWORD fileAttribute,bool isDriveRoot) -{ - fileAttribute_ = fileAttribute; - // Ignore the hidden attribute for drives. - if (!isDriveRoot && (fileAttribute_ & FILE_ATTRIBUTE_HIDDEN)) - entryFlags |= HiddenAttribute; - entryFlags |= ((fileAttribute & FILE_ATTRIBUTE_DIRECTORY) ? DirectoryType: FileType); - entryFlags |= ExistsAttribute; - knownFlagsMask |= FileType | DirectoryType | HiddenAttribute | ExistsAttribute; -} - -void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType, bool isDriveRoot) -{ - fillFromFileAttribute(findData.dwFileAttributes, isDriveRoot); - creationTime_ = findData.ftCreationTime; - lastAccessTime_ = findData.ftLastAccessTime; - lastWriteTime_ = findData.ftLastWriteTime; - if (fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY) { - size_ = 0; - } else { - size_ = findData.nFileSizeHigh; - size_ <<= 32; - size_ += findData.nFileSizeLow; - } - knownFlagsMask |= Times | SizeAttribute; - if (setLinkType) { - knownFlagsMask |= LinkType; - entryFlags &= ~LinkType; - if ((fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT) - && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK - || findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) { - entryFlags |= LinkType; - } - - } -} - -void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo) -{ - fillFromFileAttribute(fileInfo.dwFileAttributes); - creationTime_ = fileInfo.ftCreationTime; - lastAccessTime_ = fileInfo.ftLastAccessTime; - lastWriteTime_ = fileInfo.ftLastWriteTime; - if (fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY) { - size_ = 0; - } else { - size_ = fileInfo.nFileSizeHigh; - size_ <<= 32; - size_ += fileInfo.nFileSizeLow; - } - knownFlagsMask |= Times | SizeAttribute; -} - void QFileSystemEngine::clearWinStatData(QFileSystemMetaData &data) { data.size_ = 0; diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 62912a6..9181789 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -66,8 +66,8 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi if (!nativePath.endsWith(QLatin1Char('\\'))) nativePath.append(QLatin1Char('\\')); nativePath.append(QLatin1Char('*')); - if (!dirPath.endsWith(QLatin1Char('//'))) - dirPath.append(QLatin1Char('//')); + if (!dirPath.endsWith(QLatin1Char('/'))) + dirPath.append(QLatin1Char('/')); if ((filters & (QDir::Dirs|QDir::Drives)) && (!(filters & (QDir::Files)))) onlyDirs = true; } diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 29ef987..24dfe6b 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -336,6 +336,59 @@ inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) c else return groupId(); } + +inline void QFileSystemMetaData::fillFromFileAttribute(DWORD fileAttribute,bool isDriveRoot) +{ + fileAttribute_ = fileAttribute; + // Ignore the hidden attribute for drives. + if (!isDriveRoot && (fileAttribute_ & FILE_ATTRIBUTE_HIDDEN)) + entryFlags |= HiddenAttribute; + entryFlags |= ((fileAttribute & FILE_ATTRIBUTE_DIRECTORY) ? DirectoryType: FileType); + entryFlags |= ExistsAttribute; + knownFlagsMask |= FileType | DirectoryType | HiddenAttribute | ExistsAttribute; +} + +inline void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType, bool isDriveRoot) +{ + fillFromFileAttribute(findData.dwFileAttributes, isDriveRoot); + creationTime_ = findData.ftCreationTime; + lastAccessTime_ = findData.ftLastAccessTime; + lastWriteTime_ = findData.ftLastWriteTime; + if (fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY) { + size_ = 0; + } else { + size_ = findData.nFileSizeHigh; + size_ <<= 32; + size_ += findData.nFileSizeLow; + } + knownFlagsMask |= Times | SizeAttribute; + if (setLinkType) { + knownFlagsMask |= LinkType; + entryFlags &= ~LinkType; + if ((fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT) + && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK + || findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) { + entryFlags |= LinkType; + } + + } +} + +inline void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo) +{ + fillFromFileAttribute(fileInfo.dwFileAttributes); + creationTime_ = fileInfo.ftCreationTime; + lastAccessTime_ = fileInfo.ftLastAccessTime; + lastWriteTime_ = fileInfo.ftLastWriteTime; + if (fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY) { + size_ = 0; + } else { + size_ = fileInfo.nFileSizeHigh; + size_ <<= 32; + size_ += fileInfo.nFileSizeLow; + } + knownFlagsMask |= Times | SizeAttribute; +} #endif QT_END_NAMESPACE -- cgit v0.12 From b7bc57cca9e34d3622afc1c1a9ff322024f350df Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 4 Oct 2010 13:22:25 +0100 Subject: Implement error reporting for file APIs Part of the refactoring broke error reporting (false would be return on failure, but the QFile::error() would not return the right thing) A string is passed to the QFileSystemEngine functions which need to return an error, and filled in via the error code when a function fails. For windows, this is GetLastError() as for the previous workaround For unix, this is errno, as for the previous workaround For symbian, this is the integer error code returned by the function Reviewed-By: Thomas Zander Reviewed-By: Prasanth Ullattil --- src/corelib/io/qfilesystemengine_p.h | 13 ++- src/corelib/io/qfilesystemengine_symbian.cpp | 92 +++++++++++++++-- src/corelib/io/qfilesystemengine_unix.cpp | 29 ++++-- src/corelib/io/qfilesystemengine_win.cpp | 22 ++-- src/corelib/io/qfsfileengine_unix.cpp | 55 +++------- src/corelib/io/qfsfileengine_win.cpp | 20 ++-- src/s60installs/bwins/QtCoreu.def | 51 ++++++++- src/s60installs/bwins/QtDeclarativeu.def | 137 ++----------------------- src/s60installs/bwins/QtGuiu.def | 1 - src/s60installs/eabi/QtCoreu.def | 1 - src/s60installs/eabi/QtDeclarativeu.def | 148 ++------------------------- src/s60installs/eabi/QtGuiu.def | 1 - 12 files changed, 214 insertions(+), 356 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 20b664d..f4d942a 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -91,6 +91,9 @@ public: static QString owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own); static QString nativeAbsoluteFilePath(const QString &path); #endif +#ifdef Q_OS_SYMBIAN + static QString errorString(int errorcode); +#endif //homePath, rootPath and tempPath shall return clean paths static QString homePath(); static QString rootPath(); @@ -99,13 +102,13 @@ public: static bool createDirectory(const QFileSystemEntry &entry, bool createParents); static bool removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents); - static bool createLink(const QFileSystemEntry &source, const QFileSystemEntry &target); + static bool createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString); - static bool copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target); - static bool renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target); - static bool removeFile(const QFileSystemEntry &entry); + static bool copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString); + static bool renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString); + static bool removeFile(const QFileSystemEntry &entry, QString &errorString); - static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, + static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QString &errorString, QFileSystemMetaData *data = 0); static bool setCurrentPath(const QFileSystemEntry &entry); diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index efb3539..1e6f277 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -282,49 +282,56 @@ bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool remo } //static -bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target) +bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) { Q_UNUSED(source) Q_UNUSED(target) + errorString = QLatin1String("not supported"); return false; } //static -bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target) +bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) { - //TODO: review - should this be a singleton? + //CFileMan is allocated each time because it is not thread-safe CFileMan *fm = 0; TRAPD(err, fm = CFileMan::NewL(qt_s60GetRFs())); - if(err == KErrNone) { + if (err == KErrNone) { err = fm->Copy(qt_QString2TPtrC(source.nativeFilePath()), qt_QString2TPtrC(target.nativeFilePath()), 0); delete fm; return true; } - //TODO: error reporting d->setSymbianError(err, QFile::CopyError); + errorString = QFileSystemEngine::errorString(err); return false; } //static -bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target) +bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) { QString sourcepath = absoluteName(source).nativeFilePath(); QString targetpath = absoluteName(target).nativeFilePath(); RFs& fs(qt_s60GetRFs()); TInt err = fs.Rename(qt_QString2TPtrC(sourcepath), qt_QString2TPtrC(targetpath)); - return err == KErrNone; // TODO error reporting; + if (err == KErrNone) + return true; + errorString = QFileSystemEngine::errorString(err); + return false; } //static -bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry) +bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QString &errorString) { QString targetpath = absoluteName(entry).nativeFilePath(); RFs& fs(qt_s60GetRFs()); TInt err = fs.Delete(qt_QString2TPtrC(targetpath)); - return err == KErrNone; // TODO error reporting; + if (err == KErrNone) + return true; + errorString = QFileSystemEngine::errorString(err); + return false; } //static -bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QFileSystemMetaData *data) +bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QString &errorString, QFileSystemMetaData *data) { QString targetpath = absoluteName(entry).nativeFilePath(); TUint setmask = 0; @@ -340,7 +347,10 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per data->entryFlags |= QFileSystemMetaData::MetaDataFlag(uint(permissions)); data->knownFlagsMask |= QFileSystemMetaData::Permissions; } - return err == KErrNone; // TODO error reporting + if (err == KErrNone) + return true; + errorString = QFileSystemEngine::errorString(err); + return false; } QString QFileSystemEngine::homePath() @@ -405,4 +415,64 @@ QFileSystemEntry QFileSystemEngine::currentPath() return ret; } +QString QFileSystemEngine::errorString(int errorcode) +{ + switch (errorcode) { + case KErrNotFound: + return QLatin1String("not found"); + case KErrCancel: + return QLatin1String("cancelled"); + case KErrNoMemory: + return QLatin1String("out of memory"); + case KErrNotSupported: + return QLatin1String("not supported"); + case KErrBadHandle: + return QLatin1String("bad handle"); //KERN-EXEC 0 panic is more likely + case KErrAlreadyExists: + return QLatin1String("already exists"); + case KErrPathNotFound: + return QLatin1String("path not found"); + case KErrInUse: + return QLatin1String("in use"); + case KErrNotReady: + return QLatin1String("not ready (e.g. FS dismounted, no memory card)"); + case KErrCorrupt: + return QLatin1String("corrupt"); + case KErrAccessDenied: + return QLatin1String("access denied"); + case KErrLocked: + return QLatin1String("locked"); + case KErrWrite: + return QLatin1String("incomplete write error"); + case KErrDisMounted: + return QLatin1String("file system dismounted during operation"); //i.e. a forcible dismount was done while we had files open + case KErrEof: + return QLatin1String("end of file"); + case KErrDiskFull: + return QLatin1String("no space in file system"); + case KErrBadName: + return QLatin1String("invalid filename"); + case KErrTimedOut: + return QLatin1String("timed out"); + case KErrBadDescriptor: + return QLatin1String("bad descriptor (passed address on stack to async call?)"); + case KErrAbort: + return QLatin1String("aborted"); + case KErrTooBig: + return QLatin1String("too big"); //e.g. trying to open a >2GB file with 32 bit API + case KErrBadPower: + return QLatin1String("insufficient power"); + case KErrDirFull: + return QLatin1String("no space in directory table"); + case KErrHardwareNotAvailable: + return QLatin1String("hardware not available"); + case KErrSessionClosed: + return QLatin1String("session closed"); + case KErrPermissionDenied: + return QLatin1String("permission denied"); + default: + return QString(QLatin1String("symbian error %d")).arg(errorcode); + } +} + QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 1dee09b..7c733c4 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -572,34 +572,45 @@ bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool remo } //static -bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target) +bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) { - return (::symlink(source.nativeFilePath().constData(), target.nativeFilePath().constData()) == 0); + if (::symlink(source.nativeFilePath().constData(), target.nativeFilePath().constData()) == 0) + return true; + errorString = qt_error_string(errno); + return false; } //static -bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target) +bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) { Q_UNUSED(source); Q_UNUSED(target); // # we can implement this using sendfile(2) + errorString = QLatin1String("Not implemented!") return false; } //static -bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target) +bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) { - return (::rename(source.nativeFilePath().constData(), target.nativeFilePath().constData()) == 0); + if (::rename(source.nativeFilePath().constData(), target.nativeFilePath().constData()) == 0) + return true; + errorString = qt_error_string(errno); + return false; } //static -bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry) +bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QString &errorString) { - return (unlink(entry.nativeFilePath().constData()) == 0); + if (unlink(entry.nativeFilePath().constData()) == 0) + return true; + errorString = qt_error_string(errno); + return false; + } //static -bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QFileSystemMetaData *data) +bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QString &errorString, QFileSystemMetaData *data) { mode_t mode = 0; if (permissions & QFile::ReadOwner) @@ -633,6 +644,8 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per data->entryFlags |= QFileSystemMetaData::MetaDataFlag(uint(permissions)); data->knownFlagsMask |= QFileSystemMetaData::Permissions; } + if (!success) + errorString = qt_error_string(errno); return success; } diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 1f7a9b9..5cc7395 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1115,36 +1115,43 @@ QFileSystemEntry QFileSystemEngine::currentPath() } //static -bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target) +bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) { + errorString = QLatin1String("not implemented"); return false; // TODO implement; } //static -bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target) +bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) { bool ret = ::CopyFile((wchar_t*)source.nativeFilePath().utf16(), (wchar_t*)target.nativeFilePath().utf16(), true) != 0; + if(!ret) + errorString = qt_error_string(::GetLastError()); return ret; } //static -bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target) +bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) { bool ret = ::MoveFile((wchar_t*)source.nativeFilePath().utf16(), (wchar_t*)target.nativeFilePath().utf16()) != 0; + if(!ret) + errorString = qt_error_string(::GetLastError()); return ret; } //static -bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry) +bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QString &errorString) { bool ret = ::DeleteFile((wchar_t*)entry.nativeFilePath().utf16()) != 0; + if(!ret) + errorString = qt_error_string(::GetLastError()); return ret; } //static -bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, +bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QString &errorString, QFileSystemMetaData *data) { Q_UNUSED(data); @@ -1160,7 +1167,10 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per if (mode == 0) // not supported return false; - return ::_wchmod((wchar_t*)entry.nativeFilePath().utf16(), mode) == 0; + bool ret = (::_wchmod((wchar_t*)entry.nativeFilePath().utf16(), mode) == 0); + if(!ret) + errorString = qt_error_string(errno); + return ret; } static inline QDateTime fileTimeToQDateTime(const FILETIME *time) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 0845cb3..acb58a5 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -588,15 +588,11 @@ bool QFSFileEnginePrivate::nativeIsSequential() const bool QFSFileEngine::remove() { Q_D(QFSFileEngine); - bool ret = QFileSystemEngine::removeFile(d->fileEntry); + QString errorString; + bool ret = QFileSystemEngine::removeFile(d->fileEntry, errorString); d->metaData.clear(); if (!ret) { -#ifdef Q_OS_SYMBIAN - //TODO: error reporting - d->setSymbianError(KErrGeneral, QFile::RemoveError, QLatin1String("remove error")); -#else - setError(QFile::RemoveError, qt_error_string(errno)); -#endif + setError(QFile::RemoveError, errorString); } return ret; } @@ -604,16 +600,10 @@ bool QFSFileEngine::remove() bool QFSFileEngine::copy(const QString &newName) { Q_D(QFSFileEngine); - bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(newName)); + QString error; + bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(newName), error); if (!ret) { -#ifdef Q_OS_SYMBIAN - //TODO: error reporting - d->setSymbianError(KErrGeneral, QFile::CopyError, QLatin1String("copy error")); -#else - // ### Add copy code for Unix to the filesystem engine - setError(QFile::UnspecifiedError, QLatin1String("Not implemented!")); - //setError(QFile::CopyError, qt_error_string(errno)); -#endif + setError(QFile::CopyError, error); } return ret; } @@ -621,15 +611,11 @@ bool QFSFileEngine::copy(const QString &newName) bool QFSFileEngine::rename(const QString &newName) { Q_D(QFSFileEngine); - bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName)); + QString error; + bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName), error); if (!ret) { -#ifdef Q_OS_SYMBIAN - //TODO: error reporting - d->setSymbianError(KErrGeneral, QFile::RenameError, QLatin1String("rename error")); -#else - setError(QFile::RenameError, qt_error_string(errno)); -#endif + setError(QFile::RenameError, error); } return ret; @@ -638,14 +624,10 @@ bool QFSFileEngine::rename(const QString &newName) bool QFSFileEngine::link(const QString &newName) { Q_D(QFSFileEngine); - bool ret = QFileSystemEngine::createLink(d->fileEntry, QFileSystemEntry(newName)); + QString error; + bool ret = QFileSystemEngine::createLink(d->fileEntry, QFileSystemEntry(newName), error); if (!ret) { -#ifdef Q_OS_SYMBIAN - //TODO: error reporting - d->setSymbianError(KErrNotSupported, QFile::RenameError, QLatin1String("not supported")); -#else - setError(QFile::RenameError, qt_error_string(errno)); -#endif + setError(QFile::RenameError, error); } return ret; } @@ -900,14 +882,9 @@ QString QFSFileEngine::owner(FileOwner own) const bool QFSFileEngine::setPermissions(uint perms) { Q_D(QFSFileEngine); - if (!QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), 0)) { - setError(QFile::PermissionsError, -#ifdef Q_OS_SYMBIAN - //TODO: connect up error reporting properly - QString()); -#else - qt_error_string(errno)); -#endif + QString error; + if (!QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), error, 0)) { + setError(QFile::PermissionsError, error); return false; } return true; @@ -940,7 +917,7 @@ bool QFSFileEngine::setSize(qint64 size) } if (!ret) { if (err) - d->setSymbianError(err, QFile::ResizeError, QString()); + setError(QFile::ResizeError, QFileSystemEngine::errorString(err)); else setError(QFile::ResizeError, qt_error_string(errno)); } diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index b2009c3..63f2a9f 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -503,27 +503,30 @@ bool QFSFileEnginePrivate::nativeIsSequential() const bool QFSFileEngine::remove() { Q_D(QFSFileEngine); - bool ret = QFileSystemEngine::removeFile(d->fileEntry); + QString error; + bool ret = QFileSystemEngine::removeFile(d->fileEntry, error); if (!ret) - setError(QFile::RemoveError, qt_error_string()); + setError(QFile::RemoveError, error); return ret; } bool QFSFileEngine::copy(const QString ©Name) { Q_D(QFSFileEngine); - bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(copyName)); + QString error; + bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(copyName), error); if (!ret) - setError(QFile::CopyError, qt_error_string()); + setError(QFile::CopyError, error); return ret; } bool QFSFileEngine::rename(const QString &newName) { Q_D(QFSFileEngine); - bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName)); + QString error; + bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName), error); if (!ret) - setError(QFile::RenameError, qt_error_string()); + setError(QFile::RenameError, error); return ret; } @@ -851,9 +854,10 @@ QString QFSFileEngine::owner(FileOwner own) const bool QFSFileEngine::setPermissions(uint perms) { Q_D(QFSFileEngine); - bool ret = QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms)); + QString error; + bool ret = QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), error); if (!ret) - setError(QFile::PermissionsError, qt_error_string(errno)); + setError(QFile::PermissionsError, error); return ret; } diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def index 5eeb244..052ec9a 100644 --- a/src/s60installs/bwins/QtCoreu.def +++ b/src/s60installs/bwins/QtCoreu.def @@ -59,7 +59,7 @@ EXPORTS ??0QChildEvent@@QAE@W4Type@QEvent@@PAVQObject@@@Z @ 58 NONAME ; QChildEvent::QChildEvent(enum QEvent::Type, class QObject *) ??0QCoreApplication@@IAE@AAVQCoreApplicationPrivate@@@Z @ 59 NONAME ; QCoreApplication::QCoreApplication(class QCoreApplicationPrivate &) ??0QCoreApplication@@QAE@AAHPAPAD@Z @ 60 NONAME ; QCoreApplication::QCoreApplication(int &, char * *) - ??0QCoreApplicationPrivate@@QAE@AAHPAPAD@Z @ 61 NONAME ; QCoreApplicationPrivate::QCoreApplicationPrivate(int &, char * *) + ??0QCoreApplicationPrivate@@QAE@AAHPAPAD@Z @ 61 NONAME ABSENT ; QCoreApplicationPrivate::QCoreApplicationPrivate(int &, char * *) ??0QCryptographicHash@@QAE@W4Algorithm@0@@Z @ 62 NONAME ; QCryptographicHash::QCryptographicHash(enum QCryptographicHash::Algorithm) ??0QDataStream@@QAE@ABVQByteArray@@@Z @ 63 NONAME ; QDataStream::QDataStream(class QByteArray const &) ??0QDataStream@@QAE@PAVQByteArray@@V?$QFlags@W4OpenModeFlag@QIODevice@@@@@Z @ 64 NONAME ; QDataStream::QDataStream(class QByteArray *, class QFlags) @@ -3123,7 +3123,7 @@ EXPORTS ?reset@QMetaProperty@@QBE_NPAVQObject@@@Z @ 3122 NONAME ; bool QMetaProperty::reset(class QObject *) const ?reset@QTextStream@@QAEXXZ @ 3123 NONAME ; void QTextStream::reset(void) ?resetCurrentSender@QObjectPrivate@@SAXPAVQObject@@PAUSender@1@1@Z @ 3124 NONAME ; void QObjectPrivate::resetCurrentSender(class QObject *, struct QObjectPrivate::Sender *, struct QObjectPrivate::Sender *) - ?resetDeleteWatch@QObjectPrivate@@SAXPAV1@PAHH@Z @ 3125 NONAME ; void QObjectPrivate::resetDeleteWatch(class QObjectPrivate *, int *, int) + ?resetDeleteWatch@QObjectPrivate@@SAXPAV1@PAHH@Z @ 3125 NONAME ABSENT ; void QObjectPrivate::resetDeleteWatch(class QObjectPrivate *, int *, int) ?resetStatus@QDataStream@@QAEXXZ @ 3126 NONAME ; void QDataStream::resetStatus(void) ?resetStatus@QTextStream@@QAEXXZ @ 3127 NONAME ; void QTextStream::resetStatus(void) ?resize@QBitArray@@QAEXH@Z @ 3128 NONAME ; void QBitArray::resize(int) @@ -3296,7 +3296,7 @@ EXPORTS ?setDefault@QLocale@@SAXABV1@@Z @ 3295 NONAME ; void QLocale::setDefault(class QLocale const &) ?setDefaultFormat@QSettings@@SAXW4Format@1@@Z @ 3296 NONAME ; void QSettings::setDefaultFormat(enum QSettings::Format) ?setDefaultState@QHistoryState@@QAEXPAVQAbstractState@@@Z @ 3297 NONAME ; void QHistoryState::setDefaultState(class QAbstractState *) - ?setDeleteWatch@QObjectPrivate@@SAPAHPAV1@PAH@Z @ 3298 NONAME ; int * QObjectPrivate::setDeleteWatch(class QObjectPrivate *, int *) + ?setDeleteWatch@QObjectPrivate@@SAPAHPAV1@PAH@Z @ 3298 NONAME ABSENT ; int * QObjectPrivate::setDeleteWatch(class QObjectPrivate *, int *) ?setDevice@QDataStream@@QAEXPAVQIODevice@@@Z @ 3299 NONAME ; void QDataStream::setDevice(class QIODevice *) ?setDevice@QTextStream@@QAEXPAVQIODevice@@@Z @ 3300 NONAME ; void QTextStream::setDevice(class QIODevice *) ?setDevice@QXmlStreamReader@@QAEXPAVQIODevice@@@Z @ 3301 NONAME ; void QXmlStreamReader::setDevice(class QIODevice *) @@ -4482,5 +4482,48 @@ EXPORTS ?textDirection@QLocale@@QBE?AW4LayoutDirection@Qt@@XZ @ 4481 NONAME ; enum Qt::LayoutDirection QLocale::textDirection(void) const ?msecsSinceReference@QElapsedTimer@@QBE_JXZ @ 4482 NONAME ; long long QElapsedTimer::msecsSinceReference(void) const ?selectThread@QEventDispatcherSymbian@@AAEAAVQSelectThread@@XZ @ 4483 NONAME ; class QSelectThread & QEventDispatcherSymbian::selectThread(void) - ?qt_symbian_SetupThreadHeap@@YAHHAAUSStdEpocThreadCreateInfo@@@Z @ 4484 NONAME ; int qt_symbian_SetupThreadHeap(int, struct SStdEpocThreadCreateInfo &) + ??0QCoreApplication@@QAE@AAHPAPADH@Z @ 4484 NONAME ; QCoreApplication::QCoreApplication(int &, char * *, int) + ??0QCoreApplicationPrivate@@QAE@AAHPAPADI@Z @ 4485 NONAME ; QCoreApplicationPrivate::QCoreApplicationPrivate(int &, char * *, unsigned int) + ?connect@QObject@@SA_NPBV1@ABVQMetaMethod@@01W4ConnectionType@Qt@@@Z @ 4486 NONAME ; bool QObject::connect(class QObject const *, class QMetaMethod const &, class QObject const *, class QMetaMethod const &, enum Qt::ConnectionType) + ?contains@QString@@QBE?AVQBool@@ABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4487 NONAME ; class QBool QString::contains(class QStringRef const &, enum Qt::CaseSensitivity) const + ?contains@QStringRef@@QBE?AVQBool@@ABV1@W4CaseSensitivity@Qt@@@Z @ 4488 NONAME ; class QBool QStringRef::contains(class QStringRef const &, enum Qt::CaseSensitivity) const + ?contains@QStringRef@@QBE?AVQBool@@ABVQString@@W4CaseSensitivity@Qt@@@Z @ 4489 NONAME ; class QBool QStringRef::contains(class QString const &, enum Qt::CaseSensitivity) const + ?contains@QStringRef@@QBE?AVQBool@@VQChar@@W4CaseSensitivity@Qt@@@Z @ 4490 NONAME ; class QBool QStringRef::contains(class QChar, enum Qt::CaseSensitivity) const + ?contains@QStringRef@@QBE?AVQBool@@VQLatin1String@@W4CaseSensitivity@Qt@@@Z @ 4491 NONAME ; class QBool QStringRef::contains(class QLatin1String, enum Qt::CaseSensitivity) const + ?count@QString@@QBEHABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4492 NONAME ; int QString::count(class QStringRef const &, enum Qt::CaseSensitivity) const + ?count@QStringRef@@QBEHABV1@W4CaseSensitivity@Qt@@@Z @ 4493 NONAME ; int QStringRef::count(class QStringRef const &, enum Qt::CaseSensitivity) const + ?count@QStringRef@@QBEHABVQString@@W4CaseSensitivity@Qt@@@Z @ 4494 NONAME ; int QStringRef::count(class QString const &, enum Qt::CaseSensitivity) const + ?count@QStringRef@@QBEHVQChar@@W4CaseSensitivity@Qt@@@Z @ 4495 NONAME ; int QStringRef::count(class QChar, enum Qt::CaseSensitivity) const + ?disconnect@QObject@@SA_NPBV1@ABVQMetaMethod@@01@Z @ 4496 NONAME ; bool QObject::disconnect(class QObject const *, class QMetaMethod const &, class QObject const *, class QMetaMethod const &) + ?endsWith@QString@@QBE_NABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4497 NONAME ; bool QString::endsWith(class QStringRef const &, enum Qt::CaseSensitivity) const + ?endsWith@QStringRef@@QBE_NABV1@W4CaseSensitivity@Qt@@@Z @ 4498 NONAME ; bool QStringRef::endsWith(class QStringRef const &, enum Qt::CaseSensitivity) const + ?endsWith@QStringRef@@QBE_NABVQString@@W4CaseSensitivity@Qt@@@Z @ 4499 NONAME ; bool QStringRef::endsWith(class QString const &, enum Qt::CaseSensitivity) const + ?endsWith@QStringRef@@QBE_NVQChar@@W4CaseSensitivity@Qt@@@Z @ 4500 NONAME ; bool QStringRef::endsWith(class QChar, enum Qt::CaseSensitivity) const + ?endsWith@QStringRef@@QBE_NVQLatin1String@@W4CaseSensitivity@Qt@@@Z @ 4501 NONAME ; bool QStringRef::endsWith(class QLatin1String, enum Qt::CaseSensitivity) const + ?indexOf@QString@@QBEHABVQStringRef@@HW4CaseSensitivity@Qt@@@Z @ 4502 NONAME ; int QString::indexOf(class QStringRef const &, int, enum Qt::CaseSensitivity) const + ?indexOf@QStringRef@@QBEHABV1@HW4CaseSensitivity@Qt@@@Z @ 4503 NONAME ; int QStringRef::indexOf(class QStringRef const &, int, enum Qt::CaseSensitivity) const + ?indexOf@QStringRef@@QBEHABVQString@@HW4CaseSensitivity@Qt@@@Z @ 4504 NONAME ; int QStringRef::indexOf(class QString const &, int, enum Qt::CaseSensitivity) const + ?indexOf@QStringRef@@QBEHVQChar@@HW4CaseSensitivity@Qt@@@Z @ 4505 NONAME ; int QStringRef::indexOf(class QChar, int, enum Qt::CaseSensitivity) const + ?indexOf@QStringRef@@QBEHVQLatin1String@@HW4CaseSensitivity@Qt@@@Z @ 4506 NONAME ; int QStringRef::indexOf(class QLatin1String, int, enum Qt::CaseSensitivity) const + ?isLocalFile@QUrl@@QBE_NXZ @ 4507 NONAME ; bool QUrl::isLocalFile(void) const + ?lastIndexOf@QString@@QBEHABVQStringRef@@HW4CaseSensitivity@Qt@@@Z @ 4508 NONAME ; int QString::lastIndexOf(class QStringRef const &, int, enum Qt::CaseSensitivity) const + ?lastIndexOf@QStringRef@@QBEHABV1@HW4CaseSensitivity@Qt@@@Z @ 4509 NONAME ; int QStringRef::lastIndexOf(class QStringRef const &, int, enum Qt::CaseSensitivity) const + ?lastIndexOf@QStringRef@@QBEHABVQString@@HW4CaseSensitivity@Qt@@@Z @ 4510 NONAME ; int QStringRef::lastIndexOf(class QString const &, int, enum Qt::CaseSensitivity) const + ?lastIndexOf@QStringRef@@QBEHVQChar@@HW4CaseSensitivity@Qt@@@Z @ 4511 NONAME ; int QStringRef::lastIndexOf(class QChar, int, enum Qt::CaseSensitivity) const + ?lastIndexOf@QStringRef@@QBEHVQLatin1String@@HW4CaseSensitivity@Qt@@@Z @ 4512 NONAME ; int QStringRef::lastIndexOf(class QLatin1String, int, enum Qt::CaseSensitivity) const + ?lockInline@QMutex@@QAEXXZ @ 4513 NONAME ; void QMutex::lockInline(void) + ?lockInternal@QMutex@@AAEXXZ @ 4514 NONAME ; void QMutex::lockInternal(void) + ?nativeKey@QSharedMemory@@QBE?AVQString@@XZ @ 4515 NONAME ; class QString QSharedMemory::nativeKey(void) const + ?senderSignalIndex@QObject@@IBEHXZ @ 4516 NONAME ; int QObject::senderSignalIndex(void) const + ?setNativeKey@QSharedMemory@@QAEXABVQString@@@Z @ 4517 NONAME ; void QSharedMemory::setNativeKey(class QString const &) + ?startsWith@QString@@QBE_NABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4518 NONAME ; bool QString::startsWith(class QStringRef const &, enum Qt::CaseSensitivity) const + ?startsWith@QStringRef@@QBE_NABV1@W4CaseSensitivity@Qt@@@Z @ 4519 NONAME ; bool QStringRef::startsWith(class QStringRef const &, enum Qt::CaseSensitivity) const + ?startsWith@QStringRef@@QBE_NABVQString@@W4CaseSensitivity@Qt@@@Z @ 4520 NONAME ; bool QStringRef::startsWith(class QString const &, enum Qt::CaseSensitivity) const + ?startsWith@QStringRef@@QBE_NVQChar@@W4CaseSensitivity@Qt@@@Z @ 4521 NONAME ; bool QStringRef::startsWith(class QChar, enum Qt::CaseSensitivity) const + ?startsWith@QStringRef@@QBE_NVQLatin1String@@W4CaseSensitivity@Qt@@@Z @ 4522 NONAME ; bool QStringRef::startsWith(class QLatin1String, enum Qt::CaseSensitivity) const + ?tryLockInline@QMutex@@QAE_NXZ @ 4523 NONAME ; bool QMutex::tryLockInline(void) + ?unlockInline@QMutex@@QAEXXZ @ 4524 NONAME ; void QMutex::unlockInline(void) + ?unlockInternal@QMutex@@AAEXXZ @ 4525 NONAME ; void QMutex::unlockInternal(void) + ?waitForDone@QThreadPool@@QAE_NH@Z @ 4526 NONAME ; bool QThreadPool::waitForDone(int) + ?app_compile_version@QCoreApplicationPrivate@@2HA @ 4527 NONAME ; int QCoreApplicationPrivate::app_compile_version diff --git a/src/s60installs/bwins/QtDeclarativeu.def b/src/s60installs/bwins/QtDeclarativeu.def index cf0398a..cf2f325 100644 --- a/src/s60installs/bwins/QtDeclarativeu.def +++ b/src/s60installs/bwins/QtDeclarativeu.def @@ -142,7 +142,7 @@ EXPORTS ?setEnumOrFlag@QMetaPropertyBuilder@@QAEX_N@Z @ 141 NONAME ; void QMetaPropertyBuilder::setEnumOrFlag(bool) ?getStaticMetaObject@QDeclarativeRectangle@@SAABUQMetaObject@@XZ @ 142 NONAME ; struct QMetaObject const & QDeclarativeRectangle::getStaticMetaObject(void) ?isValid@QDeclarativeProperty@@QBE_NXZ @ 143 NONAME ; bool QDeclarativeProperty::isValid(void) const - ?isConnected@QDeclarativeDebugClient@@QBE_NXZ @ 144 NONAME ABSENT ; bool QDeclarativeDebugClient::isConnected(void) const + ?isConnected@QDeclarativeDebugClient@@QBE_NXZ @ 144 NONAME ; bool QDeclarativeDebugClient::isConnected(void) const ?enabled@QDeclarativeBinding@@QBE_NXZ @ 145 NONAME ; bool QDeclarativeBinding::enabled(void) const ?setSource@QDeclarativeView@@QAEXABVQUrl@@@Z @ 146 NONAME ; void QDeclarativeView::setSource(class QUrl const &) ??_EQDeclarativeDebugService@@UAE@I@Z @ 147 NONAME ; QDeclarativeDebugService::~QDeclarativeDebugService(unsigned int) @@ -242,7 +242,7 @@ EXPORTS ?idString@QDeclarativeDebugObjectReference@@QBE?AVQString@@XZ @ 241 NONAME ; class QString QDeclarativeDebugObjectReference::idString(void) const ?customTypeData@QDeclarativeDomObject@@QBE?AVQByteArray@@XZ @ 242 NONAME ; class QByteArray QDeclarativeDomObject::customTypeData(void) const ?stop@QDeclarativeTransition@@QAEXXZ @ 243 NONAME ; void QDeclarativeTransition::stop(void) - ?data@QDeclarativeListModel@@UBE?AV?$QHash@HVQVariant@@@@HABV?$QList@H@@@Z @ 244 NONAME ABSENT ; class QHash QDeclarativeListModel::data(int, class QList const &) const + ?data@QDeclarativeListModel@@UBE?AV?$QHash@HVQVariant@@@@HABV?$QList@H@@@Z @ 244 NONAME ; class QHash QDeclarativeListModel::data(int, class QList const &) const ?verticalCenterOffset@QDeclarativeAnchors@@QBEMXZ @ 245 NONAME ; float QDeclarativeAnchors::verticalCenterOffset(void) const ?metaObject@QDeclarativeText@@UBEPBUQMetaObject@@XZ @ 246 NONAME ; struct QMetaObject const * QDeclarativeText::metaObject(void) const ??0QDeclarativeComponent@@QAE@PAVQDeclarativeEngine@@PAVQObject@@@Z @ 247 NONAME ; QDeclarativeComponent::QDeclarativeComponent(class QDeclarativeEngine *, class QObject *) @@ -461,7 +461,7 @@ EXPORTS ?qt_metacall@QDeclarativeContext@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 460 NONAME ; int QDeclarativeContext::qt_metacall(enum QMetaObject::Call, int, void * *) ??_EQDeclarativeValueType@@UAE@I@Z @ 461 NONAME ; QDeclarativeValueType::~QDeclarativeValueType(unsigned int) ?qt_metacall@QDeclarativeState@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 462 NONAME ; int QDeclarativeState::qt_metacall(enum QMetaObject::Call, int, void * *) - ?isEnabled@QDeclarativeDebugService@@QBE_NXZ @ 463 NONAME ABSENT ; bool QDeclarativeDebugService::isEnabled(void) const + ?isEnabled@QDeclarativeDebugService@@QBE_NXZ @ 463 NONAME ; bool QDeclarativeDebugService::isEnabled(void) const ?stateChanged@QDeclarativeDebugWatch@@IAEXW4State@1@@Z @ 464 NONAME ; void QDeclarativeDebugWatch::stateChanged(enum QDeclarativeDebugWatch::State) ??0QMetaMethodBuilder@@AAE@PBVQMetaObjectBuilder@@H@Z @ 465 NONAME ; QMetaMethodBuilder::QMetaMethodBuilder(class QMetaObjectBuilder const *, int) ??4QDeclarativeListReference@@QAEAAV0@ABV0@@Z @ 466 NONAME ; class QDeclarativeListReference & QDeclarativeListReference::operator=(class QDeclarativeListReference const &) @@ -608,7 +608,7 @@ EXPORTS ??_EQDeclarativeDebugObjectExpressionWatch@@UAE@I@Z @ 607 NONAME ; QDeclarativeDebugObjectExpressionWatch::~QDeclarativeDebugObjectExpressionWatch(unsigned int) ?computeTransformOrigin@QDeclarativeItemPrivate@@QBE?AVQPointF@@XZ @ 608 NONAME ; class QPointF QDeclarativeItemPrivate::computeTransformOrigin(void) const ??0QDeclarativeListReference@@QAE@PAVQObject@@PBDPAVQDeclarativeEngine@@@Z @ 609 NONAME ; QDeclarativeListReference::QDeclarativeListReference(class QObject *, char const *, class QDeclarativeEngine *) - ?setData@QListModelInterface@@UAE_NHABV?$QHash@HVQVariant@@@@@Z @ 610 NONAME ABSENT ; bool QListModelInterface::setData(int, class QHash const &) + ?setData@QListModelInterface@@UAE_NHABV?$QHash@HVQVariant@@@@@Z @ 610 NONAME ; bool QListModelInterface::setData(int, class QHash const &) ??0QDeclarativePen@@QAE@PAVQObject@@@Z @ 611 NONAME ; QDeclarativePen::QDeclarativePen(class QObject *) ?trUtf8@QPacketProtocol@@SA?AVQString@@PBD0H@Z @ 612 NONAME ; class QString QPacketProtocol::trUtf8(char const *, char const *, int) ?setContextObject@QDeclarativeContext@@QAEXPAVQObject@@@Z @ 613 NONAME ; void QDeclarativeContext::setContextObject(class QObject *) @@ -1028,7 +1028,7 @@ EXPORTS ?qmlInfo@@YA?AVQDeclarativeInfo@@PBVQObject@@ABVQDeclarativeError@@@Z @ 1027 NONAME ; class QDeclarativeInfo qmlInfo(class QObject const *, class QDeclarativeError const &) ?staticMetaObject@QDeclarativeText@@2UQMetaObject@@B @ 1028 NONAME ; struct QMetaObject const QDeclarativeText::staticMetaObject ?color@QDeclarativeRectangle@@QBE?AVQColor@@XZ @ 1029 NONAME ; class QColor QDeclarativeRectangle::color(void) const - ?isEnabled@QDeclarativeDebugClient@@QBE_NXZ @ 1030 NONAME ABSENT ; bool QDeclarativeDebugClient::isEnabled(void) const + ?isEnabled@QDeclarativeDebugClient@@QBE_NXZ @ 1030 NONAME ; bool QDeclarativeDebugClient::isEnabled(void) const ?send@QPacketProtocol@@QAEXABVQPacket@@@Z @ 1031 NONAME ; void QPacketProtocol::send(class QPacket const &) ?width@QDeclarativePixmap@@QBEHXZ @ 1032 NONAME ; int QDeclarativePixmap::width(void) const ?error@QDeclarativeCustomParser@@IAEXABVQDeclarativeCustomParserNode@@ABVQString@@@Z @ 1033 NONAME ; void QDeclarativeCustomParser::error(class QDeclarativeCustomParserNode const &, class QString const &) @@ -1147,7 +1147,7 @@ EXPORTS ?removeNotifySignal@QMetaPropertyBuilder@@QAEXXZ @ 1146 NONAME ; void QMetaPropertyBuilder::removeNotifySignal(void) ?trUtf8@QDeclarativeDebugService@@SA?AVQString@@PBD0@Z @ 1147 NONAME ; class QString QDeclarativeDebugService::trUtf8(char const *, char const *) ?setImportPathList@QDeclarativeEngine@@QAEXABVQStringList@@@Z @ 1148 NONAME ; void QDeclarativeEngine::setImportPathList(class QStringList const &) - ?enabledChanged@QDeclarativeDebugService@@MAEX_N@Z @ 1149 NONAME ABSENT ; void QDeclarativeDebugService::enabledChanged(bool) + ?enabledChanged@QDeclarativeDebugService@@MAEX_N@Z @ 1149 NONAME ; void QDeclarativeDebugService::enabledChanged(bool) ?addWatch@QDeclarativeEngineDebug@@QAEPAVQDeclarativeDebugWatch@@ABVQDeclarativeDebugObjectReference@@PAVQObject@@@Z @ 1150 NONAME ; class QDeclarativeDebugWatch * QDeclarativeEngineDebug::addWatch(class QDeclarativeDebugObjectReference const &, class QObject *) ?asAST@Variant@QDeclarativeParser@@QBEPAVNode@AST@QDeclarativeJS@@XZ @ 1151 NONAME ; class QDeclarativeJS::AST::Node * QDeclarativeParser::Variant::asAST(void) const ?indexOfClassInfo@QMetaObjectBuilder@@QAEHABVQByteArray@@@Z @ 1152 NONAME ; int QMetaObjectBuilder::indexOfClassInfo(class QByteArray const &) @@ -1386,7 +1386,7 @@ EXPORTS ?qmlTypes@QDeclarativeMetaType@@SA?AV?$QList@PAVQDeclarativeType@@@@XZ @ 1385 NONAME ; class QList QDeclarativeMetaType::qmlTypes(void) ?valueTypeCoreIndex@QDeclarativePropertyPrivate@@SAHABVQDeclarativeProperty@@@Z @ 1386 NONAME ; int QDeclarativePropertyPrivate::valueTypeCoreIndex(class QDeclarativeProperty const &) ?writeEnumProperty@QDeclarativePropertyPrivate@@SA_NABVQMetaProperty@@HPAVQObject@@ABVQVariant@@H@Z @ 1387 NONAME ; bool QDeclarativePropertyPrivate::writeEnumProperty(class QMetaProperty const &, int, class QObject *, class QVariant const &, int) - ?setEnabled@QDeclarativeDebugClient@@QAEX_N@Z @ 1388 NONAME ABSENT ; void QDeclarativeDebugClient::setEnabled(bool) + ?setEnabled@QDeclarativeDebugClient@@QAEX_N@Z @ 1388 NONAME ; void QDeclarativeDebugClient::setEnabled(bool) ??1QMetaObjectBuilder@@UAE@XZ @ 1389 NONAME ; QMetaObjectBuilder::~QMetaObjectBuilder(void) ?tr@QDeclarativeStateOperation@@SA?AVQString@@PBD0@Z @ 1390 NONAME ; class QString QDeclarativeStateOperation::tr(char const *, char const *) ?clear@QPacket@@QAEXXZ @ 1391 NONAME ; void QPacket::clear(void) @@ -1715,127 +1715,4 @@ EXPORTS ??0QDeclarativeListModel@@AAE@PBV0@PAVQDeclarativeListModelWorkerAgent@@@Z @ 1714 NONAME ; QDeclarativeListModel::QDeclarativeListModel(class QDeclarativeListModel const *, class QDeclarativeListModelWorkerAgent *) ?inWorkerThread@QDeclarativeListModel@@ABE_NXZ @ 1715 NONAME ; bool QDeclarativeListModel::inWorkerThread(void) const ?canMove@QDeclarativeListModel@@ABE_NHHH@Z @ 1716 NONAME ; bool QDeclarativeListModel::canMove(int, int, int) const - ?getScriptEngine@QDeclarativeDebugHelper@@SAPAVQScriptEngine@@PAVQDeclarativeEngine@@@Z @ 1717 NONAME ; class QScriptEngine * QDeclarativeDebugHelper::getScriptEngine(class QDeclarativeEngine *) - ?setAnimationSlowDownFactor@QDeclarativeDebugHelper@@SAXM@Z @ 1718 NONAME ; void QDeclarativeDebugHelper::setAnimationSlowDownFactor(float) - ?add@QDeclarativeBasePositioner@@QBEPAVQDeclarativeTransition@@XZ @ 1719 NONAME ; class QDeclarativeTransition * QDeclarativeBasePositioner::add(void) const - ?setLoops@QDeclarativeAbstractAnimation@@QAEXH@Z @ 1720 NONAME ; void QDeclarativeAbstractAnimation::setLoops(int) - ?trUtf8@QDeclarativeAbstractAnimation@@SA?AVQString@@PBD0@Z @ 1721 NONAME ; class QString QDeclarativeAbstractAnimation::trUtf8(char const *, char const *) - ?tr@QDeclarativeBasePositioner@@SA?AVQString@@PBD0@Z @ 1722 NONAME ; class QString QDeclarativeBasePositioner::tr(char const *, char const *) - ?staticMetaObject@QDeclarativeAbstractAnimation@@2UQMetaObject@@B @ 1723 NONAME ; struct QMetaObject const QDeclarativeAbstractAnimation::staticMetaObject - ?setMove@QDeclarativeBasePositioner@@QAEXPAVQDeclarativeTransition@@@Z @ 1724 NONAME ; void QDeclarativeBasePositioner::setMove(class QDeclarativeTransition *) - ?setRunning@QDeclarativeTimer@@QAEX_N@Z @ 1725 NONAME ; void QDeclarativeTimer::setRunning(bool) - ?tr@QDeclarativeTimer@@SA?AVQString@@PBD0@Z @ 1726 NONAME ; class QString QDeclarativeTimer::tr(char const *, char const *) - ?qt_metacall@QDeclarativeTimer@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 1727 NONAME ; int QDeclarativeTimer::qt_metacall(enum QMetaObject::Call, int, void * *) - ?setPaused@QDeclarativeAbstractAnimation@@QAEX_N@Z @ 1728 NONAME ; void QDeclarativeAbstractAnimation::setPaused(bool) - ?d_func@QDeclarativeBasePositioner@@ABEPBVQDeclarativeBasePositionerPrivate@@XZ @ 1729 NONAME ; class QDeclarativeBasePositionerPrivate const * QDeclarativeBasePositioner::d_func(void) const - ?setRepeating@QDeclarativeTimer@@QAEX_N@Z @ 1730 NONAME ; void QDeclarativeTimer::setRepeating(bool) - ?interval@QDeclarativeTimer@@QBEHXZ @ 1731 NONAME ; int QDeclarativeTimer::interval(void) const - ?start@QDeclarativeTimer@@QAEXXZ @ 1732 NONAME ; void QDeclarativeTimer::start(void) - ?transition@QDeclarativeAbstractAnimation@@UAEXAAV?$QList@VQDeclarativeAction@@@@AAV?$QList@VQDeclarativeProperty@@@@W4TransitionDirection@1@@Z @ 1733 NONAME ; void QDeclarativeAbstractAnimation::transition(class QList &, class QList &, enum QDeclarativeAbstractAnimation::TransitionDirection) - ?componentComplete@QDeclarativeAbstractAnimation@@UAEXXZ @ 1734 NONAME ; void QDeclarativeAbstractAnimation::componentComplete(void) - ?statusChanged@QDeclarativeDebugService@@MAEXW4Status@1@@Z @ 1735 NONAME ; void QDeclarativeDebugService::statusChanged(enum QDeclarativeDebugService::Status) - ?runningChanged@QDeclarativeAbstractAnimation@@IAEX_N@Z @ 1736 NONAME ; void QDeclarativeAbstractAnimation::runningChanged(bool) - ?trUtf8@QDeclarativeAbstractAnimation@@SA?AVQString@@PBD0H@Z @ 1737 NONAME ; class QString QDeclarativeAbstractAnimation::trUtf8(char const *, char const *, int) - ??_EQDeclarativeBasePositioner@@UAE@I@Z @ 1738 NONAME ; QDeclarativeBasePositioner::~QDeclarativeBasePositioner(unsigned int) - ?metaObject@QDeclarativeTimer@@UBEPBUQMetaObject@@XZ @ 1739 NONAME ; struct QMetaObject const * QDeclarativeTimer::metaObject(void) const - ?setGroup@QDeclarativeAbstractAnimation@@QAEXPAVQDeclarativeAnimationGroup@@@Z @ 1740 NONAME ; void QDeclarativeAbstractAnimation::setGroup(class QDeclarativeAnimationGroup *) - ?isRepeating@QDeclarativeTimer@@QBE_NXZ @ 1741 NONAME ; bool QDeclarativeTimer::isRepeating(void) const - ?setTriggeredOnStart@QDeclarativeTimer@@QAEX_N@Z @ 1742 NONAME ; void QDeclarativeTimer::setTriggeredOnStart(bool) - ?currentTime@QDeclarativeAbstractAnimation@@QAEHXZ @ 1743 NONAME ; int QDeclarativeAbstractAnimation::currentTime(void) - ?status@QDeclarativeEngineDebug@@QBE?AW4Status@1@XZ @ 1744 NONAME ; enum QDeclarativeEngineDebug::Status QDeclarativeEngineDebug::status(void) const - ??1QDeclarativeAbstractAnimation@@UAE@XZ @ 1745 NONAME ; QDeclarativeAbstractAnimation::~QDeclarativeAbstractAnimation(void) - ?triggered@QDeclarativeTimer@@IAEXXZ @ 1746 NONAME ; void QDeclarativeTimer::triggered(void) - ?getStaticMetaObject@QDeclarativeBasePositioner@@SAABUQMetaObject@@XZ @ 1747 NONAME ; struct QMetaObject const & QDeclarativeBasePositioner::getStaticMetaObject(void) - ?finished@QDeclarativeTimer@@AAEXXZ @ 1748 NONAME ; void QDeclarativeTimer::finished(void) - ?pausedChanged@QDeclarativeAbstractAnimation@@IAEX_N@Z @ 1749 NONAME ; void QDeclarativeAbstractAnimation::pausedChanged(bool) - ?complete@QDeclarativeAbstractAnimation@@QAEXXZ @ 1750 NONAME ; void QDeclarativeAbstractAnimation::complete(void) - ?setRunning@QDeclarativeAbstractAnimation@@QAEX_N@Z @ 1751 NONAME ; void QDeclarativeAbstractAnimation::setRunning(bool) - ?trUtf8@QDeclarativeBasePositioner@@SA?AVQString@@PBD0H@Z @ 1752 NONAME ; class QString QDeclarativeBasePositioner::trUtf8(char const *, char const *, int) - ?trUtf8@QDeclarativeBasePositioner@@SA?AVQString@@PBD0@Z @ 1753 NONAME ; class QString QDeclarativeBasePositioner::trUtf8(char const *, char const *) - ?completed@QDeclarativeAbstractAnimation@@IAEXXZ @ 1754 NONAME ; void QDeclarativeAbstractAnimation::completed(void) - ?trUtf8@QDeclarativeTimer@@SA?AVQString@@PBD0@Z @ 1755 NONAME ; class QString QDeclarativeTimer::trUtf8(char const *, char const *) - ?loopCountChanged@QDeclarativeAbstractAnimation@@IAEXH@Z @ 1756 NONAME ; void QDeclarativeAbstractAnimation::loopCountChanged(int) - ?repeatChanged@QDeclarativeTimer@@IAEXXZ @ 1757 NONAME ; void QDeclarativeTimer::repeatChanged(void) - ?setDisableUserControl@QDeclarativeAbstractAnimation@@QAEXXZ @ 1758 NONAME ; void QDeclarativeAbstractAnimation::setDisableUserControl(void) - ?componentComplete@QDeclarativeBasePositioner@@MAEXXZ @ 1759 NONAME ; void QDeclarativeBasePositioner::componentComplete(void) - ?setDefaultTarget@QDeclarativeAbstractAnimation@@QAEXABVQDeclarativeProperty@@@Z @ 1760 NONAME ; void QDeclarativeAbstractAnimation::setDefaultTarget(class QDeclarativeProperty const &) - ?staticMetaObject@QDeclarativeBasePositioner@@2UQMetaObject@@B @ 1761 NONAME ; struct QMetaObject const QDeclarativeBasePositioner::staticMetaObject - ?triggeredOnStart@QDeclarativeTimer@@QBE_NXZ @ 1762 NONAME ; bool QDeclarativeTimer::triggeredOnStart(void) const - ?notifyRunningChanged@QDeclarativeAbstractAnimation@@AAEX_N@Z @ 1763 NONAME ; void QDeclarativeAbstractAnimation::notifyRunningChanged(bool) - ?statusChanged@QDeclarativeDebugClient@@MAEXW4Status@1@@Z @ 1764 NONAME ; void QDeclarativeDebugClient::statusChanged(enum QDeclarativeDebugClient::Status) - ??0QDeclarativeBasePositioner@@IAE@AAVQDeclarativeBasePositionerPrivate@@W4PositionerType@0@PAVQDeclarativeItem@@@Z @ 1765 NONAME ; QDeclarativeBasePositioner::QDeclarativeBasePositioner(class QDeclarativeBasePositionerPrivate &, enum QDeclarativeBasePositioner::PositionerType, class QDeclarativeItem *) - ?componentComplete@QDeclarativeTimer@@MAEXXZ @ 1766 NONAME ; void QDeclarativeTimer::componentComplete(void) - ?tr@QDeclarativeAbstractAnimation@@SA?AVQString@@PBD0@Z @ 1767 NONAME ; class QString QDeclarativeAbstractAnimation::tr(char const *, char const *) - ?isRunning@QDeclarativeAbstractAnimation@@QBE_NXZ @ 1768 NONAME ; bool QDeclarativeAbstractAnimation::isRunning(void) const - ?d_func@QDeclarativeAbstractAnimation@@ABEPBVQDeclarativeAbstractAnimationPrivate@@XZ @ 1769 NONAME ; class QDeclarativeAbstractAnimationPrivate const * QDeclarativeAbstractAnimation::d_func(void) const - ??_EQDeclarativeAbstractAnimation@@UAE@I@Z @ 1770 NONAME ; QDeclarativeAbstractAnimation::~QDeclarativeAbstractAnimation(unsigned int) - ??0QDeclarativeBasePositioner@@QAE@W4PositionerType@0@PAVQDeclarativeItem@@@Z @ 1771 NONAME ; QDeclarativeBasePositioner::QDeclarativeBasePositioner(enum QDeclarativeBasePositioner::PositionerType, class QDeclarativeItem *) - ?qt_metacall@QDeclarativeBasePositioner@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 1772 NONAME ; int QDeclarativeBasePositioner::qt_metacall(enum QMetaObject::Call, int, void * *) - ?status@QDeclarativeDebugClient@@QBE?AW4Status@1@XZ @ 1773 NONAME ; enum QDeclarativeDebugClient::Status QDeclarativeDebugClient::status(void) const - ?prePositioning@QDeclarativeBasePositioner@@IAEXXZ @ 1774 NONAME ; void QDeclarativeBasePositioner::prePositioning(void) - ?finishApplyTransitions@QDeclarativeBasePositioner@@IAEXXZ @ 1775 NONAME ; void QDeclarativeBasePositioner::finishApplyTransitions(void) - ?d_func@QDeclarativeAbstractAnimation@@AAEPAVQDeclarativeAbstractAnimationPrivate@@XZ @ 1776 NONAME ; class QDeclarativeAbstractAnimationPrivate * QDeclarativeAbstractAnimation::d_func(void) - ?componentFinalized@QDeclarativeAbstractAnimation@@AAEXXZ @ 1777 NONAME ; void QDeclarativeAbstractAnimation::componentFinalized(void) - ??_EQDeclarativeTimer@@UAE@I@Z @ 1778 NONAME ; QDeclarativeTimer::~QDeclarativeTimer(unsigned int) - ?pause@QDeclarativeAbstractAnimation@@QAEXXZ @ 1779 NONAME ; void QDeclarativeAbstractAnimation::pause(void) - ?stop@QDeclarativeTimer@@QAEXXZ @ 1780 NONAME ; void QDeclarativeTimer::stop(void) - ?timelineComplete@QDeclarativeAbstractAnimation@@AAEXXZ @ 1781 NONAME ; void QDeclarativeAbstractAnimation::timelineComplete(void) - ?d_func@QDeclarativeBasePositioner@@AAEPAVQDeclarativeBasePositionerPrivate@@XZ @ 1782 NONAME ; class QDeclarativeBasePositionerPrivate * QDeclarativeBasePositioner::d_func(void) - ?setAlwaysRunToEnd@QDeclarativeAbstractAnimation@@QAEX_N@Z @ 1783 NONAME ; void QDeclarativeAbstractAnimation::setAlwaysRunToEnd(bool) - ?classBegin@QDeclarativeAbstractAnimation@@UAEXXZ @ 1784 NONAME ; void QDeclarativeAbstractAnimation::classBegin(void) - ?d_func@QDeclarativeTimer@@AAEPAVQDeclarativeTimerPrivate@@XZ @ 1785 NONAME ; class QDeclarativeTimerPrivate * QDeclarativeTimer::d_func(void) - ?spacing@QDeclarativeBasePositioner@@QBEHXZ @ 1786 NONAME ; int QDeclarativeBasePositioner::spacing(void) const - ??0QDeclarativeAbstractAnimation@@QAE@PAVQObject@@@Z @ 1787 NONAME ; QDeclarativeAbstractAnimation::QDeclarativeAbstractAnimation(class QObject *) - ?metaObject@QDeclarativeAbstractAnimation@@UBEPBUQMetaObject@@XZ @ 1788 NONAME ; struct QMetaObject const * QDeclarativeAbstractAnimation::metaObject(void) const - ?tr@QDeclarativeAbstractAnimation@@SA?AVQString@@PBD0H@Z @ 1789 NONAME ; class QString QDeclarativeAbstractAnimation::tr(char const *, char const *, int) - ?started@QDeclarativeAbstractAnimation@@IAEXXZ @ 1790 NONAME ; void QDeclarativeAbstractAnimation::started(void) - ?setInterval@QDeclarativeTimer@@QAEXH@Z @ 1791 NONAME ; void QDeclarativeTimer::setInterval(int) - ?statusChanged@QDeclarativeEngineDebug@@IAEXW4Status@1@@Z @ 1792 NONAME ; void QDeclarativeEngineDebug::statusChanged(enum QDeclarativeEngineDebug::Status) - ?d_func@QDeclarativeTimer@@ABEPBVQDeclarativeTimerPrivate@@XZ @ 1793 NONAME ; class QDeclarativeTimerPrivate const * QDeclarativeTimer::d_func(void) const - ?setSpacing@QDeclarativeBasePositioner@@QAEXH@Z @ 1794 NONAME ; void QDeclarativeBasePositioner::setSpacing(int) - ?staticMetaObject@QDeclarativeTimer@@2UQMetaObject@@B @ 1795 NONAME ; struct QMetaObject const QDeclarativeTimer::staticMetaObject - ?positionY@QDeclarativeBasePositioner@@IAEXHABVPositionedItem@1@@Z @ 1796 NONAME ; void QDeclarativeBasePositioner::positionY(int, class QDeclarativeBasePositioner::PositionedItem const &) - ?qt_metacast@QDeclarativeAbstractAnimation@@UAEPAXPBD@Z @ 1797 NONAME ; void * QDeclarativeAbstractAnimation::qt_metacast(char const *) - ?setAdd@QDeclarativeBasePositioner@@QAEXPAVQDeclarativeTransition@@@Z @ 1798 NONAME ; void QDeclarativeBasePositioner::setAdd(class QDeclarativeTransition *) - ?setCurrentTime@QDeclarativeAbstractAnimation@@QAEXH@Z @ 1799 NONAME ; void QDeclarativeAbstractAnimation::setCurrentTime(int) - ?attachedPropertiesId@QDeclarativeType@@QBEHXZ @ 1800 NONAME ; int QDeclarativeType::attachedPropertiesId(void) const - ?positionX@QDeclarativeBasePositioner@@IAEXHABVPositionedItem@1@@Z @ 1801 NONAME ; void QDeclarativeBasePositioner::positionX(int, class QDeclarativeBasePositioner::PositionedItem const &) - ?restart@QDeclarativeAbstractAnimation@@QAEXXZ @ 1802 NONAME ; void QDeclarativeAbstractAnimation::restart(void) - ?itemChange@QDeclarativeBasePositioner@@MAE?AVQVariant@@W4GraphicsItemChange@QGraphicsItem@@ABV2@@Z @ 1803 NONAME ; class QVariant QDeclarativeBasePositioner::itemChange(enum QGraphicsItem::GraphicsItemChange, class QVariant const &) - ??0QDeclarativeAbstractAnimation@@IAE@AAVQDeclarativeAbstractAnimationPrivate@@PAVQObject@@@Z @ 1804 NONAME ; QDeclarativeAbstractAnimation::QDeclarativeAbstractAnimation(class QDeclarativeAbstractAnimationPrivate &, class QObject *) - ?resume@QDeclarativeAbstractAnimation@@QAEXXZ @ 1805 NONAME ; void QDeclarativeAbstractAnimation::resume(void) - ?runningChanged@QDeclarativeTimer@@IAEXXZ @ 1806 NONAME ; void QDeclarativeTimer::runningChanged(void) - ?ticked@QDeclarativeTimer@@AAEXXZ @ 1807 NONAME ; void QDeclarativeTimer::ticked(void) - ?graphicsWidgetGeometryChanged@QDeclarativeBasePositioner@@IAEXXZ @ 1808 NONAME ; void QDeclarativeBasePositioner::graphicsWidgetGeometryChanged(void) - ?trUtf8@QDeclarativeTimer@@SA?AVQString@@PBD0H@Z @ 1809 NONAME ; class QString QDeclarativeTimer::trUtf8(char const *, char const *, int) - ??0QDeclarativeTimer@@QAE@PAVQObject@@@Z @ 1810 NONAME ; QDeclarativeTimer::QDeclarativeTimer(class QObject *) - ?loops@QDeclarativeAbstractAnimation@@QBEHXZ @ 1811 NONAME ; int QDeclarativeAbstractAnimation::loops(void) const - ?setTarget@QDeclarativeAbstractAnimation@@EAEXABVQDeclarativeProperty@@@Z @ 1812 NONAME ; void QDeclarativeAbstractAnimation::setTarget(class QDeclarativeProperty const &) - ?alwaysRunToEnd@QDeclarativeAbstractAnimation@@QBE_NXZ @ 1813 NONAME ; bool QDeclarativeAbstractAnimation::alwaysRunToEnd(void) const - ?tr@QDeclarativeTimer@@SA?AVQString@@PBD0H@Z @ 1814 NONAME ; class QString QDeclarativeTimer::tr(char const *, char const *, int) - ?status@QDeclarativeDebugService@@QBE?AW4Status@1@XZ @ 1815 NONAME ; enum QDeclarativeDebugService::Status QDeclarativeDebugService::status(void) const - ?intervalChanged@QDeclarativeTimer@@IAEXXZ @ 1816 NONAME ; void QDeclarativeTimer::intervalChanged(void) - ?isPaused@QDeclarativeAbstractAnimation@@QBE_NXZ @ 1817 NONAME ; bool QDeclarativeAbstractAnimation::isPaused(void) const - ?getStaticMetaObject@QDeclarativeAbstractAnimation@@SAABUQMetaObject@@XZ @ 1818 NONAME ; struct QMetaObject const & QDeclarativeAbstractAnimation::getStaticMetaObject(void) - ?group@QDeclarativeAbstractAnimation@@QBEPAVQDeclarativeAnimationGroup@@XZ @ 1819 NONAME ; class QDeclarativeAnimationGroup * QDeclarativeAbstractAnimation::group(void) const - ?classBegin@QDeclarativeTimer@@MAEXXZ @ 1820 NONAME ; void QDeclarativeTimer::classBegin(void) - ?restart@QDeclarativeTimer@@QAEXXZ @ 1821 NONAME ; void QDeclarativeTimer::restart(void) - ?move@QDeclarativeBasePositioner@@QBEPAVQDeclarativeTransition@@XZ @ 1822 NONAME ; class QDeclarativeTransition * QDeclarativeBasePositioner::move(void) const - ?spacingChanged@QDeclarativeBasePositioner@@IAEXXZ @ 1823 NONAME ; void QDeclarativeBasePositioner::spacingChanged(void) - ?qt_metacast@QDeclarativeBasePositioner@@UAEPAXPBD@Z @ 1824 NONAME ; void * QDeclarativeBasePositioner::qt_metacast(char const *) - ??1QDeclarativeTimer@@UAE@XZ @ 1825 NONAME ; QDeclarativeTimer::~QDeclarativeTimer(void) - ?getStaticMetaObject@QDeclarativeTimer@@SAABUQMetaObject@@XZ @ 1826 NONAME ; struct QMetaObject const & QDeclarativeTimer::getStaticMetaObject(void) - ?tr@QDeclarativeBasePositioner@@SA?AVQString@@PBD0H@Z @ 1827 NONAME ; class QString QDeclarativeBasePositioner::tr(char const *, char const *, int) - ??1QDeclarativeBasePositioner@@UAE@XZ @ 1828 NONAME ; QDeclarativeBasePositioner::~QDeclarativeBasePositioner(void) - ?moveChanged@QDeclarativeBasePositioner@@IAEXXZ @ 1829 NONAME ; void QDeclarativeBasePositioner::moveChanged(void) - ?qt_metacast@QDeclarativeTimer@@UAEPAXPBD@Z @ 1830 NONAME ; void * QDeclarativeTimer::qt_metacast(char const *) - ?metaObject@QDeclarativeBasePositioner@@UBEPBUQMetaObject@@XZ @ 1831 NONAME ; struct QMetaObject const * QDeclarativeBasePositioner::metaObject(void) const - ?alwaysRunToEndChanged@QDeclarativeAbstractAnimation@@IAEX_N@Z @ 1832 NONAME ; void QDeclarativeAbstractAnimation::alwaysRunToEndChanged(bool) - ?triggeredOnStartChanged@QDeclarativeTimer@@IAEXXZ @ 1833 NONAME ; void QDeclarativeTimer::triggeredOnStartChanged(void) - ?isRunning@QDeclarativeTimer@@QBE_NXZ @ 1834 NONAME ; bool QDeclarativeTimer::isRunning(void) const - ?update@QDeclarativeTimer@@AAEXXZ @ 1835 NONAME ; void QDeclarativeTimer::update(void) - ?stop@QDeclarativeAbstractAnimation@@QAEXXZ @ 1836 NONAME ; void QDeclarativeAbstractAnimation::stop(void) - ?addChanged@QDeclarativeBasePositioner@@IAEXXZ @ 1837 NONAME ; void QDeclarativeBasePositioner::addChanged(void) - ?start@QDeclarativeAbstractAnimation@@QAEXXZ @ 1838 NONAME ; void QDeclarativeAbstractAnimation::start(void) - ?qt_metacall@QDeclarativeAbstractAnimation@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 1839 NONAME ; int QDeclarativeAbstractAnimation::qt_metacall(enum QMetaObject::Call, int, void * *) diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 9a61523..7805dae 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -12892,5 +12892,4 @@ EXPORTS ?setTimeout@QTapAndHoldGesture@@SAXH@Z @ 12891 NONAME ; void QTapAndHoldGesture::setTimeout(int) ?qmljsDebugArguments@QApplicationPrivate@@2VQString@@A @ 12892 NONAME ; class QString QApplicationPrivate::qmljsDebugArguments ?effectiveBoundingRect@QGraphicsItemPrivate@@QBE?AVQRectF@@PAVQGraphicsItem@@@Z @ 12893 NONAME ; class QRectF QGraphicsItemPrivate::effectiveBoundingRect(class QGraphicsItem *) const - ?lastResortFont@QFont@@QBE?AVQString@@XZ @ 12894 NONAME ; class QString QFont::lastResortFont(void) const diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index f496839..01679be 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -3711,5 +3711,4 @@ EXPORTS _ZlsR11QDataStreamRK12QEasingCurve @ 3710 NONAME _ZltRK13QElapsedTimerS1_ @ 3711 NONAME _ZrsR11QDataStreamR12QEasingCurve @ 3712 NONAME - _Z26qt_symbian_SetupThreadHeapiR24SStdEpocThreadCreateInfo @ 3713 NONAME diff --git a/src/s60installs/eabi/QtDeclarativeu.def b/src/s60installs/eabi/QtDeclarativeu.def index d4084cc..11dee4d 100644 --- a/src/s60installs/eabi/QtDeclarativeu.def +++ b/src/s60installs/eabi/QtDeclarativeu.def @@ -673,7 +673,7 @@ EXPORTS _ZN22QDeclarativeTransitionD0Ev @ 672 NONAME _ZN22QDeclarativeTransitionD1Ev @ 673 NONAME _ZN22QDeclarativeTransitionD2Ev @ 674 NONAME - _ZN23QDeclarativeDebugClient10setEnabledEb @ 675 NONAME ABSENT + _ZN23QDeclarativeDebugClient10setEnabledEb @ 675 NONAME _ZN23QDeclarativeDebugClient11qt_metacallEN11QMetaObject4CallEiPPv @ 676 NONAME _ZN23QDeclarativeDebugClient11qt_metacastEPKc @ 677 NONAME _ZN23QDeclarativeDebugClient11sendMessageERK10QByteArray @ 678 NONAME @@ -766,7 +766,7 @@ EXPORTS _ZN24QDeclarativeDebugService11qt_metacallEN11QMetaObject4CallEiPPv @ 765 NONAME _ZN24QDeclarativeDebugService11qt_metacastEPKc @ 766 NONAME _ZN24QDeclarativeDebugService11sendMessageERK10QByteArray @ 767 NONAME - _ZN24QDeclarativeDebugService14enabledChangedEb @ 768 NONAME ABSENT + _ZN24QDeclarativeDebugService14enabledChangedEb @ 768 NONAME _ZN24QDeclarativeDebugService14objectToStringEP7QObject @ 769 NONAME _ZN24QDeclarativeDebugService15messageReceivedERK10QByteArray @ 770 NONAME _ZN24QDeclarativeDebugService16staticMetaObjectE @ 771 NONAME DATA 16 @@ -1351,7 +1351,7 @@ EXPORTS _ZNK21QDeclarativeDomObject8propertyERK10QByteArray @ 1350 NONAME _ZNK21QDeclarativeListModel10metaObjectEv @ 1351 NONAME _ZNK21QDeclarativeListModel3getEi @ 1352 NONAME - _ZNK21QDeclarativeListModel4dataEiRK5QListIiE @ 1353 NONAME ABSENT + _ZNK21QDeclarativeListModel4dataEiRK5QListIiE @ 1353 NONAME _ZNK21QDeclarativeListModel4dataEii @ 1354 NONAME _ZNK21QDeclarativeListModel5countEv @ 1355 NONAME _ZNK21QDeclarativeListModel5rolesEv @ 1356 NONAME @@ -1390,9 +1390,9 @@ EXPORTS _ZNK22QDeclarativeTransition7toStateEv @ 1389 NONAME _ZNK22QDeclarativeTransition9fromStateEv @ 1390 NONAME _ZNK23QDeclarativeDebugClient10metaObjectEv @ 1391 NONAME - _ZNK23QDeclarativeDebugClient11isConnectedEv @ 1392 NONAME ABSENT + _ZNK23QDeclarativeDebugClient11isConnectedEv @ 1392 NONAME _ZNK23QDeclarativeDebugClient4nameEv @ 1393 NONAME - _ZNK23QDeclarativeDebugClient9isEnabledEv @ 1394 NONAME ABSENT + _ZNK23QDeclarativeDebugClient9isEnabledEv @ 1394 NONAME _ZNK23QDeclarativeDomDocument10rootObjectEv @ 1395 NONAME _ZNK23QDeclarativeDomDocument6errorsEv @ 1396 NONAME _ZNK23QDeclarativeDomDocument7importsEv @ 1397 NONAME @@ -1427,7 +1427,7 @@ EXPORTS _ZNK24QDeclarativeCustomParser12evaluateEnumERK10QByteArray @ 1426 NONAME _ZNK24QDeclarativeDebugService10metaObjectEv @ 1427 NONAME _ZNK24QDeclarativeDebugService4nameEv @ 1428 NONAME - _ZNK24QDeclarativeDebugService9isEnabledEv @ 1429 NONAME ABSENT + _ZNK24QDeclarativeDebugService9isEnabledEv @ 1429 NONAME _ZNK24QDeclarativeDomComponent13componentRootEv @ 1430 NONAME _ZNK24QDeclarativeScriptString11scopeObjectEv @ 1431 NONAME _ZNK24QDeclarativeScriptString6scriptEv @ 1432 NONAME @@ -1747,140 +1747,4 @@ EXPORTS _ZN21QDeclarativeListModelC1EPKS_P32QDeclarativeListModelWorkerAgent @ 1746 NONAME _ZN21QDeclarativeListModelC2EPKS_P32QDeclarativeListModelWorkerAgent @ 1747 NONAME _ZNK21QDeclarativeListModel14inWorkerThreadEv @ 1748 NONAME - _ZN23QDeclarativeDebugHelper15getScriptEngineEP18QDeclarativeEngine @ 1749 NONAME - _ZN23QDeclarativeDebugHelper26setAnimationSlowDownFactorEf @ 1750 NONAME - _ZN17QDeclarativeTimer10classBeginEv @ 1751 NONAME - _ZN17QDeclarativeTimer10setRunningEb @ 1752 NONAME - _ZN17QDeclarativeTimer11qt_metacallEN11QMetaObject4CallEiPPv @ 1753 NONAME - _ZN17QDeclarativeTimer11qt_metacastEPKc @ 1754 NONAME - _ZN17QDeclarativeTimer11setIntervalEi @ 1755 NONAME - _ZN17QDeclarativeTimer12setRepeatingEb @ 1756 NONAME - _ZN17QDeclarativeTimer13repeatChangedEv @ 1757 NONAME - _ZN17QDeclarativeTimer14runningChangedEv @ 1758 NONAME - _ZN17QDeclarativeTimer15intervalChangedEv @ 1759 NONAME - _ZN17QDeclarativeTimer16staticMetaObjectE @ 1760 NONAME DATA 16 - _ZN17QDeclarativeTimer17componentCompleteEv @ 1761 NONAME - _ZN17QDeclarativeTimer19getStaticMetaObjectEv @ 1762 NONAME - _ZN17QDeclarativeTimer19setTriggeredOnStartEb @ 1763 NONAME - _ZN17QDeclarativeTimer23triggeredOnStartChangedEv @ 1764 NONAME - _ZN17QDeclarativeTimer4stopEv @ 1765 NONAME - _ZN17QDeclarativeTimer5startEv @ 1766 NONAME - _ZN17QDeclarativeTimer6tickedEv @ 1767 NONAME - _ZN17QDeclarativeTimer6updateEv @ 1768 NONAME - _ZN17QDeclarativeTimer7restartEv @ 1769 NONAME - _ZN17QDeclarativeTimer8finishedEv @ 1770 NONAME - _ZN17QDeclarativeTimer9triggeredEv @ 1771 NONAME - _ZN17QDeclarativeTimerC1EP7QObject @ 1772 NONAME - _ZN17QDeclarativeTimerC2EP7QObject @ 1773 NONAME - _ZN23QDeclarativeDebugClient13statusChangedENS_6StatusE @ 1774 NONAME - _ZN23QDeclarativeDebugClientD0Ev @ 1775 NONAME - _ZN23QDeclarativeDebugClientD1Ev @ 1776 NONAME - _ZN23QDeclarativeDebugClientD2Ev @ 1777 NONAME - _ZN23QDeclarativeEngineDebug13statusChangedENS_6StatusE @ 1778 NONAME - _ZN24QDeclarativeDebugService13statusChangedENS_6StatusE @ 1779 NONAME - _ZN24QDeclarativeDebugServiceD0Ev @ 1780 NONAME - _ZN24QDeclarativeDebugServiceD1Ev @ 1781 NONAME - _ZN24QDeclarativeDebugServiceD2Ev @ 1782 NONAME - _ZN26QDeclarativeBasePositioner10addChangedEv @ 1783 NONAME - _ZN26QDeclarativeBasePositioner10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant @ 1784 NONAME - _ZN26QDeclarativeBasePositioner10setSpacingEi @ 1785 NONAME - _ZN26QDeclarativeBasePositioner11moveChangedEv @ 1786 NONAME - _ZN26QDeclarativeBasePositioner11qt_metacallEN11QMetaObject4CallEiPPv @ 1787 NONAME - _ZN26QDeclarativeBasePositioner11qt_metacastEPKc @ 1788 NONAME - _ZN26QDeclarativeBasePositioner14prePositioningEv @ 1789 NONAME - _ZN26QDeclarativeBasePositioner14spacingChangedEv @ 1790 NONAME - _ZN26QDeclarativeBasePositioner16staticMetaObjectE @ 1791 NONAME DATA 16 - _ZN26QDeclarativeBasePositioner17componentCompleteEv @ 1792 NONAME - _ZN26QDeclarativeBasePositioner19getStaticMetaObjectEv @ 1793 NONAME - _ZN26QDeclarativeBasePositioner22finishApplyTransitionsEv @ 1794 NONAME - _ZN26QDeclarativeBasePositioner29graphicsWidgetGeometryChangedEv @ 1795 NONAME - _ZN26QDeclarativeBasePositioner6setAddEP22QDeclarativeTransition @ 1796 NONAME - _ZN26QDeclarativeBasePositioner7setMoveEP22QDeclarativeTransition @ 1797 NONAME - _ZN26QDeclarativeBasePositioner9positionXEiRKNS_14PositionedItemE @ 1798 NONAME - _ZN26QDeclarativeBasePositioner9positionYEiRKNS_14PositionedItemE @ 1799 NONAME - _ZN26QDeclarativeBasePositionerC2ENS_14PositionerTypeEP16QDeclarativeItem @ 1800 NONAME - _ZN26QDeclarativeBasePositionerC2ER33QDeclarativeBasePositionerPrivateNS_14PositionerTypeEP16QDeclarativeItem @ 1801 NONAME - _ZN26QDeclarativeBasePositionerD0Ev @ 1802 NONAME - _ZN26QDeclarativeBasePositionerD1Ev @ 1803 NONAME - _ZN26QDeclarativeBasePositionerD2Ev @ 1804 NONAME - _ZN27QDeclarativeDebugConnectionD0Ev @ 1805 NONAME - _ZN27QDeclarativeDebugConnectionD1Ev @ 1806 NONAME - _ZN27QDeclarativeDebugConnectionD2Ev @ 1807 NONAME - _ZN29QDeclarativeAbstractAnimation10classBeginEv @ 1808 NONAME - _ZN29QDeclarativeAbstractAnimation10setRunningEb @ 1809 NONAME - _ZN29QDeclarativeAbstractAnimation10transitionER5QListI18QDeclarativeActionERS0_I20QDeclarativePropertyENS_19TransitionDirectionE @ 1810 NONAME - _ZN29QDeclarativeAbstractAnimation11currentTimeEv @ 1811 NONAME - _ZN29QDeclarativeAbstractAnimation11qt_metacallEN11QMetaObject4CallEiPPv @ 1812 NONAME - _ZN29QDeclarativeAbstractAnimation11qt_metacastEPKc @ 1813 NONAME - _ZN29QDeclarativeAbstractAnimation13pausedChangedEb @ 1814 NONAME - _ZN29QDeclarativeAbstractAnimation14runningChangedEb @ 1815 NONAME - _ZN29QDeclarativeAbstractAnimation14setCurrentTimeEi @ 1816 NONAME - _ZN29QDeclarativeAbstractAnimation16loopCountChangedEi @ 1817 NONAME - _ZN29QDeclarativeAbstractAnimation16setDefaultTargetERK20QDeclarativeProperty @ 1818 NONAME - _ZN29QDeclarativeAbstractAnimation16staticMetaObjectE @ 1819 NONAME DATA 16 - _ZN29QDeclarativeAbstractAnimation16timelineCompleteEv @ 1820 NONAME - _ZN29QDeclarativeAbstractAnimation17componentCompleteEv @ 1821 NONAME - _ZN29QDeclarativeAbstractAnimation17setAlwaysRunToEndEb @ 1822 NONAME - _ZN29QDeclarativeAbstractAnimation18componentFinalizedEv @ 1823 NONAME - _ZN29QDeclarativeAbstractAnimation19getStaticMetaObjectEv @ 1824 NONAME - _ZN29QDeclarativeAbstractAnimation20notifyRunningChangedEb @ 1825 NONAME - _ZN29QDeclarativeAbstractAnimation21alwaysRunToEndChangedEb @ 1826 NONAME - _ZN29QDeclarativeAbstractAnimation21setDisableUserControlEv @ 1827 NONAME - _ZN29QDeclarativeAbstractAnimation4stopEv @ 1828 NONAME - _ZN29QDeclarativeAbstractAnimation5pauseEv @ 1829 NONAME - _ZN29QDeclarativeAbstractAnimation5startEv @ 1830 NONAME - _ZN29QDeclarativeAbstractAnimation6resumeEv @ 1831 NONAME - _ZN29QDeclarativeAbstractAnimation7restartEv @ 1832 NONAME - _ZN29QDeclarativeAbstractAnimation7startedEv @ 1833 NONAME - _ZN29QDeclarativeAbstractAnimation8completeEv @ 1834 NONAME - _ZN29QDeclarativeAbstractAnimation8setGroupEP26QDeclarativeAnimationGroup @ 1835 NONAME - _ZN29QDeclarativeAbstractAnimation8setLoopsEi @ 1836 NONAME - _ZN29QDeclarativeAbstractAnimation9completedEv @ 1837 NONAME - _ZN29QDeclarativeAbstractAnimation9setPausedEb @ 1838 NONAME - _ZN29QDeclarativeAbstractAnimation9setTargetERK20QDeclarativeProperty @ 1839 NONAME - _ZN29QDeclarativeAbstractAnimationC2EP7QObject @ 1840 NONAME - _ZN29QDeclarativeAbstractAnimationC2ER36QDeclarativeAbstractAnimationPrivateP7QObject @ 1841 NONAME - _ZN29QDeclarativeAbstractAnimationD0Ev @ 1842 NONAME - _ZN29QDeclarativeAbstractAnimationD1Ev @ 1843 NONAME - _ZN29QDeclarativeAbstractAnimationD2Ev @ 1844 NONAME - _ZNK16QDeclarativeType20attachedPropertiesIdEv @ 1845 NONAME - _ZNK17QDeclarativeTimer10metaObjectEv @ 1846 NONAME - _ZNK17QDeclarativeTimer11isRepeatingEv @ 1847 NONAME - _ZNK17QDeclarativeTimer16triggeredOnStartEv @ 1848 NONAME - _ZNK17QDeclarativeTimer8intervalEv @ 1849 NONAME - _ZNK17QDeclarativeTimer9isRunningEv @ 1850 NONAME - _ZNK23QDeclarativeDebugClient6statusEv @ 1851 NONAME - _ZNK23QDeclarativeEngineDebug6statusEv @ 1852 NONAME - _ZNK24QDeclarativeDebugService6statusEv @ 1853 NONAME - _ZNK26QDeclarativeBasePositioner10metaObjectEv @ 1854 NONAME - _ZNK26QDeclarativeBasePositioner3addEv @ 1855 NONAME - _ZNK26QDeclarativeBasePositioner4moveEv @ 1856 NONAME - _ZNK26QDeclarativeBasePositioner7spacingEv @ 1857 NONAME - _ZNK29QDeclarativeAbstractAnimation10metaObjectEv @ 1858 NONAME - _ZNK29QDeclarativeAbstractAnimation14alwaysRunToEndEv @ 1859 NONAME - _ZNK29QDeclarativeAbstractAnimation5groupEv @ 1860 NONAME - _ZNK29QDeclarativeAbstractAnimation5loopsEv @ 1861 NONAME - _ZNK29QDeclarativeAbstractAnimation8isPausedEv @ 1862 NONAME - _ZNK29QDeclarativeAbstractAnimation9isRunningEv @ 1863 NONAME - _ZTI17QDeclarativeTimer @ 1864 NONAME - _ZTI26QDeclarativeBasePositioner @ 1865 NONAME - _ZTI29QDeclarativeAbstractAnimation @ 1866 NONAME - _ZTV17QDeclarativeTimer @ 1867 NONAME - _ZTV26QDeclarativeBasePositioner @ 1868 NONAME - _ZTV29QDeclarativeAbstractAnimation @ 1869 NONAME - _ZThn12_N29QDeclarativeAbstractAnimation10classBeginEv @ 1870 NONAME - _ZThn12_N29QDeclarativeAbstractAnimation17componentCompleteEv @ 1871 NONAME - _ZThn12_N29QDeclarativeAbstractAnimationD0Ev @ 1872 NONAME - _ZThn12_N29QDeclarativeAbstractAnimationD1Ev @ 1873 NONAME - _ZThn16_N26QDeclarativeBasePositioner17componentCompleteEv @ 1874 NONAME - _ZThn16_N26QDeclarativeBasePositionerD0Ev @ 1875 NONAME - _ZThn16_N26QDeclarativeBasePositionerD1Ev @ 1876 NONAME - _ZThn8_N17QDeclarativeTimer10classBeginEv @ 1877 NONAME - _ZThn8_N17QDeclarativeTimer17componentCompleteEv @ 1878 NONAME - _ZThn8_N26QDeclarativeBasePositioner10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant @ 1879 NONAME - _ZThn8_N26QDeclarativeBasePositionerD0Ev @ 1880 NONAME - _ZThn8_N26QDeclarativeBasePositionerD1Ev @ 1881 NONAME - _ZThn8_N29QDeclarativeAbstractAnimation9setTargetERK20QDeclarativeProperty @ 1882 NONAME - _ZThn8_N29QDeclarativeAbstractAnimationD0Ev @ 1883 NONAME - _ZThn8_N29QDeclarativeAbstractAnimationD1Ev @ 1884 NONAME diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 634b7af..4442d33 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -12097,5 +12097,4 @@ EXPORTS _ZN19QApplicationPrivate19qmljsDebugArgumentsE @ 12096 NONAME DATA 4 _ZN20QGraphicsItemPrivate26childrenBoundingRectHelperEP10QTransformP6QRectFP13QGraphicsItem @ 12097 NONAME _ZNK20QGraphicsItemPrivate21effectiveBoundingRectEP13QGraphicsItem @ 12098 NONAME - _ZNK5QFont14lastResortFontEv @ 12099 NONAME -- cgit v0.12 From 36dff2ee879021bbb0d2f1ca8826088a1969e8f0 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 6 Oct 2010 11:43:53 +0100 Subject: Fix for tst_qdir cd(non existant) test case Reviewed-By: Thomas Zander --- src/corelib/io/qfilesystemengine_symbian.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 1e6f277..318a5fd 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -240,6 +240,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM if (err) { data.size_ = 0; data.modificationTime_ = TTime(0); + data.entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags); } } return data.hasFlags(what); -- cgit v0.12 From 3f8476b9d7dc6bf45db5c3e959d7bc045099cd08 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 6 Oct 2010 11:45:03 +0100 Subject: Implement error reporting for QFile position and size functions Reviewed-By: Thomas Zander --- src/corelib/io/qfsfileengine_unix.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index acb58a5..f5d40f1 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -518,6 +518,7 @@ qint64 QFSFileEnginePrivate::nativeWrite(const char *data, qint64 len) qint64 QFSFileEnginePrivate::nativePos() const { #ifdef Q_OS_SYMBIAN + const Q_Q(QFSFileEngine); if (symbianFile.SubSessionHandle()) { #ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API qint64 pos = 0; @@ -526,8 +527,7 @@ qint64 QFSFileEnginePrivate::nativePos() const #endif TInt err = symbianFile.Seek(ESeekCurrent, pos); if(err != KErrNone) { - //TODO: error reporting - //setSymbianError(err, QFile::PositionError, QLatin1String("seek failed")); + const_cast(q)->setError(QFile::PositionError, QFileSystemEngine::errorString(err)); return -1; } return pos; @@ -635,6 +635,7 @@ bool QFSFileEngine::link(const QString &newName) qint64 QFSFileEnginePrivate::nativeSize() const { #ifdef Q_OS_SYMBIAN + const Q_Q(QFSFileEngine); if (symbianFile.SubSessionHandle()) { #ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API qint64 size; @@ -643,7 +644,7 @@ qint64 QFSFileEnginePrivate::nativeSize() const #endif TInt err = symbianFile.Size(size); if(err != KErrNone) { - //TODO: error reporting + const_cast(q)->setError(QFile::PositionError, QFileSystemEngine::errorString(err)); return 0; } return size; -- cgit v0.12 From c509f556628fa73192604869b3f1135af5e447ca Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 6 Oct 2010 11:46:16 +0100 Subject: Add test case for enumerating an empty directory Reviewed-By: Thomas Zander --- tests/auto/qdiriterator/tst_qdiriterator.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/auto/qdiriterator/tst_qdiriterator.cpp b/tests/auto/qdiriterator/tst_qdiriterator.cpp index d93e91e..3a696b5 100644 --- a/tests/auto/qdiriterator/tst_qdiriterator.cpp +++ b/tests/auto/qdiriterator/tst_qdiriterator.cpp @@ -155,6 +155,8 @@ tst_QDirIterator::tst_QDirIterator() createDirectory("foo/bar"); createFile("foo/bar/readme.txt"); + createDirectory("empty"); + #ifndef Q_NO_SYMLINKS # if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) // ### Sadly, this is a platform difference right now. @@ -296,6 +298,20 @@ void tst_QDirIterator::iterateRelativeDirectory_data() #endif "entrylist/directory/dummy," "entrylist/writable").split(','); + + QTest::newRow("empty, default") + << QString("empty") << QDirIterator::IteratorFlags(0) + << QDir::Filters(QDir::NoFilter) << QStringList("*") +#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE) + << QStringList(); +#else + << QString("empty/.,empty/..").split(','); +#endif + + QTest::newRow("empty, QDir::NoDotAndDotDot") + << QString("empty") << QDirIterator::IteratorFlags(0) + << QDir::Filters(QDir::NoDotAndDotDot) << QStringList("*") + << QStringList(); } void tst_QDirIterator::iterateRelativeDirectory() -- cgit v0.12 From a9a7fa34f12c54df4951c7e3b3afd6b9712ea57a Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 6 Oct 2010 12:23:14 +0100 Subject: Fix RVCT compile error in tst_collections Reviewed-By: Olivier Goffart --- tests/auto/collections/tst_collections.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/collections/tst_collections.cpp b/tests/auto/collections/tst_collections.cpp index 0adceee..82ec0fa 100644 --- a/tests/auto/collections/tst_collections.cpp +++ b/tests/auto/collections/tst_collections.cpp @@ -3632,7 +3632,7 @@ template class C> void QTBUG13079_collectionInsideCollect } -static quint32 qHash(const QTBUG13079_Node &) +quint32 qHash(const QTBUG13079_Node &) { return 0; } -- cgit v0.12 From b5e87cbc927bbc5e58574c510dbd967c46da4bee Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 6 Oct 2010 16:28:05 +0100 Subject: Fix tst_qtemporaryfile failures on symbian The path created by the _gettemp function is not a native path, as it contains the wrong slashes. So convert it back to a QString first. Check for symbian file handle in the isReallyOpen function so that reopening temp files works correctly. Reviewed-By: Thomas Zander --- src/corelib/io/qtemporaryfile.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 479ea20..79dfa35 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -325,6 +325,9 @@ bool QTemporaryFileEngine::isReallyOpen() Q_D(QFSFileEngine); if (!((0 == d->fh) && (-1 == d->fd) +#if defined (Q_OS_SYMBIAN) + && (0 == d->symbianFile.SubSessionHandle()) +#endif #if defined Q_OS_WIN && (INVALID_HANDLE_VALUE == d->fileHandle) #endif @@ -377,7 +380,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) d->closeFileHandle = true; // Restore the file names (open() resets them). - d->fileEntry = QFileSystemEntry(QByteArray(filename), QFileSystemEntry::FromNativePath()); //changed now! + d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(filename)); //note that filename is NOT a native path filePathIsTemplate = false; delete [] filename; return true; -- cgit v0.12 From f571cba1997d142e5c9a08472b4489de61471c76 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 6 Oct 2010 17:16:16 +0100 Subject: Remove setSymbianError function Qt autotests require the same error code on all platforms, and the OS specific error to be in text format in the errorString. Tests were failing due to QFile::error returning more detailed information than was wanted. Reviewed-By: Thomas Zander --- src/corelib/io/qfsfileengine_unix.cpp | 41 ++++------------------------------- 1 file changed, 4 insertions(+), 37 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index f5d40f1..a64f8dc 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -83,39 +83,6 @@ static bool isRelativePathSymbian(const QString& fileName) || (fileName.at(0) == QLatin1Char('/') && fileName.at(1) == QLatin1Char('/'))))); } -/*! - \internal - convert symbian error code to the one suitable for setError. - example usage: setSymbianError(err, QFile::CopyError, QLatin1String("copy error")) -*/ -void QFSFileEnginePrivate::setSymbianError(int symbianError, QFile::FileError defaultError, QString defaultString) -{ - Q_Q(QFSFileEngine); - switch (symbianError) { - case KErrNone: - q->setError(QFile::NoError, QLatin1String("")); - break; - case KErrAccessDenied: - q->setError(QFile::PermissionsError, QLatin1String("access denied")); - break; - case KErrPermissionDenied: - q->setError(QFile::PermissionsError, QLatin1String("permission denied")); - break; - case KErrAbort: - q->setError(QFile::AbortError, QLatin1String("aborted")); - break; - case KErrCancel: - q->setError(QFile::AbortError, QLatin1String("cancelled")); - break; - case KErrTimedOut: - q->setError(QFile::TimeOutError, QLatin1String("timed out")); - break; - default: - q->setError(defaultError, defaultString); - break; - } -} - #endif /*! @@ -272,7 +239,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) } if (r != KErrNone) { - setSymbianError(r, QFile::OpenError, QLatin1String("open error")); + q->setError(QFile::OpenError, QFileSystemEngine::errorString(r)); symbianFile.Close(); return false; } @@ -418,7 +385,7 @@ qint64 QFSFileEnginePrivate::nativeRead(char *data, qint64 len) TInt r = symbianFile.Read(ptr); if (r != KErrNone) { - setSymbianError(r, QFile::ReadError, QLatin1String("read error")); + q->setError(QFile::ReadError, QFileSystemEngine::errorString(r)); return -1; } return qint64(ptr.Length()); @@ -503,7 +470,7 @@ qint64 QFSFileEnginePrivate::nativeWrite(const char *data, qint64 len) TInt r = symbianFile.Write(ptr); if (r != KErrNone) { - setSymbianError(r, QFile::WriteError, QLatin1String("write error")); + q->setError(QFile::WriteError, QFileSystemEngine::errorString(r)); return -1; } return len; @@ -556,7 +523,7 @@ bool QFSFileEnginePrivate::nativeSeek(qint64 pos) #endif if (r != KErrNone) { - setSymbianError(r, QFile::PositionError, QLatin1String("seek failed")); + q->setError(QFile::PositionError, QFileSystemEngine::errorString(r)); return false; } return true; -- cgit v0.12 From a3427f351c1cfde94c5d55c03ba1a82c56d9b53d Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Thu, 7 Oct 2010 15:45:32 +0200 Subject: Fix compile --- src/corelib/io/qfilesystemengine_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 7c733c4..213fdc3 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -586,7 +586,7 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst Q_UNUSED(source); Q_UNUSED(target); // # we can implement this using sendfile(2) - errorString = QLatin1String("Not implemented!") + errorString = QLatin1String("Not implemented!"); return false; } -- cgit v0.12 From a780773292c3a59e1500f5e36c3de729a8f45f1c Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 8 Oct 2010 10:43:40 +0100 Subject: Create QSystemError class This class is for holding errors returned from system calls, which can be later converted to a string when a string is needed. This will eventually replace the setError(int,string) used in file engines so that strings are only created on demand. The scope of an error is used to distinguish error codes from the C standard library vs error codes from native calls. On some OS (e.g.windows) these error ranges overlap. Reviewed-By: joao --- src/corelib/kernel/kernel.pri | 118 +++++++++++----------- src/corelib/kernel/qsystemerror.cpp | 190 ++++++++++++++++++++++++++++++++++++ src/corelib/kernel/qsystemerror_p.h | 107 ++++++++++++++++++++ 3 files changed, 357 insertions(+), 58 deletions(-) create mode 100644 src/corelib/kernel/qsystemerror.cpp create mode 100644 src/corelib/kernel/qsystemerror_p.h diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 1851e04..bd674a5 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -1,81 +1,83 @@ # Qt core object module HEADERS += \ - kernel/qabstracteventdispatcher.h \ + kernel/qabstracteventdispatcher.h \ kernel/qabstractitemmodel.h \ kernel/qabstractitemmodel_p.h \ - kernel/qbasictimer.h \ - kernel/qeventloop.h\ - kernel/qpointer.h \ + kernel/qbasictimer.h \ + kernel/qeventloop.h\ + kernel/qpointer.h \ kernel/qcorecmdlineargs_p.h \ - kernel/qcoreapplication.h \ - kernel/qcoreevent.h \ - kernel/qmetaobject.h \ - kernel/qmetatype.h \ - kernel/qmimedata.h \ - kernel/qobject.h \ - kernel/qobjectdefs.h \ - kernel/qsignalmapper.h \ - kernel/qsocketnotifier.h \ - kernel/qtimer.h \ - kernel/qtranslator.h \ + kernel/qcoreapplication.h \ + kernel/qcoreevent.h \ + kernel/qmetaobject.h \ + kernel/qmetatype.h \ + kernel/qmimedata.h \ + kernel/qobject.h \ + kernel/qobjectdefs.h \ + kernel/qsignalmapper.h \ + kernel/qsocketnotifier.h \ + kernel/qtimer.h \ + kernel/qtranslator.h \ kernel/qtranslator_p.h \ kernel/qvariant.h \ - kernel/qabstracteventdispatcher_p.h \ - kernel/qcoreapplication_p.h \ - kernel/qobjectcleanuphandler.h \ + kernel/qabstracteventdispatcher_p.h \ + kernel/qcoreapplication_p.h \ + kernel/qobjectcleanuphandler.h \ kernel/qvariant_p.h \ kernel/qmetaobject_p.h \ kernel/qobject_p.h \ - kernel/qcoreglobaldata_p.h \ - kernel/qsharedmemory.h \ + kernel/qcoreglobaldata_p.h \ + kernel/qsharedmemory.h \ kernel/qsharedmemory_p.h \ kernel/qsystemsemaphore.h \ kernel/qsystemsemaphore_p.h \ kernel/qfunctions_p.h \ - kernel/qmath.h + kernel/qmath.h \ + kernel/qsystemerror_p.h SOURCES += \ - kernel/qabstracteventdispatcher.cpp \ + kernel/qabstracteventdispatcher.cpp \ kernel/qabstractitemmodel.cpp \ - kernel/qbasictimer.cpp \ - kernel/qeventloop.cpp \ - kernel/qcoreapplication.cpp \ - kernel/qcoreevent.cpp \ - kernel/qmetaobject.cpp \ - kernel/qmetatype.cpp \ - kernel/qmimedata.cpp \ - kernel/qobject.cpp \ - kernel/qobjectcleanuphandler.cpp \ - kernel/qsignalmapper.cpp \ - kernel/qsocketnotifier.cpp \ - kernel/qtimer.cpp \ - kernel/qtranslator.cpp \ - kernel/qvariant.cpp \ + kernel/qbasictimer.cpp \ + kernel/qeventloop.cpp \ + kernel/qcoreapplication.cpp \ + kernel/qcoreevent.cpp \ + kernel/qmetaobject.cpp \ + kernel/qmetatype.cpp \ + kernel/qmimedata.cpp \ + kernel/qobject.cpp \ + kernel/qobjectcleanuphandler.cpp \ + kernel/qsignalmapper.cpp \ + kernel/qsocketnotifier.cpp \ + kernel/qtimer.cpp \ + kernel/qtranslator.cpp \ + kernel/qvariant.cpp \ kernel/qcoreglobaldata.cpp \ kernel/qsharedmemory.cpp \ kernel/qsystemsemaphore.cpp \ kernel/qpointer.cpp \ - kernel/qmath.cpp + kernel/qmath.cpp \ + kernel/qsystemerror.cpp win32 { - SOURCES += \ - kernel/qeventdispatcher_win.cpp \ - kernel/qcoreapplication_win.cpp \ - kernel/qwineventnotifier_p.cpp \ + SOURCES += \ + kernel/qeventdispatcher_win.cpp \ + kernel/qcoreapplication_win.cpp \ + kernel/qwineventnotifier_p.cpp \ kernel/qsharedmemory_win.cpp \ kernel/qsystemsemaphore_win.cpp - HEADERS += \ - kernel/qeventdispatcher_win_p.h \ - kernel/qwineventnotifier_p.h + HEADERS += \ + kernel/qeventdispatcher_win_p.h \ + kernel/qwineventnotifier_p.h } wince*: { - SOURCES += \ - kernel/qfunctions_wince.cpp - HEADERS += \ - kernel/qfunctions_wince.h + SOURCES += \ + kernel/qfunctions_wince.cpp + HEADERS += \ + kernel/qfunctions_wince.h } mac:!embedded { @@ -85,18 +87,18 @@ mac:!embedded { mac { SOURCES += \ - kernel/qcore_mac.cpp + kernel/qcore_mac.cpp } unix:!symbian { - SOURCES += \ + SOURCES += \ kernel/qcore_unix.cpp \ kernel/qcrashhandler.cpp \ kernel/qsharedmemory_unix.cpp \ kernel/qsystemsemaphore_unix.cpp - HEADERS += \ + HEADERS += \ kernel/qcore_unix_p.h \ - kernel/qcrashhandler_p.h + kernel/qcrashhandler_p.h contains(QT_CONFIG, glib) { SOURCES += \ @@ -115,7 +117,7 @@ unix:!symbian { } symbian { - SOURCES += \ + SOURCES += \ kernel/qcore_unix.cpp \ kernel/qcrashhandler.cpp \ kernel/qeventdispatcher_symbian.cpp \ @@ -123,7 +125,7 @@ symbian { kernel/qsharedmemory_symbian.cpp \ kernel/qsystemsemaphore_symbian.cpp - HEADERS += \ + HEADERS += \ kernel/qcore_unix_p.h \ kernel/qcrashhandler_p.h \ kernel/qeventdispatcher_symbian_p.h \ @@ -131,9 +133,9 @@ symbian { } vxworks { - SOURCES += \ - kernel/qfunctions_vxworks.cpp - HEADERS += \ - kernel/qfunctions_vxworks.h + SOURCES += \ + kernel/qfunctions_vxworks.cpp + HEADERS += \ + kernel/qfunctions_vxworks.h } diff --git a/src/corelib/kernel/qsystemerror.cpp b/src/corelib/kernel/qsystemerror.cpp new file mode 100644 index 0000000..065014a --- /dev/null +++ b/src/corelib/kernel/qsystemerror.cpp @@ -0,0 +1,190 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "qsystemerror_p.h" +#include + +static QString standardLibraryErrorString(int errorCode) +{ + const char *s = 0; + QString ret; + switch (errorCode) { + case 0: + break; + case EACCES: + s = QT_TRANSLATE_NOOP("QIODevice", "Permission denied"); + break; + case EMFILE: + s = QT_TRANSLATE_NOOP("QIODevice", "Too many open files"); + break; + case ENOENT: + s = QT_TRANSLATE_NOOP("QIODevice", "No such file or directory"); + break; + case ENOSPC: + s = QT_TRANSLATE_NOOP("QIODevice", "No space left on device"); + break; + default: { + #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) + QByteArray buf(1024, '\0'); + ret = fromstrerror_helper(strerror_r(errorCode, buf.data(), buf.size()), buf); + #else + ret = QString::fromLocal8Bit(strerror(errorCode)); + #endif + break; } + } + if (s) { + // ######## this breaks moc build currently + // ret = QCoreApplication::translate("QIODevice", s); + ret = QString::fromLatin1(s); + } + return ret.trimmed(); +} + +#ifdef Q_OS_WIN +static QString windowsErrorString(int errorCode) +{ + QString ret; + wchar_t *string = 0; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + errorCode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR)&string, + 0, + NULL); + ret = QString::fromWCharArray(string); + LocalFree((HLOCAL)string); + + if (ret.isEmpty() && errorCode == ERROR_MOD_NOT_FOUND) + ret = QString::fromLatin1("The specified module could not be found."); + return ret; +} +#endif + +#ifdef Q_OS_SYMBIAN +static QString symbianErrorString(int errorCode) +{ + switch (errorCode) { + case KErrNotFound: + return QLatin1String("not found"); + case KErrCancel: + return QLatin1String("cancelled"); + case KErrNoMemory: + return QLatin1String("out of memory"); + case KErrNotSupported: + return QLatin1String("not supported"); + case KErrBadHandle: + return QLatin1String("bad handle"); //KERN-EXEC 0 panic is more likely + case KErrAlreadyExists: + return QLatin1String("already exists"); + case KErrPathNotFound: + return QLatin1String("path not found"); + case KErrInUse: + return QLatin1String("in use"); + case KErrNotReady: + return QLatin1String("not ready (e.g. FS dismounted, no memory card)"); + case KErrCorrupt: + return QLatin1String("corrupt"); + case KErrAccessDenied: + return QLatin1String("access denied"); + case KErrLocked: + return QLatin1String("locked"); + case KErrWrite: + return QLatin1String("incomplete write error"); + case KErrDisMounted: + return QLatin1String("file system dismounted during operation"); //i.e. a forcible dismount was done while we had files open + case KErrEof: + return QLatin1String("end of file"); + case KErrDiskFull: + return QLatin1String("no space in file system"); + case KErrBadName: + return QLatin1String("invalid filename"); + case KErrTimedOut: + return QLatin1String("timed out"); + case KErrBadDescriptor: + return QLatin1String("bad descriptor (passed address on stack to async call?)"); + case KErrAbort: + return QLatin1String("aborted"); + case KErrTooBig: + return QLatin1String("too big"); //e.g. trying to open a >2GB file with 32 bit API + case KErrBadPower: + return QLatin1String("insufficient power"); + case KErrDirFull: + return QLatin1String("no space in directory table"); + case KErrHardwareNotAvailable: + return QLatin1String("hardware not available"); + case KErrSessionClosed: + return QLatin1String("session closed"); + case KErrPermissionDenied: + return QLatin1String("permission denied"); + default: + return QString(QLatin1String("symbian error %d")).arg(errorCode); + } +} +#endif + +QString QSystemError::toString() +{ + switch(errorScope) { + case NativeError: +#if defined (Q_OS_WIN) + errorString = windowsErrorString(errorCode); + break; +#elif defined (Q_OS_SYMBIAN) + return symbianErrorString(errorCode); + break; +#else + //unix: fall through as native and standard library are the same +#endif + case StandardLibraryError: + return standardLibraryErrorString(errorCode); + break; + default: + qWarning("invalid error scope"); + //fall through + case NoError: + return QLatin1String("No error"); + break; + } +} + +QT_END_NAMESPACE + diff --git a/src/corelib/kernel/qsystemerror_p.h b/src/corelib/kernel/qsystemerror_p.h new file mode 100644 index 0000000..c2a13a8 --- /dev/null +++ b/src/corelib/kernel/qsystemerror_p.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** 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 QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef QSYSTEMERROR_P_H +#define QSYSTEMERROR_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 + +QT_BEGIN_NAMESPACE + +class Q_CORE_EXPORT QSystemError +{ +public: + enum ErrorScope + { + NoError, + StandardLibraryError, + NativeError + }; + + inline QSystemError(int error, ErrorScope scope); + inline QSystemError(); + + QString toString(); + inline ErrorScope scope(); + inline int error(); + + //data members + int errorCode; + ErrorScope errorScope; +}; + +QSystemError::QSystemError(int error, QSystemError::ErrorScope scope) +: errorCode(error), errorScope(scope) +{ + +} + +QSystemError::QSystemError() +: errorCode(0), errorScope(NoError) +{ + +} + +QSystemError::ErrorScope QSystemError::scope() +{ + return errorScope; +} + +int QSystemError::error() +{ + return errorCode; +} + + +QT_END_NAMESPACE + +#endif // QSYSTEMERROR_P_H -- cgit v0.12 From bb66cbc4287d17a3f368d3e46e98ca026a5332c7 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 8 Oct 2010 15:26:36 +0100 Subject: Update DEF files Reviewed-By: Trust Me --- src/s60installs/bwins/QtCoreu.def | 13 +++ src/s60installs/bwins/QtGuiu.def | 75 ++++++++++++++-- src/s60installs/bwins/QtNetworku.def | 7 ++ src/s60installs/eabi/QtCoreu.def | 56 +++++++++++- src/s60installs/eabi/QtDeclarativeu.def | 149 ++++++++++++++++++++++++++++++-- src/s60installs/eabi/QtGuiu.def | 68 +++++++++++++-- src/s60installs/eabi/QtNetworku.def | 7 ++ 7 files changed, 353 insertions(+), 22 deletions(-) diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def index 052ec9a..4ad9fbb 100644 --- a/src/s60installs/bwins/QtCoreu.def +++ b/src/s60installs/bwins/QtCoreu.def @@ -4526,4 +4526,17 @@ EXPORTS ?unlockInternal@QMutex@@AAEXXZ @ 4525 NONAME ; void QMutex::unlockInternal(void) ?waitForDone@QThreadPool@@QAE_NH@Z @ 4526 NONAME ; bool QThreadPool::waitForDone(int) ?app_compile_version@QCoreApplicationPrivate@@2HA @ 4527 NONAME ; int QCoreApplicationPrivate::app_compile_version + ??0QFileInfo@@QAE@PAVQFileInfoPrivate@@@Z @ 4528 NONAME ; QFileInfo::QFileInfo(class QFileInfoPrivate *) + ??0QSystemError@@QAE@HW4ErrorScope@0@@Z @ 4529 NONAME ; QSystemError::QSystemError(int, enum QSystemError::ErrorScope) + ??0QSystemError@@QAE@XZ @ 4530 NONAME ; QSystemError::QSystemError(void) + ?cast@QMetaObject@@QBEPBVQObject@@PBV2@@Z @ 4531 NONAME ; class QObject const * QMetaObject::cast(class QObject const *) const + ?error@QSystemError@@QAEHXZ @ 4532 NONAME ; int QSystemError::error(void) + ?qt_symbian_SetupThreadHeap@@YAHHAAUSStdEpocThreadCreateInfo@@@Z @ 4533 NONAME ; int qt_symbian_SetupThreadHeap(int, struct SStdEpocThreadCreateInfo &) + ?scope@QSystemError@@QAE?AW4ErrorScope@1@XZ @ 4534 NONAME ; enum QSystemError::ErrorScope QSystemError::scope(void) + ?toAscii@QStringRef@@QBE?AVQByteArray@@XZ @ 4535 NONAME ; class QByteArray QStringRef::toAscii(void) const + ?toLatin1@QStringRef@@QBE?AVQByteArray@@XZ @ 4536 NONAME ; class QByteArray QStringRef::toLatin1(void) const + ?toLocal8Bit@QStringRef@@QBE?AVQByteArray@@XZ @ 4537 NONAME ; class QByteArray QStringRef::toLocal8Bit(void) const + ?toString@QSystemError@@QAE?AVQString@@XZ @ 4538 NONAME ; class QString QSystemError::toString(void) + ?toUcs4@QStringRef@@QBE?AV?$QVector@I@@XZ @ 4539 NONAME ; class QVector QStringRef::toUcs4(void) const + ?toUtf8@QStringRef@@QBE?AVQByteArray@@XZ @ 4540 NONAME ; class QByteArray QStringRef::toUtf8(void) const diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 9a61523..305952c 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -35,7 +35,7 @@ EXPORTS ??0QApplication@@QAE@AAHPAPADW4Type@0@H@Z @ 34 NONAME ; QApplication::QApplication(int &, char * *, enum QApplication::Type, int) ??0QApplication@@QAE@AAHPAPAD_NH@Z @ 35 NONAME ; QApplication::QApplication(int &, char * *, bool, int) ??0QApplication@@QAE@P6APAVCApaApplication@@XZAAHPAPADH@Z @ 36 NONAME ; QApplication::QApplication(class CApaApplication * (*)(void), int &, char * *, int) - ??0QApplicationPrivate@@QAE@AAHPAPADW4Type@QApplication@@@Z @ 37 NONAME ; QApplicationPrivate::QApplicationPrivate(int &, char * *, enum QApplication::Type) + ??0QApplicationPrivate@@QAE@AAHPAPADW4Type@QApplication@@@Z @ 37 NONAME ABSENT ; QApplicationPrivate::QApplicationPrivate(int &, char * *, enum QApplication::Type) ??0QBitmap@@QAE@ABVQPixmap@@@Z @ 38 NONAME ; QBitmap::QBitmap(class QPixmap const &) ??0QBitmap@@QAE@ABVQSize@@@Z @ 39 NONAME ; QBitmap::QBitmap(class QSize const &) ??0QBitmap@@QAE@ABVQString@@PBD@Z @ 40 NONAME ; QBitmap::QBitmap(class QString const &, char const *) @@ -2195,7 +2195,7 @@ EXPORTS ?alphaF@QColor@@QBEMXZ @ 2194 NONAME ; float QColor::alphaF(void) const ?alphaMapForGlyph@QFontEngine@@UAE?AVQImage@@I@Z @ 2195 NONAME ; class QImage QFontEngine::alphaMapForGlyph(unsigned int) ?alphaMapForGlyph@QFontEngine@@UAE?AVQImage@@IABVQTransform@@@Z @ 2196 NONAME ; class QImage QFontEngine::alphaMapForGlyph(unsigned int, class QTransform const &) - ?alphaRGBMapForGlyph@QFontEngine@@UAE?AVQImage@@IHABVQTransform@@@Z @ 2197 NONAME ; class QImage QFontEngine::alphaRGBMapForGlyph(unsigned int, int, class QTransform const &) + ?alphaRGBMapForGlyph@QFontEngine@@UAE?AVQImage@@IHABVQTransform@@@Z @ 2197 NONAME ABSENT ; class QImage QFontEngine::alphaRGBMapForGlyph(unsigned int, int, class QTransform const &) ?alterCharForCapitalization@QFontPrivate@@QBEXAAVQChar@@@Z @ 2198 NONAME ; void QFontPrivate::alterCharForCapitalization(class QChar &) const ?alternateBase@QPalette@@QBEABVQBrush@@XZ @ 2199 NONAME ; class QBrush const & QPalette::alternateBase(void) const ?alternatingRowColors@QAbstractItemView@@QBE_NXZ @ 2200 NONAME ; bool QAbstractItemView::alternatingRowColors(void) const @@ -10909,7 +10909,7 @@ EXPORTS ?textWidth@QTextDocument@@QBEMXZ @ 10908 NONAME ; float QTextDocument::textWidth(void) const ?texture@QBrush@@QBE?AVQPixmap@@XZ @ 10909 NONAME ; class QPixmap QBrush::texture(void) const ?textureImage@QBrush@@QBE?AVQImage@@XZ @ 10910 NONAME ; class QImage QBrush::textureImage(void) const - ?textureMapForGlyph@QTextureGlyphCache@@QBE?AVQImage@@I@Z @ 10911 NONAME ; class QImage QTextureGlyphCache::textureMapForGlyph(unsigned int) const + ?textureMapForGlyph@QTextureGlyphCache@@QBE?AVQImage@@I@Z @ 10911 NONAME ABSENT ; class QImage QTextureGlyphCache::textureMapForGlyph(unsigned int) const ?themeName@QIcon@@SA?AVQString@@XZ @ 10912 NONAME ; class QString QIcon::themeName(void) ?themeSearchPaths@QIcon@@SA?AVQStringList@@XZ @ 10913 NONAME ; class QStringList QIcon::themeSearchPaths(void) ?tickInterval@QSlider@@QBEHXZ @ 10914 NONAME ; int QSlider::tickInterval(void) const @@ -12511,7 +12511,7 @@ EXPORTS ?staticMetaObject@QFileSystemModel@@2UQMetaObject@@B @ 12510 NONAME ; struct QMetaObject const QFileSystemModel::staticMetaObject ?staticMetaObject@QKeyEventTransition@@2UQMetaObject@@B @ 12511 NONAME ; struct QMetaObject const QKeyEventTransition::staticMetaObject ?staticMetaObject@QLayout@@2UQMetaObject@@B @ 12512 NONAME ; struct QMetaObject const QLayout::staticMetaObject - ?app_compile_version@QApplicationPrivate@@2HA @ 12513 NONAME ; int QApplicationPrivate::app_compile_version + ?app_compile_version@QApplicationPrivate@@2HA @ 12513 NONAME ABSENT ; int QApplicationPrivate::app_compile_version ?spacerItemFactoryMethod@QLayoutPrivate@@2P6APAVQSpacerItem@@PBVQLayout@@HHW4Policy@QSizePolicy@@1@ZA @ 12514 NONAME ; class QSpacerItem * (*QLayoutPrivate::spacerItemFactoryMethod)(class QLayout const *, int, int, enum QSizePolicy::Policy, enum QSizePolicy::Policy) ?allWidgets@QWidgetPrivate@@2PAV?$QSet@PAVQWidget@@@@A @ 12515 NONAME ; class QSet * QWidgetPrivate::allWidgets ?effectiveFocusWidget@QWidgetPrivate@@QAEPAVQWidget@@XZ @ 12516 NONAME ; class QWidget * QWidgetPrivate::effectiveFocusWidget(void) @@ -12522,7 +12522,7 @@ EXPORTS ?addCacheData@QVectorPath@@QBEPAUCacheEntry@1@PAVQPaintEngineEx@@PAXP6AX01@Z@Z @ 12521 NONAME ; struct QVectorPath::CacheEntry * QVectorPath::addCacheData(class QPaintEngineEx *, void *, void (*)(class QPaintEngineEx *, void *)) const ?discardUpdateRequest@QGraphicsItemPrivate@@QBE_N_N00@Z @ 12522 NONAME ; bool QGraphicsItemPrivate::discardUpdateRequest(bool, bool, bool) const ?makeCacheable@QVectorPath@@QBEXXZ @ 12523 NONAME ; void QVectorPath::makeCacheable(void) const - ??0Tab@QTextOption@@QAE@ABU01@@Z @ 12524 NONAME ; QTextOption::Tab::Tab(struct QTextOption::Tab const &) + ??0Tab@QTextOption@@QAE@ABU01@@Z @ 12524 NONAME ABSENT ; QTextOption::Tab::Tab(struct QTextOption::Tab const &) ?effectiveBoundingRect@QGraphicsItemPrivate@@QBE?AVQRectF@@ABV2@@Z @ 12525 NONAME ; class QRectF QGraphicsItemPrivate::effectiveBoundingRect(class QRectF const &) const ?glyphCache@QFontEngine@@QBEPAVQFontEngineGlyphCache@@PAXW4Type@2@ABVQTransform@@@Z @ 12526 NONAME ; class QFontEngineGlyphCache * QFontEngine::glyphCache(void *, enum QFontEngineGlyphCache::Type, class QTransform const &) const ?qt_blurImage@@YAXAAVQImage@@M_NH@Z @ 12527 NONAME ; void qt_blurImage(class QImage &, float, bool, int) @@ -12824,7 +12824,7 @@ EXPORTS ?fromImageReader@QPixmapData@@UAEXPAVQImageReader@@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 12823 NONAME ; void QPixmapData::fromImageReader(class QImageReader *, class QFlags) ?toPolygon@QBezier@@QBE?AVQPolygonF@@M@Z @ 12824 NONAME ; class QPolygonF QBezier::toPolygon(float) const ?prepare@QStaticText@@QAEXABVQTransform@@ABVQFont@@@Z @ 12825 NONAME ; void QStaticText::prepare(class QTransform const &, class QFont const &) - ?fillTexture@QImageTextureGlyphCache@@UAEXABUCoord@QTextureGlyphCache@@I@Z @ 12826 NONAME ; void QImageTextureGlyphCache::fillTexture(struct QTextureGlyphCache::Coord const &, unsigned int) + ?fillTexture@QImageTextureGlyphCache@@UAEXABUCoord@QTextureGlyphCache@@I@Z @ 12826 NONAME ABSENT ; void QImageTextureGlyphCache::fillTexture(struct QTextureGlyphCache::Coord const &, unsigned int) ?OpenFileL@QS60MainDocument@@UAEXAAPAVCFileStore@@AAVRFile@@@Z @ 12827 NONAME ; void QS60MainDocument::OpenFileL(class CFileStore * &, class RFile &) ?fixup@QIntValidator@@UBEXAAVQString@@@Z @ 12828 NONAME ; void QIntValidator::fixup(class QString &) const ?resetHeight@QGraphicsItemPrivate@@UAEXXZ @ 12829 NONAME ; void QGraphicsItemPrivate::resetHeight(void) @@ -12893,4 +12893,67 @@ EXPORTS ?qmljsDebugArguments@QApplicationPrivate@@2VQString@@A @ 12892 NONAME ; class QString QApplicationPrivate::qmljsDebugArguments ?effectiveBoundingRect@QGraphicsItemPrivate@@QBE?AVQRectF@@PAVQGraphicsItem@@@Z @ 12893 NONAME ; class QRectF QGraphicsItemPrivate::effectiveBoundingRect(class QGraphicsItem *) const ?lastResortFont@QFont@@QBE?AVQString@@XZ @ 12894 NONAME ; class QString QFont::lastResortFont(void) const + ??0QApplicationPrivate@@QAE@AAHPAPADW4Type@QApplication@@H@Z @ 12895 NONAME ; QApplicationPrivate::QApplicationPrivate(int &, char * *, enum QApplication::Type, int) + ??0QGlyphs@@QAE@ABV0@@Z @ 12896 NONAME ; QGlyphs::QGlyphs(class QGlyphs const &) + ??0QGlyphs@@QAE@XZ @ 12897 NONAME ; QGlyphs::QGlyphs(void) + ??1QGlyphs@@QAE@XZ @ 12898 NONAME ; QGlyphs::~QGlyphs(void) + ??4QGlyphs@@QAEAAV0@ABV0@@Z @ 12899 NONAME ; class QGlyphs & QGlyphs::operator=(class QGlyphs const &) + ??6@YA?AVQDebug@@V0@PBVQSymbianEvent@@@Z @ 12900 NONAME ; class QDebug operator<<(class QDebug, class QSymbianEvent const *) + ??8QGlyphs@@QBE_NABV0@@Z @ 12901 NONAME ; bool QGlyphs::operator==(class QGlyphs const &) const + ??9QGlyphs@@QBE_NABV0@@Z @ 12902 NONAME ; bool QGlyphs::operator!=(class QGlyphs const &) const + ??HQGlyphs@@ABE?AV0@ABV0@@Z @ 12903 NONAME ; class QGlyphs QGlyphs::operator+(class QGlyphs const &) const + ??MQItemSelectionRange@@QBE_NABV0@@Z @ 12904 NONAME ; bool QItemSelectionRange::operator<(class QItemSelectionRange const &) const + ??YQGlyphs@@AAEAAV0@ABV0@@Z @ 12905 NONAME ; class QGlyphs & QGlyphs::operator+=(class QGlyphs const &) + ?alphaRGBMapForGlyph@QFontEngine@@UAE?AVQImage@@IUQFixed@@HABVQTransform@@@Z @ 12906 NONAME ; class QImage QFontEngine::alphaRGBMapForGlyph(unsigned int, struct QFixed, int, class QTransform const &) + ?buddy@QAbstractProxyModel@@UBE?AVQModelIndex@@ABV2@@Z @ 12907 NONAME ; class QModelIndex QAbstractProxyModel::buddy(class QModelIndex const &) const + ?calculateSubPixelPositionCount@QTextureGlyphCache@@IBEHI@Z @ 12908 NONAME ; int QTextureGlyphCache::calculateSubPixelPositionCount(unsigned int) const + ?canFetchMore@QAbstractProxyModel@@UBE_NABVQModelIndex@@@Z @ 12909 NONAME ; bool QAbstractProxyModel::canFetchMore(class QModelIndex const &) const + ?clear@QGlyphs@@QAEXXZ @ 12910 NONAME ; void QGlyphs::clear(void) + ?clipBoundingRect@QPainter@@QBE?AVQRectF@@XZ @ 12911 NONAME ; class QRectF QPainter::clipBoundingRect(void) const + ?convertToPostscriptFontFamilyName@QFontEngine@@SA?AVQByteArray@@ABV2@@Z @ 12912 NONAME ; class QByteArray QFontEngine::convertToPostscriptFontFamilyName(class QByteArray const &) + ?createExplicitFont@QFontEngine@@UBE?AVQFont@@XZ @ 12913 NONAME ; class QFont QFontEngine::createExplicitFont(void) const + ?createExplicitFontWithName@QFontEngine@@IBE?AVQFont@@ABVQString@@@Z @ 12914 NONAME ; class QFont QFontEngine::createExplicitFontWithName(class QString const &) const + ?detach@QGlyphs@@AAEXXZ @ 12915 NONAME ; void QGlyphs::detach(void) + ?drawGlyphs@QPainter@@QAEXABVQPointF@@ABVQGlyphs@@@Z @ 12916 NONAME ; void QPainter::drawGlyphs(class QPointF const &, class QGlyphs const &) + ?fetchMore@QAbstractProxyModel@@UAEXABVQModelIndex@@@Z @ 12917 NONAME ; void QAbstractProxyModel::fetchMore(class QModelIndex const &) + ?fill@QImage@@QAEXABVQColor@@@Z @ 12918 NONAME ; void QImage::fill(class QColor const &) + ?fill@QImage@@QAEXW4GlobalColor@Qt@@@Z @ 12919 NONAME ; void QImage::fill(enum Qt::GlobalColor) + ?fillInPendingGlyphs@QTextureGlyphCache@@QAEXXZ @ 12920 NONAME ; void QTextureGlyphCache::fillInPendingGlyphs(void) + ?fillTexture@QImageTextureGlyphCache@@UAEXABUCoord@QTextureGlyphCache@@IUQFixed@@@Z @ 12921 NONAME ; void QImageTextureGlyphCache::fillTexture(struct QTextureGlyphCache::Coord const &, unsigned int, struct QFixed) + ?font@QGlyphs@@QBE?AVQFont@@XZ @ 12922 NONAME ; class QFont QGlyphs::font(void) const + ?get@QFontPrivate@@SAPAV1@ABVQFont@@@Z @ 12923 NONAME ; class QFontPrivate * QFontPrivate::get(class QFont const &) + ?glyphIndexes@QGlyphs@@QBE?AV?$QVector@I@@XZ @ 12924 NONAME ; class QVector QGlyphs::glyphIndexes(void) const + ?glyphs@QTextFragment@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 12925 NONAME ; class QList QTextFragment::glyphs(void) const + ?glyphs@QTextLayout@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 12926 NONAME ; class QList QTextLayout::glyphs(void) const + ?glyphs@QTextLine@@ABE?AV?$QList@VQGlyphs@@@@HH@Z @ 12927 NONAME ; class QList QTextLine::glyphs(int, int) const + ?hasChildren@QAbstractProxyModel@@UBE_NABVQModelIndex@@@Z @ 12928 NONAME ; bool QAbstractProxyModel::hasChildren(class QModelIndex const &) const + ?hasHeightForWidth@QWidgetPrivate@@UBE_NXZ @ 12929 NONAME ; bool QWidgetPrivate::hasHeightForWidth(void) const + ?hasWidthForHeight@QSizePolicy@@QBE_NXZ @ 12930 NONAME ; bool QSizePolicy::hasWidthForHeight(void) const + ?heightForWidth@QTabWidget@@UBEHH@Z @ 12931 NONAME ; int QTabWidget::heightForWidth(int) const + ?inFontUcs4@QFontMetrics@@QBE_NI@Z @ 12932 NONAME ; bool QFontMetrics::inFontUcs4(unsigned int) const + ?inFontUcs4@QFontMetricsF@@QBE_NI@Z @ 12933 NONAME ; bool QFontMetricsF::inFontUcs4(unsigned int) const + ?maxTextureHeight@QTextureGlyphCache@@UBEHXZ @ 12934 NONAME ; int QTextureGlyphCache::maxTextureHeight(void) const + ?maxTextureWidth@QTextureGlyphCache@@UBEHXZ @ 12935 NONAME ; int QTextureGlyphCache::maxTextureWidth(void) const + ?mimeData@QAbstractProxyModel@@UBEPAVQMimeData@@ABV?$QList@VQModelIndex@@@@@Z @ 12936 NONAME ; class QMimeData * QAbstractProxyModel::mimeData(class QList const &) const + ?mimeTypes@QAbstractProxyModel@@UBE?AVQStringList@@XZ @ 12937 NONAME ; class QStringList QAbstractProxyModel::mimeTypes(void) const + ?minimumSizeHint@QCheckBox@@UBE?AVQSize@@XZ @ 12938 NONAME ; class QSize QCheckBox::minimumSizeHint(void) const + ?minimumSizeHint@QRadioButton@@UBE?AVQSize@@XZ @ 12939 NONAME ; class QSize QRadioButton::minimumSizeHint(void) const + ?numberPrefix@QTextListFormat@@QBE?AVQString@@XZ @ 12940 NONAME ; class QString QTextListFormat::numberPrefix(void) const + ?numberSuffix@QTextListFormat@@QBE?AVQString@@XZ @ 12941 NONAME ; class QString QTextListFormat::numberSuffix(void) const + ?positions@QGlyphs@@QBE?AV?$QVector@VQPointF@@@@XZ @ 12942 NONAME ; class QVector QGlyphs::positions(void) const + ?removeItem@QGraphicsGridLayout@@QAEXPAVQGraphicsLayoutItem@@@Z @ 12943 NONAME ; void QGraphicsGridLayout::removeItem(class QGraphicsLayoutItem *) + ?resizeCache@QTextureGlyphCache@@QAEXHH@Z @ 12944 NONAME ; void QTextureGlyphCache::resizeCache(int, int) + ?setFont@QGlyphs@@QAEXABVQFont@@@Z @ 12945 NONAME ; void QGlyphs::setFont(class QFont const &) + ?setGlyphIndexes@QGlyphs@@QAEXABV?$QVector@I@@@Z @ 12946 NONAME ; void QGlyphs::setGlyphIndexes(class QVector const &) + ?setItemData@QAbstractProxyModel@@UAE_NABVQModelIndex@@ABV?$QMap@HVQVariant@@@@@Z @ 12947 NONAME ; bool QAbstractProxyModel::setItemData(class QModelIndex const &, class QMap const &) + ?setNumberPrefix@QTextListFormat@@QAEXABVQString@@@Z @ 12948 NONAME ; void QTextListFormat::setNumberPrefix(class QString const &) + ?setNumberSuffix@QTextListFormat@@QAEXABVQString@@@Z @ 12949 NONAME ; void QTextListFormat::setNumberSuffix(class QString const &) + ?setPositions@QGlyphs@@QAEXABV?$QVector@VQPointF@@@@@Z @ 12950 NONAME ; void QGlyphs::setPositions(class QVector const &) + ?setWidthForHeight@QSizePolicy@@QAEX_N@Z @ 12951 NONAME ; void QSizePolicy::setWidthForHeight(bool) + ?sort@QAbstractProxyModel@@UAEXHW4SortOrder@Qt@@@Z @ 12952 NONAME ; void QAbstractProxyModel::sort(int, enum Qt::SortOrder) + ?span@QAbstractProxyModel@@UBE?AVQSize@@ABVQModelIndex@@@Z @ 12953 NONAME ; class QSize QAbstractProxyModel::span(class QModelIndex const &) const + ?subPixelPositionForX@QTextureGlyphCache@@QBE?AUQFixed@@U2@@Z @ 12954 NONAME ; struct QFixed QTextureGlyphCache::subPixelPositionForX(struct QFixed) const + ?supportedDropActions@QAbstractProxyModel@@UBE?AV?$QFlags@W4DropAction@Qt@@@@XZ @ 12955 NONAME ; class QFlags QAbstractProxyModel::supportedDropActions(void) const + ?supportsSubPixelPositions@QFontEngine@@UBE_NXZ @ 12956 NONAME ; bool QFontEngine::supportsSubPixelPositions(void) const + ?textureMapForGlyph@QTextureGlyphCache@@QBE?AVQImage@@IUQFixed@@@Z @ 12957 NONAME ; class QImage QTextureGlyphCache::textureMapForGlyph(unsigned int, struct QFixed) const diff --git a/src/s60installs/bwins/QtNetworku.def b/src/s60installs/bwins/QtNetworku.def index 21718d3..ef43370 100644 --- a/src/s60installs/bwins/QtNetworku.def +++ b/src/s60installs/bwins/QtNetworku.def @@ -1145,4 +1145,11 @@ EXPORTS ?setNetworkAccessible@QNetworkAccessManager@@QAEXW4NetworkAccessibility@1@@Z @ 1144 NONAME ; void QNetworkAccessManager::setNetworkAccessible(enum QNetworkAccessManager::NetworkAccessibility) ??_EQBearerEngineFactoryInterface@@UAE@I@Z @ 1145 NONAME ; QBearerEngineFactoryInterface::~QBearerEngineFactoryInterface(unsigned int) ?enablePolling@QNetworkConfigurationManagerPrivate@@QAEXXZ @ 1146 NONAME ; void QNetworkConfigurationManagerPrivate::enablePolling(void) + ?joinMulticastGroup@QUdpSocket@@QAE_NABVQHostAddress@@@Z @ 1147 NONAME ; bool QUdpSocket::joinMulticastGroup(class QHostAddress const &) + ?joinMulticastGroup@QUdpSocket@@QAE_NABVQHostAddress@@ABVQNetworkInterface@@@Z @ 1148 NONAME ; bool QUdpSocket::joinMulticastGroup(class QHostAddress const &, class QNetworkInterface const &) + ?leaveMulticastGroup@QUdpSocket@@QAE_NABVQHostAddress@@@Z @ 1149 NONAME ; bool QUdpSocket::leaveMulticastGroup(class QHostAddress const &) + ?leaveMulticastGroup@QUdpSocket@@QAE_NABVQHostAddress@@ABVQNetworkInterface@@@Z @ 1150 NONAME ; bool QUdpSocket::leaveMulticastGroup(class QHostAddress const &, class QNetworkInterface const &) + ?multicastInterface@QUdpSocket@@QBE?AVQNetworkInterface@@XZ @ 1151 NONAME ; class QNetworkInterface QUdpSocket::multicastInterface(void) const + ?setFinished@QNetworkReply@@IAEX_N@Z @ 1152 NONAME ; void QNetworkReply::setFinished(bool) + ?setMulticastInterface@QUdpSocket@@QAEXABVQNetworkInterface@@@Z @ 1153 NONAME ; void QUdpSocket::setMulticastInterface(class QNetworkInterface const &) diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index 01679be..ab2c5e5 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -620,8 +620,8 @@ EXPORTS _ZN14QObjectPrivate11clearGuardsEP7QObject @ 619 NONAME _ZN14QObjectPrivate13addConnectionEiPNS_10ConnectionE @ 620 NONAME _ZN14QObjectPrivate14deleteChildrenEv @ 621 NONAME - _ZN14QObjectPrivate14setDeleteWatchEPS_Pi @ 622 NONAME - _ZN14QObjectPrivate16resetDeleteWatchEPS_Pii @ 623 NONAME + _ZN14QObjectPrivate14setDeleteWatchEPS_Pi @ 622 NONAME ABSENT + _ZN14QObjectPrivate16resetDeleteWatchEPS_Pii @ 623 NONAME ABSENT _ZN14QObjectPrivate16setCurrentSenderEP7QObjectPNS_6SenderE @ 624 NONAME ABSENT _ZN14QObjectPrivate16setParent_helperEP7QObject @ 625 NONAME _ZN14QObjectPrivate18resetCurrentSenderEP7QObjectPNS_6SenderES3_ @ 626 NONAME ABSENT @@ -1274,8 +1274,8 @@ EXPORTS _ZN23QCoreApplicationPrivate34sendThroughApplicationEventFiltersEP7QObjectP6QEvent @ 1273 NONAME _ZN23QCoreApplicationPrivate35appendApplicationPathToLibraryPathsEv @ 1274 NONAME _ZN23QCoreApplicationPrivate7attribsE @ 1275 NONAME DATA 4 - _ZN23QCoreApplicationPrivateC1ERiPPc @ 1276 NONAME - _ZN23QCoreApplicationPrivateC2ERiPPc @ 1277 NONAME + _ZN23QCoreApplicationPrivateC1ERiPPc @ 1276 NONAME ABSENT + _ZN23QCoreApplicationPrivateC2ERiPPc @ 1277 NONAME ABSENT _ZN23QCoreApplicationPrivateD0Ev @ 1278 NONAME _ZN23QCoreApplicationPrivateD1Ev @ 1279 NONAME _ZN23QCoreApplicationPrivateD2Ev @ 1280 NONAME @@ -3711,4 +3711,52 @@ EXPORTS _ZlsR11QDataStreamRK12QEasingCurve @ 3710 NONAME _ZltRK13QElapsedTimerS1_ @ 3711 NONAME _ZrsR11QDataStreamR12QEasingCurve @ 3712 NONAME + _Z26qt_symbian_SetupThreadHeapiR24SStdEpocThreadCreateInfo @ 3713 NONAME + _ZN11QThreadPool11waitForDoneEi @ 3714 NONAME + _ZN12QSystemError8toStringEv @ 3715 NONAME + _ZN13QSharedMemory12setNativeKeyERK7QString @ 3716 NONAME + _ZN16QCoreApplicationC1ERiPPci @ 3717 NONAME + _ZN16QCoreApplicationC2ERiPPci @ 3718 NONAME + _ZN23QCoreApplicationPrivate19app_compile_versionE @ 3719 NONAME DATA 4 + _ZN23QCoreApplicationPrivateC1ERiPPcj @ 3720 NONAME + _ZN23QCoreApplicationPrivateC2ERiPPcj @ 3721 NONAME + _ZN6QMutex12lockInternalEv @ 3722 NONAME + _ZN6QMutex14unlockInternalEv @ 3723 NONAME + _ZN7QObject10disconnectEPKS_RK11QMetaMethodS1_S4_ @ 3724 NONAME + _ZN7QObject7connectEPKS_RK11QMetaMethodS1_S4_N2Qt14ConnectionTypeE @ 3725 NONAME + _ZN9QFileInfoC1EP16QFileInfoPrivate @ 3726 NONAME + _ZN9QFileInfoC2EP16QFileInfoPrivate @ 3727 NONAME + _ZNK10QStringRef10startsWithE13QLatin1StringN2Qt15CaseSensitivityE @ 3728 NONAME + _ZNK10QStringRef10startsWithE5QCharN2Qt15CaseSensitivityE @ 3729 NONAME + _ZNK10QStringRef10startsWithERK7QStringN2Qt15CaseSensitivityE @ 3730 NONAME + _ZNK10QStringRef10startsWithERKS_N2Qt15CaseSensitivityE @ 3731 NONAME + _ZNK10QStringRef11lastIndexOfE13QLatin1StringiN2Qt15CaseSensitivityE @ 3732 NONAME + _ZNK10QStringRef11lastIndexOfE5QChariN2Qt15CaseSensitivityE @ 3733 NONAME + _ZNK10QStringRef11lastIndexOfERK7QStringiN2Qt15CaseSensitivityE @ 3734 NONAME + _ZNK10QStringRef11lastIndexOfERKS_iN2Qt15CaseSensitivityE @ 3735 NONAME + _ZNK10QStringRef11toLocal8BitEv @ 3736 NONAME + _ZNK10QStringRef5countE5QCharN2Qt15CaseSensitivityE @ 3737 NONAME + _ZNK10QStringRef5countERK7QStringN2Qt15CaseSensitivityE @ 3738 NONAME + _ZNK10QStringRef5countERKS_N2Qt15CaseSensitivityE @ 3739 NONAME + _ZNK10QStringRef6toUcs4Ev @ 3740 NONAME + _ZNK10QStringRef6toUtf8Ev @ 3741 NONAME + _ZNK10QStringRef7indexOfE13QLatin1StringiN2Qt15CaseSensitivityE @ 3742 NONAME + _ZNK10QStringRef7indexOfE5QChariN2Qt15CaseSensitivityE @ 3743 NONAME + _ZNK10QStringRef7indexOfERK7QStringiN2Qt15CaseSensitivityE @ 3744 NONAME + _ZNK10QStringRef7indexOfERKS_iN2Qt15CaseSensitivityE @ 3745 NONAME + _ZNK10QStringRef7toAsciiEv @ 3746 NONAME + _ZNK10QStringRef8endsWithE13QLatin1StringN2Qt15CaseSensitivityE @ 3747 NONAME + _ZNK10QStringRef8endsWithE5QCharN2Qt15CaseSensitivityE @ 3748 NONAME + _ZNK10QStringRef8endsWithERK7QStringN2Qt15CaseSensitivityE @ 3749 NONAME + _ZNK10QStringRef8endsWithERKS_N2Qt15CaseSensitivityE @ 3750 NONAME + _ZNK10QStringRef8toLatin1Ev @ 3751 NONAME + _ZNK11QMetaObject4castEPK7QObject @ 3752 NONAME + _ZNK13QSharedMemory9nativeKeyEv @ 3753 NONAME + _ZNK4QUrl11isLocalFileEv @ 3754 NONAME + _ZNK7QObject17senderSignalIndexEv @ 3755 NONAME + _ZNK7QString10startsWithERK10QStringRefN2Qt15CaseSensitivityE @ 3756 NONAME + _ZNK7QString11lastIndexOfERK10QStringRefiN2Qt15CaseSensitivityE @ 3757 NONAME + _ZNK7QString5countERK10QStringRefN2Qt15CaseSensitivityE @ 3758 NONAME + _ZNK7QString7indexOfERK10QStringRefiN2Qt15CaseSensitivityE @ 3759 NONAME + _ZNK7QString8endsWithERK10QStringRefN2Qt15CaseSensitivityE @ 3760 NONAME diff --git a/src/s60installs/eabi/QtDeclarativeu.def b/src/s60installs/eabi/QtDeclarativeu.def index 11dee4d..c0b43ac 100644 --- a/src/s60installs/eabi/QtDeclarativeu.def +++ b/src/s60installs/eabi/QtDeclarativeu.def @@ -673,7 +673,7 @@ EXPORTS _ZN22QDeclarativeTransitionD0Ev @ 672 NONAME _ZN22QDeclarativeTransitionD1Ev @ 673 NONAME _ZN22QDeclarativeTransitionD2Ev @ 674 NONAME - _ZN23QDeclarativeDebugClient10setEnabledEb @ 675 NONAME + _ZN23QDeclarativeDebugClient10setEnabledEb @ 675 NONAME ABSENT _ZN23QDeclarativeDebugClient11qt_metacallEN11QMetaObject4CallEiPPv @ 676 NONAME _ZN23QDeclarativeDebugClient11qt_metacastEPKc @ 677 NONAME _ZN23QDeclarativeDebugClient11sendMessageERK10QByteArray @ 678 NONAME @@ -766,7 +766,7 @@ EXPORTS _ZN24QDeclarativeDebugService11qt_metacallEN11QMetaObject4CallEiPPv @ 765 NONAME _ZN24QDeclarativeDebugService11qt_metacastEPKc @ 766 NONAME _ZN24QDeclarativeDebugService11sendMessageERK10QByteArray @ 767 NONAME - _ZN24QDeclarativeDebugService14enabledChangedEb @ 768 NONAME + _ZN24QDeclarativeDebugService14enabledChangedEb @ 768 NONAME ABSENT _ZN24QDeclarativeDebugService14objectToStringEP7QObject @ 769 NONAME _ZN24QDeclarativeDebugService15messageReceivedERK10QByteArray @ 770 NONAME _ZN24QDeclarativeDebugService16staticMetaObjectE @ 771 NONAME DATA 16 @@ -1351,7 +1351,7 @@ EXPORTS _ZNK21QDeclarativeDomObject8propertyERK10QByteArray @ 1350 NONAME _ZNK21QDeclarativeListModel10metaObjectEv @ 1351 NONAME _ZNK21QDeclarativeListModel3getEi @ 1352 NONAME - _ZNK21QDeclarativeListModel4dataEiRK5QListIiE @ 1353 NONAME + _ZNK21QDeclarativeListModel4dataEiRK5QListIiE @ 1353 NONAME ABSENT _ZNK21QDeclarativeListModel4dataEii @ 1354 NONAME _ZNK21QDeclarativeListModel5countEv @ 1355 NONAME _ZNK21QDeclarativeListModel5rolesEv @ 1356 NONAME @@ -1390,9 +1390,9 @@ EXPORTS _ZNK22QDeclarativeTransition7toStateEv @ 1389 NONAME _ZNK22QDeclarativeTransition9fromStateEv @ 1390 NONAME _ZNK23QDeclarativeDebugClient10metaObjectEv @ 1391 NONAME - _ZNK23QDeclarativeDebugClient11isConnectedEv @ 1392 NONAME + _ZNK23QDeclarativeDebugClient11isConnectedEv @ 1392 NONAME ABSENT _ZNK23QDeclarativeDebugClient4nameEv @ 1393 NONAME - _ZNK23QDeclarativeDebugClient9isEnabledEv @ 1394 NONAME + _ZNK23QDeclarativeDebugClient9isEnabledEv @ 1394 NONAME ABSENT _ZNK23QDeclarativeDomDocument10rootObjectEv @ 1395 NONAME _ZNK23QDeclarativeDomDocument6errorsEv @ 1396 NONAME _ZNK23QDeclarativeDomDocument7importsEv @ 1397 NONAME @@ -1427,7 +1427,7 @@ EXPORTS _ZNK24QDeclarativeCustomParser12evaluateEnumERK10QByteArray @ 1426 NONAME _ZNK24QDeclarativeDebugService10metaObjectEv @ 1427 NONAME _ZNK24QDeclarativeDebugService4nameEv @ 1428 NONAME - _ZNK24QDeclarativeDebugService9isEnabledEv @ 1429 NONAME + _ZNK24QDeclarativeDebugService9isEnabledEv @ 1429 NONAME ABSENT _ZNK24QDeclarativeDomComponent13componentRootEv @ 1430 NONAME _ZNK24QDeclarativeScriptString11scopeObjectEv @ 1431 NONAME _ZNK24QDeclarativeScriptString6scriptEv @ 1432 NONAME @@ -1747,4 +1747,141 @@ EXPORTS _ZN21QDeclarativeListModelC1EPKS_P32QDeclarativeListModelWorkerAgent @ 1746 NONAME _ZN21QDeclarativeListModelC2EPKS_P32QDeclarativeListModelWorkerAgent @ 1747 NONAME _ZNK21QDeclarativeListModel14inWorkerThreadEv @ 1748 NONAME + _ZN17QDeclarativeTimer10classBeginEv @ 1749 NONAME + _ZN17QDeclarativeTimer10setRunningEb @ 1750 NONAME + _ZN17QDeclarativeTimer11qt_metacallEN11QMetaObject4CallEiPPv @ 1751 NONAME + _ZN17QDeclarativeTimer11qt_metacastEPKc @ 1752 NONAME + _ZN17QDeclarativeTimer11setIntervalEi @ 1753 NONAME + _ZN17QDeclarativeTimer12setRepeatingEb @ 1754 NONAME + _ZN17QDeclarativeTimer13repeatChangedEv @ 1755 NONAME + _ZN17QDeclarativeTimer14runningChangedEv @ 1756 NONAME + _ZN17QDeclarativeTimer15intervalChangedEv @ 1757 NONAME + _ZN17QDeclarativeTimer16staticMetaObjectE @ 1758 NONAME DATA 16 + _ZN17QDeclarativeTimer17componentCompleteEv @ 1759 NONAME + _ZN17QDeclarativeTimer19getStaticMetaObjectEv @ 1760 NONAME + _ZN17QDeclarativeTimer19setTriggeredOnStartEb @ 1761 NONAME + _ZN17QDeclarativeTimer23triggeredOnStartChangedEv @ 1762 NONAME + _ZN17QDeclarativeTimer4stopEv @ 1763 NONAME + _ZN17QDeclarativeTimer5startEv @ 1764 NONAME + _ZN17QDeclarativeTimer6tickedEv @ 1765 NONAME + _ZN17QDeclarativeTimer6updateEv @ 1766 NONAME + _ZN17QDeclarativeTimer7restartEv @ 1767 NONAME + _ZN17QDeclarativeTimer8finishedEv @ 1768 NONAME + _ZN17QDeclarativeTimer9triggeredEv @ 1769 NONAME + _ZN17QDeclarativeTimerC1EP7QObject @ 1770 NONAME + _ZN17QDeclarativeTimerC2EP7QObject @ 1771 NONAME + _ZN23QDeclarativeDebugClient13statusChangedENS_6StatusE @ 1772 NONAME + _ZN23QDeclarativeDebugClientD0Ev @ 1773 NONAME + _ZN23QDeclarativeDebugClientD1Ev @ 1774 NONAME + _ZN23QDeclarativeDebugClientD2Ev @ 1775 NONAME + _ZN23QDeclarativeDebugHelper15getScriptEngineEP18QDeclarativeEngine @ 1776 NONAME + _ZN23QDeclarativeDebugHelper26setAnimationSlowDownFactorEf @ 1777 NONAME + _ZN23QDeclarativeEngineDebug13statusChangedENS_6StatusE @ 1778 NONAME + _ZN24QDeclarativeDebugService13statusChangedENS_6StatusE @ 1779 NONAME + _ZN24QDeclarativeDebugServiceD0Ev @ 1780 NONAME + _ZN24QDeclarativeDebugServiceD1Ev @ 1781 NONAME + _ZN24QDeclarativeDebugServiceD2Ev @ 1782 NONAME + _ZN26QDeclarativeBasePositioner10addChangedEv @ 1783 NONAME + _ZN26QDeclarativeBasePositioner10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant @ 1784 NONAME + _ZN26QDeclarativeBasePositioner10setSpacingEi @ 1785 NONAME + _ZN26QDeclarativeBasePositioner11moveChangedEv @ 1786 NONAME + _ZN26QDeclarativeBasePositioner11qt_metacallEN11QMetaObject4CallEiPPv @ 1787 NONAME + _ZN26QDeclarativeBasePositioner11qt_metacastEPKc @ 1788 NONAME + _ZN26QDeclarativeBasePositioner14prePositioningEv @ 1789 NONAME + _ZN26QDeclarativeBasePositioner14spacingChangedEv @ 1790 NONAME + _ZN26QDeclarativeBasePositioner16staticMetaObjectE @ 1791 NONAME DATA 16 + _ZN26QDeclarativeBasePositioner17componentCompleteEv @ 1792 NONAME + _ZN26QDeclarativeBasePositioner19getStaticMetaObjectEv @ 1793 NONAME + _ZN26QDeclarativeBasePositioner22finishApplyTransitionsEv @ 1794 NONAME + _ZN26QDeclarativeBasePositioner29graphicsWidgetGeometryChangedEv @ 1795 NONAME + _ZN26QDeclarativeBasePositioner6setAddEP22QDeclarativeTransition @ 1796 NONAME + _ZN26QDeclarativeBasePositioner7setMoveEP22QDeclarativeTransition @ 1797 NONAME + _ZN26QDeclarativeBasePositioner9positionXEiRKNS_14PositionedItemE @ 1798 NONAME + _ZN26QDeclarativeBasePositioner9positionYEiRKNS_14PositionedItemE @ 1799 NONAME + _ZN26QDeclarativeBasePositionerC2ENS_14PositionerTypeEP16QDeclarativeItem @ 1800 NONAME + _ZN26QDeclarativeBasePositionerC2ER33QDeclarativeBasePositionerPrivateNS_14PositionerTypeEP16QDeclarativeItem @ 1801 NONAME + _ZN26QDeclarativeBasePositionerD0Ev @ 1802 NONAME + _ZN26QDeclarativeBasePositionerD1Ev @ 1803 NONAME + _ZN26QDeclarativeBasePositionerD2Ev @ 1804 NONAME + _ZN27QDeclarativeDebugConnectionD0Ev @ 1805 NONAME + _ZN27QDeclarativeDebugConnectionD1Ev @ 1806 NONAME + _ZN27QDeclarativeDebugConnectionD2Ev @ 1807 NONAME + _ZN27QDeclarativePropertyPrivate7connectEPK7QObjectiS2_iiPi @ 1808 NONAME + _ZN29QDeclarativeAbstractAnimation10classBeginEv @ 1809 NONAME + _ZN29QDeclarativeAbstractAnimation10setRunningEb @ 1810 NONAME + _ZN29QDeclarativeAbstractAnimation10transitionER5QListI18QDeclarativeActionERS0_I20QDeclarativePropertyENS_19TransitionDirectionE @ 1811 NONAME + _ZN29QDeclarativeAbstractAnimation11currentTimeEv @ 1812 NONAME + _ZN29QDeclarativeAbstractAnimation11qt_metacallEN11QMetaObject4CallEiPPv @ 1813 NONAME + _ZN29QDeclarativeAbstractAnimation11qt_metacastEPKc @ 1814 NONAME + _ZN29QDeclarativeAbstractAnimation13pausedChangedEb @ 1815 NONAME + _ZN29QDeclarativeAbstractAnimation14runningChangedEb @ 1816 NONAME + _ZN29QDeclarativeAbstractAnimation14setCurrentTimeEi @ 1817 NONAME + _ZN29QDeclarativeAbstractAnimation16loopCountChangedEi @ 1818 NONAME + _ZN29QDeclarativeAbstractAnimation16setDefaultTargetERK20QDeclarativeProperty @ 1819 NONAME + _ZN29QDeclarativeAbstractAnimation16staticMetaObjectE @ 1820 NONAME DATA 16 + _ZN29QDeclarativeAbstractAnimation16timelineCompleteEv @ 1821 NONAME + _ZN29QDeclarativeAbstractAnimation17componentCompleteEv @ 1822 NONAME + _ZN29QDeclarativeAbstractAnimation17setAlwaysRunToEndEb @ 1823 NONAME + _ZN29QDeclarativeAbstractAnimation18componentFinalizedEv @ 1824 NONAME + _ZN29QDeclarativeAbstractAnimation19getStaticMetaObjectEv @ 1825 NONAME + _ZN29QDeclarativeAbstractAnimation20notifyRunningChangedEb @ 1826 NONAME + _ZN29QDeclarativeAbstractAnimation21alwaysRunToEndChangedEb @ 1827 NONAME + _ZN29QDeclarativeAbstractAnimation21setDisableUserControlEv @ 1828 NONAME + _ZN29QDeclarativeAbstractAnimation4stopEv @ 1829 NONAME + _ZN29QDeclarativeAbstractAnimation5pauseEv @ 1830 NONAME + _ZN29QDeclarativeAbstractAnimation5startEv @ 1831 NONAME + _ZN29QDeclarativeAbstractAnimation6resumeEv @ 1832 NONAME + _ZN29QDeclarativeAbstractAnimation7restartEv @ 1833 NONAME + _ZN29QDeclarativeAbstractAnimation7startedEv @ 1834 NONAME + _ZN29QDeclarativeAbstractAnimation8completeEv @ 1835 NONAME + _ZN29QDeclarativeAbstractAnimation8setGroupEP26QDeclarativeAnimationGroup @ 1836 NONAME + _ZN29QDeclarativeAbstractAnimation8setLoopsEi @ 1837 NONAME + _ZN29QDeclarativeAbstractAnimation9completedEv @ 1838 NONAME + _ZN29QDeclarativeAbstractAnimation9setPausedEb @ 1839 NONAME + _ZN29QDeclarativeAbstractAnimation9setTargetERK20QDeclarativeProperty @ 1840 NONAME + _ZN29QDeclarativeAbstractAnimationC2EP7QObject @ 1841 NONAME + _ZN29QDeclarativeAbstractAnimationC2ER36QDeclarativeAbstractAnimationPrivateP7QObject @ 1842 NONAME + _ZN29QDeclarativeAbstractAnimationD0Ev @ 1843 NONAME + _ZN29QDeclarativeAbstractAnimationD1Ev @ 1844 NONAME + _ZN29QDeclarativeAbstractAnimationD2Ev @ 1845 NONAME + _ZNK16QDeclarativeType20attachedPropertiesIdEv @ 1846 NONAME + _ZNK17QDeclarativeTimer10metaObjectEv @ 1847 NONAME + _ZNK17QDeclarativeTimer11isRepeatingEv @ 1848 NONAME + _ZNK17QDeclarativeTimer16triggeredOnStartEv @ 1849 NONAME + _ZNK17QDeclarativeTimer8intervalEv @ 1850 NONAME + _ZNK17QDeclarativeTimer9isRunningEv @ 1851 NONAME + _ZNK23QDeclarativeDebugClient6statusEv @ 1852 NONAME + _ZNK23QDeclarativeEngineDebug6statusEv @ 1853 NONAME + _ZNK24QDeclarativeDebugService6statusEv @ 1854 NONAME + _ZNK26QDeclarativeBasePositioner10metaObjectEv @ 1855 NONAME + _ZNK26QDeclarativeBasePositioner3addEv @ 1856 NONAME + _ZNK26QDeclarativeBasePositioner4moveEv @ 1857 NONAME + _ZNK26QDeclarativeBasePositioner7spacingEv @ 1858 NONAME + _ZNK29QDeclarativeAbstractAnimation10metaObjectEv @ 1859 NONAME + _ZNK29QDeclarativeAbstractAnimation14alwaysRunToEndEv @ 1860 NONAME + _ZNK29QDeclarativeAbstractAnimation5groupEv @ 1861 NONAME + _ZNK29QDeclarativeAbstractAnimation5loopsEv @ 1862 NONAME + _ZNK29QDeclarativeAbstractAnimation8isPausedEv @ 1863 NONAME + _ZNK29QDeclarativeAbstractAnimation9isRunningEv @ 1864 NONAME + _ZTI17QDeclarativeTimer @ 1865 NONAME + _ZTI26QDeclarativeBasePositioner @ 1866 NONAME + _ZTI29QDeclarativeAbstractAnimation @ 1867 NONAME + _ZTV17QDeclarativeTimer @ 1868 NONAME + _ZTV26QDeclarativeBasePositioner @ 1869 NONAME + _ZTV29QDeclarativeAbstractAnimation @ 1870 NONAME + _ZThn12_N29QDeclarativeAbstractAnimation10classBeginEv @ 1871 NONAME + _ZThn12_N29QDeclarativeAbstractAnimation17componentCompleteEv @ 1872 NONAME + _ZThn12_N29QDeclarativeAbstractAnimationD0Ev @ 1873 NONAME + _ZThn12_N29QDeclarativeAbstractAnimationD1Ev @ 1874 NONAME + _ZThn16_N26QDeclarativeBasePositioner17componentCompleteEv @ 1875 NONAME + _ZThn16_N26QDeclarativeBasePositionerD0Ev @ 1876 NONAME + _ZThn16_N26QDeclarativeBasePositionerD1Ev @ 1877 NONAME + _ZThn8_N17QDeclarativeTimer10classBeginEv @ 1878 NONAME + _ZThn8_N17QDeclarativeTimer17componentCompleteEv @ 1879 NONAME + _ZThn8_N26QDeclarativeBasePositioner10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant @ 1880 NONAME + _ZThn8_N26QDeclarativeBasePositionerD0Ev @ 1881 NONAME + _ZThn8_N26QDeclarativeBasePositionerD1Ev @ 1882 NONAME + _ZThn8_N29QDeclarativeAbstractAnimation9setTargetERK20QDeclarativeProperty @ 1883 NONAME + _ZThn8_N29QDeclarativeAbstractAnimationD0Ev @ 1884 NONAME + _ZThn8_N29QDeclarativeAbstractAnimationD1Ev @ 1885 NONAME diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 634b7af..681649c 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -711,7 +711,7 @@ EXPORTS _ZN11QFontEngine17getGlyphPositionsERK12QGlyphLayoutRK10QTransform6QFlagsIN9QTextItem10RenderFlagEER15QVarLengthArrayIjLi256EERSA_I11QFixedPointLi256EE @ 710 NONAME _ZN11QFontEngine17getPointInOutlineEjijPiS0_Pj @ 711 NONAME _ZN11QFontEngine19addBitmapFontToPathEffRK12QGlyphLayoutP12QPainterPath6QFlagsIN9QTextItem10RenderFlagEE @ 712 NONAME - _ZN11QFontEngine19alphaRGBMapForGlyphEjiRK10QTransform @ 713 NONAME + _ZN11QFontEngine19alphaRGBMapForGlyphEjiRK10QTransform @ 713 NONAME ABSENT _ZN11QFontEngine20removeGlyphFromCacheEj @ 714 NONAME _ZN11QFontEngine21getTrueTypeGlyphIndexEPKhj @ 715 NONAME _ZN11QFontEngine7getCMapEPKhjPbPi @ 716 NONAME @@ -4324,7 +4324,7 @@ EXPORTS _ZN19QApplicationPrivate18dispatchEnterLeaveEP7QWidgetS1_ @ 4323 NONAME _ZN19QApplicationPrivate18resolveS60ScanCodeEij @ 4324 NONAME _ZN19QApplicationPrivate18wheel_scroll_linesE @ 4325 NONAME DATA 4 - _ZN19QApplicationPrivate19app_compile_versionE @ 4326 NONAME DATA 4 + _ZN19QApplicationPrivate19app_compile_versionE @ 4326 NONAME DATA 4 ABSENT _ZN19QApplicationPrivate19hidden_focus_widgetE @ 4327 NONAME DATA 4 _ZN19QApplicationPrivate19keyboard_input_timeE @ 4328 NONAME DATA 4 _ZN19QApplicationPrivate20emitLastWindowClosedEv @ 4329 NONAME @@ -4356,8 +4356,8 @@ EXPORTS _ZN19QApplicationPrivate9constructEv @ 4355 NONAME _ZN19QApplicationPrivate9fade_menuE @ 4356 NONAME DATA 1 _ZN19QApplicationPrivate9openPopupEP7QWidget @ 4357 NONAME - _ZN19QApplicationPrivateC1ERiPPcN12QApplication4TypeE @ 4358 NONAME - _ZN19QApplicationPrivateC2ERiPPcN12QApplication4TypeE @ 4359 NONAME + _ZN19QApplicationPrivateC1ERiPPcN12QApplication4TypeE @ 4358 NONAME ABSENT + _ZN19QApplicationPrivateC2ERiPPcN12QApplication4TypeE @ 4359 NONAME ABSENT _ZN19QApplicationPrivateD0Ev @ 4360 NONAME _ZN19QApplicationPrivateD1Ev @ 4361 NONAME _ZN19QApplicationPrivateD2Ev @ 4362 NONAME @@ -9242,7 +9242,7 @@ EXPORTS _ZNK18QSyntaxHighlighter20currentBlockUserDataEv @ 9241 NONAME _ZNK18QSyntaxHighlighter6formatEi @ 9242 NONAME _ZNK18QSyntaxHighlighter8documentEv @ 9243 NONAME - _ZNK18QTextureGlyphCache18textureMapForGlyphEj @ 9244 NONAME + _ZNK18QTextureGlyphCache18textureMapForGlyphEj @ 9244 NONAME ABSENT _ZNK19QAbstractProxyModel10headerDataEiN2Qt11OrientationEi @ 9245 NONAME _ZNK19QAbstractProxyModel10metaObjectEv @ 9246 NONAME _ZNK19QAbstractProxyModel11sourceModelEv @ 9247 NONAME @@ -11961,7 +11961,7 @@ EXPORTS _ZN20QGraphicsViewPrivate28updateInputMethodSensitivityEv @ 11960 NONAME _ZN20QGraphicsViewPrivateC1Ev @ 11961 NONAME _ZN20QGraphicsViewPrivateC2Ev @ 11962 NONAME - _ZN23QImageTextureGlyphCache11fillTextureERKN18QTextureGlyphCache5CoordEj @ 11963 NONAME + _ZN23QImageTextureGlyphCache11fillTextureERKN18QTextureGlyphCache5CoordEj @ 11963 NONAME ABSENT _ZN23QImageTextureGlyphCache17createTextureDataEii @ 11964 NONAME _ZN23QImageTextureGlyphCache17resizeTextureDataEii @ 11965 NONAME _ZN26QAbstractScrollAreaPrivate14layoutChildrenEv @ 11966 NONAME @@ -12098,4 +12098,60 @@ EXPORTS _ZN20QGraphicsItemPrivate26childrenBoundingRectHelperEP10QTransformP6QRectFP13QGraphicsItem @ 12097 NONAME _ZNK20QGraphicsItemPrivate21effectiveBoundingRectEP13QGraphicsItem @ 12098 NONAME _ZNK5QFont14lastResortFontEv @ 12099 NONAME + _ZN11QFontEngine19alphaRGBMapForGlyphEj6QFixediRK10QTransform @ 12100 NONAME + _ZN11QFontEngine33convertToPostscriptFontFamilyNameERK10QByteArray @ 12101 NONAME + _ZN18QTextureGlyphCache19fillInPendingGlyphsEv @ 12102 NONAME + _ZN19QAbstractProxyModel11setItemDataERK11QModelIndexRK4QMapIi8QVariantE @ 12103 NONAME + _ZN19QAbstractProxyModel4sortEiN2Qt9SortOrderE @ 12104 NONAME + _ZN19QAbstractProxyModel9fetchMoreERK11QModelIndex @ 12105 NONAME + _ZN19QApplicationPrivateC1ERiPPcN12QApplication4TypeEi @ 12106 NONAME + _ZN19QApplicationPrivateC2ERiPPcN12QApplication4TypeEi @ 12107 NONAME + _ZN19QGraphicsGridLayout10removeItemEP19QGraphicsLayoutItem @ 12108 NONAME + _ZN23QImageTextureGlyphCache11fillTextureERKN18QTextureGlyphCache5CoordEj6QFixed @ 12109 NONAME + _ZN6QImage4fillEN2Qt11GlobalColorE @ 12110 NONAME + _ZN6QImage4fillERK6QColor @ 12111 NONAME + _ZN7QGlyphs12setPositionsERK7QVectorI7QPointFE @ 12112 NONAME + _ZN7QGlyphs15setGlyphIndexesERK7QVectorIjE @ 12113 NONAME + _ZN7QGlyphs5clearEv @ 12114 NONAME + _ZN7QGlyphs6detachEv @ 12115 NONAME + _ZN7QGlyphs7setFontERK5QFont @ 12116 NONAME + _ZN7QGlyphsC1ERKS_ @ 12117 NONAME + _ZN7QGlyphsC1Ev @ 12118 NONAME + _ZN7QGlyphsC2ERKS_ @ 12119 NONAME + _ZN7QGlyphsC2Ev @ 12120 NONAME + _ZN7QGlyphsD1Ev @ 12121 NONAME + _ZN7QGlyphsD2Ev @ 12122 NONAME + _ZN7QGlyphsaSERKS_ @ 12123 NONAME + _ZN7QGlyphspLERKS_ @ 12124 NONAME + _ZN8QPainter10drawGlyphsERK7QPointFRK7QGlyphs @ 12125 NONAME + _ZNK10QTabWidget14heightForWidthEi @ 12126 NONAME + _ZNK11QFontEngine18createExplicitFontEv @ 12127 NONAME + _ZNK11QFontEngine26createExplicitFontWithNameERK7QString @ 12128 NONAME + _ZNK11QTextLayout6glyphsEv @ 12129 NONAME + _ZNK12QFontMetrics10inFontUcs4Ej @ 12130 NONAME + _ZNK12QRadioButton15minimumSizeHintEv @ 12131 NONAME + _ZNK13QFontMetricsF10inFontUcs4Ej @ 12132 NONAME + _ZNK13QTextFragment6glyphsEv @ 12133 NONAME + _ZNK14QWidgetPrivate17hasHeightForWidthEv @ 12134 NONAME + _ZNK16QFileSystemModel5rmdirERK11QModelIndex @ 12135 NONAME + _ZNK18QTextureGlyphCache18textureMapForGlyphEj6QFixed @ 12136 NONAME + _ZNK18QTextureGlyphCache20subPixelPositionForXE6QFixed @ 12137 NONAME + _ZNK18QTextureGlyphCache30calculateSubPixelPositionCountEj @ 12138 NONAME + _ZNK19QAbstractProxyModel11hasChildrenERK11QModelIndex @ 12139 NONAME + _ZNK19QAbstractProxyModel12canFetchMoreERK11QModelIndex @ 12140 NONAME + _ZNK19QAbstractProxyModel20supportedDropActionsEv @ 12141 NONAME + _ZNK19QAbstractProxyModel4spanERK11QModelIndex @ 12142 NONAME + _ZNK19QAbstractProxyModel5buddyERK11QModelIndex @ 12143 NONAME + _ZNK19QAbstractProxyModel8mimeDataERK5QListI11QModelIndexE @ 12144 NONAME + _ZNK19QAbstractProxyModel9mimeTypesEv @ 12145 NONAME + _ZNK7QGlyphs12glyphIndexesEv @ 12146 NONAME + _ZNK7QGlyphs4fontEv @ 12147 NONAME + _ZNK7QGlyphs9positionsEv @ 12148 NONAME + _ZNK7QGlyphseqERKS_ @ 12149 NONAME + _ZNK7QGlyphsneERKS_ @ 12150 NONAME + _ZNK7QGlyphsplERKS_ @ 12151 NONAME + _ZNK8QPainter16clipBoundingRectEv @ 12152 NONAME + _ZNK9QCheckBox15minimumSizeHintEv @ 12153 NONAME + _ZNK9QTextLine6glyphsEii @ 12154 NONAME + _Zls6QDebugPK13QSymbianEvent @ 12155 NONAME diff --git a/src/s60installs/eabi/QtNetworku.def b/src/s60installs/eabi/QtNetworku.def index f13fab3..21f3e73 100644 --- a/src/s60installs/eabi/QtNetworku.def +++ b/src/s60installs/eabi/QtNetworku.def @@ -1168,4 +1168,11 @@ EXPORTS _ZTV35QNetworkConfigurationManagerPrivate @ 1167 NONAME _ZThn8_N19QBearerEnginePluginD0Ev @ 1168 NONAME _ZThn8_N19QBearerEnginePluginD1Ev @ 1169 NONAME + _ZN10QUdpSocket18joinMulticastGroupERK12QHostAddress @ 1170 NONAME + _ZN10QUdpSocket18joinMulticastGroupERK12QHostAddressRK17QNetworkInterface @ 1171 NONAME + _ZN10QUdpSocket19leaveMulticastGroupERK12QHostAddress @ 1172 NONAME + _ZN10QUdpSocket19leaveMulticastGroupERK12QHostAddressRK17QNetworkInterface @ 1173 NONAME + _ZN10QUdpSocket21setMulticastInterfaceERK17QNetworkInterface @ 1174 NONAME + _ZN13QNetworkReply11setFinishedEb @ 1175 NONAME + _ZNK10QUdpSocket18multicastInterfaceEv @ 1176 NONAME -- cgit v0.12 From 7f8af7a2030c0f4ae7ad79eee93bd68a29f285d3 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Mon, 11 Oct 2010 16:35:58 +0200 Subject: Add test to test QDir caching behavior. Also fix the qfileenginemodel test to be less fragile Reviewed-by: Prasanth Ullattil --- tests/auto/qdir/tst_qdir.cpp | 13 +++++++++++++ tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 2bb0a3e..d540f29 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -175,6 +175,8 @@ private slots: void detachingOperations(); + void testCaching(); + #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) void isRoot_data(); void isRoot(); @@ -1663,6 +1665,17 @@ void tst_QDir::detachingOperations() QCOMPARE(dir1.sorting(), sorting); } +void tst_QDir::testCaching() +{ + QString dirName = QString::fromLatin1("testCaching"); + QDir::current().rmdir(dirName); // cleanup a previous run. + QDir dir(dirName); + QVERIFY(!dir.exists()); + QDir::current().mkdir(dirName); + QVERIFY(QDir(dirName).exists()); // dir exists + QVERIFY(dir.exists()); // QDir doesn't cache the 'exist' between calls. +} + #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) void tst_QDir::isRoot_data() { diff --git a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp index c234c96..aa632c7 100644 --- a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -992,8 +992,8 @@ void tst_QFileSystemModel::dirsBeforeFiles() } dir.rmdir(dirPath); } - dir.mkpath(dirPath); - QVERIFY(dir.exists()); + QVERIFY(dir.mkpath(dirPath)); + QVERIFY(QDir(dirPath).exists()); for (int i = 0; i < 3; ++i) { QLatin1Char c('a' + i); -- cgit v0.12 From 69d1025d7c506350dd90b5fb35510b1036847db7 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Mon, 11 Oct 2010 16:50:09 +0200 Subject: Fix caching of metadata in QDir to not change behavior In 4.7 and before a QDir::exists() always stats and a refresh() call would flush metadata, restore this behavior again. Reviewed-by: Prasanth Ullattil --- src/corelib/io/qdir.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index bbe9226..827294c 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -131,9 +131,8 @@ QDirPrivate::QDirPrivate(const QDirPrivate ©) bool QDirPrivate::exists() const { if (fileEngine.isNull()) { - if (!metaData.hasFlags(QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType)) - QFileSystemEngine::fillMetaData(dirEntry, metaData, - QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); + QFileSystemEngine::fillMetaData(dirEntry, metaData, + QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); // always stat return metaData.exists() && metaData.isDirectory(); } const QAbstractFileEngine::FileFlags info = @@ -2094,6 +2093,7 @@ bool QDir::isRelativePath(const QString &path) void QDir::refresh() const { QDirPrivate *d = const_cast(this)->d_ptr.data(); + d->metaData.clear(); d->initFileEngine(); d->clearFileLists(); } -- cgit v0.12 From a3550bce43bcf70f3c763f6fcae28ba5d1a31305 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Mon, 11 Oct 2010 17:43:04 +0200 Subject: Test QDir::mkdir/mkpath return codes --- tests/auto/qdir/tst_qdir.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index d540f29..9521921 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -103,6 +103,8 @@ private slots: void mkdir_data(); void mkdir(); + void makedirReturnCode(); + void rmdir_data(); void rmdir(); @@ -295,6 +297,17 @@ void tst_QDir::mkdir() QVERIFY(fi.exists() && fi.isDir()); } +void tst_QDir::makedirReturnCode() +{ + QString dirName = QString::fromLatin1("makedirReturnCode"); + QDir::current().rmdir(dirName); // cleanup a previous run. + QDir dir(dirName); + QVERIFY(!dir.exists()); + QVERIFY(QDir::current().mkdir(dirName)); + QVERIFY(!QDir::current().mkdir(dirName)); // calling mkdir on an existing dir will fail. + QVERIFY(QDir::current().mkpath(dirName)); // calling mkpath on an existing dir will pass +} + void tst_QDir::rmdir_data() { QTest::addColumn("path"); -- cgit v0.12 From 8ee99ee22729b4d9603fe83929116259956b81ce Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 8 Oct 2010 16:23:55 +0100 Subject: Use QSystemError to return errors from QFileSystemEngine Testing done: win32-msvc2008 and Mac OS X - qfile, qfileinfo, qdir, qdiriterator, qtemporaryfile autotests symbian-sbsv2 - qtcore, qtgui, qtxml autotests win32-g++ - compilation test for qmake Reviewed-By: Thomas Zander --- qmake/Makefile.unix | 6 +- qmake/Makefile.win32 | 1 + qmake/Makefile.win32-g++ | 4 ++ qmake/Makefile.win32-g++-sh | 4 ++ qmake/qmake.pri | 2 + src/corelib/io/qfilesystemengine_p.h | 14 ++--- src/corelib/io/qfilesystemengine_symbian.cpp | 83 ++++------------------------ src/corelib/io/qfilesystemengine_unix.cpp | 20 +++---- src/corelib/io/qfilesystemengine_win.cpp | 22 ++++---- src/corelib/io/qfsfileengine_p.h | 4 -- src/corelib/io/qfsfileengine_unix.cpp | 40 +++++++------- src/corelib/io/qfsfileengine_win.cpp | 16 +++--- src/corelib/kernel/qsystemerror.cpp | 40 ++++++++++++-- src/tools/bootstrap/bootstrap.pro | 3 +- 14 files changed, 120 insertions(+), 139 deletions(-) diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index f03b300..7d61cf8 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -20,7 +20,7 @@ QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qgl qfsfileengine_unix.o qfsfileengine.o \ qfsfileengine_iterator.o qregexp.o qvector.o qbitarray.o qdir.o qdiriterator.o quuid.o qhash.o \ qfileinfo.o qdatetime.o qstringlist.o qabstractfileengine.o qtemporaryfile.o \ - qmap.o qmetatype.o qsettings.o qlibraryinfo.o qvariant.o qvsnprintf.o \ + qmap.o qmetatype.o qsettings.o qsystemerror.o qlibraryinfo.o qvariant.o qvsnprintf.o \ qlocale.o qlinkedlist.o qurl.o qnumeric.o qcryptographichash.o qxmlstream.o qxmlutils.o \ $(QTOBJS) @@ -65,6 +65,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge $(SOURCE_PATH)/src/corelib/tools/qvsnprintf.cpp $(SOURCE_PATH)/src/corelib/global/qnumeric.cpp \ $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp \ $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp \ + $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp \ $(QTSRCS) CPPFLAGS = -I. -Igenerators -Igenerators/unix -Igenerators/win32 -Igenerators/mac -Igenerators/symbian \ @@ -104,6 +105,9 @@ qvariant.o: $(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp qsettings.o: $(SOURCE_PATH)/src/corelib/io/qsettings.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qsettings.cpp +qsystemerror.o: $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp + qlibraryinfo.o: $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 4333d45..c9e623d 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -103,6 +103,7 @@ QTOBJS= \ qutfcodec.obj \ qstring.obj \ qstringlist.obj \ + qsystemerror.obj \ qtextstream.obj \ qdatastream.obj \ quuid.obj \ diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index da911e7..1a20d71 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -82,6 +82,7 @@ QTOBJS= \ qutfcodec.o \ qstring.o \ qstringlist.o \ + qsystemerror.o \ qsystemlibrary.o \ qtextstream.o \ quuid.o \ @@ -247,6 +248,9 @@ qdatetime.o: $(SOURCE_PATH)/src/corelib/tools/qdatetime.cpp qstringlist.o: $(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp +qsystemerror.o: $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp + qsystemlibrary.o: $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index 2530fe8..aad4a9e 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -83,6 +83,7 @@ QTOBJS= \ qstring.o \ qstringlist.o \ qsystemlibrary.o \ + qsystemerror.o \ qtextstream.o \ quuid.o \ qvector.o \ @@ -246,6 +247,9 @@ qdatetime.o: $(SOURCE_PATH)/src/corelib/tools/qdatetime.cpp qstringlist.o: $(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp +qsystemerror.o: $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp + $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp + qsystemlibrary.o: $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp diff --git a/qmake/qmake.pri b/qmake/qmake.pri index 274cb70..83a5356 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -82,6 +82,7 @@ bootstrap { #Qt code quuid.cpp \ qsettings.cpp \ qlibraryinfo.cpp \ + qsystemerror.cpp \ qvariant.cpp \ qvector.cpp \ qvsnprintf.cpp \ @@ -119,6 +120,7 @@ bootstrap { #Qt code qstring.h \ qstringlist.h \ qstringmatcher.h \ + qsystemerror_p.h \ qtemporaryfile.h \ qtextstream.h \ qurl.h \ diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index f4d942a..1f4aad0 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -56,6 +56,7 @@ #include "qfile.h" #include "qfilesystementry_p.h" #include "qfilesystemmetadata_p.h" +#include QT_BEGIN_NAMESPACE @@ -91,9 +92,6 @@ public: static QString owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own); static QString nativeAbsoluteFilePath(const QString &path); #endif -#ifdef Q_OS_SYMBIAN - static QString errorString(int errorcode); -#endif //homePath, rootPath and tempPath shall return clean paths static QString homePath(); static QString rootPath(); @@ -102,13 +100,13 @@ public: static bool createDirectory(const QFileSystemEntry &entry, bool createParents); static bool removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents); - static bool createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString); + static bool createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error); - static bool copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString); - static bool renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString); - static bool removeFile(const QFileSystemEntry &entry, QString &errorString); + static bool copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error); + static bool renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error); + static bool removeFile(const QFileSystemEntry &entry, QSystemError &error); - static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QString &errorString, + static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data = 0); static bool setCurrentPath(const QFileSystemEntry &entry); diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 318a5fd..877ea7a 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -88,7 +88,8 @@ static QString symbianCleanAbsolutePath(const QString& path) //static QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) { - return link; // TODO implement + Q_UNUSED(data); + return link; } //static @@ -283,16 +284,16 @@ bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool remo } //static -bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) +bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { Q_UNUSED(source) Q_UNUSED(target) - errorString = QLatin1String("not supported"); + error = QSystemError(KErrNotSupported, QSystemError::NativeError); return false; } //static -bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) +bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { //CFileMan is allocated each time because it is not thread-safe CFileMan *fm = 0; @@ -302,12 +303,12 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst delete fm; return true; } - errorString = QFileSystemEngine::errorString(err); + error = QSystemError(err, QSystemError::NativeError); return false; } //static -bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) +bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { QString sourcepath = absoluteName(source).nativeFilePath(); QString targetpath = absoluteName(target).nativeFilePath(); @@ -315,24 +316,24 @@ bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSy TInt err = fs.Rename(qt_QString2TPtrC(sourcepath), qt_QString2TPtrC(targetpath)); if (err == KErrNone) return true; - errorString = QFileSystemEngine::errorString(err); + error = QSystemError(err, QSystemError::NativeError); return false; } //static -bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QString &errorString) +bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QSystemError &error) { QString targetpath = absoluteName(entry).nativeFilePath(); RFs& fs(qt_s60GetRFs()); TInt err = fs.Delete(qt_QString2TPtrC(targetpath)); if (err == KErrNone) return true; - errorString = QFileSystemEngine::errorString(err); + error = QSystemError(err, QSystemError::NativeError); return false; } //static -bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QString &errorString, QFileSystemMetaData *data) +bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data) { QString targetpath = absoluteName(entry).nativeFilePath(); TUint setmask = 0; @@ -350,7 +351,7 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per } if (err == KErrNone) return true; - errorString = QFileSystemEngine::errorString(err); + error = QSystemError(err, QSystemError::NativeError); return false; } @@ -416,64 +417,4 @@ QFileSystemEntry QFileSystemEngine::currentPath() return ret; } -QString QFileSystemEngine::errorString(int errorcode) -{ - switch (errorcode) { - case KErrNotFound: - return QLatin1String("not found"); - case KErrCancel: - return QLatin1String("cancelled"); - case KErrNoMemory: - return QLatin1String("out of memory"); - case KErrNotSupported: - return QLatin1String("not supported"); - case KErrBadHandle: - return QLatin1String("bad handle"); //KERN-EXEC 0 panic is more likely - case KErrAlreadyExists: - return QLatin1String("already exists"); - case KErrPathNotFound: - return QLatin1String("path not found"); - case KErrInUse: - return QLatin1String("in use"); - case KErrNotReady: - return QLatin1String("not ready (e.g. FS dismounted, no memory card)"); - case KErrCorrupt: - return QLatin1String("corrupt"); - case KErrAccessDenied: - return QLatin1String("access denied"); - case KErrLocked: - return QLatin1String("locked"); - case KErrWrite: - return QLatin1String("incomplete write error"); - case KErrDisMounted: - return QLatin1String("file system dismounted during operation"); //i.e. a forcible dismount was done while we had files open - case KErrEof: - return QLatin1String("end of file"); - case KErrDiskFull: - return QLatin1String("no space in file system"); - case KErrBadName: - return QLatin1String("invalid filename"); - case KErrTimedOut: - return QLatin1String("timed out"); - case KErrBadDescriptor: - return QLatin1String("bad descriptor (passed address on stack to async call?)"); - case KErrAbort: - return QLatin1String("aborted"); - case KErrTooBig: - return QLatin1String("too big"); //e.g. trying to open a >2GB file with 32 bit API - case KErrBadPower: - return QLatin1String("insufficient power"); - case KErrDirFull: - return QLatin1String("no space in directory table"); - case KErrHardwareNotAvailable: - return QLatin1String("hardware not available"); - case KErrSessionClosed: - return QLatin1String("session closed"); - case KErrPermissionDenied: - return QLatin1String("permission denied"); - default: - return QString(QLatin1String("symbian error %d")).arg(errorcode); - } -} - QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 213fdc3..dc6888d 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -572,45 +572,45 @@ bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool remo } //static -bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) +bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { if (::symlink(source.nativeFilePath().constData(), target.nativeFilePath().constData()) == 0) return true; - errorString = qt_error_string(errno); + error = QSystemError(errno, QSystemError::StandardLibraryError); return false; } //static -bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) +bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { Q_UNUSED(source); Q_UNUSED(target); // # we can implement this using sendfile(2) - errorString = QLatin1String("Not implemented!"); + //when this function returns false, block copy is used in QFile which sets the error code. return false; } //static -bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) +bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { if (::rename(source.nativeFilePath().constData(), target.nativeFilePath().constData()) == 0) return true; - errorString = qt_error_string(errno); + error = QSystemError(errno, QSystemError::StandardLibraryError); return false; } //static -bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QString &errorString) +bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QSystemError &error) { if (unlink(entry.nativeFilePath().constData()) == 0) return true; - errorString = qt_error_string(errno); + error = QSystemError(errno, QSystemError::StandardLibraryError); return false; } //static -bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QString &errorString, QFileSystemMetaData *data) +bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data) { mode_t mode = 0; if (permissions & QFile::ReadOwner) @@ -645,7 +645,7 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per data->knownFlagsMask |= QFileSystemMetaData::Permissions; } if (!success) - errorString = qt_error_string(errno); + error = QSystemError(errno, QSystemError::StandardLibraryError); return success; } diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 5cc7395..53b9e43 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1115,43 +1115,43 @@ QFileSystemEntry QFileSystemEngine::currentPath() } //static -bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) +bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { - errorString = QLatin1String("not implemented"); - return false; // TODO implement; + Q_ASSERT(false); + return false; // TODO implement; - code needs to be moved from qfsfileengine_win.cpp } //static -bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) +bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { bool ret = ::CopyFile((wchar_t*)source.nativeFilePath().utf16(), (wchar_t*)target.nativeFilePath().utf16(), true) != 0; if(!ret) - errorString = qt_error_string(::GetLastError()); + error = QSystemError(::GetLastError(), QSystemError::NativeError); return ret; } //static -bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QString &errorString) +bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { bool ret = ::MoveFile((wchar_t*)source.nativeFilePath().utf16(), (wchar_t*)target.nativeFilePath().utf16()) != 0; if(!ret) - errorString = qt_error_string(::GetLastError()); + error = QSystemError(::GetLastError(), QSystemError::NativeError); return ret; } //static -bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QString &errorString) +bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QSystemError &error) { bool ret = ::DeleteFile((wchar_t*)entry.nativeFilePath().utf16()) != 0; if(!ret) - errorString = qt_error_string(::GetLastError()); + error = QSystemError(::GetLastError(), QSystemError::NativeError); return ret; } //static -bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QString &errorString, +bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data) { Q_UNUSED(data); @@ -1169,7 +1169,7 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per bool ret = (::_wchmod((wchar_t*)entry.nativeFilePath().utf16(), mode) == 0); if(!ret) - errorString = qt_error_string(errno); + error = QSystemError(errno, QSystemError::StandardLibraryError); return ret; } diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 14a8938..715b46f 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -185,10 +185,6 @@ public: int sysOpen(const QString &, int flags); #endif -#ifdef Q_OS_SYMBIAN - void setSymbianError(int symbianError, QFile::FileError defaultError, QString defaultString); -#endif - protected: QFSFileEnginePrivate(); diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index a64f8dc..caf5f4c 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -239,7 +239,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) } if (r != KErrNone) { - q->setError(QFile::OpenError, QFileSystemEngine::errorString(r)); + q->setError(QFile::OpenError, QSystemError(r, QSystemError::NativeError).toString()); symbianFile.Close(); return false; } @@ -385,7 +385,7 @@ qint64 QFSFileEnginePrivate::nativeRead(char *data, qint64 len) TInt r = symbianFile.Read(ptr); if (r != KErrNone) { - q->setError(QFile::ReadError, QFileSystemEngine::errorString(r)); + q->setError(QFile::ReadError, QSystemError(r, QSystemError::NativeError).toString()); return -1; } return qint64(ptr.Length()); @@ -470,7 +470,7 @@ qint64 QFSFileEnginePrivate::nativeWrite(const char *data, qint64 len) TInt r = symbianFile.Write(ptr); if (r != KErrNone) { - q->setError(QFile::WriteError, QFileSystemEngine::errorString(r)); + q->setError(QFile::WriteError, QSystemError(r, QSystemError::NativeError).toString()); return -1; } return len; @@ -494,7 +494,7 @@ qint64 QFSFileEnginePrivate::nativePos() const #endif TInt err = symbianFile.Seek(ESeekCurrent, pos); if(err != KErrNone) { - const_cast(q)->setError(QFile::PositionError, QFileSystemEngine::errorString(err)); + const_cast(q)->setError(QFile::PositionError, QSystemError(err, QSystemError::NativeError).toString()); return -1; } return pos; @@ -523,7 +523,7 @@ bool QFSFileEnginePrivate::nativeSeek(qint64 pos) #endif if (r != KErrNone) { - q->setError(QFile::PositionError, QFileSystemEngine::errorString(r)); + q->setError(QFile::PositionError, QSystemError(r, QSystemError::NativeError).toString()); return false; } return true; @@ -555,11 +555,11 @@ bool QFSFileEnginePrivate::nativeIsSequential() const bool QFSFileEngine::remove() { Q_D(QFSFileEngine); - QString errorString; - bool ret = QFileSystemEngine::removeFile(d->fileEntry, errorString); + QSystemError error; + bool ret = QFileSystemEngine::removeFile(d->fileEntry, error); d->metaData.clear(); if (!ret) { - setError(QFile::RemoveError, errorString); + setError(QFile::RemoveError, error.toString()); } return ret; } @@ -567,10 +567,10 @@ bool QFSFileEngine::remove() bool QFSFileEngine::copy(const QString &newName) { Q_D(QFSFileEngine); - QString error; + QSystemError error; bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(newName), error); if (!ret) { - setError(QFile::CopyError, error); + setError(QFile::CopyError, error.toString()); } return ret; } @@ -578,11 +578,11 @@ bool QFSFileEngine::copy(const QString &newName) bool QFSFileEngine::rename(const QString &newName) { Q_D(QFSFileEngine); - QString error; + QSystemError error; bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName), error); if (!ret) { - setError(QFile::RenameError, error); + setError(QFile::RenameError, error.toString()); } return ret; @@ -591,10 +591,10 @@ bool QFSFileEngine::rename(const QString &newName) bool QFSFileEngine::link(const QString &newName) { Q_D(QFSFileEngine); - QString error; + QSystemError error; bool ret = QFileSystemEngine::createLink(d->fileEntry, QFileSystemEntry(newName), error); if (!ret) { - setError(QFile::RenameError, error); + setError(QFile::RenameError, error.toString()); } return ret; } @@ -611,7 +611,7 @@ qint64 QFSFileEnginePrivate::nativeSize() const #endif TInt err = symbianFile.Size(size); if(err != KErrNone) { - const_cast(q)->setError(QFile::PositionError, QFileSystemEngine::errorString(err)); + const_cast(q)->setError(QFile::PositionError, QSystemError(err, QSystemError::NativeError).toString()); return 0; } return size; @@ -850,9 +850,9 @@ QString QFSFileEngine::owner(FileOwner own) const bool QFSFileEngine::setPermissions(uint perms) { Q_D(QFSFileEngine); - QString error; + QSystemError error; if (!QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), error, 0)) { - setError(QFile::PermissionsError, error); + setError(QFile::PermissionsError, error.toString()); return false; } return true; @@ -884,10 +884,12 @@ bool QFSFileEngine::setSize(qint64 size) ret = (err == KErrNone); } if (!ret) { + QSystemError error; if (err) - setError(QFile::ResizeError, QFileSystemEngine::errorString(err)); + error = QSystemError(err, QSystemError::NativeError); else - setError(QFile::ResizeError, qt_error_string(errno)); + error = QSystemError(errno, QSystemError::StandardLibraryError); + setError(QFile::ResizeError, error.toString()); } return ret; } diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 63f2a9f..cf83c07 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -503,30 +503,30 @@ bool QFSFileEnginePrivate::nativeIsSequential() const bool QFSFileEngine::remove() { Q_D(QFSFileEngine); - QString error; + QSystemError error; bool ret = QFileSystemEngine::removeFile(d->fileEntry, error); if (!ret) - setError(QFile::RemoveError, error); + setError(QFile::RemoveError, error.toString()); return ret; } bool QFSFileEngine::copy(const QString ©Name) { Q_D(QFSFileEngine); - QString error; + QSystemError error; bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(copyName), error); if (!ret) - setError(QFile::CopyError, error); + setError(QFile::CopyError, error.toString()); return ret; } bool QFSFileEngine::rename(const QString &newName) { Q_D(QFSFileEngine); - QString error; + QSystemError error; bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName), error); if (!ret) - setError(QFile::RenameError, error); + setError(QFile::RenameError, error.toString()); return ret; } @@ -854,10 +854,10 @@ QString QFSFileEngine::owner(FileOwner own) const bool QFSFileEngine::setPermissions(uint perms) { Q_D(QFSFileEngine); - QString error; + QSystemError error; bool ret = QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), error); if (!ret) - setError(QFile::PermissionsError, error); + setError(QFile::PermissionsError, error.toString()); return ret; } diff --git a/src/corelib/kernel/qsystemerror.cpp b/src/corelib/kernel/qsystemerror.cpp index 065014a..d2350b5 100644 --- a/src/corelib/kernel/qsystemerror.cpp +++ b/src/corelib/kernel/qsystemerror.cpp @@ -39,8 +39,40 @@ ** ****************************************************************************/ +#include #include "qsystemerror_p.h" -#include +#if !defined(Q_OS_WINCE) +# include +# if defined(Q_CC_MSVC) +# include +# endif +#endif +#ifdef Q_OS_WIN +#include +#endif + +#if !defined(Q_OS_WIN) && !defined(QT_NO_THREAD) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) && \ + defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L +namespace { + // There are two incompatible versions of strerror_r: + // a) the XSI/POSIX.1 version, which returns an int, + // indicating success or not + // b) the GNU version, which returns a char*, which may or may not + // be the beginning of the buffer we used + // The GNU libc manpage for strerror_r says you should use the the XSI + // version in portable code. However, it's impossible to do that if + // _GNU_SOURCE is defined so we use C++ overloading to decide what to do + // depending on the return type + static inline QString fromstrerror_helper(int, const QByteArray &buf) + { + return QString::fromLocal8Bit(buf); + } + static inline QString fromstrerror_helper(const char *str, const QByteArray &) + { + return QString::fromLocal8Bit(str); + } +} +#endif static QString standardLibraryErrorString(int errorCode) { @@ -166,23 +198,19 @@ QString QSystemError::toString() switch(errorScope) { case NativeError: #if defined (Q_OS_WIN) - errorString = windowsErrorString(errorCode); - break; + return windowsErrorString(errorCode); #elif defined (Q_OS_SYMBIAN) return symbianErrorString(errorCode); - break; #else //unix: fall through as native and standard library are the same #endif case StandardLibraryError: return standardLibraryErrorString(errorCode); - break; default: qWarning("invalid error scope"); //fall through case NoError: return QLatin1String("No error"); - break; } } diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 6531a83..9e5845c 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -69,6 +69,7 @@ SOURCES += \ ../../corelib/io/qurl.cpp \ ../../corelib/kernel/qmetatype.cpp \ ../../corelib/kernel/qvariant.cpp \ + ../../corelib/kernel/qsystemerror.cpp \ ../../corelib/tools/qbitarray.cpp \ ../../corelib/tools/qbytearray.cpp \ ../../corelib/tools/qbytearraymatcher.cpp \ @@ -83,7 +84,7 @@ SOURCES += \ ../../corelib/tools/qvector.cpp \ ../../corelib/tools/qvsnprintf.cpp \ ../../corelib/xml/qxmlutils.cpp \ - ../../corelib/xml/qxmlstream.cpp \ + ../../corelib/xml/qxmlstream.cpp \ ../../xml/dom/qdom.cpp \ ../../xml/sax/qxml.cpp -- cgit v0.12 From 2030d7894d119a207f872f23fc06ab3f934073f3 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 11 Oct 2010 17:07:09 +0100 Subject: Update documentation of QDir to reflect Qt 4 behaviour Reviewed-By: Thomas Zander --- src/corelib/io/qdir.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index bbe9226..eb78e25 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1356,8 +1356,11 @@ QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filter Returns true on success; otherwise returns false. + If the directory already exists when this function is called, it will return false. + \sa rmdir() */ +// ### Qt5: behaviour when directory already exists should be made consistent for mkdir and mkpath bool QDir::mkdir(const QString &dirName) const { const QDirPrivate* d = d_ptr.constData(); @@ -1406,8 +1409,11 @@ bool QDir::rmdir(const QString &dirName) const Returns true if successful; otherwise returns false. + If the path already exists when this function is called, it will return true. + \sa rmpath() */ +// ### Qt5: behaviour when directory already exists should be made consistent for mkdir and mkpath bool QDir::mkpath(const QString &dirPath) const { const QDirPrivate* d = d_ptr.constData(); -- cgit v0.12 From 0dd8d6e60a850b42b75d64ccc7eb793ae5c1549b Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 11 Oct 2010 17:09:47 +0100 Subject: Fix compilation of two autotests These tests did not link when QT_BUILD_INTERNAL was not defined, as one of the private headers was causing QFileInfoGatherer::~QFileInfoGatherer to be referenced Reviewed-By: Thomas Zander --- tests/auto/qfiledialog/tst_qfiledialog.cpp | 4 ++++ tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp index ca7c445..5d369b4 100644 --- a/tests/auto/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp @@ -61,9 +61,13 @@ #include #include #include "../../shared/util.h" +#if defined QT_BUILD_INTERNAL #include "../../../src/gui/dialogs/qsidebar_p.h" #include "../../../src/gui/dialogs/qfilesystemmodel_p.h" #include "../../../src/gui/dialogs/qfiledialog_p.h" +#endif +#include +#include #include "../network-settings.h" diff --git a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp index c234c96..a391eb9 100644 --- a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -41,7 +41,10 @@ #include +#ifdef QT_BUILD_INTERNAL #include "../../../src/gui/dialogs/qfilesystemmodel_p.h" +#endif +#include #include #include #include @@ -826,8 +829,10 @@ void tst_QFileSystemModel::sort() MyFriendFileSystemModel *myModel = new MyFriendFileSystemModel(); QTreeView *tree = new QTreeView(); +#ifdef QT_BUILD_INTERNAL if (fileDialogMode) myModel->d_func()->disableRecursiveSort = true; +#endif QDir dir(QDir::tempPath()); //initialize the randomness -- cgit v0.12 From 4f9b25ffa8025702c82a32538b82d15acf03303b Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 11 Oct 2010 17:11:54 +0100 Subject: Fix return value for QDir::mkdir on symbian Qt 4.7 behaviour was to return false when directory already exists for mkdir but true when directory already exists for mkpath. This change makes symbian do that in master, even though it's inconsistent. Reviewed-By: Thomas Zander --- src/corelib/io/qfilesystemengine_symbian.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 877ea7a..d068248 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -115,6 +115,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) QString orig = entry.filePath(); const bool isAbsolute = entry.isAbsolute(); const bool isDirty = (orig.contains(QLatin1String("/../")) || orig.contains(QLatin1String("/./")) || + orig.contains(QLatin1String("//")) || orig.endsWith(QLatin1String("/..")) || orig.endsWith(QLatin1String("/."))); if (isAbsolute && !isDirty) return entry; @@ -258,7 +259,9 @@ bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea r = qt_s60GetRFs().MkDirAll(qt_QString2TPtrC(abspath)); else r = qt_s60GetRFs().MkDir(qt_QString2TPtrC(abspath)); - return (r == KErrNone || r == KErrAlreadyExists); + if (createParents && r == KErrAlreadyExists) + return true; //# Qt5 - QDir::mkdir returns false for existing dir, QDir::mkpath returns true (should be made consistent in Qt 5) + return (r == KErrNone); } //static -- cgit v0.12 From 75016a4a3bb2ae536a3a813f0ef410b1a0c83742 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Mon, 11 Oct 2010 16:35:58 +0200 Subject: Add test to test QDir caching behavior. Also fix the qfileenginemodel test to be less fragile Reviewed-by: Prasanth Ullattil --- tests/auto/qdir/tst_qdir.cpp | 13 +++++++++++++ tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 2bb0a3e..d540f29 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -175,6 +175,8 @@ private slots: void detachingOperations(); + void testCaching(); + #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) void isRoot_data(); void isRoot(); @@ -1663,6 +1665,17 @@ void tst_QDir::detachingOperations() QCOMPARE(dir1.sorting(), sorting); } +void tst_QDir::testCaching() +{ + QString dirName = QString::fromLatin1("testCaching"); + QDir::current().rmdir(dirName); // cleanup a previous run. + QDir dir(dirName); + QVERIFY(!dir.exists()); + QDir::current().mkdir(dirName); + QVERIFY(QDir(dirName).exists()); // dir exists + QVERIFY(dir.exists()); // QDir doesn't cache the 'exist' between calls. +} + #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) void tst_QDir::isRoot_data() { diff --git a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp index a391eb9..6b63691 100644 --- a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -997,8 +997,8 @@ void tst_QFileSystemModel::dirsBeforeFiles() } dir.rmdir(dirPath); } - dir.mkpath(dirPath); - QVERIFY(dir.exists()); + QVERIFY(dir.mkpath(dirPath)); + QVERIFY(QDir(dirPath).exists()); for (int i = 0; i < 3; ++i) { QLatin1Char c('a' + i); -- cgit v0.12 From aa117bb48971c2fe56aff1e678ee3a7f6358eb0d Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Mon, 11 Oct 2010 16:50:09 +0200 Subject: Fix caching of metadata in QDir to not change behavior In 4.7 and before a QDir::exists() always stats and a refresh() call would flush metadata, restore this behavior again. Reviewed-by: Prasanth Ullattil --- src/corelib/io/qdir.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index eb78e25..e9bc012 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -131,9 +131,8 @@ QDirPrivate::QDirPrivate(const QDirPrivate ©) bool QDirPrivate::exists() const { if (fileEngine.isNull()) { - if (!metaData.hasFlags(QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType)) - QFileSystemEngine::fillMetaData(dirEntry, metaData, - QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); + QFileSystemEngine::fillMetaData(dirEntry, metaData, + QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); // always stat return metaData.exists() && metaData.isDirectory(); } const QAbstractFileEngine::FileFlags info = @@ -2100,6 +2099,7 @@ bool QDir::isRelativePath(const QString &path) void QDir::refresh() const { QDirPrivate *d = const_cast(this)->d_ptr.data(); + d->metaData.clear(); d->initFileEngine(); d->clearFileLists(); } -- cgit v0.12 From f1f39af98afb2129daa5db2686200907de4c0999 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Mon, 11 Oct 2010 17:43:04 +0200 Subject: Test QDir::mkdir/mkpath return codes --- tests/auto/qdir/tst_qdir.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index d540f29..9521921 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -103,6 +103,8 @@ private slots: void mkdir_data(); void mkdir(); + void makedirReturnCode(); + void rmdir_data(); void rmdir(); @@ -295,6 +297,17 @@ void tst_QDir::mkdir() QVERIFY(fi.exists() && fi.isDir()); } +void tst_QDir::makedirReturnCode() +{ + QString dirName = QString::fromLatin1("makedirReturnCode"); + QDir::current().rmdir(dirName); // cleanup a previous run. + QDir dir(dirName); + QVERIFY(!dir.exists()); + QVERIFY(QDir::current().mkdir(dirName)); + QVERIFY(!QDir::current().mkdir(dirName)); // calling mkdir on an existing dir will fail. + QVERIFY(QDir::current().mkpath(dirName)); // calling mkpath on an existing dir will pass +} + void tst_QDir::rmdir_data() { QTest::addColumn("path"); -- cgit v0.12 From 1f8b697da6c6606d57a003666d35115ad72860f2 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 12 Oct 2010 12:04:29 +0100 Subject: Fix deployment for examples and tests Due to the change from default deployment in symbian from being hardcoded in qmake to being in default_deployment.prf the .pro files needed to be changed. Specifically, "DEPLOYMENT = foo" needs to be "DEPLOYMENT += foo" otherwise the default deployment lines are not added and the test won't install. Reviewed-By: Miikka Heikkinen --- demos/declarative/minehunt/minehunt.pro | 2 +- examples/declarative/cppextensions/imageprovider/imageprovider.pro | 2 +- examples/declarative/cppextensions/qwidgets/qwidgets.pro | 2 +- tests/auto/declarative/examples/examples.pro | 2 +- tests/auto/declarative/moduleqt47/moduleqt47.pro | 2 +- tests/auto/declarative/parserstress/parserstress.pro | 2 +- tests/auto/declarative/qdeclarativeanchors/qdeclarativeanchors.pro | 2 +- .../qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro | 2 +- .../declarative/qdeclarativeanimations/qdeclarativeanimations.pro | 2 +- .../auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro | 2 +- tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro | 2 +- .../declarative/qdeclarativeborderimage/qdeclarativeborderimage.pro | 2 +- .../declarative/qdeclarativeconnection/qdeclarativeconnection.pro | 2 +- tests/auto/declarative/qdeclarativedom/qdeclarativedom.pro | 2 +- .../declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro | 2 +- .../auto/declarative/qdeclarativeflickable/qdeclarativeflickable.pro | 2 +- tests/auto/declarative/qdeclarativeflipable/qdeclarativeflipable.pro | 2 +- .../declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro | 2 +- .../qdeclarativefolderlistmodel/qdeclarativefolderlistmodel.pro | 2 +- .../declarative/qdeclarativefontloader/qdeclarativefontloader.pro | 2 +- tests/auto/declarative/qdeclarativegridview/qdeclarativegridview.pro | 2 +- tests/auto/declarative/qdeclarativeimage/qdeclarativeimage.pro | 2 +- tests/auto/declarative/qdeclarativeinfo/qdeclarativeinfo.pro | 2 +- tests/auto/declarative/qdeclarativeitem/qdeclarativeitem.pro | 2 +- tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro | 2 +- .../declarative/qdeclarativelayoutitem/qdeclarativelayoutitem.pro | 2 +- .../auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro | 2 +- tests/auto/declarative/qdeclarativelistview/qdeclarativelistview.pro | 2 +- tests/auto/declarative/qdeclarativeloader/qdeclarativeloader.pro | 2 +- .../qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro | 2 +- .../auto/declarative/qdeclarativemousearea/qdeclarativemousearea.pro | 2 +- .../auto/declarative/qdeclarativeparticles/qdeclarativeparticles.pro | 2 +- tests/auto/declarative/qdeclarativepathview/qdeclarativepathview.pro | 2 +- .../declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro | 2 +- .../declarative/qdeclarativepositioners/qdeclarativepositioners.pro | 2 +- tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro | 2 +- tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro | 2 +- tests/auto/declarative/qdeclarativerepeater/qdeclarativerepeater.pro | 2 +- .../qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro | 2 +- .../qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro | 2 +- .../qdeclarativespringanimation/qdeclarativespringanimation.pro | 2 +- .../declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro | 2 +- tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro | 2 +- tests/auto/declarative/qdeclarativetext/qdeclarativetext.pro | 2 +- tests/auto/declarative/qdeclarativetextedit/qdeclarativetextedit.pro | 2 +- .../auto/declarative/qdeclarativetextinput/qdeclarativetextinput.pro | 2 +- .../declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro | 2 +- tests/auto/declarative/qdeclarativeview/qdeclarativeview.pro | 2 +- tests/auto/declarative/qdeclarativeviewer/qdeclarativeviewer.pro | 2 +- .../qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro | 2 +- tests/auto/declarative/qdeclarativewebview/qdeclarativewebview.pro | 2 +- .../declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro | 2 +- .../qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro | 2 +- .../declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro | 2 +- tests/auto/declarative/qmlvisual/qmlvisual.pro | 2 +- tests/auto/networkselftest/networkselftest.pro | 4 ++-- tests/auto/qapplication/test/test.pro | 4 ++-- tests/auto/qaudioinput/qaudioinput.pro | 2 +- tests/auto/qaudiooutput/qaudiooutput.pro | 2 +- tests/auto/qchar/qchar.pro | 2 +- tests/auto/qclipboard/test/test.pro | 2 +- tests/auto/qfile/test/test.pro | 2 +- tests/auto/qfileinfo/qfileinfo.pro | 2 +- tests/auto/qhttp/qhttp.pro | 4 ++-- tests/auto/qlocalsocket/test/test.pro | 2 +- tests/auto/qresourceengine/qresourceengine.pro | 2 +- tests/auto/qsound/qsound.pro | 2 +- tests/benchmarks/declarative/binding/binding.pro | 2 +- tests/benchmarks/declarative/qdeclarativeimage/qdeclarativeimage.pro | 2 +- tests/benchmarks/declarative/script/script.pro | 2 +- 70 files changed, 73 insertions(+), 73 deletions(-) diff --git a/demos/declarative/minehunt/minehunt.pro b/demos/declarative/minehunt/minehunt.pro index 753ca4e..4cf1441 100644 --- a/demos/declarative/minehunt/minehunt.pro +++ b/demos/declarative/minehunt/minehunt.pro @@ -19,6 +19,6 @@ symbian:{ TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) qmlminehuntfiles.sources = MinehuntCore minehunt.qml - DEPLOYMENT = qmlminehuntfiles + DEPLOYMENT += qmlminehuntfiles } \ No newline at end of file diff --git a/examples/declarative/cppextensions/imageprovider/imageprovider.pro b/examples/declarative/cppextensions/imageprovider/imageprovider.pro index 7149986..9797a3f 100644 --- a/examples/declarative/cppextensions/imageprovider/imageprovider.pro +++ b/examples/declarative/cppextensions/imageprovider/imageprovider.pro @@ -24,5 +24,5 @@ symbian:{ importFiles.sources = ImageProviderCore/qmlimageproviderplugin.dll ImageProviderCore/qmldir importFiles.path = ImageProviderCore - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } diff --git a/examples/declarative/cppextensions/qwidgets/qwidgets.pro b/examples/declarative/cppextensions/qwidgets/qwidgets.pro index 2e610f9..3353a8d 100644 --- a/examples/declarative/cppextensions/qwidgets/qwidgets.pro +++ b/examples/declarative/cppextensions/qwidgets/qwidgets.pro @@ -20,5 +20,5 @@ symbian:{ importFiles.sources = QWidgets/qmlqwidgetsplugin.dll QWidgets/qmldir importFiles.path = QWidgets - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } diff --git a/tests/auto/declarative/examples/examples.pro b/tests/auto/declarative/examples/examples.pro index 2e243b4..1a0dc55 100644 --- a/tests/auto/declarative/examples/examples.pro +++ b/tests/auto/declarative/examples/examples.pro @@ -9,7 +9,7 @@ include(../../../../tools/qml/qml.pri) symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/moduleqt47/moduleqt47.pro b/tests/auto/declarative/moduleqt47/moduleqt47.pro index 4ee634e..711e24c 100644 --- a/tests/auto/declarative/moduleqt47/moduleqt47.pro +++ b/tests/auto/declarative/moduleqt47/moduleqt47.pro @@ -7,7 +7,7 @@ SOURCES += tst_moduleqt47.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/parserstress/parserstress.pro b/tests/auto/declarative/parserstress/parserstress.pro index bb1d69f..17f297b 100644 --- a/tests/auto/declarative/parserstress/parserstress.pro +++ b/tests/auto/declarative/parserstress/parserstress.pro @@ -7,7 +7,7 @@ SOURCES += tst_parserstress.cpp symbian: { importFiles.sources = ..\\..\\qscriptjstestsuite\\tests importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeanchors/qdeclarativeanchors.pro b/tests/auto/declarative/qdeclarativeanchors/qdeclarativeanchors.pro index 9798bb6..6295079 100644 --- a/tests/auto/declarative/qdeclarativeanchors/qdeclarativeanchors.pro +++ b/tests/auto/declarative/qdeclarativeanchors/qdeclarativeanchors.pro @@ -6,7 +6,7 @@ macx:CONFIG -= app_bundle symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro b/tests/auto/declarative/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro index 0a2f0f2..8c2259a 100644 --- a/tests/auto/declarative/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro +++ b/tests/auto/declarative/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro @@ -7,7 +7,7 @@ macx:CONFIG -= app_bundle symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro b/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro index ed47dca..578f37b 100644 --- a/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro +++ b/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro @@ -6,7 +6,7 @@ macx:CONFIG -= app_bundle symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro b/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro index cfb59ef..7ba3a7d 100644 --- a/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro +++ b/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro @@ -6,7 +6,7 @@ macx:CONFIG -= app_bundle symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro b/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro index a7ba2a8..0cdaada 100644 --- a/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro +++ b/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativebinding.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeborderimage/qdeclarativeborderimage.pro b/tests/auto/declarative/qdeclarativeborderimage/qdeclarativeborderimage.pro index a21761b..0e41c13 100644 --- a/tests/auto/declarative/qdeclarativeborderimage/qdeclarativeborderimage.pro +++ b/tests/auto/declarative/qdeclarativeborderimage/qdeclarativeborderimage.pro @@ -8,7 +8,7 @@ SOURCES += tst_qdeclarativeborderimage.cpp ../shared/testhttpserver.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro b/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro index d06ce4f..33d81ba 100644 --- a/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro +++ b/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativeconnection.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativedom/qdeclarativedom.pro b/tests/auto/declarative/qdeclarativedom/qdeclarativedom.pro index 415d4e2..1866a43 100644 --- a/tests/auto/declarative/qdeclarativedom/qdeclarativedom.pro +++ b/tests/auto/declarative/qdeclarativedom/qdeclarativedom.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativedom.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro b/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro index 58cad34..2eb333a 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro +++ b/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro @@ -15,7 +15,7 @@ INCLUDEPATH += ../shared symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeflickable/qdeclarativeflickable.pro b/tests/auto/declarative/qdeclarativeflickable/qdeclarativeflickable.pro index be0ba6c..3f8b5e9 100644 --- a/tests/auto/declarative/qdeclarativeflickable/qdeclarativeflickable.pro +++ b/tests/auto/declarative/qdeclarativeflickable/qdeclarativeflickable.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativeflickable.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeflipable/qdeclarativeflipable.pro b/tests/auto/declarative/qdeclarativeflipable/qdeclarativeflipable.pro index 759e80b..cb42418 100644 --- a/tests/auto/declarative/qdeclarativeflipable/qdeclarativeflipable.pro +++ b/tests/auto/declarative/qdeclarativeflipable/qdeclarativeflipable.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativeflipable.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro b/tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro index 24749c6..3724a78 100644 --- a/tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro +++ b/tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro @@ -6,7 +6,7 @@ macx:CONFIG -= app_bundle symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativefolderlistmodel/qdeclarativefolderlistmodel.pro b/tests/auto/declarative/qdeclarativefolderlistmodel/qdeclarativefolderlistmodel.pro index 91bf4a7..3299786 100644 --- a/tests/auto/declarative/qdeclarativefolderlistmodel/qdeclarativefolderlistmodel.pro +++ b/tests/auto/declarative/qdeclarativefolderlistmodel/qdeclarativefolderlistmodel.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativefolderlistmodel.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro b/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro index 01dca26..fbd2550 100644 --- a/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro +++ b/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro @@ -8,7 +8,7 @@ SOURCES += tst_qdeclarativefontloader.cpp ../shared/testhttpserver.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativegridview/qdeclarativegridview.pro b/tests/auto/declarative/qdeclarativegridview/qdeclarativegridview.pro index a99a1b9..4ea1e47 100644 --- a/tests/auto/declarative/qdeclarativegridview/qdeclarativegridview.pro +++ b/tests/auto/declarative/qdeclarativegridview/qdeclarativegridview.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativegridview.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeimage/qdeclarativeimage.pro b/tests/auto/declarative/qdeclarativeimage/qdeclarativeimage.pro index 244a1e1..e5db298 100644 --- a/tests/auto/declarative/qdeclarativeimage/qdeclarativeimage.pro +++ b/tests/auto/declarative/qdeclarativeimage/qdeclarativeimage.pro @@ -8,7 +8,7 @@ SOURCES += tst_qdeclarativeimage.cpp ../shared/testhttpserver.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeinfo/qdeclarativeinfo.pro b/tests/auto/declarative/qdeclarativeinfo/qdeclarativeinfo.pro index 2c20e7e..188ea23 100644 --- a/tests/auto/declarative/qdeclarativeinfo/qdeclarativeinfo.pro +++ b/tests/auto/declarative/qdeclarativeinfo/qdeclarativeinfo.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativeinfo.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeitem/qdeclarativeitem.pro b/tests/auto/declarative/qdeclarativeitem/qdeclarativeitem.pro index f4901c4..26bd624 100644 --- a/tests/auto/declarative/qdeclarativeitem/qdeclarativeitem.pro +++ b/tests/auto/declarative/qdeclarativeitem/qdeclarativeitem.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativeitem.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro b/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro index 43c451f..d702082 100644 --- a/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro +++ b/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro @@ -14,7 +14,7 @@ SOURCES += ../shared/testhttpserver.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativelayoutitem/qdeclarativelayoutitem.pro b/tests/auto/declarative/qdeclarativelayoutitem/qdeclarativelayoutitem.pro index 5076e51..b74ea98 100644 --- a/tests/auto/declarative/qdeclarativelayoutitem/qdeclarativelayoutitem.pro +++ b/tests/auto/declarative/qdeclarativelayoutitem/qdeclarativelayoutitem.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativelayoutitem.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro b/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro index e90db49..d1146b1 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro +++ b/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro @@ -8,7 +8,7 @@ SOURCES += tst_qdeclarativelistmodel.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativelistview/qdeclarativelistview.pro b/tests/auto/declarative/qdeclarativelistview/qdeclarativelistview.pro index 2c5a859..f26a71e 100644 --- a/tests/auto/declarative/qdeclarativelistview/qdeclarativelistview.pro +++ b/tests/auto/declarative/qdeclarativelistview/qdeclarativelistview.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativelistview.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeloader/qdeclarativeloader.pro b/tests/auto/declarative/qdeclarativeloader/qdeclarativeloader.pro index b07bf9e..29b9eb9 100644 --- a/tests/auto/declarative/qdeclarativeloader/qdeclarativeloader.pro +++ b/tests/auto/declarative/qdeclarativeloader/qdeclarativeloader.pro @@ -10,7 +10,7 @@ SOURCES += tst_qdeclarativeloader.cpp \ symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro index fb3630f..36dbb83 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro +++ b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro @@ -6,7 +6,7 @@ CONFIG -= app_bundle symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativemousearea/qdeclarativemousearea.pro b/tests/auto/declarative/qdeclarativemousearea/qdeclarativemousearea.pro index 3d39aa8..fec73c5 100644 --- a/tests/auto/declarative/qdeclarativemousearea/qdeclarativemousearea.pro +++ b/tests/auto/declarative/qdeclarativemousearea/qdeclarativemousearea.pro @@ -8,7 +8,7 @@ SOURCES += tst_qdeclarativemousearea.cpp ../shared/testhttpserver.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeparticles/qdeclarativeparticles.pro b/tests/auto/declarative/qdeclarativeparticles/qdeclarativeparticles.pro index f9ca90f..9762b7c 100644 --- a/tests/auto/declarative/qdeclarativeparticles/qdeclarativeparticles.pro +++ b/tests/auto/declarative/qdeclarativeparticles/qdeclarativeparticles.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativeparticles.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativepathview/qdeclarativepathview.pro b/tests/auto/declarative/qdeclarativepathview/qdeclarativepathview.pro index 04fd26b..3270c5e 100644 --- a/tests/auto/declarative/qdeclarativepathview/qdeclarativepathview.pro +++ b/tests/auto/declarative/qdeclarativepathview/qdeclarativepathview.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativepathview.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro b/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro index 3130364..2e2c6bc 100644 --- a/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro +++ b/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro @@ -12,7 +12,7 @@ SOURCES += ../shared/testhttpserver.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativepositioners/qdeclarativepositioners.pro b/tests/auto/declarative/qdeclarativepositioners/qdeclarativepositioners.pro index 5dc7bb8..f2c9eee 100644 --- a/tests/auto/declarative/qdeclarativepositioners/qdeclarativepositioners.pro +++ b/tests/auto/declarative/qdeclarativepositioners/qdeclarativepositioners.pro @@ -6,7 +6,7 @@ macx:CONFIG -= app_bundle symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro b/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro index 4121a33..504a371 100644 --- a/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro +++ b/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativeproperty.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro b/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro index 6af6500..775f445 100644 --- a/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro +++ b/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro @@ -6,7 +6,7 @@ macx:CONFIG -= app_bundle symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativerepeater/qdeclarativerepeater.pro b/tests/auto/declarative/qdeclarativerepeater/qdeclarativerepeater.pro index f3ff9ed..0f3773c 100644 --- a/tests/auto/declarative/qdeclarativerepeater/qdeclarativerepeater.pro +++ b/tests/auto/declarative/qdeclarativerepeater/qdeclarativerepeater.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativerepeater.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro b/tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro index c2d30a0..8a63355 100644 --- a/tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro +++ b/tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro @@ -11,7 +11,7 @@ INCLUDEPATH += ../shared symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro b/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro index 872aeb9..e770d46 100644 --- a/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro +++ b/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativesmoothedanimation.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro b/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro index 213b262..07bcbe7 100644 --- a/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro +++ b/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativespringanimation.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro b/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro index 1462c9a..400512d 100644 --- a/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro +++ b/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro @@ -8,7 +8,7 @@ SOURCES += tst_qdeclarativesqldatabase.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro b/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro index 2bae041..cb3e0fe 100644 --- a/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro +++ b/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativestates.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativetext/qdeclarativetext.pro b/tests/auto/declarative/qdeclarativetext/qdeclarativetext.pro index c1a36fd..28a9fcd 100644 --- a/tests/auto/declarative/qdeclarativetext/qdeclarativetext.pro +++ b/tests/auto/declarative/qdeclarativetext/qdeclarativetext.pro @@ -12,7 +12,7 @@ SOURCES += ../shared/testhttpserver.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativetextedit/qdeclarativetextedit.pro b/tests/auto/declarative/qdeclarativetextedit/qdeclarativetextedit.pro index 4b6bd49..8606eb0 100644 --- a/tests/auto/declarative/qdeclarativetextedit/qdeclarativetextedit.pro +++ b/tests/auto/declarative/qdeclarativetextedit/qdeclarativetextedit.pro @@ -8,7 +8,7 @@ HEADERS += ../shared/testhttpserver.h symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativetextinput/qdeclarativetextinput.pro b/tests/auto/declarative/qdeclarativetextinput/qdeclarativetextinput.pro index 8f42448..7d178d7 100644 --- a/tests/auto/declarative/qdeclarativetextinput/qdeclarativetextinput.pro +++ b/tests/auto/declarative/qdeclarativetextinput/qdeclarativetextinput.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativetextinput.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro b/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro index 90e46d3..56c3cd4 100644 --- a/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro +++ b/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro @@ -10,7 +10,7 @@ SOURCES += tst_qdeclarativevaluetypes.cpp \ symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeview/qdeclarativeview.pro b/tests/auto/declarative/qdeclarativeview/qdeclarativeview.pro index 21a9195..2f0a474 100644 --- a/tests/auto/declarative/qdeclarativeview/qdeclarativeview.pro +++ b/tests/auto/declarative/qdeclarativeview/qdeclarativeview.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativeview.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeviewer/qdeclarativeviewer.pro b/tests/auto/declarative/qdeclarativeviewer/qdeclarativeviewer.pro index 6189916..08adf26 100644 --- a/tests/auto/declarative/qdeclarativeviewer/qdeclarativeviewer.pro +++ b/tests/auto/declarative/qdeclarativeviewer/qdeclarativeviewer.pro @@ -9,7 +9,7 @@ SOURCES += tst_qdeclarativeviewer.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro b/tests/auto/declarative/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro index 92e5f60..d0d9b36 100644 --- a/tests/auto/declarative/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro +++ b/tests/auto/declarative/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativevisualdatamodel.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativewebview/qdeclarativewebview.pro b/tests/auto/declarative/qdeclarativewebview/qdeclarativewebview.pro index 562a9fb..2ab27a1 100644 --- a/tests/auto/declarative/qdeclarativewebview/qdeclarativewebview.pro +++ b/tests/auto/declarative/qdeclarativewebview/qdeclarativewebview.pro @@ -8,7 +8,7 @@ SOURCES += tst_qdeclarativewebview.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro b/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro index 2f8f23d..9d4e0ed 100644 --- a/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro +++ b/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro @@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativeworkerscript.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro b/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro index 619b239..bfd47c5 100644 --- a/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro +++ b/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro @@ -11,7 +11,7 @@ SOURCES += tst_qdeclarativexmlhttprequest.cpp \ symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro b/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro index 472cffb..f4b25b5 100644 --- a/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro +++ b/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro @@ -11,7 +11,7 @@ SOURCES += tst_qdeclarativexmllistmodel.cpp symbian: { importFiles.sources = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qmlvisual/qmlvisual.pro b/tests/auto/declarative/qmlvisual/qmlvisual.pro index cb7e5d7..be9f26f 100644 --- a/tests/auto/declarative/qmlvisual/qmlvisual.pro +++ b/tests/auto/declarative/qmlvisual/qmlvisual.pro @@ -27,7 +27,7 @@ symbian: { repeater \ selftest_noimages \ webview - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += QT_TEST_SOURCE_DIR=\"\\\"$$PWD\\\"\" } diff --git a/tests/auto/networkselftest/networkselftest.pro b/tests/auto/networkselftest/networkselftest.pro index d7cb7f3..2217a32 100644 --- a/tests/auto/networkselftest/networkselftest.pro +++ b/tests/auto/networkselftest/networkselftest.pro @@ -6,12 +6,12 @@ QT = core network wince*: { addFiles.sources = rfc3252.txt addFiles.path = . - DEPLOYMENT = addFiles + DEPLOYMENT += addFiles DEFINES += SRCDIR=\\\"\\\" } else:symbian { addFiles.sources = rfc3252.txt addFiles.path = . - DEPLOYMENT = addFiles + DEPLOYMENT += addFiles } else:vxworks*: { DEFINES += SRCDIR=\\\"\\\" } else { diff --git a/tests/auto/qapplication/test/test.pro b/tests/auto/qapplication/test/test.pro index 2c54c37..e1193c2 100644 --- a/tests/auto/qapplication/test/test.pro +++ b/tests/auto/qapplication/test/test.pro @@ -8,7 +8,7 @@ wince* { additional.path = desktopsettingsaware someTest.sources = test.pro someTest.path = test - DEPLOYMENT = additional deploy someTest + DEPLOYMENT += additional deploy someTest } symbian: { @@ -17,7 +17,7 @@ symbian: { someTest.sources = test.pro someTest.path = test windowIcon.sources = ../heart.svg - DEPLOYMENT = additional deploy someTest windowIcon + DEPLOYMENT += additional deploy someTest windowIcon LIBS += -lcone -lavkon } diff --git a/tests/auto/qaudioinput/qaudioinput.pro b/tests/auto/qaudioinput/qaudioinput.pro index 5eb1613..0bbbb19 100644 --- a/tests/auto/qaudioinput/qaudioinput.pro +++ b/tests/auto/qaudioinput/qaudioinput.pro @@ -6,7 +6,7 @@ QT = core multimedia wince* { deploy.sources += 4.wav - DEPLOYMENT = deploy + DEPLOYMENT += deploy DEFINES += SRCDIR=\\\"\\\" QT += gui } else { diff --git a/tests/auto/qaudiooutput/qaudiooutput.pro b/tests/auto/qaudiooutput/qaudiooutput.pro index e1734e0..09d7ae3 100644 --- a/tests/auto/qaudiooutput/qaudiooutput.pro +++ b/tests/auto/qaudiooutput/qaudiooutput.pro @@ -6,7 +6,7 @@ QT = core multimedia wince*|symbian: { deploy.sources += 4.wav - DEPLOYMENT = deploy + DEPLOYMENT += deploy !symbian { DEFINES += SRCDIR=\\\"\\\" QT += gui diff --git a/tests/auto/qchar/qchar.pro b/tests/auto/qchar/qchar.pro index 3813e4e..8224448 100644 --- a/tests/auto/qchar/qchar.pro +++ b/tests/auto/qchar/qchar.pro @@ -5,7 +5,7 @@ QT = core wince*|symbian: { deploy.sources += NormalizationTest.txt -DEPLOYMENT = deploy +DEPLOYMENT += deploy } symbian: { diff --git a/tests/auto/qclipboard/test/test.pro b/tests/auto/qclipboard/test/test.pro index 0f8cad1..620ff36 100644 --- a/tests/auto/qclipboard/test/test.pro +++ b/tests/auto/qclipboard/test/test.pro @@ -26,5 +26,5 @@ wince*|symbian: { reg_resource.path = $$REG_RESOURCE_IMPORT_DIR } - DEPLOYMENT = copier paster rsc reg_resource + DEPLOYMENT += copier paster rsc reg_resource } \ No newline at end of file diff --git a/tests/auto/qfile/test/test.pro b/tests/auto/qfile/test/test.pro index 70c93ce..9a2d847 100644 --- a/tests/auto/qfile/test/test.pro +++ b/tests/auto/qfile/test/test.pro @@ -10,7 +10,7 @@ wince*|symbian { resour.sources += ..\\resources\\file1.ext1 resour.path = resources - DEPLOYMENT = files resour + DEPLOYMENT += files resour } wince* { diff --git a/tests/auto/qfileinfo/qfileinfo.pro b/tests/auto/qfileinfo/qfileinfo.pro index 30656e2..7df721e 100644 --- a/tests/auto/qfileinfo/qfileinfo.pro +++ b/tests/auto/qfileinfo/qfileinfo.pro @@ -10,7 +10,7 @@ wince*:|symbian: { deploy.sources += qfileinfo.qrc tst_qfileinfo.cpp res.sources = resources\\file1 resources\\file1.ext1 resources\\file1.ext1.ext2 res.path = resources - DEPLOYMENT = deploy res + DEPLOYMENT += deploy res } symbian { diff --git a/tests/auto/qhttp/qhttp.pro b/tests/auto/qhttp/qhttp.pro index c0be518..b7b78f1 100644 --- a/tests/auto/qhttp/qhttp.pro +++ b/tests/auto/qhttp/qhttp.pro @@ -11,7 +11,7 @@ wince*: { cgi.path = webserver/cgi-bin addFiles.sources = rfc3252.txt trolltech addFiles.path = . - DEPLOYMENT = addFiles webFiles cgi + DEPLOYMENT += addFiles webFiles cgi DEFINES += SRCDIR=\\\"\\\" } else:symbian { webFiles.sources = webserver/* @@ -20,7 +20,7 @@ wince*: { cgi.path = webserver/cgi-bin addFiles.sources = rfc3252.txt trolltech addFiles.path = . - DEPLOYMENT = addFiles webFiles cgi + DEPLOYMENT += addFiles webFiles cgi TARGET.CAPABILITY = NetworkServices } else:vxworks*: { DEFINES += SRCDIR=\\\"\\\" diff --git a/tests/auto/qlocalsocket/test/test.pro b/tests/auto/qlocalsocket/test/test.pro index 687aae2..0ee1cb6 100644 --- a/tests/auto/qlocalsocket/test/test.pro +++ b/tests/auto/qlocalsocket/test/test.pro @@ -42,7 +42,7 @@ symbian { wince*|symbian { scriptFiles.sources = ../lackey/scripts/*.js scriptFiles.path = lackey/scripts - DEPLOYMENT = additionalFiles scriptFiles + DEPLOYMENT += additionalFiles scriptFiles QT += script # for easy deployment of QtScript requires(contains(QT_CONFIG,script)) diff --git a/tests/auto/qresourceengine/qresourceengine.pro b/tests/auto/qresourceengine/qresourceengine.pro index 17e36af..1ad0f5d 100644 --- a/tests/auto/qresourceengine/qresourceengine.pro +++ b/tests/auto/qresourceengine/qresourceengine.pro @@ -38,7 +38,7 @@ wince*|symbian:{ testsub.path = testqrc/test testsub2.sources = testqrc/test/test/* testsub2.path = testqrc/test/test - DEPLOYMENT = deploy test alias other search1 search2 sub testsub testsub2 + DEPLOYMENT += deploy test alias other search1 search2 sub testsub testsub2 !symbian:DEFINES += SRCDIR=\\\"\\\" } else { DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tests/auto/qsound/qsound.pro b/tests/auto/qsound/qsound.pro index bb1981c..e3279f3 100644 --- a/tests/auto/qsound/qsound.pro +++ b/tests/auto/qsound/qsound.pro @@ -3,7 +3,7 @@ SOURCES += tst_qsound.cpp wince*|symbian: { deploy.sources += 4.wav - DEPLOYMENT = deploy + DEPLOYMENT += deploy !symbian:DEFINES += SRCDIR=\\\"\\\" } else { DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tests/benchmarks/declarative/binding/binding.pro b/tests/benchmarks/declarative/binding/binding.pro index c1a8223..b93977a 100644 --- a/tests/benchmarks/declarative/binding/binding.pro +++ b/tests/benchmarks/declarative/binding/binding.pro @@ -10,7 +10,7 @@ HEADERS += testtypes.h symbian { data.sources = data data.path = . - DEPLOYMENT = data + DEPLOYMENT += data } else { # Define SRCDIR equal to test's source directory DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/benchmarks/declarative/qdeclarativeimage/qdeclarativeimage.pro b/tests/benchmarks/declarative/qdeclarativeimage/qdeclarativeimage.pro index a68792b..313282b 100644 --- a/tests/benchmarks/declarative/qdeclarativeimage/qdeclarativeimage.pro +++ b/tests/benchmarks/declarative/qdeclarativeimage/qdeclarativeimage.pro @@ -10,7 +10,7 @@ SOURCES += tst_qdeclarativeimage.cpp symbian { importFiles.sources = image.png importFiles.path = - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/benchmarks/declarative/script/script.pro b/tests/benchmarks/declarative/script/script.pro index 685ba03..759c6dd 100644 --- a/tests/benchmarks/declarative/script/script.pro +++ b/tests/benchmarks/declarative/script/script.pro @@ -10,7 +10,7 @@ SOURCES += tst_script.cpp symbian { importFiles.sources = data importFiles.path = - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } -- cgit v0.12 From ec1c89a9440cefc0ebea225d3aeca2decb56e690 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 12 Oct 2010 17:32:29 +0100 Subject: Correct errors in the qimagereader autotest First, pgm and pbm formats need the same exception given to ppm format as they are subtypes of the same format. (as text based image formats they are vulnerable to line end differences) Second, a workaround for the readFromDevice test case hanging on the symbian emulator. The test expects to be able to send a whole image to a socket and have this fit within the send/receive buffers of the TCP stack. At least for the emulator's winsock backend, this hangs the autotest inside a blocking write. On the Nokia 5800, the test passed so it's currently skipped only for the emulator. Reviewed-By: Jason Barron --- tests/auto/qimagereader/tst_qimagereader.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/auto/qimagereader/tst_qimagereader.cpp b/tests/auto/qimagereader/tst_qimagereader.cpp index 4b4bdd6..a6fb886 100644 --- a/tests/auto/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/qimagereader/tst_qimagereader.cpp @@ -1098,6 +1098,11 @@ void tst_QImageReader::readFromDevice() QCOMPARE(image1, expectedImage); } +#if defined (Q_OS_SYMBIAN) && defined (__WINS__) + //the emulator hangs in socket write (this is a test bug, it assumes the TCP stack can accept a whole image to its buffers) + if(imageData.size() > 16384) + QSKIP("image larger than socket buffer (test needs to be rewritten)", SkipSingle); +#endif Server server(imageData); QEventLoop loop; connect(&server, SIGNAL(ready()), &loop, SLOT(quit())); @@ -1249,7 +1254,10 @@ void tst_QImageReader::devicePosition() buf.seek(preLen); QImageReader reader(&buf, format); QCOMPARE(expected, reader.read()); - if (format != "ppm" && format != "gif") // Known not to work + if (format != "ppm" && + format != "pgm" && + format != "pbm" && + format != "gif") // Known not to work QCOMPARE(buf.pos(), qint64(preLen+imageDataSize)); } -- cgit v0.12 From 0aa70ec7195e7a6ee07f73ac3c37030c9d37b132 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 12 Oct 2010 17:38:24 +0100 Subject: Fix for QFile::copy failing silently with relative paths CFileMan doesn't support . and .. in relative paths. Therefore, paths are converted to absolute first. Also, the error was being ignored which has been fixed. Reviewed-By: joao --- src/corelib/io/qfilesystemengine_symbian.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index d068248..e2dfe53 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -302,10 +302,11 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst CFileMan *fm = 0; TRAPD(err, fm = CFileMan::NewL(qt_s60GetRFs())); if (err == KErrNone) { - err = fm->Copy(qt_QString2TPtrC(source.nativeFilePath()), qt_QString2TPtrC(target.nativeFilePath()), 0); + err = fm->Copy(qt_QString2TPtrC(absoluteName(source).nativeFilePath()), qt_QString2TPtrC(absoluteName(target).nativeFilePath()), 0); delete fm; - return true; } + if (err == KErrNone) + return true; error = QSystemError(err, QSystemError::NativeError); return false; } -- cgit v0.12 From 5c5a74aa789a876805dbdb0f58de03c2195c3b97 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 12 Oct 2010 17:40:21 +0100 Subject: Fix for qfileinfo isExecutable test case. Files in /sys/bin/ on any drive can be assumed to be executable. So the executable flag is set in the metadata for this path, even though RFs::Entry fails due to permissions (so we don't know if the file exists or not) Reviewed-By: joao --- src/corelib/io/qfilesystemengine_symbian.cpp | 3 +++ tests/auto/qfileinfo/tst_qfileinfo.cpp | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index e2dfe53..dcb99d4 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -244,6 +244,9 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM data.modificationTime_ = TTime(0); data.entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags); } + //files in /sys/bin on any drive are executable, even though we don't normally have permission to check whether they exist or not + if(absentry.filePath().midRef(1,10).compare(QLatin1String(":/sys/bin/"), Qt::CaseInsensitive) == 0) + data.entryFlags |= QFileSystemMetaData::ExecutePermissions; } return data.hasFlags(what); } diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index e4aa0d3..d2019b1 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -1465,9 +1465,6 @@ void tst_QFileInfo::isWritable() void tst_QFileInfo::isExecutable() { #ifdef Q_OS_SYMBIAN -# if defined(Q_CC_NOKIAX86) - QSKIP("Impossible to implement reading/touching of application binaries in Symbian emulator", SkipAll); -# endif QString appPath = "c:/sys/bin/tst_qfileinfo.exe"; #else QString appPath = QCoreApplication::applicationDirPath(); -- cgit v0.12 From 303bb0a3d60c3d7b991ea7829c6dd2c5b3beb9d6 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 13 Oct 2010 14:20:38 +0100 Subject: Fix crash in QApplication auto test The pointer is lazily initialised by QWidget, but becomes invalid after the application is destroyed. In the QApplication autotest, QApplication is created and destroyed many times in the same thread (while in normal use it is created at startup and destroyed on exit) As a result, the pointer which is stored in global data became stale and caused a crash due to calling functions on a deleted object. Reviewed-By: Jason Barron --- src/gui/kernel/qapplication_s60.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index ad44d21..57702c6 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1613,6 +1613,9 @@ extern void qt_cleanup_symbianFontDatabaseExtras(); // qfontdatabase_s60.cpp *****************************************************************************/ void qt_cleanup() { +#ifdef Q_WS_S60 + S60->setButtonGroupContainer(0); +#endif if(qt_S60Beep) { delete qt_S60Beep; qt_S60Beep = 0; -- cgit v0.12 From 7a5adf67655b54a0ea43b641dfbd0924b06d214a Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 13 Oct 2010 17:40:03 +0100 Subject: Create regression test for QFileInfo("").exists() File engine refactor caused a regression in QTextDocument, due to a QFileInfo constructed with an empty string returning true from exists() Added a test case to QFileInfo to catch this at the correct level. Reviewed-By: joao --- tests/auto/qfileinfo/tst_qfileinfo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index d2019b1..cd1a597 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -412,6 +412,7 @@ void tst_QFileInfo::exists_data() QTest::newRow("data9") << SRCDIR "resources/file?.ext1" << false; QTest::newRow("data10") << "." << true; QTest::newRow("data11") << ". " << false; + QTest::newRow("empty") << "" << false; QTest::newRow("simple dir") << SRCDIR "resources" << true; QTest::newRow("simple dir with slash") << SRCDIR "resources/" << true; -- cgit v0.12 From c822fba71e2949eea3de49009ef99602a4110914 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 13 Oct 2010 17:42:54 +0100 Subject: Fix QFileInfo("").exists() regression for symbian Because RFs::Entry("") gets the entry for the current directory, we need to explicitly check for empty strings and treat as a non existant file. Reviewed-By: joao --- src/corelib/io/qfilesystemengine_symbian.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index dcb99d4..89a2b29 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -222,7 +222,9 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM RFs& fs(qt_s60GetRFs()); TInt err; QFileSystemEntry absentry(absoluteName(entry)); - if (absentry.isRoot()) { + if (entry.isEmpty()) { + err = KErrNotFound; + } else if (absentry.isRoot()) { //Root directories don't have an entry, and Entry() returns KErrBadName. //Therefore get information about the volume instead. TInt drive; -- cgit v0.12 From 9ea66f867c1aeb60dc4e90acefb2258a084740ca Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 13 Oct 2010 19:00:00 +0100 Subject: Autotest for seeking beyond end of file and then writing File engine refactor caused a regression in the TIFF image codec, as QFile::seek() previously worked like lseek() / fseek() in posix. But on symbian the native RFile::Seek api clamps to the end of the file if you attempt to seek beyond there. This test checks seek behaviour in the appropriate place, the QFile auto test. Reviewed-By: joao --- tests/auto/qfile/tst_qfile.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 2524e6e..4e7cb9f 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -170,6 +170,7 @@ private slots: void encodeName(); void truncate(); void seekToPos(); + void seekAfterEndOfFile(); void FILEReadWrite(); void i18nFileName_data(); void i18nFileName(); @@ -1644,6 +1645,36 @@ void tst_QFile::seekToPos() } +void tst_QFile::seekAfterEndOfFile() +{ + QLatin1String filename("seekAfterEof.dat"); + QFile::remove(filename); + { + QFile file(filename); + QVERIFY(file.open(QFile::WriteOnly)); + file.write("abcd"); + QCOMPARE(file.size(), qint64(4)); + file.seek(8); + file.write("ijkl"); + QCOMPARE(file.size(), qint64(12)); + file.seek(4); + file.write("efgh"); + QCOMPARE(file.size(), qint64(12)); + file.seek(16); + file.write("----"); + QCOMPARE(file.size(), qint64(20)); + file.flush(); + } + + QFile file(filename); + QVERIFY(file.open(QFile::ReadOnly)); + QByteArray contents = file.readAll(); + QCOMPARE(contents.left(12), QByteArray("abcdefghijkl", 12)); + //bytes 12-15 are uninitialised so we don't care what they read as. + QCOMPARE(contents.mid(16), QByteArray("----", 4)); + file.close(); + QFile::remove(filename); +} void tst_QFile::FILEReadWrite() { -- cgit v0.12 From a2a748f59a14f71c7f7cd5762ae9d358af2518c3 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 14 Oct 2010 14:42:34 +0100 Subject: Fix crashes and hangs in qprocess autotest The qprocess autotest launches various sub processes and checks their results, but this lacked error handling. Added a QVERIFY when opening files (if fopen returned NULL, the test fails instead of crashing) Added a 10s guard when waiting for a subprocess to create a file - previously this loop did not terminate if the subprocess failed. Reviewed-By: Markus Goetz --- tests/auto/qprocess/tst_qprocess.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp index fd310f4..a497b13 100644 --- a/tests/auto/qprocess/tst_qprocess.cpp +++ b/tests/auto/qprocess/tst_qprocess.cpp @@ -1585,6 +1585,7 @@ void tst_QProcess::spaceArgsTest() #if defined(Q_OS_SYMBIAN) // Symbian test outputs to a file, so check that FILE* file = fopen("c:\\logs\\qprocess_args_test.txt","r"); + QVERIFY(file); char buf[256]; fgets(buf, 256, file); fclose(file); @@ -1614,6 +1615,7 @@ void tst_QProcess::spaceArgsTest() #if defined(Q_OS_SYMBIAN) // Symbian test outputs to a file, so check that file = fopen("c:\\logs\\qprocess_args_test.txt","r"); + QVERIFY(file); fgets(buf, 256, file); fclose(file); actual = QString::fromLatin1(buf).split("|"); @@ -1661,6 +1663,7 @@ void tst_QProcess::nativeArguments() # else FILE* file = fopen("\\temp\\qprocess_args_test.txt","r"); # endif + QVERIFY(file); char buf[256]; fgets(buf, 256, file); fclose(file); @@ -2285,7 +2288,9 @@ void tst_QProcess::detachedWorkingDirectoryAndPid() QFileInfo fi(infoFile); fi.setCaching(false); - while (fi.size() == 0) { + //The guard counter ensures the test does not hang if the sub process fails. + //Instead, the test will fail when trying to open & verify the sub process output file. + for (int guard = 0; guard < 100 && fi.size() == 0; guard++) { QTest::qSleep(100); } @@ -2397,6 +2402,7 @@ void tst_QProcess::startFinishStartFinish() #if defined(Q_OS_SYMBIAN) // Symbian test outputs to a file, so check that FILE* file = fopen("c:\\logs\\qprocess_output_test.txt","r"); + QVERIFY(file); char buf[30]; fgets(buf, 30, file); QCOMPARE(QString::fromLatin1(buf), -- cgit v0.12 From 2e35e9c1eabe667798572457c61e1d1d1f373317 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 15 Oct 2010 12:12:49 +0100 Subject: Document behaviour of QFile::seek when seeking beyond EOF Reviewed-By: joao --- src/corelib/io/qfile.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 50e9a8f..a0bc68e 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -1477,7 +1477,17 @@ bool QFile::atEnd() const } /*! - \reimp + For random-access devices, this function sets the current position + to \a pos, returning true on success, or false if an error occurred. + For sequential devices, the default behavior is to do nothing and + return false. + + Seeking beyond the end of a file: + If the position is beyond the end of a file, then seek() shall not + immediately extend the file. If a write is performed at this position, + then the file shall be extended. The content of the file between the + previous end of file and the newly written data is UNDEFINED and + varies between platforms and file systems. */ bool QFile::seek(qint64 off) -- cgit v0.12 From 366d2ed09ebf5aa27171a46d723497e5aaa5dd06 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 18 Oct 2010 15:15:39 +0100 Subject: Implement seek beyond end of file for symbian On Symbian, the Seek() function clamps to the end of file position if a position beyond the end of file is given. Also the write functions which take a position silently append at the end of file position if asked to write to a start position beyond EOF. To avoid this behaviour, we don't use seek but rather maintain our own cursor position. When writing, we check if the cursor is beyond EOF and if so extend the file using SetSize() before writing. Reviewed-By: joao --- src/corelib/io/qfsfileengine_unix.cpp | 51 ++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index caf5f4c..96946d6 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -382,12 +382,13 @@ qint64 QFSFileEnginePrivate::nativeRead(char *data, qint64 len) return -1; } TPtr8 ptr(reinterpret_cast(data), static_cast(len)); - TInt r = symbianFile.Read(ptr); + TInt r = symbianFile.Read(symbianFilePos, ptr); if (r != KErrNone) { q->setError(QFile::ReadError, QSystemError(r, QSystemError::NativeError).toString()); return -1; } + symbianFilePos += ptr.Length(); return qint64(ptr.Length()); } #endif @@ -467,12 +468,28 @@ qint64 QFSFileEnginePrivate::nativeWrite(const char *data, qint64 len) return -1; } const TPtrC8 ptr(reinterpret_cast(data), static_cast(len)); - TInt r = symbianFile.Write(ptr); - if (r != KErrNone) - { +#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API + TInt64 eofpos = 0; +#else + TInt eofpos = 0; +#endif + //The end of file position is not cached because QFile is read/write sharable, therefore another + //process may have altered the file size. + TInt r = symbianFile.Seek(ESeekEnd, eofpos); + if (r == KErrNone && symbianFilePos > eofpos) { + //seek position is beyond end of file so file needs to be extended before write. + //note that SetSize does not zero-initialise (c.f. posix lseek) + r = symbianFile.SetSize(symbianFilePos); + } + if (r == KErrNone) { + //write to specific position in the file (i.e. use our own cursor rather than calling seek) + r = symbianFile.Write(symbianFilePos, ptr); + } + if (r != KErrNone) { q->setError(QFile::WriteError, QSystemError(r, QSystemError::NativeError).toString()); return -1; } + symbianFilePos += len; return len; } #endif @@ -487,17 +504,7 @@ qint64 QFSFileEnginePrivate::nativePos() const #ifdef Q_OS_SYMBIAN const Q_Q(QFSFileEngine); if (symbianFile.SubSessionHandle()) { -#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API - qint64 pos = 0; -#else - TInt pos = 0; -#endif - TInt err = symbianFile.Seek(ESeekCurrent, pos); - if(err != KErrNone) { - const_cast(q)->setError(QFile::PositionError, QSystemError(err, QSystemError::NativeError).toString()); - return -1; - } - return pos; + return symbianFilePos; } #endif return posFdFh(); @@ -511,21 +518,13 @@ bool QFSFileEnginePrivate::nativeSeek(qint64 pos) #ifdef Q_OS_SYMBIAN Q_Q(QFSFileEngine); if (symbianFile.SubSessionHandle()) { -#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API - TInt r = symbianFile.Seek(ESeekStart, pos); -#else +#ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API if(pos > KMaxTInt) { q->setError(QFile::PositionError, QLatin1String("Maximum 2GB file position on this platform")); return false; } - TInt pos32(pos); - TInt r = symbianFile.Seek(ESeekStart, pos32); #endif - if (r != KErrNone) - { - q->setError(QFile::PositionError, QSystemError(r, QSystemError::NativeError).toString()); - return false; - } + symbianFilePos = pos; return true; } #endif @@ -867,6 +866,8 @@ bool QFSFileEngine::setSize(qint64 size) if (d->symbianFile.SubSessionHandle()) { TInt err = d->symbianFile.SetSize(size); ret = (err == KErrNone); + if (ret && d->symbianFilePos > size) + d->symbianFilePos = size; } else if (d->fd != -1) ret = QT_FTRUNCATE(d->fd, size) == 0; -- cgit v0.12 From 4bdf081da0276f55662de826568441ca0e85e877 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 14 Oct 2010 14:06:20 +0100 Subject: Move QDir::fromNativeSeparators call to the QFileSystemEntry constructor The m_filePath should always have / as the separator, while m_nativeFilePath should always have the native separator. Almost every place the constructor is used, the path could be one passed into an API from code outside our control. So it's easier to do the path conversion in the constructor than to have to remember to call fromNativeSeparators in every place a QFileSystemEntry is constructed (especially since unix tests won't reveal any error) Reviewed-By: joao --- src/corelib/io/qdir.cpp | 6 +++--- src/corelib/io/qfilesystemengine_symbian.cpp | 2 +- src/corelib/io/qfilesystemengine_win.cpp | 2 +- src/corelib/io/qfilesystementry.cpp | 24 +++++++++++++++++++++++- src/corelib/io/qfilesystementry_p.h | 2 ++ src/corelib/io/qfsfileengine.cpp | 4 ++-- src/corelib/io/qfsfileengine_unix.cpp | 2 +- 7 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index e9bc012..22a3baa 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -177,7 +177,7 @@ inline void QDirPrivate::setPath(const QString &path) p.truncate(p.length() - 1); } - dirEntry = QFileSystemEntry(p); + dirEntry = QFileSystemEntry(p, QFileSystemEntry::FromInternalPath()); metaData.clear(); initFileEngine(); clearFileLists(); @@ -198,7 +198,7 @@ inline void QDirPrivate::resolveAbsoluteEntry() const if (dirEntry.isRelative()) { QFileSystemEntry answer = QFileSystemEngine::absoluteName(dirEntry); - absoluteDirEntry = QFileSystemEntry(QDir::cleanPath(answer.filePath())); + absoluteDirEntry = QFileSystemEntry(QDir::cleanPath(answer.filePath()), QFileSystemEntry::FromInternalPath()); } else { absoluteDirEntry = dirEntry; } @@ -1757,7 +1757,7 @@ QChar QDir::separator() */ bool QDir::setCurrent(const QString &path) { - return QFileSystemEngine::setCurrentPath(QFileSystemEntry(fromNativeSeparators(path))); + return QFileSystemEngine::setCurrentPath(QFileSystemEntry(path)); } /*! diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 89a2b29..c4e8d36 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -148,7 +148,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) result.append(orig); } - return QFileSystemEntry(symbianCleanAbsolutePath(result)); + return QFileSystemEntry(symbianCleanAbsolutePath(result), QFileSystemEntry::FromInternalPath()); } //static diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 53b9e43..8fa4d62 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -444,7 +444,7 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, ret = readLink(link); else if (data.isLink()) ret = readSymLink(link); - return QFileSystemEntry(QDir::fromNativeSeparators(ret)); + return QFileSystemEntry(ret); } //static diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index bc7f121..d4c6d0a 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -81,7 +81,25 @@ QFileSystemEntry::QFileSystemEntry() { } +/*! + \internal + Use this constructor when the path is supplied by user code, as it may contain a mix + of '/' and the native separator. + */ QFileSystemEntry::QFileSystemEntry(const QString &filePath) + : m_filePath(QDir::fromNativeSeparators(filePath)), + m_lastSeparator(-2), + m_firstDotInFileName(-2), + m_lastDotInFileName(0) +{ +} + +/*! + \internal + Use this constructor when the path is guaranteed to be in internal format, i.e. all + directory separators are '/' and not the native separator. + */ +QFileSystemEntry::QFileSystemEntry(const QString &filePath, FromInternalPath /* dummy */) : m_filePath(filePath), m_lastSeparator(-2), m_firstDotInFileName(-2), @@ -89,6 +107,10 @@ QFileSystemEntry::QFileSystemEntry(const QString &filePath) { } +/*! + \internal + Use this constructor when the path comes from a native API + */ QFileSystemEntry::QFileSystemEntry(const NativePath &nativeFilePath, FromNativePath /* dummy */) : m_nativeFilePath(nativeFilePath), m_lastSeparator(-2), @@ -98,7 +120,7 @@ QFileSystemEntry::QFileSystemEntry(const NativePath &nativeFilePath, FromNativeP } QFileSystemEntry::QFileSystemEntry(const QString &filePath, const NativePath &nativeFilePath) - : m_filePath(filePath), + : m_filePath(QDir::fromNativeSeparators(filePath)), m_nativeFilePath(nativeFilePath), m_lastSeparator(-2), m_firstDotInFileName(-2), diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index 7a9c2a5..2ce0a83 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -72,10 +72,12 @@ public: typedef QString NativePath; #endif struct FromNativePath{}; + struct FromInternalPath{}; QFileSystemEntry(); explicit QFileSystemEntry(const QString &filePath); + QFileSystemEntry(const QString &filePath, FromInternalPath dummy); QFileSystemEntry(const NativePath &nativeFilePath, FromNativePath dummy); QFileSystemEntry(const QString &filePath, const NativePath &nativeFilePath); diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 9c8df39..5491caf 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -140,7 +140,7 @@ QFSFileEngine::QFSFileEngine(const QString &file) : QAbstractFileEngine(*new QFSFileEnginePrivate) { Q_D(QFSFileEngine); - d->fileEntry = QFileSystemEntry(QDir::fromNativeSeparators(file)); + d->fileEntry = QFileSystemEntry(file); } /*! @@ -189,7 +189,7 @@ void QFSFileEngine::setFileName(const QString &file) { Q_D(QFSFileEngine); d->init(); - d->fileEntry = QFileSystemEntry(QDir::fromNativeSeparators(file)); + d->fileEntry = QFileSystemEntry(file); } /*! diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 96946d6..28e0677 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -640,7 +640,7 @@ bool QFSFileEngine::caseSensitive() const bool QFSFileEngine::setCurrentPath(const QString &path) { - return QFileSystemEngine::setCurrentPath(QFileSystemEntry(QDir::fromNativeSeparators(path))); + return QFileSystemEngine::setCurrentPath(QFileSystemEntry(path)); } QString QFSFileEngine::currentPath(const QString &) -- cgit v0.12 From 064c5714c2167fb2ddfb4f1ab2f706282444884f Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 19 Oct 2010 10:12:30 +0100 Subject: Fix compile error in tst_qxmlstream The same workaround used for other autotests, as the symbian build system doesn't accept \" in DEFINES. Reviewed-By: Janne Koskinen --- tests/auto/qxmlstream/qxmlstream.pro | 2 +- tests/auto/qxmlstream/tst_qxmlstream.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/auto/qxmlstream/qxmlstream.pro b/tests/auto/qxmlstream/qxmlstream.pro index 8f076be..31331cf 100644 --- a/tests/auto/qxmlstream/qxmlstream.pro +++ b/tests/auto/qxmlstream/qxmlstream.pro @@ -8,7 +8,7 @@ wince*|symbian: { addFiles.sources = data XML-Test-Suite addFiles.path = . DEPLOYMENT += addFiles - DEFINES += SRCDIR=\\\"\\\" + wince*:DEFINES += SRCDIR=\\\"\\\" } else { DEFINES += SRCDIR=\\\"$$PWD/\\\" } diff --git a/tests/auto/qxmlstream/tst_qxmlstream.cpp b/tests/auto/qxmlstream/tst_qxmlstream.cpp index 7d5e3b7..19e4b90 100644 --- a/tests/auto/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/qxmlstream/tst_qxmlstream.cpp @@ -55,6 +55,10 @@ //TESTED_CLASS=QXmlStreamReader QXmlStreamWriter //TESTED_FILES=corelib/xml/stream/qxmlutils.cpp corelib/xml/stream/qxmlstream.cpp corelib/xml/stream/qxmlstream_p.h +#ifdef Q_OS_SYMBIAN +#define SRCDIR "" +#endif + Q_DECLARE_METATYPE(QXmlStreamReader::ReadElementTextBehaviour) static const char *const catalogFile = SRCDIR "XML-Test-Suite/xmlconf/finalCatalog.xml"; -- cgit v0.12 From ea69ae0df02de27ec0f0a1a9b0a122655445fc01 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 20 Oct 2010 13:36:00 +0100 Subject: Fix QFileDialog regression in symbian Symbian now follows the same convention as windows, where "c:" means the working directory on the C: drive. As a result, the path "c:/" needs to be passed to QFileInfoGatherer when getting info for the root directory. This code already existed but only enabled for windows - now enabled for symbian as well. Reviewed-By: Markus Goetz --- src/gui/dialogs/qfilesystemmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp index b8aafe3..be4261d 100644 --- a/src/gui/dialogs/qfilesystemmodel.cpp +++ b/src/gui/dialogs/qfilesystemmodel.cpp @@ -1290,7 +1290,7 @@ QString QFileSystemModelPrivate::filePath(const QModelIndex &index) const if ((fullPath.length() > 2) && fullPath[0] == QLatin1Char('/') && fullPath[1] == QLatin1Char('/')) fullPath = fullPath.mid(1); #endif -#if defined(Q_OS_WIN) +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) if (fullPath.length() == 2 && fullPath.endsWith(QLatin1Char(':'))) fullPath.append(QLatin1Char('/')); #endif -- cgit v0.12 From 12ae7dea67244458fc92575ae2f49a8e32343047 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 20 Oct 2010 13:45:50 +0100 Subject: Fix errors in the QFileDialog autotest The filesSelectedSignal() test case was using the Qt source tree as its test directory - however this is not deployed to the device for symbian and windows CE. On symbian, the path evaluates to the root directory, which doesn't meet the conditions of the test (it contains only directories, while the test requires both files and directories to be present) Changed the test to use SRCDIR (on desktops, the source directory of the test code; on symbian/wince the deployed files location) This directory is valid for the test as it contains both files and directories. The hooks() test case crashes on symbian versions prior to symbian^3, because data exports from dlls are not properly supported by the symbian kernel So, this test is skipped for old symbian versions (if a test crashes, then no xml result file is created) Reviewed-By: Markus Goetz --- tests/auto/qfiledialog/tst_qfiledialog.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp index 5d369b4..ec244c5 100644 --- a/tests/auto/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp @@ -279,7 +279,7 @@ void tst_QFiledialog::filesSelectedSignal() QNonNativeFileDialog fd; fd.setViewMode(QFileDialog::List); fd.setOptions(QFileDialog::DontUseNativeDialog); - QDir testDir(SRCDIR"/../../.."); + QDir testDir(SRCDIR); fd.setDirectory(testDir); QFETCH(QFileDialog::FileMode, fileMode); fd.setFileMode(fileMode); @@ -1308,6 +1308,10 @@ QString saveName(QWidget *, const QString &, const QString &, const QString &, Q void tst_QFiledialog::hooks() { +#ifdef Q_OS_SYMBIAN + if(QSysInfo::symbianVersion() < QSysInfo::SV_SF_3) + QSKIP("writing to data exports in paged dll not supported and crashes on symbian versions prior to ^3", SkipAll); +#endif qt_filedialog_existing_directory_hook = &existing; qt_filedialog_save_filename_hook = &saveName; qt_filedialog_open_filename_hook = &openName; -- cgit v0.12 From 848bbec851ca1bb83ce43aa07240c28cdcb0125a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 22 Oct 2010 10:50:40 +0200 Subject: Fix qmake compilation on *nix platforms --- qmake/Makefile.unix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 7d61cf8..f1697a9 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -106,7 +106,7 @@ qsettings.o: $(SOURCE_PATH)/src/corelib/io/qsettings.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qsettings.cpp qsystemerror.o: $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp - $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp qlibraryinfo.o: $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp -- cgit v0.12 From 02f3d23bc2cb6f4011918cff50fe157a8523c10b Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 26 Oct 2010 13:48:15 +0200 Subject: Add support for QFileInfo owner() & group() on Windows Since windows doesn't have the concept of user and group IDs, the name resolution has to be done differently. If the qt_ntfs_permission_lookup flag is set (default = 0), the user information is retrieved through the NTFS object security information. Reviewed-by: Joao --- src/corelib/io/qfilesystemengine.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index 9bfd382..8613dd7 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -349,17 +349,35 @@ void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry) //static QString QFileSystemEngine::resolveUserName(const QFileSystemEntry &entry, QFileSystemMetaData &metaData) { +#if defined (Q_OS_SYMBIAN) + Q_UNUSED(entry); + Q_UNUSED(metaData); + return QString(); +#elif defined(Q_OS_WIN) + Q_UNUSED(metaData); + return QFileSystemEngine::owner(entry, QAbstractFileEngine::OwnerUser); +#else //(Q_OS_UNIX) if (!metaData.hasFlags(QFileSystemMetaData::UserId)) QFileSystemEngine::fillMetaData(entry, metaData, QFileSystemMetaData::UserId); return resolveGroupName(metaData.userId()); +#endif } //static QString QFileSystemEngine::resolveGroupName(const QFileSystemEntry &entry, QFileSystemMetaData &metaData) { +#if defined (Q_OS_SYMBIAN) + Q_UNUSED(entry); + Q_UNUSED(metaData); + return QString(); +#elif defined(Q_OS_WIN) + Q_UNUSED(metaData); + return QFileSystemEngine::owner(entry, QAbstractFileEngine::OwnerGroup); +#else //(Q_OS_UNIX) if (!metaData.hasFlags(QFileSystemMetaData::GroupId)) QFileSystemEngine::fillMetaData(entry, metaData, QFileSystemMetaData::GroupId); return resolveGroupName(metaData.groupId()); +#endif } QT_END_NAMESPACE -- cgit v0.12 From ae9b1a4a392953097d05d55549cc1583f94c3bc8 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 27 Oct 2010 13:48:43 +0200 Subject: Add tests for QFileInfo::owner() Reviewed-by: Joao --- tests/auto/qfileinfo/qfileinfo.pro | 2 ++ tests/auto/qfileinfo/tst_qfileinfo.cpp | 66 ++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/tests/auto/qfileinfo/qfileinfo.pro b/tests/auto/qfileinfo/qfileinfo.pro index 7df721e..101128c 100644 --- a/tests/auto/qfileinfo/qfileinfo.pro +++ b/tests/auto/qfileinfo/qfileinfo.pro @@ -13,6 +13,8 @@ wince*:|symbian: { DEPLOYMENT += deploy res } +win32*:LIBS += -ladvapi32 -lnetapi32 + symbian { TARGET.CAPABILITY=AllFiles LIBS *= -lefsrv diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index cd1a597..898bf54 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -59,6 +59,7 @@ #define _WIN32_WINNT 0x500 #include #include +#include #endif #include #include @@ -184,6 +185,10 @@ private slots: void notEqualOperator() const; void detachingOperations(); + +#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) + void owner(); +#endif }; tst_QFileInfo::tst_QFileInfo() @@ -1599,5 +1604,66 @@ void tst_QFileInfo::detachingOperations() QVERIFY(!info1.caching()); } +#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) +void tst_QFileInfo::owner() +{ + QString userName; +#if defined(Q_OS_UNIX) + char *usernameBuf = getlogin(); + if (usernameBuf) { + userName = QString::fromLocal8Bit(usernameBuf); + } +#endif +#if defined(Q_OS_WIN) + wchar_t usernameBuf[1024]; + DWORD bufSize = 1024; + if (GetUserNameW(usernameBuf, &bufSize)) { + userName = QString::fromWCharArray(usernameBuf, bufSize); + // Special case : If the user is a member of Adminstrators group, all files + // created by the current user are owned by the Admistrators group. + LPLOCALGROUP_USERS_INFO_0 pBuf = NULL; + DWORD dwLevel = 0; + DWORD dwFlags = LG_INCLUDE_INDIRECT ; + DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH; + DWORD dwEntriesRead = 0; + DWORD dwTotalEntries = 0; + NET_API_STATUS nStatus; + nStatus = NetUserGetLocalGroups(0, usernameBuf, dwLevel, dwFlags, (LPBYTE *) &pBuf, + dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries); + // Check if the current user is a member of Adminstrators group + if (nStatus == NERR_Success && pBuf){ + for (int i = 0; i < dwEntriesRead; i++) { + QString groupName = QString::fromWCharArray(pBuf[i].lgrui0_name); + if (!groupName.compare(QLatin1String("Administrators"))) + userName = groupName; + } + } + if (pBuf != NULL) + NetApiBufferFree(pBuf); + } + extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; + qt_ntfs_permission_lookup = 1; +#endif + if (userName.isEmpty()) + QSKIP("Can't retrieve the user name", SkipAll); + QString fileName("ownertest.txt"); + if (QFile::exists(fileName)) + QFile::remove(fileName); + QFile testFile(fileName); + QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Text)); + QByteArray testData("testfile"); + QVERIFY(testFile.write(testData) != -1); + testFile.close(); + QFileInfo fi(fileName); + QVERIFY(fi.exists()); + QCOMPARE(userName, fi.owner()); + if (QFile::exists(fileName)) + QFile::remove(fileName); +#if defined(Q_OS_WIN) + qt_ntfs_permission_lookup = 0; +#endif +} +#endif + QTEST_MAIN(tst_QFileInfo) #include "tst_qfileinfo.moc" -- cgit v0.12 From c1148ee9a60a6fae88ca09c21203e3f6c68c3c63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 28 Oct 2010 14:35:43 +0200 Subject: Lighthouse: eventloop integration rework. For cocoa we really need to be able to run the cocoa eventloop [NSApplicatyion run]. Also it makes sense for openKODE without nvidia extensions. --- src/gui/kernel/qeventdispatcher_qpa.cpp | 45 ++++++++- .../kernel/qplatformeventloopintegration_qpa.cpp | 45 +++++++++ src/gui/kernel/qplatformeventloopintegration_qpa.h | 24 ++++- .../platforms/cocoa/qcocoaeventloopintegration.h | 21 ++--- .../platforms/cocoa/qcocoaeventloopintegration.mm | 104 +++++++++------------ src/plugins/platforms/cocoa/qcocoaintegration.mm | 2 +- src/plugins/platforms/cocoa/qcocoawindow.mm | 8 +- 7 files changed, 158 insertions(+), 91 deletions(-) diff --git a/src/gui/kernel/qeventdispatcher_qpa.cpp b/src/gui/kernel/qeventdispatcher_qpa.cpp index cb70141..31fb356 100644 --- a/src/gui/kernel/qeventdispatcher_qpa.cpp +++ b/src/gui/kernel/qeventdispatcher_qpa.cpp @@ -51,6 +51,8 @@ #include #include +#include + #include QT_BEGIN_NAMESPACE @@ -122,7 +124,8 @@ public: selectWorkerNeedsSync(true), selectWorkerHasResult(false), m_integrationInitialised(false), - m_hasIntegration(false) + m_hasIntegration(false), + m_isEventLoopIntegrationRunning(false) { } @@ -160,6 +163,20 @@ public: return m_hasIntegration; } + bool isEventLoopIntegrationRunning() const + { + return m_isEventLoopIntegrationRunning; + } + + void runEventLoopIntegration() + { + if (qApp && (qApp->thread() == QThread::currentThread())) { + m_isEventLoopIntegrationRunning = true; + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); + eventLoopIntegration->startEventLoop(); + } + } + QPlatformEventLoopIntegration *eventLoopIntegration; Rendezvous *barrierBeforeBlocking; Rendezvous *barrierReturnValue; @@ -172,6 +189,7 @@ public: private: bool m_integrationInitialised; bool m_hasIntegration; + bool m_isEventLoopIntegrationRunning; }; QEventDispatcherQPA::QEventDispatcherQPA(QObject *parent) @@ -184,6 +202,17 @@ QEventDispatcherQPA::~QEventDispatcherQPA() bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags) { Q_D(QEventDispatcherQPA); + + if (d->hasIntegration()) { + if (!d->isEventLoopIntegrationRunning()) { + d->runEventLoopIntegration(); + } + if (d->threadData->quitNow) { + d->eventLoopIntegration->quitEventLoop(); + return false; + } + } + int nevents = 0; // handle gui and posted events @@ -213,8 +242,10 @@ bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags) } if (!d->interrupt) { - if (QEventDispatcherUNIX::processEvents(flags)) + if (QEventDispatcherUNIX::processEvents(flags)) { + QEventDispatcherUNIX::processEvents(flags); return true; + } } return (nevents > 0); } @@ -248,7 +279,6 @@ void QEventDispatcherQPA::flush() qApp->sendPostedEvents(); } - int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, timeval *timeout) { @@ -266,6 +296,7 @@ int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_ d->selectReturnMutex->unlock(); d->barrierReturnValue->checkpoint(); + d->eventLoopIntegration->setNextTimerEvent(0); return retVal; } else { d->selectWorkerNeedsSync = false; @@ -274,7 +305,7 @@ int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_ } } d->selectReturnMutex->unlock(); - d->eventLoopIntegration->processEvents(timeoutmsec); + d->eventLoopIntegration->setNextTimerEvent(timeoutmsec); retVal = 0; //is 0 if select has not returned } else { retVal = QEventDispatcherUNIX::select(nfds, readfds, writefds, exceptfds, timeout); @@ -282,14 +313,16 @@ int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_ return retVal; } + void SelectWorker::run() { + while(true) { m_retVal = 0; m_edPrivate->barrierBeforeBlocking->checkpoint(); // wait for mainthread int tmpRet = qt_safe_select(m_nfds,m_readfds,m_writefds,m_exceptfds,0); m_edPrivate->selectReturnMutex->lock(); - m_edPrivate->eventLoopIntegration->wakeup(); + m_edPrivate->eventLoopIntegration->qtNeedsToProcessEvents(); m_edPrivate->selectWorkerNeedsSync = true; m_edPrivate->selectWorkerHasResult = true; @@ -299,4 +332,6 @@ void SelectWorker::run() m_edPrivate->barrierReturnValue->checkpoint(); } } + +#include "qeventdispatcher_qpa.moc" QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformeventloopintegration_qpa.cpp b/src/gui/kernel/qplatformeventloopintegration_qpa.cpp index 8bdba5e..fdb3852 100644 --- a/src/gui/kernel/qplatformeventloopintegration_qpa.cpp +++ b/src/gui/kernel/qplatformeventloopintegration_qpa.cpp @@ -39,3 +39,48 @@ ** ****************************************************************************/ +#include "qplatformeventloopintegration_qpa.h" + +#include + +#include + +class QPlatformEventLoopIntegrationPrivate +{ +public: + QPlatformEventLoopIntegrationPrivate(); + qint64 nextTimerEvent; +}; + +QPlatformEventLoopIntegrationPrivate::QPlatformEventLoopIntegrationPrivate() + : nextTimerEvent(0) +{ +} + +QPlatformEventLoopIntegration::QPlatformEventLoopIntegration() + : d_ptr(new QPlatformEventLoopIntegrationPrivate) + +{ +} + +QPlatformEventLoopIntegration::~QPlatformEventLoopIntegration() +{ +} + +qint64 QPlatformEventLoopIntegration::nextTimerEvent() const +{ + Q_D(const QPlatformEventLoopIntegration); + return d->nextTimerEvent; +} + + +void QPlatformEventLoopIntegration::setNextTimerEvent(qint64 nextTimerEvent) +{ + Q_D(QPlatformEventLoopIntegration); + d->nextTimerEvent = nextTimerEvent; +} + +void QPlatformEventLoopIntegration::processEvents() +{ + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); +} diff --git a/src/gui/kernel/qplatformeventloopintegration_qpa.h b/src/gui/kernel/qplatformeventloopintegration_qpa.h index a06fecf..6e0f984 100644 --- a/src/gui/kernel/qplatformeventloopintegration_qpa.h +++ b/src/gui/kernel/qplatformeventloopintegration_qpa.h @@ -43,6 +43,7 @@ #define QPLATFORMEVENTLOOPINTEGRATION_QPA_H #include +#include QT_BEGIN_HEADER @@ -50,11 +51,28 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) -class QPlatformEventLoopIntegration +class QPlatformEventLoopIntegrationPrivate; + +class Q_GUI_EXPORT QPlatformEventLoopIntegration { + Q_DECLARE_PRIVATE(QPlatformEventLoopIntegration); public: - virtual void processEvents( qint64 msec ) = 0; - virtual void wakeup() = 0; + QPlatformEventLoopIntegration(); + virtual ~QPlatformEventLoopIntegration(); + + virtual void startEventLoop() = 0; + virtual void quitEventLoop() = 0; + virtual void qtNeedsToProcessEvents() = 0; + + qint64 nextTimerEvent() const; + void setNextTimerEvent(qint64 nextTimerEvent); + + static void processEvents(); +protected: + QScopedPointer d_ptr; +private: + Q_DISABLE_COPY(QPlatformEventLoopIntegration); + friend class QEventDispatcherQPA; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h index 8c21944..87998e3 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h @@ -46,29 +46,20 @@ #include -@interface OurApplication: NSApplication -{ - bool shouldKeepRunning; -} - -- (void) run; -- (void) processEvents: (int) msec; - -@end class QCocoaEventLoopIntegration : public QPlatformEventLoopIntegration { public: QCocoaEventLoopIntegration(); - void processEvents( qint64 msec ); - void wakeup(); + void startEventLoop(); + void quitEventLoop(); + void qtNeedsToProcessEvents(); - static int wakeupEventId; private: - OurApplication *app; + CFRunLoopSourceContext m_sourceContext; + CFRunLoopTimerContext m_timerContext; + CFRunLoopSourceRef m_source; }; - - #endif // QCOCAEVENTLOOPINTEGRATION_H diff --git a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm index b184f90..844751c 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm @@ -48,81 +48,65 @@ #include #include +#include -@implementation OurApplication - -- (void) run -{ - QCocoaAutoReleasePool pool; - [self finishLaunching]; - - shouldKeepRunning = YES; +void wakeupCallback ( void * ) { + QPlatformEventLoopIntegration::processEvents(); } -- (void) processEvents : (int) msec +void timerCallback( CFRunLoopTimerRef timer, void *info) { - QCocoaAutoReleasePool pool; - Q_UNUSED(pool); - - QElapsedTimer timer; - timer.start(); - - NSTimeInterval seconds = NSTimeInterval(msec)/1000; - id untilDate = [NSDate dateWithTimeIntervalSinceNow:seconds]; - bool continueLooping = true; - while ((timer.elapsed() < (msec-1)) && continueLooping) { - NSEvent *event = - [self nextEventMatchingMask:NSAnyEventMask - untilDate:untilDate - inMode:NSDefaultRunLoopMode - dequeue:YES]; - if ([event type] == NSApplicationDefined - && [event subtype] == QCocoaEventLoopIntegration::wakeupEventId) { - continueLooping = false; - } else { - [self sendEvent:event]; - } - - } - [self updateWindows]; + QPlatformEventLoopIntegration::processEvents(); + QCocoaEventLoopIntegration *eventLoopIntegration = + static_cast(info); + qint64 nextTime = eventLoopIntegration->nextTimerEvent(); + CFAbsoluteTime nexttime = CFAbsoluteTimeGetCurrent(); + nexttime = nexttime + (double(nextTime)/1000); + CFRunLoopTimerSetNextFireDate(timer,nexttime); } -@end - -int QCocoaEventLoopIntegration::wakeupEventId = SHRT_MAX; - QCocoaEventLoopIntegration::QCocoaEventLoopIntegration() : QPlatformEventLoopIntegration() { - app = (OurApplication *)[OurApplication sharedApplication]; - [app run]; + [NSApplication sharedApplication]; + m_sourceContext.version = 0; + m_sourceContext.info = this; + m_sourceContext.retain = 0; + m_sourceContext.release = 0; + m_sourceContext.copyDescription = 0; + m_sourceContext.equal = 0; + m_sourceContext.hash = 0; + m_sourceContext.schedule = 0; + m_sourceContext.cancel = 0; + m_sourceContext.perform = wakeupCallback; + + m_source = CFRunLoopSourceCreate(0,0,&m_sourceContext); + CFRunLoopAddSource(CFRunLoopGetMain(),m_source,kCFRunLoopCommonModes); + + m_timerContext.version = 0; + m_timerContext.info = this; + m_timerContext.retain = 0; + m_timerContext.release = 0; + m_timerContext.copyDescription = 0; + CFAbsoluteTime fireDate = CFAbsoluteTimeGetCurrent (); + CFTimeInterval interval = 30; + + CFRunLoopTimerRef m_timerSource = CFRunLoopTimerCreate(0,fireDate,interval,0,0,timerCallback,&m_timerContext); + CFRunLoopAddTimer(CFRunLoopGetMain(),m_timerSource,kCFRunLoopCommonModes); } -void QCocoaEventLoopIntegration::processEvents(qint64 msec) +void QCocoaEventLoopIntegration::startEventLoop() { - [app processEvents:msec]; + [[NSApplication sharedApplication] run]; } -void QCocoaEventLoopIntegration::wakeup() +void QCocoaEventLoopIntegration::quitEventLoop() { - QCocoaAutoReleasePool pool; - Q_UNUSED(pool); - - NSPoint p = NSMakePoint(0,0); - NSWindow *nswin = [app keyWindow]; - double timestamp = (double)(AbsoluteToDuration(UpTime())) / 1000.0; - NSEvent *event = [NSEvent - otherEventWithType:NSApplicationDefined - location:NSZeroPoint - modifierFlags:0 - timestamp: timestamp - windowNumber:[nswin windowNumber] - context:0 - subtype:QCocoaEventLoopIntegration::wakeupEventId - data1:0 - data2:0 - ]; - [app postEvent:event atStart:NO]; + [[NSApplication sharedApplication] terminate:nil]; +} +void QCocoaEventLoopIntegration::qtNeedsToProcessEvents() +{ + CFRunLoopSourceSignal(m_source); } diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 79d5f51..28e894c 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -79,7 +79,7 @@ QCocoaIntegration::QCocoaIntegration() mPool = new QCocoaAutoReleasePool; //Make sure we have a nsapplication :) - [OurApplication sharedApplication]; + [NSApplication sharedApplication]; // [[OurApplication alloc] init]; NSArray *screens = [NSScreen screens]; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index f004cb8..4e233ee 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -106,11 +106,5 @@ void QCocoaWindow::windowDidResize() //jlind: XXX This isn't ideal. Eventdispatcher does not run when resizing... NSRect rect = [[m_nsWindow contentView]frame]; QRect geo(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height); - if (geometry() != geo) { - widget()->setGeometry(geo); - QResizeEvent e(geo.size(), geometry().size()); - setGeometry(geo); - QApplication::sendEvent(widget(), &e); - widget()->repaint(); - } + QWindowSystemInterface::handleGeometryChange(widget(),geo); } -- cgit v0.12 From 3d86d2a8e5e3c68f9e0022e676293ddc5288c849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 27 Oct 2010 09:54:23 +0200 Subject: Disable the ./configure -qpa [platform] flag also fix what mkspec should be picked up when compiling on mac --- configure | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/configure b/configure index da48dba..08d2f54 100755 --- a/configure +++ b/configure @@ -346,7 +346,7 @@ earlyArgParse() fi ;; qpa) - CFG_EMBEDDED="$VAL" + CFG_EMBEDDED="no" if [ "$PLATFORM_QPA" != "no" ]; then if [ "$PLATFORM_QPA" = "maybe" ]; then PLATFORM_X11=no @@ -1333,7 +1333,7 @@ while [ "$#" -gt 0 ]; do fi ;; embedded-lite|qpa) - CFG_EMBEDDED="$VAL" + CFG_EMBEDDED="no" if [ "$PLATFORM_QPA" != "no" ]; then if [ "$PLATFORM_QPA" = "maybe" ]; then PLATFORM_X11=no @@ -2622,7 +2622,6 @@ fi ### help #------------------------------------------------------------------------------- [ "$PLATFORM_QWS" = "yes" -a "$CFG_EMBEDDED" = "no" ] && CFG_EMBEDDED=auto -[ "$PLATFORM_QPA" = "yes" -a "$CFG_EMBEDDED" = "no" ] && CFG_EMBEDDED=auto if [ "$CFG_EMBEDDED" != "no" ]; then case "$UNAME_SYSTEM:$UNAME_RELEASE" in Darwin:*) @@ -2705,7 +2704,7 @@ if [ -z "$PLATFORM" ]; then PLATFORM_NOTES= case "$UNAME_SYSTEM:$UNAME_RELEASE" in Darwin:*) - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$PLATFORM_MAC" = "yes" -o "$PLATFORM_QPA" = "yes" ]; then PLATFORM=macx-g++ # PLATFORM=macx-xcode else @@ -6957,7 +6956,6 @@ if [ "$PLATFORM_QWS" = "yes" ]; then rm -f "src/.moc/$QMAKE_OUTDIR/allmoc.cpp" # needs remaking if config changes fi if [ "$PLATFORM_QPA" = "yes" ]; then - QMAKE_OUTDIR="${QMAKE_OUTDIR}-emb-$CFG_EMBEDDED" QMAKE_CONFIG="$QMAKE_CONFIG qpa" QT_CONFIG="$QT_CONFIG qpa" rm -f "src/.moc/$QMAKE_OUTDIR/allmoc.cpp" # needs remaking if config changes -- cgit v0.12 From 6a5a894dda402b433505447f14fb7ed9eeac8a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 28 Oct 2010 12:41:31 +0200 Subject: Moving QCoreTextFontEngine with related classes into own file The declaration of QCoreTextFontEngine was ifdefed in qfontengine_p.h. So was QMacFontEngine. I have moved them into their own files (qfontengine_coretext_p.h and qfontengine_mac_p.h). --- src/gui/dialogs/qfontdialog_mac.mm | 1 + src/gui/image/qimage.cpp | 20 + src/gui/image/qimage_p.h | 1 + src/gui/painting/qpaintengine_mac.cpp | 2 + src/gui/text/qfont_mac.cpp | 1 + src/gui/text/qfontdatabase_mac.cpp | 2 + src/gui/text/qfontengine_coretext.mm | 667 +++++++++++++++++++++++++++++++++ src/gui/text/qfontengine_coretext_p.h | 136 +++++++ src/gui/text/qfontengine_mac.mm | 680 +--------------------------------- src/gui/text/qfontengine_mac_p.h | 167 +++++++++ src/gui/text/qfontengine_p.h | 210 ----------- src/gui/text/qtextengine_mac.cpp | 3 + src/gui/text/text.pri | 10 +- src/gui/util/qdesktopservices_mac.cpp | 2 + 14 files changed, 1014 insertions(+), 888 deletions(-) create mode 100644 src/gui/text/qfontengine_coretext.mm create mode 100644 src/gui/text/qfontengine_coretext_p.h create mode 100644 src/gui/text/qfontengine_mac_p.h diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm index 6fb363b..1b9778c 100644 --- a/src/gui/dialogs/qfontdialog_mac.mm +++ b/src/gui/dialogs/qfontdialog_mac.mm @@ -51,6 +51,7 @@ #include #include #include +#include #import #import diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 5829fe8..ee0ee96 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3861,6 +3861,26 @@ void qInitImageConversions() #endif } +void qGamma_correct_back_to_linear_cs(QImage *image) +{ + extern uchar qt_pow_rgb_gamma[256]; + + // gamma correct the pixels back to linear color space... + int h = image->height(); + int w = image->width(); + + for (int y=0; yscanLine(y); + for (int x=0; x #include +#include +#include #include #include #include diff --git a/src/gui/text/qfont_mac.cpp b/src/gui/text/qfont_mac.cpp index 0bc8ca2..7380f03 100644 --- a/src/gui/text/qfont_mac.cpp +++ b/src/gui/text/qfont_mac.cpp @@ -42,6 +42,7 @@ #include "qfont.h" #include "qfont_p.h" #include "qfontengine_p.h" +#include "qfontengine_mac_p.h" #include "qfontinfo.h" #include "qfontmetrics.h" #include "qpaintdevice.h" diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp index 712bdb4..93f9c84 100644 --- a/src/gui/text/qfontdatabase_mac.cpp +++ b/src/gui/text/qfontdatabase_mac.cpp @@ -45,6 +45,8 @@ #include #include #include +#include +#include QT_BEGIN_NAMESPACE diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm new file mode 100644 index 0000000..984531b --- /dev/null +++ b/src/gui/text/qfontengine_coretext.mm @@ -0,0 +1,667 @@ +#include "qfontengine_coretext_p.h" + +#include +#include + +#include + +#if !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) + +QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning) + : QFontEngineMulti(0) +{ + this->fontDef = fontDef; + CTFontSymbolicTraits symbolicTraits = 0; + if (fontDef.weight >= QFont::Bold) + symbolicTraits |= kCTFontBoldTrait; + switch (fontDef.style) { + case QFont::StyleNormal: + break; + case QFont::StyleItalic: + case QFont::StyleOblique: + symbolicTraits |= kCTFontItalicTrait; + break; + } + + transform = CGAffineTransformIdentity; + if (fontDef.stretch != 100) { + transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1); + } + + QCFType descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize); + QCFType baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, &transform); + ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, &transform, symbolicTraits, symbolicTraits); + + // CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does + // not exist for the given font. (for example italic) + if (ctfont == 0) { + ctfont = baseFont; + CFRetain(ctfont); + } + + attributeDict = CFDictionaryCreateMutable(0, 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(attributeDict, NSFontAttributeName, ctfont); + if (!kerning) { + float zero = 0.0; + QCFType noKern = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &zero); + CFDictionaryAddValue(attributeDict, kCTKernAttributeName, noKern); + } + + QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef, this); + fe->ref.ref(); + engines.append(fe); + +} + +QCoreTextFontEngineMulti::~QCoreTextFontEngineMulti() +{ + CFRelease(ctfont); +} + +uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef id) const +{ + for (int i = 0; i < engines.count(); ++i) { + if (CFEqual(engineAt(i)->ctfont, id)) + return i; + } + + QCoreTextFontEngineMulti *that = const_cast(this); + QCoreTextFontEngine *fe = new QCoreTextFontEngine(id, fontDef, that); + fe->ref.ref(); + that->engines.append(fe); + return engines.count() - 1; +} + +bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags, + unsigned short *logClusters, const HB_CharAttributes *) const +{ + QCFType cfstring = CFStringCreateWithCharactersNoCopy(0, + reinterpret_cast(str), + len, kCFAllocatorNull); + QCFType attributedString = CFAttributedStringCreate(0, cfstring, attributeDict); + QCFType typeSetter = CTTypesetterCreateWithAttributedString(attributedString); + CFRange range = {0, 0}; + QCFType line = CTTypesetterCreateLine(typeSetter, range); + CFArrayRef array = CTLineGetGlyphRuns(line); + uint arraySize = CFArrayGetCount(array); + glyph_t *outGlyphs = glyphs->glyphs; + HB_GlyphAttributes *outAttributes = glyphs->attributes; + QFixed *outAdvances_x = glyphs->advances_x; + QFixed *outAdvances_y = glyphs->advances_y; + glyph_t *initialGlyph = outGlyphs; + + if (arraySize == 0) { + // CoreText failed to shape the text we gave it, so we assume one glyph + // per character and build a list of invalid glyphs with zero advance + *nglyphs = len; + for (int i = 0; i < len; ++i) { + outGlyphs[i] = 0; + if (logClusters) + logClusters[i] = i; + outAdvances_x[i] = QFixed(); + outAdvances_y[i] = QFixed(); + outAttributes[i].clusterStart = true; + } + return true; + } + + const bool rtl = (CTRunGetStatus(static_cast(CFArrayGetValueAtIndex(array, 0))) & kCTRunStatusRightToLeft); + + bool outOBounds = false; + for (uint i = 0; i < arraySize; ++i) { + CTRunRef run = static_cast(CFArrayGetValueAtIndex(array, rtl ? (arraySize - 1 - i) : i)); + CFIndex glyphCount = CTRunGetGlyphCount(run); + if (glyphCount == 0) + continue; + + Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl); + + if (!outOBounds && outGlyphs + glyphCount - initialGlyph > *nglyphs) { + outOBounds = true; + } + if (!outOBounds) { + CFDictionaryRef runAttribs = CTRunGetAttributes(run); + //NSLog(@"Dictionary %@", runAttribs); + if (!runAttribs) + runAttribs = attributeDict; + CTFontRef runFont = static_cast(CFDictionaryGetValue(runAttribs, NSFontAttributeName)); + const uint fontIndex = (fontIndexForFont(runFont) << 24); + //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont)); + QVarLengthArray cgglyphs(0); + const CGGlyph *tmpGlyphs = CTRunGetGlyphsPtr(run); + if (!tmpGlyphs) { + cgglyphs.resize(glyphCount); + CTRunGetGlyphs(run, range, cgglyphs.data()); + tmpGlyphs = cgglyphs.constData(); + } + QVarLengthArray cgpoints(0); + const CGPoint *tmpPoints = CTRunGetPositionsPtr(run); + if (!tmpPoints) { + cgpoints.resize(glyphCount); + CTRunGetPositions(run, range, cgpoints.data()); + tmpPoints = cgpoints.constData(); + } + + const int rtlOffset = rtl ? (glyphCount - 1) : 0; + const int rtlSign = rtl ? -1 : 1; + + if (logClusters) { + CFRange stringRange = CTRunGetStringRange(run); + QVarLengthArray stringIndices(0); + const CFIndex *tmpIndices = CTRunGetStringIndicesPtr(run); + if (!tmpIndices) { + stringIndices.resize(glyphCount); + CTRunGetStringIndices(run, range, stringIndices.data()); + tmpIndices = stringIndices.constData(); + } + + const int firstGlyphIndex = outGlyphs - initialGlyph; + outAttributes[0].clusterStart = true; + + CFIndex k = 0; + CFIndex i = 0; + for (i = stringRange.location; + (i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) { + if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) { + logClusters[i] = k + firstGlyphIndex; + outAttributes[k].clusterStart = true; + ++k; + } else { + logClusters[i] = k + firstGlyphIndex - 1; + } + } + // in case of a ligature at the end, fill the remaining logcluster entries + for (;i < stringRange.location + stringRange.length; i++) { + logClusters[i] = k + firstGlyphIndex - 1; + } + } + for (CFIndex i = 0; i < glyphCount - 1; ++i) { + int idx = rtlOffset + rtlSign * i; + outGlyphs[idx] = tmpGlyphs[i] | fontIndex; + outAdvances_x[idx] = QFixed::fromReal(tmpPoints[i + 1].x - tmpPoints[i].x); + outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i + 1].y - tmpPoints[i].y); + + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + outAdvances_x[idx] = outAdvances_x[idx].round(); + outAdvances_y[idx] = outAdvances_y[idx].round(); + } + } + CGSize lastGlyphAdvance; + CTFontGetAdvancesForGlyphs(runFont, kCTFontHorizontalOrientation, tmpGlyphs + glyphCount - 1, &lastGlyphAdvance, 1); + + outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex; + outAdvances_x[rtl ? 0 : (glyphCount - 1)] = + (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(lastGlyphAdvance.width).round() + : QFixed::fromReal(lastGlyphAdvance.width); + } + outGlyphs += glyphCount; + outAttributes += glyphCount; + outAdvances_x += glyphCount; + outAdvances_y += glyphCount; + } + *nglyphs = (outGlyphs - initialGlyph); + return !outOBounds; +} + +bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, + int *nglyphs, QTextEngine::ShaperFlags flags) const +{ + *nglyphs = len; + QCFType cfstring; + + QVarLengthArray cgGlyphs(len); + CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len); + + for (int i = 0; i < len; ++i) { + if (cgGlyphs[i]) { + glyphs->glyphs[i] = cgGlyphs[i]; + } else { + if (!cfstring) + cfstring = CFStringCreateWithCharactersNoCopy(0, reinterpret_cast(str), len, kCFAllocatorNull); + QCFType substituteFont = CTFontCreateForString(ctfont, cfstring, CFRangeMake(i, 1)); + CGGlyph substituteGlyph = 0; + CTFontGetGlyphsForCharacters(substituteFont, (const UniChar*)str + i, &substituteGlyph, 1); + if (substituteGlyph) { + const uint fontIndex = (fontIndexForFont(substituteFont) << 24); + glyphs->glyphs[i] = substituteGlyph | fontIndex; + if (!(flags & QTextEngine::GlyphIndicesOnly)) { + CGSize advance; + CTFontGetAdvancesForGlyphs(substituteFont, kCTFontHorizontalOrientation, &substituteGlyph, &advance, 1); + glyphs->advances_x[i] = QFixed::fromReal(advance.width); + glyphs->advances_y[i] = QFixed::fromReal(advance.height); + } + } + } + } + + if (flags & QTextEngine::GlyphIndicesOnly) + return true; + + QVarLengthArray advances(len); + CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, cgGlyphs.data(), advances.data(), len); + + for (int i = 0; i < len; ++i) { + if (glyphs->glyphs[i] & 0xff000000) + continue; + glyphs->advances_x[i] = QFixed::fromReal(advances[i].width); + glyphs->advances_y[i] = QFixed::fromReal(advances[i].height); + } + + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + for (int i = 0; i < len; ++i) { + glyphs->advances_x[i] = glyphs->advances_x[i].round(); + glyphs->advances_y[i] = glyphs->advances_y[i].round(); + } + } + + return true; +} + +void QCoreTextFontEngineMulti::recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const +{ +} +void QCoreTextFontEngineMulti::doKerning(int , QGlyphLayout *, QTextEngine::ShaperFlags) const +{ +} + +void QCoreTextFontEngineMulti::loadEngine(int) +{ + // Do nothing + Q_ASSERT(false); +} + + + +QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def, + QCoreTextFontEngineMulti *multiEngine) +{ + fontDef = def; + parentEngine = multiEngine; + synthesisFlags = 0; + ctfont = font; + CFRetain(ctfont); + cgFont = CTFontCopyGraphicsFont(ctfont, NULL); + CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont); + if (fontDef.weight >= QFont::Bold && !(traits & kCTFontBoldTrait)) { + synthesisFlags |= SynthesizedBold; + } + + if (fontDef.style != QFont::StyleNormal && !(traits & kCTFontItalicTrait)) { + synthesisFlags |= SynthesizedItalic; + } + transform = CGAffineTransformIdentity; + if (fontDef.stretch != 100) { + transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1); + } + QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2')); + if (os2Table.size() >= 10) + fsType = qFromBigEndian(reinterpret_cast(os2Table.constData() + 8)); + + QSettings appleSettings(QLatin1String("apple.com")); + QVariant appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold")); + if (appleValue.isValid()) + antialiasing_threshold = appleValue.toInt(); + else + antialiasing_threshold = -1; +} + +QCoreTextFontEngine::~QCoreTextFontEngine() +{ + CFRelease(cgFont); + CFRelease(ctfont); +} + +bool QCoreTextFontEngine::stringToCMap(const QChar *, int, QGlyphLayout *, int *, QTextEngine::ShaperFlags) const +{ + return false; +} + +glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs) +{ + QFixed w; + bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics; + + for (int i = 0; i < glyphs.numGlyphs; ++i) { + w += round ? glyphs.effectiveAdvance(i).round() + : glyphs.effectiveAdvance(i); + } + return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0); +} +glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph) +{ + glyph_metrics_t ret; + CGGlyph g = glyph; + CGRect rect = CTFontGetBoundingRectsForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, 0, 1); + ret.width = QFixed::fromReal(rect.size.width); + ret.height = QFixed::fromReal(rect.size.height); + ret.x = QFixed::fromReal(rect.origin.x); + ret.y = -QFixed::fromReal(rect.origin.y) - ret.height; + CGSize advances[1]; + CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, advances, 1); + ret.xoff = QFixed::fromReal(advances[0].width); + ret.yoff = QFixed::fromReal(advances[0].height); + + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + ret.xoff = ret.xoff.round(); + ret.yoff = ret.yoff.round(); + } + + return ret; +} + +QFixed QCoreTextFontEngine::ascent() const +{ + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(CTFontGetAscent(ctfont)).round() + : QFixed::fromReal(CTFontGetAscent(ctfont)); +} +QFixed QCoreTextFontEngine::descent() const +{ + QFixed d = QFixed::fromReal(CTFontGetDescent(ctfont)); + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + d = d.round(); + + // subtract a pixel to even out the historical +1 in QFontMetrics::height(). + // Fix in Qt 5. + return d - 1; +} +QFixed QCoreTextFontEngine::leading() const +{ + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(CTFontGetLeading(ctfont)).round() + : QFixed::fromReal(CTFontGetLeading(ctfont)); +} +QFixed QCoreTextFontEngine::xHeight() const +{ + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(CTFontGetXHeight(ctfont)).round() + : QFixed::fromReal(CTFontGetXHeight(ctfont)); +} +QFixed QCoreTextFontEngine::averageCharWidth() const +{ + // ### Need to implement properly and get the information from the OS/2 Table. + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFontEngine::averageCharWidth().round() + : QFontEngine::averageCharWidth(); +} + +qreal QCoreTextFontEngine::maxCharWidth() const +{ + // ### Max Help! + return 0; + +} +qreal QCoreTextFontEngine::minLeftBearing() const +{ + // ### Min Help! + return 0; + +} +qreal QCoreTextFontEngine::minRightBearing() const +{ + // ### Max Help! (even thought it's right) + return 0; + +} + +void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight) +{ + QVarLengthArray positions; + QVarLengthArray glyphs; + QTransform matrix; + matrix.translate(x, y); + getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); + if (glyphs.size() == 0) + return; + + CGContextSetFontSize(ctx, fontDef.pixelSize); + + CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); + + CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight); + + CGAffineTransformConcat(cgMatrix, oldTextMatrix); + + if (synthesisFlags & QFontEngine::SynthesizedItalic) + cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); + + cgMatrix = CGAffineTransformConcat(cgMatrix, transform); + + CGContextSetTextMatrix(ctx, cgMatrix); + + CGContextSetTextDrawingMode(ctx, kCGTextFill); + + + QVarLengthArray advances(glyphs.size()); + QVarLengthArray cgGlyphs(glyphs.size()); + + for (int i = 0; i < glyphs.size() - 1; ++i) { + advances[i].width = (positions[i + 1].x - positions[i].x).toReal(); + advances[i].height = (positions[i + 1].y - positions[i].y).toReal(); + cgGlyphs[i] = glyphs[i]; + } + advances[glyphs.size() - 1].width = 0; + advances[glyphs.size() - 1].height = 0; + cgGlyphs[glyphs.size() - 1] = glyphs[glyphs.size() - 1]; + + CGContextSetFont(ctx, cgFont); + //NSLog(@"Font inDraw %@ ctfont %@", CGFontCopyFullName(cgFont), CTFontCopyFamilyName(ctfont)); + + CGContextSetTextPosition(ctx, positions[0].x.toReal(), positions[0].y.toReal()); + + CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); + + if (synthesisFlags & QFontEngine::SynthesizedBold) { + CGContextSetTextPosition(ctx, positions[0].x.toReal() + 0.5 * lineThickness().toReal(), + positions[0].y.toReal()); + + CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); + } + + CGContextSetTextMatrix(ctx, oldTextMatrix); +} + +struct ConvertPathInfo +{ + ConvertPathInfo(QPainterPath *newPath, const QPointF &newPos) : path(newPath), pos(newPos) {} + QPainterPath *path; + QPointF pos; +}; + +static void convertCGPathToQPainterPath(void *info, const CGPathElement *element) +{ + ConvertPathInfo *myInfo = static_cast(info); + switch(element->type) { + case kCGPathElementMoveToPoint: + myInfo->path->moveTo(element->points[0].x + myInfo->pos.x(), + element->points[0].y + myInfo->pos.y()); + break; + case kCGPathElementAddLineToPoint: + myInfo->path->lineTo(element->points[0].x + myInfo->pos.x(), + element->points[0].y + myInfo->pos.y()); + break; + case kCGPathElementAddQuadCurveToPoint: + myInfo->path->quadTo(element->points[0].x + myInfo->pos.x(), + element->points[0].y + myInfo->pos.y(), + element->points[1].x + myInfo->pos.x(), + element->points[1].y + myInfo->pos.y()); + break; + case kCGPathElementAddCurveToPoint: + myInfo->path->cubicTo(element->points[0].x + myInfo->pos.x(), + element->points[0].y + myInfo->pos.y(), + element->points[1].x + myInfo->pos.x(), + element->points[1].y + myInfo->pos.y(), + element->points[2].x + myInfo->pos.x(), + element->points[2].y + myInfo->pos.y()); + break; + case kCGPathElementCloseSubpath: + myInfo->path->closeSubpath(); + break; + default: + qDebug() << "Unhandled path transform type: " << element->type; + } + +} + +void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nGlyphs, + QPainterPath *path, QTextItem::RenderFlags) +{ + + CGAffineTransform cgMatrix = CGAffineTransformIdentity; + cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1); + + if (synthesisFlags & QFontEngine::SynthesizedItalic) + cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); + + + for (int i = 0; i < nGlyphs; ++i) { + QCFType cgpath = CTFontCreatePathForGlyph(ctfont, glyphs[i], &cgMatrix); + ConvertPathInfo info(path, positions[i].toPointF()); + CGPathApply(cgpath, &info, convertCGPathToQPainterPath); + } +} + +QFont QCoreTextFontEngine::createExplicitFont() const +{ + QString familyName = QCFString::toQString(CTFontCopyFamilyName(ctfont)); + return createExplicitFontWithName(familyName); +} + +QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int /*margin*/, bool aa) +{ + const glyph_metrics_t br = boundingBox(glyph); + QImage im(qRound(br.width)+2, qRound(br.height)+2, QImage::Format_RGB32); + im.fill(0); + + CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + uint cgflags = kCGImageAlphaNoneSkipFirst; +#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version + cgflags |= kCGBitmapByteOrder32Host; +#endif + CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(), + 8, im.bytesPerLine(), colorspace, + cgflags); + CGContextSetFontSize(ctx, fontDef.pixelSize); + CGContextSetShouldAntialias(ctx, aa || + (fontDef.pointSize > antialiasing_threshold + && !(fontDef.styleStrategy & QFont::NoAntialias))); + CGContextSetShouldSmoothFonts(ctx, aa); + CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); + CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0); + + CGAffineTransformConcat(cgMatrix, oldTextMatrix); + + if (synthesisFlags & QFontEngine::SynthesizedItalic) + cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0)); + + cgMatrix = CGAffineTransformConcat(cgMatrix, transform); + + CGContextSetTextMatrix(ctx, cgMatrix); + CGContextSetRGBFillColor(ctx, 1, 1, 1, 1); + CGContextSetTextDrawingMode(ctx, kCGTextFill); + + CGContextSetFont(ctx, cgFont); + + qreal pos_x = -br.x.toReal() + subPixelPosition.toReal(); + qreal pos_y = im.height()+br.y.toReal(); + CGContextSetTextPosition(ctx, pos_x, pos_y); + + CGSize advance; + advance.width = 0; + advance.height = 0; + CGGlyph cgGlyph = glyph; + CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1); + + if (synthesisFlags & QFontEngine::SynthesizedBold) { + CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y); + CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1); + } + + CGContextRelease(ctx); + + return im; +} + +QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph) +{ + QImage im = imageForGlyph(glyph, QFixed(), 0, false); + + QImage indexed(im.width(), im.height(), QImage::Format_Indexed8); + QVector colors(256); + for (int i=0; i<256; ++i) + colors[i] = qRgba(0, 0, 0, i); + indexed.setColorTable(colors); + + for (int y=0; y= QTransform::TxScale) + return QFontEngine::alphaRGBMapForGlyph(glyph, subPixelPosition, margin, x); + + QImage im = imageForGlyph(glyph, subPixelPosition, margin, true); + qGamma_correct_back_to_linear_cs(&im); + return im; +} + +void QCoreTextFontEngine::recalcAdvances(int numGlyphs, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const +{ + Q_ASSERT(false); + Q_UNUSED(numGlyphs); + Q_UNUSED(glyphs); + Q_UNUSED(flags); +} + +QFontEngine::FaceId QCoreTextFontEngine::faceId() const +{ + return QFontEngine::FaceId(); +} + +bool QCoreTextFontEngine::canRender(const QChar *string, int len) +{ + QCFType retFont = CTFontCreateForString(ctfont, + QCFType(CFStringCreateWithCharactersNoCopy(0, + reinterpret_cast(string), + len, kCFAllocatorNull)), + CFRangeMake(0, len)); + return retFont != 0; + return false; +} + + bool QCoreTextFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const + { + QCFType table = CTFontCopyTable(ctfont, tag, 0); + if (!table || !length) + return false; + CFIndex tableLength = CFDataGetLength(table); + int availableLength = *length; + *length = tableLength; + if (buffer) { + if (tableLength > availableLength) + return false; + CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer); + } + return true; + } + +void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metrics_t *) +{ + // ### +} + +#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) + diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h new file mode 100644 index 0000000..d86c153 --- /dev/null +++ b/src/gui/text/qfontengine_coretext_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef QFONTENGINE_CORETEXT_P_H +#define QFONTENGINE_CORETEXT_P_H + +#include + +#if !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) + +class QCoreTextFontEngineMulti; +class QCoreTextFontEngine : public QFontEngine +{ +public: + QCoreTextFontEngine(CTFontRef font, const QFontDef &def, + QCoreTextFontEngineMulti *multiEngine = 0); + ~QCoreTextFontEngine(); + virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; + virtual void recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; + + virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); + virtual glyph_metrics_t boundingBox(glyph_t glyph); + + virtual QFixed ascent() const; + virtual QFixed descent() const; + virtual QFixed leading() const; + virtual QFixed xHeight() const; + virtual qreal maxCharWidth() const; + virtual QFixed averageCharWidth() const; + + virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, + QPainterPath *path, QTextItem::RenderFlags); + + virtual const char *name() const { return "QCoreTextFontEngine"; } + + virtual bool canRender(const QChar *string, int len); + + virtual int synthesized() const { return synthesisFlags; } + virtual bool supportsSubPixelPositions() const { return true; } + + virtual Type type() const { return QFontEngine::Mac; } + + void draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight); + + virtual FaceId faceId() const; + virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const; + virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); + virtual QImage alphaMapForGlyph(glyph_t); + virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); + virtual qreal minRightBearing() const; + virtual qreal minLeftBearing() const; + virtual QFont createExplicitFont() const; + +private: + QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, bool colorful); + CTFontRef ctfont; + CGFontRef cgFont; + QCoreTextFontEngineMulti *parentEngine; + int synthesisFlags; + CGAffineTransform transform; + friend class QCoreTextFontEngineMulti; + int antialiasing_threshold; +}; + +class QCoreTextFontEngineMulti : public QFontEngineMulti +{ +public: + QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning); + ~QCoreTextFontEngineMulti(); + + virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, + QTextEngine::ShaperFlags flags) const; + bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, + QTextEngine::ShaperFlags flags, + unsigned short *logClusters, const HB_CharAttributes *charAttributes) const; + + + virtual void recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; + virtual void doKerning(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; + + virtual const char *name() const { return "CoreText"; } +protected: + virtual void loadEngine(int at); + +private: + inline const QCoreTextFontEngine *engineAt(int i) const + { return static_cast(engines.at(i)); } + + uint fontIndexForFont(CTFontRef id) const; + CTFontRef ctfont; + mutable QCFType attributeDict; + CGAffineTransform transform; + friend class QFontDialogPrivate; +}; + +#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) + +#endif // QFONTENGINE_CORETEXT_P_H diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index ebc1f6d..8801181 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#include "qfontengine_mac_p.h" + #include #include #include @@ -53,6 +55,7 @@ #include #include #include +#include #include #include @@ -118,681 +121,6 @@ OSStatus QMacFontPath::closePath(void *data) return noErr; } - - -void qmacfontengine_gamma_correct(QImage *image) -{ - extern uchar qt_pow_rgb_gamma[256]; - - // gamma correct the pixels back to linear color space... - int h = image->height(); - int w = image->width(); - - for (int y=0; yscanLine(y); - for (int x=0; x= MAC_OS_X_VERSION_10_5 -QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning) - : QFontEngineMulti(0) -{ - this->fontDef = fontDef; - CTFontSymbolicTraits symbolicTraits = 0; - if (fontDef.weight >= QFont::Bold) - symbolicTraits |= kCTFontBoldTrait; - switch (fontDef.style) { - case QFont::StyleNormal: - break; - case QFont::StyleItalic: - case QFont::StyleOblique: - symbolicTraits |= kCTFontItalicTrait; - break; - } - - transform = CGAffineTransformIdentity; - if (fontDef.stretch != 100) { - transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1); - } - - QCFType descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize); - QCFType baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, &transform); - ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, &transform, symbolicTraits, symbolicTraits); - - // CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does - // not exist for the given font. (for example italic) - if (ctfont == 0) { - ctfont = baseFont; - CFRetain(ctfont); - } - - attributeDict = CFDictionaryCreateMutable(0, 2, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFDictionaryAddValue(attributeDict, NSFontAttributeName, ctfont); - if (!kerning) { - float zero = 0.0; - QCFType noKern = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &zero); - CFDictionaryAddValue(attributeDict, kCTKernAttributeName, noKern); - } - - QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef, this); - fe->ref.ref(); - engines.append(fe); - -} - -QCoreTextFontEngineMulti::~QCoreTextFontEngineMulti() -{ - CFRelease(ctfont); -} - -uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef id) const -{ - for (int i = 0; i < engines.count(); ++i) { - if (CFEqual(engineAt(i)->ctfont, id)) - return i; - } - - QCoreTextFontEngineMulti *that = const_cast(this); - QCoreTextFontEngine *fe = new QCoreTextFontEngine(id, fontDef, that); - fe->ref.ref(); - that->engines.append(fe); - return engines.count() - 1; -} - -bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags, - unsigned short *logClusters, const HB_CharAttributes *) const -{ - QCFType cfstring = CFStringCreateWithCharactersNoCopy(0, - reinterpret_cast(str), - len, kCFAllocatorNull); - QCFType attributedString = CFAttributedStringCreate(0, cfstring, attributeDict); - QCFType typeSetter = CTTypesetterCreateWithAttributedString(attributedString); - CFRange range = {0, 0}; - QCFType line = CTTypesetterCreateLine(typeSetter, range); - CFArrayRef array = CTLineGetGlyphRuns(line); - uint arraySize = CFArrayGetCount(array); - glyph_t *outGlyphs = glyphs->glyphs; - HB_GlyphAttributes *outAttributes = glyphs->attributes; - QFixed *outAdvances_x = glyphs->advances_x; - QFixed *outAdvances_y = glyphs->advances_y; - glyph_t *initialGlyph = outGlyphs; - - if (arraySize == 0) { - // CoreText failed to shape the text we gave it, so we assume one glyph - // per character and build a list of invalid glyphs with zero advance - *nglyphs = len; - for (int i = 0; i < len; ++i) { - outGlyphs[i] = 0; - if (logClusters) - logClusters[i] = i; - outAdvances_x[i] = QFixed(); - outAdvances_y[i] = QFixed(); - outAttributes[i].clusterStart = true; - } - return true; - } - - const bool rtl = (CTRunGetStatus(static_cast(CFArrayGetValueAtIndex(array, 0))) & kCTRunStatusRightToLeft); - - bool outOBounds = false; - for (uint i = 0; i < arraySize; ++i) { - CTRunRef run = static_cast(CFArrayGetValueAtIndex(array, rtl ? (arraySize - 1 - i) : i)); - CFIndex glyphCount = CTRunGetGlyphCount(run); - if (glyphCount == 0) - continue; - - Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl); - - if (!outOBounds && outGlyphs + glyphCount - initialGlyph > *nglyphs) { - outOBounds = true; - } - if (!outOBounds) { - CFDictionaryRef runAttribs = CTRunGetAttributes(run); - //NSLog(@"Dictionary %@", runAttribs); - if (!runAttribs) - runAttribs = attributeDict; - CTFontRef runFont = static_cast(CFDictionaryGetValue(runAttribs, NSFontAttributeName)); - const uint fontIndex = (fontIndexForFont(runFont) << 24); - //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont)); - QVarLengthArray cgglyphs(0); - const CGGlyph *tmpGlyphs = CTRunGetGlyphsPtr(run); - if (!tmpGlyphs) { - cgglyphs.resize(glyphCount); - CTRunGetGlyphs(run, range, cgglyphs.data()); - tmpGlyphs = cgglyphs.constData(); - } - QVarLengthArray cgpoints(0); - const CGPoint *tmpPoints = CTRunGetPositionsPtr(run); - if (!tmpPoints) { - cgpoints.resize(glyphCount); - CTRunGetPositions(run, range, cgpoints.data()); - tmpPoints = cgpoints.constData(); - } - - const int rtlOffset = rtl ? (glyphCount - 1) : 0; - const int rtlSign = rtl ? -1 : 1; - - if (logClusters) { - CFRange stringRange = CTRunGetStringRange(run); - QVarLengthArray stringIndices(0); - const CFIndex *tmpIndices = CTRunGetStringIndicesPtr(run); - if (!tmpIndices) { - stringIndices.resize(glyphCount); - CTRunGetStringIndices(run, range, stringIndices.data()); - tmpIndices = stringIndices.constData(); - } - - const int firstGlyphIndex = outGlyphs - initialGlyph; - outAttributes[0].clusterStart = true; - - CFIndex k = 0; - CFIndex i = 0; - for (i = stringRange.location; - (i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) { - if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) { - logClusters[i] = k + firstGlyphIndex; - outAttributes[k].clusterStart = true; - ++k; - } else { - logClusters[i] = k + firstGlyphIndex - 1; - } - } - // in case of a ligature at the end, fill the remaining logcluster entries - for (;i < stringRange.location + stringRange.length; i++) { - logClusters[i] = k + firstGlyphIndex - 1; - } - } - for (CFIndex i = 0; i < glyphCount - 1; ++i) { - int idx = rtlOffset + rtlSign * i; - outGlyphs[idx] = tmpGlyphs[i] | fontIndex; - outAdvances_x[idx] = QFixed::fromReal(tmpPoints[i + 1].x - tmpPoints[i].x); - outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i + 1].y - tmpPoints[i].y); - - if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { - outAdvances_x[idx] = outAdvances_x[idx].round(); - outAdvances_y[idx] = outAdvances_y[idx].round(); - } - } - CGSize lastGlyphAdvance; - CTFontGetAdvancesForGlyphs(runFont, kCTFontHorizontalOrientation, tmpGlyphs + glyphCount - 1, &lastGlyphAdvance, 1); - - outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex; - outAdvances_x[rtl ? 0 : (glyphCount - 1)] = - (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFixed::fromReal(lastGlyphAdvance.width).round() - : QFixed::fromReal(lastGlyphAdvance.width); - } - outGlyphs += glyphCount; - outAttributes += glyphCount; - outAdvances_x += glyphCount; - outAdvances_y += glyphCount; - } - *nglyphs = (outGlyphs - initialGlyph); - return !outOBounds; -} - -bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, - int *nglyphs, QTextEngine::ShaperFlags flags) const -{ - *nglyphs = len; - QCFType cfstring; - - QVarLengthArray cgGlyphs(len); - CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len); - - for (int i = 0; i < len; ++i) { - if (cgGlyphs[i]) { - glyphs->glyphs[i] = cgGlyphs[i]; - } else { - if (!cfstring) - cfstring = CFStringCreateWithCharactersNoCopy(0, reinterpret_cast(str), len, kCFAllocatorNull); - QCFType substituteFont = CTFontCreateForString(ctfont, cfstring, CFRangeMake(i, 1)); - CGGlyph substituteGlyph = 0; - CTFontGetGlyphsForCharacters(substituteFont, (const UniChar*)str + i, &substituteGlyph, 1); - if (substituteGlyph) { - const uint fontIndex = (fontIndexForFont(substituteFont) << 24); - glyphs->glyphs[i] = substituteGlyph | fontIndex; - if (!(flags & QTextEngine::GlyphIndicesOnly)) { - CGSize advance; - CTFontGetAdvancesForGlyphs(substituteFont, kCTFontHorizontalOrientation, &substituteGlyph, &advance, 1); - glyphs->advances_x[i] = QFixed::fromReal(advance.width); - glyphs->advances_y[i] = QFixed::fromReal(advance.height); - } - } - } - } - - if (flags & QTextEngine::GlyphIndicesOnly) - return true; - - QVarLengthArray advances(len); - CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, cgGlyphs.data(), advances.data(), len); - - for (int i = 0; i < len; ++i) { - if (glyphs->glyphs[i] & 0xff000000) - continue; - glyphs->advances_x[i] = QFixed::fromReal(advances[i].width); - glyphs->advances_y[i] = QFixed::fromReal(advances[i].height); - } - - if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { - for (int i = 0; i < len; ++i) { - glyphs->advances_x[i] = glyphs->advances_x[i].round(); - glyphs->advances_y[i] = glyphs->advances_y[i].round(); - } - } - - return true; -} - -void QCoreTextFontEngineMulti::recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const -{ -} -void QCoreTextFontEngineMulti::doKerning(int , QGlyphLayout *, QTextEngine::ShaperFlags) const -{ -} - -void QCoreTextFontEngineMulti::loadEngine(int) -{ - // Do nothing - Q_ASSERT(false); -} - - - -QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def, - QCoreTextFontEngineMulti *multiEngine) -{ - fontDef = def; - parentEngine = multiEngine; - synthesisFlags = 0; - ctfont = font; - CFRetain(ctfont); - cgFont = CTFontCopyGraphicsFont(ctfont, NULL); - CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont); - if (fontDef.weight >= QFont::Bold && !(traits & kCTFontBoldTrait)) { - synthesisFlags |= SynthesizedBold; - } - - if (fontDef.style != QFont::StyleNormal && !(traits & kCTFontItalicTrait)) { - synthesisFlags |= SynthesizedItalic; - } - transform = CGAffineTransformIdentity; - if (fontDef.stretch != 100) { - transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1); - } - QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2')); - if (os2Table.size() >= 10) - fsType = qFromBigEndian(reinterpret_cast(os2Table.constData() + 8)); -} - -QCoreTextFontEngine::~QCoreTextFontEngine() -{ - CFRelease(cgFont); - CFRelease(ctfont); -} - -bool QCoreTextFontEngine::stringToCMap(const QChar *, int, QGlyphLayout *, int *, QTextEngine::ShaperFlags) const -{ - return false; -} - -glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs) -{ - QFixed w; - bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics; - - for (int i = 0; i < glyphs.numGlyphs; ++i) { - w += round ? glyphs.effectiveAdvance(i).round() - : glyphs.effectiveAdvance(i); - } - return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0); -} -glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph) -{ - glyph_metrics_t ret; - CGGlyph g = glyph; - CGRect rect = CTFontGetBoundingRectsForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, 0, 1); - ret.width = QFixed::fromReal(rect.size.width); - ret.height = QFixed::fromReal(rect.size.height); - ret.x = QFixed::fromReal(rect.origin.x); - ret.y = -QFixed::fromReal(rect.origin.y) - ret.height; - CGSize advances[1]; - CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, advances, 1); - ret.xoff = QFixed::fromReal(advances[0].width); - ret.yoff = QFixed::fromReal(advances[0].height); - - if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { - ret.xoff = ret.xoff.round(); - ret.yoff = ret.yoff.round(); - } - - return ret; -} - -QFixed QCoreTextFontEngine::ascent() const -{ - return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFixed::fromReal(CTFontGetAscent(ctfont)).round() - : QFixed::fromReal(CTFontGetAscent(ctfont)); -} -QFixed QCoreTextFontEngine::descent() const -{ - QFixed d = QFixed::fromReal(CTFontGetDescent(ctfont)); - if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - d = d.round(); - - // subtract a pixel to even out the historical +1 in QFontMetrics::height(). - // Fix in Qt 5. - return d - 1; -} -QFixed QCoreTextFontEngine::leading() const -{ - return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFixed::fromReal(CTFontGetLeading(ctfont)).round() - : QFixed::fromReal(CTFontGetLeading(ctfont)); -} -QFixed QCoreTextFontEngine::xHeight() const -{ - return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFixed::fromReal(CTFontGetXHeight(ctfont)).round() - : QFixed::fromReal(CTFontGetXHeight(ctfont)); -} -QFixed QCoreTextFontEngine::averageCharWidth() const -{ - // ### Need to implement properly and get the information from the OS/2 Table. - return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFontEngine::averageCharWidth().round() - : QFontEngine::averageCharWidth(); -} - -qreal QCoreTextFontEngine::maxCharWidth() const -{ - // ### Max Help! - return 0; - -} -qreal QCoreTextFontEngine::minLeftBearing() const -{ - // ### Min Help! - return 0; - -} -qreal QCoreTextFontEngine::minRightBearing() const -{ - // ### Max Help! (even thought it's right) - return 0; - -} - -void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight) -{ - QVarLengthArray positions; - QVarLengthArray glyphs; - QTransform matrix; - matrix.translate(x, y); - getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); - if (glyphs.size() == 0) - return; - - CGContextSetFontSize(ctx, fontDef.pixelSize); - - CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); - - CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight); - - CGAffineTransformConcat(cgMatrix, oldTextMatrix); - - if (synthesisFlags & QFontEngine::SynthesizedItalic) - cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); - - cgMatrix = CGAffineTransformConcat(cgMatrix, transform); - - CGContextSetTextMatrix(ctx, cgMatrix); - - CGContextSetTextDrawingMode(ctx, kCGTextFill); - - - QVarLengthArray advances(glyphs.size()); - QVarLengthArray cgGlyphs(glyphs.size()); - - for (int i = 0; i < glyphs.size() - 1; ++i) { - advances[i].width = (positions[i + 1].x - positions[i].x).toReal(); - advances[i].height = (positions[i + 1].y - positions[i].y).toReal(); - cgGlyphs[i] = glyphs[i]; - } - advances[glyphs.size() - 1].width = 0; - advances[glyphs.size() - 1].height = 0; - cgGlyphs[glyphs.size() - 1] = glyphs[glyphs.size() - 1]; - - CGContextSetFont(ctx, cgFont); - //NSLog(@"Font inDraw %@ ctfont %@", CGFontCopyFullName(cgFont), CTFontCopyFamilyName(ctfont)); - - CGContextSetTextPosition(ctx, positions[0].x.toReal(), positions[0].y.toReal()); - - CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); - - if (synthesisFlags & QFontEngine::SynthesizedBold) { - CGContextSetTextPosition(ctx, positions[0].x.toReal() + 0.5 * lineThickness().toReal(), - positions[0].y.toReal()); - - CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); - } - - CGContextSetTextMatrix(ctx, oldTextMatrix); -} - -struct ConvertPathInfo -{ - ConvertPathInfo(QPainterPath *newPath, const QPointF &newPos) : path(newPath), pos(newPos) {} - QPainterPath *path; - QPointF pos; -}; - -static void convertCGPathToQPainterPath(void *info, const CGPathElement *element) -{ - ConvertPathInfo *myInfo = static_cast(info); - switch(element->type) { - case kCGPathElementMoveToPoint: - myInfo->path->moveTo(element->points[0].x + myInfo->pos.x(), - element->points[0].y + myInfo->pos.y()); - break; - case kCGPathElementAddLineToPoint: - myInfo->path->lineTo(element->points[0].x + myInfo->pos.x(), - element->points[0].y + myInfo->pos.y()); - break; - case kCGPathElementAddQuadCurveToPoint: - myInfo->path->quadTo(element->points[0].x + myInfo->pos.x(), - element->points[0].y + myInfo->pos.y(), - element->points[1].x + myInfo->pos.x(), - element->points[1].y + myInfo->pos.y()); - break; - case kCGPathElementAddCurveToPoint: - myInfo->path->cubicTo(element->points[0].x + myInfo->pos.x(), - element->points[0].y + myInfo->pos.y(), - element->points[1].x + myInfo->pos.x(), - element->points[1].y + myInfo->pos.y(), - element->points[2].x + myInfo->pos.x(), - element->points[2].y + myInfo->pos.y()); - break; - case kCGPathElementCloseSubpath: - myInfo->path->closeSubpath(); - break; - default: - qDebug() << "Unhandled path transform type: " << element->type; - } - -} - -void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nGlyphs, - QPainterPath *path, QTextItem::RenderFlags) -{ - - CGAffineTransform cgMatrix = CGAffineTransformIdentity; - cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1); - - if (synthesisFlags & QFontEngine::SynthesizedItalic) - cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); - - - for (int i = 0; i < nGlyphs; ++i) { - QCFType cgpath = CTFontCreatePathForGlyph(ctfont, glyphs[i], &cgMatrix); - ConvertPathInfo info(path, positions[i].toPointF()); - CGPathApply(cgpath, &info, convertCGPathToQPainterPath); - } -} - -QFont QCoreTextFontEngine::createExplicitFont() const -{ - QString familyName = QCFString::toQString(CTFontCopyFamilyName(ctfont)); - return createExplicitFontWithName(familyName); -} - -QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int /*margin*/, bool aa) -{ - const glyph_metrics_t br = boundingBox(glyph); - QImage im(qRound(br.width)+2, qRound(br.height)+2, QImage::Format_RGB32); - im.fill(0); - - CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace(); - uint cgflags = kCGImageAlphaNoneSkipFirst; -#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version - cgflags |= kCGBitmapByteOrder32Host; -#endif - CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(), - 8, im.bytesPerLine(), colorspace, - cgflags); - CGContextSetFontSize(ctx, fontDef.pixelSize); - CGContextSetShouldAntialias(ctx, aa || - (fontDef.pointSize > qt_antialiasing_threshold - && !(fontDef.styleStrategy & QFont::NoAntialias))); - CGContextSetShouldSmoothFonts(ctx, aa); - CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); - CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0); - - CGAffineTransformConcat(cgMatrix, oldTextMatrix); - - if (synthesisFlags & QFontEngine::SynthesizedItalic) - cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0)); - - cgMatrix = CGAffineTransformConcat(cgMatrix, transform); - - CGContextSetTextMatrix(ctx, cgMatrix); - CGContextSetRGBFillColor(ctx, 1, 1, 1, 1); - CGContextSetTextDrawingMode(ctx, kCGTextFill); - - CGContextSetFont(ctx, cgFont); - - qreal pos_x = -br.x.toReal() + subPixelPosition.toReal(); - qreal pos_y = im.height()+br.y.toReal(); - CGContextSetTextPosition(ctx, pos_x, pos_y); - - CGSize advance; - advance.width = 0; - advance.height = 0; - CGGlyph cgGlyph = glyph; - CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1); - - if (synthesisFlags & QFontEngine::SynthesizedBold) { - CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y); - CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1); - } - - CGContextRelease(ctx); - - return im; -} - -QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph) -{ - QImage im = imageForGlyph(glyph, QFixed(), 0, false); - - QImage indexed(im.width(), im.height(), QImage::Format_Indexed8); - QVector colors(256); - for (int i=0; i<256; ++i) - colors[i] = qRgba(0, 0, 0, i); - indexed.setColorTable(colors); - - for (int y=0; y= QTransform::TxScale) - return QFontEngine::alphaRGBMapForGlyph(glyph, subPixelPosition, margin, x); - - QImage im = imageForGlyph(glyph, subPixelPosition, margin, true); - qmacfontengine_gamma_correct(&im); - return im; -} - -void QCoreTextFontEngine::recalcAdvances(int numGlyphs, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const -{ - Q_ASSERT(false); - Q_UNUSED(numGlyphs); - Q_UNUSED(glyphs); - Q_UNUSED(flags); -} - -QFontEngine::FaceId QCoreTextFontEngine::faceId() const -{ - return QFontEngine::FaceId(); -} - -bool QCoreTextFontEngine::canRender(const QChar *string, int len) -{ - QCFType retFont = CTFontCreateForString(ctfont, - QCFType(CFStringCreateWithCharactersNoCopy(0, - reinterpret_cast(string), - len, kCFAllocatorNull)), - CFRangeMake(0, len)); - return retFont != 0; - return false; -} - - bool QCoreTextFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const - { - QCFType table = CTFontCopyTable(ctfont, tag, 0); - if (!table || !length) - return false; - CFIndex tableLength = CFDataGetLength(table); - int availableLength = *length; - *length = tableLength; - if (buffer) { - if (tableLength > availableLength) - return false; - CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer); - } - return true; - } - -void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metrics_t *) -{ - // ### -} - -#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - #ifndef QT_MAC_USE_COCOA QFontEngineMacMulti::QFontEngineMacMulti(const ATSFontFamilyRef &atsFamily, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning) : QFontEngineMulti(0) @@ -1708,7 +1036,7 @@ QImage QFontEngineMac::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, co im = im.transformed(t); } - qmacfontengine_gamma_correct(&im); + qGamma_correct_back_to_linear_cs(&im); return im; } diff --git a/src/gui/text/qfontengine_mac_p.h b/src/gui/text/qfontengine_mac_p.h new file mode 100644 index 0000000..5577c76 --- /dev/null +++ b/src/gui/text/qfontengine_mac_p.h @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef QFONTENGINE_MAC_P_H +#define QFONTENGINE_MAC_P_H + +#include + +#ifndef QT_MAC_USE_COCOA +class QFontEngineMacMulti; +class QFontEngineMac : public QFontEngine +{ + friend class QFontEngineMacMulti; +public: + QFontEngineMac(ATSUStyle baseStyle, ATSUFontID fontID, const QFontDef &def, QFontEngineMacMulti *multiEngine = 0); + virtual ~QFontEngineMac(); + + virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *numGlyphs, QTextEngine::ShaperFlags flags) const; + virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const; + + virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); + virtual glyph_metrics_t boundingBox(glyph_t glyph); + + virtual QFixed ascent() const; + virtual QFixed descent() const; + virtual QFixed leading() const; + virtual QFixed xHeight() const; + virtual qreal maxCharWidth() const; + virtual QFixed averageCharWidth() const; + + virtual QFont createExplicitFont() const; + + virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, + QPainterPath *path, QTextItem::RenderFlags); + + virtual const char *name() const { return "QFontEngineMac"; } + + virtual bool canRender(const QChar *string, int len); + + virtual int synthesized() const { return synthesisFlags; } + + virtual Type type() const { return QFontEngine::Mac; } + + void draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight); + + virtual FaceId faceId() const; + virtual QByteArray getSfntTable(uint tag) const; + virtual Properties properties() const; + virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); + virtual QImage alphaMapForGlyph(glyph_t); + virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); + +private: + QImage imageForGlyph(glyph_t glyph, int margin, bool colorful); + + ATSUFontID fontID; + QCFType cgFont; + ATSUStyle style; + int synthesisFlags; + mutable QGlyphLayout kashidaGlyph; + QFontEngineMacMulti *multiEngine; + mutable const unsigned char *cmap; + mutable bool symbolCMap; + mutable QByteArray cmapTable; + CGAffineTransform transform; + QFixed m_ascent; + QFixed m_descent; + QFixed m_leading; + qreal m_maxCharWidth; + QFixed m_xHeight; + QFixed m_averageCharWidth; +}; + +class QFontEngineMacMulti : public QFontEngineMulti +{ + friend class QFontEngineMac; +public: + // internal + struct ShaperItem + { + inline ShaperItem() : string(0), from(0), length(0), + log_clusters(0), charAttributes(0) {} + + const QChar *string; + int from; + int length; + QGlyphLayout glyphs; + unsigned short *log_clusters; + const HB_CharAttributes *charAttributes; + QTextEngine::ShaperFlags flags; + }; + + QFontEngineMacMulti(const ATSFontFamilyRef &atsFamily, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning); + virtual ~QFontEngineMacMulti(); + + virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; + bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, + unsigned short *logClusters, const HB_CharAttributes *charAttributes) const; + + virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const; + virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const; + + virtual const char *name() const { return "ATSUI"; } + + virtual bool canRender(const QChar *string, int len); + + inline ATSUFontID macFontID() const { return fontID; } + +protected: + virtual void loadEngine(int at); + +private: + inline const QFontEngineMac *engineAt(int i) const + { return static_cast(engines.at(i)); } + + bool stringToCMapInternal(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, ShaperItem *item) const; + + int fontIndexForFontID(ATSUFontID id) const; + + ATSUFontID fontID; + uint kerning : 1; + + mutable ATSUTextLayout textLayout; + mutable ATSUStyle style; + CGAffineTransform transform; +}; +#endif //!QT_MAC_USE_COCOA + +#endif // QFONTENGINE_MAC_P_H diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 6d6daaa..c584ba1 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -431,216 +431,6 @@ protected: QVector engines; }; -#if defined(Q_WS_MAC) - -struct QCharAttributes; -class QFontEngineMacMulti; -# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 -class QCoreTextFontEngineMulti; -class QCoreTextFontEngine : public QFontEngine -{ -public: - QCoreTextFontEngine(CTFontRef font, const QFontDef &def, - QCoreTextFontEngineMulti *multiEngine = 0); - ~QCoreTextFontEngine(); - virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; - virtual void recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; - - virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); - virtual glyph_metrics_t boundingBox(glyph_t glyph); - - virtual QFixed ascent() const; - virtual QFixed descent() const; - virtual QFixed leading() const; - virtual QFixed xHeight() const; - virtual qreal maxCharWidth() const; - virtual QFixed averageCharWidth() const; - - virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, - QPainterPath *path, QTextItem::RenderFlags); - - virtual const char *name() const { return "QCoreTextFontEngine"; } - - virtual bool canRender(const QChar *string, int len); - - virtual int synthesized() const { return synthesisFlags; } - virtual bool supportsSubPixelPositions() const { return true; } - - virtual Type type() const { return QFontEngine::Mac; } - - void draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight); - - virtual FaceId faceId() const; - virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const; - virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); - virtual QImage alphaMapForGlyph(glyph_t); - virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); - virtual qreal minRightBearing() const; - virtual qreal minLeftBearing() const; - virtual QFont createExplicitFont() const; - -private: - QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, bool colorful); - CTFontRef ctfont; - CGFontRef cgFont; - QCoreTextFontEngineMulti *parentEngine; - int synthesisFlags; - CGAffineTransform transform; - friend class QCoreTextFontEngineMulti; -}; - -class QCoreTextFontEngineMulti : public QFontEngineMulti -{ -public: - QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning); - ~QCoreTextFontEngineMulti(); - - virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, - QTextEngine::ShaperFlags flags) const; - bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, - QTextEngine::ShaperFlags flags, - unsigned short *logClusters, const HB_CharAttributes *charAttributes) const; - - - virtual void recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; - virtual void doKerning(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; - - virtual const char *name() const { return "CoreText"; } -protected: - virtual void loadEngine(int at); - -private: - inline const QCoreTextFontEngine *engineAt(int i) const - { return static_cast(engines.at(i)); } - - uint fontIndexForFont(CTFontRef id) const; - CTFontRef ctfont; - mutable QCFType attributeDict; - CGAffineTransform transform; - friend class QFontDialogPrivate; -}; -# endif //MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - -#ifndef QT_MAC_USE_COCOA -class QFontEngineMac : public QFontEngine -{ - friend class QFontEngineMacMulti; -public: - QFontEngineMac(ATSUStyle baseStyle, ATSUFontID fontID, const QFontDef &def, QFontEngineMacMulti *multiEngine = 0); - virtual ~QFontEngineMac(); - - virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *numGlyphs, QTextEngine::ShaperFlags flags) const; - virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const; - - virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); - virtual glyph_metrics_t boundingBox(glyph_t glyph); - - virtual QFixed ascent() const; - virtual QFixed descent() const; - virtual QFixed leading() const; - virtual QFixed xHeight() const; - virtual qreal maxCharWidth() const; - virtual QFixed averageCharWidth() const; - - virtual QFont createExplicitFont() const; - - virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, - QPainterPath *path, QTextItem::RenderFlags); - - virtual const char *name() const { return "QFontEngineMac"; } - - virtual bool canRender(const QChar *string, int len); - - virtual int synthesized() const { return synthesisFlags; } - - virtual Type type() const { return QFontEngine::Mac; } - - void draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight); - - virtual FaceId faceId() const; - virtual QByteArray getSfntTable(uint tag) const; - virtual Properties properties() const; - virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); - virtual QImage alphaMapForGlyph(glyph_t); - virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); - -private: - QImage imageForGlyph(glyph_t glyph, int margin, bool colorful); - - ATSUFontID fontID; - QCFType cgFont; - ATSUStyle style; - int synthesisFlags; - mutable QGlyphLayout kashidaGlyph; - QFontEngineMacMulti *multiEngine; - mutable const unsigned char *cmap; - mutable bool symbolCMap; - mutable QByteArray cmapTable; - CGAffineTransform transform; - QFixed m_ascent; - QFixed m_descent; - QFixed m_leading; - qreal m_maxCharWidth; - QFixed m_xHeight; - QFixed m_averageCharWidth; -}; - -class QFontEngineMacMulti : public QFontEngineMulti -{ - friend class QFontEngineMac; -public: - // internal - struct ShaperItem - { - inline ShaperItem() : string(0), from(0), length(0), - log_clusters(0), charAttributes(0) {} - - const QChar *string; - int from; - int length; - QGlyphLayout glyphs; - unsigned short *log_clusters; - const HB_CharAttributes *charAttributes; - QTextEngine::ShaperFlags flags; - }; - - QFontEngineMacMulti(const ATSFontFamilyRef &atsFamily, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning); - virtual ~QFontEngineMacMulti(); - - virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; - bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, - unsigned short *logClusters, const HB_CharAttributes *charAttributes) const; - - virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const; - virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const; - - virtual const char *name() const { return "ATSUI"; } - - virtual bool canRender(const QChar *string, int len); - - inline ATSUFontID macFontID() const { return fontID; } - -protected: - virtual void loadEngine(int at); - -private: - inline const QFontEngineMac *engineAt(int i) const - { return static_cast(engines.at(i)); } - - bool stringToCMapInternal(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, ShaperItem *item) const; - - int fontIndexForFontID(ATSUFontID id) const; - - ATSUFontID fontID; - uint kerning : 1; - - mutable ATSUTextLayout textLayout; - mutable ATSUStyle style; - CGAffineTransform transform; -}; -#endif //!QT_MAC_USE_COCOA -#endif - class QTestFontEngine : public QFontEngineBox { public: diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp index 342fb5e..7002851 100644 --- a/src/gui/text/qtextengine_mac.cpp +++ b/src/gui/text/qtextengine_mac.cpp @@ -41,6 +41,9 @@ #include "qtextengine_p.h" +#include +#include + QT_BEGIN_NAMESPACE // set the glyph attributes heuristically. Assumes a 1 to 1 relationship between chars and glyphs diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index 0040b54..daafdd9 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -93,9 +93,15 @@ unix:x11 { } !embedded:!qpa:!x11:mac { + HEADERS += \ + text/qfontengine_mac_p.h + OBJECTIVE_HEADERS += \ + text/qfontengine_coretext_p.h SOURCES += \ - text/qfont_mac.cpp - OBJECTIVE_SOURCES += text/qfontengine_mac.mm + text/qfont_mac.cpp + OBJECTIVE_SOURCES += \ + text/qfontengine_coretext.mm \ + text/qfontengine_mac.mm } embedded { diff --git a/src/gui/util/qdesktopservices_mac.cpp b/src/gui/util/qdesktopservices_mac.cpp index 6c5ff18..05a1789 100644 --- a/src/gui/util/qdesktopservices_mac.cpp +++ b/src/gui/util/qdesktopservices_mac.cpp @@ -49,6 +49,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE /* -- cgit v0.12 From 484770255f421d71954df4511e3541d2d4654d4e Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 22 Oct 2010 16:00:24 +0100 Subject: Re-enable emulated QFile::map on symbian Memory mapping of RFile handles is not supported in current symbian OS versions. However the "open C" libraries provide an emulated mmap() implementation which was used by QFile::map in Qt 4.6 release. To avoid breaking applications which rely on this function, QFile::map will now open the file with open C as well in order to use that handle to call mmap(). When symbian implements a file mapping API, we can switch the implementation to use that for RFile handles. Reviewed-By: joao --- src/corelib/io/qfile.cpp | 2 ++ src/corelib/io/qfsfileengine.cpp | 12 +++++++++ src/corelib/io/qfsfileengine_p.h | 2 ++ src/corelib/io/qfsfileengine_unix.cpp | 47 ++++++++++++++++------------------- tests/auto/qfile/tst_qfile.cpp | 12 --------- 5 files changed, 37 insertions(+), 38 deletions(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index a0bc68e..f0ca11b 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -48,6 +48,7 @@ #include "qfileinfo.h" #include "private/qiodevice_p.h" #include "private/qfile_p.h" +#include "private/qsystemerror_p.h" #if defined(QT_BUILD_CORE_LIB) # include "qcoreapplication.h" #endif @@ -1223,6 +1224,7 @@ bool QFile::unmap(uchar *address) d->setError(d->fileEngine->error(), d->fileEngine->errorString()); return success; } + d->setError(PermissionsError, QSystemError(EACCES, QSystemError::StandardLibraryError).toString()); return false; } diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 5491caf..ae301f7 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -120,6 +120,9 @@ void QFSFileEnginePrivate::init() openMode = QIODevice::NotOpen; fd = -1; fh = 0; +#ifdef Q_OS_SYMBIAN + fileHandleForMaps = -1; +#endif lastIOCommand = IOFlushCommand; lastFlushFailed = false; closeFileHandle = false; @@ -355,6 +358,7 @@ bool QFSFileEnginePrivate::closeFdFh() if (fd == -1 && !fh #ifdef Q_OS_SYMBIAN && !symbianFile.SubSessionHandle() + && fileHandleForMaps == -1 #endif ) return false; @@ -364,6 +368,14 @@ bool QFSFileEnginePrivate::closeFdFh() bool closed = true; tried_stat = 0; +#ifdef Q_OS_SYMBIAN + // Map handle is always owned by us so always close it + if (fileHandleForMaps >= 0) { + QT_CLOSE(fileHandleForMaps); + fileHandleForMaps = -1; + } +#endif + // Close the file if we created the handle. if (closeFileHandle) { int ret; diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 715b46f..7c088b8 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -139,6 +139,8 @@ public: */ TInt symbianFilePos; #endif + mutable int fileHandleForMaps; + int getMapHandle(); #endif #ifdef Q_WS_WIN diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 28e0677..035e78f 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -85,6 +85,7 @@ static bool isRelativePathSymbian(const QString& fileName) #endif +#ifndef Q_OS_SYMBIAN /*! \internal @@ -124,6 +125,7 @@ static inline QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QF return mode; } +#endif /*! \internal @@ -153,6 +155,7 @@ static inline int openModeToOpenFlags(QIODevice::OpenMode mode) return oflags; } +#ifndef Q_OS_SYMBIAN /*! \internal @@ -163,6 +166,7 @@ static inline bool setCloseOnExec(int fd) { return fd != -1 && fcntl(fd, F_SETFD, FD_CLOEXEC) != -1; } +#endif #ifdef Q_OS_SYMBIAN /*! @@ -539,6 +543,22 @@ int QFSFileEnginePrivate::nativeHandle() const return fh ? fileno(fh) : fd; } +#ifdef Q_OS_SYMBIAN +int QFSFileEnginePrivate::getMapHandle() +{ + if (symbianFile.SubSessionHandle()) { + // Symbian file handle can't be used for open C mmap() so open the file with open C as well. + if (fileHandleForMaps < 0) { + int flags = openModeToOpenFlags(openMode); + flags &= ~(O_CREAT | O_TRUNC); + fileHandleForMaps = ::wopen((wchar_t*)(fileEntry.nativeFilePath().utf16()), flags, 0666); + } + return fileHandleForMaps; + } + return nativeHandle(); +} +#endif + /*! \internal */ @@ -921,30 +941,6 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const return QDateTime(); } -#ifdef Q_OS_SYMBIAN -uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) -{ - //Q_Q(QFSFileEngine); - Q_UNUSED(flags) - Q_UNUSED(offset) - Q_UNUSED(size) - return 0; - //TODO: use RFileMap when available in symbian^4 -} - -bool QFSFileEnginePrivate::unmap(uchar *ptr) -{ - //TODO: RFileMap as the value in maps, unmap it here when API is available... - //Q_Q(QFSFileEngine); - //if (!maps.contains(ptr)) { - // q->setError(QFile::PermissionsError, qt_error_string(EACCES)); - // return false; - //} - Q_UNUSED(ptr) - - return false; -} -#else uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) { Q_Q(QFSFileEngine); @@ -985,7 +981,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla #ifdef Q_OS_SYMBIAN void *mapAddress; TRAPD(err, mapAddress = QT_MMAP((void*)0, realSize, - access, MAP_SHARED, nativeHandle(), realOffset)); + access, MAP_SHARED, getMapHandle(), realOffset)); if (err != KErrNone) { qWarning("OpenC bug: leave from mmap %d", err); mapAddress = MAP_FAILED; @@ -1035,7 +1031,6 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr) maps.remove(ptr); return true; } -#endif QT_END_NAMESPACE diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 4e7cb9f..088c1f2 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -2800,10 +2800,6 @@ void tst_QFile::map() QFETCH(int, size); QFETCH(QFile::FileError, error); -#ifdef Q_OS_SYMBIAN - QSKIP("memory mapped files not supported on this platform", SkipAll); -#endif - QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile"; #ifdef Q_WS_WINCE @@ -2925,10 +2921,6 @@ void tst_QFile::mapResource() QFETCH(int, size); QFETCH(QFile::FileError, error); -#ifdef Q_OS_SYMBIAN - QSKIP("memory mapped files not supported on this platform", SkipAll); -#endif - QFile file(fileName); uchar *memory = file.map(offset, size); QCOMPARE(file.error(), error); @@ -2954,10 +2946,6 @@ void tst_QFile::mapOpenMode() QFETCH(int, openMode); static const qint64 fileSize = 4096; -#ifdef Q_OS_SYMBIAN - QSKIP("memory mapped files not supported on this platform", SkipAll); -#endif - QByteArray pattern(fileSize, 'A'); QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile"; -- cgit v0.12 From 415358416981249dc00446ba3368be1b7c0cba51 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Fri, 29 Oct 2010 16:24:29 +0200 Subject: Compile fix for c1148ee9a60a6fae8. --- src/gui/kernel/qeventdispatcher_qpa.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/kernel/qeventdispatcher_qpa.cpp b/src/gui/kernel/qeventdispatcher_qpa.cpp index 31fb356..519d2a6 100644 --- a/src/gui/kernel/qeventdispatcher_qpa.cpp +++ b/src/gui/kernel/qeventdispatcher_qpa.cpp @@ -332,6 +332,4 @@ void SelectWorker::run() m_edPrivate->barrierReturnValue->checkpoint(); } } - -#include "qeventdispatcher_qpa.moc" QT_END_NAMESPACE -- cgit v0.12 From 05b65c2f9df1c2c56c72f313401a6adb422d381b Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Mon, 1 Nov 2010 13:44:36 +0100 Subject: Fix cross-compilation for Lighthouse after 3d86d2a8e5e3c68f9e0022e67629 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Morten Johan Sørvig --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 08d2f54..61f2413 100755 --- a/configure +++ b/configure @@ -2938,7 +2938,7 @@ if [ '!' -f "${XQMAKESPEC}/qplatformdefs.h" ]; then fi # now look at the configs and figure out what platform we are config'd for -[ "$CFG_EMBEDDED" = "no" ] \ +[ "$CFG_EMBEDDED" = "no" ] && [ "$PLATFORM_QPA" != "yes" ] \ && [ '!' -z "`getQMakeConf \"$XQMAKESPEC\" | grep QMAKE_LIBS_X11 | awk '{print $3;}'`" ] \ && PLATFORM_X11=yes ### echo "$XQMAKESPEC" | grep mkspecs/qws >/dev/null 2>&1 && PLATFORM_QWS=yes -- cgit v0.12 From b251f7f9d2d1fb336e0b4f92858aad2eab0ba88c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 16 Nov 2010 15:17:49 +0100 Subject: QFileSystemEngine::resolveUserName and not group Reviewed-by: Shane Kearns --- src/corelib/io/qfilesystemengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index 8613dd7..fe0bad7 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -359,7 +359,7 @@ QString QFileSystemEngine::resolveUserName(const QFileSystemEntry &entry, QFileS #else //(Q_OS_UNIX) if (!metaData.hasFlags(QFileSystemMetaData::UserId)) QFileSystemEngine::fillMetaData(entry, metaData, QFileSystemMetaData::UserId); - return resolveGroupName(metaData.userId()); + return resolveUserName(metaData.userId()); #endif } -- cgit v0.12 From eb474123412c52e74f402e082c85286047c9aeda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 16 Nov 2010 15:28:17 +0100 Subject: QFile: Fix compilation EACCES was not defined at this point, but it is also not needed, since we know exactly why unmap is failing. Reviewed-by: Shane Kearns --- src/corelib/io/qfile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index f0ca11b..fac4ac6 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -1224,7 +1224,7 @@ bool QFile::unmap(uchar *address) d->setError(d->fileEngine->error(), d->fileEngine->errorString()); return success; } - d->setError(PermissionsError, QSystemError(EACCES, QSystemError::StandardLibraryError).toString()); + d->setError(PermissionsError, tr("No file engine available or engine does not support UnMapExtension")); return false; } -- cgit v0.12 From 02aca4e5a1d3e3e47a2c69a63faa772439ac92cf Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 16 Nov 2010 11:53:14 +0000 Subject: Fix tst_qfileinfo crash on windows with UAC enabled Creating symbolic links requires admin privilege by default - when UAC is enabled then even users in the administrators group do not have admin privileges without an escalation prompt. (which is inappropriate for an autotest). When run with insufficient privileges, the test is skipped with a warning Reviewed-By: Prasanth Ullattil --- tests/auto/qfileinfo/tst_qfileinfo.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 898bf54..07e33d3 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -1353,8 +1353,24 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data() file.open(QIODevice::ReadWrite); file.close(); - QVERIFY(pwd.exists("abs_symlink") || createSymbolicLinkW((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x1)); - QVERIFY(pwd.exists(relSymlink) || createSymbolicLinkW((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x1)); + DWORD err = ERROR_SUCCESS ; + if (!pwd.exists("abs_symlink")) + if (!createSymbolicLinkW((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x1)) + err = GetLastError(); + if (err == ERROR_SUCCESS && !pwd.exists(relSymlink)) + if (!createSymbolicLinkW((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x1)) + err = GetLastError(); + if (err != ERROR_SUCCESS) { + wchar_t errstr[0x100]; + DWORD count = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, + 0, err, 0, errstr, 0x100, 0); + QString error(QString::fromUtf16(errstr, count)); + qWarning() << error; + //we need at least one data set for the test not to assert fail when skipping _data function + QDir target("target"); + QTest::newRow("dummy") << target.path() << false << "" << target.canonicalPath(); + QSKIP("link not supported by FS or insufficient privilege", SkipSingle); + } QVERIFY(file.exists()); QTest::newRow("absolute dir symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalPath(); -- cgit v0.12 From 5a9b670ef04232c7cd5017bd5e241c6ed975be6e Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 16 Nov 2010 13:43:14 +0000 Subject: Test coverage - ensure tst_qfileinfo tests dir & absoluteDir functions The existing dir test function is appropriate, now it checks the dir functions as well as the path functions. Reviewed-By: Prasanth Ullattil --- tests/auto/qfileinfo/qfileinfo.pro | 1 + tests/auto/qfileinfo/tst_qfileinfo.cpp | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/auto/qfileinfo/qfileinfo.pro b/tests/auto/qfileinfo/qfileinfo.pro index 101128c..fdbcd26 100644 --- a/tests/auto/qfileinfo/qfileinfo.pro +++ b/tests/auto/qfileinfo/qfileinfo.pro @@ -30,3 +30,4 @@ wince* { DEFINES += SRCDIR=\\\"$$PWD/\\\" } +contains(QT_CONFIG, qt3support): QT += qt3support diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 07e33d3..d021df5 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -705,10 +705,19 @@ void tst_QFileInfo::dir() QFETCH(QString, expected); QFileInfo fi(file); - if (absPath) + if (absPath) { QCOMPARE(fi.absolutePath(), expected); - else + QCOMPARE(fi.absoluteDir().path(), expected); +#ifdef QT3_SUPPORT + QCOMPARE(fi.dir(true).path(), expected); +#endif + } else { QCOMPARE(fi.path(), expected); + QCOMPARE(fi.dir().path(), expected); +#ifdef QT3_SUPPORT + QCOMPARE(fi.dir(false).path(), expected); +#endif + } } -- cgit v0.12 From eab60b677c6e61c2d31f7aec02f05eb9c12862c9 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 16 Nov 2010 16:20:44 +0000 Subject: test coverage: test QFileInfo::group() Reviewed-By: joao --- tests/auto/qfileinfo/tst_qfileinfo.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index d021df5..3e67fb8 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -189,6 +189,7 @@ private slots: #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) void owner(); #endif + void group(); }; tst_QFileInfo::tst_QFileInfo() @@ -1690,5 +1691,29 @@ void tst_QFileInfo::owner() } #endif +void tst_QFileInfo::group() +{ + QString expected; +#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) + struct group *gr; + gid_t gid = getegid(); + gr = getgrgid(gid); + expected = QString::fromLocal8Bit(gr->gr_name); +#endif + + QString fileName("ownertest.txt"); + if (QFile::exists(fileName)) + QFile::remove(fileName); + QFile testFile(fileName); + QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Text)); + QByteArray testData("testfile"); + QVERIFY(testFile.write(testData) != -1); + testFile.close(); + QFileInfo fi(fileName); + QVERIFY(fi.exists()); + + QCOMPARE(fi.group(), expected); +} + QTEST_MAIN(tst_QFileInfo) #include "tst_qfileinfo.moc" -- cgit v0.12 From c7e569802ac4d547482d529e910232a80347fc67 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 16 Nov 2010 16:50:38 +0000 Subject: test coverage: test QDir::addSearchPath Reviewed-By: joao --- tests/auto/qdir/tst_qdir.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 9521921..4f6c784 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -1434,6 +1434,29 @@ void tst_QDir::searchPaths() for (int i = 0; i < searchPathPrefixList.count(); ++i) { QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)).isEmpty()); } + + for (int i = 0; i < searchPathPrefixList.count(); ++i) { + foreach (QString path, searchPathsList.at(i).split(",")) { + QDir::addSearchPath(searchPathPrefixList.at(i), path); + } + } + for (int i = 0; i < searchPathPrefixList.count(); ++i) { + QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)) == searchPathsList.at(i).split(",")); + } + + QCOMPARE(QFile(filename).exists(), exists); + QCOMPARE(QFileInfo(filename).exists(), exists); + + if (exists) { + QCOMPARE(QFileInfo(filename).absoluteFilePath(), expectedAbsolutePath); + } + + for (int i = 0; i < searchPathPrefixList.count(); ++i) { + QDir::setSearchPaths(searchPathPrefixList.at(i), QStringList()); + } + for (int i = 0; i < searchPathPrefixList.count(); ++i) { + QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)).isEmpty()); + } } void tst_QDir::entryListWithSearchPaths() -- cgit v0.12 From bc6d6b99981f5abf4d8f4059f86f0441156b6700 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 16 Nov 2010 16:56:20 +0000 Subject: test coverage: add test for QDir::match static functions Reviewed-By: joao --- tests/auto/qdir/tst_qdir.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 4f6c784..62f45e8 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -183,6 +183,11 @@ private slots: void isRoot_data(); void isRoot(); #endif + +#ifndef QT_NO_REGEXP + void match_data(); + void match(); +#endif }; // Testing get/set functions @@ -1738,6 +1743,31 @@ void tst_QDir::isRoot() } #endif +#ifndef QT_NO_REGEXP +void tst_QDir::match_data() +{ + QTest::addColumn("filter"); + QTest::addColumn("filename"); + QTest::addColumn("match"); + + QTest::newRow("single, matching") << "*.cpp" << "tst_qdir.cpp" << true; + QTest::newRow("single, not matching") << "*.cpp" << "tst_qdir.h" << false; + QTest::newRow("multi, matching") << "*.cpp;*.h" << "tst_qdir.cpp" << true; + QTest::newRow("multi, matching2") << "*.cpp;*.h" << "tst_qdir.h" << true; + QTest::newRow("multi, not matching") << "*.cpp;*.h" << "readme.txt" << false; +} + +void tst_QDir::match() +{ + QFETCH(QString, filter); + QFETCH(QString, filename); + QFETCH(bool, match); + + QCOMPARE(QDir::match(filter, filename), match); + QCOMPARE(QDir::match(filter.split(QLatin1Char(';')), filename), match); +} +#endif + QTEST_MAIN(tst_QDir) #include "tst_qdir.moc" -- cgit v0.12 From 43aa80fe8c1064d88b104a8f8f1b97bbaeaf1cec Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 16 Nov 2010 18:21:05 +0000 Subject: Test coverage: test QFile::resize Reviewed-By: joao --- tests/auto/qfile/tst_qfile.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 088c1f2..53618e5 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -211,6 +211,9 @@ private slots: void openStandardStreams(); + void resize_data(); + void resize(); + // --- Task related tests below this line void task167217(); @@ -3085,5 +3088,28 @@ void tst_QFile::writeNothing() } } +void tst_QFile::resize_data() +{ + QTest::addColumn("filetype"); + + QTest::newRow("native") << int(OpenQFile); + QTest::newRow("fileno") << int(OpenFd); + QTest::newRow("stream") << int(OpenStream); +} + +void tst_QFile::resize() +{ + QFETCH(int, filetype); + QString filename(QLatin1String("file.txt")); + QFile file(filename); + QVERIFY(openFile(file, QIODevice::ReadWrite, FileType(filetype))); + QVERIFY(file.resize(8)); + QCOMPARE(file.size(), qint64(8)); + closeFile(file); + QFile::resize(filename, 4); + QCOMPARE(QFileInfo(filename).size(), qint64(4)); + QVERIFY(QFile::remove(filename)); +} + QTEST_MAIN(tst_QFile) #include "tst_qfile.moc" -- cgit v0.12 From f50098de5af1886f69214285345ef7ef4ebdc1fd Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 16 Nov 2010 18:21:56 +0000 Subject: Fix QFile::resize on windows for files opened from a FILE* Reviewed-By: joao --- src/corelib/io/qfsfileengine_win.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index cf83c07..97d1330 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -865,12 +865,16 @@ bool QFSFileEngine::setSize(qint64 size) { Q_D(QFSFileEngine); - if (d->fileHandle != INVALID_HANDLE_VALUE || d->fd != -1) { + if (d->fileHandle != INVALID_HANDLE_VALUE || d->fd != -1 || d->fh) { // resize open file HANDLE fh = d->fileHandle; #if !defined(Q_OS_WINCE) - if (fh == INVALID_HANDLE_VALUE) - fh = (HANDLE)_get_osfhandle(d->fd); + if (fh == INVALID_HANDLE_VALUE) { + if (d->fh) + fh = (HANDLE)_get_osfhandle(QT_FILENO(d->fh)); + else + fh = (HANDLE)_get_osfhandle(d->fd); + } #endif if (fh == INVALID_HANDLE_VALUE) return false; -- cgit v0.12 From 5ebad6878478c33f8a832929a2fb74e93bc29b62 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 17 Nov 2010 12:29:54 +0000 Subject: Test coverage: test more of QFile API Adding tests for these functions: symLinkTarget / readLink (static & non static) permissions (static) constructors which take a QObject parent After this, all function of QFile API are tested except encoding/decoding functions and some QT3_SUPPORT inlines in the header. Reviewed-by: joao --- tests/auto/qfile/tst_qfile.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 53618e5..f60ab1e 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -214,6 +214,8 @@ private slots: void resize_data(); void resize(); + void objectConstructors(); + // --- Task related tests below this line void task167217(); @@ -1112,6 +1114,7 @@ void tst_QFile::permissions() QFETCH(bool, expected); QFile f(file); QCOMPARE(((f.permissions() & perms) == QFile::Permissions(perms)), expected); + QCOMPARE(((QFile::permissions(file) & perms) == QFile::Permissions(perms)), expected); } void tst_QFile::setPermissions() @@ -1299,6 +1302,12 @@ void tst_QFile::link() QVERIFY(info2.isSymLink()); QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath()); + QFile link("myLink.lnk"); + QVERIFY(link.open(QIODevice::ReadOnly)); + QCOMPARE(link.symLinkTarget(), info1.absoluteFilePath()); + link.close(); + QCOMPARE(QFile::symLinkTarget("myLink.lnk"), info1.absoluteFilePath()); + #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) QString wd = getWorkingDirectoryForLink(info2.absoluteFilePath()); QCOMPARE(QDir::fromNativeSeparators(wd), info1.absolutePath()); @@ -3111,5 +3120,14 @@ void tst_QFile::resize() QVERIFY(QFile::remove(filename)); } +void tst_QFile::objectConstructors() +{ + QObject ob; + QFile* file1 = new QFile(SRCDIR "testfile.txt", &ob); + QFile* file2 = new QFile(&ob); + QVERIFY(file1->exists()); + QVERIFY(!file2->exists()); +} + QTEST_MAIN(tst_QFile) #include "tst_qfile.moc" -- cgit v0.12 From 51a28e0ffaaff9f97117256fc6d0e11df392d706 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 17 Nov 2010 12:34:26 +0000 Subject: Windows: fix QFile::symLinkTarget Missing return statement Reviewed-by: joao --- src/corelib/io/qfsfileengine_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 97d1330..f3e2c4c 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -825,7 +825,7 @@ QString QFSFileEngine::fileName(FileName file) const return entry.path(); return entry.filePath(); } else if (file == LinkName) { - QFileSystemEngine::getLinkTarget(d->fileEntry, d->metaData).filePath(); + return QFileSystemEngine::getLinkTarget(d->fileEntry, d->metaData).filePath(); } else if (file == BundleName) { return QString(); } -- cgit v0.12 From 43adb2ed628f79d3c59f4bf0b4cec03efc9c3ab6 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 17 Nov 2010 16:28:21 +0000 Subject: Test Coverage: add tests to cover QDir API Functional coverage of QDir, except for trivial shims for deprecated APIs and the QDebug streaming functions. Reviewed-by: joao --- tests/auto/qdir/qdir.pro | 1 + tests/auto/qdir/tst_qdir.cpp | 210 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 207 insertions(+), 4 deletions(-) diff --git a/tests/auto/qdir/qdir.pro b/tests/auto/qdir/qdir.pro index cf612f1..01a88cd 100644 --- a/tests/auto/qdir/qdir.pro +++ b/tests/auto/qdir/qdir.pro @@ -15,6 +15,7 @@ wince* { TARGET.CAPABILITY += AllFiles TARGET.UID3 = 0xE0340002 DEFINES += SYMBIAN_SRCDIR_UID=$$lower($$replace(TARGET.UID3,"0x","")) + LIBS += -lefsrv } else { contains(QT_CONFIG, qt3support):QT += qt3support DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 62f45e8..7f98a9a 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -57,11 +57,13 @@ #include "../../shared/filesystem.h" #if defined(Q_OS_SYMBIAN) +# include # define STRINGIFY(x) #x # define TOSTRING(x) STRINGIFY(x) # define SRCDIR "C:/Private/" TOSTRING(SYMBIAN_SRCDIR_UID) "/" #elif defined(Q_OS_UNIX) # include +# include #endif #if defined(Q_OS_VXWORKS) @@ -188,6 +190,22 @@ private slots: void match_data(); void match(); #endif + + void drives(); + + void arrayOperator(); + +#ifdef QT3_SUPPORT + void setNameFilter(); +#endif + + void equalityOperator_data(); + void equalityOperator(); + + void isRelative_data(); + void isRelative(); + + void isReadable(); }; // Testing get/set functions @@ -1190,6 +1208,8 @@ void tst_QDir::remove() QDir dir; QVERIFY(dir.remove("remove-test")); QVERIFY(!dir.remove("/remove-test")); + QTest::ignoreMessage(QtWarningMsg, "QDir::remove: Empty or null file name"); + QVERIFY(!dir.remove("")); } void tst_QDir::rename() @@ -1202,10 +1222,18 @@ void tst_QDir::rename() QVERIFY(dir.rename("rename-test-renamed", "rename-test")); #if defined(Q_OS_MAC) QVERIFY(!dir.rename("rename-test", "/etc/rename-test-renamed")); -#elif !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN) - // on windows/symbian this is possible - maybe make the test a bit better +#elif defined(Q_OS_SYMBIAN) + QVERIFY(!dir.rename("rename-test", "/resource/rename-test-renamed")); +#elif !defined(Q_OS_WIN) + // on windows this is possible - maybe make the test a bit better QVERIFY(!dir.rename("rename-test", "/rename-test-renamed")); #endif + QTest::ignoreMessage(QtWarningMsg, "QDir::rename: Empty or null file name(s)"); + QVERIFY(!dir.rename("rename-test", "")); + QTest::ignoreMessage(QtWarningMsg, "QDir::rename: Empty or null file name(s)"); + QVERIFY(!dir.rename("", "rename-test-renamed")); + QVERIFY(!dir.rename("some-file-that-does-not-exist", "rename-test-renamed")); + QVERIFY(dir.remove("rename-test")); } @@ -1717,7 +1745,6 @@ void tst_QDir::testCaching() QVERIFY(dir.exists()); // QDir doesn't cache the 'exist' between calls. } -#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) void tst_QDir::isRoot_data() { QTest::addColumn("path"); @@ -1729,8 +1756,13 @@ void tst_QDir::isRoot_data() QTest::newRow(QString("./ appended " + test).toLatin1()) << test << false; test = QDir(QDir::rootPath().append("./")).canonicalPath(); QTest::newRow(QString("canonicalPath " + test).toLatin1()) << test << true; +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) test = QDir::rootPath().left(2); QTest::newRow(QString("drive relative " + test).toLatin1()) << test << false; +#endif + + QTest::newRow("resources root") << ":/" << true; + QTest::newRow("resources nonroot") << ":/entrylist" << false; } void tst_QDir::isRoot() @@ -1741,7 +1773,6 @@ void tst_QDir::isRoot() QDir dir(path); QCOMPARE(dir.isRoot(),isRoot); } -#endif #ifndef QT_NO_REGEXP void tst_QDir::match_data() @@ -1768,6 +1799,177 @@ void tst_QDir::match() } #endif +void tst_QDir::drives() +{ + QFileInfoList list(QDir::drives()); +#if defined(Q_OS_WIN) + QVERIFY(list.count() >= 1); //system + QLatin1Char systemdrive('c'); +#elif defined(Q_OS_SYMBIAN) + QVERIFY(list.count() >= 2); //system, rom + QLatin1Char romdrive('z'); + QLatin1Char systemdrive('a' + int(RFs::SystemDrive())); +#endif +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + QVERIFY(list.count() <= 26); + bool foundsystem = false; +#ifdef Q_OS_SYMBIAN + bool foundrom = false; +#endif + foreach (QFileInfo fi, list) { + QCOMPARE(fi.absolutePath().size(), 3); //"x:/" + QCOMPARE(fi.absolutePath().at(1), QChar(QLatin1Char(':'))); + QCOMPARE(fi.absolutePath().at(2), QChar(QLatin1Char('/'))); + if (fi.absolutePath().at(0).toLower() == systemdrive) + foundsystem = true; +#ifdef Q_OS_SYMBIAN + if (fi.absolutePath().at(0).toLower() == romdrive) + foundrom = true; +#endif + } + QCOMPARE(foundsystem, true); +#ifdef Q_OS_SYMBIAN + QCOMPARE(foundrom, true); +#endif +#else + QCOMPARE(list.count(), 1); //root + QCOMPARE(list.at(0).absolutePath(), "/"); +#endif +} + +void tst_QDir::arrayOperator() +{ + QDir dir1(SRCDIR "entrylist/"); + QDir dir2(SRCDIR "entrylist/"); + + QStringList entries(dir1.entryList()); + int i = dir2.count(); + QCOMPARE(i, entries.count()); + --i; + for (;i>=0;--i) { + QCOMPARE(dir2[i], entries.at(i)); + } +} + +#ifdef QT3_SUPPORT +void tst_QDir::setNameFilter() +{ + QStringList filters; + filters << "*.jpg" << "*.png" << "*.gif"; + QStringList filters2; + filters2 << "*.cpp" << "*.h" << "*.c"; + + QDir dir(SRCDIR "entrylist/"); + + dir.setNameFilter(filters.join(";")); + QCOMPARE(filters, dir.nameFilters()); + QCOMPARE(filters, dir.nameFilter().split(';')); + + dir.setNameFilters(filters2); + QCOMPARE(filters2, dir.nameFilter().split(';')); + + dir.setNameFilter(filters.join(" ")); + QCOMPARE(filters, dir.nameFilters()); + QCOMPARE(filters, dir.nameFilter().split(' ')); + + dir.setNameFilters(filters2); + QCOMPARE(filters2, dir.nameFilter().split(' ')); +} +#endif + +void tst_QDir::equalityOperator_data() +{ + QTest::addColumn("leftPath"); + QTest::addColumn("leftNameFilters"); + QTest::addColumn("leftSort"); + QTest::addColumn("leftFilters"); + QTest::addColumn("rightPath"); + QTest::addColumn("rightNameFilters"); + QTest::addColumn("rightSort"); + QTest::addColumn("rightFilters"); + QTest::addColumn("expected"); + + QTest::newRow("same") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << true; + + QTest::newRow("relativepaths") << "entrylist/" << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << "./entrylist" << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << true; + + QTest::newRow("diff-filters") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Dirs) + << false; + + QTest::newRow("diff-sort") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << SRCDIR << "*.cpp" << int(QDir::Time) << int(QDir::Files) + << false; + + QTest::newRow("diff-namefilters") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << SRCDIR << "*.jpg" << int(QDir::Name) << int(QDir::Files) + << false; +} + +void tst_QDir::equalityOperator() +{ + QFETCH(QString, leftPath); + QFETCH(QString, leftNameFilters); + QFETCH(int, leftSort); + QFETCH(int, leftFilters); + QFETCH(QString, rightPath); + QFETCH(QString, rightNameFilters); + QFETCH(int, rightSort); + QFETCH(int, rightFilters); + QFETCH(bool, expected); + + QDir dir1(leftPath, leftNameFilters, QDir::SortFlags(leftSort), QDir::Filters(leftFilters)); + QDir dir2(rightPath, rightNameFilters, QDir::SortFlags(rightSort), QDir::Filters(rightFilters)); + + QCOMPARE((dir1 == dir2), expected); + QCOMPARE((dir2 == dir1), expected); + QCOMPARE((dir1 != dir2), !expected); + QCOMPARE((dir2 != dir1), !expected); +} + +void tst_QDir::isRelative_data() +{ + QTest::addColumn("path"); + QTest::addColumn("relative"); + + QTest::newRow(".") << "./" << true; + QTest::newRow("..") << "../" << true; + QTest::newRow("content") << "entrylist/" << true; + QTest::newRow("current") << QDir::currentPath() << false; + QTest::newRow("homepath") << QDir::homePath() << false; + QTest::newRow("temppath") << QDir::tempPath() << false; + QTest::newRow("rootpath") << QDir::rootPath() << false; + foreach (QFileInfo root, QDir::drives()) { + QTest::newRow(root.absolutePath()) << root.absolutePath() << false; + } +} + +void tst_QDir::isRelative() +{ + QFETCH(QString, path); + QFETCH(bool, relative); + + QCOMPARE(QDir(path).isRelative(), relative); +} + +void tst_QDir::isReadable() +{ + QDir dir; + + QVERIFY(dir.isReadable()); +#if defined (Q_OS_UNIX) && !defined (Q_OS_SYMBIAN) + QVERIFY(dir.mkdir("nonreadabledir")); + QVERIFY(0 == ::chmod("nonreadabledir", 0)); + QVERIFY(!QDir("nonreadabledir").isReadable()); + QVERIFY(0 == ::chmod("nonreadabledir", S_IRUSR | S_IWUSR | S_IXUSR)); + QVERIFY(dir.rmdir("nonreadabledir")); +#endif +} + QTEST_MAIN(tst_QDir) #include "tst_qdir.moc" -- cgit v0.12 From a5de017fe85ce8058c32df1f61df0c9c59ccf01c Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 17 Nov 2010 18:21:45 +0100 Subject: Fix test compile error on linux Reviewed-By: Trust Me --- tests/auto/qdir/tst_qdir.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 7f98a9a..e8c8e07 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -181,10 +181,8 @@ private slots: void testCaching(); -#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) void isRoot_data(); void isRoot(); -#endif #ifndef QT_NO_REGEXP void match_data(); @@ -1833,7 +1831,7 @@ void tst_QDir::drives() #endif #else QCOMPARE(list.count(), 1); //root - QCOMPARE(list.at(0).absolutePath(), "/"); + QCOMPARE(list.at(0).absolutePath(), QLatin1String("/")); #endif } -- cgit v0.12 From c75d76bc8c08805d2f1b0003ff17c25a28955b52 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 17 Nov 2010 18:04:32 +0000 Subject: Fix test compile issues on symbian Reviewed-by: Trust Me --- tests/auto/qdir/tst_qdir.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index e8c8e07..6a81da6 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -1305,12 +1305,13 @@ void tst_QDir::dotAndDotDot() { #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) QSKIP("WinCE and Symbian do not have . nor ..", SkipAll); -#endif +#else QDir dir(QString(SRCDIR "testdir/")); QStringList entryList = dir.entryList(QDir::Dirs); QCOMPARE(entryList, QStringList() << QString(".") << QString("..") << QString("dir") << QString("spaces")); entryList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); QCOMPARE(entryList, QStringList() << QString("dir") << QString("spaces")); +#endif } #ifdef QT3_SUPPORT @@ -1806,7 +1807,7 @@ void tst_QDir::drives() #elif defined(Q_OS_SYMBIAN) QVERIFY(list.count() >= 2); //system, rom QLatin1Char romdrive('z'); - QLatin1Char systemdrive('a' + int(RFs::SystemDrive())); + QLatin1Char systemdrive('a' + int(RFs::GetSystemDrive())); #endif #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) QVERIFY(list.count() <= 26); @@ -1942,7 +1943,7 @@ void tst_QDir::isRelative_data() QTest::newRow("temppath") << QDir::tempPath() << false; QTest::newRow("rootpath") << QDir::rootPath() << false; foreach (QFileInfo root, QDir::drives()) { - QTest::newRow(root.absolutePath()) << root.absolutePath() << false; + QTest::newRow(root.absolutePath().toLocal8Bit()) << root.absolutePath() << false; } } -- cgit v0.12 From c5a5696ca5273fb0a8474b525d1df4a52463afbd Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 18 Nov 2010 11:55:55 +0000 Subject: Update QDirModel autotest (symbian) Skip test requiring symbolic link as they aren't supported Move a Q_EXPECT_FAIL to immediately before the test function that fails (so the test result is XFAIL instead of FAIL) Reviewed-by: joao --- tests/auto/qdirmodel/tst_qdirmodel.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/tests/auto/qdirmodel/tst_qdirmodel.cpp b/tests/auto/qdirmodel/tst_qdirmodel.cpp index 41bbd87..e252b82 100644 --- a/tests/auto/qdirmodel/tst_qdirmodel.cpp +++ b/tests/auto/qdirmodel/tst_qdirmodel.cpp @@ -583,19 +583,15 @@ void tst_QDirModel::unreadable() void tst_QDirModel::filePath() { +#ifdef Q_OS_SYMBIAN + QSKIP("OS doesn't support symbolic links", SkipAll); +#else QFile::remove(SRCDIR "test.lnk"); QVERIFY(QFile(SRCDIR "tst_qdirmodel.cpp").link(SRCDIR "test.lnk")); QDirModel model; model.setResolveSymlinks(false); QModelIndex index = model.index(SRCDIR "test.lnk"); QVERIFY(index.isValid()); -#if defined(Q_OS_SYMBIAN) - // Since model will force lowercase path in Symbian, make case insensitive compare - // Note: Windows should fail this, too, if test path has any uppercase letters. - QCOMPARE(model.filePath(index).toLower(), QString(SRCDIR).toLower() + "test.lnk"); - model.setResolveSymlinks(true); - QCOMPARE(model.filePath(index).toLower(), QString(SRCDIR).toLower() + "tst_qdirmodel.cpp"); -#else #ifndef Q_OS_WINCE QString path = SRCDIR; #else @@ -604,8 +600,8 @@ void tst_QDirModel::filePath() QCOMPARE(model.filePath(index), path + QString( "test.lnk")); model.setResolveSymlinks(true); QCOMPARE(model.filePath(index), path + QString( "tst_qdirmodel.cpp")); -#endif QFile::remove(SRCDIR "test.lnk"); +#endif } void tst_QDirModel::task196768_sorting() @@ -613,11 +609,6 @@ void tst_QDirModel::task196768_sorting() //this task showed that the persistent model indexes got corrupted when sorting QString path = SRCDIR; -#ifdef Q_OS_SYMBIAN - if(!RProcess().HasCapability(ECapabilityAllFiles)) - QEXPECT_FAIL("", "QTBUG-9746", Continue); -#endif - QDirModel model; /* QDirModel has a bug if we show the content of the subdirectory inside a hidden directory @@ -637,6 +628,11 @@ void tst_QDirModel::task196768_sorting() QCOMPARE(index.data(), index2.data()); view.setSortingEnabled(true); index2 = model.index(path); + +#ifdef Q_OS_SYMBIAN + if(!RProcess().HasCapability(ECapabilityAllFiles)) + QEXPECT_FAIL("", "QTBUG-9746", Continue); +#endif QCOMPARE(index.data(), index2.data()); } -- cgit v0.12 From 587728bf81e60de63a80b10ae2d57b7bc18bec4e Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 16 Nov 2010 21:21:12 +0100 Subject: Add workaround_brokenFBOReadback=true for mali --- src/opengl/qgl_qpa.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 49c0860..4b530de 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -166,6 +166,15 @@ void QGLContext::makeCurrent() Q_D(QGLContext); d->platformContext->makeCurrent(); QGLContextPrivate::setCurrentContext(this); + + if (!d->workaroundsCached) { + d->workaroundsCached = true; + const char *renderer = reinterpret_cast(glGetString(GL_RENDERER)); + if (renderer && strstr(renderer, "Mali")) { + d->workaround_brokenFBOReadBack = true; + } + } + } void QGLContext::doneCurrent() -- cgit v0.12 From 687d44569dbccea72c582c6d7da9a271ae2c86c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Mon, 15 Nov 2010 16:18:25 +0100 Subject: No more windowsurface for QGLWidget in Lighthouse Reviewed-by: paul --- src/gui/kernel/qplatformwindowformat_qpa.cpp | 39 ++++++++++++++-------------- src/gui/kernel/qplatformwindowformat_qpa.h | 16 +++++++----- src/gui/kernel/qwidget_qpa.cpp | 7 +++-- src/opengl/qgl_qpa.cpp | 1 + 4 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/gui/kernel/qplatformwindowformat_qpa.cpp b/src/gui/kernel/qplatformwindowformat_qpa.cpp index d497e85..f0dad17 100644 --- a/src/gui/kernel/qplatformwindowformat_qpa.cpp +++ b/src/gui/kernel/qplatformwindowformat_qpa.cpp @@ -53,7 +53,7 @@ public: , opts(QPlatformWindowFormat::DoubleBuffer | QPlatformWindowFormat::DepthBuffer | QPlatformWindowFormat::Rgba | QPlatformWindowFormat::DirectRendering | QPlatformWindowFormat::StencilBuffer | QPlatformWindowFormat::DeprecatedFunctions - | QPlatformWindowFormat::UseDefaultSharedContext) + | QPlatformWindowFormat::UseDefaultSharedContext | QPlatformWindowFormat::HasWindowSurface) , depthSize(-1) , accumSize(-1) , stencilSize(-1) @@ -616,31 +616,32 @@ QPlatformGLContext *QPlatformWindowFormat::sharedGLContext() const return d->sharedContext; } -///*! -// \fn bool QPlatformWindowFormat::hasOverlay() const +/*! + \fn bool QPlatformWindowFormat::hasWindowSurface() const -// Returns true if overlay plane is enabled; otherwise returns false. + Returns true if the corresponding widget has an instance of QWindowSurface. -// Overlay is disabled by default. + Otherwise returns false. -// \sa setOverlay() -//*/ + WindowSurface is enabled by default. -///*! -// If \a enable is true enables an overlay plane; otherwise disables -// the overlay plane. + \sa setOverlay() +*/ -// Enabling the overlay plane will cause QGLWidget to create an -// additional context in an overlay plane. See the QGLWidget -// documentation for further information. +/*! + If \a enable is true a top level QWidget will create a QWindowSurface at creation; -// \sa hasOverlay() -//*/ + otherwise the QWidget will only have a QPlatformWindow. -//void QPlatformWindowFormat::setOverlay(bool enable) -//{ -// setOption(enable ? QPlatformWindowFormat::HasOverlay : QPlatformWindowFormat::NoOverlay); -//} + This is usefull for ie. QGLWidget where the QPlatformGLContext controlls the surface. + + \sa hasOverlay() +*/ + +void QPlatformWindowFormat::setWindowSurface(bool enable) +{ + setOption(enable ? QPlatformWindowFormat::HasWindowSurface : QPlatformWindowFormat::NoWindowSurface); +} /*! Sets the format option to \a opt. diff --git a/src/gui/kernel/qplatformwindowformat_qpa.h b/src/gui/kernel/qplatformwindowformat_qpa.h index 63df76a..790385b 100644 --- a/src/gui/kernel/qplatformwindowformat_qpa.h +++ b/src/gui/kernel/qplatformwindowformat_qpa.h @@ -67,6 +67,7 @@ public: SampleBuffers = 0x0200, DeprecatedFunctions = 0x0400, UseDefaultSharedContext = 0x0800, + HasWindowSurface = 0x1000, SingleBuffer = DoubleBuffer << 16, NoDepthBuffer = DepthBuffer << 16, ColorIndex = Rgba << 16, @@ -78,7 +79,8 @@ public: NoOverlay = HasOverlay << 16, NoSampleBuffers = SampleBuffers << 16, NoDeprecatedFunctions = DeprecatedFunctions << 16, - NoDefaultSharedContext = UseDefaultSharedContext << 16 + NoDefaultSharedContext = UseDefaultSharedContext << 16, + NoWindowSurface = HasWindowSurface << 16 }; Q_DECLARE_FLAGS(FormatOptions, FormatOption) @@ -149,8 +151,8 @@ public: void setDirectRendering(bool enable); bool useDefaultSharedContext() const; void setUseDefaultSharedContext(bool enable); -// bool hasOverlay() const; -// void setOverlay(bool enable); + bool hasWindowSurface() const; + void setWindowSurface(bool enable); void setOption(QPlatformWindowFormat::FormatOptions opt); bool testOption(QPlatformWindowFormat::FormatOptions opt) const; @@ -219,10 +221,10 @@ inline bool QPlatformWindowFormat::directRendering() const return testOption(QPlatformWindowFormat::DirectRendering); } -//inline bool QPlatformWindowFormat::hasOverlay() const -//{ -// return testOption(QPlatformWindowFormat::HasOverlay); -//} +inline bool QPlatformWindowFormat::hasWindowSurface() const +{ + return testOption(QPlatformWindowFormat::HasWindowSurface); +} inline bool QPlatformWindowFormat::sampleBuffers() const { diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp index ac8b37d..aff959e 100644 --- a/src/gui/kernel/qwidget_qpa.cpp +++ b/src/gui/kernel/qwidget_qpa.cpp @@ -97,7 +97,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } Q_ASSERT(platformWindow); - if (!surface) { + if (!surface && platformWindow && q->platformWindowFormat().hasWindowSurface()) { surface = QApplicationPrivate::platformIntegration()->createWindowSurface(q,platformWindow->winId()); } @@ -831,7 +831,10 @@ QPaintEngine *QWidget::paintEngine() const QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys() { Q_Q(QWidget); - return QApplicationPrivate::platformIntegration()->createWindowSurface(q,0); + if (q->platformWindowFormat().hasWindowSurface()) + return QApplicationPrivate::platformIntegration()->createWindowSurface(q,0); + else + return 0; } void QWidgetPrivate::setModal_sys() diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 4b530de..1197013 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -134,6 +134,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) winFormat.setSharedContext(shareContext->d_func()->platformContext); } winFormat.setWindowApi(QPlatformWindowFormat::OpenGL); + winFormat.setWindowSurface(false); widget->setPlatformWindowFormat(winFormat); widget->winId();//make window } -- cgit v0.12 From 9d00cf202376c2b02dec27b362cf88a00e952e88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 16 Nov 2010 08:51:17 +0100 Subject: Lighthouse: using QFont enums when possible in QPlatformFontdatabase also, make it possible to register fonts in QPlatformDatabases with a null handle Reviewed-by: paul --- src/gui/text/qfontdatabase_qpa.cpp | 11 ++++------- src/gui/text/qplatformfontdatabase_qpa.cpp | 12 ++++++------ src/gui/text/qplatformfontdatabase_qpa.h | 4 ++-- .../fontdatabases/basicunix/qbasicunixfontdatabase.cpp | 6 ++++-- .../fontdatabases/fontconfig/qfontconfigdatabase.cpp | 14 +++++++++----- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp index 19ce1be..e54093c 100644 --- a/src/gui/text/qfontdatabase_qpa.cpp +++ b/src/gui/text/qfontdatabase_qpa.cpp @@ -156,14 +156,11 @@ QFontEngine *loadSingleEngine(int script, QFontEngine *engine = QFontCache::instance()->findEngine(key); if (!engine) { QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase(); - if (size->handle) { - engine = pfdb->fontEngine(def,QUnicodeTables::Script(script),size->handle); - if (engine) { - QFontCache::Key key(def,script); - QFontCache::instance()->instance()->insertEngine(key,engine); - } + engine = pfdb->fontEngine(def,QUnicodeTables::Script(script),size->handle); + if (engine) { + QFontCache::Key key(def,script); + QFontCache::instance()->instance()->insertEngine(key,engine); } - } return engine; } diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp index 370c921..7a89fe4 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.cpp +++ b/src/gui/text/qplatformfontdatabase_qpa.cpp @@ -65,9 +65,9 @@ void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void * QByteArray writingSystemBits = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_WritingSystems).toByteArray(); if (!fontName.isEmpty() && pixelSize) { - int fontWeight = 50; + QFont::Weight fontWeight = QFont::Normal; if (weight.type() == QVariant::Int || weight.type() == QVariant::UInt) - fontWeight = weight.toInt(); + fontWeight = QFont::Weight(weight.toInt()); QFont::Style fontStyle = static_cast(style.toInt()); @@ -80,16 +80,16 @@ void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void * currentByte >>= 1; } } - - registerFont(fontName,QString(),fontWeight,fontStyle,100,true,false,pixelSize,writingSystems,handle); + QFont::Stretch stretch = QFont::Unstretched; + registerFont(fontName,QString(),fontWeight,fontStyle,stretch,true,false,pixelSize,writingSystems,handle); } } else { qDebug() << "header verification of QPF2 font failed. maybe it is corrupt?"; } } -void QPlatformFontDatabase::registerFont(const QString &familyname, const QString &foundryname, int weight, - QFont::Style style, int stretch, bool antialiased, bool scalable, int pixelSize, +void QPlatformFontDatabase::registerFont(const QString &familyname, const QString &foundryname, QFont::Weight weight, + QFont::Style style, QFont::Stretch stretch, bool antialiased, bool scalable, int pixelSize, const QSupportedWritingSystems &writingSystems, void *usrPtr) { if (scalable) diff --git a/src/gui/text/qplatformfontdatabase_qpa.h b/src/gui/text/qplatformfontdatabase_qpa.h index 75b0a18..aa465ab 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.h +++ b/src/gui/text/qplatformfontdatabase_qpa.h @@ -96,8 +96,8 @@ public: //callback static void registerQPF2Font(const QByteArray &dataArray, void *handle); - static void registerFont(const QString &familyname, const QString &foundryname, int weight, - QFont::Style style, int stetch, bool antialiased, bool scalable, int pixelSize, + static void registerFont(const QString &familyname, const QString &foundryname, QFont::Weight weight, + QFont::Style style, QFont::Stretch stretch, bool antialiased, bool scalable, int pixelSize, const QSupportedWritingSystems &writingSystems, void *handle); }; diff --git a/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp b/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp index 4634477..ee520be 100644 --- a/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp +++ b/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp @@ -278,7 +278,7 @@ QStringList QBasicUnixFontDatabase::addTTFile(const QByteArray &fontData, const } numFaces = face->num_faces; - int weight = QFont::Normal; + QFont::Weight weight = QFont::Normal; QFont::Style style = QFont::StyleNormal; if (face->style_flags & FT_STYLE_FLAG_ITALIC) @@ -315,7 +315,9 @@ QStringList QBasicUnixFontDatabase::addTTFile(const QByteArray &fontData, const fontFile->fileName = file; fontFile->indexValue = index; - registerFont(family,"",weight,style,100,true,true,0,writingSystems,fontFile); + QFont::Stretch stretch = QFont::Unstretched; + + registerFont(family,"",weight,style,stretch,true,true,0,writingSystems,fontFile); families.append(family); diff --git a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp index c9d1b74..92f30fc 100644 --- a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -395,7 +395,7 @@ void QFontconfigDatabase::populateFontDatabase() : ((slant_value == FC_SLANT_OBLIQUE) ? QFont::StyleOblique : QFont::StyleNormal); - int weight = getFCWeight(weight_value); + QFont::Weight weight = QFont::Weight(getFCWeight(weight_value)); double pixel_size = 0; if (!scalable) { @@ -404,7 +404,8 @@ void QFontconfigDatabase::populateFontDatabase() FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size); } - QPlatformFontDatabase::registerFont(familyName,QLatin1String((const char *)foundry_value),weight,style,100,antialias,scalable,pixel_size,writingSystems,fontFile); + QFont::Stretch stretch = QFont::Unstretched; + QPlatformFontDatabase::registerFont(familyName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,writingSystems,fontFile); // qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size; } @@ -426,10 +427,11 @@ void QFontconfigDatabase::populateFontDatabase() QSupportedWritingSystems ws; ws.setSupported(QFontDatabase::Latin); + while (f->qtname) { - registerFont(f->qtname,"",50,QFont::StyleNormal,100,true,true,0,ws,0); - registerFont(f->qtname,"",50,QFont::StyleItalic,100,true,true,0,ws,0); - registerFont(f->qtname,"",50,QFont::StyleOblique,100,true,true,0,ws,0); + registerFont(f->qtname,QLatin1String(""),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,ws,0); + registerFont(f->qtname,QLatin1String(""),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,ws,0); + registerFont(f->qtname,QLatin1String(""),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,ws,0); ++f; } @@ -444,6 +446,8 @@ void QFontconfigDatabase::populateFontDatabase() QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QUnicodeTables::Script script, void *usrPtr) { + if (!usrPtr) + return 0; QFontDef fontDef = f; QFontEngineFT *engine; -- cgit v0.12 From 799e7456268e347356cf4949fcab525968e9fea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 16 Nov 2010 10:51:28 +0100 Subject: Lighthouse: Make sure that we call QPlatformWindow::setVisible on native child widgets. Reviewed-by: paul --- src/gui/kernel/qwidget_qpa.cpp | 35 ++++++++++------------ src/plugins/platforms/testlite/qtestlitewindow.cpp | 1 - 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp index aff959e..acb2615 100644 --- a/src/gui/kernel/qwidget_qpa.cpp +++ b/src/gui/kernel/qwidget_qpa.cpp @@ -392,25 +392,22 @@ void QWidgetPrivate::show_sys() QPlatformWindow *window = q->platformWindow(); if (window) { - const QRect geomRect = q->geometry(); - const QRect windowRect = window->geometry(); - if (windowRect != geomRect) { - window->setGeometry(geomRect); - } - if (q->isWindow()) { - if (QWindowSurface *surface = q->windowSurface()) { - if (windowRect.size() != geomRect.size()) { - surface->resize(geomRect.size()); - } - } - - if (window) - window->setVisible(true); - - if (q->windowType() != Qt::Popup && q->windowType() != Qt::ToolTip && !(q->windowFlags() & Qt::X11BypassWindowManagerHint)) - q->activateWindow(); //### - } - } + const QRect geomRect = q->geometry(); + const QRect windowRect = window->geometry(); + if (windowRect != geomRect) { + window->setGeometry(geomRect); + } + if (QWindowSurface *surface = q->windowSurface()) { + if (windowRect.size() != geomRect.size()) { + surface->resize(geomRect.size()); + } + } + if (window) + window->setVisible(true); + + if (q->isWindow() && q->windowType() != Qt::Popup && q->windowType() != Qt::ToolTip && !(q->windowFlags() & Qt::X11BypassWindowManagerHint)) + q->activateWindow(); //### QWindowSystemInterface should have callback function for when WS actually activates window. + } } diff --git a/src/plugins/platforms/testlite/qtestlitewindow.cpp b/src/plugins/platforms/testlite/qtestlitewindow.cpp index 1de4b9d..9f3c435 100644 --- a/src/plugins/platforms/testlite/qtestlitewindow.cpp +++ b/src/plugins/platforms/testlite/qtestlitewindow.cpp @@ -649,7 +649,6 @@ void QTestLiteWindow::setParent(const QPlatformWindow *window) { QPoint point = widget()->mapTo(widget()->nativeParentWidget(),QPoint()); XReparentWindow(xd->display,x_window,window->winId(),point.x(),point.y()); - XMapWindow(xd->display, x_window); } void QTestLiteWindow::raise() -- cgit v0.12 From 6901d3a9ff05a6fbf13ef7f38a36ad21d20f6a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 16 Nov 2010 12:45:15 +0100 Subject: Fix transformIsSimple in QGraphicsScene The transformIsSimple was a bit to restrictive Reviewed-by: bnilsen --- src/gui/graphicsview/qgraphicsscene.cpp | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 981fbbc..19b2cb8 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4367,25 +4367,8 @@ static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion & static inline bool transformIsSimple(const QTransform& transform) { QTransform::TransformationType type = transform.type(); - if (type == QTransform::TxNone || type == QTransform::TxTranslate) { + if (type <= QTransform::TxScale) { return true; - } else if (type == QTransform::TxScale) { - // Check for 0 and 180 degree rotations. - // (0 might happen after 4 rotations of 90 degrees). - qreal m11 = transform.m11(); - qreal m12 = transform.m12(); - qreal m21 = transform.m21(); - qreal m22 = transform.m22(); - if (m12 == 0.0f && m21 == 0.0f) { - if (m11 == 1.0f && m22 == 1.0f) - return true; // 0 degrees - else if (m11 == -1.0f && m22 == -1.0f) - return true; // 180 degrees. - if(m11 == 1.0f && m22 == -1.0f) - return true; // 0 degrees inverted y. - else if(m11 == -1.0f && m22 == 1.0f) - return true; // 180 degrees inverted y. - } } else if (type == QTransform::TxRotate) { // Check for 90, and 270 degree rotations. qreal m11 = transform.m11(); -- cgit v0.12 From a1acef227647b3043998f9ccf364ead5c29b882d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 18 Nov 2010 10:30:21 +0100 Subject: Remove QWidget::paintEngine() codepath for Lighthouse Reviewed-by: paul --- src/gui/painting/qbackingstore.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index df1210f..c051228 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -1620,7 +1620,11 @@ void QWidgetPrivate::repaint_sys(const QRegion &rgn) extra->staticContentsSize = data.crect.size(); } +#ifdef Q_WS_QPA //Dont even call q->p + QPaintEngine *engine = 0; +#else QPaintEngine *engine = q->paintEngine(); +#endif // QGLWidget does not support partial updates if: // 1) The context is double buffered // 2) The context is single buffered and auto-fill background is enabled. -- cgit v0.12 From 292f6a9ba1b5da049e4898525974c6f0575ccd65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 18 Nov 2010 13:03:59 +0100 Subject: Lighthouse: move the currentContext functionality to QPlatformGLContext This means the threading functionality has been delegated down to QPlatformGLContext. However, it is still possible to use QGLContext::currentContext to retrieve the QGLContext. This so that QGLFunctions, QGLShaderProgram etc can be used without a QGLWidget. Reviewed-by: paul --- src/gui/kernel/qplatformglcontext_qpa.cpp | 116 ++++++++++++++++++++- src/gui/kernel/qplatformglcontext_qpa.h | 23 +++- src/gui/kernel/qwidget_qpa.cpp | 12 +++ src/opengl/qgl.cpp | 24 +++++ src/opengl/qgl.h | 8 ++ src/opengl/qgl_qpa.cpp | 22 ++-- .../eglconvenience/qeglplatformcontext.cpp | 6 +- .../platforms/eglconvenience/qeglplatformcontext.h | 2 +- src/plugins/platforms/testlite/qglxintegration.cpp | 12 ++- src/plugins/platforms/testlite/qglxintegration.h | 4 +- src/plugins/platforms/testlite/qtestlitewindow.cpp | 2 +- 11 files changed, 205 insertions(+), 26 deletions(-) diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp index 36db2b0..5ed1d3d 100644 --- a/src/gui/kernel/qplatformglcontext_qpa.cpp +++ b/src/gui/kernel/qplatformglcontext_qpa.cpp @@ -41,17 +41,123 @@ #include "qplatformglcontext_qpa.h" +#include +#include + +#include + +class QPlatformGLThreadContext +{ +public: + ~QPlatformGLThreadContext() { + if (context) + context->doneCurrent(); + } + QPlatformGLContext *context; +}; + +static QThreadStorage qplatformgl_context_storage; + +class QPlatformGLContextPrivate +{ +public: + QPlatformGLContextPrivate(QPlatformWindow *platformWindow) + :qGLContextHandle(0),platformWindow(platformWindow) + { + } + + virtual ~QPlatformGLContextPrivate() + { + //do not delete the QGLContext handle here as it is deleted in + //QWidgetPrivate::deleteTLSysExtra() + } + void *qGLContextHandle; + void (*qGLContextDeleteFunction)(void *handle); + QPlatformWindow *platformWindow; + static QPlatformGLContext *staticSharedContext; + + static void setCurrentContext(QPlatformGLContext *context); +}; + +QPlatformGLContext *QPlatformGLContextPrivate::staticSharedContext = 0; + +void QPlatformGLContextPrivate::setCurrentContext(QPlatformGLContext *context) +{ + QPlatformGLThreadContext *threadContext = qplatformgl_context_storage.localData(); + if (!threadContext) { + if (!QThread::currentThread()) { + qWarning("No QTLS available. currentContext wont work"); + return; + } + threadContext = new QPlatformGLThreadContext; + qplatformgl_context_storage.setLocalData(threadContext); + } + threadContext->context = context; +} + +QPlatformWindow *QPlatformGLContext::platformWindow() const +{ + Q_D(const QPlatformGLContext); + return d->platformWindow; +} + +const QPlatformGLContext* QPlatformGLContext::currentContext() +{ + QPlatformGLThreadContext *threadContext = qplatformgl_context_storage.localData(); + if(threadContext) { + return threadContext->context; + } + return 0; +} + +QPlatformGLContext::QPlatformGLContext(QPlatformWindow *platformWindow) + :d_ptr(new QPlatformGLContextPrivate(platformWindow)) +{ +} + QPlatformGLContext::~QPlatformGLContext() -{ } +{ + if (QPlatformGLContext::currentContext() == this) { + doneCurrent(); + } -static QPlatformGLContext *staticSharedContext = 0; +} void QPlatformGLContext::setDefaultSharedContext(QPlatformGLContext *sharedContext) { - staticSharedContext = sharedContext; + QPlatformGLContextPrivate::staticSharedContext = sharedContext; +} + +const QPlatformGLContext *QPlatformGLContext::defaultSharedContext() +{ + return QPlatformGLContextPrivate::staticSharedContext; +} + +void QPlatformGLContext::makeCurrent() +{ + QPlatformGLContextPrivate::setCurrentContext(this); +} + +void QPlatformGLContext::doneCurrent() +{ + QPlatformGLContextPrivate::setCurrentContext(0); +} + +void *QPlatformGLContext::qGLContextHandle() const +{ + Q_D(const QPlatformGLContext); + return d->qGLContextHandle; +} + +void QPlatformGLContext::setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *)) +{ + Q_D(QPlatformGLContext); + d->qGLContextHandle = handle; + d->qGLContextDeleteFunction = qGLContextDeleteFunction; } -QPlatformGLContext *QPlatformGLContext::defaultSharedContext() +void QPlatformGLContext::deleteQGLContext() { - return staticSharedContext; + Q_D(QPlatformGLContext); + d->qGLContextDeleteFunction(d->qGLContextHandle); } diff --git a/src/gui/kernel/qplatformglcontext_qpa.h b/src/gui/kernel/qplatformglcontext_qpa.h index ed41723..3e10c2b 100644 --- a/src/gui/kernel/qplatformglcontext_qpa.h +++ b/src/gui/kernel/qplatformglcontext_qpa.h @@ -51,24 +51,41 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) +class QPlatformGLContextPrivate; + class Q_OPENGL_EXPORT QPlatformGLContext { +Q_DECLARE_PRIVATE(QPlatformGLContext); + public: + explicit QPlatformGLContext(QPlatformWindow *platformWindow); virtual ~QPlatformGLContext(); - virtual void makeCurrent() = 0; - virtual void doneCurrent() = 0; + virtual void makeCurrent(); + virtual void doneCurrent(); virtual void swapBuffers() = 0; virtual void* getProcAddress(const QString& procName) = 0; virtual QPlatformWindowFormat platformWindowFormat() const = 0; - static QPlatformGLContext *defaultSharedContext(); + QPlatformWindow *platformWindow() const; + + const static QPlatformGLContext *currentContext(); + const static QPlatformGLContext *defaultSharedContext(); protected: static void setDefaultSharedContext(QPlatformGLContext *sharedContext); + QScopedPointer d_ptr; +private: + //hack to make it work with QGLContext::CurrentContext + friend class QGLContext; + friend class QWidgetPrivate; + void *qGLContextHandle() const; + void setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *)); + void deleteQGLContext(); + Q_DISABLE_COPY(QPlatformGLContext); }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp index acb2615..aa6b3f8 100644 --- a/src/gui/kernel/qwidget_qpa.cpp +++ b/src/gui/kernel/qwidget_qpa.cpp @@ -48,6 +48,7 @@ #include "QtGui/private/qapplication_p.h" #include "QtGui/qdesktopwidget.h" #include "QtGui/qplatformwindow_qpa.h" +#include "QtGui/qplatformglcontext_qpa.h" #include @@ -99,6 +100,8 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO if (!surface && platformWindow && q->platformWindowFormat().hasWindowSurface()) { surface = QApplicationPrivate::platformIntegration()->createWindowSurface(q,platformWindow->winId()); + } else { + q->setAttribute(Qt::WA_PaintOnScreen,true); } data.window_flags = q->platformWindow()->setWindowFlags(data.window_flags); @@ -784,6 +787,15 @@ void QWidgetPrivate::createTLSysExtra() void QWidgetPrivate::deleteTLSysExtra() { if (extra && extra->topextra) { + if (extra->topextra->platformWindowFormat.windowApi() == QPlatformWindowFormat::OpenGL) { + //the toplevel might have a context with a "qglcontext assosiated with it. We need to + //delete the qglcontext before we delete the qplatformglcontext. + if (extra->topextra->platformWindow) { + if (QPlatformGLContext *context = extra->topextra->platformWindow->glContext()) { + context->deleteQGLContext(); + } + } + } delete extra->topextra->platformWindow; extra->topextra->platformWindow = 0; extra->topextra->backingStore.destroy(); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index cf45239..65d3bbe 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -79,6 +79,10 @@ #include #endif +#ifdef Q_WS_QPA +#include +#endif + #include #include @@ -117,7 +121,9 @@ struct QGLThreadContext { QGLContext *context; }; +#ifndef Q_WS_QPA static QThreadStorage qgl_context_storage; +#endif Q_GLOBAL_STATIC(QGLFormat, qgl_default_format) @@ -3381,14 +3387,31 @@ void QGLContext::setInitialized(bool on) const QGLContext* QGLContext::currentContext() { +#ifdef Q_WS_QPA + if (const QPlatformGLContext *threadContext = QPlatformGLContext::currentContext()) { + if (threadContext->qGLContextHandle()) { + return (const QGLContext *)threadContext->qGLContextHandle(); + } else { + QWidget *widget = threadContext->platformWindow()->widget(); + QGLContext *context = new QGLContext(QGLFormat::fromPlatformWindowFormat(threadContext->platformWindowFormat()),widget); + context->create(); //don't know how to pass in the sharecontext. (doesn't really matter though) + return context; + } + } + return 0; +#else QGLThreadContext *threadContext = qgl_context_storage.localData(); if (threadContext) return threadContext->context; return 0; +#endif //Q_WS_QPA } void QGLContextPrivate::setCurrentContext(QGLContext *context) { +#ifdef Q_WS_QPA + Q_UNUSED(context); +#else QGLThreadContext *threadContext = qgl_context_storage.localData(); if (!threadContext) { if (!QThread::currentThread()) { @@ -3401,6 +3424,7 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context) } threadContext->context = context; QGLContext::currentCtx = context; // XXX: backwards-compat, not thread-safe +#endif } /*! diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 4f10e5c..1f864a3 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -48,6 +48,10 @@ #include #include +#ifdef Q_WS_QPA +#include +#endif + QT_BEGIN_HEADER #if defined(Q_WS_WIN) @@ -270,6 +274,10 @@ public: static OpenGLVersionFlags openGLVersionFlags(); +#if defined(Q_WS_QPA) + static QGLFormat fromPlatformWindowFormat(const QPlatformWindowFormat &format); + static QPlatformWindowFormat toPlatformWindowFormat(const QGLFormat &format); +#endif private: QGLFormatPrivate *d; diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 1197013..28bea83 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE -static QGLFormat qt_platformwindowformat_to_glformat(const QPlatformWindowFormat &format) +QGLFormat QGLFormat::fromPlatformWindowFormat(const QPlatformWindowFormat &format) { QGLFormat retFormat; retFormat.setAccum(format.accum()); @@ -83,7 +83,7 @@ static QGLFormat qt_platformwindowformat_to_glformat(const QPlatformWindowFormat return retFormat; } -static QPlatformWindowFormat qt_glformat_to_platformwindowformat(const QGLFormat &format) +QPlatformWindowFormat QGLFormat::toPlatformWindowFormat(const QGLFormat &format) { QPlatformWindowFormat retFormat; retFormat.setAccum(format.accum()); @@ -120,6 +120,12 @@ bool QGLFormat::hasOpenGL() return QApplicationPrivate::platformIntegration()->hasOpenGL(); } +void qDeleteQGLContext(void *handle) +{ + QGLContext *context = static_cast(handle); + delete context; +} + bool QGLContext::chooseContext(const QGLContext* shareContext) { Q_D(QGLContext); @@ -129,7 +135,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) QWidget *widget = static_cast(d->paintDevice); if (!widget->platformWindow()){ QGLFormat glformat = format(); - QPlatformWindowFormat winFormat = qt_glformat_to_platformwindowformat(glformat); + QPlatformWindowFormat winFormat = QGLFormat::toPlatformWindowFormat(glformat); if (shareContext) { winFormat.setSharedContext(shareContext->d_func()->platformContext); } @@ -140,8 +146,11 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) } d->platformContext = widget->platformWindow()->glContext(); Q_ASSERT(d->platformContext); - d->glFormat = qt_platformwindowformat_to_glformat(d->platformContext->platformWindowFormat()); + d->glFormat = QGLFormat::fromPlatformWindowFormat(d->platformContext->platformWindowFormat()); d->valid =(bool) d->platformContext; + if (d->valid) { + d->platformContext->setQGLContextHandle(this,qDeleteQGLContext); + } } return d->valid; @@ -254,13 +263,13 @@ class QGLTemporaryContextPrivate { public: QWidget *widget; - QGLContext *context; + QPlatformGLContext *context; }; QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) : d(new QGLTemporaryContextPrivate) { - d->context = const_cast(QGLContext::currentContext()); + d->context = const_cast(QPlatformGLContext::currentContext()); if (d->context) d->context->doneCurrent(); d->widget = new QWidget; @@ -269,7 +278,6 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) format.setWindowApi(QPlatformWindowFormat::OpenGL); d->widget->winId(); - d->widget->platformWindow()->glContext()->makeCurrent(); } diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp index ae3b539..a169c35 100644 --- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp +++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp @@ -48,8 +48,8 @@ #include -QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi) - : QPlatformGLContext() +QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi, QPlatformWindow *platformWindow) + : QPlatformGLContext(platformWindow) , m_eglDisplay(display) , m_eglSurface(surface) , m_eglApi(eglApi) @@ -88,6 +88,7 @@ QEGLPlatformContext::~QEGLPlatformContext() void QEGLPlatformContext::makeCurrent() { + QPlatformGLContext::makeCurrent(); #ifdef QEGL_EXTRA_DEBUG qWarning("QEglContext::makeCurrent: %p\n",this); #endif @@ -117,6 +118,7 @@ void QEGLPlatformContext::makeCurrent() } void QEGLPlatformContext::doneCurrent() { + QPlatformGLContext::doneCurrent(); #ifdef QEGL_EXTRA_DEBUG qWarning("QEglContext::doneCurrent:%p\n",this); #endif diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h index ae1a891..2c38aca 100644 --- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h +++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h @@ -48,7 +48,7 @@ class QEGLPlatformContext : public QPlatformGLContext { public: - QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi); + QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi, QPlatformWindow *platformWindow); ~QEGLPlatformContext(); void makeCurrent(); diff --git a/src/plugins/platforms/testlite/qglxintegration.cpp b/src/plugins/platforms/testlite/qglxintegration.cpp index e262d5b..c35db9b 100644 --- a/src/plugins/platforms/testlite/qglxintegration.cpp +++ b/src/plugins/platforms/testlite/qglxintegration.cpp @@ -235,14 +235,14 @@ QPlatformWindowFormat QGLXGLContext::reducePlatformWindowFormat(const QPlatformW return retFormat; } -QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindowFormat &format) - : QPlatformGLContext() +QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *platformWindow, const QPlatformWindowFormat &format) + : QPlatformGLContext(platformWindow) , m_xd(xd) , m_drawable((Drawable)window) , m_context(0) { - QPlatformGLContext *sharePlatformContext; + const QPlatformGLContext *sharePlatformContext; if (format.useDefaultSharedContext()) { if (!QPlatformGLContext::defaultSharedContext()) { if (m_defaultSharedContextMutex.tryLock()){ @@ -259,7 +259,7 @@ QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindow } GLXContext shareGlxContext = 0; if (sharePlatformContext) - shareGlxContext = static_cast(sharePlatformContext)->glxContext(); + shareGlxContext = static_cast(sharePlatformContext)->glxContext(); GLXFBConfig config = findConfig(xd,format); m_context = glXCreateNewContext(xd->display,config,GLX_RGBA_TYPE,shareGlxContext,TRUE); @@ -271,7 +271,7 @@ QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindow } QGLXGLContext::QGLXGLContext(MyDisplay *display, Drawable drawable, GLXContext context) - : QPlatformGLContext(), m_xd(display), m_drawable(drawable), m_context(context) + : QPlatformGLContext(0), m_xd(display), m_drawable(drawable), m_context(context) { } @@ -313,6 +313,7 @@ void QGLXGLContext::createDefaultSharedContex(MyDisplay *xd) void QGLXGLContext::makeCurrent() { + QPlatformGLContext::makeCurrent(); #ifdef MYX11_DEBUG qDebug("QGLXGLContext::makeCurrent(window=0x%x, ctx=0x%x)", m_drawable, m_context); #endif @@ -321,6 +322,7 @@ void QGLXGLContext::makeCurrent() void QGLXGLContext::doneCurrent() { + QPlatformGLContext::doneCurrent(); glXMakeCurrent(m_xd->display, 0, 0); } diff --git a/src/plugins/platforms/testlite/qglxintegration.h b/src/plugins/platforms/testlite/qglxintegration.h index 479be4b..432dec5 100644 --- a/src/plugins/platforms/testlite/qglxintegration.h +++ b/src/plugins/platforms/testlite/qglxintegration.h @@ -58,7 +58,7 @@ class MyDisplay; class QGLXGLContext : public QPlatformGLContext { public: - QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindowFormat &format); + QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *platformWindow, const QPlatformWindowFormat &format); ~QGLXGLContext(); virtual void makeCurrent(); @@ -66,7 +66,7 @@ public: virtual void swapBuffers(); virtual void* getProcAddress(const QString& procName); - GLXContext glxContext() {return m_context;} + GLXContext glxContext() const {return m_context;} QPlatformWindowFormat platformWindowFormat() const; diff --git a/src/plugins/platforms/testlite/qtestlitewindow.cpp b/src/plugins/platforms/testlite/qtestlitewindow.cpp index 9f3c435..0a6e1ff 100644 --- a/src/plugins/platforms/testlite/qtestlitewindow.cpp +++ b/src/plugins/platforms/testlite/qtestlitewindow.cpp @@ -1021,7 +1021,7 @@ QPlatformGLContext *QTestLiteWindow::glContext() const if (!mGLContext) { QTestLiteWindow *that = const_cast(this); #ifndef QT_NO_OPENGL - that->mGLContext = new QGLXGLContext(x_window, xd, widget()->platformWindowFormat()); + that->mGLContext = new QGLXGLContext(x_window, xd, that,widget()->platformWindowFormat()); #endif } return mGLContext; -- cgit v0.12 From b24c0c77610c29442d538d4d33d6e0c53e88ae00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 19 Nov 2010 11:58:59 +0100 Subject: Adding some documentation for Lighthouse The spirit here is "something is better than nothing". Ie. its the first itteration of documenting the classes. No general Lighthouse introduction yet... --- src/gui/kernel/qplatformglcontext_qpa.cpp | 70 ++++++++++++++++ src/gui/kernel/qplatformintegration_qpa.cpp | 119 +++++++++++++++++++++++++++ src/gui/kernel/qplatformintegration_qpa.h | 2 +- src/gui/kernel/qplatformscreen_qpa.cpp | 48 +++++++++++ src/gui/kernel/qplatformscreen_qpa.h | 1 + src/gui/kernel/qplatformwindow_qpa.cpp | 89 +++++++++++++++++++- src/gui/kernel/qplatformwindow_qpa.h | 2 +- src/gui/kernel/qplatformwindowformat_qpa.cpp | 12 ++- src/gui/painting/qwindowsurface.cpp | 11 ++- src/gui/text/qplatformfontdatabase_qpa.cpp | 49 +++++++++++ 10 files changed, 393 insertions(+), 10 deletions(-) diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp index 5ed1d3d..a450b33 100644 --- a/src/gui/kernel/qplatformglcontext_qpa.cpp +++ b/src/gui/kernel/qplatformglcontext_qpa.cpp @@ -95,12 +95,18 @@ void QPlatformGLContextPrivate::setCurrentContext(QPlatformGLContext *context) threadContext->context = context; } +/*! + Returns the platformWindow which this QPlatformGLContext belongs to. +*/ QPlatformWindow *QPlatformGLContext::platformWindow() const { Q_D(const QPlatformGLContext); return d->platformWindow; } +/*! + Returns the last context which called makeCurrent. This function is thread aware. +*/ const QPlatformGLContext* QPlatformGLContext::currentContext() { QPlatformGLThreadContext *threadContext = qplatformgl_context_storage.localData(); @@ -110,11 +116,17 @@ const QPlatformGLContext* QPlatformGLContext::currentContext() return 0; } +/*! + All subclasses needs to specify the platformWindow. It can be a null window. +*/ QPlatformGLContext::QPlatformGLContext(QPlatformWindow *platformWindow) :d_ptr(new QPlatformGLContextPrivate(platformWindow)) { } +/*! + If this is the current context for the thread, doneCurrent is called +*/ QPlatformGLContext::~QPlatformGLContext() { if (QPlatformGLContext::currentContext() == this) { @@ -123,26 +135,45 @@ QPlatformGLContext::~QPlatformGLContext() } + +/*! + Makes it possible to set the context which can be the default for making new contexts. +*/ void QPlatformGLContext::setDefaultSharedContext(QPlatformGLContext *sharedContext) { QPlatformGLContextPrivate::staticSharedContext = sharedContext; } +/*! + Default shared context is intended to be a globally awailable pointer to a context which can + be used for sharing resources when creating new contexts. Its default value is 0; +*/ const QPlatformGLContext *QPlatformGLContext::defaultSharedContext() { return QPlatformGLContextPrivate::staticSharedContext; } +/*! + Reimplement in subclass to do makeCurrent on native GL context +*/ void QPlatformGLContext::makeCurrent() { QPlatformGLContextPrivate::setCurrentContext(this); } +/*! + Reimplement in subclass to release current context. + Typically this is calling makeCurrent with 0 "surface" +*/ void QPlatformGLContext::doneCurrent() { QPlatformGLContextPrivate::setCurrentContext(0); } +/* + internal: Needs to have a pointer to qGLContext. But since this is in QtGui we cant + have any type information. +*/ void *QPlatformGLContext::qGLContextHandle() const { Q_D(const QPlatformGLContext); @@ -161,3 +192,42 @@ void QPlatformGLContext::deleteQGLContext() Q_D(QPlatformGLContext); d->qGLContextDeleteFunction(d->qGLContextHandle); } + +/*! + \class QPlatformGLContext + \since 4.8 + \internal + \preliminary + \ingroup qpa + + \brief The QPlatformGLContext class provides an abstraction for native GL contexts. + + In QPA the way to support OpenGL or OpenVG or other technologies that requires a native GL + context is through the QPlatformGLContext wrapper. + + There is no factory function for QPlatformGLContexts, but rather only one accessor function. + The only place to retrieve a QPlatformGLContext from is through a QPlatformWindow. + + The context which is current for a specific thread can be collected by the currentContext() + function. This is how QPlatformGLContext also makes it possible to use the QtOpenGL module + withhout using QGLWidget. When using QGLContext::currentContext(), it will ask + QPlatformGLContext for the currentContext. Then a corresponding QGLContext will be returned, + which maps to the QPlatformGLContext. +*/ + +/*! \fn void swapBuffers() + Reimplement in subclass to native swap buffers calls +*/ + +/*! getProcAddress(const QString& procName) + Reimplement in subclass to native getProcAddr calls. + + Note: its convenient to use qPrintable(const QString &str) to get the const char * pointer +*/ + +/*! platformWindowFormat() const + QWidget has the function qplatformWindowFormat(). That function is for the application + programmer to request the format of the window and the context that he wants. + + Reimplement this function in a subclass to indicate what format the glContext actually has. +*/ diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp index e2a493d..2a9bf77 100644 --- a/src/gui/kernel/qplatformintegration_qpa.cpp +++ b/src/gui/kernel/qplatformintegration_qpa.cpp @@ -55,16 +55,35 @@ QPixmap QPlatformIntegration::grabWindow(WId window, int x, int y, int width, in return QPixmap(); } +/*! + Factory function for the eventloop integration interface. + + Default implementation returns 0, which causes the eventloop to run in a single thread mode. + + \sa QPlatformEventLoopIntegration +*/ QPlatformEventLoopIntegration *QPlatformIntegration::createEventLoopIntegration() const { return 0; } +/*! + Returns wheter the given platform integration supports OpenGL. + + Default implementation returns false, +*/ bool QPlatformIntegration::hasOpenGL() const { return false; } +/*! + Accessor for the platform integrations fontdatabase. + + Default implementation returns a default QPlatformFontDatabase. + + \sa QPlatformFontDatabase +*/ QPlatformFontDatabase *QPlatformIntegration::fontDatabase() const { static QPlatformFontDatabase *db = 0; @@ -74,4 +93,104 @@ QPlatformFontDatabase *QPlatformIntegration::fontDatabase() const return db; } +/*! + \class QPlatformIntegration + \since 4.8 + \internal + \preliminary + \ingroup qpa + \brief The QPlatformIntegration class is the entry for WindowSystem specific functionality. + + QPlatformIntegration is the single entry point for windowsystem specific functionality when + using the QPA platform. It has factory functions for creating platform specific pixmaps and + windows. The class also controlls the font subsystem. + + QPlatformIntegration is a singelton class which gets instansiated in the QApplication + constructor. The QPlatformIntegration instance do not have ownership of objects it creates in + functions where the name starts with create. However, functions which don't have a name + starting with create acts as assessors to member variables. + + It is not trivial to create or build a platform plugin outside of the Qt source tree. Therefor + the recommended approach for making new platform plugin is to copy an existing plugin inside + the QTSRCTREE/src/plugins/platform and develop the plugin inside the source tree. + + The minimal platformintegration is the smallest platform integration it is possible to make, + which makes it an ideal starting point for new plugins. For a slightly more advanced plugin, + consider reviewing the directfb plugin, or the testlite plugin. +*/ + +/*! + \fn QPixmapData *createPixmapData(QPixmapData::PixelType type) const + + Factory function for QPixmapData. PixelType can be either PixmapType or BitmapType. + \sa QPixmapData +*/ + +/*! + \fn QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const + + Factory function for QPlatformWindow. The widget parameter is a pointer to the top level + widget(tlw) which the QPlatformWindow is suppose to be created for. The WId handle is actually + never used, but there for future reference. Its purpose is if it is going to be possible to + create QPlatformWindows on existing WId. + + All tlw has to have a QPlatformWindow, and it will be created when the QPlatformWindow is set + to be visible for the first time. If the tlw's window flags are changed, or if the tlw's + QPlatformWindowFormat is changed, then the tlw's QPlatformWindow is deleted and a new one is + created. + + \sa QPlatformWindow, QPlatformWindowFormat + \sa createWindowSurface(QWidget *widget, WId winId) const +*/ + +/*! + \fn QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const + + Factory function for QWindowSurface. The QWidget parameter is a pointer to the + top level widget(tlw) the window surface is created for. A QPlatformWindow is allways created + before the QWindowSurface for tlw where the widget also requires a WindowSurface. It is + possible to create top level QWidgets without a QWindowSurface by specifying + QPlatformWindowFormat::setWindowSurface(false) for the tlw QPlatformWindowFormat. + + \sa QWindowSurface + \sa createPlatformWindow(QWidget *widget, WId winId = 0) const +*/ + +/*! + \fn void moveToScreen(QWidget *window, int screen) + + This function is called when a QWidget is displayed on screen, or the QWidget is to be + displayed on a new screen. The QWidget parameter is a pointer to the top level widget and + the int parameter is the index to the screen in QList screens() const. + + Default implementation does nothing. + + \sa screens() const +*/ + +/*! + \fn QList screens() const + + Accessor function to a list of all the screens on the current system. The screen with the + index == 0 is the default/main screen. +*/ + +/*! + \fn bool isVirtualDesktop() + + Returns if the current windowing system configuration defines all the screens to be one + desktop(virtual desktop), or if each screen is a desktop of its own. + + Default implementation returns false. +*/ + +/*! + \fn QPixmap grabWindow(WId window, int x, int y, int width, int height) const + + This function is called when Qt needs to be able to grab the content of a window. + + Returnes the content of the window specified with the WId handle within the boundaries of + QRect(x,y,width,height). +*/ + QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformintegration_qpa.h b/src/gui/kernel/qplatformintegration_qpa.h index b1f4e5f..f01b4f4 100644 --- a/src/gui/kernel/qplatformintegration_qpa.h +++ b/src/gui/kernel/qplatformintegration_qpa.h @@ -69,10 +69,10 @@ public: virtual QPixmapData *createPixmapData(QPixmapData::PixelType type) const = 0; virtual QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const = 0; virtual QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const = 0; - virtual void moveToScreen(QWidget *window, int screen) {Q_UNUSED(window); Q_UNUSED(screen);} // Window System functions virtual QList screens() const = 0; + virtual void moveToScreen(QWidget *window, int screen) {Q_UNUSED(window); Q_UNUSED(screen);} virtual bool isVirtualDesktop() { return false; } virtual QPixmap grabWindow(WId window, int x, int y, int width, int height) const; diff --git a/src/gui/kernel/qplatformscreen_qpa.cpp b/src/gui/kernel/qplatformscreen_qpa.cpp index 478d2d6..5e80ba8 100644 --- a/src/gui/kernel/qplatformscreen_qpa.cpp +++ b/src/gui/kernel/qplatformscreen_qpa.cpp @@ -43,6 +43,12 @@ #include #include +/*! + Return the given top level widget for a given position. + + Default implementation retrieves a list of all top level widgets and finds the first widget + which contains point \a pos +*/ QWidget *QPlatformScreen::topLevelAt(const QPoint & pos) const { QWidgetList list = QApplication::topLevelWidgets(); @@ -56,6 +62,13 @@ QWidget *QPlatformScreen::topLevelAt(const QPoint & pos) const return 0; } +/*! \fn physicalSize() const + Reimplement in subclass to return the physical size of the screen. This function is used by + QFont to convert point sizes to pixel sizes. + + Default implementation takes the pixel size of the screen, considers a dpi of 100 and returns + the calculated (and probably wrong) physical size +*/ QSize QPlatformScreen::physicalSize() const { static const int dpi = 100; @@ -64,3 +77,38 @@ QSize QPlatformScreen::physicalSize() const return QSize(width,height); } +/*! + \class QPlatformScreen + \since 4.8 + \internal + \preliminary + \ingroup qpa + + \brief The QPlatformScreen class provides an abstraction for visual displays. + + Many window systems has support for retrieving information on the attached displays. To be able + to query the display QPA uses QPlatformScreen. Qt its self is most dependent on the + physicalSize() function, since this is the function it uses to calculate the dpi to use when + converting point sizes to pixels sizes. However, this is unfortunate on some systems, as the + native system fakes its dpi size. + + QPlatformScreen is also used by the public api QDesktopWidget for information about the desktop. + */ + +/*! \fn geometry() const + Reimplement in subclass to return the pixel geometry of the screen +*/ + +/*! \fn availableGeometry() const + Reimplement in subclass to return the pixel geometry of the available space + This normally is the desktop screen minus the task manager, global menubar etc. +*/ + +/*! \fn depth() const + Reimplement in subclass to return current depth of the screen +*/ + +/*! \fn format() const + Reimplement in subclass to return the image format which corresponds to the screen format +*/ + diff --git a/src/gui/kernel/qplatformscreen_qpa.h b/src/gui/kernel/qplatformscreen_qpa.h index 1704f0f..9080489 100644 --- a/src/gui/kernel/qplatformscreen_qpa.h +++ b/src/gui/kernel/qplatformscreen_qpa.h @@ -70,6 +70,7 @@ public: virtual int depth() const = 0; virtual QImage::Format format() const = 0; virtual QSize physicalSize() const; + //jl: should setDirty be removed. virtual void setDirty(const QRect &) {} virtual QWidget *topLevelAt(const QPoint &point) const; }; diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp index 9d722d8..378fc68 100644 --- a/src/gui/kernel/qplatformwindow_qpa.cpp +++ b/src/gui/kernel/qplatformwindow_qpa.cpp @@ -51,6 +51,10 @@ class QPlatformWindowPrivate friend class QPlatformWindow; }; +/*! + Constructs a platform window with the given top level widget. +*/ + QPlatformWindow::QPlatformWindow(QWidget *tlw) : d_ptr(new QPlatformWindowPrivate) { @@ -59,22 +63,37 @@ QPlatformWindow::QPlatformWindow(QWidget *tlw) tlw->setPlatformWindow(this); } +/*! + Virtual destructor does not delete its top level widget. +*/ QPlatformWindow::~QPlatformWindow() { } +/*! + Returnes the widget which belongs to the QPlatformWindow +*/ QWidget *QPlatformWindow::widget() const { Q_D(const QPlatformWindow); return d->tlw; } +/*! + This function is called by Qt whenever a window is moved or the window is resized. The resize + can happen programatically(from ie. user application) or by the window manager. This means that + there is no need to call this function specifically from the window manager callback, instead + call QWindowSystemInterface::handleGeometryChange(QWidget *w, const QRect &newRect); +*/ void QPlatformWindow::setGeometry(const QRect &rect) { Q_D(QPlatformWindow); d->rect = rect; } +/*! + Returnes the current geometry of a window +*/ QRect QPlatformWindow::geometry() const { Q_D(const QPlatformWindow); @@ -82,14 +101,16 @@ QRect QPlatformWindow::geometry() const } /*! -Reimplemented in subclasses to show the surface if \a visible is \c true, and hide it if \a visible is \c false. + Reimplemented in subclasses to show the surface + if \a visible is \c true, and hide it if \a visible is \c false. */ void QPlatformWindow::setVisible(bool visible) { Q_UNUSED(visible); } /*! -Requests setting the window flags of this surface to \a type. Returns the actual flags set. + Requests setting the window flags of this surface + to \a type. Returns the actual flags set. */ Qt::WindowFlags QPlatformWindow::setWindowFlags(Qt::WindowFlags flags) { @@ -107,23 +128,83 @@ Qt::WindowFlags QPlatformWindow::windowFlags() const return d->flags; } +/*! + Reimplement in subclasses to return a handle to the native window +*/ WId QPlatformWindow::winId() const { return WId(0); } -void QPlatformWindow::setParent(const QPlatformWindow *) { qWarning("This plugin does not support setParent!"); } +/*! + This function is called to enable native child widgets in QPA. It is common not to support this + feature in Window systems, but can be faked. When this function is called all geometry of this + platform window will be relative to the parent. +*/ +//jl: It would be usefull to have a property on the platform window which indicated if the sub-class +// supported the setParent. If not, then geometry would be in screen coordinates. +void QPlatformWindow::setParent(const QPlatformWindow *parent) +{ + Q_UNUSED(parent); + qWarning("This plugin does not support setParent!"); +} -void QPlatformWindow::setWindowTitle(const QString &) {} +/*! + Reimplement to set the window title to \a title +*/ +void QPlatformWindow::setWindowTitle(const QString &title) {} +/*! + Reimplement to be able to let Qt rais windows to the top of the desktop +*/ void QPlatformWindow::raise() { qWarning("This plugin does not support raise()"); } +/*! + Reimplement to be able to let Qt lower winows to the bottom of the dekstop +*/ void QPlatformWindow::lower() { qWarning("This plugin does not support lower()"); } +/*! + Reimplement to be able to let Qt set the opacity level of a window +*/ void QPlatformWindow::setOpacity(qreal level) { Q_UNUSED(level); qWarning("This plugin does not support setting window opacity"); } +/*! + Reimplement to return the glContext assosiated with the window. +*/ QPlatformGLContext *QPlatformWindow::glContext() const { return 0; } + +/*! + \class QPlatformWindow + \since 4.8 + \internal + \preliminary + \ingroup qpa + + \brief The QPlatformWindow class provides an abstraction for top-level windows. + + The QPlatformWindow abstraction is used by QWidget for all its top level widgets. It is being + created by calling the createPlatformWindow function in the loaded QPlatformIntegration + instance. + + QPlatformWindow is used to signal to the windowing system, how Qt persieves its frame. + However, it is not concerned with how Qt renders into the window it represents. + + Top level QWidgets(tlw) will allways have a QPlatformWindow. However, it is not neccesary for + all tlw to have a QWindowSurface. This is the case for QGLWidget. And could be the case for + widgets where some 3.party renders into it. + + The platform specific window handle can be retrieved by the winId function. + + QPlatformWindow is also the way QPA defines how native child windows should be supported + through the setParent function. + + The only way to retrieve a QPlatformGLContext in QPA is by calling the glContext() function + on QPlatformWindow. + + \sa QWindowSurface, QWidget +*/ diff --git a/src/gui/kernel/qplatformwindow_qpa.h b/src/gui/kernel/qplatformwindow_qpa.h index 6dfba05..90bc1cb 100644 --- a/src/gui/kernel/qplatformwindow_qpa.h +++ b/src/gui/kernel/qplatformwindow_qpa.h @@ -75,7 +75,7 @@ public: virtual WId winId() const; virtual void setParent(const QPlatformWindow *window); - virtual void setWindowTitle(const QString &); + virtual void setWindowTitle(const QString &title); virtual void raise(); virtual void lower(); diff --git a/src/gui/kernel/qplatformwindowformat_qpa.cpp b/src/gui/kernel/qplatformwindowformat_qpa.cpp index f0dad17..ade6bb3 100644 --- a/src/gui/kernel/qplatformwindowformat_qpa.cpp +++ b/src/gui/kernel/qplatformwindowformat_qpa.cpp @@ -102,9 +102,15 @@ public: /*! \class QPlatformWindowFormat \brief The QPlatformWindowFormat class specifies the display format of an OpenGL - rendering context. + rendering context and if possible attributes of the corresponding QPlatformWindow. - \ingroup painting-3D + \ingroup painting + + QWidget has a setter and getter function for QPlatformWindowFormat. These functions can be used + by the application programmer to signal what kind of format he wants to the window and glcontext + should have. However, it is not allways possible to furfill these requirements. The application + programmer should therefor check the resulting QPlatformWindowFormat from QPlatformGLContext + to see the format that was actually created. A display format has several characteristics: \list @@ -162,7 +168,7 @@ public: United States and other countries. \endlegalese - \sa QGLContext, QGLWidget + \sa QPlatformContext, QWidget */ /*! diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp index e9eb9c5..3ee8281 100644 --- a/src/gui/painting/qwindowsurface.cpp +++ b/src/gui/painting/qwindowsurface.cpp @@ -74,7 +74,7 @@ public: \since 4.3 \internal \preliminary - \ingroup qws + \ingroup qws qpa \brief The QWindowSurface class provides the drawing area for top-level windows. @@ -179,11 +179,20 @@ QRect QWindowSurface::geometry() const return d_ptr->geometry; } #else + +/*! + Sets the size of the windowsurface to be \a size. + + \sa size() +*/ void QWindowSurface::resize(const QSize &size) { d_ptr->size = size; } +/*! + Returns the current size of the windowsurface. +*/ QSize QWindowSurface::size() const { return d_ptr->size; diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp index 7a89fe4..d6dff41 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.cpp +++ b/src/gui/text/qplatformfontdatabase_qpa.cpp @@ -165,6 +165,23 @@ bool QSupportedWritingSystems::supported(QFontDatabase::WritingSystem writingSys return d->vector.at(writingSystem); } +/*! + \class QSupportedWritingSystems + \brief The QSupportedWritingSystems class is used when registering fonts with the internal Qt + fontdatabase + \ingroup painting + + Its to provide an easy to use interface for indicating what writing systems a specific font + supports. + +*/ + +/*! + This function is called once at startup by Qts internal fontdatabase. Reimplement this function + in a subclass for a convenient place to initialise the internal fontdatabase. + + The default implementation looks in the fontDir() location and registers all qpf2 fonts. +*/ void QPlatformFontDatabase::populateFontDatabase() { QString fontpath = fontDir(); @@ -188,6 +205,9 @@ void QPlatformFontDatabase::populateFontDatabase() } } +/*! + +*/ QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle) { Q_UNUSED(script); @@ -198,6 +218,9 @@ QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicode return engine; } +/*! + +*/ QStringList QPlatformFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QUnicodeTables::Script &script) const { Q_UNUSED(family); @@ -219,12 +242,18 @@ QStringList QPlatformFontDatabase::addApplicationFont(const QByteArray &fontData return QStringList(); } +/*! + +*/ void QPlatformFontDatabase::releaseHandle(void *handle) { QByteArray *fileDataPtr = static_cast(handle); delete fileDataPtr; } +/*! + +*/ QString QPlatformFontDatabase::fontDir() const { QString fontpath = QString::fromLocal8Bit(qgetenv("QT_QPA_FONTDIR")); @@ -238,4 +267,24 @@ QString QPlatformFontDatabase::fontDir() const return fontpath; } +/*! + \class QPlatformFontDatabase + \brief The QPlatformFontDatabase makes it possible to customize how fonts are picked up, and + and how they are rendered + + \ingroup painting + + QPlatformFontDatabase is the superclass which is intended to let platform implementations use + native font handling. + + Qt has its internal fontdatabase which it uses to pick up available fonts. To be able + to populate this database subclass this class, and reimplement populateFontDatabase(). + + Use the function registerFont to populate the internal fontdatabase. + + Sometimes a specified font does not have the required glyphs, then the fallbackForFamily + function is called. + + \sa QSupportedWritingSystems +*/ QT_END_NAMESPACE -- cgit v0.12 From 96acd93d741cd735f8c4bdaf6fdcf073192b1562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 17 Nov 2010 18:20:26 +0100 Subject: QFileSystemEngine: clean up unused code resolveUser/GroupName(id) only make sense on Unix platforms, there's no point in replicating them elsewhere. bundleName is a Mac-only feature, so we can otherwise merge the default implementation for other platforms. Reviewed-by: Shane Kearns --- src/corelib/io/qfilesystemengine_p.h | 9 ++++++++- src/corelib/io/qfilesystemengine_symbian.cpp | 21 --------------------- src/corelib/io/qfilesystemengine_unix.cpp | 6 ++---- src/corelib/io/qfilesystemengine_win.cpp | 19 ------------------- 4 files changed, 10 insertions(+), 45 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 1f4aad0..63d2a91 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -69,11 +69,18 @@ public: static QFileSystemEntry canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data); static QFileSystemEntry absoluteName(const QFileSystemEntry &entry); static QString resolveUserName(const QFileSystemEntry &entry, QFileSystemMetaData &data); - static QString resolveUserName(uint userId); static QString resolveGroupName(const QFileSystemEntry &entry, QFileSystemMetaData &data); + +#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) + static QString resolveUserName(uint userId); static QString resolveGroupName(uint groupId); +#endif +#if !defined(QWS) && defined(Q_OS_MAC) static QString bundleName(const QFileSystemEntry &entry); +#else + static QString bundleName(const QFileSystemEntry &entry) { Q_UNUSED(entry) return QString(); } +#endif static bool fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what); diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index c4e8d36..3659a39 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -151,27 +151,6 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) return QFileSystemEntry(symbianCleanAbsolutePath(result), QFileSystemEntry::FromInternalPath()); } -//static -QString QFileSystemEngine::resolveUserName(uint userId) -{ - Q_UNUSED(userId) - return QString(); // no users or groups on symbian -} - -//static -QString QFileSystemEngine::resolveGroupName(uint groupId) -{ - Q_UNUSED(groupId) - return QString(); // no users or groups on symbian -} - -//static -QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) -{ - Q_UNUSED(entry); - return QString(); -} - void QFileSystemMetaData::fillFromTEntry(const TEntry& entry) { entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags); diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index dc6888d..329da08 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -333,10 +333,10 @@ QString QFileSystemEngine::resolveGroupName(uint groupId) return QString(); } +#if !defined(QWS) && defined(Q_OS_MAC) //static QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) { -#if !defined(QWS) && defined(Q_OS_MAC) QCFType url = CFURLCreateWithFileSystemPath(0, QCFString(entry.filePath()), kCFURLPOSIXPathStyle, true); if (QCFType dict = CFBundleCopyInfoDictionaryForURL(url)) { @@ -345,11 +345,9 @@ QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) return QCFString::toQString((CFStringRef)name); } } -#else - Q_UNUSED(entry); -#endif return QString(); } +#endif //static bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 8fa4d62..b2afe90 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -529,25 +529,6 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) } //static -QString QFileSystemEngine::resolveUserName(uint userId) -{ - return QString(); // TODO -} - -//static -QString QFileSystemEngine::resolveGroupName(uint groupId) -{ - return QString(); // TODO -} - -//static -QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) -{ - Q_UNUSED(entry); - return QString(); -} - -//static QString QFileSystemEngine::owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own) { QString name; -- cgit v0.12 From ee1f78b08521955342b2ce0f1244c7406bfd3124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 17 Nov 2010 18:28:11 +0100 Subject: QFileSystemEngine: remove symbian code from Unix-specific implementation Symbian is not serviced by this code, anyway. So it's just dead code. Reviewed-by: Shane Kearns --- src/corelib/io/qfilesystemengine_unix.cpp | 51 ------------------------------- 1 file changed, 51 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 329da08..815ff42 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -52,12 +52,6 @@ #include #include -#if defined(Q_OS_SYMBIAN) -# include -# include -# include -# include -#endif #if defined(Q_OS_MAC) # include @@ -65,24 +59,6 @@ QT_BEGIN_NAMESPACE -#if defined(Q_OS_SYMBIAN) -static bool _q_isSymbianHidden(const QFileSystemEntry &entry, bool isDir) -{ - RFs rfs = qt_s60GetRFs(); - - QFileSystemEntry absoluteEntry = QFileSystemEngine::absoluteName(entry); - QString absolutePath = absoluteEntry.filePath(); - - if (isDir && !absolutePath.endsWith(QLatin1Char('/'))) - absolutePath.append(QLatin1Char('/')); - - TPtrC ptr(qt_QString2TPtrC(absolutePath)); - TUint attributes; - TInt err = rfs.Att(ptr, attributes); - return (err == KErrNone && (attributes & KEntryAttHidden)); -} -#endif - #if !defined(QWS) && defined(Q_OS_MAC) static inline bool _q_isMacHidden(const char *nativePath) { @@ -113,11 +89,7 @@ static inline bool _q_isMacHidden(const char *nativePath) bool QFileSystemEngine::isCaseSensitive() { -#if defined(Q_OS_SYMBIAN) - return false; -#else return true; -#endif } //static @@ -306,7 +278,6 @@ QString QFileSystemEngine::resolveGroupName(uint groupId) QVarLengthArray buf(size_max); #endif -#if !defined(Q_OS_SYMBIAN) struct group *gr = 0; #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) size_max = sysconf(_SC_GETGR_R_SIZE_MAX); @@ -329,7 +300,6 @@ QString QFileSystemEngine::resolveGroupName(uint groupId) #endif if (gr) return QFile::decodeName(QByteArray(gr->gr_name)); -#endif return QString(); } @@ -360,13 +330,6 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM } #endif -#if defined(Q_OS_SYMBIAN) - if (what & QFileSystemMetaData::HiddenAttribute) { - if (!data.hasFlags(QFileSystemMetaData::LinkType | QFileSystemMetaData::DirectoryType)) - what |= QFileSystemMetaData::LinkType | QFileSystemMetaData::DirectoryType; - } -#endif - #if !defined(QWS) && defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 if (what & QFileSystemMetaData::HiddenAttribute) { // Mac OS >= 10.5: st_flags & UF_HIDDEN @@ -471,18 +434,10 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM if (what & QFileSystemMetaData::HiddenAttribute && !data.isHidden()) { -#if defined(Q_OS_SYMBIAN) - // In Symbian, all symlinks have hidden attribute for some reason; - // lets make them visible for better compatibility with other platforms. - // If somebody actually wants a hidden link, then they are out of luck. - if (entryExists && !data.isLink() && _q_isSymbianHidden(entry, data.isDirectory())) - data.entryFlags |= QFileSystemMetaData::HiddenAttribute; -#else QString fileName = entry.fileName(); if ((fileName.size() > 0 && fileName.at(0) == QLatin1Char('.')) || (entryExists && _q_isMacHidden(nativeFilePath))) data.entryFlags |= QFileSystemMetaData::HiddenAttribute; -#endif data.knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; } @@ -513,9 +468,6 @@ bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea QString dirName = entry.filePath(); if (createParents) { dirName = QDir::cleanPath(dirName); -#if defined(Q_OS_SYMBIAN) - dirName = QDir::toNativeSeparators(dirName); -#endif for (int oldslash = -1, slash=0; slash != -1; oldslash = slash) { slash = dirName.indexOf(QDir::separator(), oldslash+1); if (slash == -1) { @@ -548,9 +500,6 @@ bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool remo { if (removeEmptyParents) { QString dirName = QDir::cleanPath(entry.filePath()); -#if defined(Q_OS_SYMBIAN) - dirName = QDir::toNativeSeparators(dirName); -#endif for (int oldslash = 0, slash=dirName.length(); slash > 0; oldslash = slash) { QByteArray chunk = QFile::encodeName(dirName.left(slash)); QT_STATBUF st; -- cgit v0.12 From 901fee7e610ec53f744416aeeca89c4605923120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 22 Nov 2010 18:40:05 +0100 Subject: Fix QFile autotest for out-of-source builds --- tests/auto/qfile/tst_qfile.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index f60ab1e..dbd4302 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -1296,8 +1296,8 @@ void tst_QFile::link() QSKIP("Symbian does not support links", SkipAll); #endif QFile::remove("myLink.lnk"); - QFileInfo info1("tst_qfile.cpp"); - QVERIFY(QFile::link("tst_qfile.cpp", "myLink.lnk")); + QFileInfo info1(SRCDIR "tst_qfile.cpp"); + QVERIFY(QFile::link(SRCDIR "tst_qfile.cpp", "myLink.lnk")); QFileInfo info2("myLink.lnk"); QVERIFY(info2.isSymLink()); QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath()); -- cgit v0.12 From f309a20b4177572282082b8c17ec9025b75a69b1 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 23 Nov 2010 07:38:08 +0100 Subject: Make EglFS plugin compile after changes to QPlatformEGLContext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Jørgen Lind --- src/plugins/platforms/eglfs/qeglfsscreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index 9a40b86..b9d1b17 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -189,7 +189,7 @@ QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display) attribList[temp++] = 2; // GLES version 2 attribList[temp++] = EGL_NONE; - m_platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API); + m_platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API, 0); // qWarning("Created platformcontext"); EGLint w,h; -- cgit v0.12 From c8aa3d037ead9a7d1d62dc9ba454de8ff7eae9c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 23 Nov 2010 12:32:30 +0100 Subject: Adding #ifdefs/#defines lost in the merge to master The file-engine-refactor moved a lot of code around. So simple merge conflict resolution didn't cut it to finish the merge. Lighthouse on OS X adds Q_WS_QPA, where we were already using QWS. Also introduced QT_NO_CORESERVICES. --- src/corelib/io/qfilesystemengine.cpp | 3 ++- src/corelib/io/qfilesystemengine_p.h | 2 +- src/corelib/io/qfilesystemengine_unix.cpp | 17 +++++++++-------- src/corelib/io/qfilesystemengine_win.cpp | 8 ++++++++ src/corelib/io/qfilesystemmetadata_p.h | 4 ++-- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index fe0bad7..1e5914b 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -266,7 +266,8 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) // Attributes entryFlags |= QFileSystemMetaData::ExistsAttribute; size_ = statBuffer.st_size; -#if !defined(QWS) && defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +#if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) \ + && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 if (statBuffer.st_flags & UF_HIDDEN) { entryFlags |= QFileSystemMetaData::HiddenAttribute; knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 63d2a91..a3ec0ab 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -76,7 +76,7 @@ public: static QString resolveGroupName(uint groupId); #endif -#if !defined(QWS) && defined(Q_OS_MAC) +#if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) static QString bundleName(const QFileSystemEntry &entry); #else static QString bundleName(const QFileSystemEntry &entry) { Q_UNUSED(entry) return QString(); } diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 815ff42..40fb0c0 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE -#if !defined(QWS) && defined(Q_OS_MAC) +#if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) static inline bool _q_isMacHidden(const char *nativePath) { OSErr err; @@ -148,7 +148,7 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, ret.chop(1); return QFileSystemEntry(ret); } -#if !defined(QWS) && defined(Q_OS_MAC) +#if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) { FSRef fref; if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(link.filePath())).data(), &fref, 0) == noErr) { @@ -178,7 +178,7 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, return QFileSystemEntry::slowCanonicalName(entry); #else char *ret = 0; -# if defined(Q_OS_MAC) +# if defined(Q_OS_MAC) && !defined(QT_NO_CORESERVICES) // Mac OS X 10.5.x doesn't support the realpath(X,0) extension we use here. if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) { ret = realpath(entry.nativeFilePath().constData(), (char*)0); @@ -303,7 +303,7 @@ QString QFileSystemEngine::resolveGroupName(uint groupId) return QString(); } -#if !defined(QWS) && defined(Q_OS_MAC) +#if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) //static QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) { @@ -323,14 +323,15 @@ QString QFileSystemEngine::bundleName(const QFileSystemEntry &entry) bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) { -#if !defined(QWS) && defined(Q_OS_MAC) +#if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) if (what & QFileSystemMetaData::BundleType) { if (!data.hasFlags(QFileSystemMetaData::DirectoryType)) what |= QFileSystemMetaData::DirectoryType; } #endif -#if !defined(QWS) && defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +#if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) \ + && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 if (what & QFileSystemMetaData::HiddenAttribute) { // Mac OS >= 10.5: st_flags & UF_HIDDEN what |= QFileSystemMetaData::PosixStatFlags; @@ -395,7 +396,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM | QFileSystemMetaData::ExistsAttribute; } -#if !defined(QWS) && defined(Q_OS_MAC) +#if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) if (what & QFileSystemMetaData::AliasType) { if (entryExists) { @@ -441,7 +442,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM data.knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; } -#if !defined(QWS) && defined(Q_OS_MAC) +#if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) if (what & QFileSystemMetaData::BundleType) { if (entryExists && data.isDirectory()) { QCFType path = CFStringCreateWithBytes(0, diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index b2afe90..621b631 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -71,6 +71,14 @@ #define SECURITY_WIN32 #include +#ifndef SPI_GETPLATFORMTYPE +#define SPI_GETPLATFORMTYPE 257 +#endif + +#ifndef PATH_MAX +#define PATH_MAX FILENAME_MAX +#endif + #ifndef _INTPTR_T_DEFINED #ifdef _WIN64 typedef __int64 intptr_t; diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 24dfe6b..860b887 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -104,7 +104,7 @@ public: #endif FileType = 0x00020000, DirectoryType = 0x00040000, -#if !defined(QWS) && defined(Q_OS_MAC) +#if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) BundleType = 0x00080000, AliasType = 0x08000000, #else @@ -264,7 +264,7 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(QFileSystemMetaData::MetaDataFlags) -#if !defined(QWS) && defined(Q_OS_MAC) +#if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) inline bool QFileSystemMetaData::isBundle() const { return (entryFlags & BundleType); } inline bool QFileSystemMetaData::isAlias() const { return (entryFlags & AliasType); } #else -- cgit v0.12 From 88dd7568fff419510a7c26ffb93d93cc276d7b3b Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 23 Nov 2010 15:31:12 +0100 Subject: Fix filtering of columns in QSFPM. Fixes a crash introduced in 315c09c3873f7c5d8b785443372bf975bae47ee7 Reviewed-by: Gabriel de Dietrich Reviewed-by: Olivier --- src/gui/itemviews/qsortfilterproxymodel.cpp | 4 +-- .../qsortfilterproxymodel.pro | 5 +-- .../tst_qsortfilterproxymodel.cpp | 39 ++++++++++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index dc8d938..0d9819e 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -782,14 +782,14 @@ void QSortFilterProxyModelPrivate::source_items_inserted( if (orthogonal_source_to_proxy.isEmpty()) { const int ortho_end = (orient == Qt::Horizontal) ? model->rowCount(source_parent) : model->columnCount(source_parent); + orthogonal_source_to_proxy.resize(ortho_end); + for (int ortho_item = 0; ortho_item < ortho_end; ++ortho_item) { if ((orient == Qt::Horizontal) ? q->filterAcceptsRow(ortho_item, source_parent) : q->filterAcceptsColumn(ortho_item, source_parent)) { orthogonal_proxy_to_source.append(ortho_item); } } - orthogonal_source_to_proxy.resize(orthogonal_proxy_to_source.size()); - if (orient == Qt::Horizontal) { // We're reacting to columnsInserted, but we've just inserted new rows. Sort them. sort_source_rows(orthogonal_proxy_to_source, source_parent); diff --git a/tests/auto/qsortfilterproxymodel/qsortfilterproxymodel.pro b/tests/auto/qsortfilterproxymodel/qsortfilterproxymodel.pro index d2c1147..7edd4a5 100644 --- a/tests/auto/qsortfilterproxymodel/qsortfilterproxymodel.pro +++ b/tests/auto/qsortfilterproxymodel/qsortfilterproxymodel.pro @@ -1,6 +1,7 @@ load(qttest_p4) -SOURCES += tst_qsortfilterproxymodel.cpp - +INCLUDEPATH += $$PWD/../modeltest +SOURCES += tst_qsortfilterproxymodel.cpp ../modeltest/dynamictreemodel.cpp ../modeltest/modeltest.cpp +HEADERS += ../modeltest/dynamictreemodel.h ../modeltest/modeltest.h diff --git a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 66caf4a..93b9d30 100644 --- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -43,6 +43,9 @@ #include #include "../../shared/util.h" +#include "dynamictreemodel.h" +#include "modeltest.h" + #include #include @@ -144,6 +147,7 @@ private slots: void testMultipleProxiesWithSelection(); void mapSelectionFromSource(); + void filteredColumns(); protected: void buildHierarchy(const QStringList &data, QAbstractItemModel *model); @@ -3174,5 +3178,40 @@ void tst_QSortFilterProxyModel::taskQTBUG_10287_unnecessaryMapCreation() // No assert failure, it passes. } +class FilteredColumnProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + FilteredColumnProxyModel(QObject *parent = 0) + : QSortFilterProxyModel(parent) + { + + } + +protected: + bool filterAcceptsColumn(int column, const QModelIndex &source_parent) const + { + return column % 2 != 0; + } +}; + +void tst_QSortFilterProxyModel::filteredColumns() +{ + DynamicTreeModel *model = new DynamicTreeModel(this); + + FilteredColumnProxyModel *proxy = new FilteredColumnProxyModel(this); + proxy->setSourceModel(model); + + new ModelTest(proxy, this); + + ModelInsertCommand *insertCommand = new ModelInsertCommand(model, this); + insertCommand->setNumCols(2); + insertCommand->setStartRow(0); + insertCommand->setEndRow(0); + // Parent is QModelIndex() + insertCommand->doCommand(); + +} + QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" -- cgit v0.12 From ad1e82323225e996720136e8b2d669166b8d8441 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 17 Nov 2010 18:33:22 +0100 Subject: QNetworkAccessManager: enable synchronous HTTP calls To enable synchronous calls, an attribute in the QNetworkRequest has to be set. If set, when QNetworkAccessManager::get() (and post(), put()) returns, the reply is finished and all data has been read in case of success. This feature is semi-public for now (usable, but not documented). To enable this, an attribute in the QNetworkRequest must be set. If this attribute is set, we open a new connection to the server with only one channel and call the channels' sockets' waitFor* methods. Reviewed-by: Markus Goetz --- src/network/access/qhttpnetworkconnection.cpp | 9 +- src/network/access/qhttpnetworkconnection_p.h | 4 +- .../access/qhttpnetworkconnectionchannel.cpp | 2 +- .../access/qhttpnetworkconnectionchannel_p.h | 2 + src/network/access/qhttpnetworkreply.cpp | 6 + src/network/access/qhttpnetworkreply_p.h | 1 + src/network/access/qnetworkaccessbackend.cpp | 1 + src/network/access/qnetworkaccessbackend_p.h | 6 + src/network/access/qnetworkaccessdatabackend.cpp | 6 + src/network/access/qnetworkaccessdatabackend_p.h | 2 + src/network/access/qnetworkaccesshttpbackend.cpp | 140 +++++- src/network/access/qnetworkaccesshttpbackend_p.h | 4 +- src/network/access/qnetworkaccessmanager.cpp | 16 +- src/network/access/qnetworkreplyimpl.cpp | 47 +- src/network/access/qnetworkrequest.h | 3 + .../tst_qabstractnetworkcache.cpp | 111 ++++- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 506 ++++++++++++++++++++- 17 files changed, 799 insertions(+), 67 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 4d27531..0531595 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -327,8 +327,6 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket Q_ASSERT(socket); Q_ASSERT(reply); - Q_Q(QHttpNetworkConnection); - resend = false; //create the response header to be used with QAuthenticatorPrivate. QList > fields = reply->header(); @@ -854,12 +852,17 @@ QHttpNetworkReply* QHttpNetworkConnection::sendRequest(const QHttpNetworkRequest return d->queueRequest(request); } -bool QHttpNetworkConnection::isEncrypted() const +bool QHttpNetworkConnection::isSsl() const { Q_D(const QHttpNetworkConnection); return d->encrypt; } +QHttpNetworkConnectionChannel *QHttpNetworkConnection::channels() const +{ + return d_func()->channels; +} + #ifndef QT_NO_NETWORKPROXY void QHttpNetworkConnection::setCacheProxy(const QNetworkProxy &networkProxy) { diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 8461426c..9f23cbf 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -108,7 +108,9 @@ public: QNetworkProxy transparentProxy() const; #endif - bool isEncrypted() const; + bool isSsl() const; + + QHttpNetworkConnectionChannel *channels() const; #ifndef QT_NO_OPENSSL void setSslConfiguration(const QSslConfiguration &config); diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 02daa50..c8caad4 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -180,7 +180,6 @@ bool QHttpNetworkConnectionChannel::sendRequest() reply->d_func()->autoDecompress = request.d->autoDecompress; reply->d_func()->pipeliningUsed = false; - pendingEncrypt = false; // if the url contains authentication parameters, use the new ones // both channels will use the new authentication parameters if (!request.url().userInfo().isEmpty() && request.withCredentials()) { @@ -1019,6 +1018,7 @@ void QHttpNetworkConnectionChannel::_q_encrypted() if (!socket) return; // ### error state = QHttpNetworkConnectionChannel::IdleState; + pendingEncrypt = false; sendRequest(); } diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index 442086a..fd18042 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -158,6 +158,8 @@ public: bool isSocketWaiting() const; bool isSocketReading() const; + friend class QNetworkAccessHttpBackend; + protected slots: void _q_receiveReply(); void _q_bytesWritten(qint64 bytes); // proceed sending diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index e4eb7c4..21bc427 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -188,6 +188,12 @@ QByteArray QHttpNetworkReply::readAny() return d->responseData.read(); } +QByteArray QHttpNetworkReply::readAll() +{ + Q_D(QHttpNetworkReply); + return d->responseData.readAll(); +} + void QHttpNetworkReply::setDownstreamLimited(bool dsl) { Q_D(QHttpNetworkReply); diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 3f79d81..9cf805c 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -126,6 +126,7 @@ public: qint64 bytesAvailable() const; qint64 bytesAvailableNextBlock() const; QByteArray readAny(); + QByteArray readAll(); void setDownstreamLimited(bool t); bool isFinished() const; diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index 05eb6cb..12b6400 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -142,6 +142,7 @@ void QNetworkAccessBackend::emitReplyUploadProgress(qint64 bytesSent, qint64 byt QNetworkAccessBackend::QNetworkAccessBackend() : manager(0) , reply(0) + , synchronous(false) { } diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h index 7faa5cb..c9ec37e 100644 --- a/src/network/access/qnetworkaccessbackend_p.h +++ b/src/network/access/qnetworkaccessbackend_p.h @@ -157,6 +157,9 @@ public: QVariant attribute(QNetworkRequest::Attribute code) const; void setAttribute(QNetworkRequest::Attribute code, const QVariant &value); + bool isSynchronous() { return synchronous; } + void setSynchronous(bool sync) { synchronous = sync; } + // return true if the QNonContiguousByteDevice of the upload // data needs to support reset(). Currently needed for HTTP. // This will possibly enable buffering of the upload data. @@ -166,6 +169,8 @@ public: virtual bool canResume() const { return false; } virtual void setResumeOffset(quint64 offset) { Q_UNUSED(offset); } + virtual bool processRequestSynchronously() { return false; } + protected: // Create the device used for reading the upload data QNonContiguousByteDevice* createUploadByteDevice(); @@ -200,6 +205,7 @@ private: friend class QNetworkReplyImplPrivate; QNetworkAccessManagerPrivate *manager; QNetworkReplyImplPrivate *reply; + bool synchronous; }; class QNetworkAccessBackendFactory diff --git a/src/network/access/qnetworkaccessdatabackend.cpp b/src/network/access/qnetworkaccessdatabackend.cpp index efb6e3e..74aebdb 100644 --- a/src/network/access/qnetworkaccessdatabackend.cpp +++ b/src/network/access/qnetworkaccessdatabackend.cpp @@ -122,4 +122,10 @@ bool QNetworkAccessDataBackend::waitForUpstreamBytesWritten(int) return false; } +bool QNetworkAccessDataBackend::processRequestSynchronously() +{ + start(); + return true; +} + QT_END_NAMESPACE diff --git a/src/network/access/qnetworkaccessdatabackend_p.h b/src/network/access/qnetworkaccessdatabackend_p.h index a7c63d5..0e5a494 100644 --- a/src/network/access/qnetworkaccessdatabackend_p.h +++ b/src/network/access/qnetworkaccessdatabackend_p.h @@ -68,6 +68,8 @@ public: virtual void closeUpstreamChannel(); virtual bool waitForDownstreamReadyRead(int msecs); virtual bool waitForUpstreamBytesWritten(int msecs); + + virtual bool processRequestSynchronously(); }; class QNetworkAccessDataBackendFactory: public QNetworkAccessBackendFactory diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 80b05a4..070111d 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -50,6 +50,7 @@ #include "qnetworkrequest_p.h" #include "qnetworkcookie_p.h" #include "QtCore/qdatetime.h" +#include "QtCore/qelapsedtimer.h" #include "QtNetwork/qsslconfiguration.h" #ifndef QT_NO_HTTP @@ -318,7 +319,10 @@ void QNetworkAccessHttpBackend::disconnectFromHttp() // Get the object cache that stores our QHttpNetworkConnection objects QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this); - cache->releaseEntry(cacheKey); + + // synchronous calls are not put into the cache, so for them the key is empty + if (!cacheKey.isEmpty()) + cache->releaseEntry(cacheKey); } // This is abut disconnecting signals, not about disconnecting TCP connections @@ -639,34 +643,49 @@ void QNetworkAccessHttpBackend::open() if (transparentProxy.type() == QNetworkProxy::DefaultProxy && cacheProxy.type() == QNetworkProxy::DefaultProxy) { // unsuitable proxies - QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, - Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProxyNotFoundError), - Q_ARG(QString, tr("No suitable proxy found"))); - QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); - return; + if (isSynchronous()) { + error(QNetworkReply::ProxyNotFoundError, tr("No suitable proxy found")); + finished(); + } else { + QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, + Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProxyNotFoundError), + Q_ARG(QString, tr("No suitable proxy found"))); + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); + } + return; } #endif - // check if we have an open connection to this host - cacheKey = makeCacheKey(this, theProxy); - QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this); - // the http object is actually a QHttpNetworkConnection - http = static_cast(cache->requestEntryNow(cacheKey)); - if (http == 0) { - // no entry in cache; create an object - // the http object is actually a QHttpNetworkConnection - http = new QNetworkAccessCachedHttpConnection(url.host(), url.port(), encrypt); - + if (isSynchronous()) { + // for synchronous requests, we just create a new connection + http = new QHttpNetworkConnection(1, url.host(), url.port(), encrypt, this); #ifndef QT_NO_NETWORKPROXY http->setTransparentProxy(transparentProxy); http->setCacheProxy(cacheProxy); #endif + postRequest(); + processRequestSynchronously(); + } else { + // check if we have an open connection to this host + cacheKey = makeCacheKey(this, theProxy); + QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this); + // the http object is actually a QHttpNetworkConnection + http = static_cast(cache->requestEntryNow(cacheKey)); + if (http == 0) { + // no entry in cache; create an object + // the http object is actually a QHttpNetworkConnection + http = new QNetworkAccessCachedHttpConnection(url.host(), url.port(), encrypt); - // cache the QHttpNetworkConnection corresponding to this cache key - cache->addEntry(cacheKey, http); - } +#ifndef QT_NO_NETWORKPROXY + http->setTransparentProxy(transparentProxy); + http->setCacheProxy(cacheProxy); +#endif - postRequest(); + // cache the QHttpNetworkConnection corresponding to this cache key + cache->addEntry(cacheKey, static_cast(http.data())); + } + postRequest(); + } } void QNetworkAccessHttpBackend::closeDownstreamChannel() @@ -1125,6 +1144,87 @@ void QNetworkAccessHttpBackend::setResumeOffset(quint64 offset) resumeOffset = offset; } +bool QNetworkAccessHttpBackend::processRequestSynchronously() +{ + QHttpNetworkConnectionChannel *channel = &http->channels()[0]; + + // Disconnect all socket signals. They will only confuse us when using waitFor* + QObject::disconnect(channel->socket, 0, 0, 0); + + qint64 timeout = 20*1000; // 20 sec + QElapsedTimer timeoutTimer; + + bool waitResult = channel->socket->waitForConnected(timeout); + timeoutTimer.start(); + + if (!waitResult || channel->socket->state() != QAbstractSocket::Connected) { + error(QNetworkReply::UnknownNetworkError, QLatin1String("could not connect")); + return false; + } + channel->_q_connected(); // this will send the request (via sendRequest()) + +#ifndef QT_NO_OPENSSL + if (http->isSsl()) { + qint64 remainingTimeEncrypted = timeout - timeoutTimer.elapsed(); + if (!static_cast(channel->socket)->waitForEncrypted(remainingTimeEncrypted)) { + error(QNetworkReply::SslHandshakeFailedError, + QLatin1String("could not encrypt or timeout while encrypting")); + return false; + } + channel->_q_encrypted(); + } +#endif + + // if we get a 401 or 407, we might need to send the request twice, see below + bool authenticating = false; + + do { + channel->sendRequest(); + + qint64 remainingTimeBytesWritten; + while(channel->socket->bytesToWrite() > 0 || + channel->state == QHttpNetworkConnectionChannel::WritingState) { + remainingTimeBytesWritten = timeout - timeoutTimer.elapsed(); + channel->sendRequest(); // triggers channel->socket->write() + if (!channel->socket->waitForBytesWritten(remainingTimeBytesWritten)) { + error(QNetworkReply::TimeoutError, + QLatin1String("could not write bytes to socket or timeout while writing")); + return false; + } + } + + qint64 remainingTimeBytesRead = timeout - timeoutTimer.elapsed(); + // Loop for at most remainingTime until either the socket disconnects + // or the reply is finished + do { + waitResult = channel->socket->waitForReadyRead(remainingTimeBytesRead); + remainingTimeBytesRead = timeout - timeoutTimer.elapsed(); + if (!waitResult || remainingTimeBytesRead <= 0 + || channel->socket->state() != QAbstractSocket::ConnectedState) { + error(QNetworkReply::TimeoutError, + QLatin1String("could not read from socket or timeout while reading")); + return false; + } + + if (channel->socket->bytesAvailable()) + channel->_q_readyRead(); + + if (!httpReply) + return false; // we got a 401 or 407 and cannot handle it (it might happen that + // disconnectFromHttp() was called, in that case the reply is zero) + // ### I am quite sure this does not work for NTLM + // ### how about uploading to an auth / proxyAuth site? + + authenticating = (httpReply->statusCode() == 401 || httpReply->statusCode() == 407); + + if (httpReply->isFinished()) + break; + } while (remainingTimeBytesRead > 0); + } while (authenticating); + + return true; +} + QT_END_NAMESPACE #endif // QT_NO_HTTP diff --git a/src/network/access/qnetworkaccesshttpbackend_p.h b/src/network/access/qnetworkaccesshttpbackend_p.h index 5de3429..cc2f9ac 100644 --- a/src/network/access/qnetworkaccesshttpbackend_p.h +++ b/src/network/access/qnetworkaccesshttpbackend_p.h @@ -99,6 +99,8 @@ public: bool canResume() const; void setResumeOffset(quint64 offset); + virtual bool processRequestSynchronously(); + private slots: void replyReadyRead(); void replyFinished(); @@ -111,7 +113,7 @@ private slots: private: QHttpNetworkReply *httpReply; - QPointer http; + QPointer http; QByteArray cacheKey; QNetworkAccessBackendUploadIODevice *uploadDevice; diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index effd79e..4bc036e 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -1060,12 +1060,14 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera priv->backend->setParent(reply); priv->backend->reply = priv; } - // fourth step: setup the reply - priv->setup(op, request, outgoingData); #ifndef QT_NO_OPENSSL reply->setSslConfiguration(request.sslConfiguration()); #endif + + // fourth step: setup the reply + priv->setup(op, request, outgoingData); + return reply; } @@ -1141,6 +1143,11 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QNetworkAccessBackend } } + // if we emit a signal here in synchronous mode, the user might spin + // an event loop, which might recurse and lead to problems + if (backend->isSynchronous()) + return; + backend->reply->urlForLastAuthentication = url; emit q->authenticationRequired(backend->reply->q_func(), authenticator); cacheCredentials(url, authenticator); @@ -1168,6 +1175,11 @@ void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(QNetworkAccessBac } } + // if we emit a signal here in synchronous mode, the user might spin + // an event loop, which might recurse and lead to problems + if (backend->isSynchronous()) + return; + backend->reply->lastProxyAuthentication = proxy; emit q->proxyAuthenticationRequired(proxy, authenticator); cacheProxyCredentials(proxy, authenticator); diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 5850494..cf6e674 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -85,7 +85,7 @@ void QNetworkReplyImplPrivate::_q_startOperation() } #ifndef QT_NO_BEARERMANAGEMENT - if (!backend->start()) { + if (!backend->start()) { // ### we should call that method even if bearer is not used // backend failed to start because the session state is not Connected. // QNetworkAccessManager will call reply->backend->start() again for us when the session // state changes. @@ -109,11 +109,15 @@ void QNetworkReplyImplPrivate::_q_startOperation() } #endif - if (state != Finished) { - if (operation == QNetworkAccessManager::GetOperation) - pendingNotifications.append(NotifyDownstreamReadyWrite); + if (backend->isSynchronous()) { + state = Finished; + } else { + if (state != Finished) { + if (operation == QNetworkAccessManager::GetOperation) + pendingNotifications.append(NotifyDownstreamReadyWrite); - handleNotifications(); + handleNotifications(); + } } } @@ -287,7 +291,25 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const url = request.url(); operation = op; - if (outgoingData && backend) { + q->QIODevice::open(QIODevice::ReadOnly); + // Internal code that does a HTTP reply for the synchronous Ajax + // in QtWebKit. + QVariant synchronousHttpAttribute = req.attribute( + static_cast(QNetworkRequest::DownloadBufferAttribute + 1)); + if (synchronousHttpAttribute.toBool()) { + backend->setSynchronous(true); + if (outgoingData && outgoingData->isSequential()) { + outgoingDataBuffer = new QRingBuffer(); + QByteArray data; + do { + data = outgoingData->readAll(); + if (data.isEmpty()) + break; + outgoingDataBuffer->append(data); + } while (1); + } + } + if (outgoingData && backend && !backend->isSynchronous()) { // there is data to be uploaded, e.g. HTTP POST. if (!backend->needsResetableUploadData() || !outgoingData->isSequential()) { @@ -298,7 +320,7 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const } else { bool bufferingDisallowed = req.attribute(QNetworkRequest::DoNotBufferUploadDataAttribute, - false).toBool(); + false).toBool(); if (bufferingDisallowed) { // if a valid content-length header for the request was supplied, we can disable buffering @@ -323,17 +345,18 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const // for HTTP, we want to send out the request as fast as possible to the network, without // invoking methods in a QueuedConnection #ifndef QT_NO_HTTP - if (qobject_cast(backend)) { + if (qobject_cast(backend) || (backend && backend->isSynchronous())) { _q_startOperation(); } else { QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); } #else - QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); + if (backend->isSynchronous()) + _q_startOperation(); + else + QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); #endif // QT_NO_HTTP - } - - q->QIODevice::open(QIODevice::ReadOnly); + } } void QNetworkReplyImplPrivate::backendNotify(InternalNotifications notification) diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h index cdadf0f..9bcc900 100644 --- a/src/network/access/qnetworkrequest.h +++ b/src/network/access/qnetworkrequest.h @@ -85,6 +85,9 @@ public: MaximumDownloadBufferSizeAttribute, // internal DownloadBufferAttribute, // internal + // (DownloadBufferAttribute + 1) is reserved internal for QSynchronousHttpNetworkReply + // add the enum in 4.8 + User = 1000, UserMax = 32767 }; diff --git a/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp b/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp index 04bd432..fc8a126 100644 --- a/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp +++ b/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp @@ -58,20 +58,29 @@ public: private slots: void expires_data(); void expires(); + void expiresSynchronous_data(); + void expiresSynchronous(); void lastModified_data(); void lastModified(); + void lastModifiedSynchronous_data(); + void lastModifiedSynchronous(); void etag_data(); void etag(); + void etagSynchronous_data(); + void etagSynchronous(); void cacheControl_data(); void cacheControl(); + void cacheControlSynchronous_data(); + void cacheControlSynchronous(); void deleteCache(); private: void check(); + void checkSynchronous(); }; class NetworkDiskCache : public QNetworkDiskCache @@ -142,6 +151,16 @@ void tst_QAbstractNetworkCache::expires() check(); } +void tst_QAbstractNetworkCache::expiresSynchronous_data() +{ + expires_data(); +} + +void tst_QAbstractNetworkCache::expiresSynchronous() +{ + checkSynchronous(); +} + void tst_QAbstractNetworkCache::lastModified_data() { QTest::addColumn("cacheLoadControl"); @@ -164,6 +183,16 @@ void tst_QAbstractNetworkCache::lastModified() check(); } +void tst_QAbstractNetworkCache::lastModifiedSynchronous_data() +{ + tst_QAbstractNetworkCache::lastModified_data(); +} + +void tst_QAbstractNetworkCache::lastModifiedSynchronous() +{ + checkSynchronous(); +} + void tst_QAbstractNetworkCache::etag_data() { QTest::addColumn("cacheLoadControl"); @@ -186,6 +215,16 @@ void tst_QAbstractNetworkCache::etag() check(); } +void tst_QAbstractNetworkCache::etagSynchronous_data() +{ + tst_QAbstractNetworkCache::etag_data(); +} + +void tst_QAbstractNetworkCache::etagSynchronous() +{ + checkSynchronous(); +} + void tst_QAbstractNetworkCache::cacheControl_data() { QTest::addColumn("cacheLoadControl"); @@ -217,6 +256,16 @@ void tst_QAbstractNetworkCache::cacheControl() check(); } +void tst_QAbstractNetworkCache::cacheControlSynchronous_data() +{ + tst_QAbstractNetworkCache::cacheControl_data(); +} + +void tst_QAbstractNetworkCache::cacheControlSynchronous() +{ + checkSynchronous(); +} + void tst_QAbstractNetworkCache::check() { QFETCH(QNetworkRequest::CacheLoadControl, cacheLoadControl); @@ -250,8 +299,6 @@ void tst_QAbstractNetworkCache::check() QCOMPARE(reply2->error(), QNetworkReply::ContentNotFoundError); QCOMPARE(secondData, QByteArray()); } else { - if (reply2->error() != QNetworkReply::NoError) - qDebug() << reply2->errorString(); QCOMPARE(reply2->error(), QNetworkReply::NoError); QCOMPARE(QString(secondData), QString(goodData)); QCOMPARE(secondData, goodData); @@ -263,16 +310,60 @@ void tst_QAbstractNetworkCache::check() QList rawHeaderList2 = reply2->rawHeaderList(); qSort(rawHeaderList); qSort(rawHeaderList2); + } + QCOMPARE(diskCache->gotData, fetchFromCache); +} - // headers can change - for (int i = 0; i < rawHeaderList.count(); ++i) { - //qDebug() << i << rawHeaderList.value(i) << reply->rawHeader(rawHeaderList.value(i)); - //qDebug() << i << rawHeaderList2.value(i) << reply2->rawHeader(rawHeaderList2.value(i)); - //QCOMPARE(QString(rawHeaderList.value(i)), QString(rawHeaderList2.value(i))); - //QCOMPARE(QString(reply->rawHeader(rawHeaderList.value(i))), QString(reply2->rawHeader(rawHeaderList2.value(i)))); - } - //QCOMPARE(rawHeaderList.count(), rawHeaderList2.count()); +void tst_QAbstractNetworkCache::checkSynchronous() +{ + QSKIP("not working yet, see QTBUG-15221", SkipAll); + QFETCH(QNetworkRequest::CacheLoadControl, cacheLoadControl); + QFETCH(QString, url); + QFETCH(bool, fetchFromCache); + + QNetworkAccessManager manager; + NetworkDiskCache *diskCache = new NetworkDiskCache(&manager); + manager.setCache(diskCache); + QCOMPARE(diskCache->gotData, false); + + QUrl realUrl = url.contains("://") ? url : TESTFILE + url; + QNetworkRequest request(realUrl); + + request.setAttribute( + static_cast(QNetworkRequest::DownloadBufferAttribute + 1), + true); + + // prime the cache + QNetworkReply *reply = manager.get(request); + QVERIFY(reply->isFinished()); // synchronous + QCOMPARE(diskCache->gotData, false); + QByteArray goodData = reply->readAll(); + + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, cacheLoadControl); + + // should be in the cache now + QNetworkReply *reply2 = manager.get(request); + QVERIFY(reply2->isFinished()); // synchronous + + QByteArray secondData = reply2->readAll(); + if (!fetchFromCache && cacheLoadControl == QNetworkRequest::AlwaysCache) { + QCOMPARE(reply2->error(), QNetworkReply::ContentNotFoundError); + QCOMPARE(secondData, QByteArray()); + } else { + if (reply2->error() != QNetworkReply::NoError) + qDebug() << reply2->errorString(); + QCOMPARE(reply2->error(), QNetworkReply::NoError); + QCOMPARE(QString(secondData), QString(goodData)); + QCOMPARE(secondData, goodData); + QCOMPARE(reply2->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + } + + if (fetchFromCache) { + QList rawHeaderList = reply->rawHeaderList(); + QList rawHeaderList2 = reply2->rawHeaderList(); + qSort(rawHeaderList); + qSort(rawHeaderList2); } QCOMPARE(diskCache->gotData, fetchFromCache); } diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index ddb7687..90416f2 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -75,7 +75,6 @@ #include "../network-settings.h" - Q_DECLARE_METATYPE(QNetworkReply*) Q_DECLARE_METATYPE(QAuthenticator*) Q_DECLARE_METATYPE(QNetworkProxy) @@ -84,6 +83,8 @@ Q_DECLARE_METATYPE(QList) Q_DECLARE_METATYPE(QNetworkReply::NetworkError) Q_DECLARE_METATYPE(QBuffer*) +const int SynchronousRequestAttribute = QNetworkRequest::DownloadBufferAttribute + 1; + class QNetworkReplyPtr: public QSharedPointer { public: @@ -108,6 +109,16 @@ class tst_QNetworkReply: public QObject bool requiresAuthentication; }; + static bool seedCreated; + static QString createUniqueExtension() { + if (!seedCreated) { + qsrand(QTime(0,0,0).msecsTo(QTime::currentTime()) + QCoreApplication::applicationPid()); + seedCreated = true; // not thread-safe, but who cares + } + QString s = QString("%1-%2-%3").arg(QTime(0,0,0).msecsTo(QTime::currentTime())).arg(QCoreApplication::applicationPid()).arg(qrand()); + return s; + }; + QEventLoop *loop; enum RunSimpleRequestReturn { Timeout = 0, Success, Failure }; int returnCode; @@ -173,8 +184,12 @@ private Q_SLOTS: void putToFtp(); void putToHttp_data(); void putToHttp(); + void putToHttpSynchronous_data(); + void putToHttpSynchronous(); void postToHttp_data(); void postToHttp(); + void postToHttpSynchronous_data(); + void postToHttpSynchronous(); void deleteFromHttp_data(); void deleteFromHttp(); void putGetDeleteGetFromHttp_data(); @@ -198,7 +213,9 @@ private Q_SLOTS: void ioGetFromHttpWithReuseParallel(); void ioGetFromHttpWithReuseSequential(); void ioGetFromHttpWithAuth(); + void ioGetFromHttpWithAuthSynchronous(); void ioGetFromHttpWithProxyAuth(); + void ioGetFromHttpWithProxyAuthSynchronous(); void ioGetFromHttpWithSocksProxy(); #ifndef QT_NO_OPENSSL void ioGetFromHttpsWithSslErrors(); @@ -233,6 +250,8 @@ private Q_SLOTS: void ioPostToHttpFromFile(); void ioPostToHttpFromSocket_data(); void ioPostToHttpFromSocket(); + void ioPostToHttpFromSocketSynchronous(); + void ioPostToHttpFromSocketSynchronous_data(); void ioPostToHttpFromMiddleOfFileToEnd(); void ioPostToHttpFromMiddleOfFileFiveBytes(); void ioPostToHttpFromMiddleOfQBufferFiveBytes(); @@ -258,13 +277,19 @@ private Q_SLOTS: void receiveCookiesFromHttp_data(); void receiveCookiesFromHttp(); + void receiveCookiesFromHttpSynchronous_data(); + void receiveCookiesFromHttpSynchronous(); void sendCookies_data(); void sendCookies(); + void sendCookiesSynchronous_data(); + void sendCookiesSynchronous(); void nestedEventLoops(); void httpProxyCommands_data(); void httpProxyCommands(); + void httpProxyCommandsSynchronous_data(); + void httpProxyCommandsSynchronous(); void proxyChange(); void authorizationError_data(); void authorizationError(); @@ -303,12 +328,18 @@ private Q_SLOTS: void qtbug15311doubleContentLength(); + void synchronousRequest_data(); + void synchronousRequest(); + void synchronousRequestSslFailure(); + // NOTE: This test must be last! void parentingRepliesToTheApp(); }; QT_BEGIN_NAMESPACE +bool tst_QNetworkReply::seedCreated = false; + namespace QTest { template<> char *toString(const QNetworkReply::NetworkError& code) @@ -915,14 +946,15 @@ protected: tst_QNetworkReply::tst_QNetworkReply() { + qRegisterMetaType(); // for QSignalSpy + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType >(); + Q_SET_DEFAULT_IAP testFileName = QDir::currentPath() + "/testfile"; -#ifndef Q_OS_WINCE - uniqueExtension = QString("%1%2%3").arg((qulonglong)this).arg(rand()).arg((qulonglong)time(0)); -#else - uniqueExtension = QString("%1%2").arg((qulonglong)this).arg(rand()); -#endif + uniqueExtension = createUniqueExtension(); cookieJar = new MyCookieJar; manager.setCookieJar(cookieJar); @@ -1009,15 +1041,25 @@ QString tst_QNetworkReply::runSimpleRequest(QNetworkAccessManager::Operation op, Q_ASSERT_X(false, "tst_QNetworkReply", "Invalid/unknown operation requested"); } reply->setParent(this); - connect(reply, SIGNAL(finished()), SLOT(finished())); - connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(gotError())); returnCode = Timeout; - loop = new QEventLoop; - QTimer::singleShot(20000, loop, SLOT(quit())); - int code = returnCode == Timeout ? loop->exec() : returnCode; - delete loop; - loop = 0; + int code = Success; + + if (request.attribute(static_cast(SynchronousRequestAttribute)).toBool()) { + if (reply->isFinished()) + code = reply->error() != QNetworkReply::NoError ? Failure : Success; + else + code = Failure; + } else { + connect(reply, SIGNAL(finished()), SLOT(finished())); + connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(gotError())); + + loop = new QEventLoop; + QTimer::singleShot(20000, loop, SLOT(quit())); + code = returnCode == Timeout ? loop->exec() : returnCode; + delete loop; + loop = 0; + } switch (code) { case Failure: @@ -1492,6 +1534,9 @@ void tst_QNetworkReply::putToFile_data() data = QByteArray(128*1024+1, '\177'); QTest::newRow("128k+1") << data << md5sum(data); + + data = QByteArray(2*1024*1024+1, '\177'); + QTest::newRow("2MB+1") << data << md5sum(data); } void tst_QNetworkReply::putToFile() @@ -1598,6 +1643,47 @@ void tst_QNetworkReply::putToHttp() QCOMPARE(uploadedData, data); } +void tst_QNetworkReply::putToHttpSynchronous_data() +{ + uniqueExtension = createUniqueExtension(); + putToFile_data(); +} + +void tst_QNetworkReply::putToHttpSynchronous() +{ + QUrl url("http://" + QtNetworkSettings::serverName()); + url.setPath(QString("/dav/qnetworkaccess-putToHttp-%1-%2") + .arg(QTest::currentDataTag()) + .arg(uniqueExtension)); + + QNetworkRequest request(url); + QNetworkReplyPtr reply; + + QFETCH(QByteArray, data); + + request.setAttribute( + static_cast(SynchronousRequestAttribute), + true); + + RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::PutOperation, request, reply, data)); + + QCOMPARE(reply->url(), url); + QCOMPARE(reply->error(), QNetworkReply::NoError); + + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 201); // 201 Created + + // download the file again from HTTP to make sure it was uploaded + // correctly. HTTP/0.9 is enough + QTcpSocket socket; + socket.connectToHost(QtNetworkSettings::serverName(), 80); + socket.write("GET " + url.toEncoded(QUrl::RemoveScheme | QUrl::RemoveAuthority) + "\r\n"); + if (!socket.waitForDisconnected(10000)) + QFAIL("Network timeout"); + + QByteArray uploadedData = socket.readAll(); + QCOMPARE(uploadedData, data); +} + void tst_QNetworkReply::postToHttp_data() { putToFile_data(); @@ -1624,6 +1710,37 @@ void tst_QNetworkReply::postToHttp() QCOMPARE(uploadedData, md5sum.toHex()); } +void tst_QNetworkReply::postToHttpSynchronous_data() +{ + putToFile_data(); +} + +void tst_QNetworkReply::postToHttpSynchronous() +{ + QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi"); + + QNetworkRequest request(url); + + request.setAttribute( + static_cast(SynchronousRequestAttribute), + true); + + QNetworkReplyPtr reply; + + QFETCH(QByteArray, data); + + RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::PostOperation, request, reply, data)); + + QCOMPARE(reply->url(), url); + QCOMPARE(reply->error(), QNetworkReply::NoError); + + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); // 200 Ok + + QFETCH(QByteArray, md5sum); + QByteArray uploadedData = reply->readAll().trimmed(); + QCOMPARE(uploadedData, md5sum.toHex()); +} + void tst_QNetworkReply::deleteFromHttp_data() { QTest::addColumn("url"); @@ -2048,9 +2165,6 @@ void tst_QNetworkReply::ioGetFromHttpWithReuseSequential() void tst_QNetworkReply::ioGetFromHttpWithAuth() { - qRegisterMetaType(); // for QSignalSpy - qRegisterMetaType(); - // This test sends three requests // The first two in parallel // The third after the first two finished @@ -2109,6 +2223,44 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth() QCOMPARE(authspy.count(), 0); } + + // now check with synchronous calls: + reference.seek(0); + { + request.setAttribute( + static_cast(SynchronousRequestAttribute), + true); + + QSignalSpy authspy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); + QNetworkReplyPtr replySync = manager.get(request); + QVERIFY(replySync->isFinished()); // synchronous + QCOMPARE(authspy.count(), 0); + + // we cannot use a data reader here, since that connects to the readyRead signal, + // just use readAll() + + // the only thing we check here is that the auth cache was used when using synchronous requests + QCOMPARE(replySync->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + QCOMPARE(replySync->readAll(), reference.readAll()); + } +} + +void tst_QNetworkReply::ioGetFromHttpWithAuthSynchronous() +{ + // verify that we do not enter an endless loop with synchronous calls and wrong credentials + // the case when we succed with the login is tested in ioGetFromHttpWithAuth() + + QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt")); + request.setAttribute( + static_cast(SynchronousRequestAttribute), + true); + + QSignalSpy authspy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); + QNetworkReplyPtr replySync = manager.get(request); + QVERIFY(replySync->isFinished()); // synchronous + QCOMPARE(replySync->error(), QNetworkReply::AuthenticationRequiredError); + QCOMPARE(authspy.count(), 0); + QCOMPARE(replySync->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 401); } void tst_QNetworkReply::ioGetFromHttpWithProxyAuth() @@ -2180,6 +2332,47 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuth() QCOMPARE(authspy.count(), 0); } + + // now check with synchronous calls: + reference.seek(0); + { + request.setAttribute( + static_cast(SynchronousRequestAttribute), + true); + + QSignalSpy authspy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); + QNetworkReplyPtr replySync = manager.get(request); + QVERIFY(replySync->isFinished()); // synchronous + QCOMPARE(authspy.count(), 0); + + // we cannot use a data reader here, since that connects to the readyRead signal, + // just use readAll() + + // the only thing we check here is that the proxy auth cache was used when using synchronous requests + QCOMPARE(replySync->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + QCOMPARE(replySync->readAll(), reference.readAll()); + } +} + +void tst_QNetworkReply::ioGetFromHttpWithProxyAuthSynchronous() +{ + // verify that we do not enter an endless loop with synchronous calls and wrong credentials + // the case when we succed with the login is tested in ioGetFromHttpWithAuth() + + QNetworkProxy proxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129); + QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); + manager.setProxy(proxy); + request.setAttribute( + static_cast(SynchronousRequestAttribute), + true); + + QSignalSpy authspy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); + QNetworkReplyPtr replySync = manager.get(request); + manager.setProxy(QNetworkProxy()); // reset + QVERIFY(replySync->isFinished()); // synchronous + QCOMPARE(replySync->error(), QNetworkReply::ProxyAuthenticationRequiredError); + QCOMPARE(authspy.count(), 0); + QCOMPARE(replySync->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 407); } void tst_QNetworkReply::ioGetFromHttpWithSocksProxy() @@ -3238,7 +3431,67 @@ void tst_QNetworkReply::ioPostToHttpFromSocket() QTEST(authenticationRequiredSpy.count(), "authenticationRequiredCount"); QTEST(proxyAuthenticationRequiredSpy.count(), "proxyAuthenticationRequiredCount"); - } +} + +void tst_QNetworkReply::ioPostToHttpFromSocketSynchronous_data() +{ + QTest::addColumn("data"); + QTest::addColumn("md5sum"); + + QByteArray data; + data = ""; + QTest::newRow("empty") << data << md5sum(data); + + data = "This is a normal message."; + QTest::newRow("generic") << data << md5sum(data); + + data = "This is a message to show that Qt rocks!\r\n\n"; + QTest::newRow("small") << data << md5sum(data); + + data = QByteArray("abcd\0\1\2\abcd",12); + QTest::newRow("with-nul") << data << md5sum(data); + + data = QByteArray(4097, '\4'); + QTest::newRow("4k+1") << data << md5sum(data); + + data = QByteArray(128*1024+1, '\177'); + QTest::newRow("128k+1") << data << md5sum(data); + + data = QByteArray(2*1024*1024+1, '\177'); + QTest::newRow("2MB+1") << data << md5sum(data); +} + +void tst_QNetworkReply::ioPostToHttpFromSocketSynchronous() +{ + QFETCH(QByteArray, data); + + SocketPair socketpair; + QVERIFY(socketpair.create()); + QVERIFY(socketpair.endPoints[0] && socketpair.endPoints[1]); + socketpair.endPoints[0]->write(data); + socketpair.endPoints[0]->waitForBytesWritten(5000); + // ### for 4.8: make the socket pair unbuffered, to not read everything in one go in QNetworkReplyImplPrivate::setup() + QTestEventLoop::instance().enterLoop(3); + + QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi"); + QNetworkRequest request(url); + request.setAttribute( + static_cast(SynchronousRequestAttribute), + true); + + QNetworkReplyPtr reply = manager.post(request, socketpair.endPoints[1]); + QVERIFY(reply->isFinished()); + socketpair.endPoints[0]->close(); + + QCOMPARE(reply->error(), QNetworkReply::NoError); + + QCOMPARE(reply->url(), url); + QCOMPARE(reply->error(), QNetworkReply::NoError); + // verify that the HTTP status code is 200 Ok + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + + QCOMPARE(reply->readAll().trimmed(), md5sum(data).toHex()); +} // this tests checks if rewinding the POST-data to some place in the middle // worked. @@ -3981,6 +4234,38 @@ void tst_QNetworkReply::receiveCookiesFromHttp() QTEST(cookieJar->allCookies(), "expectedCookiesInJar"); } +void tst_QNetworkReply::receiveCookiesFromHttpSynchronous_data() +{ + tst_QNetworkReply::receiveCookiesFromHttp_data(); +} + +void tst_QNetworkReply::receiveCookiesFromHttpSynchronous() +{ + QFETCH(QString, cookieString); + + QByteArray data = cookieString.toLatin1() + '\n'; + QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/set-cookie.cgi"); + + QNetworkRequest request(url); + + request.setAttribute( + static_cast(SynchronousRequestAttribute), + true); + + QNetworkReplyPtr reply; + RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::PostOperation, request, reply, data)); + + QCOMPARE(reply->url(), url); + QCOMPARE(reply->error(), QNetworkReply::NoError); + + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); // 200 Ok + + QList setCookies = + qvariant_cast >(reply->header(QNetworkRequest::SetCookieHeader)); + QTEST(setCookies, "expectedCookiesFromHttp"); + QTEST(cookieJar->allCookies(), "expectedCookiesInJar"); +} + void tst_QNetworkReply::sendCookies_data() { QTest::addColumn >("cookiesToSet"); @@ -4041,6 +4326,35 @@ void tst_QNetworkReply::sendCookies() QCOMPARE(QString::fromLatin1(reply->readAll()).trimmed(), expectedCookieString); } +void tst_QNetworkReply::sendCookiesSynchronous_data() +{ + tst_QNetworkReply::sendCookies_data(); +} + +void tst_QNetworkReply::sendCookiesSynchronous() +{ + QFETCH(QString, expectedCookieString); + QFETCH(QList, cookiesToSet); + cookieJar->setAllCookies(cookiesToSet); + + QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/get-cookie.cgi"); + QNetworkRequest request(url); + + request.setAttribute( + static_cast(SynchronousRequestAttribute), + true); + + QNetworkReplyPtr reply; + RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::GetOperation, request, reply)); + + QCOMPARE(reply->url(), url); + QCOMPARE(reply->error(), QNetworkReply::NoError); + + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); // 200 Ok + + QCOMPARE(QString::fromLatin1(reply->readAll()).trimmed(), expectedCookieString); +} + void tst_QNetworkReply::nestedEventLoops_slot() { QEventLoop subloop; @@ -4144,6 +4458,49 @@ private: int signalCount; }; +void tst_QNetworkReply::httpProxyCommandsSynchronous_data() +{ + httpProxyCommands_data(); +} + +void tst_QNetworkReply::httpProxyCommandsSynchronous() +{ + QFETCH(QUrl, url); + QFETCH(QByteArray, responseToSend); + QFETCH(QString, expectedCommand); + + // when using synchronous commands, we need a different event loop for + // the server thread, because the client is never returning to the + // event loop + MiniHttpServer proxyServer(responseToSend); + QThread serverThread; + proxyServer.moveToThread(&serverThread); + serverThread.start(); + QNetworkProxy proxy(QNetworkProxy::HttpProxy, "127.0.0.1", proxyServer.serverPort()); + + manager.setProxy(proxy); + QNetworkRequest request(url); + + // send synchronous request + request.setAttribute( + static_cast(SynchronousRequestAttribute), + true); + + QNetworkReplyPtr reply = manager.get(request); + QVERIFY(reply->isFinished()); // synchronous + manager.setProxy(QNetworkProxy()); + serverThread.quit(); + + //qDebug() << reply->error() << reply->errorString(); + + // we don't really care if the request succeeded + // especially since it won't succeed in the HTTPS case + // so just check that the command was correct + + QString receivedHeader = proxyServer.receivedData.left(expectedCommand.length()); + QCOMPARE(receivedHeader, expectedCommand); +} + void tst_QNetworkReply::proxyChange() { ProxyChangeHelper helper; @@ -4746,7 +5103,122 @@ void tst_QNetworkReply::qtbug15311doubleContentLength() QCOMPARE(reply->readAll(), QByteArray("ABC")); } +void tst_QNetworkReply::synchronousRequest_data() +{ + QTest::addColumn("url"); + QTest::addColumn("expected"); + QTest::addColumn("checkContentLength"); + QTest::addColumn("mimeType"); + + // ### cache, auth, proxies + + QTest::newRow("http") + << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt") + << QString("file:" SRCDIR "/rfc3252.txt") + << true + << QString("text/plain"); + + QTest::newRow("http-gzip") + << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/deflate/rfc3252.txt") + << QString("file:" SRCDIR "/rfc3252.txt") + << false // don't check content length, because it's gzip encoded + // ### we would need to enflate (un-deflate) the file content and compare the sizes + << QString("text/plain"); + +#ifndef QT_NO_OPENSSL + QTest::newRow("https") + << QUrl("https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt") + << QString("file:" SRCDIR "/rfc3252.txt") + << true + << QString("text/plain"); +#endif + + QTest::newRow("data") + << QUrl(QString::fromLatin1("data:text/plain,hello world")) + << QString("data:hello world") + << true // check content length + << QString("text/plain"); + + QTest::newRow("simple-file") + << QUrl(QString::fromLatin1("file:///" SRCDIR "/rfc3252.txt")) + << QString("file:" SRCDIR "/rfc3252.txt") + << true + << QString(); +} + +// FIXME add testcase for failing network etc +void tst_QNetworkReply::synchronousRequest() +{ + QFETCH(QUrl, url); + QFETCH(QString, expected); + QFETCH(bool, checkContentLength); + QFETCH(QString, mimeType); + + QNetworkRequest request(url); + +#ifndef QT_NO_OPENSSL + // workaround for HTTPS requests: add self-signed server cert to list of CA certs, + // since we cannot react to the sslErrors() signal + // to fix this properly we would need to have an ignoreSslErrors() method in the + // QNetworkRequest, see http://bugreports.qt.nokia.com/browse/QTBUG-14774 + if (url.scheme() == "https") { + QSslConfiguration sslConf; + QList certs = QSslCertificate::fromPath(SRCDIR "/certs/qt-test-server-cacert.pem"); + sslConf.setCaCertificates(certs); + request.setSslConfiguration(sslConf); + } +#endif + + request.setAttribute( + static_cast(SynchronousRequestAttribute), + true); + + QNetworkReplyPtr reply; + QSignalSpy finishedSpy(&manager, SIGNAL(finished(QNetworkReply*))); + QSignalSpy sslErrorsSpy(&manager, SIGNAL(sslErrors(QNetworkReply*,QList))); + RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::GetOperation, request, reply, 0)); + QVERIFY(reply->isFinished()); + QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(sslErrorsSpy.count(), 0); + + QCOMPARE(reply->header(QNetworkRequest::ContentTypeHeader).toString(), mimeType); + + QByteArray expectedContent; + + if (expected.startsWith("file:")) { + QString path = expected.mid(5); + QFile file(path); + file.open(QIODevice::ReadOnly); + expectedContent = file.readAll(); + } else if (expected.startsWith("data:")) { + expectedContent = expected.mid(5).toUtf8(); + } + + if (checkContentLength) + QCOMPARE(reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(), qint64(expectedContent.size())); + QCOMPARE(reply->readAll(), expectedContent); + + reply->deleteLater(); +} + +void tst_QNetworkReply::synchronousRequestSslFailure() +{ + // test that SSL won't be accepted with self-signed certificate, + // and that we do not emit the sslError signal (in the manager that is, + // in the reply we don't care) + QUrl url("https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"); + QNetworkRequest request(url); + request.setAttribute( + static_cast(SynchronousRequestAttribute), + true); + QNetworkReplyPtr reply; + QSignalSpy sslErrorsSpy(&manager, SIGNAL(sslErrors(QNetworkReply *, const QList &))); + runSimpleRequest(QNetworkAccessManager::GetOperation, request, reply, 0); + QVERIFY(reply->isFinished()); + QCOMPARE(reply->error(), QNetworkReply::SslHandshakeFailedError); + QCOMPARE(sslErrorsSpy.count(), 0); +} // NOTE: This test must be last testcase in tst_qnetworkreply! void tst_QNetworkReply::parentingRepliesToTheApp() -- cgit v0.12 From b91221ebe4acc5f59793b1070dd134ed56eb91fb Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Tue, 23 Nov 2010 17:53:25 +0100 Subject: HTTP backend: fix build without Qt3 support Reviewed-by: Markus Goetz --- src/network/access/qnetworkaccesshttpbackend.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 070111d..9df5d7b 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -1157,7 +1157,7 @@ bool QNetworkAccessHttpBackend::processRequestSynchronously() bool waitResult = channel->socket->waitForConnected(timeout); timeoutTimer.start(); - if (!waitResult || channel->socket->state() != QAbstractSocket::Connected) { + if (!waitResult || channel->socket->state() != QAbstractSocket::ConnectedState) { error(QNetworkReply::UnknownNetworkError, QLatin1String("could not connect")); return false; } -- cgit v0.12 From 004cd14b84e3683cd92cf01061ee9688990f990c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 23 Nov 2010 15:34:09 +0100 Subject: Lighthouse: Fix QGLContext::currentContext for systems with limited resources. The example plugins EGLFS uses only 1 native context. Make sure that we only use this 1 context, and that we dont wrap it in many different QPlatformGLContexts or QGLContexts instanses. This change also removes the QPlatformWindow link which was made in the initial QPlatformGLContext change. Lighthouse has to support situations where a context isnt bound to a QPlatformWindow. Reviewed-by: gunnar --- src/gui/kernel/qplatformglcontext_qpa.cpp | 18 ++---- src/gui/kernel/qplatformglcontext_qpa.h | 4 +- src/opengl/qgl.cpp | 58 ++++++++++++++--- src/opengl/qgl.h | 5 ++ src/opengl/qgl_qpa.cpp | 20 +++--- .../eglconvenience/qeglplatformcontext.cpp | 4 +- .../platforms/eglconvenience/qeglplatformcontext.h | 2 +- src/plugins/platforms/eglfs/qeglfsscreen.cpp | 72 +++++++++++++++++----- src/plugins/platforms/eglfs/qeglfsscreen.h | 11 ++-- .../platforms/eglfs/qeglfswindowsurface.cpp | 5 +- src/plugins/platforms/testlite/qglxintegration.cpp | 6 +- src/plugins/platforms/testlite/qglxintegration.h | 2 +- src/plugins/platforms/testlite/qtestlitewindow.cpp | 2 +- 13 files changed, 141 insertions(+), 68 deletions(-) diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp index a450b33..5d2faf1 100644 --- a/src/gui/kernel/qplatformglcontext_qpa.cpp +++ b/src/gui/kernel/qplatformglcontext_qpa.cpp @@ -61,8 +61,8 @@ static QThreadStorage qplatformgl_context_storage; class QPlatformGLContextPrivate { public: - QPlatformGLContextPrivate(QPlatformWindow *platformWindow) - :qGLContextHandle(0),platformWindow(platformWindow) + QPlatformGLContextPrivate() + :qGLContextHandle(0) { } @@ -73,7 +73,6 @@ public: } void *qGLContextHandle; void (*qGLContextDeleteFunction)(void *handle); - QPlatformWindow *platformWindow; static QPlatformGLContext *staticSharedContext; static void setCurrentContext(QPlatformGLContext *context); @@ -96,15 +95,6 @@ void QPlatformGLContextPrivate::setCurrentContext(QPlatformGLContext *context) } /*! - Returns the platformWindow which this QPlatformGLContext belongs to. -*/ -QPlatformWindow *QPlatformGLContext::platformWindow() const -{ - Q_D(const QPlatformGLContext); - return d->platformWindow; -} - -/*! Returns the last context which called makeCurrent. This function is thread aware. */ const QPlatformGLContext* QPlatformGLContext::currentContext() @@ -119,8 +109,8 @@ const QPlatformGLContext* QPlatformGLContext::currentContext() /*! All subclasses needs to specify the platformWindow. It can be a null window. */ -QPlatformGLContext::QPlatformGLContext(QPlatformWindow *platformWindow) - :d_ptr(new QPlatformGLContextPrivate(platformWindow)) +QPlatformGLContext::QPlatformGLContext() + :d_ptr(new QPlatformGLContextPrivate()) { } diff --git a/src/gui/kernel/qplatformglcontext_qpa.h b/src/gui/kernel/qplatformglcontext_qpa.h index 3e10c2b..a70e046 100644 --- a/src/gui/kernel/qplatformglcontext_qpa.h +++ b/src/gui/kernel/qplatformglcontext_qpa.h @@ -58,7 +58,7 @@ class Q_OPENGL_EXPORT QPlatformGLContext Q_DECLARE_PRIVATE(QPlatformGLContext); public: - explicit QPlatformGLContext(QPlatformWindow *platformWindow); + explicit QPlatformGLContext(); virtual ~QPlatformGLContext(); virtual void makeCurrent(); @@ -68,8 +68,6 @@ public: virtual QPlatformWindowFormat platformWindowFormat() const = 0; - QPlatformWindow *platformWindow() const; - const static QPlatformGLContext *currentContext(); const static QPlatformGLContext *defaultSharedContext(); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 65d3bbe..5eb4c16 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2095,6 +2095,14 @@ QGLContext::QGLContext(const QGLFormat &format) d->init(0, format); } +QGLContext::QGLContext(QPlatformGLContext *platformContext) + : d_ptr(new QGLContextPrivate(this)) +{ + Q_D(QGLContext); + d->init(0,QGLFormat::fromPlatformWindowFormat(platformContext->platformWindowFormat())); + d->platformContext = platformContext; +} + /*! Destroys the OpenGL context and frees its resources. */ @@ -3152,6 +3160,18 @@ void QGLContext::setDevice(QPaintDevice *pDev) } } +QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContext) +{ + if (!platformContext) + return 0; + if (platformContext->qGLContextHandle()) { + return reinterpret_cast(platformContext->qGLContextHandle()); + } + QGLContext *glContext = new QGLContext(platformContext); + glContext->create(); + return glContext; +} + /*! \fn bool QGLContext::isValid() const @@ -3304,11 +3324,16 @@ bool QGLContext::areSharing(const QGLContext *context1, const QGLContext *contex bool QGLContext::create(const QGLContext* shareContext) { Q_D(QGLContext); +#ifdef Q_WS_QPA + if (!d->paintDevice && !d->platformContext) +#else if (!d->paintDevice) +#endif return false; + reset(); d->valid = chooseContext(shareContext); - if (d->valid && d->paintDevice->devType() == QInternal::Widget) { + if (d->valid && d->paintDevice && d->paintDevice->devType() == QInternal::Widget) { QWidgetPrivate *wd = qt_widget_private(static_cast(d->paintDevice)); wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer(); } @@ -3389,14 +3414,7 @@ const QGLContext* QGLContext::currentContext() { #ifdef Q_WS_QPA if (const QPlatformGLContext *threadContext = QPlatformGLContext::currentContext()) { - if (threadContext->qGLContextHandle()) { - return (const QGLContext *)threadContext->qGLContextHandle(); - } else { - QWidget *widget = threadContext->platformWindow()->widget(); - QGLContext *context = new QGLContext(QGLFormat::fromPlatformWindowFormat(threadContext->platformWindowFormat()),widget); - context->create(); //don't know how to pass in the sharecontext. (doesn't really matter though) - return context; - } + return QGLContext::fromPlatformGLContext(const_cast(threadContext)); } return 0; #else @@ -3781,7 +3799,18 @@ QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFl setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_NoSystemBackground); setAutoFillBackground(true); // for compatibility +#ifdef Q_WS_QPA + setPlatformWindowFormat(QGLFormat::toPlatformWindowFormat(QGLFormat::defaultFormat())); + winId(); // create window; + QGLContext *glContext = 0; + if (platformWindow()) + glContext = QGLContext::fromPlatformGLContext(platformWindow()->glContext()); + if (glContext){ + d->init(glContext,shareWidget); + } +#else d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget); +#endif } @@ -3821,7 +3850,18 @@ QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent, const QGLWidget* setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_NoSystemBackground); setAutoFillBackground(true); // for compatibility +#ifdef Q_WS_QPA + setPlatformWindowFormat(QGLFormat::toPlatformWindowFormat(QGLFormat::defaultFormat())); + winId(); // create window; + QGLContext *glContext = 0; + if (platformWindow()) + glContext = QGLContext::fromPlatformGLContext(platformWindow()->glContext()); + if (glContext){ + d->init(glContext,shareWidget); + } +#else d->init(new QGLContext(format, this), shareWidget); +#endif } /*! diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 1f864a3..f5e0bd7 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -383,6 +383,7 @@ public: static const QGLContext* currentContext(); + static QGLContext *fromPlatformGLContext(QPlatformGLContext *platformContext); protected: virtual bool chooseContext(const QGLContext* shareContext = 0); @@ -412,6 +413,10 @@ protected: static QGLContext* currentCtx; private: +#ifdef Q_WS_QPA + QGLContext(QPlatformGLContext *platformContext); +#endif + QScopedPointer d_ptr; friend class QGLPixelBuffer; diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 28bea83..e997704 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -129,7 +129,11 @@ void qDeleteQGLContext(void *handle) bool QGLContext::chooseContext(const QGLContext* shareContext) { Q_D(QGLContext); - if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) { + if (d->platformContext && !d->platformContext->qGLContextHandle()) { + d->platformContext->setQGLContextHandle(this,qDeleteQGLContext); + d->glFormat = QGLFormat::fromPlatformWindowFormat(d->platformContext->platformWindowFormat()); + d->valid = true; + }else if(!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) { d->valid = false; }else { QWidget *widget = static_cast(d->paintDevice); @@ -215,10 +219,9 @@ void QGLWidget::setContext(QGLContext *context, qWarning("QGLWidget::setContext: Cannot set null context"); return; } - if (!context->deviceIsPixmap() && context->device() != this) { - qWarning("QGLWidget::setContext: Context must refer to this widget"); - return; - } + + if (context->device() == 0) // a context may refere to more than 1 window. + context->setDevice(this); //but its better to point to 1 of them than none of them. QGLContext* oldcx = d->glcx; d->glcx = context; @@ -312,11 +315,8 @@ bool QGLWidget::event(QEvent *e) { Q_D(QGLWidget); if (e->type() == QEvent::WinIdChange) { - if (d->glcx->isValid()) { - if (QGLContext::currentContext() == d->glcx) - QGLContextPrivate::setCurrentContext(0); //Its not valid anymore - setContext(new QGLContext(d->glcx->requestedFormat(), this)); - + if (platformWindow()) { + d->glcx = QGLContext::fromPlatformGLContext(platformWindow()->glContext()); } } return QWidget::event(e); diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp index a169c35..c4adb6f 100644 --- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp +++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp @@ -48,8 +48,8 @@ #include -QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi, QPlatformWindow *platformWindow) - : QPlatformGLContext(platformWindow) +QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi) + : QPlatformGLContext() , m_eglDisplay(display) , m_eglSurface(surface) , m_eglApi(eglApi) diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h index 2c38aca..ae1a891 100644 --- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h +++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h @@ -48,7 +48,7 @@ class QEGLPlatformContext : public QPlatformGLContext { public: - QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi, QPlatformWindow *platformWindow); + QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi); ~QEGLPlatformContext(); void makeCurrent(); diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index b9d1b17..7abc492 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -87,7 +87,10 @@ static struct AttrInfo attrs[] = { #endif //QEGL_EXTRA_DEBUG QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display) - : m_depth(32), m_format(QImage::Format_ARGB32_Premultiplied), m_platformContext(0) + : m_depth(32) + , m_format(QImage::Format_Invalid) + , m_platformContext(0) + , m_surface(0) { #ifdef QEGL_EXTRA_DEBUG qWarning("QEglScreen %p\n", this); @@ -116,7 +119,25 @@ QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display) qWarning("Initialized display %d %d\n", major, minor); - QPlatformWindowFormat platformFormat; + int swapInterval = 1; + QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL"); + if (!swapIntervalString.isEmpty()) { + bool ok; + swapInterval = swapIntervalString.toInt(&ok); + if (!ok) + swapInterval = 1; + } + eglSwapInterval(m_dpy, swapInterval); +} + +void QEglFSScreen::createAndSetPlatformContext() const { + const_cast(this)->createAndSetPlatformContext(); +} + +void QEglFSScreen::createAndSetPlatformContext() +{ + QPlatformWindowFormat platformFormat = QPlatformWindowFormat::defaultFormat(); + platformFormat.setWindowApi(QPlatformWindowFormat::OpenGL); QByteArray depthString = qgetenv("QT_QPA_EGLFS_DEPTH"); @@ -132,23 +153,15 @@ QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display) platformFormat.setRedBufferSize(8); platformFormat.setGreenBufferSize(8); platformFormat.setBlueBufferSize(8); + m_depth = 32; + m_format = QImage::Format_RGB32; } - if (!qgetenv("QT_QPA_EGLFS_MULTISAMPLE").isEmpty()) { platformFormat.setSampleBuffers(true); } - int swapInterval = 1; - QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL"); - if (!swapIntervalString.isEmpty()) { - bool ok; - swapInterval = swapIntervalString.toInt(&ok); - if (!ok) - swapInterval = 1; - } EGLConfig config = q_configFromQPlatformWindowFormat(m_dpy, platformFormat); - eglSwapInterval(display, swapInterval); EGLNativeWindowType eglWindow = 0; #ifdef Q_OPENKODE @@ -189,15 +202,42 @@ QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display) attribList[temp++] = 2; // GLES version 2 attribList[temp++] = EGL_NONE; - m_platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API, 0); - -// qWarning("Created platformcontext"); - EGLint w,h; + m_platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API); + EGLint w,h; // screen size detection eglQuerySurface(m_dpy, m_surface, EGL_WIDTH, &w); eglQuerySurface(m_dpy, m_surface, EGL_HEIGHT, &h); m_geometry = QRect(0,0,w,h); + +} + +QRect QEglFSScreen::geometry() const +{ + if (m_geometry.isNull()) { + createAndSetPlatformContext(); + } + return m_geometry; +} + +int QEglFSScreen::depth() const +{ + return m_depth; +} + +QImage::Format QEglFSScreen::format() const +{ + if (m_format == QImage::Format_Invalid) + createAndSetPlatformContext(); + return m_format; +} +QPlatformGLContext *QEglFSScreen::platformContext() const +{ + if (!m_platformContext) { + QEglFSScreen *that = const_cast(this); + that->createAndSetPlatformContext(); + } + return m_platformContext; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h index 9ed1b04..bfbfa62 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.h +++ b/src/plugins/platforms/eglfs/qeglfsscreen.h @@ -57,13 +57,16 @@ public: QEglFSScreen(EGLNativeDisplayType display); ~QEglFSScreen() {} - QRect geometry() const { return m_geometry; } - int depth() const { return m_depth; } - QImage::Format format() const { return m_format; } + QRect geometry() const; + int depth() const; + QImage::Format format() const; - QPlatformGLContext *platformContext() const { return m_platformContext; } + QPlatformGLContext *platformContext() const; private: + void createAndSetPlatformContext() const; + void createAndSetPlatformContext(); + QRect m_geometry; int m_depth; QImage::Format m_format; diff --git a/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp b/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp index fcea4d3..ebc04bd 100644 --- a/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp @@ -57,13 +57,10 @@ public: #ifdef QEGL_EXTRA_DEBUG qWarning("QEglPaintDevice %p, %p, %p",this, screen, widget); #endif - QGLFormat format; - m_context = new QGLContext(format, widget); - m_context->create(); } QSize size() const { return m_screen->geometry().size(); } - QGLContext* context() const { return m_context;} + QGLContext* context() const { return QGLContext::fromPlatformGLContext(m_screen->platformContext());} QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } diff --git a/src/plugins/platforms/testlite/qglxintegration.cpp b/src/plugins/platforms/testlite/qglxintegration.cpp index c35db9b..a4b7b69 100644 --- a/src/plugins/platforms/testlite/qglxintegration.cpp +++ b/src/plugins/platforms/testlite/qglxintegration.cpp @@ -235,8 +235,8 @@ QPlatformWindowFormat QGLXGLContext::reducePlatformWindowFormat(const QPlatformW return retFormat; } -QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *platformWindow, const QPlatformWindowFormat &format) - : QPlatformGLContext(platformWindow) +QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindowFormat &format) + : QPlatformGLContext() , m_xd(xd) , m_drawable((Drawable)window) , m_context(0) @@ -271,7 +271,7 @@ QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *plat } QGLXGLContext::QGLXGLContext(MyDisplay *display, Drawable drawable, GLXContext context) - : QPlatformGLContext(0), m_xd(display), m_drawable(drawable), m_context(context) + : QPlatformGLContext(), m_xd(display), m_drawable(drawable), m_context(context) { } diff --git a/src/plugins/platforms/testlite/qglxintegration.h b/src/plugins/platforms/testlite/qglxintegration.h index 432dec5..e17790e 100644 --- a/src/plugins/platforms/testlite/qglxintegration.h +++ b/src/plugins/platforms/testlite/qglxintegration.h @@ -58,7 +58,7 @@ class MyDisplay; class QGLXGLContext : public QPlatformGLContext { public: - QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *platformWindow, const QPlatformWindowFormat &format); + QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindowFormat &format); ~QGLXGLContext(); virtual void makeCurrent(); diff --git a/src/plugins/platforms/testlite/qtestlitewindow.cpp b/src/plugins/platforms/testlite/qtestlitewindow.cpp index 0a6e1ff..b52aae9 100644 --- a/src/plugins/platforms/testlite/qtestlitewindow.cpp +++ b/src/plugins/platforms/testlite/qtestlitewindow.cpp @@ -1021,7 +1021,7 @@ QPlatformGLContext *QTestLiteWindow::glContext() const if (!mGLContext) { QTestLiteWindow *that = const_cast(this); #ifndef QT_NO_OPENGL - that->mGLContext = new QGLXGLContext(x_window, xd, that,widget()->platformWindowFormat()); + that->mGLContext = new QGLXGLContext(x_window, xd,widget()->platformWindowFormat()); #endif } return mGLContext; -- cgit v0.12 From 5ea5d929144ddf334bf8f47cccec35ee7dcbb10c Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 24 Nov 2010 11:14:23 +0100 Subject: Fix compile error on Windows Reviewed-by: Joao --- src/corelib/io/qfsfileengine_win.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index f3e2c4c..715fe39 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -69,6 +69,10 @@ #define SECURITY_WIN32 #include +#ifndef PATH_MAX +#define PATH_MAX FILENAME_MAX +#endif + QT_BEGIN_NAMESPACE -- cgit v0.12 From ba9816d1160998abe75b8b45f4b1c14985119553 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 24 Nov 2010 11:57:49 +0100 Subject: Ensure that if this is does not have a valid filter when on XP or less The renderer is only supported on Windows Vista or later so if we are on an earlier version of Windows then this should not be used. In addition this patch also ensures that it resets the filter if any of the needed functions fail. Task-number: QTBUG-13062 Reviewed-by: Thierry Bastian --- src/3rdparty/phonon/ds9/videorenderer_evr.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/3rdparty/phonon/ds9/videorenderer_evr.cpp b/src/3rdparty/phonon/ds9/videorenderer_evr.cpp index de3f46f..ff39eccc4 100644 --- a/src/3rdparty/phonon/ds9/videorenderer_evr.cpp +++ b/src/3rdparty/phonon/ds9/videorenderer_evr.cpp @@ -62,19 +62,21 @@ namespace Phonon VideoRendererEVR::VideoRendererEVR(QWidget *target) : m_target(target) { + if (QSysInfo::WindowsVersion < QSysInfo::WV_VISTA) + return; m_filter = Filter(CLSID_EnhancedVideoRenderer, IID_IBaseFilter); if (!m_filter) { return; } ComPointer filterControl = getService(m_filter, MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl); - if (!filterControl) { + if (!filterControl || + FAILED(filterControl->SetVideoWindow(reinterpret_cast(target->winId()))) || + FAILED(filterControl->SetAspectRatioMode(MFVideoARMode_None)) || // We're in control of the size + !getService(m_filter, MR_VIDEO_MIXER_SERVICE, IID_IMFVideoMixerControl) || + !getService(m_filter, MR_VIDEO_MIXER_SERVICE, IID_IMFVideoProcessor)) { m_filter = Filter(); //will release the interface - return; } - - filterControl->SetVideoWindow(reinterpret_cast(target->winId())); - filterControl->SetAspectRatioMode(MFVideoARMode_None); // We're in control of the size } QImage VideoRendererEVR::snapshot() const -- cgit v0.12 From cbf7a7782f465846455a5fd5df339ebde31a5521 Mon Sep 17 00:00:00 2001 From: Ville Pernu Date: Wed, 24 Nov 2010 12:59:36 +0200 Subject: Fix a missing error-signal when a server is shut down while downloading QT-3494: During download, if a QAbstractSocket::RemoteHostClosedError occurs, the error handling is deferred to _q_disconnected() slot. However, the error message is not saved for the function, and thus the _q_disconnected only emits a finished-signal. Solution: Store an unhandled error into a private member. It is handled and reset by the _q_disconnected (or more specifically, allDone-function). --- src/network/access/qhttpnetworkconnectionchannel.cpp | 18 +++++++++++++++++- src/network/access/qhttpnetworkconnectionchannel_p.h | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 02daa50..39f4811 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -66,6 +66,7 @@ QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel() , bytesTotal(0) , resendCurrent(false) , lastStatus(0) + , unhandledError(QNetworkReply::NoError) , pendingEncrypt(false) , reconnectAttempts(2) , authMethod(QAuthenticatorPrivate::None) @@ -643,7 +644,21 @@ void QHttpNetworkConnectionChannel::allDone() // slot connected to it. The socket will not fire readyRead signal, if we are already // in the slot connected to readyRead if (emitFinished) - QMetaObject::invokeMethod(reply, "finished", Qt::QueuedConnection); + { + // Check whether _q_error was invoked previously and if it left a socket + // error unhandled. + if(unhandledError != QNetworkReply::NoError) { + QString errorString = connection->d_func()->errorDetail(unhandledError, socket, socket->errorString()); + qRegisterMetaType("QNetworkReply::NetworkError"); + QMetaObject::invokeMethod(reply, "finishedWithError", + Qt::QueuedConnection, + Q_ARG(QNetworkReply::NetworkError, unhandledError), + Q_ARG(QString, errorString)); + unhandledError = QNetworkReply::NoError; // Reset the value + } else { + QMetaObject::invokeMethod(reply, "finished", Qt::QueuedConnection); + } + } // reset the reconnection attempts after we receive a complete reply. // in case of failures, each channel will attempt two reconnects before emitting error. reconnectAttempts = 2; @@ -965,6 +980,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket errorCode = QNetworkReply::RemoteHostClosedError; } } else { + unhandledError = QNetworkReply::RemoteHostClosedError; return; } break; diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index 442086a..33cef5a 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -105,6 +105,7 @@ public: qint64 bytesTotal; bool resendCurrent; int lastStatus; // last status received on this channel + QNetworkReply::NetworkError unhandledError; // Stored code of an unhandled error. bool pendingEncrypt; // for https (send after encrypted) int reconnectAttempts; // maximum 2 reconnection attempts QAuthenticatorPrivate::Method authMethod; -- cgit v0.12 From 692ca95391678b2035014026cbdd19770b53eddf Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 24 Nov 2010 12:48:36 +0100 Subject: compile with debug defined enabled --- src/gui/painting/qtextureglyphcache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 4a6c03f..a3e3bb4 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -440,7 +440,7 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP QPoint base(c.x + glyphMargin(), c.y + glyphMargin() + c.baseLineY-1); if (m_image.rect().contains(base)) m_image.setPixel(base, 255); - m_image.save(QString::fromLatin1("cache-%1.png").arg(int(this))); + m_image.save(QString::fromLatin1("cache-%1.png").arg(qint64(this))); #endif } -- cgit v0.12 From 66611fb5c9641dad2c605be790028d206480ea24 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 24 Nov 2010 12:50:29 +0100 Subject: --warn --- src/opengl/qgl_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 8285f06..a603ae6 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -509,6 +509,7 @@ Q_SIGNALS: private slots: void freeTexture_slot(QGLContext *context, QPixmapData *boundPixmap, GLuint id) { + Q_UNUSED(boundPixmap); #if defined(Q_WS_X11) if (boundPixmap) { QGLContext *oldContext = const_cast(QGLContext::currentContext()); -- cgit v0.12 From 535df2381d4f0e9cef9abab2c52db1ec93929e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 24 Nov 2010 15:03:33 +0100 Subject: Smoke test for QAbstractFileEngine This tests the default file support provided by Qt, together with QFSFileEngine, QResource engine and a reference custom file engine that works on top of a simple virtual in-memory file system. For now, the test is only focusing on QFile I/O functionality, it should be extended to cover QFileInfo, QDir, QDirIterator and file system operations in QFile. The intent for the reference file engine is not to be a fully functional file system, but to ensure that minimal support for custom file engines is working. Reviewed-by: Shane Kearns --- tests/auto/corelib.pro | 1 + .../qabstractfileengine/qabstractfileengine.pro | 6 + .../qabstractfileengine/qabstractfileengine.qrc | 5 + tests/auto/qabstractfileengine/resources/file.txt | 1 + .../tst_qabstractfileengine.cpp | 724 +++++++++++++++++++++ 5 files changed, 737 insertions(+) create mode 100644 tests/auto/qabstractfileengine/qabstractfileengine.pro create mode 100644 tests/auto/qabstractfileengine/qabstractfileengine.qrc create mode 100644 tests/auto/qabstractfileengine/resources/file.txt create mode 100644 tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp diff --git a/tests/auto/corelib.pro b/tests/auto/corelib.pro index 5ac0c81..3451b53 100644 --- a/tests/auto/corelib.pro +++ b/tests/auto/corelib.pro @@ -102,6 +102,7 @@ SUBDIRS=\ selftests \ utf8 \ qfilesystementry \ + qabstractfileengine symbian:SUBDIRS -= \ qtconcurrentfilter \ diff --git a/tests/auto/qabstractfileengine/qabstractfileengine.pro b/tests/auto/qabstractfileengine/qabstractfileengine.pro new file mode 100644 index 0000000..870473a --- /dev/null +++ b/tests/auto/qabstractfileengine/qabstractfileengine.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +QT = core + +SOURCES = tst_qabstractfileengine.cpp +RESOURCES += qabstractfileengine.qrc + diff --git a/tests/auto/qabstractfileengine/qabstractfileengine.qrc b/tests/auto/qabstractfileengine/qabstractfileengine.qrc new file mode 100644 index 0000000..5401b08 --- /dev/null +++ b/tests/auto/qabstractfileengine/qabstractfileengine.qrc @@ -0,0 +1,5 @@ + + + resources/ + + diff --git a/tests/auto/qabstractfileengine/resources/file.txt b/tests/auto/qabstractfileengine/resources/file.txt new file mode 100644 index 0000000..8a03e0e --- /dev/null +++ b/tests/auto/qabstractfileengine/resources/file.txt @@ -0,0 +1 @@ +This is a simple text file. diff --git a/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp b/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp new file mode 100644 index 0000000..b2003a0 --- /dev/null +++ b/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp @@ -0,0 +1,724 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +class tst_QAbstractFileEngine + : public QObject +{ + Q_OBJECT +public slots: + void cleanupTestCase(); + +private slots: + void customHandler(); + + void fileIO_data(); + void fileIO(); + +private: + QStringList filesForRemoval; +}; + +class ReferenceFileEngine + : public QAbstractFileEngine +{ +public: + ReferenceFileEngine(const QString &fileName) + : fileName_(fileName) + , position_(-1) + , openForRead_(false) + , openForWrite_(false) + { + } + + bool open(QIODevice::OpenMode openMode) + { + Q_ASSERT(!openForRead_); + Q_ASSERT(!openForWrite_); + + openFile_ = resolveFile(openMode & QIODevice::WriteOnly); + if (!openFile_) + return false; + + position_ = 0; + if (openMode & QIODevice::ReadOnly) + openForRead_ = true; + + if (openMode & QIODevice::WriteOnly) { + openForWrite_ = true; + + QMutexLocker lock(&openFile_->mutex); + if (openMode & QIODevice::Truncate + || !(openForRead_ || openMode & QIODevice::Append)) + openFile_->content.clear(); + + if (openMode & QIODevice::Append) + position_ = openFile_->content.size(); + } + + return true; + } + + bool close() + { + openFile_.clear(); + + openForRead_ = false; + openForWrite_ = false; + position_ = -1; + + return true; + } + + qint64 size() const + { + QSharedPointer file = resolveFile(false); + if (!file) + return 0; + + QMutexLocker lock(&file->mutex); + return file->content.size(); + } + + qint64 pos() const + { + Q_ASSERT(openForRead_ || openForWrite_); + return position_; + } + + bool seek(qint64 pos) + { + Q_ASSERT(openForRead_ || openForWrite_); + + if (pos >= 0) { + position_ = pos; + return true; + } + + return false; + } + + bool flush() + { + Q_ASSERT(openForRead_ || openForWrite_); + return true; + } + + bool remove() + { + QMutexLocker lock(&fileSystemMutex); + int count = fileSystem.remove(fileName_); + + return (count == 1); + } + + bool copy(const QString &newName) + { + QMutexLocker lock(&fileSystemMutex); + if (!fileSystem.contains(fileName_) + || fileSystem.contains(newName)) + return false; + + fileSystem.insert(newName, fileSystem.value(fileName_)); + return true; + } + + bool rename(const QString &newName) + { + QMutexLocker lock(&fileSystemMutex); + if (!fileSystem.contains(fileName_) + || fileSystem.contains(newName)) + return false; + + fileSystem.insert(newName, fileSystem.take(fileName_)); + return true; + } + + // bool link(const QString &newName) + // { + // Q_UNUSED(newName) + // return false; + // } + + // bool mkdir(const QString &dirName, bool createParentDirectories) const + // { + // Q_UNUSED(dirName) + // Q_UNUSED(createParentDirectories) + + // return false; + // } + + // bool rmdir(const QString &dirName, bool recurseParentDirectories) const + // { + // Q_UNUSED(dirName) + // Q_UNUSED(recurseParentDirectories) + + // return false; + // } + + bool setSize(qint64 size) + { + if (size < 0) + return false; + + QSharedPointer file = resolveFile(false); + if (!file) + return false; + + QMutexLocker lock(&file->mutex); + file->content.resize(size); + + if (openForRead_ || openForWrite_) + if (position_ > size) + position_ = size; + + return (file->content.size() == size); + } + + FileFlags fileFlags(FileFlags type) const + { + QSharedPointer file = resolveFile(false); + if (file) { + QMutexLocker lock(&file->mutex); + return (file->fileFlags & type); + } + + return FileFlags(); + } + + // bool setPermissions(uint perms) + // { + // Q_UNUSED(perms) + + // return false; + // } + + QString fileName(FileName file) const + { + switch (file) { + case DefaultName: + return QLatin1String("DefaultName"); + case BaseName: + return QLatin1String("BaseName"); + case PathName: + return QLatin1String("PathName"); + case AbsoluteName: + return QLatin1String("AbsoluteName"); + case AbsolutePathName: + return QLatin1String("AbsolutePathName"); + case LinkName: + return QLatin1String("LinkName"); + case CanonicalName: + return QLatin1String("CanonicalName"); + case CanonicalPathName: + return QLatin1String("CanonicalPathName"); + case BundleName: + return QLatin1String("BundleName"); + + default: + break; + } + + return QString(); + } + + uint ownerId(FileOwner owner) const + { + QSharedPointer file = resolveFile(false); + if (file) { + switch (owner) { + case OwnerUser: + { + QMutexLocker lock(&file->mutex); + return file->userId; + } + case OwnerGroup: + { + QMutexLocker lock(&file->mutex); + return file->groupId; + } + } + } + + return -2; + } + + QString owner(FileOwner owner) const + { + QSharedPointer file = resolveFile(false); + if (file) { + uint ownerId; + switch (owner) { + case OwnerUser: + { + QMutexLocker lock(&file->mutex); + ownerId = file->userId; + } + + { + QMutexLocker lock(&fileSystemMutex); + return fileSystemUsers.value(ownerId); + } + + case OwnerGroup: + { + QMutexLocker lock(&file->mutex); + ownerId = file->groupId; + } + + { + QMutexLocker lock(&fileSystemMutex); + return fileSystemGroups.value(ownerId); + } + } + } + + return QString(); + } + + QDateTime fileTime(FileTime time) const + { + QSharedPointer file = resolveFile(false); + if (file) { + QMutexLocker lock(&file->mutex); + switch (time) { + case CreationTime: + return file->creation; + case ModificationTime: + return file->modification; + case AccessTime: + return file->access; + } + } + + return QDateTime(); + } + + void setFileName(const QString &file) + { + Q_ASSERT(!openForRead_); + Q_ASSERT(!openForWrite_); + + fileName_ = file; + } + + // typedef QAbstractFileEngineIterator Iterator; + // Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) + // { + // Q_UNUSED(filters) + // Q_UNUSED(filterNames) + + // return 0; + // } + + // Iterator *endEntryList() + // { + // return 0; + // } + + qint64 read(char *data, qint64 maxLen) + { + Q_ASSERT(openForRead_); + + Q_ASSERT(!openFile_.isNull()); + QMutexLocker lock(&openFile_->mutex); + qint64 readSize = qMin(openFile_->content.size() - position_, maxLen); + if (readSize < 0) + return -1; + + qMemCopy(data, openFile_->content.constData() + position_, readSize); + position_ += readSize; + + return readSize; + } + + qint64 write(const char *data, qint64 length) + { + Q_ASSERT(openForWrite_); + + if (length < 0) + return -1; + + Q_ASSERT(!openFile_.isNull()); + QMutexLocker lock(&openFile_->mutex); + if (openFile_->content.size() == position_) + openFile_->content.append(data, length); + else { + if (position_ + length > openFile_->content.size()) + openFile_->content.resize(position_ + length); + openFile_->content.replace(position_, length, data, length); + } + + qint64 writeSize = qMin(length, openFile_->content.size() - position_); + position_ += writeSize; + + return writeSize; + } + +protected: + // void setError(QFile::FileError error, const QString &str); + + struct File + { + File() + : userId(0) + , groupId(0) + , fileFlags( + ReadOwnerPerm | WriteOwnerPerm | ExeOwnerPerm + | ReadUserPerm | WriteUserPerm | ExeUserPerm + | ReadGroupPerm | WriteGroupPerm | ExeGroupPerm + | ReadOtherPerm | WriteOtherPerm | ExeOtherPerm + | FileType | ExistsFlag) + { + } + + QMutex mutex; + + uint userId, groupId; + QAbstractFileEngine::FileFlags fileFlags; + QDateTime creation, modification, access; + + QByteArray content; + }; + + QSharedPointer resolveFile(bool create) const + { + if (openForRead_ || openForWrite_) { + Q_ASSERT(openFile_); + return openFile_; + } + + QMutexLocker lock(&fileSystemMutex); + if (create) { + QSharedPointer &p = fileSystem[fileName_]; + if (p.isNull()) + p = QSharedPointer(new File); + return p; + } + + return fileSystem.value(fileName_); + } + + static QMutex fileSystemMutex; + static QHash fileSystemUsers, fileSystemGroups; + static QHash > fileSystem; + +private: + QString fileName_; + qint64 position_; + bool openForRead_; + bool openForWrite_; + + mutable QSharedPointer openFile_; +}; + +QMutex ReferenceFileEngine::fileSystemMutex; +QHash ReferenceFileEngine::fileSystemUsers, ReferenceFileEngine::fileSystemGroups; +QHash > ReferenceFileEngine::fileSystem; + +class FileEngineHandler + : QAbstractFileEngineHandler +{ + QAbstractFileEngine *create(const QString &fileName) const + { + if (fileName.startsWith("QFSFileEngine:")) + return new QFSFileEngine(fileName.mid(14)); + if (fileName.startsWith("reference-file-engine:")) + return new ReferenceFileEngine(fileName.mid(22)); + if (fileName.startsWith("resource:")) + return QAbstractFileEngine::create(QLatin1String(":/tst_qabstractfileengine/resources/") + fileName.mid(9)); + return 0; + } +}; + +void tst_QAbstractFileEngine::cleanupTestCase() +{ + bool failed = false; + + FileEngineHandler handler; + Q_FOREACH(QString file, filesForRemoval) + if (!QFile::remove(file) + || QFile::exists(file)) { + failed = true; + qDebug() << "Couldn't remove file:" << file; + } + + QVERIFY(!failed); +} + +void tst_QAbstractFileEngine::customHandler() +{ + QScopedPointer file; + { + file.reset(QAbstractFileEngine::create("resource:file.txt")); + + QVERIFY(file); + } + + { + FileEngineHandler handler; + + QFile file("resource:file.txt"); + QVERIFY(file.exists()); + } + + { + QFile file("resource:file.txt"); + QVERIFY(!file.exists()); + } +} + +void tst_QAbstractFileEngine::fileIO_data() +{ + QTest::addColumn("fileName"); + QTest::addColumn("readContent"); + QTest::addColumn("writeContent"); + QTest::addColumn("fileExists"); + + QString resourceTxtFile(":/tst_qabstractfileengine/resources/file.txt"); + QByteArray readContent("This is a simple text file.\n"); + QByteArray writeContent("This contains two lines of text.\n"); + + QTest::newRow("resource") << resourceTxtFile << readContent << QByteArray() << true; + QTest::newRow("native") << "native-file.txt" << readContent << writeContent << false; + QTest::newRow("Forced QFSFileEngine") << "QFSFileEngine:QFSFileEngine-file.txt" << readContent << writeContent << false; + QTest::newRow("Custom FE") << "reference-file-engine:file.txt" << readContent << writeContent << false; + + QTest::newRow("Forced QFSFileEngine (native)") << "QFSFileEngine:native-file.txt" << readContent << writeContent << true; + QTest::newRow("native (Forced QFSFileEngine)") << "QFSFileEngine-file.txt" << readContent << writeContent << true; + QTest::newRow("Custom FE (2)") << "reference-file-engine:file.txt" << readContent << writeContent << true; +} + +void tst_QAbstractFileEngine::fileIO() +{ + QFETCH(QString, fileName); + QFETCH(QByteArray, readContent); + QFETCH(QByteArray, writeContent); + QFETCH(bool, fileExists); + + FileEngineHandler handler; + + + { + QFile file(fileName); + QCOMPARE(file.exists(), fileExists); + + if (!fileExists) { + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Unbuffered)); + filesForRemoval.append(fileName); + + QCOMPARE(file.write(readContent), qint64(readContent.size())); + } + } + + // + // File content is: readContent + // + + qint64 fileSize = readContent.size(); + { + // Reading + QFile file(fileName); + + QVERIFY(!file.isOpen()); + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered)); + + QVERIFY(file.isOpen()); + QCOMPARE(file.size(), fileSize); + QCOMPARE(file.pos(), qint64(0)); + + QCOMPARE(file.size(), fileSize); + QCOMPARE(file.readAll(), readContent); + QCOMPARE(file.pos(), fileSize); + + file.close(); + QVERIFY(!file.isOpen()); + QCOMPARE(file.size(), fileSize); + } + + if (writeContent.isEmpty()) + return; + + { + // Writing / appending + QFile file(fileName); + + QVERIFY(!file.isOpen()); + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered)); + + QVERIFY(file.isOpen()); + QCOMPARE(file.size(), fileSize); + QCOMPARE(file.pos(), fileSize); + + QCOMPARE(file.write(writeContent), qint64(writeContent.size())); + + fileSize += writeContent.size(); + QCOMPARE(file.pos(), fileSize); + QCOMPARE(file.size(), fileSize); + + file.close(); + QVERIFY(!file.isOpen()); + QCOMPARE(file.size(), fileSize); + } + + // + // File content is: readContent + writeContent + // + + { + // Reading and Writing + QFile file(fileName); + + QVERIFY(!file.isOpen()); + QVERIFY(file.open(QIODevice::ReadWrite | QIODevice::Unbuffered)); + + QVERIFY(file.isOpen()); + QCOMPARE(file.size(), fileSize); + QCOMPARE(file.pos(), qint64(0)); + + QCOMPARE(file.readAll(), readContent + writeContent); + QCOMPARE(file.pos(), fileSize); + QCOMPARE(file.size(), fileSize); + + QVERIFY(file.seek(writeContent.size())); + QCOMPARE(file.pos(), qint64(writeContent.size())); + QCOMPARE(file.size(), fileSize); + + QCOMPARE(file.write(readContent), qint64(readContent.size())); + QCOMPARE(file.pos(), fileSize); + QCOMPARE(file.size(), fileSize); + + QVERIFY(file.seek(0)); + QCOMPARE(file.pos(), qint64(0)); + QCOMPARE(file.size(), fileSize); + + QCOMPARE(file.write(writeContent), qint64(writeContent.size())); + QCOMPARE(file.pos(), qint64(writeContent.size())); + QCOMPARE(file.size(), fileSize); + + QVERIFY(file.seek(0)); + QCOMPARE(file.read(writeContent.size()), writeContent); + QCOMPARE(file.pos(), qint64(writeContent.size())); + QCOMPARE(file.size(), fileSize); + + QCOMPARE(file.readAll(), readContent); + QCOMPARE(file.pos(), fileSize); + QCOMPARE(file.size(), fileSize); + + file.close(); + QVERIFY(!file.isOpen()); + QCOMPARE(file.size(), fileSize); + } + + // + // File content is: writeContent + readContent + // + + { + // Writing + QFile file(fileName); + + QVERIFY(!file.isOpen()); + QVERIFY(file.open(QIODevice::ReadWrite | QIODevice::Unbuffered)); + + QVERIFY(file.isOpen()); + QCOMPARE(file.size(), fileSize); + QCOMPARE(file.pos(), qint64(0)); + + QCOMPARE(file.write(writeContent), qint64(writeContent.size())); + QCOMPARE(file.pos(), qint64(writeContent.size())); + QCOMPARE(file.size(), fileSize); + + QVERIFY(file.resize(writeContent.size())); + QCOMPARE(file.size(), qint64(writeContent.size())); + + file.close(); + QVERIFY(!file.isOpen()); + QCOMPARE(file.size(), qint64(writeContent.size())); + + QVERIFY(file.resize(fileSize)); + QCOMPARE(file.size(), fileSize); + } + + // + // File content is: writeContent + + // File size is : (readContent + writeContent).size() + // + + { + // Writing / extending + QFile file(fileName); + + QVERIFY(!file.isOpen()); + QVERIFY(file.open(QIODevice::ReadWrite | QIODevice::Unbuffered)); + + QVERIFY(file.isOpen()); + QCOMPARE(file.size(), fileSize); + QCOMPARE(file.pos(), qint64(0)); + + QVERIFY(file.seek(1024)); + QCOMPARE(file.pos(), qint64(1024)); + QCOMPARE(file.size(), fileSize); + + fileSize = 1024 + writeContent.size(); + QCOMPARE(file.write(writeContent), qint64(writeContent.size())); + QCOMPARE(file.pos(), fileSize); + QCOMPARE(file.size(), fileSize); + + QVERIFY(file.seek(1028)); + QCOMPARE(file.pos(), qint64(1028)); + QCOMPARE(file.size(), fileSize); + + fileSize = 1028 + writeContent.size(); + QCOMPARE(file.write(writeContent), qint64(writeContent.size())); + QCOMPARE(file.pos(), fileSize); + QCOMPARE(file.size(), fileSize); + + file.close(); + QVERIFY(!file.isOpen()); + QCOMPARE(file.size(), fileSize); + } + + // + // File content is: writeContent + + writeContent + // File size is : 1024 + writeContent.size() + // + + { + // Writing / truncating + QFile file(fileName); + + QVERIFY(!file.isOpen()); + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Unbuffered)); + + QVERIFY(file.isOpen()); + QCOMPARE(file.size(), qint64(0)); + QCOMPARE(file.pos(), qint64(0)); + + fileSize = readContent.size(); + QCOMPARE(file.write(readContent), fileSize); + QCOMPARE(file.pos(), fileSize); + QCOMPARE(file.size(), fileSize); + + file.close(); + QVERIFY(!file.isOpen()); + QCOMPARE(file.size(), fileSize); + } + + // + // File content is: readContent + // +} + +QTEST_APPLESS_MAIN(tst_QAbstractFileEngine) +#include "tst_qabstractfileengine.moc" + -- cgit v0.12 From 04c3d2e98cebd16a357923ab71a95882e4667ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 24 Nov 2010 16:43:58 +0100 Subject: QAbstractFileEngine test case Oops, I let a space character slip... --- tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp b/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp index b2003a0..f98adca 100644 --- a/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp +++ b/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp @@ -236,7 +236,7 @@ public: QSharedPointer file = resolveFile(false); if (file) { switch (owner) { - case OwnerUser: + case OwnerUser: { QMutexLocker lock(&file->mutex); return file->userId; -- cgit v0.12 From b04df748d8c170a969eb6a3097cbda7a08fb3ea1 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Thu, 25 Nov 2010 10:11:01 +1000 Subject: Document KeyEvent::modifiers Task-number: QTBUG-15569 --- .../graphicsitems/qdeclarativeevents.cpp | 30 +++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativeevents.cpp b/src/declarative/graphicsitems/qdeclarativeevents.cpp index 61fd562..4b5e777 100644 --- a/src/declarative/graphicsitems/qdeclarativeevents.cpp +++ b/src/declarative/graphicsitems/qdeclarativeevents.cpp @@ -108,6 +108,34 @@ Item { so that ancestor items do not also respond to the same event. */ +/*! + \qmlproperty int KeyEvent::modifiers + + This property holds the keyboard modifier flags that existed immediately + before the event occurred. + + It contains a bitwise combination of: + \list + \o Qt.NoModifier - No modifier key is pressed. + \o Qt.ShiftModifier - A Shift key on the keyboard is pressed. + \o Qt.ControlModifier - A Ctrl key on the keyboard is pressed. + \o Qt.AltModifier - An Alt key on the keyboard is pressed. + \o Qt.MetaModifier - A Meta key on the keyboard is pressed. + \o Qt.KeypadModifier - A keypad button is pressed. + \endlist + + For example, to react to a Shift key + Enter key combination: + \qml + Item { + focus: true + Keys.onPressed: { + if ((event.key == Qt.Key_Enter) && (event.modifiers & Qt.ShiftModifier)) + doSomething(); + } + } + \endqml +*/ + /*! \qmlclass MouseEvent QDeclarativeMouseEvent @@ -199,7 +227,7 @@ Item { \qml MouseArea { onClicked: { - if (mouse.button == Qt.LeftButton && mouse.modifiers & Qt.ShiftModifier) + if ((mouse.button == Qt.LeftButton) && (mouse.modifiers & Qt.ShiftModifier)) doSomething(); } } -- cgit v0.12 From 9e353ea7a1fedd020d39e83322286931f536dc16 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Thu, 25 Nov 2010 13:36:24 +1000 Subject: End painting of Rectangle pixmap before inserting it to pixmap cache to avoid an unnecessary copy Task-number: QTBUG-15534 Reviewed-by: Martin Jones --- src/declarative/graphicsitems/qdeclarativerectangle.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativerectangle.cpp b/src/declarative/graphicsitems/qdeclarativerectangle.cpp index 7686dde..dedb3f7 100644 --- a/src/declarative/graphicsitems/qdeclarativerectangle.cpp +++ b/src/declarative/graphicsitems/qdeclarativerectangle.cpp @@ -420,6 +420,10 @@ void QDeclarativeRectangle::generateRoundedRect() p.drawRoundedRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, d->rectImage.width()-(pw+1), d->rectImage.height()-(pw+1)), d->radius, d->radius); else p.drawRoundedRect(QRectF(qreal(pw)/2, qreal(pw)/2, d->rectImage.width()-pw, d->rectImage.height()-pw), d->radius, d->radius); + + // end painting before inserting pixmap + // to pixmap cache to avoid a deep copy + p.end(); QPixmapCache::insert(key, d->rectImage); } } @@ -454,6 +458,10 @@ void QDeclarativeRectangle::generateBorderedRect() p.drawRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, d->rectImage.width()-(pw+1), d->rectImage.height()-(pw+1))); else p.drawRect(QRectF(qreal(pw)/2, qreal(pw)/2, d->rectImage.width()-pw, d->rectImage.height()-pw)); + + // end painting before inserting pixmap + // to pixmap cache to avoid a deep copy + p.end(); QPixmapCache::insert(key, d->rectImage); } } -- cgit v0.12 From bb575d308350036eff913a6b61c680712613c540 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Thu, 25 Nov 2010 14:21:11 +1000 Subject: Update visual tests Just a frame here or there, probably warranted. --- .../qmlvisual/qdeclarativeflickable/data/flickable-horizontal.qml | 2 +- .../qmlvisual/qdeclarativeflickable/data/flickable-vertical.qml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-horizontal.qml b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-horizontal.qml index 5cb4f78..a94aca8 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-horizontal.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-horizontal.qml @@ -994,7 +994,7 @@ VisualTest { } Frame { msec: 3264 - hash: "10a89da9887cb4bbd812c090a8a56797" + hash: "244c12e82ee0b2528a0dbb02a8b8134a" } Mouse { type: 5 diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-vertical.qml b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-vertical.qml index 8c746bf..920a48f 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-vertical.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-vertical.qml @@ -1922,7 +1922,7 @@ VisualTest { } Frame { msec: 4480 - hash: "155a834ddaa7128b6f5a2a406b340315" + hash: "16b99c9cf5297a5251869a3935084cf7" } Mouse { type: 5 @@ -2106,7 +2106,7 @@ VisualTest { } Frame { msec: 4768 - hash: "155a834ddaa7128b6f5a2a406b340315" + hash: "d315f82e175361fed83193ce550cb6e9" } Mouse { type: 5 -- cgit v0.12 From 852f4811453cb0b082748f2fcefac5898e603ab0 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Thu, 25 Nov 2010 15:33:13 +1000 Subject: Fixup visual tests on Mac Disable sub-pixel antialiasing and skip text on 10.5 --- tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp | 8 +++++++- tools/qml/qdeclarativetester.cpp | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp index 2a15102..18fbfca 100644 --- a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp +++ b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp @@ -105,10 +105,16 @@ void tst_qmlvisual::visual_data() files << findQmlFiles(QDir(QT_TEST_SOURCE_DIR)); if (qgetenv("QMLVISUAL_ALL") != "1") { #if defined(Q_WS_X11) - //Text on X11 varies per distro - and the CI system is currently using something outdated. + //Text on X11 varies per version - and the CI system is currently using something outdated. foreach(const QString &str, files.filter(QRegExp(".*text.*"))) files.removeAll(str); #endif +#if defined(Q_WS_MAC) + //Text on Mac also varies per version. Only check the text on 10.6 + if(QSysInfo::MacintoshVersion != QSysInfo::MV_10_6) + foreach(const QString &str, files.filter(QRegExp(".*text.*"))) + files.removeAll(str); +#endif #if defined(Q_WS_QWS) //We don't want QWS test results to mire down the CI system files.clear(); diff --git a/tools/qml/qdeclarativetester.cpp b/tools/qml/qdeclarativetester.cpp index a516fd7..e3a1f59 100644 --- a/tools/qml/qdeclarativetester.cpp +++ b/tools/qml/qdeclarativetester.cpp @@ -274,7 +274,16 @@ void QDeclarativeTester::updateCurrentTime(int msec) if (options & QDeclarativeViewer::TestImages) { img.fill(qRgb(255,255,255)); + +#ifdef Q_WS_MAC + bool oldSmooth = qt_applefontsmoothing_enabled; + qt_applefontsmoothing_enabled = false; +#endif QPainter p(&img); +#ifdef Q_WS_MAC + qt_applefontsmoothing_enabled = oldSmooth; +#endif + m_view->render(&p); } -- cgit v0.12 From d11f5011f84099a6558840118588c293605b05d4 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 25 Nov 2010 17:36:11 +1000 Subject: Update qml visual tests for mac. --- .../data-MAC/flickable-horizontal.0.png | Bin 0 -> 1439 bytes .../data-MAC/flickable-horizontal.1.png | Bin 0 -> 1424 bytes .../data-MAC/flickable-horizontal.2.png | Bin 0 -> 1428 bytes .../data-MAC/flickable-horizontal.3.png | Bin 0 -> 1396 bytes .../data-MAC/flickable-horizontal.4.png | Bin 0 -> 1454 bytes .../data-MAC/flickable-horizontal.qml | 1575 +++++++++++++++++ .../data-MAC/follow.0.png | Bin 0 -> 941 bytes .../data-MAC/follow.1.png | Bin 0 -> 975 bytes .../data-MAC/follow.2.png | Bin 0 -> 1235 bytes .../data-MAC/follow.3.png | Bin 0 -> 1225 bytes .../data-MAC/follow.4.png | Bin 0 -> 1247 bytes .../data-MAC/follow.5.png | Bin 0 -> 1243 bytes .../data-MAC/follow.6.png | Bin 0 -> 1234 bytes .../data-MAC/follow.7.png | Bin 0 -> 1242 bytes .../data-MAC/follow.qml | 1763 ++++++++++++++++++++ .../align/data-MAC/multilineAlign.0.png | Bin 2569 -> 801 bytes .../align/data-MAC/multilineAlign.qml | 118 +- .../baseline/data-MAC/parentanchor.0.png | Bin 5648 -> 1392 bytes .../baseline/data-MAC/parentanchor.qml | 60 +- .../bugs/data-MAC/QTBUG-14469.0.png | Bin 0 -> 210 bytes .../bugs/data-MAC/QTBUG-14469.1.png | Bin 0 -> 270 bytes .../qdeclarativetext/bugs/data-MAC/QTBUG-14469.qml | 475 ++++++ .../qdeclarativetext/data-MAC/qtbug_14865.0.png | Bin 1083 -> 322 bytes .../qdeclarativetext/data-MAC/qtbug_14865.1.png | Bin 1083 -> 322 bytes .../qdeclarativetext/data-MAC/qtbug_14865.qml | 122 +- .../qdeclarativetext/elide/data-MAC/elide.0.png | Bin 1353 -> 491 bytes .../qdeclarativetext/elide/data-MAC/elide.1.png | Bin 1353 -> 491 bytes .../qdeclarativetext/elide/data-MAC/elide.qml | 130 +- .../qdeclarativetext/elide/data-MAC/elide2.0.png | Bin 3572 -> 1240 bytes .../qdeclarativetext/elide/data-MAC/elide2.1.png | Bin 3320 -> 1106 bytes .../qdeclarativetext/elide/data-MAC/elide2.2.png | Bin 2953 -> 999 bytes .../qdeclarativetext/elide/data-MAC/elide2.3.png | Bin 2386 -> 864 bytes .../qdeclarativetext/elide/data-MAC/elide2.4.png | Bin 1650 -> 703 bytes .../qdeclarativetext/elide/data-MAC/elide2.qml | 480 +++--- .../elide/data-MAC/multilength.0.png | Bin 2748 -> 791 bytes .../elide/data-MAC/multilength.1.png | Bin 3064 -> 854 bytes .../elide/data-MAC/multilength.qml | 144 +- .../qdeclarativetext/font/data-MAC/plaintext.0.png | Bin 60155 -> 14238 bytes .../font/data-MAC/plaintext2.0.png | Bin 3805 -> 1563 bytes .../font/data-MAC/plaintext3.0.png | Bin 21056 -> 6348 bytes .../qdeclarativetext/font/data-MAC/richtext.0.png | Bin 62489 -> 9321 bytes .../qdeclarativetext/font/data-MAC/richtext2.0.png | Bin 29962 -> 10663 bytes .../qdeclarativetextinput/data-MAC/echoMode.1.png | Bin 715 -> 343 bytes .../qdeclarativetextinput/data-MAC/echoMode.2.png | Bin 1295 -> 461 bytes .../qdeclarativetextinput/data-MAC/echoMode.3.png | Bin 1922 -> 539 bytes .../qdeclarativetextinput/data-MAC/echoMode.qml | 332 ++-- .../data-MAC/usingLineEdit.qml | 12 +- 47 files changed, 4512 insertions(+), 699 deletions(-) create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.0.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.1.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.2.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.3.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.4.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.qml create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.0.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.1.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.2.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.3.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.4.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.5.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.6.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.7.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.qml create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativetext/bugs/data-MAC/QTBUG-14469.0.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativetext/bugs/data-MAC/QTBUG-14469.1.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativetext/bugs/data-MAC/QTBUG-14469.qml diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.0.png b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.0.png new file mode 100644 index 0000000..9a81b29 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.1.png b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.1.png new file mode 100644 index 0000000..2d9c4fd Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.2.png b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.2.png new file mode 100644 index 0000000..2bb0cb0 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.3.png b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.3.png new file mode 100644 index 0000000..8260a65 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.4.png b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.4.png new file mode 100644 index 0000000..0abcbc2 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.qml b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.qml new file mode 100644 index 0000000..f1bb428 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data-MAC/flickable-horizontal.qml @@ -0,0 +1,1575 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "flickable-horizontal.0.png" + } + Frame { + msec: 32 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 48 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 64 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 80 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 96 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 112 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 128 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 144 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 160 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 176 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 192 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 208 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 224 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 240 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 256 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 272 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 288 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 304 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 320 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 336 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 352 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 368 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 384 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 400 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 416 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 432 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 448 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 464 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 480 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 496 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 512 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 528 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 544 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 560 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 576 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 592 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 608 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 624 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 640 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 656 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 672 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 688 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 704 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 720 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 447; y: 145 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 736 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 752 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 768 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 446; y: 145 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 784 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 440; y: 146 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 800 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 425; y: 151 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 407; y: 157 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 816 + hash: "c92e345e4ffdb30c28d9d5aa5400bd30" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 359; y: 169 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 832 + hash: "90f94986ab44ab59618e9a5da17b8cc9" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 309; y: 181 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 848 + hash: "0154a65f8693b98576101ac1c2fc8761" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 282; y: 187 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 282; y: 187 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 864 + hash: "792c1b5267f14c891dae2348a8188a92" + } + Frame { + msec: 880 + hash: "15ce9e88d4ad2e698bf167d1432c0b8a" + } + Frame { + msec: 896 + hash: "8f4109ef4c24d286d73f689565a0d056" + } + Frame { + msec: 912 + hash: "f5728190bf5c94742686f063b4a4b09b" + } + Frame { + msec: 928 + hash: "a38c7527a9a818b7bc25466b0e4939f9" + } + Frame { + msec: 944 + hash: "ed3902455fc31a4e3232308b815a4daa" + } + Frame { + msec: 960 + hash: "a2093589363ac2d50491412e99e0193a" + } + Frame { + msec: 976 + image: "flickable-horizontal.1.png" + } + Frame { + msec: 992 + hash: "c32349580e3a9586cc1133c935607cf0" + } + Frame { + msec: 1008 + hash: "cd2068492e346eb20d50aee69e3a3559" + } + Frame { + msec: 1024 + hash: "f43a1a38894b8ffad009ba995d84b0ee" + } + Frame { + msec: 1040 + hash: "2d5c4a73df2a054801571f1ce119e31f" + } + Frame { + msec: 1056 + hash: "b8825cc6bdca8102a655d797ea41b5b1" + } + Frame { + msec: 1072 + hash: "3f0be15b85220743d004f2d54b6e137c" + } + Frame { + msec: 1088 + hash: "4b0952d33149b44ffa0a06723a4116c7" + } + Frame { + msec: 1104 + hash: "9056bda43259e92cfe56fdf394e2ca54" + } + Frame { + msec: 1120 + hash: "82ec9f09d2303e5b0b9c05b9a10a84db" + } + Frame { + msec: 1136 + hash: "751a9b3054c09d900364d7c9cac8bc2b" + } + Frame { + msec: 1152 + hash: "17dfdfef20f9da7e8b6f16df974baea9" + } + Frame { + msec: 1168 + hash: "108e6d9a5a81df32823bfd7a90a000a7" + } + Frame { + msec: 1184 + hash: "71dd0d55a3e837d3a8e4b4e318579ade" + } + Frame { + msec: 1200 + hash: "8013cdb2615bca89134ea040409af509" + } + Frame { + msec: 1216 + hash: "4b2826ad4c755690bd837994133f5fac" + } + Frame { + msec: 1232 + hash: "52d0da7f138bd37ac587a448d6402aca" + } + Frame { + msec: 1248 + hash: "e634724c5bb294d338210845bf64d2cf" + } + Frame { + msec: 1264 + hash: "59bc5f0d057ee431f289806377f19213" + } + Frame { + msec: 1280 + hash: "6ef2c5f7766c2cc77b30d636bfaa4422" + } + Frame { + msec: 1296 + hash: "578d056c3db094420dbaa51bd08ced20" + } + Frame { + msec: 1312 + hash: "14c6f7a04a52caffefa07af556ccb262" + } + Frame { + msec: 1328 + hash: "7cb63d56fec144d0509ce219fc6fe459" + } + Frame { + msec: 1344 + hash: "462dafa7f6427aecf6c28a5dcf5a10cc" + } + Frame { + msec: 1360 + hash: "45360814f985ed780a443568a91fc170" + } + Frame { + msec: 1376 + hash: "0d18ceb2436e4f7eb56a3443fab706e6" + } + Frame { + msec: 1392 + hash: "1d83f367ba9f7f1d4496208271e925ed" + } + Frame { + msec: 1408 + hash: "fdbd00ee4c122aef779df42ea53f403a" + } + Frame { + msec: 1424 + hash: "bedd1cb304efd4851813b39a746198a4" + } + Frame { + msec: 1440 + hash: "9aa7bed86efa9634466736f20ee0ab5b" + } + Frame { + msec: 1456 + hash: "00fc8186a7ae44e10195a7b13defa0d2" + } + Frame { + msec: 1472 + hash: "42d6e8e0bbed879ed63644c83e61e7bd" + } + Frame { + msec: 1488 + hash: "df074f8c210249e5ef652349479b6325" + } + Frame { + msec: 1504 + hash: "4f94020437e35cf44dd3576997990ab7" + } + Frame { + msec: 1520 + hash: "8ca6c3b4fa3be73ac35073356b680a35" + } + Frame { + msec: 1536 + hash: "c25eee1c5791383ebc59974e7754eacb" + } + Frame { + msec: 1552 + hash: "f4917ada78942428cc6b9aa5e56c013d" + } + Frame { + msec: 1568 + hash: "23e1e607101fc7260a4ac841344f5fe0" + } + Frame { + msec: 1584 + hash: "2dcc7d187d8e0493e5766efbf09ef37c" + } + Frame { + msec: 1600 + hash: "c1e5602753e80cf44d7b330140c6912e" + } + Frame { + msec: 1616 + hash: "febaf72d01a3763461b4b7d2ddd7a23e" + } + Frame { + msec: 1632 + hash: "071262b911b61576f451be25691a57cf" + } + Frame { + msec: 1648 + hash: "44705db9289fd8753b9d63e8bc963b38" + } + Frame { + msec: 1664 + hash: "0c41d7b7d36bd083abfc0b83b862cad9" + } + Frame { + msec: 1680 + hash: "0c41d7b7d36bd083abfc0b83b862cad9" + } + Frame { + msec: 1696 + hash: "071262b911b61576f451be25691a57cf" + } + Frame { + msec: 1712 + hash: "a00aa90e894b48203b0446ca287ee712" + } + Frame { + msec: 1728 + hash: "26c9ca53ee4b084c6595ad65bf4880df" + } + Frame { + msec: 1744 + hash: "f4917ada78942428cc6b9aa5e56c013d" + } + Frame { + msec: 1760 + hash: "ffedee7bf2d8099e361b8b1706b03f88" + } + Frame { + msec: 1776 + hash: "1778ef1629ce977015b641448b46634f" + } + Frame { + msec: 1792 + hash: "42d6e8e0bbed879ed63644c83e61e7bd" + } + Frame { + msec: 1808 + hash: "99e843ec69b79b79b0792e0a2f28cd1b" + } + Frame { + msec: 1824 + hash: "8b3ebca70b50a6a93823e015ea80f0f9" + } + Frame { + msec: 1840 + hash: "8eaa7f076064ce55051237b04861e408" + } + Frame { + msec: 1856 + hash: "6acc0ca5e5808d911287edfa78c8ac02" + } + Frame { + msec: 1872 + hash: "e9f05899e0b53c21f6efe834095a3ea4" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 91; y: 208 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 93; y: 209 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1888 + hash: "e9f05899e0b53c21f6efe834095a3ea4" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 99; y: 210 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 108; y: 210 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1904 + hash: "d2dece405f5f6ed1de2acb6615a931de" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 142; y: 214 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1920 + hash: "21e0f21edc77424e8327c9a3350ecc1d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 198; y: 216 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1936 + image: "flickable-horizontal.2.png" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 229; y: 218 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 266; y: 220 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1952 + hash: "c10c8b0c94f899414d8b3ef0b7c97646" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 322; y: 223 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 322; y: 223 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1968 + hash: "807aff4e6c96a9d0de7fa55e233446b1" + } + Frame { + msec: 1984 + hash: "dbd02848cefacbb26f4bcb7d8f073d6c" + } + Frame { + msec: 2000 + hash: "9a60608d8ea1b39fa2d3851873f2f08e" + } + Frame { + msec: 2016 + hash: "e7b3e3a40281f63889808211d6746374" + } + Frame { + msec: 2032 + hash: "188c225c46ec00105df230bfeea09974" + } + Frame { + msec: 2048 + hash: "e2e977b42e91d8c5dee57fd8245692eb" + } + Frame { + msec: 2064 + hash: "ca2f12fb173c405f95e608858ab982ad" + } + Frame { + msec: 2080 + hash: "fa86ee5f25fa425cf2569c8ef570b9d8" + } + Frame { + msec: 2096 + hash: "9b74656866fb8c7394bbbecec6414aca" + } + Frame { + msec: 2112 + hash: "87147326d1baab174c0f9a5ccdc2cb84" + } + Frame { + msec: 2128 + hash: "c0d00f98c71bf3f8e5954b45fbab95a8" + } + Frame { + msec: 2144 + hash: "c087d1d62e56e573b55c1d8599bba8a6" + } + Frame { + msec: 2160 + hash: "dd5a94c6febdee58e8f115cb75131aaa" + } + Frame { + msec: 2176 + hash: "a7465d6137f865f512ce65ceb29533b4" + } + Frame { + msec: 2192 + hash: "409086f6bb661aab8b548fea56d7e6b1" + } + Frame { + msec: 2208 + hash: "6a22911e0fb58df31271baa463ff599d" + } + Frame { + msec: 2224 + hash: "c4f6dd30d5fdfcf91a8b29cf5c622423" + } + Frame { + msec: 2240 + hash: "5a95b83f237c7243a198a43e9a587179" + } + Frame { + msec: 2256 + hash: "d79ed290efc6dbd976d574bf0b14a6a3" + } + Frame { + msec: 2272 + hash: "a7bcb436e96d7c981852239462573495" + } + Frame { + msec: 2288 + hash: "f63cc82e351daab503e316f8b516990f" + } + Frame { + msec: 2304 + hash: "4ea63cd25a1424042ffc60549a78563c" + } + Frame { + msec: 2320 + hash: "ef0fb776012575b3b0dbf6e5f4dee571" + } + Frame { + msec: 2336 + hash: "e2508faec7737be2666d87ad715b5f74" + } + Frame { + msec: 2352 + hash: "9fe4e897c6b853f774d11817a0eb53bf" + } + Frame { + msec: 2368 + hash: "c122ce2e73cbfedcc99d649c21d91f9d" + } + Frame { + msec: 2384 + hash: "883b8b180853f1f432ae98ddfe1b6ce3" + } + Frame { + msec: 2400 + hash: "d0808284e431da60f61d571c257a3011" + } + Frame { + msec: 2416 + hash: "df90f19450bf4d9496aab987a89e3a02" + } + Frame { + msec: 2432 + hash: "5640c1e64556b90e7fbd4448fa9db462" + } + Frame { + msec: 2448 + hash: "6d9b5c2f7d0dedbbc444e69bb39fed08" + } + Frame { + msec: 2464 + hash: "485c4a8049068cf73bf22db5fd3618be" + } + Frame { + msec: 2480 + hash: "9e25da59c9e7e4cf7796902e8e2ff92a" + } + Frame { + msec: 2496 + hash: "bd45e8f2442d7c1a1b16a762bc29e7cf" + } + Frame { + msec: 2512 + hash: "ec1013d23e581dbb39b1549d2e1b3b32" + } + Frame { + msec: 2528 + hash: "1ea3c2fde8ee3a14406e027f2124d793" + } + Frame { + msec: 2544 + hash: "3c3f31a05fb2f32538872c9fa158aaab" + } + Frame { + msec: 2560 + hash: "05a84d9c55e634ec01edd2a63e13613b" + } + Frame { + msec: 2576 + hash: "0f7ccd2da58e2e73b0ab18bb681dafd5" + } + Frame { + msec: 2592 + hash: "e481ff78029f8bc4bf7c697db6824f6a" + } + Frame { + msec: 2608 + hash: "efb92b8b7a90acabeb4a8d5cae52fe3c" + } + Frame { + msec: 2624 + hash: "4728dd0fac4edf40cfd5ef5a422b4ed9" + } + Frame { + msec: 2640 + hash: "27641dcd772c979ae22d12bfbadbb67f" + } + Frame { + msec: 2656 + hash: "26268714105bc4832d336a38a859fc50" + } + Frame { + msec: 2672 + hash: "caf0d351d3b6914ca52853a30643ea48" + } + Frame { + msec: 2688 + hash: "319824b1143925162f04aaddcfaa65d9" + } + Frame { + msec: 2704 + hash: "73aa36815f34bf5e005000e7da38555e" + } + Frame { + msec: 2720 + hash: "73aa36815f34bf5e005000e7da38555e" + } + Frame { + msec: 2736 + hash: "319824b1143925162f04aaddcfaa65d9" + } + Frame { + msec: 2752 + hash: "caf0d351d3b6914ca52853a30643ea48" + } + Frame { + msec: 2768 + hash: "6608412ee80d14e13a1a05fb4716e719" + } + Frame { + msec: 2784 + hash: "f4f6f002fb76407a5120329972285dc4" + } + Frame { + msec: 2800 + hash: "474d8b566b9e4ef7dc125a8df30ccbb1" + } + Frame { + msec: 2816 + hash: "0133138f30be4ffc7f3af3d9f477c4b4" + } + Frame { + msec: 2832 + hash: "e9ee9d7d0ab9dcea3f28ae71ee19270f" + } + Frame { + msec: 2848 + hash: "9fd9eb665a42b48583bc28c6c0118799" + } + Frame { + msec: 2864 + hash: "94231107bc4a7e900fe5f4eb823bd9bf" + } + Frame { + msec: 2880 + hash: "6011b10728fb1c83f10d3c27366ea3a5" + } + Frame { + msec: 2896 + image: "flickable-horizontal.3.png" + } + Frame { + msec: 2912 + hash: "e456c5fddb5fbcb02662716f19755622" + } + Frame { + msec: 2928 + hash: "88cef15940302e2b8b43e73234fd7b9c" + } + Frame { + msec: 2944 + hash: "041aecec2b0b0d59a56e1dd26b45cab1" + } + Frame { + msec: 2960 + hash: "0d519463c713f3da46ecacd155e1a0f3" + } + Frame { + msec: 2976 + hash: "5dd0c855b97d298244fb599c9f781651" + } + Frame { + msec: 2992 + hash: "8677cec5e559e51095d89abfeda8e542" + } + Frame { + msec: 3008 + hash: "b05fb6e798ab3fed940b5ac4d88ca378" + } + Frame { + msec: 3024 + hash: "6bc9cc0d3b11ea91856296b0ec934a8b" + } + Frame { + msec: 3040 + hash: "f4e63f3af69dacbf2d1d719d4d03a266" + } + Frame { + msec: 3056 + hash: "31ab08997eb86fab062a3128aecbccb5" + } + Frame { + msec: 3072 + hash: "90736b240ba1e634bd0ea86423908e16" + } + Frame { + msec: 3088 + hash: "90736b240ba1e634bd0ea86423908e16" + } + Frame { + msec: 3104 + hash: "e74982557dc06aac572078840c7e889a" + } + Frame { + msec: 3120 + hash: "e74982557dc06aac572078840c7e889a" + } + Frame { + msec: 3136 + hash: "ca30c14c7344d1711a35c707f8804f6e" + } + Frame { + msec: 3152 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 3168 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 3184 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 3200 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 412; y: 214 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3216 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 3232 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 3248 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 408; y: 214 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 407; y: 214 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3264 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 403; y: 214 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3280 + hash: "1991cbb0fb053937f922731d5716032c" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 398; y: 214 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3296 + hash: "df447575a4734bb5bd9badc6e27d98e4" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 391; y: 214 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3312 + hash: "0fbfe1e0d7fb54450188398aa40690cd" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 383; y: 214 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3328 + hash: "cb62e60296046c73d301d7186e14faed" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 369; y: 213 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3344 + hash: "909cbd1292476584554e22232cb43639" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 352; y: 211 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3360 + hash: "e63b7e502dfb2834c06a969b683b9bd3" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 331; y: 210 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3376 + hash: "4ea63cd25a1424042ffc60549a78563c" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 314; y: 210 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3392 + hash: "77e39d2d4bfcacecdae4f014e4506d71" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 300; y: 210 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3408 + hash: "db576eca8bad67cb8b994f12fc448969" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 288; y: 210 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3424 + hash: "efeb3f616da9d78505c3c82fc34ee31c" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 278; y: 210 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3440 + hash: "e4f8bb02f8ac6bc40e1801cc8f360078" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 266; y: 210 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3456 + hash: "82118ef71809e3867717232c4d9c5518" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 252; y: 208 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3472 + hash: "5363451c696f6c6eb792b23d086243d7" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 238; y: 208 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3488 + hash: "fe6afe8ae8a7c216a1cffc5515f273d5" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 227; y: 206 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3504 + hash: "9b165741d86c70380c15e15cff3fabb6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 224; y: 206 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3520 + hash: "f5e176355468f4fa224d4dfcdd7525a3" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 222; y: 206 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3536 + hash: "8c5a14a76e052cc6503a3e78245d1da3" + } + Frame { + msec: 3552 + hash: "8c5a14a76e052cc6503a3e78245d1da3" + } + Frame { + msec: 3568 + hash: "8c5a14a76e052cc6503a3e78245d1da3" + } + Frame { + msec: 3584 + hash: "8c5a14a76e052cc6503a3e78245d1da3" + } + Frame { + msec: 3600 + hash: "8c5a14a76e052cc6503a3e78245d1da3" + } + Frame { + msec: 3616 + hash: "8c5a14a76e052cc6503a3e78245d1da3" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 224; y: 206 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3632 + hash: "f5e176355468f4fa224d4dfcdd7525a3" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 232; y: 204 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3648 + hash: "acf538fce5f1b90b83474d9898b7cdd7" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 246; y: 203 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3664 + hash: "5a0ee016b8732fbc36064e8a35d91215" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 265; y: 203 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3680 + hash: "8fd06a14c1de175813845ce8f07db6ec" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 292; y: 201 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3696 + hash: "26b0ff6ffda0725e0800f7ea3af510ef" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 310; y: 201 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3712 + hash: "80443f134511be0356a687c9b542b3e7" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 321; y: 199 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3728 + hash: "3eeb98a829d29b3dc52f3d145ac49d58" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 323; y: 199 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3744 + hash: "f4d43069b16f41a30e5549aae911d4cd" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 324; y: 199 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3760 + hash: "661c89fa832f0abdcf4ae0c9e8e2d18f" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 324; y: 199 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3776 + hash: "661c89fa832f0abdcf4ae0c9e8e2d18f" + } + Frame { + msec: 3792 + hash: "1520f54b6c8606b9e8372c5c06180453" + } + Frame { + msec: 3808 + hash: "0fcf5e2ce47348cbb5bb485f101fe5ac" + } + Frame { + msec: 3824 + hash: "2eb070e69de07c89830543e0475fc110" + } + Frame { + msec: 3840 + hash: "d73c1059219c0655968af268d22e2c18" + } + Frame { + msec: 3856 + image: "flickable-horizontal.4.png" + } + Frame { + msec: 3872 + hash: "cc969b2c64839ca6d3b5069c0ed938d0" + } + Frame { + msec: 3888 + hash: "1f819e18d1297a1c7eeebb7b040bdef8" + } + Frame { + msec: 3904 + hash: "3643b99afbd8af0953cb39b2c8c04b9f" + } + Frame { + msec: 3920 + hash: "713fd2e2fa38ab27604cb9cae59f1777" + } + Frame { + msec: 3936 + hash: "e2508faec7737be2666d87ad715b5f74" + } + Frame { + msec: 3952 + hash: "fc33b1c7479caeff676ffd885a18d618" + } + Frame { + msec: 3968 + hash: "aca01143db4f870a56bb7546e84cbc5e" + } + Frame { + msec: 3984 + hash: "442b58c39fd3745c61a1eb5043fcbb53" + } + Frame { + msec: 4000 + hash: "7983d7183cc11d6819fa0a006c2d67b4" + } + Frame { + msec: 4016 + hash: "9fe4e897c6b853f774d11817a0eb53bf" + } + Frame { + msec: 4032 + hash: "43f528c81ccfa5b9921dfa3564a24c68" + } + Frame { + msec: 4048 + hash: "dfe04ff0b3ccf205bb38beeab58a4411" + } + Frame { + msec: 4064 + hash: "32ff30b50b500e9feb51e8eef205783c" + } + Frame { + msec: 4080 + hash: "7d83ab4c336b05bcf2cde4e7d8031f6c" + } + Frame { + msec: 4096 + hash: "c92e345e4ffdb30c28d9d5aa5400bd30" + } + Frame { + msec: 4112 + hash: "02eec604d0c00965aae4ac61b91bdc22" + } + Frame { + msec: 4128 + hash: "df447575a4734bb5bd9badc6e27d98e4" + } + Frame { + msec: 4144 + hash: "bac10d8f94a39573313b3b8b2f871c49" + } + Frame { + msec: 4160 + hash: "e5944c5dc6dec8f0c28b7ec3cd58723d" + } + Frame { + msec: 4176 + hash: "1991cbb0fb053937f922731d5716032c" + } + Frame { + msec: 4192 + hash: "50d6538bcaffc343f6626635a3e5899c" + } + Frame { + msec: 4208 + hash: "f3613f57cdb9ed38d8e3fa636962aa99" + } + Frame { + msec: 4224 + hash: "10a89da9887cb4bbd812c090a8a56797" + } + Frame { + msec: 4240 + hash: "89ba74d46970ad2edff701475c059ec8" + } + Frame { + msec: 4256 + hash: "6e8b84c70e81578a2216e9e975b35434" + } + Frame { + msec: 4272 + hash: "6e8b84c70e81578a2216e9e975b35434" + } + Frame { + msec: 4288 + hash: "883b8b180853f1f432ae98ddfe1b6ce3" + } + Frame { + msec: 4304 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 4320 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 4336 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 4352 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 4368 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 4384 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 4400 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 4416 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 4432 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 4448 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 4464 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 4480 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 4496 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 4512 + hash: "e616110d39009f0d636b816828cc0ccb" + } + Frame { + msec: 4528 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 4544 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 4560 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 4576 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 4592 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 4608 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 4624 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 4640 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 4656 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 4672 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 4688 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } + Frame { + msec: 4704 + hash: "244c12e82ee0b2528a0dbb02a8b8134a" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.0.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.0.png new file mode 100644 index 0000000..8714f58 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.1.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.1.png new file mode 100644 index 0000000..05e4a98 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.2.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.2.png new file mode 100644 index 0000000..29df073 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.3.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.3.png new file mode 100644 index 0000000..b38486e Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.4.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.4.png new file mode 100644 index 0000000..4de915b Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.5.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.5.png new file mode 100644 index 0000000..61a4684 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.5.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.6.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.6.png new file mode 100644 index 0000000..4ce5e30 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.6.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.7.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.7.png new file mode 100644 index 0000000..2376b13 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.7.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.qml b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.qml new file mode 100644 index 0000000..893355b --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data-MAC/follow.qml @@ -0,0 +1,1763 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "follow.0.png" + } + Frame { + msec: 32 + hash: "e94ba580322887dbbbf9cb6309e39c23" + } + Frame { + msec: 48 + hash: "787a59cda2c0b27d8959026e6d1b9427" + } + Frame { + msec: 64 + hash: "9ca724d4b31aa16015b5cbb50eea0c3a" + } + Frame { + msec: 80 + hash: "8a2c62a0190da1b7c1bade243baea6b8" + } + Frame { + msec: 96 + hash: "e129bebca7ad348c3134569d8eee4efc" + } + Frame { + msec: 112 + hash: "fd6387415e1c02fe6d17d9c3aa1d1ed8" + } + Frame { + msec: 128 + hash: "a82a4042fdca7c30facd2c4740c455f7" + } + Frame { + msec: 144 + hash: "62195722eb3acbfbad137ec71fd50bfe" + } + Frame { + msec: 160 + hash: "449819cdc880d59650732b5447ec6237" + } + Frame { + msec: 176 + hash: "552a838ebcacc0e08fa93b64a2433831" + } + Frame { + msec: 192 + hash: "3984992606d54f05eb31dd0974af2183" + } + Frame { + msec: 208 + hash: "3fd7225bbb0215ca8b6397580f2352a5" + } + Frame { + msec: 224 + hash: "0fd8f26f40a9049de1cf2a9493d579d1" + } + Frame { + msec: 240 + hash: "d08f0c57f071dc42e79fc5e0e3c32eeb" + } + Frame { + msec: 256 + hash: "084c2db330ee82cd032df248ecc9629d" + } + Frame { + msec: 272 + hash: "98da0d7f280d7fc4579c970c9a173b51" + } + Frame { + msec: 288 + hash: "4c819c54ced1b6ef0574417a7e11f2e7" + } + Frame { + msec: 304 + hash: "3dc5f7b412cb176c3b23d37cda3ef87c" + } + Frame { + msec: 320 + hash: "c368a01b43d94205c03f9c750c37f330" + } + Frame { + msec: 336 + hash: "8842bd0c8b17cac4fc9df84835999174" + } + Frame { + msec: 352 + hash: "26829e9c7ca44dfcb0c03852f4158a18" + } + Frame { + msec: 368 + hash: "ecffdb0888f1721e27b163e1f29a1950" + } + Frame { + msec: 384 + hash: "eaead96f2683c464a12df8aadba20691" + } + Frame { + msec: 400 + hash: "1e931963925bd208dce1ec9011372a3b" + } + Frame { + msec: 416 + hash: "1c3fd049001c1e883f21d0d1e0e32cba" + } + Frame { + msec: 432 + hash: "e8c3422ca637750ac52565594737d092" + } + Frame { + msec: 448 + hash: "b1c36322cf89e15a80af7c43f2aebca1" + } + Frame { + msec: 464 + hash: "f676c3171495f7bb2cb1812cfebaa17a" + } + Frame { + msec: 480 + hash: "255119e2efa99c8e31fee611aaaa5137" + } + Frame { + msec: 496 + hash: "e0bd32e3d44cfc2351db105f4595f18a" + } + Frame { + msec: 512 + hash: "b7f23b8f3769f929b42491efda7ebe19" + } + Frame { + msec: 528 + hash: "718cee11d869a8a8c5191cc0c09f2d30" + } + Frame { + msec: 544 + hash: "fbdbf92f8c5f507605ff50abc594682b" + } + Frame { + msec: 560 + hash: "c07fdc69c72b40d3c8dd1cc499008888" + } + Frame { + msec: 576 + hash: "38e17ecd537dc0f51211ad672a2ebb21" + } + Frame { + msec: 592 + hash: "2cbdc8728ef779c62f9938672986658a" + } + Frame { + msec: 608 + hash: "7fb66509d5d1df34861e9c70f9a579f0" + } + Frame { + msec: 624 + hash: "410b89392e859058718a08b79ec3d8fa" + } + Frame { + msec: 640 + hash: "9bd90f80700217d08dafed93b81ee9cf" + } + Frame { + msec: 656 + hash: "6d83671504a4274887b4e0d9bd2b24e7" + } + Frame { + msec: 672 + hash: "51ff7bd3fd4a776af33fce7b935b145c" + } + Frame { + msec: 688 + hash: "20f27392368b63b248bcd455cf3c9106" + } + Frame { + msec: 704 + hash: "1a5ab296bd55aa215c9b04a7ff6c73a1" + } + Frame { + msec: 720 + hash: "020fd7b14e8662fc006b0c39adca7c6a" + } + Frame { + msec: 736 + hash: "2619120bdb25a153963bdf05c4a16d44" + } + Frame { + msec: 752 + hash: "fd321314031efeb9ce71146764289d9f" + } + Frame { + msec: 768 + hash: "378a71f09445dfff284db919787cbf87" + } + Frame { + msec: 784 + hash: "d59eefe82ab8a00c903141dd9ea767ef" + } + Frame { + msec: 800 + hash: "0a65004d69a4567f2a5c7e84dab3a905" + } + Frame { + msec: 816 + hash: "92a4631716a51ff484ca14d9cfe05b2e" + } + Frame { + msec: 832 + hash: "87203f627cf410cad56d6ba38a140efa" + } + Frame { + msec: 848 + hash: "054cc085998cc059a6b7b4a7300dd36b" + } + Frame { + msec: 864 + hash: "af3fefeb908a0485c723d36f61eff0a4" + } + Frame { + msec: 880 + hash: "3f905d1e1ea79858b5a9bbfeab4eb255" + } + Frame { + msec: 896 + hash: "f935f1fc5f26a201098d894fca9a4d1f" + } + Frame { + msec: 912 + hash: "42b003dbb531da514716b9c32bdd3614" + } + Frame { + msec: 928 + hash: "a82fed83ee4efee7896b639c7691b13a" + } + Frame { + msec: 944 + hash: "31ad8cbf875233ea495330b0d3d4d2dd" + } + Frame { + msec: 960 + hash: "00586f2f1d49fa81f90f7b06614311b4" + } + Frame { + msec: 976 + image: "follow.1.png" + } + Frame { + msec: 992 + hash: "5d71ff48b865ad4266eb8292f981b04e" + } + Frame { + msec: 1008 + hash: "df599d934d131c92b209284277009efb" + } + Frame { + msec: 1024 + hash: "5aaf33d11eb70ffdfe89246c637caed7" + } + Frame { + msec: 1040 + hash: "9648cf623a66ded145c4fd23a42917b3" + } + Frame { + msec: 1056 + hash: "9d33c2cc44ceac5a527ddcf809a51df6" + } + Frame { + msec: 1072 + hash: "6d0ad2e0d012e53a03e246e6d5e49e13" + } + Frame { + msec: 1088 + hash: "d33fa68796e38b19f44571d11c1bcd33" + } + Frame { + msec: 1104 + hash: "636680f49bbf30b0fac31a6c581f18dd" + } + Frame { + msec: 1120 + hash: "66801dbc39301e6b46b244fe502e0340" + } + Frame { + msec: 1136 + hash: "f8fa6a033483279e78636f26493b10ac" + } + Frame { + msec: 1152 + hash: "11b46611550173df42986dee4339d907" + } + Frame { + msec: 1168 + hash: "5c9afdb519006079ee8d28b2b60d0b76" + } + Frame { + msec: 1184 + hash: "9a55c38b2cd8abf25fbe448c7ef80971" + } + Frame { + msec: 1200 + hash: "27ebdf1424e892b35c93ec009d942407" + } + Frame { + msec: 1216 + hash: "2d9e3f0ae56f7337012b51c4dd173108" + } + Frame { + msec: 1232 + hash: "e6f89ca892131d68ff1f4ca95c95d807" + } + Frame { + msec: 1248 + hash: "f75791f1b12a217d37acb09bdb114cc5" + } + Frame { + msec: 1264 + hash: "94c5ab1460fb1b0f957a9718b45bca36" + } + Frame { + msec: 1280 + hash: "e246c8a0ec3d01ea20258b24a5673fe1" + } + Frame { + msec: 1296 + hash: "529de7735e73409dff266d8c1275215c" + } + Frame { + msec: 1312 + hash: "330400763a670580570cb62241ebec62" + } + Frame { + msec: 1328 + hash: "ae444d1de9c509fc6f74136ca90f927a" + } + Frame { + msec: 1344 + hash: "c43631ca8ee90ea5dc7664be5bc45429" + } + Frame { + msec: 1360 + hash: "b366ac4a5b66c331a7667e9df0fc4eda" + } + Frame { + msec: 1376 + hash: "1c7f4c47a9c57a34787cc9703e99bff1" + } + Frame { + msec: 1392 + hash: "5555535609d512e8d34549b6624f74b8" + } + Frame { + msec: 1408 + hash: "be59df714541923494b59f31f57e310e" + } + Frame { + msec: 1424 + hash: "63e434f053032e54298f6e61c8d4da7d" + } + Frame { + msec: 1440 + hash: "b0bb838637eceb6f8993ebc5b887afed" + } + Frame { + msec: 1456 + hash: "fc39f33add4ebcaf578558ecd4aea281" + } + Frame { + msec: 1472 + hash: "3f36faa7cc1e5898d4d5890c47633ff3" + } + Frame { + msec: 1488 + hash: "4b328002b4461869b1f7de48e7291902" + } + Frame { + msec: 1504 + hash: "26252c63924d2abcaebea2c7caf1d7aa" + } + Frame { + msec: 1520 + hash: "a9a6023484ae439be86b2c2ff59dc40b" + } + Frame { + msec: 1536 + hash: "620dab11bd4aab84cc0d949c48dd9a5d" + } + Frame { + msec: 1552 + hash: "3b45ef80ee3e6fbbd3533bfa0d666e2f" + } + Frame { + msec: 1568 + hash: "b33306abcb6a8402e491b7216495c778" + } + Frame { + msec: 1584 + hash: "3cc52e8649a02e87785f1dc63f5c1efd" + } + Frame { + msec: 1600 + hash: "fe21141f48da685213ed9d7641b2e7a0" + } + Frame { + msec: 1616 + hash: "205aac4e822e20bd32f637256250f3c8" + } + Frame { + msec: 1632 + hash: "124df0948f36aaf6151556d301f4b930" + } + Frame { + msec: 1648 + hash: "c1701edd5eaf143fd1dbdc4a5324b48a" + } + Frame { + msec: 1664 + hash: "117402df55367c918a3835958f4ab1d6" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 195; y: 95 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1680 + hash: "73e3b86a1da28490cae4b03fdceefe19" + } + Frame { + msec: 1696 + hash: "172e329fb47d6db0180242990a84fe3b" + } + Frame { + msec: 1712 + hash: "82cf704cdfd406bab22689bc888ddc8d" + } + Frame { + msec: 1728 + hash: "4c288f198a06d1b2815d34c3c8f97051" + } + Frame { + msec: 1744 + hash: "6404d81456bb95a6b1c1ae55a181e40e" + } + Frame { + msec: 1760 + hash: "6c11b9f079936ea08d11aa1172bfd954" + } + Frame { + msec: 1776 + hash: "95388037c1f79a9dab951031f1d7c307" + } + Frame { + msec: 1792 + hash: "c4ee57d9bffbb5f0ff173db48eadf2e3" + } + Frame { + msec: 1808 + hash: "703ac9672a9c55cf08e6381ef76ac13c" + } + Frame { + msec: 1824 + hash: "ea7726d2a2923290398262c8f70d511e" + } + Frame { + msec: 1840 + hash: "9897c12603326a30c62381015c9adae3" + } + Frame { + msec: 1856 + hash: "a52aa37b10a05382f1b136896b7e00e8" + } + Frame { + msec: 1872 + hash: "a5acc1a45c95a67725e5e15084b7be18" + } + Frame { + msec: 1888 + hash: "c9fac8b5a4110493958d49b073ea96ed" + } + Frame { + msec: 1904 + hash: "6fca3a5c6d1cfbf1b905aca25b7785c5" + } + Frame { + msec: 1920 + hash: "a40e5e2744d1d84c8b9a45525801a745" + } + Frame { + msec: 1936 + image: "follow.2.png" + } + Frame { + msec: 1952 + hash: "b2f980ab19d44ee98ab3e82a19adfe2d" + } + Frame { + msec: 1968 + hash: "e01732623930aebefd76ab62c81dc722" + } + Frame { + msec: 1984 + hash: "3a59c6851bc89eb31100092b1ceddbd9" + } + Frame { + msec: 2000 + hash: "2949de19eacb9f35816aa7ba69614f2c" + } + Frame { + msec: 2016 + hash: "f2c4c1f4429cbb6bd10f2318b2cb6904" + } + Frame { + msec: 2032 + hash: "2c48af64162e7e028cd536dba03eab71" + } + Frame { + msec: 2048 + hash: "7fe13b8f9253f720b6591b396cfba2d1" + } + Frame { + msec: 2064 + hash: "559947a03e650575a764801366cc504b" + } + Frame { + msec: 2080 + hash: "a8d09f6c862fd5ec2dcf34f06d1ef744" + } + Frame { + msec: 2096 + hash: "e3bb4b62209631ff84134f2243bfdb42" + } + Frame { + msec: 2112 + hash: "a1956a9d1939bc154ea0c88d596948cc" + } + Frame { + msec: 2128 + hash: "c98a375727860da1e827d4dd74af8f63" + } + Frame { + msec: 2144 + hash: "df4edcbb2ef5348341ff55c808609b6c" + } + Frame { + msec: 2160 + hash: "6287564be85b7cbadc6bb6f0232bc837" + } + Frame { + msec: 2176 + hash: "9826fdb48f7ea770fa5f198ec49d7cb7" + } + Frame { + msec: 2192 + hash: "56f82641a5591df9bb929cc0d32eb95d" + } + Frame { + msec: 2208 + hash: "526c55e555fb2e58796561efa3568c50" + } + Frame { + msec: 2224 + hash: "6b4b74613421c1841a17c369cb316754" + } + Frame { + msec: 2240 + hash: "37f785c30947d5eec113dcf6af649abf" + } + Frame { + msec: 2256 + hash: "5ff2c975dd9e261c764537c836627c4d" + } + Frame { + msec: 2272 + hash: "efe554981583749c3d09988bce7fed02" + } + Frame { + msec: 2288 + hash: "0f7204b4afb0ea5d58e49650e8027c0c" + } + Frame { + msec: 2304 + hash: "817291f91f4b309710ad3aed53a7d47a" + } + Frame { + msec: 2320 + hash: "c15c9cd03089090cf8a777c1f0d88de7" + } + Frame { + msec: 2336 + hash: "05f45cb8d0856dcc81091351615e35d6" + } + Frame { + msec: 2352 + hash: "99785a16fed6d6409b4b47ec55afb56b" + } + Frame { + msec: 2368 + hash: "39032cb4432ee9536af500673fccf526" + } + Frame { + msec: 2384 + hash: "9057653e3cd6042831037d3590e7595b" + } + Frame { + msec: 2400 + hash: "76c772eb2ab8f117c260c9c96bc99e1d" + } + Frame { + msec: 2416 + hash: "b6474665b8f8bcdd76d1a38efecad889" + } + Frame { + msec: 2432 + hash: "106c2d2efafad0181e3ded3a6805f2c6" + } + Frame { + msec: 2448 + hash: "5275fa4ffef6c1909f9d03bb1e7b9cae" + } + Frame { + msec: 2464 + hash: "0c1043c0087d60000dc7259d4ac03618" + } + Frame { + msec: 2480 + hash: "645748569b4f5cb9b206b0808bb7d23d" + } + Frame { + msec: 2496 + hash: "dd95dfa80e1b3ff511e7c75efd0d87ce" + } + Frame { + msec: 2512 + hash: "86b3dd03b04d7610837cdc67cad07e0a" + } + Frame { + msec: 2528 + hash: "8264f67ac92e4ebcfe4cc8e954f8c5d2" + } + Frame { + msec: 2544 + hash: "6bf52377d822b09eb28a1ec36d3a36a9" + } + Frame { + msec: 2560 + hash: "7ae1d65cdaf7fa71eb4ec318b37bb0aa" + } + Frame { + msec: 2576 + hash: "860f5ce9844c90cf9e6a6d383ff0972f" + } + Frame { + msec: 2592 + hash: "5502229c038dfc59d966f69ae6ed8957" + } + Frame { + msec: 2608 + hash: "21843c027bc1434ae60b3bb0fced2c54" + } + Frame { + msec: 2624 + hash: "962df45680949c3eb6c968f98cd76b20" + } + Frame { + msec: 2640 + hash: "f313c26fa76a0edce61244bdf92528e4" + } + Frame { + msec: 2656 + hash: "b7bbde239e98cbd66b1e51b54b747f51" + } + Frame { + msec: 2672 + hash: "62340707fbc832fcb805c8f80ab353d1" + } + Frame { + msec: 2688 + hash: "d008a3f7af1810ff70b68b38a4cd0f0d" + } + Frame { + msec: 2704 + hash: "e651dd628af24faf34d716beb392b052" + } + Frame { + msec: 2720 + hash: "a97733963c7a7616b25741545b07ffba" + } + Frame { + msec: 2736 + hash: "3e017cc1db720cf16521bd17308e4f44" + } + Frame { + msec: 2752 + hash: "13652ebaa610cca71486517e2eed21a5" + } + Frame { + msec: 2768 + hash: "09f0f500c6f7d11be39c31f9e589b38a" + } + Frame { + msec: 2784 + hash: "b87968cbc60ddc6a5f5699e830410eab" + } + Frame { + msec: 2800 + hash: "50e65b043d1f07a321a08ee4c25204f6" + } + Frame { + msec: 2816 + hash: "122d1ffa1510468e8c4067e0f511588f" + } + Frame { + msec: 2832 + hash: "585f6c25caaafb99a22a23d8a998d202" + } + Frame { + msec: 2848 + hash: "9b245a00ad576666c10f509d8a80a61e" + } + Frame { + msec: 2864 + hash: "9b245a00ad576666c10f509d8a80a61e" + } + Frame { + msec: 2880 + hash: "3c5d3d10bacc093afc6a9c0b5aa4cddc" + } + Frame { + msec: 2896 + image: "follow.3.png" + } + Frame { + msec: 2912 + hash: "31926d69c2309fdf13fbd7f0e9868c3d" + } + Frame { + msec: 2928 + hash: "eb3acacce5dd31b0e94b59b9e546ccae" + } + Frame { + msec: 2944 + hash: "9a51cff3276d75803a0a6e480f7ecb70" + } + Frame { + msec: 2960 + hash: "fbbd8b9d519993a699815d935bcd2b9f" + } + Frame { + msec: 2976 + hash: "0314190c6de73f9f374a4eaed0709645" + } + Frame { + msec: 2992 + hash: "8ca1a203bdb5446094eb948aeb0a333e" + } + Frame { + msec: 3008 + hash: "301e1b86ce38e11ad9d0d7aba0909985" + } + Frame { + msec: 3024 + hash: "922095867d0a91b73ab7a63df2041279" + } + Frame { + msec: 3040 + hash: "ba8275f3ba4633bf64a1f81f630c90f1" + } + Frame { + msec: 3056 + hash: "efe39545279a7bd015d2de75d2b9d8b1" + } + Frame { + msec: 3072 + hash: "78926c3c0c6fcf89b9291f9902710964" + } + Frame { + msec: 3088 + hash: "ea63dcb7f00d3ddede0d8be59ad9d6bc" + } + Frame { + msec: 3104 + hash: "286ad493301b713a49e378f123482a53" + } + Frame { + msec: 3120 + hash: "a4bbbb8bb88188d3e99996502e3eebd1" + } + Frame { + msec: 3136 + hash: "a6100e79f3dc5af594e86ab6cd8dfb76" + } + Frame { + msec: 3152 + hash: "d9e3f777dc89bcf1b7f712206db768e2" + } + Frame { + msec: 3168 + hash: "768045c600c0aa0b1e9e6f012733c600" + } + Frame { + msec: 3184 + hash: "d8b4caa641ddee786f7898359efe9d07" + } + Frame { + msec: 3200 + hash: "f7c3b76d5bb7c263ac9447eaad685158" + } + Frame { + msec: 3216 + hash: "f7f97db815d653ec29fa31b87f72af2a" + } + Frame { + msec: 3232 + hash: "18524623762487b60943312cd8bd4388" + } + Frame { + msec: 3248 + hash: "5823dee5dd56e9f7515601f9629ccbae" + } + Frame { + msec: 3264 + hash: "5823dee5dd56e9f7515601f9629ccbae" + } + Frame { + msec: 3280 + hash: "5823dee5dd56e9f7515601f9629ccbae" + } + Frame { + msec: 3296 + hash: "5823dee5dd56e9f7515601f9629ccbae" + } + Frame { + msec: 3312 + hash: "18524623762487b60943312cd8bd4388" + } + Frame { + msec: 3328 + hash: "430995770b655054aaeda383df8e27f7" + } + Frame { + msec: 3344 + hash: "16a3a00f2b89aed676f80d63c4933ec3" + } + Frame { + msec: 3360 + hash: "6c55aa62079ec546522edbf69c37b270" + } + Frame { + msec: 3376 + hash: "0d68ca3ccecdd831013950cc7405e46e" + } + Frame { + msec: 3392 + hash: "9da2511bc8b434218695fa74ed543439" + } + Frame { + msec: 3408 + hash: "05afdd0b99dab81a500cdc2b2f0786fe" + } + Frame { + msec: 3424 + hash: "e6f8882d146ae60bcc6ea47ff41a637b" + } + Frame { + msec: 3440 + hash: "154542ed0e88321294f382501819aefc" + } + Frame { + msec: 3456 + hash: "8f47b6980c387c5020145bf04645fd2d" + } + Frame { + msec: 3472 + hash: "b34b055c7602f1f4e1cde875b258120c" + } + Frame { + msec: 3488 + hash: "5a697f675575f05e297d4877604b9a47" + } + Frame { + msec: 3504 + hash: "729dff1d1b357d19fc81804ec8940d0e" + } + Frame { + msec: 3520 + hash: "c6f3fee46baa94a6139d2ee40254b160" + } + Frame { + msec: 3536 + hash: "af0e700bb8ae34834510830f8b44afdb" + } + Frame { + msec: 3552 + hash: "9c87bb54c2dfe58c2da9194dae6f7502" + } + Frame { + msec: 3568 + hash: "2132356a92c75d725f9feafb8201b142" + } + Frame { + msec: 3584 + hash: "50d855d2595eeae2bfd6aaa8c2fa0454" + } + Frame { + msec: 3600 + hash: "5fde3c62d6e53a9056e3586f9dcda59e" + } + Frame { + msec: 3616 + hash: "8f04460254a1e9fb949d5165894cd92a" + } + Frame { + msec: 3632 + hash: "2b514c5e3b20d30f9c7e71092c69f081" + } + Frame { + msec: 3648 + hash: "2c1ba6224037790e15f5c0f2864ace4d" + } + Frame { + msec: 3664 + hash: "0d5b8e7bd5f560888aacaf2b3c6827a8" + } + Frame { + msec: 3680 + hash: "ae25004530e7df134414018e4a34780e" + } + Frame { + msec: 3696 + hash: "1a8fd9eaf9a91f1b42924f8986fbed9a" + } + Frame { + msec: 3712 + hash: "2ea6de2025d40ed5beeff12a5b70ccc9" + } + Frame { + msec: 3728 + hash: "624e417718d3cac1e4b7e4ce258ce6ea" + } + Frame { + msec: 3744 + hash: "8b56d29391257c7be8966af6be26ea9f" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 195; y: 95 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3760 + hash: "5c0d977d8b446d9191bde57335cf1062" + } + Frame { + msec: 3776 + hash: "100be2b21d069e3a5dbb694a90da4d4f" + } + Frame { + msec: 3792 + hash: "caab03f6c81080dd8fdbedb4e94ae4a5" + } + Frame { + msec: 3808 + hash: "3328a4d06f2f80a7e9ccf2ff21522fca" + } + Frame { + msec: 3824 + hash: "a534e6cc28daf3eff6a9cf8379bd6375" + } + Frame { + msec: 3840 + hash: "6686f9c1a814c6a6b785b70f94937b68" + } + Frame { + msec: 3856 + image: "follow.4.png" + } + Frame { + msec: 3872 + hash: "d3f1c3593375ca5c022a1361a7ec70bd" + } + Frame { + msec: 3888 + hash: "67843e6192e2ecaa3820c37dc2f93106" + } + Frame { + msec: 3904 + hash: "19a022f678e5b8f4ebdff936162323dc" + } + Frame { + msec: 3920 + hash: "34e55ae70c9e156db339ae15642359c3" + } + Frame { + msec: 3936 + hash: "3784778c817f9d9bb73d990cfe12685a" + } + Frame { + msec: 3952 + hash: "0403fdf79e3ba339c7e3786db0c9c0f0" + } + Frame { + msec: 3968 + hash: "93e4a0d5645d1cfc916f1e8422655555" + } + Frame { + msec: 3984 + hash: "29080bfabb87160b7c51385fb36b474b" + } + Frame { + msec: 4000 + hash: "9da2d83edc9d35f00fb8a159e79de4d9" + } + Frame { + msec: 4016 + hash: "5505a42d4788f00cfc7499fbfda851ce" + } + Frame { + msec: 4032 + hash: "bdd3040ab16fa9ffdd2fbc66b06699f8" + } + Frame { + msec: 4048 + hash: "2a347e30a20c693a9440caa60ade0a0f" + } + Frame { + msec: 4064 + hash: "0307f1857c091a639d47f112ce1a2f5a" + } + Frame { + msec: 4080 + hash: "778d18e539bbd562ebe39283a6315df1" + } + Frame { + msec: 4096 + hash: "0369cf6c3d1f5db2e92ee1f7c5d3b8ed" + } + Frame { + msec: 4112 + hash: "9f7413587ab50f1abf776bf180ec2d6f" + } + Frame { + msec: 4128 + hash: "7d04a27236485808e571e8a39f23ea17" + } + Frame { + msec: 4144 + hash: "a1dff63b723473d5a4c9c59975a2fb81" + } + Frame { + msec: 4160 + hash: "9795ea70a3b9d3b7805221a58c19e5da" + } + Frame { + msec: 4176 + hash: "f1392c489e21107136eb8e0d1e8b427e" + } + Frame { + msec: 4192 + hash: "95c225ef07171a96335e99078195b06a" + } + Frame { + msec: 4208 + hash: "d46ef3e7f9cec06e8c18afc0d07be4f3" + } + Frame { + msec: 4224 + hash: "b017f5b51d423bb0fca0d6df3aaded8b" + } + Frame { + msec: 4240 + hash: "60584d085b0cd6fbc436773be678597e" + } + Frame { + msec: 4256 + hash: "117951465dfd5c386826b295560d2dec" + } + Frame { + msec: 4272 + hash: "1b70137da5f4e024593999e93121fe8b" + } + Frame { + msec: 4288 + hash: "bd50dffd41941fef127f39b55c4748e0" + } + Frame { + msec: 4304 + hash: "8eec34d8e1d2e22d11b85a671cd4d3aa" + } + Frame { + msec: 4320 + hash: "9e3c97cfad5002ef5f3fcc365aeb7bd0" + } + Frame { + msec: 4336 + hash: "28e1cf1ee033915ea2ee39c9ab00a73d" + } + Frame { + msec: 4352 + hash: "99101a156a553f441f00221f6facbf1f" + } + Frame { + msec: 4368 + hash: "419023e5d59d16c26b35bee7d3cea559" + } + Frame { + msec: 4384 + hash: "485d23519293975b04031fe4baa5c276" + } + Frame { + msec: 4400 + hash: "c8bc60735e0ede26dbaf228294853f9a" + } + Frame { + msec: 4416 + hash: "ada3680b807d59843e3adf6640704066" + } + Frame { + msec: 4432 + hash: "3e28f3adf9241512cd0d6918d81ffffb" + } + Frame { + msec: 4448 + hash: "8f339acc33cbc89ae1c62391ce021bb3" + } + Frame { + msec: 4464 + hash: "d303960c0853a90557d64a04b8283c94" + } + Frame { + msec: 4480 + hash: "f907dbdacf2cfa9fdf8f9c8dead5b4c4" + } + Frame { + msec: 4496 + hash: "30c6e6f283f4a3f538cdda9c2e92de8c" + } + Frame { + msec: 4512 + hash: "04d2ac55774b43107a43a7d33764199b" + } + Frame { + msec: 4528 + hash: "cddf3e111cbc59e721725daa1d8a0c31" + } + Frame { + msec: 4544 + hash: "15b1b63cd1695207ebf9f04387be0739" + } + Frame { + msec: 4560 + hash: "690769b9bbe86a3c5b1fbdee39615fbd" + } + Frame { + msec: 4576 + hash: "2bd640d8ddbf878d808f22656fef1ed9" + } + Frame { + msec: 4592 + hash: "a654f1e4519bf883d554276ebbe96323" + } + Frame { + msec: 4608 + hash: "68f0313cfc3f51a0bb9b47c5407c19b6" + } + Frame { + msec: 4624 + hash: "77f29806b084de4cabf7ab9bf1a93d5e" + } + Frame { + msec: 4640 + hash: "f9991189e3282d107b98fb0ae5f5ef00" + } + Frame { + msec: 4656 + hash: "0cd1f2f6e347d48feea1b26a4968dec7" + } + Frame { + msec: 4672 + hash: "e75a6f6a088e2289042572a161ffb0e9" + } + Frame { + msec: 4688 + hash: "5a541081444c0a71128223a4c4c3144c" + } + Frame { + msec: 4704 + hash: "6813d442cc610f346a5441ed0cd723e5" + } + Frame { + msec: 4720 + hash: "24ec539bc57899819915f833f26deacd" + } + Frame { + msec: 4736 + hash: "3a7ed1b4b533b817674aa141c420cd61" + } + Frame { + msec: 4752 + hash: "d0a643fae97bb152e97ca60e96299003" + } + Frame { + msec: 4768 + hash: "c84093931520f4661eff6645091a294b" + } + Frame { + msec: 4784 + hash: "81e7ceaece82505a4a16ead195a66162" + } + Frame { + msec: 4800 + hash: "315764d20b647f6ab1ba30239a69bf72" + } + Frame { + msec: 4816 + image: "follow.5.png" + } + Frame { + msec: 4832 + hash: "d1824ced8af34ad9edb36a58ae9aa7f5" + } + Frame { + msec: 4848 + hash: "167b9a49fbb94908e09e7e9c9147cd8b" + } + Frame { + msec: 4864 + hash: "442d5f0906840de526d59a80ada322c0" + } + Frame { + msec: 4880 + hash: "78206c4d4d23c7c1ba888b9062b09432" + } + Frame { + msec: 4896 + hash: "e898202cfebbff1952efc6e01254d855" + } + Frame { + msec: 4912 + hash: "ab31dc7bbad2b0552359866bb8d92f0c" + } + Frame { + msec: 4928 + hash: "f093304e88964376baf9721d53d4fb49" + } + Frame { + msec: 4944 + hash: "3ef76f3e1c44d13c3a469bd192ff7b5d" + } + Frame { + msec: 4960 + hash: "5d3b6d0d91f8cc5b89e39407bc3b5a15" + } + Frame { + msec: 4976 + hash: "3c73573f12f49b34e1d990a55ad913fa" + } + Frame { + msec: 4992 + hash: "d1bac071b01a1c6fddab90cdc435fad4" + } + Frame { + msec: 5008 + hash: "36a219aadec910f1dbef616c641e1d2b" + } + Frame { + msec: 5024 + hash: "5871fc67d361cc988551592ee21dfb23" + } + Frame { + msec: 5040 + hash: "6e65ee6c814b9a9da205c36925e663bf" + } + Frame { + msec: 5056 + hash: "290b20fa8e91d34000d7c2d81745f6d2" + } + Frame { + msec: 5072 + hash: "19e7405a9083a8143f7bb040f8837b29" + } + Frame { + msec: 5088 + hash: "c0a0fa2b4c1ceb6c70594994a1ac8713" + } + Frame { + msec: 5104 + hash: "c236224c16743fb606deb78bcb8afc8d" + } + Frame { + msec: 5120 + hash: "7d44db15eb300b4338ffc26e9bcfce20" + } + Frame { + msec: 5136 + hash: "067a79148a194c45c6f32d85316a1e11" + } + Frame { + msec: 5152 + hash: "9075c379044476994a87f0fdcce8e332" + } + Frame { + msec: 5168 + hash: "b2316988fbd51096a4f512e71fe7d0a2" + } + Frame { + msec: 5184 + hash: "280f70877d93af5f84e178aad6a102d8" + } + Frame { + msec: 5200 + hash: "3eef4ae7e43a8cf1cd9dd562237296f8" + } + Frame { + msec: 5216 + hash: "e3184f77ce3a47ca4dca6386f42d7fec" + } + Frame { + msec: 5232 + hash: "a2a5df66fe4808ea8d466cac84ba910c" + } + Frame { + msec: 5248 + hash: "9f8a0e54788112d6c30482e840504f35" + } + Frame { + msec: 5264 + hash: "ae69cf84798844f9f360c86790feaecd" + } + Frame { + msec: 5280 + hash: "0244526572acb6266db5b7eb9d29c6fc" + } + Frame { + msec: 5296 + hash: "8fb53d60b95ddb5aef27442934ea9983" + } + Frame { + msec: 5312 + hash: "930fcfde491b4f5681e3861764003895" + } + Frame { + msec: 5328 + hash: "bcdcd0a637112d113ebe11dc18823237" + } + Frame { + msec: 5344 + hash: "65a564d5a5afbc14c0cdad4d52753507" + } + Frame { + msec: 5360 + hash: "0c5056d438d2d54938f31ef5f996673a" + } + Frame { + msec: 5376 + hash: "11c157ad2236fc390ffbdf339366cbc1" + } + Frame { + msec: 5392 + hash: "6cb341b1f281a97a35c2e41bfd4c4d9d" + } + Frame { + msec: 5408 + hash: "553a945f7f19f70ddae4ebe88e52a79b" + } + Frame { + msec: 5424 + hash: "d10b42b4095a2474e66a5a322f72e936" + } + Frame { + msec: 5440 + hash: "0f943d61e8072d70eddee8aa1ba0de5a" + } + Frame { + msec: 5456 + hash: "3df18e237b666e78d57857739b759e6d" + } + Frame { + msec: 5472 + hash: "1ddc0bfdb2ca7b6dee63f1024e62f26e" + } + Frame { + msec: 5488 + hash: "aaa397714528f41238059e3a88833abc" + } + Frame { + msec: 5504 + hash: "c94bd69f925c782656afc5f9618180a6" + } + Frame { + msec: 5520 + hash: "824ff8c0e1ab43e3c0eaa79b7cc19b9c" + } + Frame { + msec: 5536 + hash: "6c440a0b2293811335bdbf2c4f25f47d" + } + Frame { + msec: 5552 + hash: "bfc7936cdf833d5b720ec9baca740112" + } + Frame { + msec: 5568 + hash: "375fa305dbae2872dc9b20e59381cc0c" + } + Frame { + msec: 5584 + hash: "fffd6173aa49e74164dc17a238bcd830" + } + Frame { + msec: 5600 + hash: "44d9007e00fab161fd393b653255d7f4" + } + Frame { + msec: 5616 + hash: "f669ee25c58b4fa20a01705d334f0065" + } + Frame { + msec: 5632 + hash: "2dbb7d57711b67d5d9e1b81f70e22d34" + } + Frame { + msec: 5648 + hash: "19351b91448265cb95c1670ee283c611" + } + Frame { + msec: 5664 + hash: "19351b91448265cb95c1670ee283c611" + } + Frame { + msec: 5680 + hash: "3a24b99d048348a21f4e4bd69393de89" + } + Frame { + msec: 5696 + hash: "35a6fe955a52950bbfa954a453e4008e" + } + Frame { + msec: 5712 + hash: "896f4ec28c976237b34fb2725a44460e" + } + Frame { + msec: 5728 + hash: "ed3008ea950ec84c57518e573ea36d15" + } + Frame { + msec: 5744 + hash: "3447c7be992759f772c1db2033eead99" + } + Frame { + msec: 5760 + hash: "b7133225daa03563d3f5b1dac5f56a23" + } + Frame { + msec: 5776 + image: "follow.6.png" + } + Frame { + msec: 5792 + hash: "adc55f2fcf312a90b025a75fa80aa079" + } + Frame { + msec: 5808 + hash: "3ac85cad400d2b8e4f33798f4f6b7b42" + } + Frame { + msec: 5824 + hash: "1c115efd84ccbe489d24c3c521c4a61c" + } + Frame { + msec: 5840 + hash: "39518f1bbc0c4aba6ff517bc3dc7c279" + } + Frame { + msec: 5856 + hash: "7bd28d32996f4de61c415d3217da16d0" + } + Frame { + msec: 5872 + hash: "f5d06e25d775bf8db07e95625a712733" + } + Frame { + msec: 5888 + hash: "4820ea6ea3be88af2f86111c547a19d7" + } + Frame { + msec: 5904 + hash: "fa6e681c368118b7f135a47ae8fc12ff" + } + Frame { + msec: 5920 + hash: "f6b30e618aeeb837d2b3eca270b0a060" + } + Frame { + msec: 5936 + hash: "ac8504bde8d3063a8bf02b9d4b69d755" + } + Frame { + msec: 5952 + hash: "9670537bb77caa8e23fda7bbfa96ca60" + } + Frame { + msec: 5968 + hash: "8cd292865ce5c1d240e9ddc93881a0ed" + } + Frame { + msec: 5984 + hash: "de112013e526203d151c46e6cfba9f92" + } + Frame { + msec: 6000 + hash: "cd61066e697de8c055aaa168791c2d8c" + } + Frame { + msec: 6016 + hash: "cd61066e697de8c055aaa168791c2d8c" + } + Frame { + msec: 6032 + hash: "e68b27ff14aac03c827fd43ac488d23e" + } + Frame { + msec: 6048 + hash: "e68b27ff14aac03c827fd43ac488d23e" + } + Frame { + msec: 6064 + hash: "1f61d857a8c26587fbda5895c603441a" + } + Frame { + msec: 6080 + hash: "1e0dffdd02e05ade1ae444427d4aa345" + } + Frame { + msec: 6096 + hash: "9a416ee7a1de9ac45ab2d609233c9520" + } + Frame { + msec: 6112 + hash: "dfa35bf1cd908011c3214a506bcbdcb8" + } + Frame { + msec: 6128 + hash: "bd502dc72dce4af3036f7af9ed7cf9e9" + } + Frame { + msec: 6144 + hash: "c77280527612408daa3037aab45da59d" + } + Frame { + msec: 6160 + hash: "a38ed1532a40210ad7da4c0d4d1a7195" + } + Frame { + msec: 6176 + hash: "8ac8a8df937da526bbffb9a3590d89ac" + } + Frame { + msec: 6192 + hash: "07527cb9a4494e11f4c9f99eb72598b9" + } + Frame { + msec: 6208 + hash: "655b0327ef0f8711810714ba50f2f8cc" + } + Frame { + msec: 6224 + hash: "549fd25292012a2be1f78118998ca892" + } + Frame { + msec: 6240 + hash: "7a382ae4e6a48826eaa2c83ee7a73fb2" + } + Frame { + msec: 6256 + hash: "5acd5f250c5b32d9006ed68dfecbfa1c" + } + Frame { + msec: 6272 + hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + } + Frame { + msec: 6288 + hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + } + Frame { + msec: 6304 + hash: "07e5f1277558bfe7638b00cf9d967baf" + } + Frame { + msec: 6320 + hash: "07e5f1277558bfe7638b00cf9d967baf" + } + Frame { + msec: 6336 + hash: "07e5f1277558bfe7638b00cf9d967baf" + } + Frame { + msec: 6352 + hash: "07e5f1277558bfe7638b00cf9d967baf" + } + Frame { + msec: 6368 + hash: "07e5f1277558bfe7638b00cf9d967baf" + } + Frame { + msec: 6384 + hash: "877aca1c64e588845329ca8a38222604" + } + Frame { + msec: 6400 + hash: "877aca1c64e588845329ca8a38222604" + } + Frame { + msec: 6416 + hash: "877aca1c64e588845329ca8a38222604" + } + Frame { + msec: 6432 + hash: "877aca1c64e588845329ca8a38222604" + } + Frame { + msec: 6448 + hash: "877aca1c64e588845329ca8a38222604" + } + Frame { + msec: 6464 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6480 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6496 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6512 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6528 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6544 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6560 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6576 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6592 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6608 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6624 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6640 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6656 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6672 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6688 + hash: "b0f28e923f93dcdcea8460ca9d8cd674" + } + Frame { + msec: 6704 + hash: "228920e994ebf71d542c71ce8263614e" + } + Frame { + msec: 6720 + hash: "228920e994ebf71d542c71ce8263614e" + } + Frame { + msec: 6736 + image: "follow.7.png" + } + Frame { + msec: 6752 + hash: "228920e994ebf71d542c71ce8263614e" + } + Frame { + msec: 6768 + hash: "228920e994ebf71d542c71ce8263614e" + } + Frame { + msec: 6784 + hash: "228920e994ebf71d542c71ce8263614e" + } + Frame { + msec: 6800 + hash: "228920e994ebf71d542c71ce8263614e" + } + Frame { + msec: 6816 + hash: "228920e994ebf71d542c71ce8263614e" + } + Frame { + msec: 6832 + hash: "07e5f1277558bfe7638b00cf9d967baf" + } + Key { + type: 6 + key: 16777249 + modifiers: 0 + text: "" + autorep: false + count: 1 + } + Frame { + msec: 6848 + hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + } + Frame { + msec: 6864 + hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + } + Frame { + msec: 6880 + hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + } + Frame { + msec: 6896 + hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + } + Frame { + msec: 6912 + hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + } + Frame { + msec: 6928 + hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/multilineAlign.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/multilineAlign.0.png index 87bc640..1b808ef 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/multilineAlign.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/multilineAlign.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/multilineAlign.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/multilineAlign.qml index f56f498..5485174 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/multilineAlign.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/multilineAlign.qml @@ -10,238 +10,238 @@ VisualTest { } Frame { msec: 32 - hash: "7fb2062f5786da9323db4286688682a0" + hash: "3fc7ab44f913d350f7aef342b958e56d" } Frame { msec: 48 - hash: "7fb2062f5786da9323db4286688682a0" + hash: "3fc7ab44f913d350f7aef342b958e56d" } Frame { msec: 64 - hash: "7fb2062f5786da9323db4286688682a0" + hash: "3fc7ab44f913d350f7aef342b958e56d" } Frame { msec: 80 - hash: "7fb2062f5786da9323db4286688682a0" + hash: "3fc7ab44f913d350f7aef342b958e56d" } Frame { msec: 96 - hash: "7fb2062f5786da9323db4286688682a0" + hash: "3fc7ab44f913d350f7aef342b958e56d" } Frame { msec: 112 - hash: "7fb2062f5786da9323db4286688682a0" + hash: "3fc7ab44f913d350f7aef342b958e56d" } Frame { msec: 128 - hash: "7fb2062f5786da9323db4286688682a0" + hash: "3fc7ab44f913d350f7aef342b958e56d" } Frame { msec: 144 - hash: "7fb2062f5786da9323db4286688682a0" + hash: "3fc7ab44f913d350f7aef342b958e56d" } Frame { msec: 160 - hash: "7fb2062f5786da9323db4286688682a0" + hash: "3fc7ab44f913d350f7aef342b958e56d" } Frame { msec: 176 - hash: "c67a5ae840827487ab618ff2d4e9a056" + hash: "a495a8a95c8aa82ac437c2f2970bd42d" } Frame { msec: 192 - hash: "c67a5ae840827487ab618ff2d4e9a056" + hash: "a495a8a95c8aa82ac437c2f2970bd42d" } Frame { msec: 208 - hash: "c67a5ae840827487ab618ff2d4e9a056" + hash: "a495a8a95c8aa82ac437c2f2970bd42d" } Frame { msec: 224 - hash: "c67a5ae840827487ab618ff2d4e9a056" + hash: "a495a8a95c8aa82ac437c2f2970bd42d" } Frame { msec: 240 - hash: "c67a5ae840827487ab618ff2d4e9a056" + hash: "a495a8a95c8aa82ac437c2f2970bd42d" } Frame { msec: 256 - hash: "c67a5ae840827487ab618ff2d4e9a056" + hash: "a495a8a95c8aa82ac437c2f2970bd42d" } Frame { msec: 272 - hash: "c67a5ae840827487ab618ff2d4e9a056" + hash: "a495a8a95c8aa82ac437c2f2970bd42d" } Frame { msec: 288 - hash: "c67a5ae840827487ab618ff2d4e9a056" + hash: "a495a8a95c8aa82ac437c2f2970bd42d" } Frame { msec: 304 - hash: "c67a5ae840827487ab618ff2d4e9a056" + hash: "a495a8a95c8aa82ac437c2f2970bd42d" } Frame { msec: 320 - hash: "c67a5ae840827487ab618ff2d4e9a056" + hash: "a495a8a95c8aa82ac437c2f2970bd42d" } Frame { msec: 336 - hash: "c7986aca05835e238ee95be063bdd032" + hash: "e2d2a6e60537b9a434d0029ef5ff26dc" } Frame { msec: 352 - hash: "c7986aca05835e238ee95be063bdd032" + hash: "e2d2a6e60537b9a434d0029ef5ff26dc" } Frame { msec: 368 - hash: "c7986aca05835e238ee95be063bdd032" + hash: "e2d2a6e60537b9a434d0029ef5ff26dc" } Frame { msec: 384 - hash: "c7986aca05835e238ee95be063bdd032" + hash: "e2d2a6e60537b9a434d0029ef5ff26dc" } Frame { msec: 400 - hash: "c7986aca05835e238ee95be063bdd032" + hash: "e2d2a6e60537b9a434d0029ef5ff26dc" } Frame { msec: 416 - hash: "c7986aca05835e238ee95be063bdd032" + hash: "e2d2a6e60537b9a434d0029ef5ff26dc" } Frame { msec: 432 - hash: "c7986aca05835e238ee95be063bdd032" + hash: "e2d2a6e60537b9a434d0029ef5ff26dc" } Frame { msec: 448 - hash: "c7986aca05835e238ee95be063bdd032" + hash: "e2d2a6e60537b9a434d0029ef5ff26dc" } Frame { msec: 464 - hash: "c7986aca05835e238ee95be063bdd032" + hash: "e2d2a6e60537b9a434d0029ef5ff26dc" } Frame { msec: 480 - hash: "c7986aca05835e238ee95be063bdd032" + hash: "e2d2a6e60537b9a434d0029ef5ff26dc" } Frame { msec: 496 - hash: "dd8ee9c060450beef6cc2494fa463e0a" + hash: "00cba961e67c2124ace75dddb657cd6c" } Frame { msec: 512 - hash: "dd8ee9c060450beef6cc2494fa463e0a" + hash: "00cba961e67c2124ace75dddb657cd6c" } Frame { msec: 528 - hash: "dd8ee9c060450beef6cc2494fa463e0a" + hash: "00cba961e67c2124ace75dddb657cd6c" } Frame { msec: 544 - hash: "dd8ee9c060450beef6cc2494fa463e0a" + hash: "00cba961e67c2124ace75dddb657cd6c" } Frame { msec: 560 - hash: "dd8ee9c060450beef6cc2494fa463e0a" + hash: "00cba961e67c2124ace75dddb657cd6c" } Frame { msec: 576 - hash: "dd8ee9c060450beef6cc2494fa463e0a" + hash: "00cba961e67c2124ace75dddb657cd6c" } Frame { msec: 592 - hash: "dd8ee9c060450beef6cc2494fa463e0a" + hash: "00cba961e67c2124ace75dddb657cd6c" } Frame { msec: 608 - hash: "dd8ee9c060450beef6cc2494fa463e0a" + hash: "00cba961e67c2124ace75dddb657cd6c" } Frame { msec: 624 - hash: "dd8ee9c060450beef6cc2494fa463e0a" + hash: "00cba961e67c2124ace75dddb657cd6c" } Frame { msec: 640 - hash: "dd8ee9c060450beef6cc2494fa463e0a" + hash: "00cba961e67c2124ace75dddb657cd6c" } Frame { msec: 656 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 672 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 688 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 704 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 720 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 736 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 752 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 768 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 784 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 800 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 816 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 832 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 848 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 864 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 880 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 896 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 912 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 928 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 944 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } Frame { msec: 960 - hash: "f55ebe08f1b538d085cda157f566859e" + hash: "31d518de83e195def2d957b7d86b98e5" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-MAC/parentanchor.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-MAC/parentanchor.0.png index 4b78165..1fd0213 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-MAC/parentanchor.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-MAC/parentanchor.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-MAC/parentanchor.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-MAC/parentanchor.qml index 7c557e0..c5a5a76 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-MAC/parentanchor.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-MAC/parentanchor.qml @@ -10,122 +10,122 @@ VisualTest { } Frame { msec: 32 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 48 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 64 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 80 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 96 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 112 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 128 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 144 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 160 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 176 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 192 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 208 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 224 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 240 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 256 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 272 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 288 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 304 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 320 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 336 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 352 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 368 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 384 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 400 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 416 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 432 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 448 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 464 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 480 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } Frame { msec: 496 - hash: "455caf06270992e3367c2a5a4371b6ac" + hash: "f45eda9414f7db5ed1f97a8275459abd" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/bugs/data-MAC/QTBUG-14469.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/bugs/data-MAC/QTBUG-14469.0.png new file mode 100644 index 0000000..4d6bf55 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativetext/bugs/data-MAC/QTBUG-14469.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/bugs/data-MAC/QTBUG-14469.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/bugs/data-MAC/QTBUG-14469.1.png new file mode 100644 index 0000000..a75da16 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativetext/bugs/data-MAC/QTBUG-14469.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/bugs/data-MAC/QTBUG-14469.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/bugs/data-MAC/QTBUG-14469.qml new file mode 100644 index 0000000..002e1c8 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/bugs/data-MAC/QTBUG-14469.qml @@ -0,0 +1,475 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "QTBUG-14469.0.png" + } + Frame { + msec: 32 + hash: "fab978e1e0ee5140d8131320ff2322e9" + } + Frame { + msec: 48 + hash: "fab978e1e0ee5140d8131320ff2322e9" + } + Frame { + msec: 64 + hash: "fab978e1e0ee5140d8131320ff2322e9" + } + Frame { + msec: 80 + hash: "fab978e1e0ee5140d8131320ff2322e9" + } + Frame { + msec: 96 + hash: "fab978e1e0ee5140d8131320ff2322e9" + } + Frame { + msec: 112 + hash: "fab978e1e0ee5140d8131320ff2322e9" + } + Frame { + msec: 128 + hash: "cf74324c2a0c8f45c728d42390aac1e0" + } + Frame { + msec: 144 + hash: "cf74324c2a0c8f45c728d42390aac1e0" + } + Frame { + msec: 160 + hash: "cf74324c2a0c8f45c728d42390aac1e0" + } + Frame { + msec: 176 + hash: "cf74324c2a0c8f45c728d42390aac1e0" + } + Frame { + msec: 192 + hash: "cf74324c2a0c8f45c728d42390aac1e0" + } + Frame { + msec: 208 + hash: "cf74324c2a0c8f45c728d42390aac1e0" + } + Frame { + msec: 224 + hash: "07c938ac9ff9f591e84fc553291c7c49" + } + Frame { + msec: 240 + hash: "07c938ac9ff9f591e84fc553291c7c49" + } + Frame { + msec: 256 + hash: "07c938ac9ff9f591e84fc553291c7c49" + } + Frame { + msec: 272 + hash: "07c938ac9ff9f591e84fc553291c7c49" + } + Frame { + msec: 288 + hash: "07c938ac9ff9f591e84fc553291c7c49" + } + Frame { + msec: 304 + hash: "07c938ac9ff9f591e84fc553291c7c49" + } + Frame { + msec: 320 + hash: "7b585eb6226e6ce2de355f9730dba377" + } + Frame { + msec: 336 + hash: "7b585eb6226e6ce2de355f9730dba377" + } + Frame { + msec: 352 + hash: "7b585eb6226e6ce2de355f9730dba377" + } + Frame { + msec: 368 + hash: "7b585eb6226e6ce2de355f9730dba377" + } + Frame { + msec: 384 + hash: "7b585eb6226e6ce2de355f9730dba377" + } + Frame { + msec: 400 + hash: "7b585eb6226e6ce2de355f9730dba377" + } + Frame { + msec: 416 + hash: "a7817a7d902ab2fe2875183feb6513dd" + } + Frame { + msec: 432 + hash: "a7817a7d902ab2fe2875183feb6513dd" + } + Frame { + msec: 448 + hash: "a7817a7d902ab2fe2875183feb6513dd" + } + Frame { + msec: 464 + hash: "a7817a7d902ab2fe2875183feb6513dd" + } + Frame { + msec: 480 + hash: "a7817a7d902ab2fe2875183feb6513dd" + } + Frame { + msec: 496 + hash: "a7817a7d902ab2fe2875183feb6513dd" + } + Frame { + msec: 512 + hash: "a7817a7d902ab2fe2875183feb6513dd" + } + Frame { + msec: 528 + hash: "067dfe70eca44e2157b723858897c90e" + } + Frame { + msec: 544 + hash: "067dfe70eca44e2157b723858897c90e" + } + Frame { + msec: 560 + hash: "067dfe70eca44e2157b723858897c90e" + } + Frame { + msec: 576 + hash: "067dfe70eca44e2157b723858897c90e" + } + Frame { + msec: 592 + hash: "067dfe70eca44e2157b723858897c90e" + } + Frame { + msec: 608 + hash: "067dfe70eca44e2157b723858897c90e" + } + Frame { + msec: 624 + hash: "b1ac0015f173bf5789daa5d45d04dadd" + } + Frame { + msec: 640 + hash: "b1ac0015f173bf5789daa5d45d04dadd" + } + Frame { + msec: 656 + hash: "b1ac0015f173bf5789daa5d45d04dadd" + } + Frame { + msec: 672 + hash: "b1ac0015f173bf5789daa5d45d04dadd" + } + Frame { + msec: 688 + hash: "b1ac0015f173bf5789daa5d45d04dadd" + } + Frame { + msec: 704 + hash: "b1ac0015f173bf5789daa5d45d04dadd" + } + Frame { + msec: 720 + hash: "431cb09ccdcfab7c3ff7d498aa1f0816" + } + Frame { + msec: 736 + hash: "431cb09ccdcfab7c3ff7d498aa1f0816" + } + Frame { + msec: 752 + hash: "431cb09ccdcfab7c3ff7d498aa1f0816" + } + Frame { + msec: 768 + hash: "431cb09ccdcfab7c3ff7d498aa1f0816" + } + Frame { + msec: 784 + hash: "431cb09ccdcfab7c3ff7d498aa1f0816" + } + Frame { + msec: 800 + hash: "431cb09ccdcfab7c3ff7d498aa1f0816" + } + Frame { + msec: 816 + hash: "533b23f29fe5f9dc85a6ca390c6dd023" + } + Frame { + msec: 832 + hash: "533b23f29fe5f9dc85a6ca390c6dd023" + } + Frame { + msec: 848 + hash: "533b23f29fe5f9dc85a6ca390c6dd023" + } + Frame { + msec: 864 + hash: "533b23f29fe5f9dc85a6ca390c6dd023" + } + Frame { + msec: 880 + hash: "533b23f29fe5f9dc85a6ca390c6dd023" + } + Frame { + msec: 896 + hash: "533b23f29fe5f9dc85a6ca390c6dd023" + } + Frame { + msec: 912 + hash: "533b23f29fe5f9dc85a6ca390c6dd023" + } + Frame { + msec: 928 + hash: "cd397908009ddf16ec3101efb0d7468e" + } + Frame { + msec: 944 + hash: "cd397908009ddf16ec3101efb0d7468e" + } + Frame { + msec: 960 + hash: "cd397908009ddf16ec3101efb0d7468e" + } + Frame { + msec: 976 + image: "QTBUG-14469.1.png" + } + Frame { + msec: 992 + hash: "cd397908009ddf16ec3101efb0d7468e" + } + Frame { + msec: 1008 + hash: "cd397908009ddf16ec3101efb0d7468e" + } + Frame { + msec: 1024 + hash: "a1eebf1a97314851b5154802f05abe8d" + } + Frame { + msec: 1040 + hash: "a1eebf1a97314851b5154802f05abe8d" + } + Frame { + msec: 1056 + hash: "a1eebf1a97314851b5154802f05abe8d" + } + Frame { + msec: 1072 + hash: "a1eebf1a97314851b5154802f05abe8d" + } + Frame { + msec: 1088 + hash: "a1eebf1a97314851b5154802f05abe8d" + } + Frame { + msec: 1104 + hash: "a1eebf1a97314851b5154802f05abe8d" + } + Frame { + msec: 1120 + hash: "71d91d85b9c555eb9b39dac79b35dd46" + } + Frame { + msec: 1136 + hash: "71d91d85b9c555eb9b39dac79b35dd46" + } + Frame { + msec: 1152 + hash: "71d91d85b9c555eb9b39dac79b35dd46" + } + Frame { + msec: 1168 + hash: "71d91d85b9c555eb9b39dac79b35dd46" + } + Frame { + msec: 1184 + hash: "71d91d85b9c555eb9b39dac79b35dd46" + } + Frame { + msec: 1200 + hash: "71d91d85b9c555eb9b39dac79b35dd46" + } + Frame { + msec: 1216 + hash: "b1da2d1f4aad2a197a80788607bd867d" + } + Frame { + msec: 1232 + hash: "b1da2d1f4aad2a197a80788607bd867d" + } + Frame { + msec: 1248 + hash: "b1da2d1f4aad2a197a80788607bd867d" + } + Frame { + msec: 1264 + hash: "b1da2d1f4aad2a197a80788607bd867d" + } + Frame { + msec: 1280 + hash: "b1da2d1f4aad2a197a80788607bd867d" + } + Frame { + msec: 1296 + hash: "b1da2d1f4aad2a197a80788607bd867d" + } + Frame { + msec: 1312 + hash: "b1da2d1f4aad2a197a80788607bd867d" + } + Frame { + msec: 1328 + hash: "df14e9cfeba3850bae7cad111fdbc8df" + } + Frame { + msec: 1344 + hash: "df14e9cfeba3850bae7cad111fdbc8df" + } + Frame { + msec: 1360 + hash: "df14e9cfeba3850bae7cad111fdbc8df" + } + Frame { + msec: 1376 + hash: "df14e9cfeba3850bae7cad111fdbc8df" + } + Frame { + msec: 1392 + hash: "df14e9cfeba3850bae7cad111fdbc8df" + } + Frame { + msec: 1408 + hash: "df14e9cfeba3850bae7cad111fdbc8df" + } + Frame { + msec: 1424 + hash: "fab978e1e0ee5140d8131320ff2322e9" + } + Frame { + msec: 1440 + hash: "fab978e1e0ee5140d8131320ff2322e9" + } + Frame { + msec: 1456 + hash: "fab978e1e0ee5140d8131320ff2322e9" + } + Frame { + msec: 1472 + hash: "fab978e1e0ee5140d8131320ff2322e9" + } + Frame { + msec: 1488 + hash: "fab978e1e0ee5140d8131320ff2322e9" + } + Frame { + msec: 1504 + hash: "fab978e1e0ee5140d8131320ff2322e9" + } + Frame { + msec: 1520 + hash: "cf74324c2a0c8f45c728d42390aac1e0" + } + Frame { + msec: 1536 + hash: "cf74324c2a0c8f45c728d42390aac1e0" + } + Frame { + msec: 1552 + hash: "cf74324c2a0c8f45c728d42390aac1e0" + } + Frame { + msec: 1568 + hash: "cf74324c2a0c8f45c728d42390aac1e0" + } + Frame { + msec: 1584 + hash: "cf74324c2a0c8f45c728d42390aac1e0" + } + Frame { + msec: 1600 + hash: "cf74324c2a0c8f45c728d42390aac1e0" + } + Frame { + msec: 1616 + hash: "07c938ac9ff9f591e84fc553291c7c49" + } + Frame { + msec: 1632 + hash: "07c938ac9ff9f591e84fc553291c7c49" + } + Frame { + msec: 1648 + hash: "07c938ac9ff9f591e84fc553291c7c49" + } + Frame { + msec: 1664 + hash: "07c938ac9ff9f591e84fc553291c7c49" + } + Frame { + msec: 1680 + hash: "07c938ac9ff9f591e84fc553291c7c49" + } + Frame { + msec: 1696 + hash: "07c938ac9ff9f591e84fc553291c7c49" + } + Frame { + msec: 1712 + hash: "07c938ac9ff9f591e84fc553291c7c49" + } + Frame { + msec: 1728 + hash: "7b585eb6226e6ce2de355f9730dba377" + } + Frame { + msec: 1744 + hash: "7b585eb6226e6ce2de355f9730dba377" + } + Frame { + msec: 1760 + hash: "7b585eb6226e6ce2de355f9730dba377" + } + Frame { + msec: 1776 + hash: "7b585eb6226e6ce2de355f9730dba377" + } + Frame { + msec: 1792 + hash: "7b585eb6226e6ce2de355f9730dba377" + } + Frame { + msec: 1808 + hash: "7b585eb6226e6ce2de355f9730dba377" + } + Frame { + msec: 1824 + hash: "a7817a7d902ab2fe2875183feb6513dd" + } + Frame { + msec: 1840 + hash: "a7817a7d902ab2fe2875183feb6513dd" + } + Frame { + msec: 1856 + hash: "a7817a7d902ab2fe2875183feb6513dd" + } + Frame { + msec: 1872 + hash: "a7817a7d902ab2fe2875183feb6513dd" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/data-MAC/qtbug_14865.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/data-MAC/qtbug_14865.0.png index 804a443..7e84164 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/data-MAC/qtbug_14865.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/data-MAC/qtbug_14865.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/data-MAC/qtbug_14865.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/data-MAC/qtbug_14865.1.png index 804a443..7e84164 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/data-MAC/qtbug_14865.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/data-MAC/qtbug_14865.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/data-MAC/qtbug_14865.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/data-MAC/qtbug_14865.qml index efdb916..d6d8c2a 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/data-MAC/qtbug_14865.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/data-MAC/qtbug_14865.qml @@ -10,239 +10,239 @@ VisualTest { } Frame { msec: 32 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 48 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 64 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 80 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 96 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 112 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 128 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 144 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 160 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 176 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 192 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 208 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 224 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 240 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 256 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 272 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 288 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 304 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 320 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 336 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 352 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 368 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 384 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 400 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 416 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 432 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 448 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 464 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 480 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 496 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 512 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 528 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 544 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 560 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 576 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 592 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 608 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 624 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 640 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 656 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 672 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 688 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 704 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 720 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 736 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 752 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 768 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 784 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 800 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 816 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 832 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 848 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 864 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 880 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 896 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 912 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 928 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 944 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 960 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 976 @@ -250,11 +250,11 @@ VisualTest { } Frame { msec: 992 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 1008 - hash: "9886d2b883d236bd0a346c6763c1f245" + hash: "212d34fa7425fe24398c9de6d4f10422" } Frame { msec: 1024 diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide.0.png index 99f0eb7..749a9c5 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide.1.png index 99f0eb7..749a9c5 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide.qml index 6dc7f4f..fbb542e 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide.qml @@ -10,239 +10,239 @@ VisualTest { } Frame { msec: 32 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 48 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 64 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 80 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 96 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 112 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 128 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 144 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 160 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 176 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 192 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 208 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 224 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 240 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 256 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 272 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 288 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 304 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 320 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 336 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 352 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 368 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 384 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 400 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 416 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 432 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 448 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 464 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 480 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 496 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 512 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 528 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 544 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 560 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 576 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 592 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 608 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 624 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 640 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 656 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 672 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 688 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 704 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 720 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 736 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 752 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 768 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 784 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 800 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 816 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 832 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 848 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 864 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 880 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 896 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 912 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 928 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 944 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 960 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 976 @@ -251,29 +251,29 @@ VisualTest { Key { type: 6 key: 16777249 - modifiers: 67108864 + modifiers: 0 text: "" autorep: false count: 1 } Frame { msec: 992 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 1008 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 1024 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 1040 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } Frame { msec: 1056 - hash: "8401ef19b1e07ca917b8b061888d4e70" + hash: "4d49ec1a14a321ea9c0d506663df55c2" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.0.png index 0b08fba..b84b8a9 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.1.png index dbf8cd3..dbae0ce 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.2.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.2.png index 09646f8..bf56c80 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.2.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.3.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.3.png index b6734b4..c4f6e18 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.3.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.4.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.4.png index 861f6b0..ea86925 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.4.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.qml index 026f880..e780ea6 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/elide2.qml @@ -10,239 +10,239 @@ VisualTest { } Frame { msec: 32 - hash: "d482dd54c0f3876a11d80979ada91fa9" + hash: "1c45bbf4494aeb017d7ad53c5e29cbc0" } Frame { msec: 48 - hash: "d482dd54c0f3876a11d80979ada91fa9" + hash: "1c45bbf4494aeb017d7ad53c5e29cbc0" } Frame { msec: 64 - hash: "d482dd54c0f3876a11d80979ada91fa9" + hash: "1c45bbf4494aeb017d7ad53c5e29cbc0" } Frame { msec: 80 - hash: "d482dd54c0f3876a11d80979ada91fa9" + hash: "1c45bbf4494aeb017d7ad53c5e29cbc0" } Frame { msec: 96 - hash: "d482dd54c0f3876a11d80979ada91fa9" + hash: "1c45bbf4494aeb017d7ad53c5e29cbc0" } Frame { msec: 112 - hash: "3eb1cc8fa11ae88a3bf5004263805264" + hash: "452d8e4da326413e4961f20a0d24d0f0" } Frame { msec: 128 - hash: "3eb1cc8fa11ae88a3bf5004263805264" + hash: "452d8e4da326413e4961f20a0d24d0f0" } Frame { msec: 144 - hash: "3eb1cc8fa11ae88a3bf5004263805264" + hash: "452d8e4da326413e4961f20a0d24d0f0" } Frame { msec: 160 - hash: "3eb1cc8fa11ae88a3bf5004263805264" + hash: "452d8e4da326413e4961f20a0d24d0f0" } Frame { msec: 176 - hash: "3eb1cc8fa11ae88a3bf5004263805264" + hash: "452d8e4da326413e4961f20a0d24d0f0" } Frame { msec: 192 - hash: "b169f3828fafa79245bd5886d94a33b2" + hash: "8dc43f316fd36a877c773c10c23b5703" } Frame { msec: 208 - hash: "b169f3828fafa79245bd5886d94a33b2" + hash: "8dc43f316fd36a877c773c10c23b5703" } Frame { msec: 224 - hash: "b169f3828fafa79245bd5886d94a33b2" + hash: "8dc43f316fd36a877c773c10c23b5703" } Frame { msec: 240 - hash: "b169f3828fafa79245bd5886d94a33b2" + hash: "8dc43f316fd36a877c773c10c23b5703" } Frame { msec: 256 - hash: "c9a22f77cce333ea041730bc76d9bb96" + hash: "b7e055ce8d510c5ec66e71fa5a78fddf" } Frame { msec: 272 - hash: "c9a22f77cce333ea041730bc76d9bb96" + hash: "b7e055ce8d510c5ec66e71fa5a78fddf" } Frame { msec: 288 - hash: "c9a22f77cce333ea041730bc76d9bb96" + hash: "b7e055ce8d510c5ec66e71fa5a78fddf" } Frame { msec: 304 - hash: "c9a22f77cce333ea041730bc76d9bb96" + hash: "b7e055ce8d510c5ec66e71fa5a78fddf" } Frame { msec: 320 - hash: "958e5805b2bc2ffeaf8a6c8c24721dd5" + hash: "e9b0abe5719027348cd267eb4823fc5f" } Frame { msec: 336 - hash: "958e5805b2bc2ffeaf8a6c8c24721dd5" + hash: "e9b0abe5719027348cd267eb4823fc5f" } Frame { msec: 352 - hash: "958e5805b2bc2ffeaf8a6c8c24721dd5" + hash: "e9b0abe5719027348cd267eb4823fc5f" } Frame { msec: 368 - hash: "958e5805b2bc2ffeaf8a6c8c24721dd5" + hash: "e9b0abe5719027348cd267eb4823fc5f" } Frame { msec: 384 - hash: "958e5805b2bc2ffeaf8a6c8c24721dd5" + hash: "e9b0abe5719027348cd267eb4823fc5f" } Frame { msec: 400 - hash: "ed14c796dc2980f7a1bdedb15698ae01" + hash: "441102f2f69e9f4e10335c1746d47bd3" } Frame { msec: 416 - hash: "ed14c796dc2980f7a1bdedb15698ae01" + hash: "441102f2f69e9f4e10335c1746d47bd3" } Frame { msec: 432 - hash: "ed14c796dc2980f7a1bdedb15698ae01" + hash: "441102f2f69e9f4e10335c1746d47bd3" } Frame { msec: 448 - hash: "ed14c796dc2980f7a1bdedb15698ae01" + hash: "441102f2f69e9f4e10335c1746d47bd3" } Frame { msec: 464 - hash: "ed14c796dc2980f7a1bdedb15698ae01" + hash: "441102f2f69e9f4e10335c1746d47bd3" } Frame { msec: 480 - hash: "24d811c9b98b0cb140e7e82090e793ab" + hash: "95668288170720989adde2a0b41d5ee8" } Frame { msec: 496 - hash: "24d811c9b98b0cb140e7e82090e793ab" + hash: "95668288170720989adde2a0b41d5ee8" } Frame { msec: 512 - hash: "24d811c9b98b0cb140e7e82090e793ab" + hash: "95668288170720989adde2a0b41d5ee8" } Frame { msec: 528 - hash: "24d811c9b98b0cb140e7e82090e793ab" + hash: "95668288170720989adde2a0b41d5ee8" } Frame { msec: 544 - hash: "afa28a6a682128b1b44df31c78b63b04" + hash: "16bba6b72993e474b4c302af3f682834" } Frame { msec: 560 - hash: "afa28a6a682128b1b44df31c78b63b04" + hash: "16bba6b72993e474b4c302af3f682834" } Frame { msec: 576 - hash: "afa28a6a682128b1b44df31c78b63b04" + hash: "16bba6b72993e474b4c302af3f682834" } Frame { msec: 592 - hash: "afa28a6a682128b1b44df31c78b63b04" + hash: "16bba6b72993e474b4c302af3f682834" } Frame { msec: 608 - hash: "c43bba2d3406fabdafac344102d7d72c" + hash: "86c4d8bd1b19116411b6a6e450547425" } Frame { msec: 624 - hash: "c43bba2d3406fabdafac344102d7d72c" + hash: "86c4d8bd1b19116411b6a6e450547425" } Frame { msec: 640 - hash: "c43bba2d3406fabdafac344102d7d72c" + hash: "86c4d8bd1b19116411b6a6e450547425" } Frame { msec: 656 - hash: "c43bba2d3406fabdafac344102d7d72c" + hash: "86c4d8bd1b19116411b6a6e450547425" } Frame { msec: 672 - hash: "c43bba2d3406fabdafac344102d7d72c" + hash: "86c4d8bd1b19116411b6a6e450547425" } Frame { msec: 688 - hash: "0e1fb18acb72ca1da6fd619e31dd2c86" + hash: "d0d3cfa922ebca20c590ab7e59985268" } Frame { msec: 704 - hash: "0e1fb18acb72ca1da6fd619e31dd2c86" + hash: "d0d3cfa922ebca20c590ab7e59985268" } Frame { msec: 720 - hash: "0e1fb18acb72ca1da6fd619e31dd2c86" + hash: "d0d3cfa922ebca20c590ab7e59985268" } Frame { msec: 736 - hash: "0e1fb18acb72ca1da6fd619e31dd2c86" + hash: "d0d3cfa922ebca20c590ab7e59985268" } Frame { msec: 752 - hash: "0e1fb18acb72ca1da6fd619e31dd2c86" + hash: "d0d3cfa922ebca20c590ab7e59985268" } Frame { msec: 768 - hash: "d5780e5b30828f33d18c1f4e32ba8c3f" + hash: "397d72a090171090f897283729b19bc8" } Frame { msec: 784 - hash: "d5780e5b30828f33d18c1f4e32ba8c3f" + hash: "397d72a090171090f897283729b19bc8" } Frame { msec: 800 - hash: "d5780e5b30828f33d18c1f4e32ba8c3f" + hash: "397d72a090171090f897283729b19bc8" } Frame { msec: 816 - hash: "d5780e5b30828f33d18c1f4e32ba8c3f" + hash: "397d72a090171090f897283729b19bc8" } Frame { msec: 832 - hash: "28bdd1ab1c1af1b39a2f9d11be456682" + hash: "2b038e59289d2e3cef02245d2d128271" } Frame { msec: 848 - hash: "28bdd1ab1c1af1b39a2f9d11be456682" + hash: "2b038e59289d2e3cef02245d2d128271" } Frame { msec: 864 - hash: "28bdd1ab1c1af1b39a2f9d11be456682" + hash: "2b038e59289d2e3cef02245d2d128271" } Frame { msec: 880 - hash: "28bdd1ab1c1af1b39a2f9d11be456682" + hash: "2b038e59289d2e3cef02245d2d128271" } Frame { msec: 896 - hash: "28bdd1ab1c1af1b39a2f9d11be456682" + hash: "2b038e59289d2e3cef02245d2d128271" } Frame { msec: 912 - hash: "e34a9080716cebc0260e682960cc7c6e" + hash: "5f64aa763acdd8f5d6cc249be36e226a" } Frame { msec: 928 - hash: "e34a9080716cebc0260e682960cc7c6e" + hash: "5f64aa763acdd8f5d6cc249be36e226a" } Frame { msec: 944 - hash: "e34a9080716cebc0260e682960cc7c6e" + hash: "5f64aa763acdd8f5d6cc249be36e226a" } Frame { msec: 960 - hash: "e34a9080716cebc0260e682960cc7c6e" + hash: "5f64aa763acdd8f5d6cc249be36e226a" } Frame { msec: 976 @@ -250,247 +250,247 @@ VisualTest { } Frame { msec: 992 - hash: "61959fc3d6f84a9fe88ec1a2979da9af" + hash: "4f8c81adc72fce17c7e54f4d45ec08e4" } Frame { msec: 1008 - hash: "61959fc3d6f84a9fe88ec1a2979da9af" + hash: "4f8c81adc72fce17c7e54f4d45ec08e4" } Frame { msec: 1024 - hash: "61959fc3d6f84a9fe88ec1a2979da9af" + hash: "4f8c81adc72fce17c7e54f4d45ec08e4" } Frame { msec: 1040 - hash: "47794b18771d6d558ebbca881de92377" + hash: "91a7a0c0f686975d0087ee0e066911eb" } Frame { msec: 1056 - hash: "47794b18771d6d558ebbca881de92377" + hash: "91a7a0c0f686975d0087ee0e066911eb" } Frame { msec: 1072 - hash: "47794b18771d6d558ebbca881de92377" + hash: "91a7a0c0f686975d0087ee0e066911eb" } Frame { msec: 1088 - hash: "47794b18771d6d558ebbca881de92377" + hash: "91a7a0c0f686975d0087ee0e066911eb" } Frame { msec: 1104 - hash: "47794b18771d6d558ebbca881de92377" + hash: "91a7a0c0f686975d0087ee0e066911eb" } Frame { msec: 1120 - hash: "ba34b024ddb4e701d1d7f0c19e24d6cf" + hash: "b19f6b8b4dc9d2a2d9aba82983e41889" } Frame { msec: 1136 - hash: "ba34b024ddb4e701d1d7f0c19e24d6cf" + hash: "b19f6b8b4dc9d2a2d9aba82983e41889" } Frame { msec: 1152 - hash: "ba34b024ddb4e701d1d7f0c19e24d6cf" + hash: "b19f6b8b4dc9d2a2d9aba82983e41889" } Frame { msec: 1168 - hash: "ba34b024ddb4e701d1d7f0c19e24d6cf" + hash: "b19f6b8b4dc9d2a2d9aba82983e41889" } Frame { msec: 1184 - hash: "ba34b024ddb4e701d1d7f0c19e24d6cf" + hash: "b19f6b8b4dc9d2a2d9aba82983e41889" } Frame { msec: 1200 - hash: "e94344268d2a118053ecc3aef278d91d" + hash: "456542b672303ddae500b96e9b66a558" } Frame { msec: 1216 - hash: "e94344268d2a118053ecc3aef278d91d" + hash: "456542b672303ddae500b96e9b66a558" } Frame { msec: 1232 - hash: "e94344268d2a118053ecc3aef278d91d" + hash: "456542b672303ddae500b96e9b66a558" } Frame { msec: 1248 - hash: "e94344268d2a118053ecc3aef278d91d" + hash: "456542b672303ddae500b96e9b66a558" } Frame { msec: 1264 - hash: "df1959605d3bd74e84e51cbd4d322235" + hash: "8ec69f05d929c3b397dc721198ccacd4" } Frame { msec: 1280 - hash: "df1959605d3bd74e84e51cbd4d322235" + hash: "8ec69f05d929c3b397dc721198ccacd4" } Frame { msec: 1296 - hash: "df1959605d3bd74e84e51cbd4d322235" + hash: "8ec69f05d929c3b397dc721198ccacd4" } Frame { msec: 1312 - hash: "df1959605d3bd74e84e51cbd4d322235" + hash: "8ec69f05d929c3b397dc721198ccacd4" } Frame { msec: 1328 - hash: "26e1c8d13f0dd3713dce24211a8d26c1" + hash: "2d63fd91f4b01f6b178c795838e78990" } Frame { msec: 1344 - hash: "26e1c8d13f0dd3713dce24211a8d26c1" + hash: "2d63fd91f4b01f6b178c795838e78990" } Frame { msec: 1360 - hash: "26e1c8d13f0dd3713dce24211a8d26c1" + hash: "2d63fd91f4b01f6b178c795838e78990" } Frame { msec: 1376 - hash: "26e1c8d13f0dd3713dce24211a8d26c1" + hash: "2d63fd91f4b01f6b178c795838e78990" } Frame { msec: 1392 - hash: "26e1c8d13f0dd3713dce24211a8d26c1" + hash: "2d63fd91f4b01f6b178c795838e78990" } Frame { msec: 1408 - hash: "fd1344db48093182eb2c2872ceb887df" + hash: "c7c1d2c288653b414fe534ff6fab3381" } Frame { msec: 1424 - hash: "fd1344db48093182eb2c2872ceb887df" + hash: "c7c1d2c288653b414fe534ff6fab3381" } Frame { msec: 1440 - hash: "fd1344db48093182eb2c2872ceb887df" + hash: "c7c1d2c288653b414fe534ff6fab3381" } Frame { msec: 1456 - hash: "fd1344db48093182eb2c2872ceb887df" + hash: "c7c1d2c288653b414fe534ff6fab3381" } Frame { msec: 1472 - hash: "fd1344db48093182eb2c2872ceb887df" + hash: "c7c1d2c288653b414fe534ff6fab3381" } Frame { msec: 1488 - hash: "a4bf54bbb5bcbf54de6a7a2be9b73b81" + hash: "23188e926a855a7a06211783ee51d22a" } Frame { msec: 1504 - hash: "a4bf54bbb5bcbf54de6a7a2be9b73b81" + hash: "23188e926a855a7a06211783ee51d22a" } Frame { msec: 1520 - hash: "a4bf54bbb5bcbf54de6a7a2be9b73b81" + hash: "23188e926a855a7a06211783ee51d22a" } Frame { msec: 1536 - hash: "a4bf54bbb5bcbf54de6a7a2be9b73b81" + hash: "23188e926a855a7a06211783ee51d22a" } Frame { msec: 1552 - hash: "072a6c0e64853f57487845f2ff376c12" + hash: "cfc64d8876d59e0d75f079c2e08cea5f" } Frame { msec: 1568 - hash: "072a6c0e64853f57487845f2ff376c12" + hash: "cfc64d8876d59e0d75f079c2e08cea5f" } Frame { msec: 1584 - hash: "072a6c0e64853f57487845f2ff376c12" + hash: "cfc64d8876d59e0d75f079c2e08cea5f" } Frame { msec: 1600 - hash: "072a6c0e64853f57487845f2ff376c12" + hash: "cfc64d8876d59e0d75f079c2e08cea5f" } Frame { msec: 1616 - hash: "072a6c0e64853f57487845f2ff376c12" + hash: "cfc64d8876d59e0d75f079c2e08cea5f" } Frame { msec: 1632 - hash: "d4183aba9cd5607ea1ff1572c78d33cc" + hash: "766c679eaec4bd28dc92cb3642d5be83" } Frame { msec: 1648 - hash: "d4183aba9cd5607ea1ff1572c78d33cc" + hash: "766c679eaec4bd28dc92cb3642d5be83" } Frame { msec: 1664 - hash: "d4183aba9cd5607ea1ff1572c78d33cc" + hash: "766c679eaec4bd28dc92cb3642d5be83" } Frame { msec: 1680 - hash: "d4183aba9cd5607ea1ff1572c78d33cc" + hash: "766c679eaec4bd28dc92cb3642d5be83" } Frame { msec: 1696 - hash: "31cb8e151b34187f712b269b38a317a7" + hash: "a86ba05a854fde208e6cf7849327d5d0" } Frame { msec: 1712 - hash: "31cb8e151b34187f712b269b38a317a7" + hash: "a86ba05a854fde208e6cf7849327d5d0" } Frame { msec: 1728 - hash: "31cb8e151b34187f712b269b38a317a7" + hash: "a86ba05a854fde208e6cf7849327d5d0" } Frame { msec: 1744 - hash: "31cb8e151b34187f712b269b38a317a7" + hash: "a86ba05a854fde208e6cf7849327d5d0" } Key { type: 6 key: 16777249 - modifiers: 67108864 + modifiers: 0 text: "" autorep: false count: 1 } Frame { msec: 1760 - hash: "31cb8e151b34187f712b269b38a317a7" + hash: "a86ba05a854fde208e6cf7849327d5d0" } Frame { msec: 1776 - hash: "e24ad0aed6a071d6da9f51af00c69300" + hash: "23b60817be2a741cada2af663b0d7f54" } Frame { msec: 1792 - hash: "e24ad0aed6a071d6da9f51af00c69300" + hash: "23b60817be2a741cada2af663b0d7f54" } Frame { msec: 1808 - hash: "e24ad0aed6a071d6da9f51af00c69300" + hash: "23b60817be2a741cada2af663b0d7f54" } Frame { msec: 1824 - hash: "e24ad0aed6a071d6da9f51af00c69300" + hash: "23b60817be2a741cada2af663b0d7f54" } Frame { msec: 1840 - hash: "760eea420a5eb52ccd1f6a29d6701338" + hash: "c098c1c0d5239c59735a5c9450e9d531" } Frame { msec: 1856 - hash: "760eea420a5eb52ccd1f6a29d6701338" + hash: "c098c1c0d5239c59735a5c9450e9d531" } Frame { msec: 1872 - hash: "760eea420a5eb52ccd1f6a29d6701338" + hash: "c098c1c0d5239c59735a5c9450e9d531" } Frame { msec: 1888 - hash: "760eea420a5eb52ccd1f6a29d6701338" + hash: "c098c1c0d5239c59735a5c9450e9d531" } Frame { msec: 1904 - hash: "760eea420a5eb52ccd1f6a29d6701338" + hash: "c098c1c0d5239c59735a5c9450e9d531" } Frame { msec: 1920 - hash: "07cdcdb9b551750c4a742ee6dff9f3f9" + hash: "09f6ee218d314d3a405ae43e32588c07" } Frame { msec: 1936 @@ -498,239 +498,239 @@ VisualTest { } Frame { msec: 1952 - hash: "07cdcdb9b551750c4a742ee6dff9f3f9" + hash: "09f6ee218d314d3a405ae43e32588c07" } Frame { msec: 1968 - hash: "07cdcdb9b551750c4a742ee6dff9f3f9" + hash: "09f6ee218d314d3a405ae43e32588c07" } Frame { msec: 1984 - hash: "ec4dada16fb19fb4cf24367c9f25f161" + hash: "6ee480e7d8b0abe295ae12a660119102" } Frame { msec: 2000 - hash: "ec4dada16fb19fb4cf24367c9f25f161" + hash: "6ee480e7d8b0abe295ae12a660119102" } Frame { msec: 2016 - hash: "ec4dada16fb19fb4cf24367c9f25f161" + hash: "6ee480e7d8b0abe295ae12a660119102" } Frame { msec: 2032 - hash: "ec4dada16fb19fb4cf24367c9f25f161" + hash: "6ee480e7d8b0abe295ae12a660119102" } Frame { msec: 2048 - hash: "ec4dada16fb19fb4cf24367c9f25f161" + hash: "6ee480e7d8b0abe295ae12a660119102" } Frame { msec: 2064 - hash: "f5ef19dc69f8b6060056f7005f613ca3" + hash: "b43ca0ea75f4c17c09248f78170d3839" } Frame { msec: 2080 - hash: "f5ef19dc69f8b6060056f7005f613ca3" + hash: "b43ca0ea75f4c17c09248f78170d3839" } Frame { msec: 2096 - hash: "f5ef19dc69f8b6060056f7005f613ca3" + hash: "b43ca0ea75f4c17c09248f78170d3839" } Frame { msec: 2112 - hash: "f5ef19dc69f8b6060056f7005f613ca3" + hash: "b43ca0ea75f4c17c09248f78170d3839" } Frame { msec: 2128 - hash: "6bd00519ea14f0dd34d45de4deaaa65e" + hash: "92e0ee1174ffcb710403bb831aeec353" } Frame { msec: 2144 - hash: "6bd00519ea14f0dd34d45de4deaaa65e" + hash: "92e0ee1174ffcb710403bb831aeec353" } Frame { msec: 2160 - hash: "6bd00519ea14f0dd34d45de4deaaa65e" + hash: "92e0ee1174ffcb710403bb831aeec353" } Frame { msec: 2176 - hash: "6bd00519ea14f0dd34d45de4deaaa65e" + hash: "92e0ee1174ffcb710403bb831aeec353" } Frame { msec: 2192 - hash: "6bd00519ea14f0dd34d45de4deaaa65e" + hash: "92e0ee1174ffcb710403bb831aeec353" } Frame { msec: 2208 - hash: "1c3e491e889e408f705477f060103243" + hash: "bba79ad6f3630b7aa382541cc2d3a2cd" } Frame { msec: 2224 - hash: "1c3e491e889e408f705477f060103243" + hash: "bba79ad6f3630b7aa382541cc2d3a2cd" } Frame { msec: 2240 - hash: "1c3e491e889e408f705477f060103243" + hash: "bba79ad6f3630b7aa382541cc2d3a2cd" } Frame { msec: 2256 - hash: "1c3e491e889e408f705477f060103243" + hash: "bba79ad6f3630b7aa382541cc2d3a2cd" } Frame { msec: 2272 - hash: "80bc59211ffab64820e306e6eb13d2fc" + hash: "7efeb1565125f25252ce3f03dadc3bea" } Frame { msec: 2288 - hash: "80bc59211ffab64820e306e6eb13d2fc" + hash: "7efeb1565125f25252ce3f03dadc3bea" } Frame { msec: 2304 - hash: "80bc59211ffab64820e306e6eb13d2fc" + hash: "7efeb1565125f25252ce3f03dadc3bea" } Frame { msec: 2320 - hash: "80bc59211ffab64820e306e6eb13d2fc" + hash: "7efeb1565125f25252ce3f03dadc3bea" } Frame { msec: 2336 - hash: "80bc59211ffab64820e306e6eb13d2fc" + hash: "7efeb1565125f25252ce3f03dadc3bea" } Frame { msec: 2352 - hash: "7765c76dd2ef99e4d7286fcb3a172a07" + hash: "9086d24dff90f8c9e4543c6b14c99bf6" } Frame { msec: 2368 - hash: "7765c76dd2ef99e4d7286fcb3a172a07" + hash: "9086d24dff90f8c9e4543c6b14c99bf6" } Frame { msec: 2384 - hash: "7765c76dd2ef99e4d7286fcb3a172a07" + hash: "9086d24dff90f8c9e4543c6b14c99bf6" } Frame { msec: 2400 - hash: "7765c76dd2ef99e4d7286fcb3a172a07" + hash: "9086d24dff90f8c9e4543c6b14c99bf6" } Frame { msec: 2416 - hash: "7765c76dd2ef99e4d7286fcb3a172a07" + hash: "9086d24dff90f8c9e4543c6b14c99bf6" } Frame { msec: 2432 - hash: "8fedc4d5d4161922c1d9d50adcf67e4a" + hash: "15d8e99a0676e0a1588dfddc00ab0d16" } Frame { msec: 2448 - hash: "8fedc4d5d4161922c1d9d50adcf67e4a" + hash: "15d8e99a0676e0a1588dfddc00ab0d16" } Frame { msec: 2464 - hash: "8fedc4d5d4161922c1d9d50adcf67e4a" + hash: "15d8e99a0676e0a1588dfddc00ab0d16" } Frame { msec: 2480 - hash: "8fedc4d5d4161922c1d9d50adcf67e4a" + hash: "15d8e99a0676e0a1588dfddc00ab0d16" } Frame { msec: 2496 - hash: "4f26d7ab05e6d39a869be1259e33c739" + hash: "ecc25b88c29dc9d6c70df6e36a91f95c" } Frame { msec: 2512 - hash: "4f26d7ab05e6d39a869be1259e33c739" + hash: "ecc25b88c29dc9d6c70df6e36a91f95c" } Frame { msec: 2528 - hash: "4f26d7ab05e6d39a869be1259e33c739" + hash: "ecc25b88c29dc9d6c70df6e36a91f95c" } Frame { msec: 2544 - hash: "4f26d7ab05e6d39a869be1259e33c739" + hash: "ecc25b88c29dc9d6c70df6e36a91f95c" } Frame { msec: 2560 - hash: "d4ead42bcc2e283e513f1ab4f8a89f27" + hash: "905c81686d8d2ecdde513622c35c0ea6" } Frame { msec: 2576 - hash: "d4ead42bcc2e283e513f1ab4f8a89f27" + hash: "905c81686d8d2ecdde513622c35c0ea6" } Frame { msec: 2592 - hash: "d4ead42bcc2e283e513f1ab4f8a89f27" + hash: "905c81686d8d2ecdde513622c35c0ea6" } Frame { msec: 2608 - hash: "d4ead42bcc2e283e513f1ab4f8a89f27" + hash: "905c81686d8d2ecdde513622c35c0ea6" } Frame { msec: 2624 - hash: "d4ead42bcc2e283e513f1ab4f8a89f27" + hash: "905c81686d8d2ecdde513622c35c0ea6" } Frame { msec: 2640 - hash: "6d91b100f369381b24052e5a4466e24d" + hash: "537a2cf41a5e15220d2ca2218ac49a5a" } Frame { msec: 2656 - hash: "6d91b100f369381b24052e5a4466e24d" + hash: "537a2cf41a5e15220d2ca2218ac49a5a" } Frame { msec: 2672 - hash: "6d91b100f369381b24052e5a4466e24d" + hash: "537a2cf41a5e15220d2ca2218ac49a5a" } Frame { msec: 2688 - hash: "6d91b100f369381b24052e5a4466e24d" + hash: "537a2cf41a5e15220d2ca2218ac49a5a" } Frame { msec: 2704 - hash: "2d6082b41e3cfdc3be9c130311ac854a" + hash: "53325ce7d011eeb72369463721f15e87" } Frame { msec: 2720 - hash: "2d6082b41e3cfdc3be9c130311ac854a" + hash: "53325ce7d011eeb72369463721f15e87" } Frame { msec: 2736 - hash: "2d6082b41e3cfdc3be9c130311ac854a" + hash: "53325ce7d011eeb72369463721f15e87" } Frame { msec: 2752 - hash: "2d6082b41e3cfdc3be9c130311ac854a" + hash: "53325ce7d011eeb72369463721f15e87" } Frame { msec: 2768 - hash: "2d6082b41e3cfdc3be9c130311ac854a" + hash: "53325ce7d011eeb72369463721f15e87" } Frame { msec: 2784 - hash: "78732b58812f202768fa224aefce187d" + hash: "9ad2565cc95647a83d3ce3acc106485a" } Frame { msec: 2800 - hash: "78732b58812f202768fa224aefce187d" + hash: "9ad2565cc95647a83d3ce3acc106485a" } Frame { msec: 2816 - hash: "78732b58812f202768fa224aefce187d" + hash: "9ad2565cc95647a83d3ce3acc106485a" } Frame { msec: 2832 - hash: "78732b58812f202768fa224aefce187d" + hash: "9ad2565cc95647a83d3ce3acc106485a" } Frame { msec: 2848 - hash: "54d728d677cf3a07c4da7727a75e6c59" + hash: "de7b66581e0743385a984f76c993b01b" } Frame { msec: 2864 - hash: "54d728d677cf3a07c4da7727a75e6c59" + hash: "de7b66581e0743385a984f76c993b01b" } Frame { msec: 2880 - hash: "54d728d677cf3a07c4da7727a75e6c59" + hash: "de7b66581e0743385a984f76c993b01b" } Frame { msec: 2896 @@ -738,239 +738,239 @@ VisualTest { } Frame { msec: 2912 - hash: "54d728d677cf3a07c4da7727a75e6c59" + hash: "de7b66581e0743385a984f76c993b01b" } Frame { msec: 2928 - hash: "45ec3534077f6fa66d7710010cceb332" + hash: "f66852df1738e4fe29ac1f6938d814c2" } Frame { msec: 2944 - hash: "45ec3534077f6fa66d7710010cceb332" + hash: "f66852df1738e4fe29ac1f6938d814c2" } Frame { msec: 2960 - hash: "45ec3534077f6fa66d7710010cceb332" + hash: "f66852df1738e4fe29ac1f6938d814c2" } Frame { msec: 2976 - hash: "45ec3534077f6fa66d7710010cceb332" + hash: "f66852df1738e4fe29ac1f6938d814c2" } Frame { msec: 2992 - hash: "ef909728fa59292ffed1d047835439d6" + hash: "cf6dde6c590879a9e905a0f559f089ca" } Frame { msec: 3008 - hash: "ef909728fa59292ffed1d047835439d6" + hash: "cf6dde6c590879a9e905a0f559f089ca" } Frame { msec: 3024 - hash: "ef909728fa59292ffed1d047835439d6" + hash: "cf6dde6c590879a9e905a0f559f089ca" } Frame { msec: 3040 - hash: "ef909728fa59292ffed1d047835439d6" + hash: "cf6dde6c590879a9e905a0f559f089ca" } Frame { msec: 3056 - hash: "ef909728fa59292ffed1d047835439d6" + hash: "cf6dde6c590879a9e905a0f559f089ca" } Frame { msec: 3072 - hash: "454741313d087e5d13ddeaf02663746f" + hash: "bd63e4df280010ed9f67fc7976b86cb5" } Frame { msec: 3088 - hash: "454741313d087e5d13ddeaf02663746f" + hash: "bd63e4df280010ed9f67fc7976b86cb5" } Frame { msec: 3104 - hash: "454741313d087e5d13ddeaf02663746f" + hash: "bd63e4df280010ed9f67fc7976b86cb5" } Frame { msec: 3120 - hash: "454741313d087e5d13ddeaf02663746f" + hash: "bd63e4df280010ed9f67fc7976b86cb5" } Frame { msec: 3136 - hash: "454741313d087e5d13ddeaf02663746f" + hash: "bd63e4df280010ed9f67fc7976b86cb5" } Frame { msec: 3152 - hash: "02928f0a8f8f1011028114487b8dccf8" + hash: "065d3d370faa58aed9899cae0f86f032" } Frame { msec: 3168 - hash: "02928f0a8f8f1011028114487b8dccf8" + hash: "065d3d370faa58aed9899cae0f86f032" } Frame { msec: 3184 - hash: "02928f0a8f8f1011028114487b8dccf8" + hash: "065d3d370faa58aed9899cae0f86f032" } Frame { msec: 3200 - hash: "02928f0a8f8f1011028114487b8dccf8" + hash: "065d3d370faa58aed9899cae0f86f032" } Frame { msec: 3216 - hash: "e0fca67bb095c9891831cd9355b4880d" + hash: "b5623d05c578a6f09bcfacd4d3163b09" } Frame { msec: 3232 - hash: "e0fca67bb095c9891831cd9355b4880d" + hash: "b5623d05c578a6f09bcfacd4d3163b09" } Frame { msec: 3248 - hash: "e0fca67bb095c9891831cd9355b4880d" + hash: "b5623d05c578a6f09bcfacd4d3163b09" } Frame { msec: 3264 - hash: "e0fca67bb095c9891831cd9355b4880d" + hash: "b5623d05c578a6f09bcfacd4d3163b09" } Frame { msec: 3280 - hash: "f5ae54931d953fc95cfbdbde1993bebe" + hash: "83c70529d05911ea26a5cbbab5aa20f2" } Frame { msec: 3296 - hash: "f5ae54931d953fc95cfbdbde1993bebe" + hash: "83c70529d05911ea26a5cbbab5aa20f2" } Frame { msec: 3312 - hash: "f5ae54931d953fc95cfbdbde1993bebe" + hash: "83c70529d05911ea26a5cbbab5aa20f2" } Frame { msec: 3328 - hash: "f5ae54931d953fc95cfbdbde1993bebe" + hash: "83c70529d05911ea26a5cbbab5aa20f2" } Frame { msec: 3344 - hash: "f5ae54931d953fc95cfbdbde1993bebe" + hash: "83c70529d05911ea26a5cbbab5aa20f2" } Frame { msec: 3360 - hash: "9afb0b2a185e2f825e9fad1c3644f6cb" + hash: "17927c706da1bc222ba5462af66a9d2f" } Frame { msec: 3376 - hash: "9afb0b2a185e2f825e9fad1c3644f6cb" + hash: "17927c706da1bc222ba5462af66a9d2f" } Frame { msec: 3392 - hash: "9afb0b2a185e2f825e9fad1c3644f6cb" + hash: "17927c706da1bc222ba5462af66a9d2f" } Frame { msec: 3408 - hash: "9afb0b2a185e2f825e9fad1c3644f6cb" + hash: "17927c706da1bc222ba5462af66a9d2f" } Frame { msec: 3424 - hash: "9afb0b2a185e2f825e9fad1c3644f6cb" + hash: "17927c706da1bc222ba5462af66a9d2f" } Frame { msec: 3440 - hash: "f3f5a81d3b5f644a00cea6203f38994c" + hash: "f49627ba8d3e257e0e94404da24d12dc" } Frame { msec: 3456 - hash: "f3f5a81d3b5f644a00cea6203f38994c" + hash: "f49627ba8d3e257e0e94404da24d12dc" } Frame { msec: 3472 - hash: "f3f5a81d3b5f644a00cea6203f38994c" + hash: "f49627ba8d3e257e0e94404da24d12dc" } Frame { msec: 3488 - hash: "f3f5a81d3b5f644a00cea6203f38994c" + hash: "f49627ba8d3e257e0e94404da24d12dc" } Frame { msec: 3504 - hash: "bd9884712fd5afe67a3622c809bf4e76" + hash: "37a0c9dc20431c8398409d4522a0fdd3" } Frame { msec: 3520 - hash: "bd9884712fd5afe67a3622c809bf4e76" + hash: "37a0c9dc20431c8398409d4522a0fdd3" } Frame { msec: 3536 - hash: "bd9884712fd5afe67a3622c809bf4e76" + hash: "37a0c9dc20431c8398409d4522a0fdd3" } Frame { msec: 3552 - hash: "bd9884712fd5afe67a3622c809bf4e76" + hash: "37a0c9dc20431c8398409d4522a0fdd3" } Frame { msec: 3568 - hash: "c9324386954380a72ef4084d13e623b5" + hash: "67bebfe9fb5ac745f40040ff8083e999" } Frame { msec: 3584 - hash: "c9324386954380a72ef4084d13e623b5" + hash: "67bebfe9fb5ac745f40040ff8083e999" } Frame { msec: 3600 - hash: "c9324386954380a72ef4084d13e623b5" + hash: "67bebfe9fb5ac745f40040ff8083e999" } Frame { msec: 3616 - hash: "c9324386954380a72ef4084d13e623b5" + hash: "67bebfe9fb5ac745f40040ff8083e999" } Frame { msec: 3632 - hash: "c9324386954380a72ef4084d13e623b5" + hash: "67bebfe9fb5ac745f40040ff8083e999" } Frame { msec: 3648 - hash: "6d05fd8e8690e44293af1809f359aa72" + hash: "84f8b27b83b566c99e65ea39b29772c1" } Frame { msec: 3664 - hash: "6d05fd8e8690e44293af1809f359aa72" + hash: "84f8b27b83b566c99e65ea39b29772c1" } Frame { msec: 3680 - hash: "6d05fd8e8690e44293af1809f359aa72" + hash: "84f8b27b83b566c99e65ea39b29772c1" } Frame { msec: 3696 - hash: "6d05fd8e8690e44293af1809f359aa72" + hash: "84f8b27b83b566c99e65ea39b29772c1" } Frame { msec: 3712 - hash: "6d05fd8e8690e44293af1809f359aa72" + hash: "84f8b27b83b566c99e65ea39b29772c1" } Frame { msec: 3728 - hash: "2d7350a79f5a68d3e3dfc994c6e002ed" + hash: "c6ba663536f19b9f291ef35b7a70e490" } Frame { msec: 3744 - hash: "2d7350a79f5a68d3e3dfc994c6e002ed" + hash: "c6ba663536f19b9f291ef35b7a70e490" } Frame { msec: 3760 - hash: "2d7350a79f5a68d3e3dfc994c6e002ed" + hash: "c6ba663536f19b9f291ef35b7a70e490" } Frame { msec: 3776 - hash: "2d7350a79f5a68d3e3dfc994c6e002ed" + hash: "c6ba663536f19b9f291ef35b7a70e490" } Frame { msec: 3792 - hash: "edb5d50f23a293a7791122fc159aaaa0" + hash: "65f22784730aa27b2628d015a1cc4abe" } Frame { msec: 3808 - hash: "edb5d50f23a293a7791122fc159aaaa0" + hash: "65f22784730aa27b2628d015a1cc4abe" } Frame { msec: 3824 - hash: "edb5d50f23a293a7791122fc159aaaa0" + hash: "65f22784730aa27b2628d015a1cc4abe" } Frame { msec: 3840 - hash: "edb5d50f23a293a7791122fc159aaaa0" + hash: "65f22784730aa27b2628d015a1cc4abe" } Frame { msec: 3856 @@ -978,14 +978,14 @@ VisualTest { } Frame { msec: 3872 - hash: "a863480fec9abf817752c5eb62a2ddf4" + hash: "b11a511d80de87329501b9c11aebbc58" } Frame { msec: 3888 - hash: "a863480fec9abf817752c5eb62a2ddf4" + hash: "b11a511d80de87329501b9c11aebbc58" } Frame { msec: 3904 - hash: "a863480fec9abf817752c5eb62a2ddf4" + hash: "b11a511d80de87329501b9c11aebbc58" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/multilength.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/multilength.0.png index e1d3b75..3861b4f 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/multilength.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/multilength.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/multilength.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/multilength.1.png index 8013dc9..ce166f1 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/multilength.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/multilength.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/multilength.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/multilength.qml index 77a7b2f..84778ac 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/multilength.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-MAC/multilength.qml @@ -10,239 +10,239 @@ VisualTest { } Frame { msec: 32 - hash: "ef2b4cc93e5bf5e64d3338921fe36336" + hash: "58d757783e6d57c5ac2596219dfd37be" } Frame { msec: 48 - hash: "3ddbd1a53a36b0f8b36d87e742f3b1bd" + hash: "e76b3b98f447b706c59ba0c175e1829d" } Frame { msec: 64 - hash: "f7acfdaf29a3d7bd179b30db784ca01b" + hash: "f0dbb0b55d1d27bf7c0260db5b5782a2" } Frame { msec: 80 - hash: "b5277d02ed63180e845c60e1dd4da7d0" + hash: "00845517336befd7ead0141312ea38ce" } Frame { msec: 96 - hash: "a7964577d77943d5a62c02ea1e689eb7" + hash: "99723ae092407e5291ed3a13f5a7be61" } Frame { msec: 112 - hash: "fc597a07209bfea49227ec491b033af1" + hash: "2d531f1dd1545a4e2f8ca4c65338e0c3" } Frame { msec: 128 - hash: "429a7dd5a23a5012f1985bcddd27ba0c" + hash: "9f273323f48a70be279302b194203a36" } Frame { msec: 144 - hash: "fbf845e137e0b389babdcd71a95c3060" + hash: "7de4bd5f82369953c2a4a990ddaf4339" } Frame { msec: 160 - hash: "1d1272df3a53cb9860d23be3343a143e" + hash: "96c5f74c01723a15a57db161604bc245" } Frame { msec: 176 - hash: "cef05f6564b21fd2cbd02f6def604c0b" + hash: "df2eac6300919044cfe2a2f591c3bd99" } Frame { msec: 192 - hash: "be0ca54bc7aa23c2b9c56e3a0444197a" + hash: "a153904cdfa0be697a25bebc4ce1fbca" } Frame { msec: 208 - hash: "5372a7052d10b8c6c2204efdc88c2f48" + hash: "de243731b92ac1cac05e194aed0acd1e" } Frame { msec: 224 - hash: "43b775c558843c1334e86ca4fcf07ae2" + hash: "f6ccc0f127bfc6212885c3c6470639ed" } Frame { msec: 240 - hash: "10daf71511454ef4db3692a19ecbcbaa" + hash: "a2d56227aebedb9590a1124e44fe8e84" } Frame { msec: 256 - hash: "5c545ecb0ddfaa5d6cde266be6fae35c" + hash: "5f8c0a42a231580dcfff6a534e77bef8" } Frame { msec: 272 - hash: "1a3c05b189c3adf87710eeb03296aec2" + hash: "e631663ac692ab097cb28095b45e8563" } Frame { msec: 288 - hash: "de2c6f4d3bf4d245e45e47a743808f5d" + hash: "2a03f6ba3c67a9e9732cc1f5cdc42c23" } Frame { msec: 304 - hash: "7c71dcbd8e2be19ac2d090ab3e012a62" + hash: "26b85080d624b232e5209aa082fc11b1" } Frame { msec: 320 - hash: "3bd42257fe4a5d941a8755e66db94870" + hash: "1c027f4a0114bb9050a3a8d9de2b8a56" } Frame { msec: 336 - hash: "d52f57a1f289d2c697fd1db2086a4df3" + hash: "788e6ad3cb5f6e120e40fd3dc6ac8483" } Frame { msec: 352 - hash: "5d9e22ca6b6f8e4805a49fcf9c6a4dd6" + hash: "7e1b0fb71528dfa17a87950c0ff86111" } Frame { msec: 368 - hash: "cbafada44b434ac7fe64fdebef7a816e" + hash: "e1878e6e8ba14d8945e1f71ac8d42c1e" } Frame { msec: 384 - hash: "4ac900c005cfedb9e3367a4612334cc1" + hash: "556f42297eb1e57d6a8af0946651a75e" } Frame { msec: 400 - hash: "3dbe30edac497ca316bf39e55ff9580a" + hash: "73df08e7e3391b339cea9f5f082fd83a" } Frame { msec: 416 - hash: "e892891c063172d513f4f8c0a0b2644f" + hash: "de3bd8a12c2a448738ce77036b97bda7" } Frame { msec: 432 - hash: "7c214a442c8f37d22f74343fdb7f7faa" + hash: "0ab187aa7a478dbf005f35416a93c456" } Frame { msec: 448 - hash: "c4461c6c26eb9689e640149b7755bf14" + hash: "e5baf64ccafa6a4d2bf74aacf52019c6" } Frame { msec: 464 - hash: "e7be611f007716a80698558d0600f5b6" + hash: "0ed2ee4a773ade712ef207549006aa7b" } Frame { msec: 480 - hash: "5a3abaa7b36fcd7e2279318671597386" + hash: "b23dd49bdfe8fb155e2055262e6a1478" } Frame { msec: 496 - hash: "2dba1fcba5bdce948fa56ffc02a7f80c" + hash: "871f82636a03d6fa8cbfb580038bd0b7" } Frame { msec: 512 - hash: "55043bcce83e4f8899b1a692fe30fa67" + hash: "463cdc2cbde034d7d7a5061338b319c7" } Frame { msec: 528 - hash: "f92df1fb28a7da39ed907dd2bc177ab8" + hash: "22ff8e25136877fd6f5dce1b01e65c08" } Frame { msec: 544 - hash: "7dcf90cd5f81999359ed389c7050d934" + hash: "97d4e49622d877e9e1e0102786e1ee55" } Frame { msec: 560 - hash: "021014366809103b76bd5d472c43b062" + hash: "ebf5304185abe4bc33be44c3df09a93a" } Frame { msec: 576 - hash: "fff5b2c8d63083d132c0f106fad84fa1" + hash: "307887d9973e807c52b2143cdfe438ad" } Frame { msec: 592 - hash: "ab3a6a6c646d31be97884484a6647330" + hash: "d89547539741f387fdd6aa80ef239fbd" } Frame { msec: 608 - hash: "d46a168f89d94a32496b75ee5d3794e4" + hash: "b818215b4cdd6e811057f1a0f5eb1a5a" } Frame { msec: 624 - hash: "f7b62e86595a4d2c7f5a2cd52e0938b9" + hash: "84f7e523c0f21236ff8aad1333470d11" } Frame { msec: 640 - hash: "df95a29a101889c50537cfb1b027f9a6" + hash: "7f974663c7add6d10ebdd401794e087a" } Frame { msec: 656 - hash: "4c6691ef37222260dce72868ae809d68" + hash: "4c824dc01e8fead2706608ca68293d11" } Frame { msec: 672 - hash: "ad816534dcf446a1456894ff2b1afa33" + hash: "86b0f617eb3bfff944c3b670b3b51c71" } Frame { msec: 688 - hash: "bfa9f9f833f38aedf766e061f3a18c48" + hash: "86c5660c22003099cc4121381c11de85" } Frame { msec: 704 - hash: "f4a6786e9db58cf3fd3f3b896d3cf84f" + hash: "3c2bd08ea17aaa920949239f06b255cf" } Frame { msec: 720 - hash: "e51e8b766e5d4a0f061dc6885fcf8eb3" + hash: "2380278cc065a3ac5355127d9873796c" } Frame { msec: 736 - hash: "eab6d261429c36c4e37005f37b7823d5" + hash: "e5d8624e841476926b3e2a5ebca8c65f" } Frame { msec: 752 - hash: "3cc5db209a98daef06127bae53b1929d" + hash: "eab70f5005a6b39e3ead6e4452df1a54" } Frame { msec: 768 - hash: "230cd6e6ca18a921a21379dd85e24822" + hash: "46acef023d154bad3f91e0267996421b" } Frame { msec: 784 - hash: "e3a877e8f01bf17fe6ea8b9fbb780f14" + hash: "26ba9f30a4bfd72c9b6dae2a25660ea9" } Frame { msec: 800 - hash: "a19f504a81409dea775481f21f992ba6" + hash: "9fabdd5cf1190fb34bdc7834eba01cd3" } Frame { msec: 816 - hash: "e77cc3ab14551638e704a1493189d5d1" + hash: "b1e7af47d4ee706374365fdd4b4d52be" } Frame { msec: 832 - hash: "613bdf9d32358ab0db310ae1e2246d52" + hash: "86fa2e142e75d9d2a074a5376992f139" } Frame { msec: 848 - hash: "d4fab0193f567cce4ad1e1cf6b156ce5" + hash: "a3dea2bf8f84743d35070e82ec585c9a" } Frame { msec: 864 - hash: "03ce3083411d10b14ac0bb85b22bfbd1" + hash: "ab649fbbe0ca508812de9839d14b3f8c" } Frame { msec: 880 - hash: "4be10fb14abf82705d8071cf75956ece" + hash: "08f8a334e121d4edb0ca1617353bfebc" } Frame { msec: 896 - hash: "4c1f150fb5ba1194ad198eb32f705af6" + hash: "bb7997c1e18b90cfaad4c3e4ec44356e" } Frame { msec: 912 - hash: "5ddfd98c8a49eefe08ae33d0c0ea52ff" + hash: "31a7e5d71c28eebfcd29e9ea4950ad17" } Frame { msec: 928 - hash: "f2018d16f38e113c9477c19431e3d1e4" + hash: "2b759276e03c2884bff7ed863c032dfc" } Frame { msec: 944 - hash: "9fe6406d65978dba74716f1ba02bdf76" + hash: "aa0868f006097a435c46368ea9e3ba36" } Frame { msec: 960 - hash: "265d92edca113f465e624079c266b213" + hash: "6454753699c21589d2523a83da0aaa34" } Frame { msec: 976 @@ -250,54 +250,54 @@ VisualTest { } Frame { msec: 992 - hash: "6beb60f7645be5f1d07449610b5e13b0" + hash: "ac26abff68fbc1cf89dc5efc4a714a04" } Frame { msec: 1008 - hash: "55c34cb290732a1fa94b5037477fd882" + hash: "d3f9dc8cb653d996fb57652f85abcbc1" } Frame { msec: 1024 - hash: "4d6ed8044e3ac5da61cf61f4d08c5a19" + hash: "002a94f067eef532f63b6ef916977c2c" } Frame { msec: 1040 - hash: "83657cfa447060a01d5fbdb890ad3fb9" + hash: "f7935d01ee9b497034cc1d8f007a0fdf" } Frame { msec: 1056 - hash: "b04b6cb7e5e464ecee15a2c9803a857f" + hash: "4a1bfdcc85e5444c1bd836399e86ee05" } Frame { msec: 1072 - hash: "ea4f1707e49527f6cae0a3df1b75137b" + hash: "1b86514f3c85a8438ef183cc4772e997" } Frame { msec: 1088 - hash: "ae4893aca919be2d89f1107185b5fe9a" + hash: "7bf4c1ca946288e9d1a7ad055d8cacaa" } Frame { msec: 1104 - hash: "d991c469947a94ffcfb63716226fa912" + hash: "b3a00861967157786a80c80030d5495b" } Frame { msec: 1120 - hash: "df63c1dba0399d1fe5e7b9c9c794b598" + hash: "b9c6195d3336d7519cc72b16e75d00f6" } Frame { msec: 1136 - hash: "305d263f68b4ccd78bffccd887870f97" + hash: "6dba6d030a5ff6a92a57f0bdcf0fe781" } Frame { msec: 1152 - hash: "f4d1f7245b519d623defdc12e76285d2" + hash: "cc97a2721f4339094819c8b7aec6d74c" } Frame { msec: 1168 - hash: "5a47e6498ddf8a02cb1df7a3510bac37" + hash: "190f67abce51f58fdd1591651633d67e" } Frame { msec: 1184 - hash: "358b9b6be7f8379815d8ee828eed3e43" + hash: "b255f75cfc4918663b8bd47c887cfb3c" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/plaintext.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/plaintext.0.png index 591c1ef..cfa61a9 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/plaintext.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/plaintext.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/plaintext2.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/plaintext2.0.png index dc90e0d..be676c0 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/plaintext2.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/plaintext2.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/plaintext3.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/plaintext3.0.png index c787029..df2fe2f 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/plaintext3.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/plaintext3.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/richtext.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/richtext.0.png index fdd64ac..76e5b9f 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/richtext.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/richtext.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/richtext2.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/richtext2.0.png index 1286e54..bb65ade 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/richtext2.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-MAC/richtext2.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.1.png index 05dd690..060be22 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.2.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.2.png index eb74cc5..d373aef 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.2.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.3.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.3.png index 3aed06c..5dad108 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.3.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.qml index 2de4a10..6081aaf 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/echoMode.qml @@ -110,23 +110,23 @@ VisualTest { } Frame { msec: 368 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 384 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 400 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 416 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 432 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Key { type: 7 @@ -138,27 +138,27 @@ VisualTest { } Frame { msec: 448 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 464 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 480 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 496 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 512 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 528 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Key { type: 7 @@ -170,43 +170,43 @@ VisualTest { } Frame { msec: 544 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 560 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 576 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 592 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 608 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 624 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 640 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 656 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 672 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Frame { msec: 688 - hash: "bc06530170cf26690a09ed9f6c4014fd" + hash: "593867b082681c362d7dffda12615284" } Key { type: 6 @@ -218,23 +218,23 @@ VisualTest { } Frame { msec: 704 - hash: "8c64a986ce7bd19dcc88785309456f4e" + hash: "8d4a4baca932c318fba437b05962a635" } Frame { msec: 720 - hash: "8c64a986ce7bd19dcc88785309456f4e" + hash: "8d4a4baca932c318fba437b05962a635" } Frame { msec: 736 - hash: "8c64a986ce7bd19dcc88785309456f4e" + hash: "8d4a4baca932c318fba437b05962a635" } Frame { msec: 752 - hash: "8c64a986ce7bd19dcc88785309456f4e" + hash: "8d4a4baca932c318fba437b05962a635" } Frame { msec: 768 - hash: "8c64a986ce7bd19dcc88785309456f4e" + hash: "8d4a4baca932c318fba437b05962a635" } Key { type: 7 @@ -246,23 +246,23 @@ VisualTest { } Frame { msec: 784 - hash: "8c64a986ce7bd19dcc88785309456f4e" + hash: "8d4a4baca932c318fba437b05962a635" } Frame { msec: 800 - hash: "8c64a986ce7bd19dcc88785309456f4e" + hash: "8d4a4baca932c318fba437b05962a635" } Frame { msec: 816 - hash: "8c64a986ce7bd19dcc88785309456f4e" + hash: "8d4a4baca932c318fba437b05962a635" } Frame { msec: 832 - hash: "8c64a986ce7bd19dcc88785309456f4e" + hash: "8d4a4baca932c318fba437b05962a635" } Frame { msec: 848 - hash: "8c64a986ce7bd19dcc88785309456f4e" + hash: "8d4a4baca932c318fba437b05962a635" } Key { type: 6 @@ -274,15 +274,15 @@ VisualTest { } Frame { msec: 864 - hash: "4cfca8edcb96b1d9986db4ee491bf857" + hash: "b2698dba3a5ebe80e26f273b32857506" } Frame { msec: 880 - hash: "4cfca8edcb96b1d9986db4ee491bf857" + hash: "b2698dba3a5ebe80e26f273b32857506" } Frame { msec: 896 - hash: "4cfca8edcb96b1d9986db4ee491bf857" + hash: "b2698dba3a5ebe80e26f273b32857506" } Key { type: 7 @@ -294,19 +294,19 @@ VisualTest { } Frame { msec: 912 - hash: "4cfca8edcb96b1d9986db4ee491bf857" + hash: "b2698dba3a5ebe80e26f273b32857506" } Frame { msec: 928 - hash: "4cfca8edcb96b1d9986db4ee491bf857" + hash: "b2698dba3a5ebe80e26f273b32857506" } Frame { msec: 944 - hash: "4cfca8edcb96b1d9986db4ee491bf857" + hash: "b2698dba3a5ebe80e26f273b32857506" } Frame { msec: 960 - hash: "4cfca8edcb96b1d9986db4ee491bf857" + hash: "b2698dba3a5ebe80e26f273b32857506" } Frame { msec: 976 @@ -322,19 +322,19 @@ VisualTest { } Frame { msec: 992 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Frame { msec: 1008 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Frame { msec: 1024 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Frame { msec: 1040 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Key { type: 7 @@ -346,51 +346,51 @@ VisualTest { } Frame { msec: 1056 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Frame { msec: 1072 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Frame { msec: 1088 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Frame { msec: 1104 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Frame { msec: 1120 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Frame { msec: 1136 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Frame { msec: 1152 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Frame { msec: 1168 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Frame { msec: 1184 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Frame { msec: 1200 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Frame { msec: 1216 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Frame { msec: 1232 - hash: "3d25316ea23ace5a88dbe8765b743eb3" + hash: "3ea06a90d633d5e9fe5a11cc4ed67764" } Key { type: 6 @@ -402,15 +402,15 @@ VisualTest { } Frame { msec: 1248 - hash: "fea82a32ec46a88027cc9b0c00aa0aba" + hash: "a190bbf59ec807391077b9d1183f72b5" } Frame { msec: 1264 - hash: "fea82a32ec46a88027cc9b0c00aa0aba" + hash: "a190bbf59ec807391077b9d1183f72b5" } Frame { msec: 1280 - hash: "fea82a32ec46a88027cc9b0c00aa0aba" + hash: "a190bbf59ec807391077b9d1183f72b5" } Key { type: 7 @@ -422,15 +422,15 @@ VisualTest { } Frame { msec: 1296 - hash: "fea82a32ec46a88027cc9b0c00aa0aba" + hash: "a190bbf59ec807391077b9d1183f72b5" } Frame { msec: 1312 - hash: "fea82a32ec46a88027cc9b0c00aa0aba" + hash: "a190bbf59ec807391077b9d1183f72b5" } Frame { msec: 1328 - hash: "fea82a32ec46a88027cc9b0c00aa0aba" + hash: "a190bbf59ec807391077b9d1183f72b5" } Key { type: 6 @@ -442,39 +442,39 @@ VisualTest { } Frame { msec: 1344 - hash: "fffa6f462ea15fe3bdbf2c199881fce4" + hash: "f171a98a3a726b517ad4b401a0720ba2" } Frame { msec: 1360 - hash: "fffa6f462ea15fe3bdbf2c199881fce4" + hash: "f171a98a3a726b517ad4b401a0720ba2" } Frame { msec: 1376 - hash: "fffa6f462ea15fe3bdbf2c199881fce4" + hash: "f171a98a3a726b517ad4b401a0720ba2" } Frame { msec: 1392 - hash: "fffa6f462ea15fe3bdbf2c199881fce4" + hash: "f171a98a3a726b517ad4b401a0720ba2" } Frame { msec: 1408 - hash: "fffa6f462ea15fe3bdbf2c199881fce4" + hash: "f171a98a3a726b517ad4b401a0720ba2" } Frame { msec: 1424 - hash: "fffa6f462ea15fe3bdbf2c199881fce4" + hash: "f171a98a3a726b517ad4b401a0720ba2" } Frame { msec: 1440 - hash: "fffa6f462ea15fe3bdbf2c199881fce4" + hash: "f171a98a3a726b517ad4b401a0720ba2" } Frame { msec: 1456 - hash: "fffa6f462ea15fe3bdbf2c199881fce4" + hash: "f171a98a3a726b517ad4b401a0720ba2" } Frame { msec: 1472 - hash: "fffa6f462ea15fe3bdbf2c199881fce4" + hash: "f171a98a3a726b517ad4b401a0720ba2" } Key { type: 7 @@ -486,7 +486,7 @@ VisualTest { } Frame { msec: 1488 - hash: "fffa6f462ea15fe3bdbf2c199881fce4" + hash: "f171a98a3a726b517ad4b401a0720ba2" } Key { type: 6 @@ -498,19 +498,19 @@ VisualTest { } Frame { msec: 1504 - hash: "d874584748e4aa14fd71730aa36d676c" + hash: "e7199e4284be9dea34caff7bde0f6303" } Frame { msec: 1520 - hash: "d874584748e4aa14fd71730aa36d676c" + hash: "e7199e4284be9dea34caff7bde0f6303" } Frame { msec: 1536 - hash: "d874584748e4aa14fd71730aa36d676c" + hash: "e7199e4284be9dea34caff7bde0f6303" } Frame { msec: 1552 - hash: "d874584748e4aa14fd71730aa36d676c" + hash: "e7199e4284be9dea34caff7bde0f6303" } Key { type: 7 @@ -522,27 +522,27 @@ VisualTest { } Frame { msec: 1568 - hash: "d874584748e4aa14fd71730aa36d676c" + hash: "e7199e4284be9dea34caff7bde0f6303" } Frame { msec: 1584 - hash: "d874584748e4aa14fd71730aa36d676c" + hash: "e7199e4284be9dea34caff7bde0f6303" } Frame { msec: 1600 - hash: "d874584748e4aa14fd71730aa36d676c" + hash: "e7199e4284be9dea34caff7bde0f6303" } Frame { msec: 1616 - hash: "d874584748e4aa14fd71730aa36d676c" + hash: "e7199e4284be9dea34caff7bde0f6303" } Frame { msec: 1632 - hash: "d874584748e4aa14fd71730aa36d676c" + hash: "e7199e4284be9dea34caff7bde0f6303" } Frame { msec: 1648 - hash: "d874584748e4aa14fd71730aa36d676c" + hash: "e7199e4284be9dea34caff7bde0f6303" } Key { type: 6 @@ -554,23 +554,23 @@ VisualTest { } Frame { msec: 1664 - hash: "5eac6452c3c01de25633be412b2c9fd6" + hash: "1d9d3c6435f2fa06bda16ef4a2ff238f" } Frame { msec: 1680 - hash: "5eac6452c3c01de25633be412b2c9fd6" + hash: "1d9d3c6435f2fa06bda16ef4a2ff238f" } Frame { msec: 1696 - hash: "5eac6452c3c01de25633be412b2c9fd6" + hash: "1d9d3c6435f2fa06bda16ef4a2ff238f" } Frame { msec: 1712 - hash: "5eac6452c3c01de25633be412b2c9fd6" + hash: "1d9d3c6435f2fa06bda16ef4a2ff238f" } Frame { msec: 1728 - hash: "5eac6452c3c01de25633be412b2c9fd6" + hash: "1d9d3c6435f2fa06bda16ef4a2ff238f" } Key { type: 6 @@ -582,7 +582,7 @@ VisualTest { } Frame { msec: 1744 - hash: "8bf395bd43cf0483aea0ddf3e8ab8c56" + hash: "9d8cb02bbc4f39d38ccdf8e9bda0ed5c" } Key { type: 7 @@ -594,15 +594,15 @@ VisualTest { } Frame { msec: 1760 - hash: "8bf395bd43cf0483aea0ddf3e8ab8c56" + hash: "9d8cb02bbc4f39d38ccdf8e9bda0ed5c" } Frame { msec: 1776 - hash: "8bf395bd43cf0483aea0ddf3e8ab8c56" + hash: "9d8cb02bbc4f39d38ccdf8e9bda0ed5c" } Frame { msec: 1792 - hash: "8bf395bd43cf0483aea0ddf3e8ab8c56" + hash: "9d8cb02bbc4f39d38ccdf8e9bda0ed5c" } Key { type: 7 @@ -614,19 +614,19 @@ VisualTest { } Frame { msec: 1808 - hash: "8bf395bd43cf0483aea0ddf3e8ab8c56" + hash: "9d8cb02bbc4f39d38ccdf8e9bda0ed5c" } Frame { msec: 1824 - hash: "8bf395bd43cf0483aea0ddf3e8ab8c56" + hash: "9d8cb02bbc4f39d38ccdf8e9bda0ed5c" } Frame { msec: 1840 - hash: "8bf395bd43cf0483aea0ddf3e8ab8c56" + hash: "9d8cb02bbc4f39d38ccdf8e9bda0ed5c" } Frame { msec: 1856 - hash: "8bf395bd43cf0483aea0ddf3e8ab8c56" + hash: "9d8cb02bbc4f39d38ccdf8e9bda0ed5c" } Key { type: 6 @@ -638,19 +638,19 @@ VisualTest { } Frame { msec: 1872 - hash: "4a31bba56f9adaccf47e6335ed4e284f" + hash: "2af75935ad1d3be02c6481c094737575" } Frame { msec: 1888 - hash: "4a31bba56f9adaccf47e6335ed4e284f" + hash: "2af75935ad1d3be02c6481c094737575" } Frame { msec: 1904 - hash: "4a31bba56f9adaccf47e6335ed4e284f" + hash: "2af75935ad1d3be02c6481c094737575" } Frame { msec: 1920 - hash: "4a31bba56f9adaccf47e6335ed4e284f" + hash: "2af75935ad1d3be02c6481c094737575" } Key { type: 7 @@ -666,23 +666,23 @@ VisualTest { } Frame { msec: 1952 - hash: "4a31bba56f9adaccf47e6335ed4e284f" + hash: "2af75935ad1d3be02c6481c094737575" } Frame { msec: 1968 - hash: "4a31bba56f9adaccf47e6335ed4e284f" + hash: "2af75935ad1d3be02c6481c094737575" } Frame { msec: 1984 - hash: "4a31bba56f9adaccf47e6335ed4e284f" + hash: "2af75935ad1d3be02c6481c094737575" } Frame { msec: 2000 - hash: "4a31bba56f9adaccf47e6335ed4e284f" + hash: "2af75935ad1d3be02c6481c094737575" } Frame { msec: 2016 - hash: "4a31bba56f9adaccf47e6335ed4e284f" + hash: "2af75935ad1d3be02c6481c094737575" } Key { type: 6 @@ -694,11 +694,11 @@ VisualTest { } Frame { msec: 2032 - hash: "8bbabbbe84de490438d1111aa728c15f" + hash: "c3512d6a7ead481aa6fec8ef8ee2f1d1" } Frame { msec: 2048 - hash: "8bbabbbe84de490438d1111aa728c15f" + hash: "c3512d6a7ead481aa6fec8ef8ee2f1d1" } Key { type: 7 @@ -710,11 +710,11 @@ VisualTest { } Frame { msec: 2064 - hash: "8bbabbbe84de490438d1111aa728c15f" + hash: "c3512d6a7ead481aa6fec8ef8ee2f1d1" } Frame { msec: 2080 - hash: "8bbabbbe84de490438d1111aa728c15f" + hash: "c3512d6a7ead481aa6fec8ef8ee2f1d1" } Key { type: 6 @@ -726,19 +726,19 @@ VisualTest { } Frame { msec: 2096 - hash: "5877f1d527fecaf1077ff5bd2fe1934f" + hash: "064e1fc885ab7f07dad1770361087bef" } Frame { msec: 2112 - hash: "5877f1d527fecaf1077ff5bd2fe1934f" + hash: "064e1fc885ab7f07dad1770361087bef" } Frame { msec: 2128 - hash: "5877f1d527fecaf1077ff5bd2fe1934f" + hash: "064e1fc885ab7f07dad1770361087bef" } Frame { msec: 2144 - hash: "5877f1d527fecaf1077ff5bd2fe1934f" + hash: "064e1fc885ab7f07dad1770361087bef" } Key { type: 6 @@ -758,19 +758,19 @@ VisualTest { } Frame { msec: 2160 - hash: "1593ef669fdff28c33f54c12c7e7424e" + hash: "9b764f6e9cc3d30446e1b32f7ab94f66" } Frame { msec: 2176 - hash: "1593ef669fdff28c33f54c12c7e7424e" + hash: "9b764f6e9cc3d30446e1b32f7ab94f66" } Frame { msec: 2192 - hash: "1593ef669fdff28c33f54c12c7e7424e" + hash: "9b764f6e9cc3d30446e1b32f7ab94f66" } Frame { msec: 2208 - hash: "1593ef669fdff28c33f54c12c7e7424e" + hash: "9b764f6e9cc3d30446e1b32f7ab94f66" } Key { type: 6 @@ -782,7 +782,7 @@ VisualTest { } Frame { msec: 2224 - hash: "da746581451954d7d941fbac825a1009" + hash: "18eff632e106f632aad481ab40f985d7" } Key { type: 7 @@ -794,23 +794,23 @@ VisualTest { } Frame { msec: 2240 - hash: "da746581451954d7d941fbac825a1009" + hash: "18eff632e106f632aad481ab40f985d7" } Frame { msec: 2256 - hash: "da746581451954d7d941fbac825a1009" + hash: "18eff632e106f632aad481ab40f985d7" } Frame { msec: 2272 - hash: "da746581451954d7d941fbac825a1009" + hash: "18eff632e106f632aad481ab40f985d7" } Frame { msec: 2288 - hash: "da746581451954d7d941fbac825a1009" + hash: "18eff632e106f632aad481ab40f985d7" } Frame { msec: 2304 - hash: "da746581451954d7d941fbac825a1009" + hash: "18eff632e106f632aad481ab40f985d7" } Key { type: 7 @@ -822,11 +822,11 @@ VisualTest { } Frame { msec: 2320 - hash: "da746581451954d7d941fbac825a1009" + hash: "18eff632e106f632aad481ab40f985d7" } Frame { msec: 2336 - hash: "da746581451954d7d941fbac825a1009" + hash: "18eff632e106f632aad481ab40f985d7" } Key { type: 6 @@ -838,27 +838,27 @@ VisualTest { } Frame { msec: 2352 - hash: "3e008b7ead8459c1667f4f385d4c5372" + hash: "eaabd4617081e3bc68a5b9099c63272a" } Frame { msec: 2368 - hash: "3e008b7ead8459c1667f4f385d4c5372" + hash: "eaabd4617081e3bc68a5b9099c63272a" } Frame { msec: 2384 - hash: "3e008b7ead8459c1667f4f385d4c5372" + hash: "eaabd4617081e3bc68a5b9099c63272a" } Frame { msec: 2400 - hash: "3e008b7ead8459c1667f4f385d4c5372" + hash: "eaabd4617081e3bc68a5b9099c63272a" } Frame { msec: 2416 - hash: "3e008b7ead8459c1667f4f385d4c5372" + hash: "eaabd4617081e3bc68a5b9099c63272a" } Frame { msec: 2432 - hash: "3e008b7ead8459c1667f4f385d4c5372" + hash: "eaabd4617081e3bc68a5b9099c63272a" } Key { type: 7 @@ -870,19 +870,19 @@ VisualTest { } Frame { msec: 2448 - hash: "3e008b7ead8459c1667f4f385d4c5372" + hash: "eaabd4617081e3bc68a5b9099c63272a" } Frame { msec: 2464 - hash: "3e008b7ead8459c1667f4f385d4c5372" + hash: "eaabd4617081e3bc68a5b9099c63272a" } Frame { msec: 2480 - hash: "3e008b7ead8459c1667f4f385d4c5372" + hash: "eaabd4617081e3bc68a5b9099c63272a" } Frame { msec: 2496 - hash: "3e008b7ead8459c1667f4f385d4c5372" + hash: "eaabd4617081e3bc68a5b9099c63272a" } Key { type: 6 @@ -894,15 +894,15 @@ VisualTest { } Frame { msec: 2512 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2528 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2544 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Key { type: 7 @@ -914,87 +914,87 @@ VisualTest { } Frame { msec: 2560 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2576 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2592 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2608 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2624 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2640 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2656 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2672 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2688 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2704 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2720 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2736 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2752 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2768 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2784 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2800 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2816 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2832 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2848 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2864 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2880 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2896 @@ -1002,42 +1002,42 @@ VisualTest { } Frame { msec: 2912 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2928 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2944 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2960 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2976 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 2992 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 3008 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 3024 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 3040 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } Frame { msec: 3056 - hash: "1dbc7e1ab58dcec8691ff4195b0d581c" + hash: "fec019ea87914d30b5bf4754ce8ba916" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/usingLineEdit.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/usingLineEdit.qml index a1a0821..fc8a115 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/usingLineEdit.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-MAC/usingLineEdit.qml @@ -379,7 +379,7 @@ VisualTest { Key { type: 6 key: 16777249 - modifiers: 67108864 + modifiers: 0 text: "" autorep: false count: 1 @@ -583,7 +583,7 @@ VisualTest { Key { type: 7 key: 16777249 - modifiers: 0 + modifiers: 67108864 text: "" autorep: false count: 1 @@ -783,7 +783,7 @@ VisualTest { Key { type: 6 key: 16777249 - modifiers: 67108864 + modifiers: 0 text: "" autorep: false count: 1 @@ -1175,7 +1175,7 @@ VisualTest { Key { type: 7 key: 16777249 - modifiers: 0 + modifiers: 67108864 text: "" autorep: false count: 1 @@ -1823,7 +1823,7 @@ VisualTest { Key { type: 6 key: 16777249 - modifiers: 67108864 + modifiers: 0 text: "" autorep: false count: 1 @@ -2327,7 +2327,7 @@ VisualTest { Key { type: 7 key: 16777249 - modifiers: 0 + modifiers: 67108864 text: "" autorep: false count: 1 -- cgit v0.12 From 79281991e21bb5bd3a6f3288ac934aa4c2b33fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 25 Nov 2010 10:47:42 +0100 Subject: Let's use engine's understanding of relative path As much as I'd like to have the definition of "relative" be independent of custom engines, the current architecture prevents us from doing that without introducing knowledge about them in QFileSystemEntry. Fixing this specifically for resource files would be possible, but let's not break custom engines... just yet. Reviewed-by: Prasanth Ullattil --- src/corelib/io/qdir.cpp | 4 +++- src/corelib/io/qfileinfo.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 22a3baa..e1fed0d 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1544,7 +1544,9 @@ bool QDir::isRoot() const */ bool QDir::isRelative() const { - return d_ptr->dirEntry.isRelative(); + if (d_ptr->fileEngine.isNull()) + return d_ptr->dirEntry.isRelative(); + return d_ptr->fileEngine->isRelativePath(); } diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 471da2e..9041c94 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -623,7 +623,9 @@ bool QFileInfo::isRelative() const Q_D(const QFileInfo); if (d->isDefaultConstructed) return true; - return d->fileEntry.isRelative(); + if (d->fileEngine == 0) + return d->fileEntry.isRelative(); + return d->fileEngine->isRelativePath(); } /*! -- cgit v0.12 From ea814440efc8a4b956ba3a4cddd1f269f1734c96 Mon Sep 17 00:00:00 2001 From: Martin Petersson Date: Thu, 25 Nov 2010 12:57:13 +0100 Subject: Fix QTBUG-13928 non flat mode for project files in VS2010. Reviewed-by: Joerg Task-number: QTBUG-13928 --- qmake/generators/win32/msbuild_objectmodel.cpp | 31 ++++++++++++++++++++------ 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index c3436b4..3381d53 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -2908,26 +2908,43 @@ void XTreeNode::generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString if (children.size()) { // Filter + QString tempFilterName; ChildrenMap::ConstIterator it, end = children.constEnd(); if (!tagName.isEmpty()) { + tempFilterName.append(filter); + tempFilterName.append("\\"); + tempFilterName.append(tagName); + xmlFilter << tag(_ItemGroup); xmlFilter << tag("Filter") - << attrTag("Include", tagName) - << attrTagS("Extensions", ""); + << attrTag("Include", tempFilterName) + << closetag(); + xmlFilter << closetag(); } // First round, do nested filters for (it = children.constBegin(); it != end; ++it) if ((*it)->children.size()) - (*it)->generateXML(xml, xmlFilter, it.key(), tool, filter); + { + if ( !tempFilterName.isEmpty() ) + (*it)->generateXML(xml, xmlFilter, it.key(), tool, tempFilterName); + else + (*it)->generateXML(xml, xmlFilter, it.key(), tool, filter); + } // Second round, do leafs for (it = children.constBegin(); it != end; ++it) if (!(*it)->children.size()) - (*it)->generateXML(xml, xmlFilter, it.key(), tool, filter); - - if (!tagName.isEmpty()) - xml << closetag("Filter"); + { + if ( !tempFilterName.isEmpty() ) + (*it)->generateXML(xml, xmlFilter, it.key(), tool, tempFilterName); + else + (*it)->generateXML(xml, xmlFilter, it.key(), tool, filter); + } } else { // Leaf + xml << tag(_ItemGroup); + xmlFilter << tag(_ItemGroup); tool.outputFileConfigs(xml, xmlFilter, info, filter); + xmlFilter << closetag(); + xml << closetag(); } } -- cgit v0.12 From 1eca3f0ac1ac04fde7f99cfeae2301b8a25af718 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 25 Nov 2010 10:36:33 +0200 Subject: Only patch package content that is necessary for self-signing Automatic patching was modifying all package files in ways that only made sense for very limited set of projects. Some things were also no longer necessary due other developments, so dropped the dependency, embedded sis, and manufacturer check modifications. Also provided an option to do a self-signed compatibility check for the package instead of patching it automatically by specifying "-d" parameter in QT_SIS_OPTIONS env variable or createpackage command line, depending on how package is made. Task-number: QTBUG-15561 Reviewed-by: axis --- bin/createpackage.pl | 14 +- bin/patch_capabilities.pl | 215 +++++++++++++++------------- doc/src/platforms/symbian-introduction.qdoc | 1 + 3 files changed, 125 insertions(+), 105 deletions(-) diff --git a/bin/createpackage.pl b/bin/createpackage.pl index 522d1fb..6b83585 100755 --- a/bin/createpackage.pl +++ b/bin/createpackage.pl @@ -82,6 +82,8 @@ Where supported options are as follows: [-s|stub] = Generates stub sis for ROM. [-n|sisname ] = Specifies the final sis name. [-g|gcce-is-armv5] = Convert gcce platform to armv5. + [-d|dont-patch] = Skip automatic patching of capabilities and pkg file if default certificate + is used. Instead non-self-signable capabilities just cause warnings. Where parameters are as follows: templatepkg = Name of .pkg file template target = Either debug or release @@ -127,6 +129,7 @@ my $stub = ""; my $signed_sis_name = ""; my $onlyUnsigned = ""; my $convertGcce = ""; +my $dontPatchCaps = ""; unless (GetOptions('i|install' => \$install, 'p|preprocess' => \$preprocessonly, @@ -135,7 +138,8 @@ unless (GetOptions('i|install' => \$install, 'o|only-unsigned' => \$onlyUnsigned, 's|stub' => \$stub, 'n|sisname=s' => \$signed_sis_name, - 'g|gcce-is-armv5' => \$convertGcce,)) { + 'g|gcce-is-armv5' => \$convertGcce, + 'd|dont-patch' => \$dontPatchCaps,)) { Usage(); } @@ -343,9 +347,13 @@ if($stub) { && !@certificates && $templatepkg !~ m/_installer\.pkg$/i && !$onlyUnsigned) { - print("Auto-patching capabilities for self signed package.\n"); my $patch_capabilities = File::Spec->catfile(dirname($0), "patch_capabilities"); - system ("$patch_capabilities $pkgoutput") and die ("ERROR: Automatic patching failed"); + if ($dontPatchCaps) { + system ("$patch_capabilities -c $pkgoutput") and print ("Warning: Package check for self-signing viability failed. Installing the package on a device will most likely fail!\n\n"); + } else { + print("Auto-patching self-signed package.\n"); + system ("$patch_capabilities $pkgoutput") and die ("ERROR: Automatic patching failed"); + } } # Create SIS. diff --git a/bin/patch_capabilities.pl b/bin/patch_capabilities.pl index 994d493..df71339 100755 --- a/bin/patch_capabilities.pl +++ b/bin/patch_capabilities.pl @@ -63,8 +63,11 @@ sub Usage() { print(" symbian-sbsv2 platform, 'target-platform' is REQUIRED. ***\n\n"); print(" *** NOTE2: When patching gcce binaries built with symbian-sbsv2 toolchain,\n"); print(" armv5 must be specified as platform.\n"); - print("\nUsage: patch_capabilities.pl pkg_filename [target-platform [capability list]]\n"); + print("\nUsage: patch_capabilities.pl [-c] pkg_filename [target-platform [capability list]]\n"); print("\nE.g. patch_capabilities.pl myapp_template.pkg release-armv5 \"All -TCB\"\n"); + print("\nThe parameter -c can be used to just check if package is compatible with self-signing\n"); + print("without actually doing any patching.\n"); + print("Explicit capability list cannot be used with -c parameter.\n"); exit(); } @@ -86,6 +89,14 @@ if (@ARGV) { # Parse the first given script argument as a ".pkg" file name. my $pkgFileName = shift(@ARGV); + my $justCheck = ""; + my $msgPrefix = "Patching:"; + + if ($pkgFileName eq "-c") { + $pkgFileName = shift(@ARGV); + $justCheck = true; + $msgPrefix = "Warning:"; + } # These variables will only be set for template .pkg files. my $target; @@ -123,15 +134,22 @@ if (@ARGV) if (($pkgFileName =~ m|\.pkg$|i) && -r($pkgFileName)) { print ("\n"); - print ("Patching package file and relevant binaries...\n"); + if ($justCheck) { + print ("Checking"); + } else { + print ("Patching"); + } + print (" package file and relevant binaries...\n"); - # If there are more arguments given, parse them as capabilities. - if (@ARGV) - { - @capabilitiesSpecified = (); - while (@ARGV) + if (!$justCheck) { + # If there are more arguments given, parse them as capabilities. + if (@ARGV) { - push (@capabilitiesSpecified, pop(@ARGV)); + @capabilitiesSpecified = (); + while (@ARGV) + { + push (@capabilitiesSpecified, pop(@ARGV)); + } } } @@ -139,11 +157,15 @@ if (@ARGV) my @binaries = (); my $tempPkgFileName = $pkgFileName."_@@TEMP@@"; - unlink($tempPkgFileName); - open (NEW_PKG, ">>".$tempPkgFileName); + + if (!$justCheck) { + unlink($tempPkgFileName); + open (NEW_PKG, ">>".$tempPkgFileName); + } open (PKG, "<".$pkgFileName); - my $manufacturerElseBlock = 0; + my $checkFailed = ""; + my $somethingPatched = ""; # Parse each line. while () @@ -155,66 +177,19 @@ if (@ARGV) if ($line =~ m/^\#.*\((0x[0-7][0-9a-fA-F]*)\).*$/) { my $oldUID = $1; - my $newUID = $oldUID; - $newUID =~ s/0x./0xE/i; - $newLine =~ s/$oldUID/$newUID/; - print ("Patching: UID $oldUID is not compatible with self-signing! Changed to: $newUID.\n"); - } - - # Patch embedded sis name and UID if UID is in protected range - if ($line =~ m/^@\"*(.*\.sis).*\((0x[0-7][0-9a-fA-F]*)\).*$/) - { - my $oldSisName = $1; - my $oldUID = $2; - my $newUID = $oldUID; - $newUID =~ s/0x./0xE/i; - $newLine =~ s/$oldUID/$newUID/; - print ("Patching: Embedded sis $oldSisName UID $oldUID changed to: $newUID.\n"); - - if ($oldSisName !~ m/^.*_selfsigned.sis$/i) - { - my $newSisName = $oldSisName; - $newSisName =~ s/\.sis$/_selfsigned\.sis/i; - $newLine =~ s/$oldSisName/$newSisName/i; - print ("Patching: Embedded sis $oldSisName name changed to: $newSisName.\n"); + print ("$msgPrefix UID $oldUID is not compatible with self-signing!\n"); + + if ($justCheck) { + $checkFailed = true; + } else { + my $newUID = $oldUID; + $newUID =~ s/0x./0xE/i; + $newLine =~ s/$oldUID/$newUID/; + print ("$msgPrefix Package UID changed to: $newUID.\n"); + $somethingPatched = true; } } - # Remove dependencies to known problem packages (i.e. packages that are likely to be patched, too) - # to reduce unnecessary error messages. - if ($line =~ m/^\((0x2002af5f)\).*\{.*\}$/) - { - $newLine = "\n"; - print ("Patching: Removed dependency to sqlite3.sis ($1) to avoid installation issues in case sqlite3.sis is also patched.\n"); - } - if ($line =~ m/^\((0x2001E61C)\).*\{.*\}$/) - { - $newLine = "\n"; - print ("Patching: Removed dependency to qt.sis ($1) to avoid installation issues in case qt.sis is also patched.\n"); - } - - # Remove manufacturer ifdef - if ($line =~ m/^.*\(MANUFACTURER\)\=\(.*\).*$/) - { - $newLine = "\n"; - print ("Patching: Removed manufacturer check as it is usually not desirable in self-signed packages.\n"); - } - - if ($line =~ m/^ELSEIF.*MANUFACTURER$/) - { - $manufacturerElseBlock = 1; - } - - if ($manufacturerElseBlock eq 1) - { - $newLine = "\n"; - } - - if ($line =~ m/^ENDIF.*MANUFACTURER$/) - { - $manufacturerElseBlock = 0; - } - # If the line specifies a file, parse the source and destination locations. if ($line =~ m|^ *\"([^\"]+)\"\s*\-\s*\"([^\"]+)\"|) { @@ -231,16 +206,20 @@ if (@ARGV) $sourcePath =~ s/\$\(TARGET\)/$target/gm; } - # Change the source file name (but only if not already patched) - my $patchedSourcePath = $sourcePath; - if ($patchedSourcePath !~ m/_patched_caps/) - { - $newLine =~ s/(^.*)(\.dll|\.exe)(.*)(\.dll|\.exe)/$1_patched_caps$2$3$4/i; - $patchedSourcePath =~ s/(^.*)(\.dll|\.exe)/$1_patched_caps$2/i; - - copy($sourcePath, $patchedSourcePath) or die "$sourcePath cannot be copied for patching."; + if ($justCheck) { + push (@binaries, $sourcePath); + } else { + # Change the source file name (but only if not already patched) + my $patchedSourcePath = $sourcePath; + if ($patchedSourcePath !~ m/_patched_caps/) + { + $newLine =~ s/(^.*)(\.dll|\.exe)(.*)(\.dll|\.exe)/$1_patched_caps$2$3$4/i; + $patchedSourcePath =~ s/(^.*)(\.dll|\.exe)/$1_patched_caps$2/i; + + copy($sourcePath, $patchedSourcePath) or die "$sourcePath cannot be copied for patching."; + } + push (@binaries, $patchedSourcePath); } - push (@binaries, $patchedSourcePath); } } @@ -250,11 +229,12 @@ if (@ARGV) } close (PKG); - close (NEW_PKG); - - unlink($pkgFileName); - rename($tempPkgFileName, $pkgFileName); + if (!$justCheck) { + close (NEW_PKG); + unlink($pkgFileName); + rename($tempPkgFileName, $pkgFileName); + } print ("\n"); my $baseCommandToExecute = "elftran -vid 0x0 -capability \"%s\" "; @@ -265,18 +245,18 @@ if (@ARGV) # Create the command line for setting the capabilities. my ($binaryVolume, $binaryDirs, $binaryBaseName) = File::Spec->splitpath($binaryPath); my $commandToExecute = $baseCommandToExecute; - my $executeNeeded = 0; + my $executeNeeded = ""; if (@capabilitiesSpecified) { $commandToExecute = sprintf($baseCommandToExecute, join(" ", @capabilitiesSpecified)); - $executeNeeded = 1; + $executeNeeded = true; my $capString = join(" ", @capabilitiesSpecified); - print ("Patching: Patching the the Vendor ID to 0 and the capabilities used to: \"$capString\" in \"$binaryBaseName\".\n"); + print ("$msgPrefix Patching the the Vendor ID to 0 and the capabilities used to: \"$capString\" in \"$binaryBaseName\".\n"); } else { # Test which capabilities are present and then restrict them to the allowed set. # This avoid raising the capabilities of apps that already have none. my $dllCaps; - open($dllCaps, "elftran -dump s $binaryPath |") or die ("Could not execute elftran"); + open($dllCaps, "elftran -dump s $binaryPath |") or die ("ERROR: Could not execute elftran"); my $capsFound = 0; my $originalVid; my @capabilitiesToSet; @@ -288,8 +268,8 @@ if (@ARGV) if ($binaryBaseName =~ /\.exe$/) { # Installer refuses to install protected executables in a self signed package, so abort if one is detected. # We can't simply just patch the executable SID, as any registration resources executable uses will be linked to it via SID. - print ("Patching: Executable with SID in the protected range (0x$exeSid) detected: \"$binaryBaseName\". A self-signed sis with protected executables is not supported.\n"); - exit(1); + print ("$msgPrefix Executable with SID in the protected range (0x$exeSid) detected: \"$binaryBaseName\". A self-signed sis with protected executables is not supported.\n\n"); + $checkFailed = true; } } if (/^Vendor ID: ([0-9a-fA-F]*)$/) { @@ -302,7 +282,7 @@ if (@ARGV) if ($capabilitiesToAllow =~ /$_/) { push(@capabilitiesToSet, $_); if (Location =~ /$_/i) { - print ("Patching: Warning - \"Location\" capability detected for binary: \"$binaryBaseName\". This capability is not self-signable for S60 3rd edition feature pack 1 devices, so installing this package on those devices will most likely not work.\n"); + print ("$msgPrefix \"Location\" capability detected for binary: \"$binaryBaseName\". This capability is not self-signable for S60 3rd edition feature pack 1 devices, so installing this package on those devices will most likely not work.\n\n"); } } else { push(@capabilitiesToDrop, $_); @@ -311,22 +291,32 @@ if (@ARGV) } close($dllCaps); if ($originalVid !~ "00000000") { - print ("Patching: Vendor ID (0x$originalVid) incompatible with self-signed packages, setting it to zero for \"$binaryBaseName\".\n"); - $executeNeeded = 1; + print ("$msgPrefix Non-zero vendor ID (0x$originalVid) is incompatible with self-signed packages in \"$binaryBaseName\""); + if ($justCheck) { + print (".\n\n"); + $checkFailed = true; + } else { + print (", setting it to zero.\n\n"); + $executeNeeded = true; + } } if ($#capabilitiesToDrop) { my $capsToDropStr = join("\", \"", @capabilitiesToDrop); $capsToDropStr =~ s/\", \"$//; - if ($binaryBaseName =~ /\.exe$/) { - # While libraries often have capabilities they do not themselves need just to enable them to be loaded by wider variety of processes, - # executables are more likely to need every capability they have been assigned or they won't function correctly. - print ("Patching: Executable with capabilities incompatible with self-signing detected: \"$binaryBaseName\". (Incompatible capabilities: \"$capsToDropStr\".) Reducing capabilities is only supported for libraries.\n"); - print ("Patching: Please use a proper developer certificate for signing this package.\n"); - exit(1); + if ($justCheck) { + print ("$msgPrefix The following capabilities used in \"$binaryBaseName\" are not compatible with a self-signed package: \"$capsToDropStr\".\n\n"); + $checkFailed = true; } else { - print ("Patching: The following capabilities used in \"$binaryBaseName\" are not compatible with a self-signed package and will be removed: \"$capsToDropStr\".\n"); - $executeNeeded = 1; + if ($binaryBaseName =~ /\.exe$/) { + # While libraries often have capabilities they do not themselves need just to enable them to be loaded by wider variety of processes, + # executables are more likely to need every capability they have been assigned or they won't function correctly. + print ("$msgPrefix Executable with capabilities incompatible with self-signing detected: \"$binaryBaseName\". (Incompatible capabilities: \"$capsToDropStr\".) Reducing capabilities is only supported for libraries.\n"); + $checkFailed = true; + } else { + print ("$msgPrefix The following capabilities used in \"$binaryBaseName\" are not compatible with a self-signed package and will be removed: \"$capsToDropStr\".\n"); + $executeNeeded = true; + } } } $commandToExecute = sprintf($baseCommandToExecute, join(" ", @capabilitiesToSet)); @@ -337,16 +327,37 @@ if (@ARGV) # Actually execute the elftran command to set the capabilities. print ("\n"); system ("$commandToExecute > $nullDevice"); + $somethingPatched = true; } ## Create another command line to check that the set capabilities are correct. #$commandToExecute = "elftran -dump s ".$binaryPath; } + if ($checkFailed) { + print ("\n"); + if ($justCheck) { + print ("$msgPrefix The package is not compatible with self-signing.\n"); + } else { + print ("$msgPrefix Unable to patch the package for self-singing.\n"); + } + print ("Use a proper developer certificate for signing this package.\n\n"); + exit(1); + } + + if ($justCheck) { + print ("Package is compatible with self-signing.\n"); + } else { + if ($somethingPatched) { + print ("NOTE: A patched package may not work as expected due to reduced capabilities and other modifications,\n"); + print (" so it should not be used for any kind of Symbian signing or distribution!\n"); + print (" Use a proper certificate to avoid the need to patch the package.\n"); + } else { + print ("No patching was required!\n"); + } + } print ("\n"); - print ("NOTE: A patched package may not work as expected due to reduced capabilities and other modifications,\n"); - print (" so it should not be used for any kind of Symbian signing or distribution!\n"); - print (" Use a proper certificate to avoid the need to patch the package.\n"); - print ("\n"); + } else { + Usage(); } } else diff --git a/doc/src/platforms/symbian-introduction.qdoc b/doc/src/platforms/symbian-introduction.qdoc index 7bc5303..9da94c4 100644 --- a/doc/src/platforms/symbian-introduction.qdoc +++ b/doc/src/platforms/symbian-introduction.qdoc @@ -222,6 +222,7 @@ \row \o -s \o Generates stub sis for ROM. \row \o -n \o Specifies the final sis name. \row \o -g \o Treat gcce platform as armv5. + \row \o -d \o Skip automatic patching of the package when default certificate is used. \endtable Execute the \c{createpackage.pl} script without any -- cgit v0.12 From a51a29e9f7b63fcefcdf9e9069e219726db1250e Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 25 Nov 2010 15:46:43 +0100 Subject: Fix possible artifacts under glyphs in texture glyph cache We would disregard the first glyph in each line when calculating the required height of the line in the glyph cache. If the first glyph was taller than any of the other glyphs in the same line, the glyph drawn underneath it in the cache could potentially overlap it, and you would see it as dots or lines underneath the glyph in the output. Task-number: QTBUG-14806 Reviewed-by: Jiang Jiang --- src/gui/painting/qtextureglyphcache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 2daa1f0..eab9cf6 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -143,7 +143,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const // no room on the current line, start new glyph strip m_cx = 0; m_cy += m_currentRowHeight + paddingDoubled; - m_currentRowHeight = 0; // New row + m_currentRowHeight = c.h + margin * 2; // New row } } if (m_cy + c.h > m_h) { -- cgit v0.12 From 72fae4bd1bdf5a56632f8ca638f7d1165f6fe1ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 25 Nov 2010 11:05:04 +0100 Subject: Fix QFileDialog autotest Test expects to see a directory in SRCDIR. Copying the resources directory from QAbstractFileEngine autotest shouldn't impact the git repository and serves our purposes well :-) Reviewed-by: Olivier Goffart --- tests/auto/qfiledialog/resources/file.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/auto/qfiledialog/resources/file.txt diff --git a/tests/auto/qfiledialog/resources/file.txt b/tests/auto/qfiledialog/resources/file.txt new file mode 100644 index 0000000..8a03e0e --- /dev/null +++ b/tests/auto/qfiledialog/resources/file.txt @@ -0,0 +1 @@ +This is a simple text file. -- cgit v0.12 From 83c91bb021e9adf86870c498641e329ab7f786c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 25 Nov 2010 11:23:10 +0100 Subject: Fix QFile::link unit test Absolute path for the link target can contain "../" elements and so needs to be cleaned. Really depends on the definition for SRCDIR. Reviewed-by: Prasanth Ullattil --- tests/auto/qfile/tst_qfile.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index dbd4302..ba9a8bf 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -1296,22 +1296,28 @@ void tst_QFile::link() QSKIP("Symbian does not support links", SkipAll); #endif QFile::remove("myLink.lnk"); + QFileInfo info1(SRCDIR "tst_qfile.cpp"); + QString referenceTarget = QDir::cleanPath(info1.absoluteFilePath()); + QVERIFY(QFile::link(SRCDIR "tst_qfile.cpp", "myLink.lnk")); + QFileInfo info2("myLink.lnk"); QVERIFY(info2.isSymLink()); - QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath()); + QCOMPARE(info2.symLinkTarget(), referenceTarget); QFile link("myLink.lnk"); QVERIFY(link.open(QIODevice::ReadOnly)); - QCOMPARE(link.symLinkTarget(), info1.absoluteFilePath()); + QCOMPARE(link.symLinkTarget(), referenceTarget); link.close(); - QCOMPARE(QFile::symLinkTarget("myLink.lnk"), info1.absoluteFilePath()); + + QCOMPARE(QFile::symLinkTarget("myLink.lnk"), referenceTarget); #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) QString wd = getWorkingDirectoryForLink(info2.absoluteFilePath()); - QCOMPARE(QDir::fromNativeSeparators(wd), info1.absolutePath()); + QCOMPARE(QDir::fromNativeSeparators(wd), referenceTarget); #endif + QVERIFY(QFile::remove(info2.absoluteFilePath())); } -- cgit v0.12 From c7f1fdbe9d1c7387b3a72624b428a1d0f19d5b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 25 Nov 2010 17:50:09 +0100 Subject: Flagging some more tests as parallelizable These tests have no GUI nor do they depend on network, so let's see what breaks if they're parallelized :-) Reviewed-by: Olivier Goffart --- tests/auto/qdir/qdir.pro | 1 + tests/auto/qfile/largefile/largefile.pro | 2 ++ tests/auto/qfile/qfile.pro | 1 + tests/auto/qfileinfo/qfileinfo.pro | 2 ++ tests/auto/qfilesystementry/qfilesystementry.pro | 1 + tests/auto/qfilesystemwatcher/qfilesystemwatcher.pro | 2 ++ tests/auto/qsettings/qsettings.pro | 2 ++ tests/auto/qtemporaryfile/qtemporaryfile.pro | 2 ++ 8 files changed, 13 insertions(+) diff --git a/tests/auto/qdir/qdir.pro b/tests/auto/qdir/qdir.pro index 33aee4b..55fd031 100644 --- a/tests/auto/qdir/qdir.pro +++ b/tests/auto/qdir/qdir.pro @@ -21,3 +21,4 @@ wince* { DEFINES += SRCDIR=\\\"$$PWD/\\\" } +CONFIG += parallel_test diff --git a/tests/auto/qfile/largefile/largefile.pro b/tests/auto/qfile/largefile/largefile.pro index d67cb46..6407cb6 100644 --- a/tests/auto/qfile/largefile/largefile.pro +++ b/tests/auto/qfile/largefile/largefile.pro @@ -4,3 +4,5 @@ QT = core SOURCES += tst_largefile.cpp wince*: SOURCES += $$QT_SOURCE_TREE/src/corelib/kernel/qfunctions_wince.cpp + +CONFIG += parallel_test diff --git a/tests/auto/qfile/qfile.pro b/tests/auto/qfile/qfile.pro index 727f660..f41d327 100644 --- a/tests/auto/qfile/qfile.pro +++ b/tests/auto/qfile/qfile.pro @@ -7,3 +7,4 @@ wince*|symbian:{ !symbian:SUBDIRS += largefile +CONFIG += parallel_test diff --git a/tests/auto/qfileinfo/qfileinfo.pro b/tests/auto/qfileinfo/qfileinfo.pro index f3622da..b35b1e0 100644 --- a/tests/auto/qfileinfo/qfileinfo.pro +++ b/tests/auto/qfileinfo/qfileinfo.pro @@ -31,3 +31,5 @@ wince* { } contains(QT_CONFIG, qt3support): QT += qt3support + +CONFIG += parallel_test diff --git a/tests/auto/qfilesystementry/qfilesystementry.pro b/tests/auto/qfilesystementry/qfilesystementry.pro index 9f75388..b9b43e6 100644 --- a/tests/auto/qfilesystementry/qfilesystementry.pro +++ b/tests/auto/qfilesystementry/qfilesystementry.pro @@ -5,3 +5,4 @@ SOURCES += tst_qfilesystementry.cpp \ HEADERS += ../../../src/corelib/io/qfilesystementry_p.h QT = core +CONFIG += parallel_test diff --git a/tests/auto/qfilesystemwatcher/qfilesystemwatcher.pro b/tests/auto/qfilesystemwatcher/qfilesystemwatcher.pro index 8b8616a..75e85a0 100644 --- a/tests/auto/qfilesystemwatcher/qfilesystemwatcher.pro +++ b/tests/auto/qfilesystemwatcher/qfilesystemwatcher.pro @@ -1,3 +1,5 @@ load(qttest_p4) SOURCES += tst_qfilesystemwatcher.cpp QT = core + +CONFIG += parallel_test diff --git a/tests/auto/qsettings/qsettings.pro b/tests/auto/qsettings/qsettings.pro index 19513b3..fe104df 100644 --- a/tests/auto/qsettings/qsettings.pro +++ b/tests/auto/qsettings/qsettings.pro @@ -6,3 +6,5 @@ contains(QT_CONFIG, qt3support):QT += qt3support CONFIG -= debug CONFIG += release win32-msvc*:LIBS += advapi32.lib + +CONFIG += parallel_test diff --git a/tests/auto/qtemporaryfile/qtemporaryfile.pro b/tests/auto/qtemporaryfile/qtemporaryfile.pro index 543c143..64a043b 100644 --- a/tests/auto/qtemporaryfile/qtemporaryfile.pro +++ b/tests/auto/qtemporaryfile/qtemporaryfile.pro @@ -10,3 +10,5 @@ symbian { }else { DEFINES += SRCDIR=\\\"$$PWD/\\\" } + +CONFIG += parallel_test -- cgit v0.12 From 6dc29b3a2f93936aa5a3eecb336631485c5195b8 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Fri, 26 Nov 2010 11:21:23 +1000 Subject: More detail when the process crashes in tst_qmlvisual. --- tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp index 18fbfca..7fee24f 100644 --- a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp +++ b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp @@ -146,10 +146,11 @@ void tst_qmlvisual::visual() #endif QProcess p; + p.setProcessChannelMode(QProcess::MergedChannels); p.start(qmlruntime, arguments); - QVERIFY(p.waitForFinished()); + QVERIFY2(p.waitForFinished(), p.readAllStandardOutput().data()); if (p.exitCode() != 0) - qDebug() << p.readAllStandardError(); + qDebug() << p.readAllStandardOutput(); QCOMPARE(p.exitStatus(), QProcess::NormalExit); QCOMPARE(p.exitCode(), 0); } -- cgit v0.12 From 9ccaecf7825a782bfd29ff6c4118d933cc614726 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Fri, 26 Nov 2010 11:41:53 +1000 Subject: Slightly improved tst_qmlvisual output --- tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp index 7fee24f..ef0d4dc 100644 --- a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp +++ b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp @@ -146,11 +146,12 @@ void tst_qmlvisual::visual() #endif QProcess p; - p.setProcessChannelMode(QProcess::MergedChannels); p.start(qmlruntime, arguments); - QVERIFY2(p.waitForFinished(), p.readAllStandardOutput().data()); + bool finished = p.waitForFinished(); + QByteArray output = p.readAllStandardOutput() + p.readAllStandardError(); + QVERIFY2(finished, output.data()); if (p.exitCode() != 0) - qDebug() << p.readAllStandardOutput(); + qDebug() << output; QCOMPARE(p.exitStatus(), QProcess::NormalExit); QCOMPARE(p.exitCode(), 0); } -- cgit v0.12 From 6ebdd5eab816f357dfc3addcf2f1e8ef0ad4a9e4 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 26 Nov 2010 12:45:44 +1000 Subject: Fix type punning warnings from gcc Also clean up some code uglyness in the process --- src/declarative/qml/qdeclarativedata_p.h | 13 +++----- src/declarative/qml/qdeclarativeengine.cpp | 53 +++++++++++++++++------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/declarative/qml/qdeclarativedata_p.h b/src/declarative/qml/qdeclarativedata_p.h index def4188..4767169 100644 --- a/src/declarative/qml/qdeclarativedata_p.h +++ b/src/declarative/qml/qdeclarativedata_p.h @@ -65,6 +65,7 @@ class QDeclarativeContext; class QDeclarativePropertyCache; class QDeclarativeContextData; class QDeclarativeNotifier; +class QDeclarativeDataExtended; // 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. @@ -150,17 +151,13 @@ public: } } + bool hasExtendedData() const { return extendedData != 0; } QDeclarativeNotifier *objectNameNotifier() const; QHash *attachedProperties() const; - struct ExtendedData { - ExtendedData(); - ~ExtendedData(); - - QHash attachedProperties; - void *objectNameNotifier; - }; - mutable ExtendedData *extendedData; +private: + // For objectNameNotifier and attachedProperties + mutable QDeclarativeDataExtended *extendedData; }; template diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 808ba68..1160ed8 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -957,7 +957,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->extendedData?data->attachedProperties()->value(id):0; + QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0; if (rv || !create) return rv; @@ -985,6 +985,35 @@ QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object, return qmlAttachedPropertiesObjectById(*idCache, object, create); } +class QDeclarativeDataExtended { +public: + QDeclarativeDataExtended(); + ~QDeclarativeDataExtended(); + + QHash attachedProperties; + QDeclarativeNotifier objectNameNotifier; +}; + +QDeclarativeDataExtended::QDeclarativeDataExtended() +{ +} + +QDeclarativeDataExtended::~QDeclarativeDataExtended() +{ +} + +QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const +{ + if (!extendedData) extendedData = new QDeclarativeDataExtended; + return &extendedData->objectNameNotifier; +} + +QHash *QDeclarativeData::attachedProperties() const +{ + if (!extendedData) extendedData = new QDeclarativeDataExtended; + return &extendedData->attachedProperties; +} + void QDeclarativeData::destroyed(QObject *object) { if (deferredComponent) @@ -1075,28 +1104,6 @@ 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 *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. -- cgit v0.12 From fa8d0838dfc40ed269b30b9872cfdc2d2b16b64a Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Fri, 26 Nov 2010 13:39:44 +1000 Subject: Repaint when text color changes Task-number: QTBUG-15623 Reviewed-by: Yann Bodson --- src/declarative/graphicsitems/qdeclarativetext.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp index 82c444e..303b21c 100644 --- a/src/declarative/graphicsitems/qdeclarativetext.cpp +++ b/src/declarative/graphicsitems/qdeclarativetext.cpp @@ -436,12 +436,13 @@ void QDeclarativeTextPrivate::invalidateImageCache() { Q_Q(QDeclarativeText); - if (imageCacheDirty) - return; - - imageCacheDirty = true; - imageCache = QPixmap(); + if(cacheAllTextAsImage || style != QDeclarativeText::Normal){//If actually using the image cache + if (imageCacheDirty) + return; + imageCacheDirty = true; + imageCache = QPixmap(); + } if (q->isComponentComplete()) q->update(); } -- cgit v0.12 From 6578492dd0badc03d2f1dcf094e426559f67308b Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Fri, 26 Nov 2010 15:40:02 +1000 Subject: Add missing newline to configure.exe output. Reviewed-by: Trust Me --- tools/configure/configureapp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 9443fee..f4fd7c6 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3417,7 +3417,7 @@ void Configure::displayConfig() QString webkit = dictionary[ "WEBKIT" ]; if (webkit == "debug") webkit = "yes (debug)"; - cout << "WebKit support.............." << webkit; + cout << "WebKit support.............." << webkit << endl; } cout << "Declarative support........." << dictionary[ "DECLARATIVE" ] << endl; cout << "Declarative debugging......." << dictionary[ "DECLARATIVE_DEBUG" ] << endl; -- cgit v0.12 From 0b728313dbca3ca6ea54bb8f533dbe70028f96e0 Mon Sep 17 00:00:00 2001 From: Karim Pinter Date: Fri, 26 Nov 2010 10:38:45 +0200 Subject: Adding warning to QMenu documentation If the QMenu is made visible using show() it causes problems because the scrolling and layout is not set properly. The warning suggests to use exec() or popup() instead. Task-number: QTBUG-12119 --- src/gui/widgets/qmenu.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 4bea6de..551e19e 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1319,6 +1319,9 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) Conversely, actions can be added to widgets with the addAction(), addActions() and insertAction() functions. + + \warning To make QMenu visible on the screen, exec() or popup() should be + used instead of show(). \section1 QMenu on Qt for Windows CE -- cgit v0.12 From 320c682c3a76c3a59ebe102ba5aad3cd1eb4a13e Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Fri, 26 Nov 2010 10:19:37 +0100 Subject: Revert "Fix a missing error-signal when a server is shut down while downloading" This reverts commit cbf7a7782f465846455a5fd5df339ebde31a5521. This commit caused autotest regressions in tst_qdeclarativeloader and tst_qdeclarativetext; reverting it for now until this has been resolved. --- src/network/access/qhttpnetworkconnectionchannel.cpp | 18 +----------------- src/network/access/qhttpnetworkconnectionchannel_p.h | 1 - 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index a47e619..c8caad4 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -66,7 +66,6 @@ QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel() , bytesTotal(0) , resendCurrent(false) , lastStatus(0) - , unhandledError(QNetworkReply::NoError) , pendingEncrypt(false) , reconnectAttempts(2) , authMethod(QAuthenticatorPrivate::None) @@ -643,21 +642,7 @@ void QHttpNetworkConnectionChannel::allDone() // slot connected to it. The socket will not fire readyRead signal, if we are already // in the slot connected to readyRead if (emitFinished) - { - // Check whether _q_error was invoked previously and if it left a socket - // error unhandled. - if(unhandledError != QNetworkReply::NoError) { - QString errorString = connection->d_func()->errorDetail(unhandledError, socket, socket->errorString()); - qRegisterMetaType("QNetworkReply::NetworkError"); - QMetaObject::invokeMethod(reply, "finishedWithError", - Qt::QueuedConnection, - Q_ARG(QNetworkReply::NetworkError, unhandledError), - Q_ARG(QString, errorString)); - unhandledError = QNetworkReply::NoError; // Reset the value - } else { - QMetaObject::invokeMethod(reply, "finished", Qt::QueuedConnection); - } - } + QMetaObject::invokeMethod(reply, "finished", Qt::QueuedConnection); // reset the reconnection attempts after we receive a complete reply. // in case of failures, each channel will attempt two reconnects before emitting error. reconnectAttempts = 2; @@ -979,7 +964,6 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket errorCode = QNetworkReply::RemoteHostClosedError; } } else { - unhandledError = QNetworkReply::RemoteHostClosedError; return; } break; diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index e1d42fb..fd18042 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -105,7 +105,6 @@ public: qint64 bytesTotal; bool resendCurrent; int lastStatus; // last status received on this channel - QNetworkReply::NetworkError unhandledError; // Stored code of an unhandled error. bool pendingEncrypt; // for https (send after encrypted) int reconnectAttempts; // maximum 2 reconnection attempts QAuthenticatorPrivate::Method authMethod; -- cgit v0.12 From 1e7b4e396ec3bacc1a769208b990c5e0450f0d3a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 26 Nov 2010 10:41:38 +0100 Subject: Declarative: Fix compiler warnings (Linux/g++) Reviewed-by: Kai Koehne --- src/declarative/debugger/qdeclarativedebugservice.cpp | 8 +++++--- src/declarative/qml/qdeclarativeengine.cpp | 3 ++- src/declarative/qml/qdeclarativepropertycache.cpp | 1 + src/declarative/util/qdeclarativepixmapcache.cpp | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/declarative/debugger/qdeclarativedebugservice.cpp b/src/declarative/debugger/qdeclarativedebugservice.cpp index 8c86ae8..41a6962 100644 --- a/src/declarative/debugger/qdeclarativedebugservice.cpp +++ b/src/declarative/debugger/qdeclarativedebugservice.cpp @@ -226,9 +226,11 @@ QDeclarativeDebugServer *QDeclarativeDebugServer::instance() server->waitForConnection(); } } else { - qWarning(QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". " - "Format is -qmljsdebugger=port:[,block]").arg( - appD->qmljsDebugArgumentsString()).toAscii().constData()); + const QString message = + QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". " + "Format is -qmljsdebugger=port:[,block]"). + arg(appD->qmljsDebugArgumentsString()); + qWarning("%s", qPrintable(message)); } } #endif diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 808ba68..19dfcea 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -2225,8 +2225,9 @@ bool QDeclarative_isFileCaseCorrect(const QString &fileName) if (a != c) return false; } +#else + Q_UNUSED(fileName) #endif - return true; } diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index 0adcdbd..af3d53f 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -321,6 +321,7 @@ void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaOb Q_ASSERT(engine); Q_ASSERT(metaObject); QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); + Q_UNUSED(enginePriv) clear(); diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp index a07b1bb..380d9bc 100644 --- a/src/declarative/util/qdeclarativepixmapcache.cpp +++ b/src/declarative/util/qdeclarativepixmapcache.cpp @@ -684,7 +684,7 @@ void QDeclarativePixmapStore::timerEvent(QTimerEvent *) } QDeclarativePixmapReply::QDeclarativePixmapReply(QDeclarativePixmapData *d) -: data(d), reader(0), loading(false), redirectCount(0), requestSize(d->requestSize) +: data(d), reader(0), requestSize(d->requestSize), loading(false), redirectCount(0) { if (finishedIndex == -1) { finishedIndex = QDeclarativePixmapReply::staticMetaObject.indexOfSignal("finished()"); -- cgit v0.12 From 2d7464febd762203a9bbfc6e202913eb93253f98 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 26 Nov 2010 10:45:17 +0100 Subject: Fix whitespace in previous 1e7b4e396ec3bacc1a769208b990c5e0450f0d3a --- src/declarative/debugger/qdeclarativedebugservice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/debugger/qdeclarativedebugservice.cpp b/src/declarative/debugger/qdeclarativedebugservice.cpp index 41a6962..849df73 100644 --- a/src/declarative/debugger/qdeclarativedebugservice.cpp +++ b/src/declarative/debugger/qdeclarativedebugservice.cpp @@ -226,7 +226,7 @@ QDeclarativeDebugServer *QDeclarativeDebugServer::instance() server->waitForConnection(); } } else { - const QString message = + const QString message = QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". " "Format is -qmljsdebugger=port:[,block]"). arg(appD->qmljsDebugArgumentsString()); -- cgit v0.12 From 85f42777111060037476895ed08ded513d44a048 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 22 Oct 2010 14:13:56 +0200 Subject: Doc: fix typo Reviewed-by: mauricek --- src/gui/itemviews/qabstractitemview.cpp | 4 ++-- src/gui/itemviews/qstandarditemmodel.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index b464330..9127898 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -823,7 +823,7 @@ QVariant QAbstractItemView::inputMethodQuery(Qt::InputMethodQuery query) const deleted. QAbstractItemView does not take ownership of \a delegate. \note If a delegate has been assigned to both a row and a column, the row - delegate (i.e., this delegate) will take presedence and manage the + delegate (i.e., this delegate) will take precedence and manage the intersecting cell index. \warning You should not share the same instance of a delegate between views. @@ -881,7 +881,7 @@ QAbstractItemDelegate *QAbstractItemView::itemDelegateForRow(int row) const deleted. QAbstractItemView does not take ownership of \a delegate. \note If a delegate has been assigned to both a row and a column, the row - delegate will take presedence and manage the intersecting cell index. + delegate will take precedence and manage the intersecting cell index. \warning You should not share the same instance of a delegate between views. Doing so can cause incorrect or unintuitive editing behavior since each diff --git a/src/gui/itemviews/qstandarditemmodel.cpp b/src/gui/itemviews/qstandarditemmodel.cpp index 9d52c78..4f1d77b 100644 --- a/src/gui/itemviews/qstandarditemmodel.cpp +++ b/src/gui/itemviews/qstandarditemmodel.cpp @@ -1130,7 +1130,7 @@ Qt::ItemFlags QStandardItem::flags() const meaning that the user can interact with the item; if \a enabled is false, the user cannot interact with the item. - This flag takes presedence over the other item flags; e.g. if an item is not + This flag takes precedence over the other item flags; e.g. if an item is not enabled, it cannot be selected by the user, even if the Qt::ItemIsSelectable flag has been set. -- cgit v0.12 From 0bf8f70f85a24ab2864775bdd38f5ced43a7d4de Mon Sep 17 00:00:00 2001 From: Jonathan Liu Date: Fri, 26 Nov 2010 10:20:56 +0100 Subject: QLocalSocket/Win: do not emit error() when no error actually occurred This fixes a regression in 4d0c4b9f09b35d707d437611519d0024f6f87a8c. Previously the error string was set if the error is not ERROR_PIPE_NOT_CONNECTED but the commit changed this behaviour to set the error string if it is ERROR_PIPE_NOT_CONNECTED. Task-number: QTBUG-13646 Merge-request: 941 Reviewed-by: Joerg Bornemann --- src/network/socket/qlocalsocket_win.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 4907f2c..6c3b769 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -322,9 +322,9 @@ bool QLocalSocketPrivate::completeAsyncRead() // buffer. We will read the remaining data in the next call. break; case ERROR_PIPE_NOT_CONNECTED: - setErrorString(QLatin1String("QLocalSocketPrivate::completeAsyncRead")); - // fall through + return false; default: + setErrorString(QLatin1String("QLocalSocketPrivate::completeAsyncRead")); return false; } } -- cgit v0.12 From 34d365bceae861c2322d09149f78476723dcb0c1 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 26 Nov 2010 12:59:57 +0200 Subject: Remove unused variable Variable currentClause is no longer used for anything, so removed its declaration. Reviewed-by: TrustMe --- qmake/generators/symbian/symmake_sbsv2.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp index c4b51f2..c219f1d 100644 --- a/qmake/generators/symbian/symmake_sbsv2.cpp +++ b/qmake/generators/symbian/symmake_sbsv2.cpp @@ -377,7 +377,6 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo t << qmakeCmd << endl; t << endl; - QString currentClause; QString locFileDep = generateLocFileTarget(t, qmakeCmd); t << "debug: " << locFileDep << BLD_INF_FILENAME << endl; -- cgit v0.12 From a061f032bc36f03d31ba39d2565857d1a14d9112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 26 Nov 2010 12:45:08 +0100 Subject: Fixed OpenGL state getting out of sync. Forward begin / endNativePainting from the emulation paint engine. Task-number: QTBUG-15498 Reviewed-by: Gunnar Sletta --- src/gui/painting/qemulationpaintengine.cpp | 9 +++++++++ src/gui/painting/qemulationpaintengine_p.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/src/gui/painting/qemulationpaintengine.cpp b/src/gui/painting/qemulationpaintengine.cpp index 0510b10..714d5de 100644 --- a/src/gui/painting/qemulationpaintengine.cpp +++ b/src/gui/painting/qemulationpaintengine.cpp @@ -268,6 +268,15 @@ void QEmulationPaintEngine::setState(QPainterState *s) real_engine->setState(s); } +void QEmulationPaintEngine::beginNativePainting() +{ + real_engine->beginNativePainting(); +} + +void QEmulationPaintEngine::endNativePainting() +{ + real_engine->endNativePainting(); +} void QEmulationPaintEngine::fillBGRect(const QRectF &r) { diff --git a/src/gui/painting/qemulationpaintengine_p.h b/src/gui/painting/qemulationpaintengine_p.h index 5835f10..e283645 100644 --- a/src/gui/painting/qemulationpaintengine_p.h +++ b/src/gui/painting/qemulationpaintengine_p.h @@ -93,6 +93,9 @@ public: virtual void setState(QPainterState *s); + virtual void beginNativePainting(); + virtual void endNativePainting(); + virtual uint flags() const {return QPaintEngineEx::IsEmulationEngine | QPaintEngineEx::DoNotEmulate;} inline QPainterState *state() { return (QPainterState *)QPaintEngine::state; } -- cgit v0.12 From fe17f36823d0b2374e3ec7badb4c2ed2c938dba8 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 26 Nov 2010 15:05:09 +0200 Subject: Fix minor memory leak QProcessPrivate::startDetached() in qprocess_symbian.cpp was leaking RProcess object. Reviewed-by: Janne Koskinen --- src/corelib/io/qprocess_symbian.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/io/qprocess_symbian.cpp b/src/corelib/io/qprocess_symbian.cpp index 003e781..5b283a5 100644 --- a/src/corelib/io/qprocess_symbian.cpp +++ b/src/corelib/io/qprocess_symbian.cpp @@ -1050,6 +1050,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a newProc->Resume(); newProc->Close(); + delete newProc; return true; } -- cgit v0.12 From 896c51e4d41a7fee06a1601f1b25746f9f98be88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 26 Nov 2010 09:17:35 +0100 Subject: Move the Lighthouse specfic api into qpa_qpa.cpp and ifdef the functions in qgl.h --- src/opengl/qgl.cpp | 12 ------------ src/opengl/qgl.h | 2 ++ src/opengl/qgl_qpa.cpp | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 5eb4c16..111a3e4 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -3160,18 +3160,6 @@ void QGLContext::setDevice(QPaintDevice *pDev) } } -QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContext) -{ - if (!platformContext) - return 0; - if (platformContext->qGLContextHandle()) { - return reinterpret_cast(platformContext->qGLContextHandle()); - } - QGLContext *glContext = new QGLContext(platformContext); - glContext->create(); - return glContext; -} - /*! \fn bool QGLContext::isValid() const diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index f5e0bd7..ff135fa 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -383,7 +383,9 @@ public: static const QGLContext* currentContext(); +#ifdef Q_WS_QPA static QGLContext *fromPlatformGLContext(QPlatformGLContext *platformContext); +#endif protected: virtual bool chooseContext(const QGLContext* shareContext = 0); diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index e997704..d45f246 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -360,4 +360,24 @@ void QGLWidget::setColormap(const QGLColormap & c) Q_UNUSED(c); } + +QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContext) +{ + if (!platformContext) + return 0; + if (platformContext->qGLContextHandle()) { + return reinterpret_cast(platformContext->qGLContextHandle()); + } + QGLContext *glContext = new QGLContext(platformContext); + //Dont call create on context. This can cause the platformFormat to be set on the widget, which + //will cause the platformWindow to be recreated. + glContext->d_func()->platformContext->setQGLContextHandle(glContext,qDeleteQGLContext); + QGLFormat format = QGLFormat::fromPlatformWindowFormat(platformContext->platformWindowFormat()); + glContext->d_func()->glFormat = format; + glContext->d_func()->valid = true; + + return glContext; +} + + QT_END_NAMESPACE -- cgit v0.12 From 71abe300263d9f6bcd6e061e889a58111c48f92a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 26 Nov 2010 15:59:30 +0100 Subject: Make QtOpenGL use shared contextexts on Lighthouse --- src/gui/kernel/qplatformglcontext_qpa.cpp | 6 ++++- src/gui/kernel/qwidget_qpa.cpp | 24 ++++++++++---------- src/opengl/qgl.cpp | 24 +++++++++++--------- src/opengl/qgl_qpa.cpp | 33 +++++++++++++++++++++------- src/opengl/qglpixmapfilter.cpp | 2 +- src/opengl/qpixmapdata_gl.cpp | 30 ++++++++++++------------- src/opengl/qwindowsurface_gl.cpp | 32 +++++++++++++++++++++++++-- src/opengl/qwindowsurface_gl_p.h | 4 ++++ src/plugins/platforms/eglfs/qeglfsscreen.cpp | 4 +++- 9 files changed, 110 insertions(+), 49 deletions(-) diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp index 5d2faf1..14bd718 100644 --- a/src/gui/kernel/qplatformglcontext_qpa.cpp +++ b/src/gui/kernel/qplatformglcontext_qpa.cpp @@ -180,7 +180,11 @@ void QPlatformGLContext::setQGLContextHandle(void *handle,void (*qGLContextDelet void QPlatformGLContext::deleteQGLContext() { Q_D(QPlatformGLContext); - d->qGLContextDeleteFunction(d->qGLContextHandle); + if (d->qGLContextDeleteFunction && d->qGLContextHandle) { + d->qGLContextDeleteFunction(d->qGLContextHandle); + d->qGLContextDeleteFunction = 0; + d->qGLContextHandle = 0; + } } /*! diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp index aa6b3f8..1f2a764 100644 --- a/src/gui/kernel/qwidget_qpa.cpp +++ b/src/gui/kernel/qwidget_qpa.cpp @@ -98,10 +98,12 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } Q_ASSERT(platformWindow); - if (!surface && platformWindow && q->platformWindowFormat().hasWindowSurface()) { - surface = QApplicationPrivate::platformIntegration()->createWindowSurface(q,platformWindow->winId()); - } else { - q->setAttribute(Qt::WA_PaintOnScreen,true); + if (!surface ) { + if (platformWindow && q->platformWindowFormat().hasWindowSurface()) { + surface = QApplicationPrivate::platformIntegration()->createWindowSurface(q,platformWindow->winId()); + } else { + q->setAttribute(Qt::WA_PaintOnScreen,true); + } } data.window_flags = q->platformWindow()->setWindowFlags(data.window_flags); @@ -787,13 +789,13 @@ void QWidgetPrivate::createTLSysExtra() void QWidgetPrivate::deleteTLSysExtra() { if (extra && extra->topextra) { - if (extra->topextra->platformWindowFormat.windowApi() == QPlatformWindowFormat::OpenGL) { - //the toplevel might have a context with a "qglcontext assosiated with it. We need to - //delete the qglcontext before we delete the qplatformglcontext. - if (extra->topextra->platformWindow) { - if (QPlatformGLContext *context = extra->topextra->platformWindow->glContext()) { - context->deleteQGLContext(); - } + //the toplevel might have a context with a "qglcontext assosiated with it. We need to + //delete the qglcontext before we delete the qplatformglcontext. + //One unfortunate thing about this is that we potentially create a glContext just to + //delete it straight afterwards. + if (extra->topextra->platformWindow) { + if (QPlatformGLContext *context = extra->topextra->platformWindow->glContext()) { + context->deleteQGLContext(); } } delete extra->topextra->platformWindow; diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 111a3e4..dc7a333 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2095,14 +2095,6 @@ QGLContext::QGLContext(const QGLFormat &format) d->init(0, format); } -QGLContext::QGLContext(QPlatformGLContext *platformContext) - : d_ptr(new QGLContextPrivate(this)) -{ - Q_D(QGLContext); - d->init(0,QGLFormat::fromPlatformWindowFormat(platformContext->platformWindowFormat())); - d->platformContext = platformContext; -} - /*! Destroys the OpenGL context and frees its resources. */ @@ -3788,7 +3780,13 @@ QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFl setAttribute(Qt::WA_NoSystemBackground); setAutoFillBackground(true); // for compatibility #ifdef Q_WS_QPA - setPlatformWindowFormat(QGLFormat::toPlatformWindowFormat(QGLFormat::defaultFormat())); + QPlatformWindowFormat platformFormat = QGLFormat::toPlatformWindowFormat(QGLFormat::defaultFormat()); + platformFormat.setUseDefaultSharedContext(false); + if (shareWidget && shareWidget->d_func()->glcx) { + QPlatformGLContext *sharedPlatformContext = shareWidget->d_func()->glcx->d_func()->platformContext; + platformFormat.setSharedContext(sharedPlatformContext); + } + setPlatformWindowFormat(platformFormat); winId(); // create window; QGLContext *glContext = 0; if (platformWindow()) @@ -3839,7 +3837,13 @@ QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent, const QGLWidget* setAttribute(Qt::WA_NoSystemBackground); setAutoFillBackground(true); // for compatibility #ifdef Q_WS_QPA - setPlatformWindowFormat(QGLFormat::toPlatformWindowFormat(QGLFormat::defaultFormat())); + QPlatformWindowFormat platformFormat = QGLFormat::toPlatformWindowFormat(format); + platformFormat.setUseDefaultSharedContext(false); + if (shareWidget && shareWidget->d_func()->glcx) { + QPlatformGLContext *sharedPlatformContext = shareWidget->d_func()->glcx->d_func()->platformContext; + platformFormat.setSharedContext(sharedPlatformContext); + } + setPlatformWindowFormat(platformFormat); winId(); // create window; QGLContext *glContext = 0; if (platformWindow()) diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index d45f246..415e915 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -129,11 +129,7 @@ void qDeleteQGLContext(void *handle) bool QGLContext::chooseContext(const QGLContext* shareContext) { Q_D(QGLContext); - if (d->platformContext && !d->platformContext->qGLContextHandle()) { - d->platformContext->setQGLContextHandle(this,qDeleteQGLContext); - d->glFormat = QGLFormat::fromPlatformWindowFormat(d->platformContext->platformWindowFormat()); - d->valid = true; - }else if(!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) { + if(!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) { d->valid = false; }else { QWidget *widget = static_cast(d->paintDevice); @@ -157,6 +153,18 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) } } + if (d->valid) { + QPlatformGLContext *sharedPlatformGLContext = d->platformContext->platformWindowFormat().sharedGLContext(); + if (sharedPlatformGLContext) { + QGLContext *actualSharedContext = QGLContext::fromPlatformGLContext(sharedPlatformGLContext); + if (actualSharedContext == shareContext) { + d->sharing = true;//Will add combination in QGLContext::create + }else { + QGLContextGroup::addShare(this,actualSharedContext); + } + } + } + return d->valid; } @@ -173,13 +181,15 @@ void QGLContext::reset() d->transpColor = QColor(); d->initDone = false; QGLContextGroup::removeShare(this); + if (d->platformContext) { + d->platformContext->setQGLContextHandle(0,0); + } } void QGLContext::makeCurrent() { Q_D(QGLContext); d->platformContext->makeCurrent(); - QGLContextPrivate::setCurrentContext(this); if (!d->workaroundsCached) { d->workaroundsCached = true; @@ -195,7 +205,6 @@ void QGLContext::doneCurrent() { Q_D(QGLContext); d->platformContext->doneCurrent(); - QGLContextPrivate::setCurrentContext(0); } void QGLContext::swapBuffers() const @@ -279,6 +288,8 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) d->widget->setGeometry(0,0,3,3); QPlatformWindowFormat format = d->widget->platformWindowFormat(); format.setWindowApi(QPlatformWindowFormat::OpenGL); + format.setWindowSurface(false); + d->widget->setPlatformWindowFormat(format); d->widget->winId(); d->widget->platformWindow()->glContext()->makeCurrent(); @@ -360,6 +371,13 @@ void QGLWidget::setColormap(const QGLColormap & c) Q_UNUSED(c); } +QGLContext::QGLContext(QPlatformGLContext *platformContext) + : d_ptr(new QGLContextPrivate(this)) +{ + Q_D(QGLContext); + d->init(0,QGLFormat::fromPlatformWindowFormat(platformContext->platformWindowFormat())); + d->platformContext = platformContext; +} QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContext) { @@ -379,5 +397,4 @@ QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContex return glContext; } - QT_END_NAMESPACE diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index 73d698c..6c20aae 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -125,7 +125,7 @@ protected: bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const; }; -extern QGLWidget *qt_gl_share_widget(); +extern const QGLContext *qt_gl_share_context(); QPixmapFilter *QGL2PaintEngineEx::pixmapFilter(int type, const QPixmapFilter *prototype) { diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index cd7f0c2..1cf5bd7 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE -extern QGLWidget* qt_gl_share_widget(); +extern const QGLContext* qt_gl_share_context(); /*! \class QGLFramebufferObjectPool @@ -261,14 +261,14 @@ QGLPixmapData::QGLPixmapData(PixelType type) QGLPixmapData::~QGLPixmapData() { - QGLWidget *shareWidget = qt_gl_share_widget(); - if (!shareWidget) + const QGLContext *shareContext = qt_gl_share_context(); + if (!shareContext) return; delete m_engine; if (m_texture.id) { - QGLShareContextScope ctx(shareWidget->context()); + QGLShareContextScope ctx(shareContext); glDeleteTextures(1, &m_texture.id); } } @@ -288,7 +288,7 @@ bool QGLPixmapData::isValidContext(const QGLContext *ctx) const if (ctx == m_ctx) return true; - const QGLContext *share_ctx = qt_gl_share_widget()->context(); + const QGLContext *share_ctx = qt_gl_share_context(); return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx); } @@ -308,7 +308,7 @@ void QGLPixmapData::resize(int width, int height) d = pixelType() == QPixmapData::PixmapType ? 32 : 1; if (m_texture.id) { - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QGLShareContextScope ctx(qt_gl_share_context()); glDeleteTextures(1, &m_texture.id); m_texture.id = 0; } @@ -325,7 +325,7 @@ void QGLPixmapData::ensureCreated() const m_dirty = false; - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QGLShareContextScope ctx(qt_gl_share_context()); m_ctx = ctx; const GLenum internal_format = m_hasAlpha ? GL_RGBA : GL_RGB; @@ -399,7 +399,7 @@ void QGLPixmapData::fromImage(const QImage &image, d = m_source.depth(); if (m_texture.id) { - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QGLShareContextScope ctx(qt_gl_share_context()); glDeleteTextures(1, &m_texture.id); m_texture.id = 0; } @@ -420,7 +420,7 @@ bool QGLPixmapData::fromFile(const QString &filename, const char *format, resize(0, 0); data = file.readAll(); file.close(); - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QGLShareContextScope ctx(qt_gl_share_context()); QSize size = m_texture.bindCompressedTexture (data.constData(), data.size(), format); if (!size.isEmpty()) { @@ -446,7 +446,7 @@ bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format, const char *buf = reinterpret_cast(buffer); if (m_texture.canBindCompressedTexture(buf, int(len), format, &alpha)) { resize(0, 0); - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QGLShareContextScope ctx(qt_gl_share_context()); QSize size = m_texture.bindCompressedTexture(buf, int(len), format); if (!size.isEmpty()) { w = size.width(); @@ -479,7 +479,7 @@ void QGLPixmapData::copy(const QPixmapData *data, const QRect &rect) const QGLPixmapData *other = static_cast(data); if (other->m_renderFbo) { - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QGLShareContextScope ctx(qt_gl_share_context()); resize(rect.width(), rect.height()); m_hasAlpha = other->m_hasAlpha; @@ -593,7 +593,7 @@ QImage QGLPixmapData::toImage() const ensureCreated(); } - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QGLShareContextScope ctx(qt_gl_share_context()); glBindTexture(GL_TEXTURE_2D, m_texture.id); return qt_gl_read_texture(QSize(w, h), true, true); } @@ -617,7 +617,7 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const m_hasFillColor = false; - const QGLContext *share_ctx = qt_gl_share_widget()->context(); + const QGLContext *share_ctx = qt_gl_share_context(); QGLShareContextScope ctx(share_ctx); ensureCreated(); @@ -672,8 +672,8 @@ QPaintEngine* QGLPixmapData::paintEngine() const extern QGLWidget* qt_gl_share_widget(); if (!QGLContext::currentContext()) - qt_gl_share_widget()->makeCurrent(); - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + const_cast(qt_gl_share_context())->makeCurrent(); + QGLShareContextScope ctx(qt_gl_share_context()); QGLFramebufferObjectFormat format; format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 47f36dd..cd7558c 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -182,6 +182,7 @@ QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL) // QGLWindowSurface // +#ifndef Q_WS_QPA class QGLGlobalShareWidget { public: @@ -255,6 +256,23 @@ void qt_destroy_gl_share_widget() { _qt_gl_share_widget()->destroy(); } +#endif//Q_WS_QPA + +const QGLContext *qt_gl_share_context() +{ +#ifdef Q_WS_QPA + //make it possible to have an assesor to defaultSharedGLContext. + const QPlatformGLContext *platformContext = QPlatformGLContext::defaultSharedContext(); + if (!platformContext) + qDebug() << "Please implement a defaultSharedContext for your platformplugin"; + return QGLContext::fromPlatformGLContext(const_cast(platformContext)); +#else + QGLWidget *widget = qt_gl_share_widget(); + if (widget) + return widget->context(); + return 0; +#endif +} struct QGLWindowSurfacePrivate { @@ -336,10 +354,12 @@ QGLWindowSurface::~QGLWindowSurface() { if (d_ptr->ctx) glDeleteTextures(1, &d_ptr->tex_id); +#ifndef Q_WS_QPA // Dont delete the contexts. Destroying the window does that for us foreach(QGLContext **ctx, d_ptr->contexts) { delete *ctx; *ctx = 0; } +#endif delete d_ptr->pb; delete d_ptr->fbo; @@ -356,6 +376,7 @@ void QGLWindowSurface::deleted(QObject *object) d_ptr->fbo = 0; } +#ifndef Q_WS_QPA //no need to specifically delete the QGLContext as it will be deleted by QWidget QWidgetPrivate *widgetPrivate = widget->d_func(); if (widgetPrivate->extraData()) { union { QGLContext **ctxPtrPtr; void **voidPtrPtr; }; @@ -367,6 +388,7 @@ void QGLWindowSurface::deleted(QObject *object) d_ptr->contexts.removeAt(index); } } +#endif } } @@ -377,8 +399,14 @@ void QGLWindowSurface::hijackWindow(QWidget *widget) if (widgetPrivate->extraData()->glContext) return; +#ifdef Q_WS_QPA + QGLContext *ctx = QGLContext::fromPlatformGLContext(widget->platformWindow()->glContext()); + if (!d_ptr->fbo && d_ptr->tried_fbo) + d_ptr->ctx = ctx; +#else QGLContext *ctx = new QGLContext(surfaceFormat, widget); ctx->create(qt_gl_share_widget()->context()); +#endif #ifndef QT_NO_EGL static bool checkedForNOKSwapRegion = false; @@ -816,7 +844,7 @@ void QGLWindowSurface::updateGeometry() { } } -#if !defined(QT_OPENGL_ES_2) +#if !defined(QT_OPENGL_ES_2) && !defined(Q_WS_QPA) //QPA doesn't support pixelbuffers if (d_ptr->destructive_swap_buffers && (d_ptr->pb || !d_ptr->tried_pb)) { d_ptr->tried_pb = true; @@ -855,7 +883,7 @@ void QGLWindowSurface::updateGeometry() { d_ptr->pb = 0; } } -#endif // !defined(QT_OPENGL_ES_2) +#endif // !defined(QT_OPENGL_ES_2) !defined(Q_WS_QPA) ctx->makeCurrent(); diff --git a/src/opengl/qwindowsurface_gl_p.h b/src/opengl/qwindowsurface_gl_p.h index 4f4ec92..22bd5f0 100644 --- a/src/opengl/qwindowsurface_gl_p.h +++ b/src/opengl/qwindowsurface_gl_p.h @@ -66,8 +66,12 @@ class QRegion; class QWidget; struct QGLWindowSurfacePrivate; +#ifdef Q_WS_QPA +Q_OPENGL_EXPORT const QGLContext* qt_gl_share_context(); +#else Q_OPENGL_EXPORT QGLWidget* qt_gl_share_widget(); Q_OPENGL_EXPORT void qt_destroy_gl_share_widget(); +#endif class QGLWindowSurfaceGLPaintDevice : public QGLPaintDevice { diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index 7abc492..cbe6210 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -202,7 +202,9 @@ void QEglFSScreen::createAndSetPlatformContext() attribList[temp++] = 2; // GLES version 2 attribList[temp++] = EGL_NONE; - m_platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API); + QEGLPlatformContext *platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API); + platformContext->makeDefaultSaredContext(); + m_platformContext = platformContext; EGLint w,h; // screen size detection eglQuerySurface(m_dpy, m_surface, EGL_WIDTH, &w); -- cgit v0.12 From f7d66442963e1380a4f2db3d24cb24aa9d5c63ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 26 Nov 2010 16:01:29 +0100 Subject: Make the openKODE use the new eventloopintegration api. And also make it work with the new GL functionality in Lighthouse --- .../openkode/qopenkodeeventloopintegration.cpp | 27 ++++++++++++++-------- .../openkode/qopenkodeeventloopintegration.h | 6 +++-- .../platforms/openkode/qopenkodeintegration.cpp | 2 +- src/plugins/platforms/openkode/qopenkodewindow.cpp | 3 +-- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp index 73d874c..aefabf0 100644 --- a/src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp +++ b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp @@ -79,7 +79,7 @@ void kdprocessevent( const KDEvent *event) qDebug() << "KD_EVENT_INPUT_KEY_ATX"; break; case QT_EVENT_WAKEUP_EVENTLOOP: -// qDebug() << "QT_EVENT_WAKEUP_EVENTLOOP"; + QPlatformEventLoopIntegration::processEvents(); break; default: break; @@ -90,25 +90,34 @@ void kdprocessevent( const KDEvent *event) } QOpenKODEEventLoopIntegration::QOpenKODEEventLoopIntegration() + : m_quit(false) { m_kdThread = kdThreadSelf(); kdInstallCallback(&kdprocessevent,QT_EVENT_WAKEUP_EVENTLOOP,this); } -void QOpenKODEEventLoopIntegration::processEvents(qint64 msec) +void QOpenKODEEventLoopIntegration::startEventLoop() { - if (msec == 0) - msec = -1; - const KDEvent *event = kdWaitEvent(msec*1000); - if (event) { - kdDefaultEvent(event); - while ((event = kdWaitEvent(0)) != 0) { + + while(!m_quit) { + qint64 msec = nextTimerEvent(); + const KDEvent *event = kdWaitEvent(msec); + if (event) { kdDefaultEvent(event); + while ((event = kdWaitEvent(0)) != 0) { + kdDefaultEvent(event); + } } + QPlatformEventLoopIntegration::processEvents(); } } -void QOpenKODEEventLoopIntegration::wakeup() +void QOpenKODEEventLoopIntegration::quitEventLoop() +{ + m_quit = true; +} + +void QOpenKODEEventLoopIntegration::qtNeedsToProcessEvents() { KDEvent *event = kdCreateEvent(); event->type = QT_EVENT_WAKEUP_EVENTLOOP; diff --git a/src/plugins/platforms/openkode/qopenkodeeventloopintegration.h b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.h index 61bd444..73b287f 100644 --- a/src/plugins/platforms/openkode/qopenkodeeventloopintegration.h +++ b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.h @@ -54,12 +54,14 @@ class QOpenKODEEventLoopIntegration : public QPlatformEventLoopIntegration { public: QOpenKODEEventLoopIntegration(); - void processEvents(qint64 msec); - void wakeup(); + void startEventLoop(); + void quitEventLoop(); + void qtNeedsToProcessEvents(); void processInputEvent(const KDEvent *event); private: + bool m_quit; KDThread *m_kdThread; }; diff --git a/src/plugins/platforms/openkode/qopenkodeintegration.cpp b/src/plugins/platforms/openkode/qopenkodeintegration.cpp index 60be897..763e69e 100644 --- a/src/plugins/platforms/openkode/qopenkodeintegration.cpp +++ b/src/plugins/platforms/openkode/qopenkodeintegration.cpp @@ -207,7 +207,7 @@ QWindowSurface *QOpenKODEIntegration::createWindowSurface(QWidget *widget, WId) case QPlatformWindowFormat::OpenVG: // returnSurface = new QVGWindowSurface(widget); - break; +// break; default: returnSurface = new QGLWindowSurface(widget); diff --git a/src/plugins/platforms/openkode/qopenkodewindow.cpp b/src/plugins/platforms/openkode/qopenkodewindow.cpp index 32517c6..91c6473 100644 --- a/src/plugins/platforms/openkode/qopenkodewindow.cpp +++ b/src/plugins/platforms/openkode/qopenkodewindow.cpp @@ -160,7 +160,7 @@ QOpenKODEWindow::QOpenKODEWindow(QWidget *tlw) m_eglContextAttrs.data(), surface, m_eglApi); m_platformGlContext->makeDefaultSaredContext(); } else { - m_platformGlContext = static_cast(QPlatformGLContext::defaultSharedContext()); + m_platformGlContext = const_cast(static_cast(QPlatformGLContext::defaultSharedContext())); kdDestroyWindow(m_kdWindow); m_kdWindow = 0; } @@ -209,7 +209,6 @@ void QOpenKODEWindow::setGeometry(const QRect &rect) //need to recreate context if (needToDeleteContext) { - qDebug() << "deleting context"; delete m_platformGlContext; QList screens = QApplicationPrivate::platformIntegration()->screens(); -- cgit v0.12 From b0fb70cd74ef1453a36169088e6f283206818d78 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Fri, 26 Nov 2010 16:32:32 +0100 Subject: Fix link() autotest on Windows This was missed from the previous commit. Reviewed-by: Joao --- tests/auto/qfile/tst_qfile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index ba9a8bf..1bbf230 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -1315,7 +1315,7 @@ void tst_QFile::link() #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) QString wd = getWorkingDirectoryForLink(info2.absoluteFilePath()); - QCOMPARE(QDir::fromNativeSeparators(wd), referenceTarget); + QCOMPARE(QDir::fromNativeSeparators(wd), QDir::cleanPath(info1.absolutePath())); #endif QVERIFY(QFile::remove(info2.absoluteFilePath())); -- cgit v0.12 From 7a5b81532d482b611d5ea8b3a93e6ee9f9098db0 Mon Sep 17 00:00:00 2001 From: miniak Date: Thu, 25 Nov 2010 18:02:16 +0100 Subject: QSystemTrayIcon::messageTimeout() signal implemented Task-number: QTBUG-3870 Merge-request: 710 Reviewed-by: Olivier Goffart --- src/gui/util/qsystemtrayicon.cpp | 14 +++++- src/gui/util/qsystemtrayicon.h | 1 + src/gui/util/qsystemtrayicon_win.cpp | 4 ++ tests/auto/qsystemtrayicon/qsystemtrayicon.pro | 1 + tests/auto/qsystemtrayicon/tst_qsystemtrayicon.cpp | 56 ++++++++++++++++++++++ 5 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/gui/util/qsystemtrayicon.cpp b/src/gui/util/qsystemtrayicon.cpp index 941961b..1c95558 100644 --- a/src/gui/util/qsystemtrayicon.cpp +++ b/src/gui/util/qsystemtrayicon.cpp @@ -335,6 +335,16 @@ bool QSystemTrayIcon::event(QEvent *e) \sa activated() */ +/*! + \fn void QSystemTrayIcon::messageTimeout() + + This signal is emitted when the message displayed using showMessage() + hides automatically after being shown for the timeout value. + + Currently this signal is not sent on Mac OS X. + + \since 4.8 +*/ /*! Returns true if the system tray is available; otherwise returns false. @@ -657,8 +667,10 @@ void QBalloonTip::timerEvent(QTimerEvent *e) { if (e->timerId() == timerId) { killTimer(timerId); - if (!underMouse()) + if (!underMouse()) { close(); + emit trayIcon->messageTimeout(); + } return; } QWidget::timerEvent(e); diff --git a/src/gui/util/qsystemtrayicon.h b/src/gui/util/qsystemtrayicon.h index 0a57e35..5812d07 100644 --- a/src/gui/util/qsystemtrayicon.h +++ b/src/gui/util/qsystemtrayicon.h @@ -111,6 +111,7 @@ public Q_SLOTS: Q_SIGNALS: void activated(QSystemTrayIcon::ActivationReason reason); void messageClicked(); + void messageTimeout(); protected: bool event(QEvent *event); diff --git a/src/gui/util/qsystemtrayicon_win.cpp b/src/gui/util/qsystemtrayicon_win.cpp index fc5de44..91b11ef 100644 --- a/src/gui/util/qsystemtrayicon_win.cpp +++ b/src/gui/util/qsystemtrayicon_win.cpp @@ -313,6 +313,10 @@ bool QSystemTrayIconSys::winEvent( MSG *m, long *result ) emit q->messageClicked(); break; + case NIN_BALLOONTIMEOUT: + emit q->messageTimeout(); + break; + case WM_MBUTTONUP: emit q->activated(QSystemTrayIcon::MiddleClick); break; diff --git a/tests/auto/qsystemtrayicon/qsystemtrayicon.pro b/tests/auto/qsystemtrayicon/qsystemtrayicon.pro index a77b478..a33d072 100644 --- a/tests/auto/qsystemtrayicon/qsystemtrayicon.pro +++ b/tests/auto/qsystemtrayicon/qsystemtrayicon.pro @@ -5,5 +5,6 @@ load(qttest_p4) SOURCES += tst_qsystemtrayicon.cpp +win32:LIBS += user32.lib diff --git a/tests/auto/qsystemtrayicon/tst_qsystemtrayicon.cpp b/tests/auto/qsystemtrayicon/tst_qsystemtrayicon.cpp index b1ec0ff..f4120ca 100644 --- a/tests/auto/qsystemtrayicon/tst_qsystemtrayicon.cpp +++ b/tests/auto/qsystemtrayicon/tst_qsystemtrayicon.cpp @@ -47,6 +47,10 @@ #include #include +#ifdef Q_OS_WIN32 +#include +#endif + //TESTED_CLASS= //TESTED_FILES= @@ -64,6 +68,7 @@ private slots: void showMessage(); void supportsMessages(); void lastWindowClosed(); + void messageTimeout(); }; tst_QSystemTrayIcon::tst_QSystemTrayIcon() @@ -144,5 +149,56 @@ void tst_QSystemTrayIcon::lastWindowClosed() QVERIFY(spy.count() == 1); } +#ifndef Q_WS_MAC + +static void triggerMessageTimeout() +{ +#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) + // the application has to loose focus on Windows for the message to timeout + INPUT input[2] = {}; + + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_LWIN; + input[0].ki.dwFlags = 0; + + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = VK_LWIN; + input[1].ki.dwFlags = KEYEVENTF_KEYUP; + + for (int i = 0; i < 2; i++) { + QTest::qWait(100); + ::SendInput(2, input, sizeof(INPUT)); + } +#endif /* defined(Q_WS_WIN) && !defined(Q_WS_WINCE) */ +} + +void tst_QSystemTrayIcon::messageTimeout() +{ + QSystemTrayIcon icon; + if (icon.supportsMessages()) { + icon.setIcon(QIcon("whatever.png")); + icon.show(); + + QObject::connect(&icon, SIGNAL(messageTimeout()), qApp, SLOT(quit())); + QSignalSpy spy(&icon, SIGNAL(messageTimeout())); + icon.showMessage("Title", "Hello World!", QSystemTrayIcon::Information, 1000); + + triggerMessageTimeout(); + + QTimer::singleShot(30000, qApp, SLOT(quit())); // in case the test fails + qApp->exec(); + QVERIFY(spy.count() == 1); + } +} + +#else + +void tst_QSystemTrayIcon::messageTimeout() +{ + // skip the test on Mac OS X +} + +#endif /* Q_WS_MAC */ + QTEST_MAIN(tst_QSystemTrayIcon) #include "tst_qsystemtrayicon.moc" -- cgit v0.12 From 3d442b86ae59b07bd0064e3a3ca9fc613545d3f3 Mon Sep 17 00:00:00 2001 From: Tijl Coosemans Date: Fri, 26 Nov 2010 10:11:06 +0100 Subject: QKqueueFileSystemWatcherEngine: Use EV_CLEAR instead of EV_ONESHOT. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using EV_ONESHOT and re-enabling the kevent after emitting the signal allows for a window in which file system changes can go undetected. By using EV_CLEAR instead the kevent can stay enabled. Merge-request: 2425 Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemwatcher_kqueue.cpp | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index 378ad20..45aea73 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -157,7 +157,7 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths, EV_SET(&kev, fd, EVFILT_VNODE, - EV_ADD | EV_ENABLE | EV_ONESHOT, + EV_ADD | EV_ENABLE | EV_CLEAR, NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE, 0, 0); @@ -315,24 +315,12 @@ void QKqueueFileSystemWatcherEngine::run() else emit fileChanged(path, true); } else { - DEBUG() << path << "changed, re-enabling watch"; + DEBUG() << path << "changed"; if (id < 0) emit directoryChanged(path, false); else emit fileChanged(path, false); - - // renable the watch - EV_SET(&kev, - fd, - EVFILT_VNODE, - EV_ADD | EV_ENABLE | EV_ONESHOT, - NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE, - 0, - 0); - if (kevent(kqfd, &kev, 1, 0, 0, 0) == -1) { - perror("QKqueueFileSystemWatcherEngine::processKqueueEvents: kevent EV_ADD"); - } } } -- cgit v0.12 From 42e861407a9977d3fa8daae5abe54e98ba6b05da Mon Sep 17 00:00:00 2001 From: Tijl Coosemans Date: Fri, 26 Nov 2010 10:11:07 +0100 Subject: QKqueueFileSystemWatcherEngine: Deleting kevent is handled by close(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge-request: 2425 Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemwatcher_kqueue.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index 45aea73..f66231a 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -203,19 +203,7 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths if (x.isEmpty() || x != path) continue; - int fd = id < 0 ? -id : id; - struct kevent kev; - EV_SET(&kev, - fd, - EVFILT_VNODE, - EV_DELETE, - NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE, - 0, - 0); - if (kevent(kqfd, &kev, 1, 0, 0, 0) == -1) { - perror("QKqueueFileSystemWatcherEngine::removeWatch: kevent"); - } - ::close(fd); + ::close(id < 0 ? -id : id); it.remove(); if (id < 0) -- cgit v0.12 From 4ff80e53a306b1727b78b49e2de6fdafd1fb5ada Mon Sep 17 00:00:00 2001 From: Tijl Coosemans Date: Fri, 26 Nov 2010 10:11:08 +0100 Subject: QKqueueFileSystemWatcherEngine: Handle kevent(2) returning EINTR. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The worker thread exits whenever the kevent call returns an error, but in the case of EINTR (interrupted by signal) it should just call kevent again. Otherwise for instance, attaching a debugger to the process causes the worker thread to exit because of the SIGSTOP it receives. Merge-request: 2425 Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemwatcher_kqueue.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index f66231a..4d15519 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -234,9 +234,10 @@ void QKqueueFileSystemWatcherEngine::run() static const struct timespec ZeroTimeout = { 0, 0 }; forever { + int r; struct kevent kev; DEBUG() << "QKqueueFileSystemWatcherEngine: waiting for kevents..."; - int r = kevent(kqfd, 0, 0, &kev, 1, 0); + EINTR_LOOP(r, kevent(kqfd, 0, 0, &kev, 1, 0)); if (r < 0) { perror("QKqueueFileSystemWatcherEngine: error during kevent wait"); return; -- cgit v0.12 From 03c82dc0d4b4bbbe17e9d91bef6a112d512ca002 Mon Sep 17 00:00:00 2001 From: Tijl Coosemans Date: Fri, 26 Nov 2010 10:11:09 +0100 Subject: QKqueueFileSystemWatcherEngine: Unlock mutex before calling write(2). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calls to write(2) potentially block, so make sure the application thread unlocks the mutex before it writes to the pipe between itself and the worker thread, so the latter can continue to process events and eventually unblock the write call (if needed) by emptying the pipe. Merge-request: 2425 Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemwatcher_kqueue.cpp | 134 ++++++++++++++------------- 1 file changed, 69 insertions(+), 65 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index 4d15519..8fba091 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -117,67 +117,69 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths, QStringList *files, QStringList *directories) { - QMutexLocker locker(&mutex); - QStringList p = paths; - QMutableListIterator it(p); - while (it.hasNext()) { - QString path = it.next(); - int fd; + { + QMutexLocker locker(&mutex); + + QMutableListIterator it(p); + while (it.hasNext()) { + QString path = it.next(); + int fd; #if defined(O_EVTONLY) - fd = qt_safe_open(QFile::encodeName(path), O_EVTONLY); + fd = qt_safe_open(QFile::encodeName(path), O_EVTONLY); #else - fd = qt_safe_open(QFile::encodeName(path), O_RDONLY); + fd = qt_safe_open(QFile::encodeName(path), O_RDONLY); #endif - if (fd == -1) { - perror("QKqueueFileSystemWatcherEngine::addPaths: open"); - continue; - } + if (fd == -1) { + perror("QKqueueFileSystemWatcherEngine::addPaths: open"); + continue; + } - QT_STATBUF st; - if (QT_FSTAT(fd, &st) == -1) { - perror("QKqueueFileSystemWatcherEngine::addPaths: fstat"); - ::close(fd); - continue; - } - int id = (S_ISDIR(st.st_mode)) ? -fd : fd; - if (id < 0) { - if (directories->contains(path)) { + QT_STATBUF st; + if (QT_FSTAT(fd, &st) == -1) { + perror("QKqueueFileSystemWatcherEngine::addPaths: fstat"); ::close(fd); continue; } - } else { - if (files->contains(path)) { + int id = (S_ISDIR(st.st_mode)) ? -fd : fd; + if (id < 0) { + if (directories->contains(path)) { + ::close(fd); + continue; + } + } else { + if (files->contains(path)) { + ::close(fd); + continue; + } + } + + struct kevent kev; + EV_SET(&kev, + fd, + EVFILT_VNODE, + EV_ADD | EV_ENABLE | EV_CLEAR, + NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE, + 0, + 0); + if (kevent(kqfd, &kev, 1, 0, 0, 0) == -1) { + perror("QKqueueFileSystemWatcherEngine::addPaths: kevent"); ::close(fd); continue; } - } - struct kevent kev; - EV_SET(&kev, - fd, - EVFILT_VNODE, - EV_ADD | EV_ENABLE | EV_CLEAR, - NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE, - 0, - 0); - if (kevent(kqfd, &kev, 1, 0, 0, 0) == -1) { - perror("QKqueueFileSystemWatcherEngine::addPaths: kevent"); - ::close(fd); - continue; - } + it.remove(); + if (id < 0) { + DEBUG() << "QKqueueFileSystemWatcherEngine: added directory path" << path; + directories->append(path); + } else { + DEBUG() << "QKqueueFileSystemWatcherEngine: added file path" << path; + files->append(path); + } - it.remove(); - if (id < 0) { - DEBUG() << "QKqueueFileSystemWatcherEngine: added directory path" << path; - directories->append(path); - } else { - DEBUG() << "QKqueueFileSystemWatcherEngine: added file path" << path; - files->append(path); + pathToID.insert(path, id); + idToPath.insert(id, path); } - - pathToID.insert(path, id); - idToPath.insert(id, path); } if (!isRunning()) @@ -192,31 +194,33 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths QStringList *files, QStringList *directories) { - QMutexLocker locker(&mutex); - + bool isEmpty; QStringList p = paths; - QMutableListIterator it(p); - while (it.hasNext()) { - QString path = it.next(); - int id = pathToID.take(path); - QString x = idToPath.take(id); - if (x.isEmpty() || x != path) - continue; + { + QMutexLocker locker(&mutex); - ::close(id < 0 ? -id : id); + QMutableListIterator it(p); + while (it.hasNext()) { + QString path = it.next(); + int id = pathToID.take(path); + QString x = idToPath.take(id); + if (x.isEmpty() || x != path) + continue; + + ::close(id < 0 ? -id : id); - it.remove(); - if (id < 0) - directories->removeAll(path); - else - files->removeAll(path); + it.remove(); + if (id < 0) + directories->removeAll(path); + else + files->removeAll(path); + } + isEmpty = pathToID.isEmpty(); } - if (pathToID.isEmpty()) { + if (isEmpty) { stop(); - locker.unlock(); wait(); - locker.relock(); } else { write(kqpipe[1], "@", 1); } -- cgit v0.12 From e0e9d4ea2cec37243d964a5309be49101d112233 Mon Sep 17 00:00:00 2001 From: Tijl Coosemans Date: Fri, 26 Nov 2010 10:11:10 +0100 Subject: QKqueueFileSystemWatcherEngine: Unlock mutex between two events. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the worker thread unlock the mutex between processing two events. Otherwise it's possible for the worker thread to block the application thread when many events occur. Also, there's no need to lock the mutex when processing a pipe event. Generally the worker thread should hamper the application thread as little as possible, so only lock the mutex where needed. Merge-request: 2425 Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemwatcher_kqueue.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index 8fba091..637a961 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -235,8 +235,6 @@ void QKqueueFileSystemWatcherEngine::stop() void QKqueueFileSystemWatcherEngine::run() { - static const struct timespec ZeroTimeout = { 0, 0 }; - forever { int r; struct kevent kev; @@ -245,10 +243,7 @@ void QKqueueFileSystemWatcherEngine::run() if (r < 0) { perror("QKqueueFileSystemWatcherEngine: error during kevent wait"); return; - } - - QMutexLocker locker(&mutex); - do { + } else { int fd = kev.ident; DEBUG() << "QKqueueFileSystemWatcherEngine: processing kevent" << kev.ident << kev.filter; @@ -280,6 +275,8 @@ void QKqueueFileSystemWatcherEngine::run() break; } } else { + QMutexLocker locker(&mutex); + int id = fd; QString path = idToPath.value(id); if (path.isEmpty()) { @@ -288,12 +285,12 @@ void QKqueueFileSystemWatcherEngine::run() path = idToPath.value(id); if (path.isEmpty()) { DEBUG() << "QKqueueFileSystemWatcherEngine: received a kevent for a file we're not watching"; - goto process_next_event; + continue; } } if (kev.filter != EVFILT_VNODE) { DEBUG() << "QKqueueFileSystemWatcherEngine: received a kevent with the wrong filter"; - goto process_next_event; + continue; } if ((kev.fflags & (NOTE_DELETE | NOTE_REVOKE | NOTE_RENAME)) != 0) { @@ -316,11 +313,7 @@ void QKqueueFileSystemWatcherEngine::run() emit fileChanged(path, false); } } - - // are there any more? -process_next_event: - r = kevent(kqfd, 0, 0, &kev, 1, &ZeroTimeout); - } while (r > 0); + } } } -- cgit v0.12 From f7feeee1733b6cb8bfcc157fff1e444068dc290c Mon Sep 17 00:00:00 2001 From: Tijl Coosemans Date: Fri, 26 Nov 2010 10:11:11 +0100 Subject: QKqueueFileSystemWatcherEngine: Use higher file descriptors. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A file descriptor is used for every path to be monitored, but descriptors below FD_SETSIZE (typically 1024) are precious, for use with select(2). To allow the application (and other parts of Qt) to use select(2), try to duplicate the descriptor returned by open(2) above FD_SETSIZE and close(2) the original. However, only do so when the descriptor table is already fairly large (FD_SETSIZE / 2). This keeps the descriptor table small for applications that use only a few descriptors. While here, also set the close-on-exec flag on the (new) descriptor. Merge-request: 2425 Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemwatcher_kqueue.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index 637a961..0103abd 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -134,6 +134,14 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths, perror("QKqueueFileSystemWatcherEngine::addPaths: open"); continue; } + if (fd >= (int)FD_SETSIZE / 2 && fd < (int)FD_SETSIZE) { + int fddup = fcntl(fd, F_DUPFD, FD_SETSIZE); + if (fddup != -1) { + ::close(fd); + fd = fddup; + } + } + fcntl(fd, F_SETFD, FD_CLOEXEC); QT_STATBUF st; if (QT_FSTAT(fd, &st) == -1) { -- cgit v0.12 From 0af0682ebbb70635f40dbed64d4cc678ade6bed2 Mon Sep 17 00:00:00 2001 From: Tijl Coosemans Date: Fri, 26 Nov 2010 10:11:12 +0100 Subject: QPollingFileSystemWatcherEngine: Fix double report of directory change. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The polling engine first retrieves a QFileInfo for a given path, then tests whether it's different from before and if so, stores the new file info and emits a signal. In case path is a directory the test also checks if the list of directory entries has changed. This creates a window between retrieving the file info and the test in which a file can be added/removed from the directory or the directory itself can be removed. In that case the test returns true, because the list of entries has changed, but outdated file info is stored which means that on the next timeout the same change will be reported a second time. Therefore, refresh the file info after the test for changes. Merge-request: 2425 Reviewed-by: João Abecasis --- src/corelib/io/qfilesystemwatcher.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp index 18c3c9f..1e6dcee 100644 --- a/src/corelib/io/qfilesystemwatcher.cpp +++ b/src/corelib/io/qfilesystemwatcher.cpp @@ -228,8 +228,14 @@ void QPollingFileSystemWatcherEngine::timeout() dit.remove(); emit directoryChanged(path, true); } else if (x.value() != fi) { - x.value() = fi; - emit directoryChanged(path, false); + fi.refresh(); + if (!fi.exists()) { + dit.remove(); + emit directoryChanged(path, true); + } else { + x.value() = fi; + emit directoryChanged(path, false); + } } } -- cgit v0.12 From b758e011a6d88448bf4c3db7f27cb4df773fd5e3 Mon Sep 17 00:00:00 2001 From: Tijl Coosemans Date: Fri, 26 Nov 2010 10:11:13 +0100 Subject: tst_QFileSystemWatcher: Don't exit the event loop on first signal. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sometimes tests can produce more than one signal and other times more than one signal would be an error. In order to test this the event loop should run long enough and not quit on the first signal. This is especially important on multicore systems where the application and worker threads run on different CPUs. Signals emitted by the worker thread are then almost immediately processed by the application thread. Merge-request: 2425 Reviewed-by: João Abecasis --- tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index a26e34d..3ed93fa 100644 --- a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -139,10 +139,6 @@ void tst_QFileSystemWatcher::basicTest() QSignalSpy changedSpy(&watcher, SIGNAL(fileChanged(const QString &))); QEventLoop eventLoop; - connect(&watcher, - SIGNAL(fileChanged(const QString &)), - &eventLoop, - SLOT(quit())); QTimer timer; connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit())); @@ -278,10 +274,6 @@ void tst_QFileSystemWatcher::watchDirectory() QSignalSpy changedSpy(&watcher, SIGNAL(directoryChanged(const QString &))); QEventLoop eventLoop; - connect(&watcher, - SIGNAL(directoryChanged(const QString &)), - &eventLoop, - SLOT(quit())); QTimer timer; connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit())); -- cgit v0.12 From 5784daa662e1ace86e6046bf369e9029d57c32d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 26 Nov 2010 10:11:14 +0100 Subject: Fix QSettings auto test to use QTRY_VERIFY ... instead of relying on qApp->processEvents. Reviewed-by: Olivier Goffart --- tests/auto/qsettings/tst_qsettings.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/auto/qsettings/tst_qsettings.cpp b/tests/auto/qsettings/tst_qsettings.cpp index 0395eff..0813e28 100644 --- a/tests/auto/qsettings/tst_qsettings.cpp +++ b/tests/auto/qsettings/tst_qsettings.cpp @@ -51,6 +51,7 @@ #include #include #include +#include "../../shared/util.h" #if !defined(Q_OS_SYMBIAN) # include @@ -1726,26 +1727,22 @@ void tst_QSettings::testUpdateRequestEvent() settings1.setValue("key1", 1); QVERIFY(QFileInfo("foo").size() == 0); - qApp->processEvents(); - QVERIFY(QFileInfo("foo").size() > 0); + QTRY_VERIFY(QFileInfo("foo").size() > 0); settings1.remove("key1"); QVERIFY(QFileInfo("foo").size() > 0); - qApp->processEvents(); - QVERIFY(QFileInfo("foo").size() == 0); + QTRY_VERIFY(QFileInfo("foo").size() == 0); settings1.setValue("key2", 2); QVERIFY(QFileInfo("foo").size() == 0); - qApp->processEvents(); - QVERIFY(QFileInfo("foo").size() > 0); + QTRY_VERIFY(QFileInfo("foo").size() > 0); settings1.clear(); QVERIFY(QFileInfo("foo").size() > 0); - qApp->processEvents(); - QVERIFY(QFileInfo("foo").size() == 0); + QTRY_VERIFY(QFileInfo("foo").size() == 0); } const int NumIterations = 5; -- cgit v0.12 From 4e6cc34b75fd42d663ced0f3da1c9a9a6950fb6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 26 Nov 2010 10:11:15 +0100 Subject: QKqueueFileSystemWatcher: don't stop thread that isn't running When removing paths from the watch list, if we end up with an empty watch list, we would send a request to the processing thread to quit. In the case where the watch list was empty to begin with (the paths being removed weren't actually being watched) the request to quit would still be queued. If the processing thread wasn't running (and it shouldn't if there weren't any paths being watched) the request to quit would still be posted but not processed. The next time paths were added and the thread started, the request would be processed and the thread would quit at once. When removing paths from the list, we now check whether the watch list is empty to begin with and exit early without asking the processing thread to quit itself. Task-Number: QTBUG-14435 Reviewed-by: Bradley T. Hughes --- src/corelib/io/qfilesystemwatcher_kqueue.cpp | 2 ++ tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index 0103abd..3664396 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -206,6 +206,8 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths QStringList p = paths; { QMutexLocker locker(&mutex); + if (pathToID.isEmpty()) + return p; QMutableListIterator it(p); while (it.hasNext()) { diff --git a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index 3ed93fa..1feaced 100644 --- a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -135,6 +135,7 @@ void tst_QFileSystemWatcher::basicTest() // create watcher, forcing it to use a specific backend QFileSystemWatcher watcher; watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend); + watcher.removePath(testFile.fileName()); watcher.addPath(testFile.fileName()); QSignalSpy changedSpy(&watcher, SIGNAL(fileChanged(const QString &))); -- cgit v0.12 From 86ddcd84dc13618cf27ae899f136d8fd138e4b26 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Fri, 26 Nov 2010 18:07:56 +0100 Subject: QNetworkReply autotest: fix possible crash ... by waiting for the thread to finish. Reviewed-by: Markus Goetz --- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 90416f2..9cf61f9 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -4490,6 +4490,7 @@ void tst_QNetworkReply::httpProxyCommandsSynchronous() QVERIFY(reply->isFinished()); // synchronous manager.setProxy(QNetworkProxy()); serverThread.quit(); + serverThread.wait(3000); //qDebug() << reply->error() << reply->errorString(); -- cgit v0.12 From 5e257bd44fa4a76f4c2c573a6c5623802022ff18 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 26 Nov 2010 18:38:55 +0100 Subject: Fix a race condition related to service acquisition. The explanation is in the testcase and in the task. The reentrancy caused some deadlocks, that's why handleMessage() stops processing if the refcount has dropped down to zero. Should also save some CPU cycles at the application shutdown time. Task-number: QTBUG-15651 Reviewed-by: Trust Me --- src/dbus/qdbusconnection_p.h | 13 +++- src/dbus/qdbusintegrator.cpp | 35 +++++++++-- tests/auto/qdbusconnection/tst_qdbusconnection.cpp | 69 ++++++++++++++++++++++ 3 files changed, 108 insertions(+), 9 deletions(-) diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 1bd00da..67145b8 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -203,6 +203,8 @@ public: void disconnectRelay(const QString &service, const QString &path, const QString &interface, QDBusAbstractInterface *receiver, const char *signal); + void registerService(const QString &serviceName); + void unregisterService(const QString &serviceName); bool handleMessage(const QDBusMessage &msg); void waitForFinished(QDBusPendingCallPrivate *pcall); @@ -247,9 +249,11 @@ public slots: void socketWrite(int); void objectDestroyed(QObject *o); void relaySignal(QObject *obj, const QMetaObject *, int signalId, const QVariantList &args); - void _q_serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); - void registerService(const QString &serviceName); - void unregisterService(const QString &serviceName); + +private slots: + void serviceOwnerChangedNoLock(const QString &name, const QString &oldOwner, const QString &newOwner); + void registerServiceNoLock(const QString &serviceName); + void unregisterServiceNoLock(const QString &serviceName); signals: void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); @@ -303,6 +307,9 @@ public: QObject *receiver, const char *signal, int minMIdx, bool buildSignature); static DBusHandlerResult messageFilter(DBusConnection *, DBusMessage *, void *); + static bool checkReplyForDelivery(QDBusConnectionPrivate *target, QObject *object, + int idx, const QList &metaTypes, + const QDBusMessage &msg); static QDBusCallDeliveryEvent *prepareReply(QDBusConnectionPrivate *target, QObject *object, int idx, const QList &metaTypes, const QDBusMessage &msg); diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index a5d8ada..1842e5a 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -552,6 +552,9 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg) (*(*list)[i])(amsg); } + if (!ref) + return false; + switch (amsg.type()) { case QDBusMessage::SignalMessage: handleSignal(amsg); @@ -713,6 +716,8 @@ static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags, return -1; } +static QDBusCallDeliveryEvent * const DIRECT_DELIVERY = (QDBusCallDeliveryEvent *)1; + QDBusCallDeliveryEvent* QDBusConnectionPrivate::prepareReply(QDBusConnectionPrivate *target, QObject *object, int idx, const QList &metaTypes, @@ -736,6 +741,8 @@ QDBusCallDeliveryEvent* QDBusConnectionPrivate::prepareReply(QDBusConnectionPriv // we can deliver // prepare for the call + if (target == object) + return DIRECT_DELIVERY; return new QDBusCallDeliveryEvent(QDBusConnection(target), idx, target, msg, metaTypes); } @@ -750,6 +757,12 @@ void QDBusConnectionPrivate::activateSignal(const QDBusConnectionPrivate::Signal // Slots can optionally have one final parameter that is a QDBusMessage // Slots receive read-only copies of the message (i.e., pass by value or by const-ref) QDBusCallDeliveryEvent *call = prepareReply(this, hook.obj, hook.midx, hook.params, msg); + if (call == DIRECT_DELIVERY) { + // short-circuit delivery + Q_ASSERT(this == hook.obj); + deliverCall(this, 0, msg, hook.params, hook.midx); + return; + } if (call) postEventToThread(ActivateSignalAction, hook.obj, call); } @@ -1207,11 +1220,11 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in q_dbus_message_unref(msg); } -void QDBusConnectionPrivate::_q_serviceOwnerChanged(const QString &name, - const QString &oldOwner, const QString &newOwner) +void QDBusConnectionPrivate::serviceOwnerChangedNoLock(const QString &name, + const QString &oldOwner, const QString &newOwner) { Q_UNUSED(oldOwner); - QDBusWriteLocker locker(UpdateSignalHookOwnerAction, this); +// QDBusWriteLocker locker(UpdateSignalHookOwnerAction, this); WatchedServicesHash::Iterator it = watchedServices.find(name); if (it == watchedServices.end()) return; @@ -1686,11 +1699,11 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError hook.obj = this; hook.params << QMetaType::Void << QVariant::String; // both functions take a QString as parameter and return void - hook.midx = staticMetaObject.indexOfSlot("registerService(QString)"); + hook.midx = staticMetaObject.indexOfSlot("registerServiceNoLock(QString)"); Q_ASSERT(hook.midx != -1); signalHooks.insert(QLatin1String("NameAcquired:" DBUS_INTERFACE_DBUS), hook); - hook.midx = staticMetaObject.indexOfSlot("unregisterService(QString)"); + hook.midx = staticMetaObject.indexOfSlot("unregisterServiceNoLock(QString)"); Q_ASSERT(hook.midx != -1); signalHooks.insert(QLatin1String("NameLost:" DBUS_INTERFACE_DBUS), hook); @@ -2081,7 +2094,7 @@ void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook // we need to watch for this service changing connectSignal(dbusServiceString(), QString(), dbusInterfaceString(), QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), - this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); + this, SLOT(serviceOwnerChangedNoLock(QString,QString,QString))); data.owner = getNameOwnerNoCache(hook.service); qDBusDebug() << this << "Watching service" << hook.service << "for owner changes (current owner:" << data.owner << ")"; @@ -2342,12 +2355,22 @@ QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &pa void QDBusConnectionPrivate::registerService(const QString &serviceName) { QDBusWriteLocker locker(RegisterServiceAction, this); + registerServiceNoLock(serviceName); +} + +void QDBusConnectionPrivate::registerServiceNoLock(const QString &serviceName) +{ serviceNames.append(serviceName); } void QDBusConnectionPrivate::unregisterService(const QString &serviceName) { QDBusWriteLocker locker(UnregisterServiceAction, this); + unregisterServiceNoLock(serviceName); +} + +void QDBusConnectionPrivate::unregisterServiceNoLock(const QString &serviceName) +{ serviceNames.removeAll(serviceName); } diff --git a/tests/auto/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/qdbusconnection/tst_qdbusconnection.cpp index 599abbd..4494d6f 100644 --- a/tests/auto/qdbusconnection/tst_qdbusconnection.cpp +++ b/tests/auto/qdbusconnection/tst_qdbusconnection.cpp @@ -106,6 +106,8 @@ private slots: void slotsWithLessParameters(); void nestedCallWithCallback(); + void serviceRegistrationRaceCondition(); + public: QString serviceName() const { return "com.trolltech.Qt.Autotests.QDBusConnection"; } bool callMethod(const QDBusConnection &conn, const QString &path); @@ -647,6 +649,73 @@ void tst_QDBusConnection::nestedCallWithCallback() QCOMPARE(signalsReceived, 1); } +class RaceConditionSignalWaiter : public QObject +{ + Q_OBJECT +public: + int count; + RaceConditionSignalWaiter() : count (0) {} + virtual ~RaceConditionSignalWaiter() {} + +public slots: + void countUp() { ++count; emit done(); } +signals: + void done(); +}; + +void tst_QDBusConnection::serviceRegistrationRaceCondition() +{ + // There was a race condition in the updating of list of name owners in + // QtDBus. When the user connects to a signal coming from a given + // service, we must listen for NameOwnerChanged signals relevant to that + // name and update when the owner changes. However, it's possible that we + // receive in one chunk from the server both the NameOwnerChanged signal + // about the service and the signal we're interested in. Since QtDBus + // posts events in order to handle the incoming signals, the update + // happens too late. + + const QString connectionName = "testConnectionName"; + const QString serviceName = "org.example.SecondaryName"; + + QDBusConnection session = QDBusConnection::sessionBus(); + QVERIFY(!session.interface()->isServiceRegistered(serviceName)); + + // connect to the signal: + RaceConditionSignalWaiter recv; + session.connect(serviceName, "/", "com.trolltech.TestCase", "oneSignal", &recv, SLOT(countUp())); + + // create a secondary connection and register a name + QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, connectionName); + QDBusConnection::disconnectFromBus(connectionName); // disconnection happens when "connection" goes out of scope + QVERIFY(connection.isConnected()); + QVERIFY(connection.registerService(serviceName)); + + // send a signal + QDBusMessage msg = QDBusMessage::createSignal("/", "com.trolltech.TestCase", "oneSignal"); + connection.send(msg); + + // make a blocking call just to be sure that the buffer was flushed + msg = QDBusMessage::createMethodCall("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", + "NameHasOwner"); + msg << connectionName; + connection.call(msg); // ignore result + + // Now here's the race condition (more info on task QTBUG-15651): + // the bus has most likely queued three signals for us to work on: + // 1) NameOwnerChanged for the connection we created above + // 2) NameOwnerChanged for the service we registered above + // 3) The "oneSignal" signal we sent + // + // We'll most likely receive all three in one go from the server. We must + // update the owner of serviceName before we start processing the + // "oneSignal" signal. + + QTestEventLoop::instance().connect(&recv, SIGNAL(done()), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + QCOMPARE(recv.count, 1); +} + QString MyObject::path; QTEST_MAIN(tst_QDBusConnection) -- cgit v0.12 From 86ed592bba2a7ef23f5065397144c3915bdbdbd5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Nov 2010 19:20:25 +0100 Subject: Fix warnings with GCC 4.5: some cases are not part of the enum --- src/gui/painting/qpdf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index ba5d164..bd68d2a 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1390,7 +1390,7 @@ int QPdfBaseEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const void QPdfBaseEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value) { Q_D(QPdfBaseEngine); - switch (key) { + switch (int(key)) { case PPK_CollateCopies: d->collate = value.toBool(); break; @@ -1480,7 +1480,7 @@ QVariant QPdfBaseEngine::property(PrintEnginePropertyKey key) const Q_D(const QPdfBaseEngine); QVariant ret; - switch (key) { + switch (int(key)) { case PPK_CollateCopies: ret = d->collate; break; -- cgit v0.12 From c89ca078ba39780ebe556aff8fff6b92118a0a1d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Nov 2010 20:52:45 +0100 Subject: Fix "value not in enum" warning with GCC 4.5. QMetaType::Float is not a member of QVariant::Type. --- src/xmlpatterns/data/qatomicvalue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xmlpatterns/data/qatomicvalue.cpp b/src/xmlpatterns/data/qatomicvalue.cpp index ecc78bf..fc4cf2e 100644 --- a/src/xmlpatterns/data/qatomicvalue.cpp +++ b/src/xmlpatterns/data/qatomicvalue.cpp @@ -202,7 +202,7 @@ ItemType::Ptr AtomicValue::qtToXDMType(const QXmlItem &item) Q_ASSERT(item.isAtomicValue()); const QVariant v(item.toAtomicValue()); - switch(v.type()) + switch(int(v.type())) { case QVariant::Char: /* Fallthrough. */ -- cgit v0.12 From 0f49bba82a62546bb53d0a29a05a560fe8f1e293 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Nov 2010 21:11:42 +0100 Subject: Phonon: Fix "value not in enum" warning with GCC 4.5. QMetaType::Float is not a member of QVariant::Type. --- src/3rdparty/phonon/phonon/effectwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/phonon/phonon/effectwidget.cpp b/src/3rdparty/phonon/phonon/effectwidget.cpp index a2fe50f..edcbe1f 100644 --- a/src/3rdparty/phonon/phonon/effectwidget.cpp +++ b/src/3rdparty/phonon/phonon/effectwidget.cpp @@ -112,7 +112,7 @@ void EffectWidgetPrivate::autogenerateUi() #endif QWidget *control = 0; - switch (para.type()) { + switch (int(para.type())) { case QVariant::String: { QComboBox *cb = new QComboBox(q); -- cgit v0.12 From 2dea30e2b044f3f02727e28ca4ff73036406870b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Nov 2010 21:12:05 +0100 Subject: Phonon: Fix warning on casting from "false" to QFlags. Instead, return Features(); --- src/3rdparty/phonon/phonon/mediacontroller.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/phonon/phonon/mediacontroller.cpp b/src/3rdparty/phonon/phonon/mediacontroller.cpp index 59fd5c7..37af3f7 100644 --- a/src/3rdparty/phonon/phonon/mediacontroller.cpp +++ b/src/3rdparty/phonon/phonon/mediacontroller.cpp @@ -76,9 +76,9 @@ MediaController::~MediaController() MediaController::Features MediaController::supportedFeatures() const { if (!d || !d->media) { - return false; + return Features(); } - IFACE false; + IFACE Features(); Features ret; if (iface->hasInterface(AddonInterface::AngleInterface)) { ret |= Angles; -- cgit v0.12 From 7f63938ab866ec517e46bf1e6bc706e8b7f22d0a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Nov 2010 21:13:02 +0100 Subject: Phonon: Fix unused parameter warning --- src/3rdparty/phonon/phonon/globalconfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/phonon/phonon/globalconfig.cpp b/src/3rdparty/phonon/phonon/globalconfig.cpp index be751ce..f83ebc4 100644 --- a/src/3rdparty/phonon/phonon/globalconfig.cpp +++ b/src/3rdparty/phonon/phonon/globalconfig.cpp @@ -97,7 +97,7 @@ static void filter(ObjectDescriptionType type, BackendInterface *backendIface, Q static QList sortDevicesByCategoryPriority(const GlobalConfig *config, const QSettingsGroup *backendConfig, ObjectDescriptionType type, Phonon::Category category, QList &defaultList) { - Q_ASSERT(config); + Q_ASSERT(config); Q_UNUSED(config); Q_ASSERT(backendConfig); Q_ASSERT(type == AudioOutputDeviceType || type == AudioCaptureDeviceType); -- cgit v0.12 From 0b26c68a749ab74fe8e72fcbc49d314b9235b16d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Nov 2010 21:13:05 +0100 Subject: Phonon: Fix use of ASCII casting in the PulseAudio support. --- src/3rdparty/phonon/phonon/pulsesupport.cpp | 146 ++++++++++++++-------------- 1 file changed, 72 insertions(+), 74 deletions(-) diff --git a/src/3rdparty/phonon/phonon/pulsesupport.cpp b/src/3rdparty/phonon/phonon/pulsesupport.cpp index 642843f..b1ba196 100644 --- a/src/3rdparty/phonon/phonon/pulsesupport.cpp +++ b/src/3rdparty/phonon/phonon/pulsesupport.cpp @@ -56,7 +56,7 @@ static int debugLevel() { static int level = -1; if (level < 1) { level = 0; - QString pulseenv = qgetenv("PHONON_PULSEAUDIO_DEBUG"); + QByteArray pulseenv = qgetenv("PHONON_PULSEAUDIO_DEBUG"); int l = pulseenv.toInt(); if (l > 0) level = (l > 2 ? 2 : l); @@ -71,18 +71,18 @@ static void logMessage(const QString &message, int priority, QObject *obj) QString output; if (obj) { // Strip away namespace from className - QString className(obj->metaObject()->className()); + QByteArray className(obj->metaObject()->className()); int nameLength = className.length() - className.lastIndexOf(':') - 1; className = className.right(nameLength); output.sprintf("%s %s (%s %p)", message.toLatin1().constData(), obj->objectName().toLatin1().constData(), - className.toLatin1().constData(), obj); + className.constData(), obj); } else { output = message; } if (priority <= debugLevel()) { - qDebug() << QString("PulseSupport(%1): %2").arg(priority).arg(output); + qDebug() << QString::fromLatin1("PulseSupport(%1): %2").arg(priority).arg(output); } } } @@ -96,7 +96,7 @@ class AudioDevice : pulseName(name), pulseIndex(index) { properties["name"] = desc; - properties["description"] = ""; // We don't have descriptions (well we do, but we use them as the name!) + properties["description"] = QLatin1String(""); // We don't have descriptions (well we do, but we use them as the name!) properties["icon"] = icon; properties["available"] = (index != PA_INVALID_INDEX); properties["isAdvanced"] = false; // Nothing is advanced! @@ -158,8 +158,8 @@ static void createGenericDevices() s_outputDevices.clear(); s_outputDevicePriorities.clear(); index = s_deviceIndexCounter++; - s_outputDeviceIndexes.insert("sink:default", index); - s_outputDevices.insert(index, AudioDevice("sink:default", QObject::tr("PulseAudio Sound Server").toUtf8(), "audio-backend-pulseaudio", 0)); + s_outputDeviceIndexes.insert(QLatin1String("sink:default"), index); + s_outputDevices.insert(index, AudioDevice(QLatin1String("sink:default"), QObject::tr("PulseAudio Sound Server"), QLatin1String("audio-backend-pulseaudio"), 0)); for (int i = Phonon::NoCategory; i <= Phonon::LastCategory; ++i) { Phonon::Category cat = static_cast(i); s_outputDevicePriorities[cat].insert(0, index); @@ -169,8 +169,8 @@ static void createGenericDevices() s_captureDevices.clear(); s_captureDevicePriorities.clear(); index = s_deviceIndexCounter++; - s_captureDeviceIndexes.insert("source:default", index); - s_captureDevices.insert(index, AudioDevice("source:default", QObject::tr("PulseAudio Sound Server").toUtf8(), "audio-backend-pulseaudio", 0)); + s_captureDeviceIndexes.insert(QLatin1String("source:default"), index); + s_captureDevices.insert(index, AudioDevice(QLatin1String("source:default"), QObject::tr("PulseAudio Sound Server"), QLatin1String("audio-backend-pulseaudio"), 0)); for (int i = Phonon::NoCategory; i <= Phonon::LastCategory; ++i) { Phonon::Category cat = static_cast(i); s_captureDevicePriorities[cat].insert(0, index); @@ -397,7 +397,7 @@ void sink_input_cb(pa_context *c, const pa_sink_input_info *i, int eol, void *us if (pa_context_errno(c) == PA_ERR_NOENTITY) return; - logMessage(QString("Sink input callback failure")); + logMessage(QLatin1String("Sink input callback failure")); return; } @@ -409,8 +409,8 @@ void sink_input_cb(pa_context *c, const pa_sink_input_info *i, int eol, void *us // loop through (*i) and extract phonon->streamindex... const char *t; if ((t = pa_proplist_gets(i->proplist, "phonon.streamid"))) { - logMessage(QString("Found PulseAudio stream index %1 for Phonon Output Stream %2").arg(i->index).arg(t)); - s_outputStreamIndexMap[QString(t)] = i->index; + logMessage(QString::fromLatin1("Found PulseAudio stream index %1 for Phonon Output Stream %2").arg(i->index).arg(QLatin1String(t))); + s_outputStreamIndexMap[QLatin1String(t)] = i->index; // Find the sink's phonon index and notify whoever cares... if (PA_INVALID_INDEX != i->sink) { @@ -426,8 +426,8 @@ void sink_input_cb(pa_context *c, const pa_sink_input_info *i, int eol, void *us } if (found) { // OK so we just emit our signal - logMessage(QString("Letting the rest of phonon know about this")); - s_instance->emitUsingDevice(QString(t), device); + logMessage(QLatin1String("Letting the rest of phonon know about this")); + s_instance->emitUsingDevice(QLatin1String(t), device); } } } @@ -441,7 +441,7 @@ void source_output_cb(pa_context *c, const pa_source_output_info *i, int eol, vo if (pa_context_errno(c) == PA_ERR_NOENTITY) return; - logMessage(QString("Source output callback failure")); + logMessage(QLatin1String("Source output callback failure")); return; } @@ -453,8 +453,8 @@ void source_output_cb(pa_context *c, const pa_source_output_info *i, int eol, vo // loop through (*i) and extract phonon->streamindex... const char *t; if ((t = pa_proplist_gets(i->proplist, "phonon.streamid"))) { - logMessage(QString("Found PulseAudio stream index %1 for Phonon Capture Stream %2").arg(i->index).arg(t)); - s_captureStreamIndexMap[QString(t)] = i->index; + logMessage(QString::fromLatin1("Found PulseAudio stream index %1 for Phonon Capture Stream %2").arg(i->index).arg(QLatin1String(t))); + s_captureStreamIndexMap[QLatin1String(t)] = i->index; // Find the source's phonon index and notify whoever cares... if (PA_INVALID_INDEX != i->source) { @@ -470,8 +470,8 @@ void source_output_cb(pa_context *c, const pa_source_output_info *i, int eol, vo } if (found) { // OK so we just emit our signal - logMessage(QString("Letting the rest of phonon know about this")); - s_instance->emitUsingDevice(QString(t), device); + logMessage(QLatin1String("Letting the rest of phonon know about this")); + s_instance->emitUsingDevice(QLatin1String(t), device); } } } @@ -486,17 +486,17 @@ static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t QString phononid = s_outputStreamIndexMap.key(index); if (!phononid.isEmpty()) { if (s_outputStreamIndexMap.contains(phononid)) { - logMessage(QString("Phonon Output Stream %1 is gone at the PA end. Marking it as invalid in our cache as we may reuse it.").arg(phononid)); + logMessage(QString::fromLatin1("Phonon Output Stream %1 is gone at the PA end. Marking it as invalid in our cache as we may reuse it.").arg(phononid)); s_outputStreamIndexMap[phononid] = PA_INVALID_INDEX; } else { - logMessage(QString("Removing Phonon Output Stream %1 (it's gone!)").arg(phononid)); + logMessage(QString::fromLatin1("Removing Phonon Output Stream %1 (it's gone!)").arg(phononid)); s_outputStreamIndexMap.remove(phononid); } } } else { pa_operation *o; if (!(o = pa_context_get_sink_input_info(c, index, sink_input_cb, NULL))) { - logMessage(QString("pa_context_get_sink_input_info() failed")); + logMessage(QLatin1String("pa_context_get_sink_input_info() failed")); return; } pa_operation_unref(o); @@ -508,17 +508,17 @@ static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t QString phononid = s_captureStreamIndexMap.key(index); if (!phononid.isEmpty()) { if (s_captureStreamIndexMap.contains(phononid)) { - logMessage(QString("Phonon Capture Stream %1 is gone at the PA end. Marking it as invalid in our cache as we may reuse it.").arg(phononid)); + logMessage(QString::fromLatin1("Phonon Capture Stream %1 is gone at the PA end. Marking it as invalid in our cache as we may reuse it.").arg(phononid)); s_captureStreamIndexMap[phononid] = PA_INVALID_INDEX; } else { - logMessage(QString("Removing Phonon Capture Stream %1 (it's gone!)").arg(phononid)); + logMessage(QString::fromLatin1("Removing Phonon Capture Stream %1 (it's gone!)").arg(phononid)); s_captureStreamIndexMap.remove(phononid); } } } else { pa_operation *o; if (!(o = pa_context_get_source_output_info(c, index, source_output_cb, NULL))) { - logMessage(QString("pa_context_get_sink_input_info() failed")); + logMessage(QLatin1String("pa_context_get_sink_input_info() failed")); return; } pa_operation_unref(o); @@ -528,29 +528,27 @@ static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t } -static const char* statename(pa_context_state_t state) +static QString statename(pa_context_state_t state) { switch (state) { - case PA_CONTEXT_UNCONNECTED: return "Unconnected"; - case PA_CONTEXT_CONNECTING: return "Connecting"; - case PA_CONTEXT_AUTHORIZING: return "Authorizing"; - case PA_CONTEXT_SETTING_NAME: return "Setting Name"; - case PA_CONTEXT_READY: return "Ready"; - case PA_CONTEXT_FAILED: return "Failed"; - case PA_CONTEXT_TERMINATED: return "Terminated"; + case PA_CONTEXT_UNCONNECTED: return QLatin1String("Unconnected"); + case PA_CONTEXT_CONNECTING: return QLatin1String("Connecting"); + case PA_CONTEXT_AUTHORIZING: return QLatin1String("Authorizing"); + case PA_CONTEXT_SETTING_NAME: return QLatin1String("Setting Name"); + case PA_CONTEXT_READY: return QLatin1String("Ready"); + case PA_CONTEXT_FAILED: return QLatin1String("Failed"); + case PA_CONTEXT_TERMINATED: return QLatin1String("Terminated"); } - static QString unknown; - unknown = QString("Unknown state: %0").arg(state); - return unknown.toAscii().constData(); + return QString::fromLatin1("Unknown state: %0").arg(state); } static void context_state_callback(pa_context *c, void *) { Q_ASSERT(c); - logMessage(QString("context_state_callback %1").arg(statename(pa_context_get_state(c)))); + logMessage(QString::fromLatin1("context_state_callback %1").arg(statename(pa_context_get_state(c)))); pa_context_state_t state = pa_context_get_state(c); if (state == PA_CONTEXT_READY) { // We've connected to PA, so it is active @@ -566,7 +564,7 @@ static void context_state_callback(pa_context *c, void *) if (!(o = pa_context_subscribe(c, (pa_subscription_mask_t) (PA_SUBSCRIPTION_MASK_SINK_INPUT| PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT), NULL, NULL))) { - logMessage(QString("pa_context_subscribe() failed")); + logMessage(QLatin1String("pa_context_subscribe() failed")); return; } pa_operation_unref(o); @@ -639,27 +637,27 @@ PulseSupport::PulseSupport() { #ifdef HAVE_PULSEAUDIO // Initialise our map (is there a better way to do this?) - s_roleCategoryMap["none"] = Phonon::NoCategory; - s_roleCategoryMap["video"] = Phonon::VideoCategory; - s_roleCategoryMap["music"] = Phonon::MusicCategory; - s_roleCategoryMap["game"] = Phonon::GameCategory; - s_roleCategoryMap["event"] = Phonon::NotificationCategory; - s_roleCategoryMap["phone"] = Phonon::CommunicationCategory; - //s_roleCategoryMap["animation"]; // No Mapping - //s_roleCategoryMap["production"]; // No Mapping - s_roleCategoryMap["a11y"] = Phonon::AccessibilityCategory; + s_roleCategoryMap[QLatin1String("none")] = Phonon::NoCategory; + s_roleCategoryMap[QLatin1String("video")] = Phonon::VideoCategory; + s_roleCategoryMap[QLatin1String("music")] = Phonon::MusicCategory; + s_roleCategoryMap[QLatin1String("game")] = Phonon::GameCategory; + s_roleCategoryMap[QLatin1String("event")] = Phonon::NotificationCategory; + s_roleCategoryMap[QLatin1String("phone")] = Phonon::CommunicationCategory; + //s_roleCategoryMap[QLatin1String("animation")]; // No Mapping + //s_roleCategoryMap[QLatin1String("production")]; // No Mapping + s_roleCategoryMap[QLatin1String("a11y")] = Phonon::AccessibilityCategory; // To allow for easy debugging, give an easy way to disable this pulseaudio check - QString pulseenv = qgetenv("PHONON_PULSEAUDIO_DISABLE"); + QByteArray pulseenv = qgetenv("PHONON_PULSEAUDIO_DISABLE"); if (pulseenv.toInt()) { - logMessage("PulseAudio support disabled: PHONON_PULSEAUDIO_DISABLE is set"); + logMessage(QLatin1String("PulseAudio support disabled: PHONON_PULSEAUDIO_DISABLE is set")); return; } // We require a glib event loop - if (QLatin1String(QAbstractEventDispatcher::instance()->metaObject()->className()) - != "QGuiEventDispatcherGlib") { - logMessage("Disabling PulseAudio integration for lack of GLib event loop."); + if (strcmp(QAbstractEventDispatcher::instance()->metaObject()->className(), + "QGuiEventDispatcherGlib") != 0) { + logMessage(QLatin1String("Disabling PulseAudio integration for lack of GLib event loop.")); return; } @@ -667,21 +665,21 @@ PulseSupport::PulseSupport() // use a fully async integrated mainloop method to connect and get proper support. pa_mainloop *p_test_mainloop; if (!(p_test_mainloop = pa_mainloop_new())) { - logMessage("PulseAudio support disabled: Unable to create mainloop"); + logMessage(QLatin1String("PulseAudio support disabled: Unable to create mainloop")); return; } pa_context *p_test_context; if (!(p_test_context = pa_context_new(pa_mainloop_get_api(p_test_mainloop), "libphonon-probe"))) { - logMessage("PulseAudio support disabled: Unable to create context"); + logMessage(QLatin1String("PulseAudio support disabled: Unable to create context")); pa_mainloop_free(p_test_mainloop); return; } - logMessage("Probing for PulseAudio..."); + logMessage(QLatin1String("Probing for PulseAudio...")); // (cg) Convert to PA_CONTEXT_NOFLAGS when PulseAudio 0.9.19 is required if (pa_context_connect(p_test_context, NULL, static_cast(0), NULL) < 0) { - logMessage(QString("PulseAudio support disabled: %1").arg(pa_strerror(pa_context_errno(p_test_context)))); + logMessage(QString::fromLatin1("PulseAudio support disabled: %1").arg(QString::fromLocal8Bit(pa_strerror(pa_context_errno(p_test_context))))); pa_context_disconnect(p_test_context); pa_context_unref(p_test_context); pa_mainloop_free(p_test_mainloop); @@ -693,7 +691,7 @@ PulseSupport::PulseSupport() pa_mainloop_iterate(p_test_mainloop, 1, NULL); if (!PA_CONTEXT_IS_GOOD(pa_context_get_state(p_test_context))) { - logMessage("PulseAudio probe complete."); + logMessage(QLatin1String("PulseAudio probe complete.")); break; } } @@ -702,12 +700,12 @@ PulseSupport::PulseSupport() pa_mainloop_free(p_test_mainloop); if (!s_pulseActive) { - logMessage("PulseAudio support is not available."); + logMessage(QLatin1String("PulseAudio support is not available.")); return; } // If we're still here, PA is available. - logMessage("PulseAudio support enabled"); + logMessage(QLatin1String("PulseAudio support enabled")); // Now we connect for real using a proper main loop that we can forget // all about processing. @@ -856,7 +854,7 @@ static void setDevicePriority(Category category, QStringList list) if (role.isEmpty()) return; - logMessage(QString("Reindexing %1: %2").arg(role).arg(list.join(", "))); + logMessage(QString::fromLatin1("Reindexing %1: %2").arg(role).arg(list.join(QLatin1String(", ")))); char **devices; devices = pa_xnew(char *, list.size()+1); @@ -926,7 +924,7 @@ void PulseSupport::setStreamPropList(Category category, QString streamUuid) if (role.isEmpty()) return; - logMessage(QString("Setting role to %1 for streamindex %2").arg(role).arg(streamUuid)); + logMessage(QString::fromLatin1("Setting role to %1 for streamindex %2").arg(role).arg(streamUuid)); setenv("PULSE_PROP_media.role", role.toLatin1().constData(), 1); setenv("PULSE_PROP_phonon.streamid", streamUuid.toLatin1().constData(), 1); #endif @@ -952,30 +950,30 @@ bool PulseSupport::setOutputDevice(QString streamUuid, int device) { return true; if (!s_outputDevices.contains(device)) { - logMessage(QString("Attempting to set Output Device for invalid device id %1.").arg(device)); + logMessage(QString::fromLatin1("Attempting to set Output Device for invalid device id %1.").arg(device)); return false; } const QVariant var = s_outputDevices[device].properties["name"]; - logMessage(QString("Attempting to set Output Device to '%1' for Output Stream %2").arg(var.toString()).arg(streamUuid)); + logMessage(QString::fromLatin1("Attempting to set Output Device to '%1' for Output Stream %2").arg(var.toString()).arg(streamUuid)); // Attempt to look up the pulse stream index. if (s_outputStreamIndexMap.contains(streamUuid) && s_outputStreamIndexMap[streamUuid] != PA_INVALID_INDEX) { - logMessage(QString("... Found in map. Moving now")); + logMessage(QLatin1String("... Found in map. Moving now")); uint32_t pulse_device_index = s_outputDevices[device].pulseIndex; uint32_t pulse_stream_index = s_outputStreamIndexMap[streamUuid]; - logMessage(QString("Moving Pulse Sink Input %1 to '%2' (Pulse Sink %3)").arg(pulse_stream_index).arg(var.toString()).arg(pulse_device_index)); + logMessage(QString::fromLatin1("Moving Pulse Sink Input %1 to '%2' (Pulse Sink %3)").arg(pulse_stream_index).arg(var.toString()).arg(pulse_device_index)); /// @todo Find a way to move the stream without saving it... We don't want to pollute the stream restore db. pa_operation* o; if (!(o = pa_context_move_sink_input_by_index(s_context, pulse_stream_index, pulse_device_index, NULL, NULL))) { - logMessage(QString("pa_context_move_sink_input_by_index() failed")); + logMessage(QLatin1String("pa_context_move_sink_input_by_index() failed")); return false; } pa_operation_unref(o); } else { - logMessage(QString("... Not found in map. We will be notified of the device when the stream appears and we can process any moves needed then")); + logMessage(QLatin1String("... Not found in map. We will be notified of the device when the stream appears and we can process any moves needed then")); } return true; #endif @@ -991,30 +989,30 @@ bool PulseSupport::setCaptureDevice(QString streamUuid, int device) { return true; if (!s_captureDevices.contains(device)) { - logMessage(QString("Attempting to set Capture Device for invalid device id %1.").arg(device)); + logMessage(QString::fromLatin1("Attempting to set Capture Device for invalid device id %1.").arg(device)); return false; } const QVariant var = s_captureDevices[device].properties["name"]; - logMessage(QString("Attempting to set Capture Device to '%1' for Capture Stream %2").arg(var.toString()).arg(streamUuid)); + logMessage(QString::fromLatin1("Attempting to set Capture Device to '%1' for Capture Stream %2").arg(var.toString()).arg(streamUuid)); // Attempt to look up the pulse stream index. if (s_captureStreamIndexMap.contains(streamUuid) && s_captureStreamIndexMap[streamUuid] == PA_INVALID_INDEX) { - logMessage(QString("... Found in map. Moving now")); + logMessage(QString::fromLatin1("... Found in map. Moving now")); uint32_t pulse_device_index = s_captureDevices[device].pulseIndex; uint32_t pulse_stream_index = s_captureStreamIndexMap[streamUuid]; - logMessage(QString("Moving Pulse Source Output %1 to '%2' (Pulse Sink %3)").arg(pulse_stream_index).arg(var.toString()).arg(pulse_device_index)); + logMessage(QString::fromLatin1("Moving Pulse Source Output %1 to '%2' (Pulse Sink %3)").arg(pulse_stream_index).arg(var.toString()).arg(pulse_device_index)); /// @todo Find a way to move the stream without saving it... We don't want to pollute the stream restore db. pa_operation* o; if (!(o = pa_context_move_source_output_by_index(s_context, pulse_stream_index, pulse_device_index, NULL, NULL))) { - logMessage(QString("pa_context_move_source_output_by_index() failed")); + logMessage(QString::fromLatin1("pa_context_move_source_output_by_index() failed")); return false; } pa_operation_unref(o); } else { - logMessage(QString("... Not found in map. We will be notified of the device when the stream appears and we can process any moves needed then")); + logMessage(QString::fromLatin1("... Not found in map. We will be notified of the device when the stream appears and we can process any moves needed then")); } return true; #endif @@ -1025,7 +1023,7 @@ void PulseSupport::clearStreamCache(QString streamUuid) { Q_UNUSED(streamUuid); return; #else - logMessage(QString("Clearing stream cache for stream %1").arg(streamUuid)); + logMessage(QString::fromLatin1("Clearing stream cache for stream %1").arg(streamUuid)); s_outputStreamIndexMap.remove(streamUuid); s_captureStreamIndexMap.remove(streamUuid); #endif -- cgit v0.12 From 2534805c3fa3dafe4fad7c35687b105c6b01fd97 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 26 Nov 2010 21:17:02 +0100 Subject: Fix warning about use of uninitialised variable --- src/network/ssl/qsslcertificate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index a3ea555..275c7be 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -716,7 +716,7 @@ QSslCertificate QSslCertificatePrivate::QSslCertificate_from_X509(X509 *x509) static bool matchLineFeed(const QByteArray &pem, int *offset) { - char ch; + char ch = 0; // ignore extra whitespace at the end of the line while (*offset < pem.size() && (ch = pem.at(*offset)) == ' ') -- cgit v0.12 From d54fe278bcbba0018bbed9a09abc35b628b0024b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Nov 2010 21:20:31 +0100 Subject: Fix warning about mixing integral with non-integral type in ?: --- src/gui/dialogs/qdialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp index b7a0026..fbdc522 100644 --- a/src/gui/dialogs/qdialog.cpp +++ b/src/gui/dialogs/qdialog.cpp @@ -282,8 +282,8 @@ QDialog::QDialog(QWidget *parent, Qt::WindowFlags f) QDialog::QDialog(QWidget *parent, const char *name, bool modal, Qt::WindowFlags f) : QWidget(*new QDialogPrivate, parent, f - | QFlag(modal ? Qt::WShowModal : 0) - | QFlag((f & Qt::WindowType_Mask) == 0 ? Qt::Dialog : 0) + | QFlag(modal ? Qt::WShowModal : Qt::WindowType(0)) + | QFlag((f & Qt::WindowType_Mask) == 0 ? Qt::Dialog : Qt::WindowType(0)) ) { setObjectName(QString::fromAscii(name)); -- cgit v0.12 From b284975435f80eba7bf6d1edd21987dcee134e86 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Nov 2010 21:23:33 +0100 Subject: Fix silly "will be initialised after" warning. --- src/declarative/util/qdeclarativepixmapcache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp index a07b1bb..380d9bc 100644 --- a/src/declarative/util/qdeclarativepixmapcache.cpp +++ b/src/declarative/util/qdeclarativepixmapcache.cpp @@ -684,7 +684,7 @@ void QDeclarativePixmapStore::timerEvent(QTimerEvent *) } QDeclarativePixmapReply::QDeclarativePixmapReply(QDeclarativePixmapData *d) -: data(d), reader(0), loading(false), redirectCount(0), requestSize(d->requestSize) +: data(d), reader(0), requestSize(d->requestSize), loading(false), redirectCount(0) { if (finishedIndex == -1) { finishedIndex = QDeclarativePixmapReply::staticMetaObject.indexOfSignal("finished()"); -- cgit v0.12 From dc23fd546163edb7ff4395f44217b5cb2600004a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 26 Nov 2010 18:41:07 +0100 Subject: Fix warnings related to unused variables. Just add some Q_UNUSED for parameters or remove the variable we don't need for the others. Reviewed-by: Trust Me --- src/declarative/qml/qdeclarativeengine.cpp | 2 ++ src/declarative/qml/qdeclarativepropertycache.cpp | 1 - src/gui/styles/qstyle.cpp | 2 ++ src/gui/styles/qstyleoption.cpp | 4 ++++ src/opengl/qgl_x11egl.cpp | 1 - src/opengl/qglpixelbuffer_egl.cpp | 1 - src/plugins/bearer/connman/qconnmanservice_linux.cpp | 2 -- tools/shared/windows/registry.cpp | 3 +++ 8 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 1160ed8..c646302 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -2232,6 +2232,8 @@ bool QDeclarative_isFileCaseCorrect(const QString &fileName) if (a != c) return false; } +#else + Q_UNUSED(fileName); #endif return true; diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index 0adcdbd..dd9a224 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -320,7 +320,6 @@ void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaOb { Q_ASSERT(engine); Q_ASSERT(metaObject); - QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); clear(); diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp index 3ebfab2..be8f794 100644 --- a/src/gui/styles/qstyle.cpp +++ b/src/gui/styles/qstyle.cpp @@ -2456,6 +2456,8 @@ QDebug operator<<(QDebug debug, QStyle::State state) qSort(states); debug << states.join(QLatin1String(" | ")); debug << ')'; +#else + Q_UNUSED(state); #endif return debug; } diff --git a/src/gui/styles/qstyleoption.cpp b/src/gui/styles/qstyleoption.cpp index 4780edf..05ca793 100644 --- a/src/gui/styles/qstyleoption.cpp +++ b/src/gui/styles/qstyleoption.cpp @@ -5483,6 +5483,8 @@ QDebug operator<<(QDebug debug, const QStyleOption::OptionType &optionType) case QStyleOption::SO_GraphicsItem: debug << "SO_GraphicsItem"; break; } +#else + Q_UNUSED(optionType); #endif return debug; } @@ -5496,6 +5498,8 @@ QDebug operator<<(QDebug debug, const QStyleOption &option) debug << ',' << option.state; debug << ',' << option.rect; debug << ')'; +#else + Q_UNUSED(option); #endif return debug; } diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index d33ea56..144d140 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -97,7 +97,6 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) XVisualInfo visualInfo; XVisualInfo *vi; int numVisuals; - EGLint id = 0; visualInfo.visualid = QEgl::getCompatibleVisualId(config); vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals); diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp index 0b94f5a..2d9f6f1 100644 --- a/src/opengl/qglpixelbuffer_egl.cpp +++ b/src/opengl/qglpixelbuffer_egl.cpp @@ -74,7 +74,6 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge // Use the same configuration as the widget we are sharing with. ctx->setConfig(shareContext->config()); #if QGL_RENDER_TEXTURE - EGLint value = EGL_FALSE; if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGBA) == EGL_TRUE) textureFormat = EGL_TEXTURE_RGBA; else if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGB) == EGL_TRUE) diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp index 952a444..0545422 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp +++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp @@ -216,7 +216,6 @@ void QConnmanManagerInterface::registerCounter(const QString &path, quint32 inte { QDBusReply > reply = this->call(QLatin1String("RegisterCounter"), QVariant::fromValue(path), QVariant::fromValue(interval)); - bool ok = true; if(reply.error().type() == QDBusError::InvalidArgs) { qWarning() << reply.error().message(); } @@ -225,7 +224,6 @@ void QConnmanManagerInterface::registerCounter(const QString &path, quint32 inte void QConnmanManagerInterface::unregisterCounter(const QString &path) { QDBusReply > reply = this->call(QLatin1String("UnregisterCounter"), QVariant::fromValue(path)); - bool ok = true; if(reply.error().type() == QDBusError::InvalidArgs) { qWarning() << reply.error().message(); } diff --git a/tools/shared/windows/registry.cpp b/tools/shared/windows/registry.cpp index 48e9ae6..f520910 100644 --- a/tools/shared/windows/registry.cpp +++ b/tools/shared/windows/registry.cpp @@ -157,6 +157,9 @@ QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey) } RegCloseKey(handle); +#else + Q_UNUSED(parentHandle); + Q_UNUSED(rSubkey) #endif return result; -- cgit v0.12 From 20da7afb4c575001b7373554ebf7e7fb434a2942 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 26 Nov 2010 20:26:58 +0100 Subject: Fix warning about address of a function being constant. In OpenGL ES 2, these functions are always expected to be present, so the address can never be zero. So only test for the function being found if we tried to find it dynamicaly. --- src/opengl/qgl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index ed9753e..18f1203 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2095,7 +2095,9 @@ void QGLContextPrivate::cleanup() void QGLContextPrivate::setVertexAttribArrayEnabled(int arrayIndex, bool enabled) { Q_ASSERT(arrayIndex < QT_GL_VERTEX_ARRAY_TRACKED_COUNT); +#ifdef glEnableVertexAttribArray Q_ASSERT(glEnableVertexAttribArray); +#endif if (vertexAttributeArraysEnabledState[arrayIndex] && !enabled) glDisableVertexAttribArray(arrayIndex); @@ -2108,7 +2110,9 @@ void QGLContextPrivate::setVertexAttribArrayEnabled(int arrayIndex, bool enabled void QGLContextPrivate::syncGlState() { +#ifdef glEnableVertexAttribArray Q_ASSERT(glEnableVertexAttribArray); +#endif for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) { if (vertexAttributeArraysEnabledState[i]) glEnableVertexAttribArray(i); -- cgit v0.12 From 3251c5023c184466e8199c8999aa6e332eb98534 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 26 Nov 2010 20:28:23 +0100 Subject: Fix warning about %x parameter type mismatch in EGL --- src/opengl/qgl_x11egl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 144d140..75dd1b6 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -345,7 +345,7 @@ void QGLWidgetPrivate::recreateEglSurface() // old surface before re-creating a new one. Note: This should not be the case as the // surface should be deleted before the old window id. if (glcx->d_func()->eglSurface != EGL_NO_SURFACE && (currentId != eglSurfaceWindowId)) { - qWarning("EGL surface for deleted window %x was not destroyed", eglSurfaceWindowId); + qWarning("EGL surface for deleted window %x was not destroyed", uint(eglSurfaceWindowId)); glcx->d_func()->destroyEglSurfaceForDevice(); } -- cgit v0.12 From d89985ce546f63f4e563ccc54951957d2f33c5ec Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Nov 2010 19:21:17 +0100 Subject: Fix strict-aliasing violation warning. Strict aliasing is violated here, so just silence the compiler (GCC) by using an extension. --- src/gui/text/qtextformat.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 46db253..fdbb680 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -265,10 +265,18 @@ private: friend QDataStream &operator>>(QDataStream &, QTextFormat &); }; -// this is only safe if sizeof(int) == sizeof(float) +// this is only safe because sizeof(int) == sizeof(float) static inline uint hash(float d) { +#ifdef Q_CC_GNU + // this is a GCC extension and isn't guaranteed to work in other compilers + // the reinterpret_cast below generates a strict-aliasing warning with GCC + union { float f; uint u; } cvt; + cvt.f = d; + return cvt.u; +#else return reinterpret_cast(d); +#endif } static inline uint hash(const QColor &color) -- cgit v0.12 From d910fa67be7981714bfc854a7b6cc10e0ecfb858 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 26 Nov 2010 20:55:49 +0100 Subject: Fix warning about uninitialised varibale. This variable cannot be dereferenced when it's zero, but let's silence the compiler warning (GCC 4.4 on ARM). --- src/plugins/bearer/connman/qconnmanengine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp index 184ceb4..7ac86b3 100644 --- a/src/plugins/bearer/connman/qconnmanengine.cpp +++ b/src/plugins/bearer/connman/qconnmanengine.cpp @@ -726,6 +726,7 @@ void QConnmanEngine::addNetworkConfiguration(const QString &networkPath) if(servicePath.isEmpty()) { id = QString::number(qHash(networkPath)); + serv = 0; // ### FIXME } else { id = QString::number(qHash(servicePath)); serv = new QConnmanServiceInterface(servicePath,this); -- cgit v0.12 From a22ecab92bacc57d0a788eb9713f442e95468fd3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 28 Nov 2010 12:46:00 +0100 Subject: Remove the FIXME, it's fixed --- src/plugins/bearer/connman/qconnmanengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp index 7ac86b3..7f3501e 100644 --- a/src/plugins/bearer/connman/qconnmanengine.cpp +++ b/src/plugins/bearer/connman/qconnmanengine.cpp @@ -726,7 +726,7 @@ void QConnmanEngine::addNetworkConfiguration(const QString &networkPath) if(servicePath.isEmpty()) { id = QString::number(qHash(networkPath)); - serv = 0; // ### FIXME + serv = 0; } else { id = QString::number(qHash(servicePath)); serv = new QConnmanServiceInterface(servicePath,this); -- cgit v0.12 From 7dafb5ca875a714ed9a1ced1a44ca536b31a44de Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 22 Oct 2010 15:29:41 +0200 Subject: Autotest: fix mistake in verifying pointers Don't assume that pointers on the heap appear always on the positive half of the addressing space. --- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 6b4904f..a05aa97 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -283,8 +283,8 @@ void tst_QSharedPointer::operators() QSharedPointer p1; QSharedPointer p2(new char); qptrdiff diff = p2.data() - p1.data(); - Q_ASSERT(p1.data() < p2.data()); - Q_ASSERT(diff > 0); + Q_ASSERT(p1.data() != p2.data()); + Q_ASSERT(diff != 0); // operator- QCOMPARE(p2 - p1.data(), diff); -- cgit v0.12 From 2fd00b200e5e1b13effdf8773386230891127dbe Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Sun, 28 Nov 2010 21:28:01 +0100 Subject: print out which GLSL shader that failed compilation for better debugging --- src/opengl/qglshaderprogram.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 74382b0..1f39884 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -260,10 +260,27 @@ bool QGLShaderPrivate::compile(QGLShader *q) glGetShaderInfoLog(shader, value, &len, logbuf); log = QString::fromLatin1(logbuf); QString name = q->objectName(); + + char *types[] = { + "Fragment", + "Vertex", + "Geometry", + "" + }; + + char *type = types[3]; + if (shaderType == QGLShader::Fragment) + type = types[0]; + else if (shaderType == QGLShader::Vertex) + type = types[1]; + else if (shaderType == QGLShader::Geometry) + type = types[2]; + if (name.isEmpty()) - qWarning() << "QGLShader::compile:" << log; + qWarning("QGLShader::compile(%s): %s", type, qPrintable(log)); else - qWarning() << "QGLShader::compile[" << name << "]:" << log; + qWarning("QGLShader::compile(%s)[%s]: %s", type, qPrintable(name), qPrintable(log)); + delete [] logbuf; } return compiled; -- cgit v0.12 From b604dc0b77a3a4b9001d682925006a3438e00cb7 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Thu, 25 Nov 2010 10:56:20 +1000 Subject: Move KeyNavigation example to snippets, plus some doc rewording --- doc/src/snippets/declarative/keynavigation.qml | 45 ++++++++++++++ src/declarative/graphicsitems/qdeclarativeitem.cpp | 72 +++++++--------------- 2 files changed, 66 insertions(+), 51 deletions(-) create mode 100644 doc/src/snippets/declarative/keynavigation.qml diff --git a/doc/src/snippets/declarative/keynavigation.qml b/doc/src/snippets/declarative/keynavigation.qml new file mode 100644 index 0000000..d72bb3a --- /dev/null +++ b/doc/src/snippets/declarative/keynavigation.qml @@ -0,0 +1,45 @@ +//![0] +import QtQuick 1.0 + +Grid { + width: 100; height: 100 + columns: 2 + + Rectangle { + id: topLeft + width: 50; height: 50 + color: focus ? "red" : "lightgray" + focus: true + + KeyNavigation.right: topRight + KeyNavigation.down: bottomLeft + } + + Rectangle { + id: topRight + width: 50; height: 50 + color: focus ? "red" : "lightgray" + + KeyNavigation.left: topLeft + KeyNavigation.down: bottomRight + } + + Rectangle { + id: bottomLeft + width: 50; height: 50 + color: focus ? "red" : "lightgray" + + KeyNavigation.right: bottomRight + KeyNavigation.up: topLeft + } + + Rectangle { + id: bottomRight + width: 50; height: 50 + color: focus ? "red" : "lightgray" + + KeyNavigation.left: bottomLeft + KeyNavigation.up: topRight + } +} +//![0] diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index e0df751..9d6fe12 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -421,58 +421,28 @@ void QDeclarativeItemKeyFilter::componentComplete() \since 4.7 \brief The KeyNavigation attached property supports key navigation by arrow keys. - It is common in key-based UIs to use arrow keys to navigate - between focused items. The KeyNavigation property provides a - convenient way of specifying which item will gain focus - when an arrow key is pressed. The following example provides - key navigation for a 2x2 grid of items. - - \code - Grid { - columns: 2 - width: 100; height: 100 - Rectangle { - id: item1 - focus: true - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.right: item2 - KeyNavigation.down: item3 - } - Rectangle { - id: item2 - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.left: item1 - KeyNavigation.down: item4 - } - Rectangle { - id: item3 - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.right: item4 - KeyNavigation.up: item1 - } - Rectangle { - id: item4 - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.left: item3 - KeyNavigation.up: item2 - } - } - \endcode + Key-based user interfaces commonly allow the use of arrow keys to navigate between + focusable items. The KeyNavigation attached property enables this behavior by providing a + convenient way to specify the item that should gain focus when an arrow or tab key is pressed. + + The following example provides key navigation for a 2x2 grid of items: - By default KeyNavigation receives key events after the item it is attached to. - If the item accepts an arrow key event, the KeyNavigation - attached property will not receive an event for that key. Setting the - \l priority property to KeyNavigation.BeforeItem allows handling - of the key events before normal item processing. + \snippet doc/src/snippets/declarative/keynavigation.qml 0 - If an item has been set for a direction and the KeyNavigation - attached property receives the corresponding - key press and release events, the events will be accepted by - KeyNavigation and will not propagate any further. + The top-left item initially receives focus by setting \l {Item::}{focus} to + \c true. When an arrow key is pressed, the focus will move to the + appropriate item, as defined by the value that has been set for + the KeyNavigation \l left, \l right, \l up or \l down properties. + + Note that if a KeyNavigation attached property receives the key press and release + events for a requested arrow or tab key, the event is accepted and does not + propagate any further. + + By default, KeyNavigation receives key events after the item to which it is attached. + If the item accepts the key event, the KeyNavigation attached property will not + receive an event for that key. Setting the \l priority property to + \c KeyNavigation.BeforeItem allows the event to be used for key navigation + before the item, rather than after. \sa {Keys}{Keys attached property} */ @@ -599,7 +569,7 @@ void QDeclarativeKeyNavigationAttached::setBacktab(QDeclarativeItem *i) \list \o KeyNavigation.BeforeItem - process the key events before normal - item key processing. If the event is accepted it will not + item key processing. If the event is used for key navigation, it will be accepted and will not be passed on to the item. \o KeyNavigation.AfterItem (default) - process the key events after normal item key handling. If the item accepts the key event it will not be -- cgit v0.12 From 312604c85b1e6a6fc6de505bac86848936f81edd Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 29 Nov 2010 18:41:24 +1000 Subject: Improve consistency in handling of aliases, bindings and value types Task-number: QTBUG-13719 --- src/declarative/qml/qdeclarativebinding.cpp | 337 +++++++++++---------- src/declarative/qml/qdeclarativebinding_p.h | 12 +- .../qml/qdeclarativecompiledbindings.cpp | 14 - src/declarative/qml/qdeclarativecompiler.cpp | 119 ++++++-- src/declarative/qml/qdeclarativecompiler_p.h | 1 + src/declarative/qml/qdeclarativecomponent.cpp | 5 +- src/declarative/qml/qdeclarativeinstruction.cpp | 7 +- src/declarative/qml/qdeclarativeinstruction_p.h | 2 + src/declarative/qml/qdeclarativeparser.cpp | 4 +- src/declarative/qml/qdeclarativeparser_p.h | 3 + src/declarative/qml/qdeclarativeproperty.cpp | 209 +++++++++++-- src/declarative/qml/qdeclarativeproperty_p.h | 8 +- src/declarative/qml/qdeclarativepropertycache_p.h | 1 + src/declarative/qml/qdeclarativevaluetype.cpp | 46 ++- src/declarative/qml/qdeclarativevme.cpp | 38 ++- src/declarative/qml/qdeclarativevmemetaobject.cpp | 47 ++- src/declarative/qml/qdeclarativevmemetaobject_p.h | 2 + .../data/AliasBindingsAssignCorrectlyType.qml | 9 + .../data/AliasBindingsOverrideTargetType.qml | 14 + .../data/AliasBindingsOverrideTargetType3.qml | 9 + .../data/aliasBindingsAssignCorrectly.qml | 59 ++++ .../data/aliasBindingsOverrideTarget.2.qml | 29 ++ .../data/aliasBindingsOverrideTarget.3.qml | 24 ++ .../data/aliasBindingsOverrideTarget.qml | 28 ++ .../data/aliasWritesOverrideBindings.2.qml | 29 ++ .../data/aliasWritesOverrideBindings.3.qml | 23 ++ .../data/aliasWritesOverrideBindings.qml | 23 ++ .../data/writeRemovesBinding.qml | 46 +++ .../tst_qdeclarativeecmascript.cpp | 95 ++++++ .../tst_qdeclarativeinstruction.cpp | 5 +- .../data/aliasPropertyBindings.qml | 19 ++ .../tst_qdeclarativeproperty.cpp | 69 +++++ .../data/BindingsSpliceCorrectlyType.qml | 7 + .../data/BindingsSpliceCorrectlyType4.qml | 7 + .../data/BindingsSpliceCorrectlyType5.qml | 7 + .../data/bindingsSpliceCorrectly.1.qml | 29 ++ .../data/bindingsSpliceCorrectly.2.qml | 31 ++ .../data/bindingsSpliceCorrectly.3.qml | 36 +++ .../data/bindingsSpliceCorrectly.4.qml | 27 ++ .../data/bindingsSpliceCorrectly.5.qml | 27 ++ .../tst_qdeclarativevaluetypes.cpp | 56 ++++ 41 files changed, 1305 insertions(+), 258 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsAssignCorrectlyType.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType3.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsAssignCorrectly.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.3.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.3.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/writeRemovesBinding.qml create mode 100644 tests/auto/declarative/qdeclarativeproperty/data/aliasPropertyBindings.qml create mode 100644 tests/auto/declarative/qdeclarativevaluetypes/data/BindingsSpliceCorrectlyType.qml create mode 100644 tests/auto/declarative/qdeclarativevaluetypes/data/BindingsSpliceCorrectlyType4.qml create mode 100644 tests/auto/declarative/qdeclarativevaluetypes/data/BindingsSpliceCorrectlyType5.qml create mode 100644 tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.1.qml create mode 100644 tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.2.qml create mode 100644 tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.3.qml create mode 100644 tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.4.qml create mode 100644 tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.5.qml diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index cb6ad8c..a7fbf44 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -55,6 +55,158 @@ QT_BEGIN_NAMESPACE +QDeclarativeAbstractBinding::QDeclarativeAbstractBinding() +: m_object(0), m_propertyIndex(-1), m_mePtr(0), m_prevBinding(0), m_nextBinding(0) +{ +} + +QDeclarativeAbstractBinding::~QDeclarativeAbstractBinding() +{ + Q_ASSERT(m_prevBinding == 0); + Q_ASSERT(m_mePtr == 0); +} + +/*! +Destroy the binding. Use this instead of calling delete. + +Bindings are free to implement their own memory management, so the delete operator is not +necessarily safe. The default implementation clears the binding, removes it from the object +and calls delete. +*/ +void QDeclarativeAbstractBinding::destroy() +{ + removeFromObject(); + clear(); + + delete this; +} + +/*! +Add this binding to \a object. + +This transfers ownership of the binding to the object, marks the object's property as +being bound. + +However, it does not enable the binding itself or call update() on it. +*/ +void QDeclarativeAbstractBinding::addToObject(QObject *object, int index) +{ + Q_ASSERT(object); + + if (m_object == object && m_propertyIndex == index) + return; + + removeFromObject(); + + Q_ASSERT(!m_prevBinding); + + m_object = object; + m_propertyIndex = index; + + QDeclarativeData *data = QDeclarativeData::get(object, true); + + if (index & 0xFF000000) { + // Value type + + int coreIndex = index & 0xFFFFFF; + + // Find the value type proxy (if there is one) + QDeclarativeValueTypeProxyBinding *proxy = 0; + if (data->hasBindingBit(coreIndex)) { + QDeclarativeAbstractBinding *b = data->bindings; + while (b && b->propertyIndex() != coreIndex) + b = b->m_nextBinding; + Q_ASSERT(b && b->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy); + proxy = static_cast(b); + } + + if (!proxy) { + proxy = new QDeclarativeValueTypeProxyBinding(object, coreIndex); + proxy->addToObject(object, coreIndex); + } + + m_nextBinding = proxy->m_bindings; + if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding; + m_prevBinding = &proxy->m_bindings; + proxy->m_bindings = this; + + } else { + m_nextBinding = data->bindings; + if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding; + m_prevBinding = &data->bindings; + data->bindings = this; + + data->setBindingBit(m_object, index); + } +} + +/*! +Remove the binding from the object. +*/ +void QDeclarativeAbstractBinding::removeFromObject() +{ + if (m_prevBinding) { + int index = propertyIndex(); + + *m_prevBinding = m_nextBinding; + if (m_nextBinding) m_nextBinding->m_prevBinding = m_prevBinding; + m_prevBinding = 0; + m_nextBinding = 0; + + if (index & 0xFF000000) { + // Value type - we don't remove the proxy from the object. It will sit their happily + // doing nothing until it is removed by a write, a binding change or it is reused + // to hold more sub-bindings. + } else if (m_object) { + QDeclarativeData *data = QDeclarativeData::get(m_object, false); + if (data) data->clearBindingBit(index); + } + + m_object = 0; + m_propertyIndex = -1; + } +} + +static void bindingDummyDeleter(QDeclarativeAbstractBinding *) +{ +} + +QDeclarativeAbstractBinding::Pointer QDeclarativeAbstractBinding::weakPointer() +{ + if (m_selfPointer.isNull()) + m_selfPointer = QSharedPointer(this, bindingDummyDeleter); + + return m_selfPointer.toWeakRef(); +} + +void QDeclarativeAbstractBinding::clear() +{ + if (m_mePtr) { + *m_mePtr = 0; + m_mePtr = 0; + } +} + +QString QDeclarativeAbstractBinding::expression() const +{ + return QLatin1String(""); +} + +QObject *QDeclarativeAbstractBinding::object() const +{ + return m_object; +} + +int QDeclarativeAbstractBinding::propertyIndex() const +{ + return m_propertyIndex; +} + +void QDeclarativeAbstractBinding::setEnabled(bool enabled, QDeclarativePropertyPrivate::WriteFlags flags) +{ + if (enabled) update(flags); +} + void QDeclarativeBindingPrivate::refresh() { Q_Q(QDeclarativeBinding); @@ -255,20 +407,8 @@ void QDeclarativeBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteF d->enabled = e; setNotifyOnValueChanged(e); - QDeclarativeAbstractBinding::setEnabled(e, flags); - - if (e) { - addToObject(d->property.object()); + if (e) update(flags); - } else { - removeFromObject(); - } -} - -int QDeclarativeBinding::propertyIndex() -{ - Q_D(QDeclarativeBinding); - return QDeclarativePropertyPrivate::bindingIndex(d->property); } bool QDeclarativeBinding::enabled() const @@ -283,127 +423,6 @@ QString QDeclarativeBinding::expression() const return QDeclarativeExpression::expression(); } -QDeclarativeAbstractBinding::QDeclarativeAbstractBinding() -: m_object(0), m_mePtr(0), m_prevBinding(0), m_nextBinding(0) -{ -} - -QDeclarativeAbstractBinding::~QDeclarativeAbstractBinding() -{ - Q_ASSERT(m_prevBinding == 0); - Q_ASSERT(m_mePtr == 0); -} - -void QDeclarativeAbstractBinding::destroy() -{ - removeFromObject(); - clear(); - - delete this; -} - -void QDeclarativeAbstractBinding::addToObject(QObject *object) -{ - Q_ASSERT(object); - - if (m_object == object) - return; - - int index = propertyIndex(); - - removeFromObject(); - - Q_ASSERT(!m_prevBinding); - - m_object = object; - QDeclarativeData *data = QDeclarativeData::get(object, true); - - if (index & 0xFF000000) { - // Value type - - int coreIndex = index & 0xFFFFFF; - - // Find the value type proxy (if there is one) - QDeclarativeValueTypeProxyBinding *proxy = 0; - if (data->hasBindingBit(coreIndex)) { - QDeclarativeAbstractBinding *b = data->bindings; - while (b && b->propertyIndex() != coreIndex) - b = b->m_nextBinding; - Q_ASSERT(b && b->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy); - proxy = static_cast(b); - } - - if (!proxy) - proxy = new QDeclarativeValueTypeProxyBinding(object, coreIndex); - proxy->addToObject(object); - - m_nextBinding = proxy->m_bindings; - if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding; - m_prevBinding = &proxy->m_bindings; - proxy->m_bindings = this; - - } else { - m_nextBinding = data->bindings; - if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding; - m_prevBinding = &data->bindings; - data->bindings = this; - - data->setBindingBit(m_object, index); - } -} - -void QDeclarativeAbstractBinding::removeFromObject() -{ - if (m_prevBinding) { - int index = propertyIndex(); - - *m_prevBinding = m_nextBinding; - if (m_nextBinding) m_nextBinding->m_prevBinding = m_prevBinding; - m_prevBinding = 0; - m_nextBinding = 0; - - if (index & 0xFF000000) { - // Value type - we don't remove the proxy from the object. It will sit their happily - // doing nothing for ever more. - } else if (m_object) { - QDeclarativeData *data = QDeclarativeData::get(m_object, false); - if (data) data->clearBindingBit(index); - } - - m_object = 0; - } -} - -static void bindingDummyDeleter(QDeclarativeAbstractBinding *) -{ -} - -QDeclarativeAbstractBinding::Pointer QDeclarativeAbstractBinding::weakPointer() -{ - if (m_selfPointer.isNull()) - m_selfPointer = QSharedPointer(this, bindingDummyDeleter); - - return m_selfPointer.toWeakRef(); -} - -void QDeclarativeAbstractBinding::clear() -{ - if (m_mePtr) { - *m_mePtr = 0; - m_mePtr = 0; - } -} - -QString QDeclarativeAbstractBinding::expression() const -{ - return QLatin1String(""); -} - -void QDeclarativeAbstractBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags) -{ - if (e) m_mePtr = 0; -} - QDeclarativeValueTypeProxyBinding::QDeclarativeValueTypeProxyBinding(QObject *o, int index) : m_object(o), m_index(index), m_bindings(0) { @@ -421,16 +440,10 @@ QDeclarativeValueTypeProxyBinding::~QDeclarativeValueTypeProxyBinding() void QDeclarativeValueTypeProxyBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags) { if (e) { - addToObject(m_object); - QDeclarativeAbstractBinding *bindings = m_bindings; - m_bindings = 0; recursiveEnable(bindings, flags); } else { - removeFromObject(); - QDeclarativeAbstractBinding *bindings = m_bindings; - m_bindings = 0; recursiveDisable(bindings); } } @@ -440,13 +453,7 @@ void QDeclarativeValueTypeProxyBinding::recursiveEnable(QDeclarativeAbstractBind if (!b) return; - QDeclarativeAbstractBinding *next = b->m_nextBinding; - b->m_prevBinding = 0; - b->m_nextBinding = 0; - Q_ASSERT(b->m_mePtr == 0); - b->m_mePtr = &b; - - recursiveEnable(next, flags); + recursiveEnable(b->m_nextBinding, flags); if (b) b->setEnabled(true, flags); @@ -459,19 +466,8 @@ void QDeclarativeValueTypeProxyBinding::recursiveDisable(QDeclarativeAbstractBin recursiveDisable(b->m_nextBinding); - b->setEnabled(false, 0); - - Q_ASSERT(b->m_prevBinding == 0); - Q_ASSERT(b->m_nextBinding == 0); - b->m_nextBinding = m_bindings; - if (b->m_nextBinding) b->m_nextBinding->m_prevBinding = &b->m_nextBinding; - b->m_prevBinding = &m_bindings; - m_bindings = b; -} - -int QDeclarativeValueTypeProxyBinding::propertyIndex() -{ - return m_index; + if (b) + b->setEnabled(false, 0); } void QDeclarativeValueTypeProxyBinding::update(QDeclarativePropertyPrivate::WriteFlags) @@ -488,4 +484,25 @@ QDeclarativeAbstractBinding *QDeclarativeValueTypeProxyBinding::binding(int prop return binding; } +/*! +Removes a collection of bindings, corresponding to the set bits in \a mask. +*/ +void QDeclarativeValueTypeProxyBinding::removeBindings(quint32 mask) +{ + QDeclarativeAbstractBinding *binding = m_bindings; + while (binding) { + if (mask & (1 << (binding->propertyIndex() >> 24))) { + QDeclarativeAbstractBinding *remove = binding; + binding = remove->m_nextBinding; + *remove->m_prevBinding = remove->m_nextBinding; + if (remove->m_nextBinding) remove->m_nextBinding->m_prevBinding = remove->m_prevBinding; + remove->m_prevBinding = 0; + remove->m_nextBinding = 0; + remove->destroy(); + } else { + binding = binding->m_nextBinding; + } + } +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h index 0b9bde6..7823a3d 100644 --- a/src/declarative/qml/qdeclarativebinding_p.h +++ b/src/declarative/qml/qdeclarativebinding_p.h @@ -78,14 +78,16 @@ public: enum Type { PropertyBinding, ValueTypeProxy }; virtual Type bindingType() const { return PropertyBinding; } + QObject *object() const; + int propertyIndex() const; + void setEnabled(bool e) { setEnabled(e, QDeclarativePropertyPrivate::DontRemoveBinding); } virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags) = 0; - virtual int propertyIndex() = 0; void update() { update(QDeclarativePropertyPrivate::DontRemoveBinding); } virtual void update(QDeclarativePropertyPrivate::WriteFlags) = 0; - void addToObject(QObject *); + void addToObject(QObject *, int); void removeFromObject(); static Pointer getPointer(QDeclarativeAbstractBinding *p) { return p ? p->weakPointer() : Pointer(); } @@ -98,12 +100,14 @@ private: Pointer weakPointer(); friend class QDeclarativeData; + friend class QDeclarativeComponentPrivate; friend class QDeclarativeValueTypeProxyBinding; friend class QDeclarativePropertyPrivate; friend class QDeclarativeVME; friend class QtSharedPointer::ExternalRefCount; QObject *m_object; + int m_propertyIndex; QDeclarativeAbstractBinding **m_mePtr; QDeclarativeAbstractBinding **m_prevBinding; QDeclarativeAbstractBinding *m_nextBinding; @@ -118,11 +122,12 @@ public: virtual Type bindingType() const { return ValueTypeProxy; } virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags); - virtual int propertyIndex(); virtual void update(QDeclarativePropertyPrivate::WriteFlags); QDeclarativeAbstractBinding *binding(int propertyIndex); + void removeBindings(quint32 mask); + protected: ~QDeclarativeValueTypeProxyBinding(); @@ -154,7 +159,6 @@ public: // Inherited from QDeclarativeAbstractBinding virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags); - virtual int propertyIndex(); virtual void update(QDeclarativePropertyPrivate::WriteFlags flags); virtual QString expression() const; diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp index fbe5829..5c295b9 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings.cpp +++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp @@ -187,7 +187,6 @@ public: // Inherited from QDeclarativeAbstractBinding virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags); - virtual int propertyIndex(); virtual void update(QDeclarativePropertyPrivate::WriteFlags flags); virtual void destroy(); @@ -294,14 +293,6 @@ QDeclarativeAbstractBinding *QDeclarativeCompiledBindings::configBinding(int ind void QDeclarativeCompiledBindingsPrivate::Binding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags) { - if (e) { - addToObject(target); - } else { - removeFromObject(); - } - - QDeclarativeAbstractBinding::setEnabled(e, flags); - if (enabled != e) { enabled = e; @@ -309,11 +300,6 @@ void QDeclarativeCompiledBindingsPrivate::Binding::setEnabled(bool e, QDeclarati } } -int QDeclarativeCompiledBindingsPrivate::Binding::propertyIndex() -{ - return property & 0xFFFF; -} - void QDeclarativeCompiledBindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags) { parent->run(this, flags); diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 645402e..df428b1 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -946,6 +946,16 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj) QDeclarativePropertyCache::Data::IsVMEFunction, QDeclarativePropertyCache::Data::IsVMESignal); + // Add flag for alias properties + if (!obj->synthdata.isEmpty()) { + const QDeclarativeVMEMetaData *vmeMetaData = + reinterpret_cast(obj->synthdata.constData()); + for (int ii = 0; ii < vmeMetaData->aliasCount; ++ii) { + int index = obj->metaObject()->propertyOffset() + vmeMetaData->propertyCount + ii; + propertyCache->property(index)->flags |= QDeclarativePropertyCache::Data::IsAlias; + } + } + if (obj == unitRoot) { propertyCache->addref(); output->rootPropertyCache = propertyCache; @@ -1003,7 +1013,8 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) seenDefer = true; continue; } - genValueProperty(prop, obj); + if (!prop->isAlias) + genValueProperty(prop, obj); } if (seenDefer) { QDeclarativeInstruction defer; @@ -1113,25 +1124,56 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) } foreach(Property *prop, obj->valueTypeProperties) { - QDeclarativeInstruction fetch; - fetch.type = QDeclarativeInstruction::FetchValueType; - fetch.fetchValue.property = prop->index; - fetch.fetchValue.type = prop->type; - fetch.line = prop->location.start.line; + if (!prop->isAlias) + genValueTypeProperty(obj, prop); + } - output->bytecode << fetch; + foreach(Property *prop, obj->valueProperties) { + if (prop->isDeferred) + continue; + if (prop->isAlias) + genValueProperty(prop, obj); + } + + foreach(Property *prop, obj->valueTypeProperties) { + if (prop->isAlias) + genValueTypeProperty(obj, prop); + } +} +void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj,QDeclarativeParser::Property *prop) +{ + QDeclarativeInstruction fetch; + fetch.type = QDeclarativeInstruction::FetchValueType; + fetch.fetchValue.property = prop->index; + fetch.fetchValue.type = prop->type; + fetch.fetchValue.bindingSkipList = 0; + fetch.line = prop->location.start.line; + + if (obj->type == -1 || output->types.at(obj->type).component) { + // We only have to do this if this is a composite type. If it is a builtin + // type it can't possibly already have bindings that need to be cleared. foreach(Property *vprop, prop->value->valueProperties) { - genPropertyAssignment(vprop, prop->value, prop); + if (!vprop->values.isEmpty()) { + Q_ASSERT(vprop->index >= 0 && vprop->index < 32); + fetch.fetchValue.bindingSkipList |= (1 << vprop->index); + } } + } - QDeclarativeInstruction pop; - pop.type = QDeclarativeInstruction::PopValueType; - pop.fetchValue.property = prop->index; - pop.fetchValue.type = prop->type; - pop.line = prop->location.start.line; - output->bytecode << pop; + output->bytecode << fetch; + + foreach(Property *vprop, prop->value->valueProperties) { + genPropertyAssignment(vprop, prop->value, prop); } + + QDeclarativeInstruction pop; + pop.type = QDeclarativeInstruction::PopValueType; + pop.fetchValue.property = prop->index; + pop.fetchValue.type = prop->type; + pop.fetchValue.bindingSkipList = 0; + pop.line = prop->location.start.line; + output->bytecode << pop; } void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj) @@ -1440,10 +1482,22 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop, if (p.name()) { prop->type = p.userType(); } - } - if (prop->index != -1) - prop->parent->setBindingBit(prop->index); + // Check if this is an alias + if (prop->index != -1 && + prop->parent && + prop->parent->type != -1 && + output->types.at(prop->parent->type).component) { + + QDeclarativePropertyCache *cache = output->types.at(prop->parent->type).component->rootPropertyCache; + if (cache && cache->property(prop->index) && + cache->property(prop->index)->flags & QDeclarativePropertyCache::Data::IsAlias) + prop->isAlias = true; + } + + if (prop->index != -1 && !prop->values.isEmpty()) + prop->parent->setBindingBit(prop->index); + } if (!prop->isDefault && prop->name == "id" && !ctxt.isSubContext()) { @@ -1778,6 +1832,12 @@ bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *pr COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name))); } + + if (prop->isAlias) { + foreach (Property *vtProp, prop->value->properties) + vtProp->isAlias = true; + } + COMPILE_CHECK(buildValueTypeProperty(enginePrivate->valueTypes[prop->type], prop->value, obj, ctxt.incr())); obj->addValueTypeProperty(prop); @@ -2423,7 +2483,7 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn if (p.type == Object::DynamicProperty::Alias) { if (mode == ResolveAliases) { ((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++; - compileAlias(builder, dynamicData, obj, p); + COMPILE_CHECK(compileAlias(builder, dynamicData, obj, p)); } else { // Need a fake signal so that the metaobject remains consistent across // the resolve and non-resolve alias runs @@ -2694,7 +2754,10 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi } QDeclarativeInstruction store; - store.type = QDeclarativeInstruction::StoreBinding; + if (!prop->isAlias) + store.type = QDeclarativeInstruction::StoreBinding; + else + store.type = QDeclarativeInstruction::StoreBindingOnAlias; store.assignBinding.value = output->indexForByteArray(ref.compiledData); store.assignBinding.context = ref.bindingContext.stack; store.assignBinding.owner = ref.bindingContext.owner; @@ -2769,13 +2832,17 @@ bool QDeclarativeCompiler::completeComponentBuild() expr.expression = binding.expression; expr.imports = unit->imports(); - int index = bindingCompiler.compile(expr, enginePrivate); - if (index != -1) { - binding.dataType = BindingReference::Experimental; - binding.compiledIndex = index; - componentStat.optimizedBindings.append(iter.key()->location); - continue; - } + // ### We don't currently optimize for bindings on alias's - because + // of the solution to QTBUG-13719 + if (!binding.property->isAlias) { + int index = bindingCompiler.compile(expr, enginePrivate); + if (index != -1) { + binding.dataType = BindingReference::Experimental; + binding.compiledIndex = index; + componentStat.optimizedBindings.append(iter.key()->location); + continue; + } + } binding.dataType = BindingReference::QtScript; diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h index 5cd1fd2..7d76ad9 100644 --- a/src/declarative/qml/qdeclarativecompiler_p.h +++ b/src/declarative/qml/qdeclarativecompiler_p.h @@ -252,6 +252,7 @@ private: void genObject(QDeclarativeParser::Object *obj); void genObjectBody(QDeclarativeParser::Object *obj); + void genValueTypeProperty(QDeclarativeParser::Object *obj,QDeclarativeParser::Property *); void genComponent(QDeclarativeParser::Object *obj); void genValueProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj); void genListProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj); diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index 2686ce3..63bde0f 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -876,9 +876,12 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri QDeclarativeEnginePrivate::SimpleList bv = state->bindValues.at(ii); for (int jj = 0; jj < bv.count; ++jj) { - if(bv.at(jj)) + if(bv.at(jj)) { + // XXX akennedy + bv.at(jj)->m_mePtr = 0; bv.at(jj)->setEnabled(true, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); + } } QDeclarativeEnginePrivate::clear(bv); } diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp index 1767d2f..818c15d 100644 --- a/src/declarative/qml/qdeclarativeinstruction.cpp +++ b/src/declarative/qml/qdeclarativeinstruction.cpp @@ -63,7 +63,7 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) qWarning().nospace() << idx << "\t\t" << line << "\t" << "INIT\t\t\t" << instr->init.bindingsSize << "\t" << instr->init.parserStatusSize << "\t" << instr->init.contextCache << "\t" << instr->init.compiledBinding; break; case QDeclarativeInstruction::CreateObject: - qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE\t\t\t" << instr->create.type << "\t\t\t" << types.at(instr->create.type).className; + qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE\t\t\t" << instr->create.type << "\t" << instr->create.bindingBits << "\t\t" << types.at(instr->create.type).className; break; case QDeclarativeInstruction::CreateSimpleObject: qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE_SIMPLE\t\t" << instr->createSimple.typeSize; @@ -174,6 +174,9 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) case QDeclarativeInstruction::StoreBinding: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context; break; + case QDeclarativeInstruction::StoreBindingOnAlias: + qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_BINDING_ALIAS\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context; + break; case QDeclarativeInstruction::StoreCompiledBinding: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_COMPILED_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context; break; @@ -203,7 +206,7 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) qWarning().nospace() << idx << "\t\t" << line << "\t" << "FETCH\t\t\t" << instr->fetch.property; break; case QDeclarativeInstruction::FetchValueType: - qWarning().nospace() << idx << "\t\t" << line << "\t" << "FETCH_VALUE\t\t" << instr->fetchValue.property << "\t" << instr->fetchValue.type; + qWarning().nospace() << idx << "\t\t" << line << "\t" << "FETCH_VALUE\t\t" << instr->fetchValue.property << "\t" << instr->fetchValue.type << "\t" << instr->fetchValue.bindingSkipList; break; case QDeclarativeInstruction::PopFetchedObject: qWarning().nospace() << idx << "\t\t" << line << "\t" << "POP"; diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h index f0b032c..94676fc 100644 --- a/src/declarative/qml/qdeclarativeinstruction_p.h +++ b/src/declarative/qml/qdeclarativeinstruction_p.h @@ -132,6 +132,7 @@ public: AssignCustomType, /* assignCustomType */ StoreBinding, /* assignBinding */ + StoreBindingOnAlias, /* assignBinding */ StoreCompiledBinding, /* assignBinding */ StoreValueSource, /* assignValueSource */ StoreValueInterceptor, /* assignValueInterceptor */ @@ -214,6 +215,7 @@ public: struct FetchValueInstruction { int property; int type; + quint32 bindingSkipList; }; struct FetchQmlListInstruction { int property; diff --git a/src/declarative/qml/qdeclarativeparser.cpp b/src/declarative/qml/qdeclarativeparser.cpp index 8d00ef8..effecb1 100644 --- a/src/declarative/qml/qdeclarativeparser.cpp +++ b/src/declarative/qml/qdeclarativeparser.cpp @@ -205,13 +205,13 @@ QDeclarativeParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o) QDeclarativeParser::Property::Property() : parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false), - isValueTypeSubProperty(false) + isValueTypeSubProperty(false), isAlias(false) { } QDeclarativeParser::Property::Property(const QByteArray &n) : parent(0), type(0), index(-1), value(0), name(n), isDefault(false), - isDeferred(false), isValueTypeSubProperty(false) + isDeferred(false), isValueTypeSubProperty(false), isAlias(false) { } diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h index 77184c2..633847d 100644 --- a/src/declarative/qml/qdeclarativeparser_p.h +++ b/src/declarative/qml/qdeclarativeparser_p.h @@ -358,6 +358,9 @@ namespace QDeclarativeParser bool isDeferred; // True if this property is a value-type pseudo-property bool isValueTypeSubProperty; + // True if this property is a property alias. Set by the + // QDeclarativeCompiler + bool isAlias; LocationSpan location; LocationRange listValueRange; diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index 1395e97..df0917f 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -607,26 +607,7 @@ QDeclarativePropertyPrivate::binding(const QDeclarativeProperty &that) if (!that.isProperty() || !that.d->object) return 0; - QDeclarativeData *data = QDeclarativeData::get(that.d->object); - if (!data) - return 0; - - if (!data->hasBindingBit(that.d->core.coreIndex)) - return 0; - - QDeclarativeAbstractBinding *binding = data->bindings; - while (binding && binding->propertyIndex() != that.d->core.coreIndex) - binding = binding->m_nextBinding; - - if (binding && that.d->valueType.valueTypeCoreIdx != -1) { - if (binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) { - QDeclarativeValueTypeProxyBinding *proxy = static_cast(binding); - - binding = proxy->binding(bindingIndex(that)); - } - } - - return binding; + return binding(that.d->object, that.d->core.coreIndex, that.d->valueType.valueTypeCoreIdx); } /*! @@ -658,12 +639,106 @@ QDeclarativePropertyPrivate::setBinding(const QDeclarativeProperty &that, } QDeclarativeAbstractBinding * +QDeclarativePropertyPrivate::binding(QObject *object, int coreIndex, int valueTypeIndex) +{ + QDeclarativeData *data = QDeclarativeData::get(object); + if (!data) + return 0; + + QDeclarativePropertyCache::Data *propertyData = + data->propertyCache?data->propertyCache->property(coreIndex):0; + if (propertyData && propertyData->flags & QDeclarativePropertyCache::Data::IsAlias) { + const QDeclarativeVMEMetaObject *vme = + static_cast(metaObjectForProperty(object->metaObject(), coreIndex)); + + QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1; + if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) + return 0; + + // This will either be a value type sub-reference or an alias to a value-type sub-reference not both + Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1); + return binding(aObject, aCoreIndex, (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex); + } + + if (!data->hasBindingBit(coreIndex)) + return 0; + + QDeclarativeAbstractBinding *binding = data->bindings; + while (binding && binding->propertyIndex() != coreIndex) + binding = binding->m_nextBinding; + + if (binding && valueTypeIndex != -1) { + if (binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) { + int index = coreIndex | (valueTypeIndex << 24); + binding = static_cast(binding)->binding(index); + } + } + + return binding; +} + +void QDeclarativePropertyPrivate::findAliasTarget(QObject *object, int bindingIndex, + QObject **targetObject, int *targetBindingIndex) +{ + int coreIndex = bindingIndex & 0xFFFFFF; + int valueTypeIndex = bindingIndex >> 24; + if (valueTypeIndex == 0) valueTypeIndex = -1; + + QDeclarativeData *data = QDeclarativeData::get(object, false); + if (data) { + QDeclarativePropertyCache::Data *propertyData = + data->propertyCache?data->propertyCache->property(coreIndex):0; + if (propertyData && propertyData->flags & QDeclarativePropertyCache::Data::IsAlias) { + const QDeclarativeVMEMetaObject *vme = + static_cast(metaObjectForProperty(object->metaObject(), coreIndex)); + QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1; + if (vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) { + // This will either be a value type sub-reference or an alias to a value-type sub-reference not both + Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1); + + int aBindingIndex = aCoreIndex; + if (aValueTypeIndex != -1) + aBindingIndex |= aValueTypeIndex << 24; + else if (valueTypeIndex != -1) + aBindingIndex |= valueTypeIndex << 24; + + findAliasTarget(aObject, aBindingIndex, targetObject, targetBindingIndex); + return; + } + } + } + + *targetObject = object; + *targetBindingIndex = bindingIndex; +} + +QDeclarativeAbstractBinding * QDeclarativePropertyPrivate::setBinding(QObject *object, int coreIndex, int valueTypeIndex, QDeclarativeAbstractBinding *newBinding, WriteFlags flags) { QDeclarativeData *data = QDeclarativeData::get(object, 0 != newBinding); QDeclarativeAbstractBinding *binding = 0; + if (data) { + QDeclarativePropertyCache::Data *propertyData = + data->propertyCache?data->propertyCache->property(coreIndex):0; + if (propertyData && propertyData->flags & QDeclarativePropertyCache::Data::IsAlias) { + const QDeclarativeVMEMetaObject *vme = + static_cast(metaObjectForProperty(object->metaObject(), coreIndex)); + + QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1; + if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) { + if (newBinding) newBinding->destroy(); + return 0; + } + + // This will either be a value type sub-reference or an alias to a value-type sub-reference not both + Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1); + return setBinding(aObject, aCoreIndex, (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex, + newBinding, flags); + } + } + if (data && data->hasBindingBit(coreIndex)) { binding = data->bindings; @@ -671,16 +746,72 @@ QDeclarativePropertyPrivate::setBinding(QObject *object, int coreIndex, int valu binding = binding->m_nextBinding; } - if (binding && valueTypeIndex != -1 && binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) { - int index = coreIndex | (valueTypeIndex << 24); + int index = coreIndex; + if (valueTypeIndex != -1) + index |= (valueTypeIndex << 24); + + if (binding && valueTypeIndex != -1 && binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) binding = static_cast(binding)->binding(index); + + if (binding) { + binding->removeFromObject(); + binding->setEnabled(false, 0); } + if (newBinding) { + newBinding->addToObject(object, index); + newBinding->setEnabled(true, flags); + } + + return binding; +} + +QDeclarativeAbstractBinding * +QDeclarativePropertyPrivate::setBindingNoEnable(QObject *object, int coreIndex, int valueTypeIndex, + QDeclarativeAbstractBinding *newBinding) +{ + QDeclarativeData *data = QDeclarativeData::get(object, 0 != newBinding); + QDeclarativeAbstractBinding *binding = 0; + + if (data) { + QDeclarativePropertyCache::Data *propertyData = + data->propertyCache?data->propertyCache->property(coreIndex):0; + if (propertyData && propertyData->flags & QDeclarativePropertyCache::Data::IsAlias) { + const QDeclarativeVMEMetaObject *vme = + static_cast(metaObjectForProperty(object->metaObject(), coreIndex)); + + QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1; + if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) { + if (newBinding) newBinding->destroy(); + return 0; + } + + // This will either be a value type sub-reference or an alias to a value-type sub-reference not both + Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1); + return setBindingNoEnable(aObject, aCoreIndex, (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex, + newBinding); + } + } + + if (data && data->hasBindingBit(coreIndex)) { + binding = data->bindings; + + while (binding && binding->propertyIndex() != coreIndex) + binding = binding->m_nextBinding; + } + + int index = coreIndex; + if (valueTypeIndex != -1) + index |= (valueTypeIndex << 24); + + if (binding && valueTypeIndex != -1 && binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) + binding = static_cast(binding)->binding(index); + if (binding) - binding->setEnabled(false); + binding->removeFromObject(); if (newBinding) - newBinding->setEnabled(true, flags); + newBinding->addToObject(object, index); return binding; } @@ -1392,11 +1523,26 @@ static inline int QMetaObject_methods(const QMetaObject *metaObject) int className; int classInfoCount, classInfoData; int methodCount, methodData; + int propertyCount, propertyData; }; return reinterpret_cast(metaObject->d.data)->methodCount; } +static inline int QMetaObject_properties(const QMetaObject *metaObject) +{ + struct Private + { + int revision; + int className; + int classInfoCount, classInfoData; + int methodCount, methodData; + int propertyCount, propertyData; + }; + + return reinterpret_cast(metaObject->d.data)->propertyCount; +} + static inline void flush_vme_signal(const QObject *object, int index) { QDeclarativeData *data = static_cast(QObjectPrivate::get(const_cast(object))->declarativeData); @@ -1437,4 +1583,19 @@ bool QDeclarativePropertyPrivate::connect(const QObject *sender, int signal_inde return QMetaObject::connect(sender, signal_index, receiver, method_index, type, types); } +/*! +Return \a metaObject's [super] meta object that provides data for \a property. +*/ +const QMetaObject *QDeclarativePropertyPrivate::metaObjectForProperty(const QMetaObject *metaObject, int property) +{ + int propertyOffset = metaObject->propertyOffset(); + + while (propertyOffset > property) { + metaObject = metaObject->d.superdata; + propertyOffset -= QMetaObject_properties(metaObject); + } + + return metaObject; +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h index a9d6979..6392f88 100644 --- a/src/declarative/qml/qdeclarativeproperty_p.h +++ b/src/declarative/qml/qdeclarativeproperty_p.h @@ -68,7 +68,7 @@ class QDeclarativeExpression; class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativePropertyPrivate { public: - enum WriteFlag { BypassInterceptor = 0x01, DontRemoveBinding = 0x02 }; + enum WriteFlag { BypassInterceptor = 0x01, DontRemoveBinding = 0x02, RemoveBindingOnAliasWrite = 0x04 }; Q_DECLARE_FLAGS(WriteFlags, WriteFlag) QDeclarativePropertyPrivate() @@ -108,9 +108,13 @@ public: const QVariant &value, int flags); static bool write(QObject *, const QDeclarativePropertyCache::Data &, const QVariant &, QDeclarativeContextData *, WriteFlags flags = 0); + static void findAliasTarget(QObject *, int, QObject **, int *); static QDeclarativeAbstractBinding *setBinding(QObject *, int coreIndex, int valueTypeIndex /* -1 */, QDeclarativeAbstractBinding *, WriteFlags flags = DontRemoveBinding); + static QDeclarativeAbstractBinding *setBindingNoEnable(QObject *, int coreIndex, int valueTypeIndex /* -1 */, + QDeclarativeAbstractBinding *); + static QDeclarativeAbstractBinding *binding(QObject *, int coreIndex, int valueTypeIndex /* -1 */); static QByteArray saveValueType(const QMetaObject *, int, const QMetaObject *, int); @@ -120,7 +124,6 @@ public: static bool equal(const QMetaObject *, const QMetaObject *); static bool canConvert(const QMetaObject *from, const QMetaObject *to); - // "Public" (to QML) methods static QDeclarativeAbstractBinding *binding(const QDeclarativeProperty &that); static QDeclarativeAbstractBinding *setBinding(const QDeclarativeProperty &that, @@ -136,6 +139,7 @@ public: static bool connect(const QObject *sender, int signal_index, const QObject *receiver, int method_index, int type = 0, int *types = 0); + static const QMetaObject *metaObjectForProperty(const QMetaObject *, int); }; Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePropertyPrivate::WriteFlags) diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index 922010d..f7c5daa 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -83,6 +83,7 @@ public: IsConstant = 0x00000001, IsWritable = 0x00000002, IsResettable = 0x00000004, + IsAlias = 0x00000008, // These are mutualy exclusive IsFunction = 0x00000010, diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp index b9e9cec..5dc6ffd 100644 --- a/src/declarative/qml/qdeclarativevaluetype.cpp +++ b/src/declarative/qml/qdeclarativevaluetype.cpp @@ -109,36 +109,54 @@ void QDeclarativeValueTypeFactory::registerValueTypes() QDeclarativeValueType *QDeclarativeValueTypeFactory::valueType(int t) { + QDeclarativeValueType *rv = 0; + switch (t) { case QVariant::Point: - return new QDeclarativePointValueType; + rv = new QDeclarativePointValueType; + break; case QVariant::PointF: - return new QDeclarativePointFValueType; + rv = new QDeclarativePointFValueType; + break; case QVariant::Size: - return new QDeclarativeSizeValueType; + rv = new QDeclarativeSizeValueType; + break; case QVariant::SizeF: - return new QDeclarativeSizeFValueType; + rv = new QDeclarativeSizeFValueType; + break; case QVariant::Rect: - return new QDeclarativeRectValueType; + rv = new QDeclarativeRectValueType; + break; case QVariant::RectF: - return new QDeclarativeRectFValueType; + rv = new QDeclarativeRectFValueType; + break; case QVariant::Vector2D: - return new QDeclarativeVector2DValueType; + rv = new QDeclarativeVector2DValueType; + break; case QVariant::Vector3D: - return new QDeclarativeVector3DValueType; + rv = new QDeclarativeVector3DValueType; + break; case QVariant::Vector4D: - return new QDeclarativeVector4DValueType; + rv = new QDeclarativeVector4DValueType; + break; case QVariant::Quaternion: - return new QDeclarativeQuaternionValueType; + rv = new QDeclarativeQuaternionValueType; + break; case QVariant::Matrix4x4: - return new QDeclarativeMatrix4x4ValueType; + rv = new QDeclarativeMatrix4x4ValueType; + break; case QVariant::EasingCurve: - return new QDeclarativeEasingValueType; + rv = new QDeclarativeEasingValueType; + break; case QVariant::Font: - return new QDeclarativeFontValueType; + rv = new QDeclarativeFontValueType; + break; default: - return 0; + break; } + + Q_ASSERT(!rv || rv->metaObject()->propertyCount() < 32); + return rv; } QDeclarativeValueType::QDeclarativeValueType(QObject *parent) diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index db90aff..c742dec 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -154,7 +154,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); int status = -1; //for dbus - QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::BypassInterceptor; + QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::BypassInterceptor | + QDeclarativePropertyPrivate::RemoveBindingOnAliasWrite; for (int ii = start; !isError() && ii < (start + count); ++ii) { const QDeclarativeInstruction &instr = comp->bytecode.at(ii); @@ -664,6 +665,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, break; case QDeclarativeInstruction::StoreBinding: + case QDeclarativeInstruction::StoreBindingOnAlias: { QObject *target = stack.at(stack.count() - 1 - instr.assignBinding.owner); @@ -675,14 +677,20 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, int coreIndex = mp.index(); - if (stack.count() == 1 && bindingSkipList.testBit(coreIndex)) + if ((stack.count() - instr.assignBinding.owner) == 1 && bindingSkipList.testBit(coreIndex)) break; QDeclarativeBinding *bind = new QDeclarativeBinding((void *)datas.at(instr.assignBinding.value).constData(), comp, context, ctxt, comp->name, instr.line, 0); bindValues.append(bind); bind->m_mePtr = &bindValues.values[bindValues.count - 1]; bind->setTarget(mp); - bind->addToObject(target); + + if (instr.type == QDeclarativeInstruction::StoreBindingOnAlias) { + QDeclarativeAbstractBinding *old = QDeclarativePropertyPrivate::setBindingNoEnable(target, coreIndex, QDeclarativePropertyPrivate::valueTypeCoreIndex(mp), bind); + if (old) { old->destroy(); } + } else { + bind->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(mp)); + } } break; @@ -701,7 +709,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, ctxt->optimizedBindings->configBinding(instr.assignBinding.value, target, scope, property); bindValues.append(binding); binding->m_mePtr = &bindValues.values[bindValues.count - 1]; - binding->addToObject(target); + binding->addToObject(target, property); } break; @@ -874,8 +882,26 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::FetchValueType: { QObject *target = stack.top(); - QDeclarativeValueType *valueHandler = - ep->valueTypes[instr.fetchValue.type]; + + if (instr.fetchValue.bindingSkipList != 0) { + // Possibly need to clear bindings + QDeclarativeData *targetData = QDeclarativeData::get(target); + if (targetData) { + QDeclarativeAbstractBinding *binding = + QDeclarativePropertyPrivate::binding(target, instr.fetchValue.property, -1); + + if (binding && binding->bindingType() != QDeclarativeAbstractBinding::ValueTypeProxy) { + QDeclarativePropertyPrivate::setBinding(target, instr.fetchValue.property, -1, 0); + binding->destroy(); + } else if (binding) { + QDeclarativeValueTypeProxyBinding *proxy = + static_cast(binding); + proxy->removeBindings(instr.fetchValue.bindingSkipList); + } + } + } + + QDeclarativeValueType *valueHandler = ep->valueTypes[instr.fetchValue.type]; valueHandler->read(target, instr.fetchValue.property); stack.push(valueHandler); } diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp index e28062b..38c1709 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject.cpp +++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp @@ -46,6 +46,7 @@ #include "qdeclarativeexpression.h" #include "private/qdeclarativeexpression_p.h" #include "private/qdeclarativecontext_p.h" +#include "private/qdeclarativebinding_p.h" Q_DECLARE_METATYPE(QScriptValue); @@ -589,7 +590,21 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) if (d->isObjectAlias()) { *reinterpret_cast(a[0]) = target; return -1; - } else if (d->isValueTypeAlias()) { + } + + // Remove binding (if any) on write + if(c == QMetaObject::WriteProperty) { + int flags = *reinterpret_cast(a[3]); + if (flags & QDeclarativePropertyPrivate::RemoveBindingOnAliasWrite) { + QDeclarativeData *targetData = QDeclarativeData::get(target); + if (targetData && targetData->hasBindingBit(d->propertyIndex())) { + QDeclarativeAbstractBinding *binding = QDeclarativePropertyPrivate::setBinding(target, d->propertyIndex(), d->isValueTypeAlias()?d->valueTypeIndex():-1, 0); + if (binding) binding->destroy(); + } + } + } + + if (d->isValueTypeAlias()) { // Value type property QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); @@ -821,6 +836,36 @@ void QDeclarativeVMEMetaObject::setVMEProperty(int index, const QScriptValue &v) return writeVarProperty(index - propOffset, v); } +bool QDeclarativeVMEMetaObject::aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const +{ + Q_ASSERT(index >= propOffset + metaData->propertyCount); + + *target = 0; + *coreIndex = -1; + *valueTypeIndex = -1; + + if (!ctxt) + return false; + + QDeclarativeVMEMetaData::AliasData *d = metaData->aliasData() + (index - propOffset - metaData->propertyCount); + QDeclarativeContext *context = ctxt->asQDeclarativeContext(); + QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(context); + + *target = ctxtPriv->data->idValues[d->contextIdx].data(); + if (!*target) + return false; + + if (d->isObjectAlias()) { + } else if (d->isValueTypeAlias()) { + *coreIndex = d->propertyIndex(); + *valueTypeIndex = d->valueTypeIndex(); + } else { + *coreIndex = d->propertyIndex(); + } + + return true; +} + void QDeclarativeVMEMetaObject::connectAlias(int aliasId) { if (!aConnected.testBit(aliasId)) { diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h index 5134763..7b6b410 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject_p.h +++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h @@ -138,6 +138,7 @@ public: QDeclarativeCompiledData *compiledData); ~QDeclarativeVMEMetaObject(); + bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const; void registerInterceptor(int index, int valueIndex, QDeclarativePropertyValueInterceptor *interceptor); QScriptValue vmeMethod(int index); int vmeMethodLineNumber(int index); @@ -146,6 +147,7 @@ public: void setVMEProperty(int index, const QScriptValue &); void connectAliasSignal(int index); + protected: virtual int metaCall(QMetaObject::Call _c, int _id, void **_a); diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsAssignCorrectlyType.qml b/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsAssignCorrectlyType.qml new file mode 100644 index 0000000..0eda67d --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsAssignCorrectlyType.qml @@ -0,0 +1,9 @@ +import QtQuick 1.0 + +QtObject { + id: root + + property real realProperty + property alias aliasProperty: root.realProperty +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType.qml b/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType.qml new file mode 100644 index 0000000..f539fb6 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType.qml @@ -0,0 +1,14 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyTypeObject { + id: root + + property int data: 7 + + property int targetProperty: root.data * 43 - root.data + property alias aliasProperty: root.targetProperty + + pointProperty: Qt.point(data, data); + property alias pointAliasProperty: root.pointProperty +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType3.qml new file mode 100644 index 0000000..a4b0527 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType3.qml @@ -0,0 +1,9 @@ +import QtQuick 1.0 + +QtObject { + id: root + + property int testProperty + property alias aliasProperty: root.testProperty +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsAssignCorrectly.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsAssignCorrectly.qml new file mode 100644 index 0000000..f0808c4 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsAssignCorrectly.qml @@ -0,0 +1,59 @@ +import QtQuick 1.0 + +Item { + id: root + + property bool test: false + + property real testData: 9 + property real testData2: 9 + + states: State { + name: "change" + PropertyChanges { + target: myType + realProperty: if (testData2 > 3) 9; else 11; + } + } + + AliasBindingsAssignCorrectlyType { + id: myType + + aliasProperty: if (testData > 3) 14; else 12; + } + + Component.onCompleted: { + // Check original binding works + if (myType.aliasProperty != 14) return; + + testData = 2; + if (myType.aliasProperty != 12) return; + + // Change binding indirectly by modifying the "realProperty" + root.state = "change"; + if (myType.aliasProperty != 9) return; + + // Check the new binding works + testData2 = 1; + if (myType.aliasProperty != 11) return; + + // Try and trigger the old binding (that should have been removed) + testData = 6; + if (myType.aliasProperty != 11) return; + + // Restore the original binding + root.state = ""; + if (myType.aliasProperty != 14) return; + + // Test the restored binding works + testData = 0; + if (myType.aliasProperty != 12) return; + + // Test the old binding isn't somehow hanging around and still in effect + testData2 = 13; + if (myType.aliasProperty != 12) return; + + test = true; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.2.qml new file mode 100644 index 0000000..4f07cbf --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.2.qml @@ -0,0 +1,29 @@ +import QtQuick 1.0 + +Item { + id: me + property bool test: false + + property int value: 9 + + AliasBindingsOverrideTargetType { + id: aliasType + pointAliasProperty.x: me.value + } + + Component.onCompleted: { + if (aliasType.pointAliasProperty.x != 9) return; + + me.value = 11; + if (aliasType.pointAliasProperty.x != 11) return; + + aliasType.data = 8; + if (aliasType.pointAliasProperty.x != 11) return; + + me.value = 4; + if (aliasType.pointAliasProperty.x != 4) return; + + test = true; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.3.qml new file mode 100644 index 0000000..937ae91 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.3.qml @@ -0,0 +1,24 @@ +import QtQuick 1.0 + +Item { + id: root + property bool test: false; + + property int value1: 10 + property int value2: 11 + + AliasBindingsOverrideTargetType3 { + id: obj + + testProperty: root.value1 * 9 + aliasProperty: root.value2 * 10 + } + + Component.onCompleted: { + if (obj.testProperty != 110) return; + if (obj.aliasProperty != 110) return; + + test = true; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.qml new file mode 100644 index 0000000..a01dc5b --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.qml @@ -0,0 +1,28 @@ +import QtQuick 1.0 + +Item { + id: me + property bool test: false + + property int value: 9 + + AliasBindingsOverrideTargetType { + id: aliasType + aliasProperty: me.value + } + + Component.onCompleted: { + if (aliasType.aliasProperty != 9) return; + + me.value = 11; + if (aliasType.aliasProperty != 11) return; + + aliasType.data = 8; + if (aliasType.aliasProperty != 11) return; + + me.value = 4; + if (aliasType.aliasProperty != 4) return; + + test = true; + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.2.qml new file mode 100644 index 0000000..5bf9f6a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.2.qml @@ -0,0 +1,29 @@ +import QtQuick 1.0 + +Item { + id: me + property bool test: false + + property int value: 9 + + AliasBindingsOverrideTargetType { + id: aliasType + } + + Component.onCompleted: { + if (aliasType.aliasProperty != 294) return; + + aliasType.data = 8; + if (aliasType.aliasProperty != 336) return; + + aliasType.aliasProperty = 4; + if (aliasType.aliasProperty != 4) return; + + aliasType.data = 7; + if (aliasType.aliasProperty != 4) return; + + test = true; + } +} + + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.3.qml new file mode 100644 index 0000000..a23ad4a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.3.qml @@ -0,0 +1,23 @@ +import QtQuick 1.0 + +Item { + id: me + property bool test: false + + property int value: 9 + + AliasBindingsOverrideTargetType { + id: aliasType + pointAliasProperty.x: 9 + } + + Component.onCompleted: { + if (aliasType.pointAliasProperty.x != 9) return; + + aliasType.data = 8; + if (aliasType.pointAliasProperty.x != 9) return; + + test = true; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.qml new file mode 100644 index 0000000..ac20371 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.qml @@ -0,0 +1,23 @@ +import QtQuick 1.0 + +Item { + id: me + property bool test: false + + property int value: 9 + + AliasBindingsOverrideTargetType { + id: aliasType + aliasProperty: 11 + } + + Component.onCompleted: { + if (aliasType.aliasProperty != 11) return; + + aliasType.data = 8; + if (aliasType.aliasProperty != 11) return; + + test = true; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/writeRemovesBinding.qml b/tests/auto/declarative/qdeclarativeecmascript/data/writeRemovesBinding.qml new file mode 100644 index 0000000..035f037 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/writeRemovesBinding.qml @@ -0,0 +1,46 @@ +import QtQuick 1.0 + +QtObject { + id: root + + property bool test: false + + property real data: 9 + property real binding: data + + property alias aliasProperty: root.aliasBinding + property real aliasBinding: data + + Component.onCompleted: { + // Non-aliased properties + if (binding != 9) return; + + data = 11; + if (binding != 11) return; + + binding = 6; + if (binding != 6) return; + + data = 3; + if (binding != 6) return; + + + // Writing through an aliased property + if (aliasProperty != 3) return; + if (aliasBinding != 3) return; + + data = 4; + if (aliasProperty != 4) return; + if (aliasBinding != 4) return; + + aliasProperty = 19; + if (aliasProperty != 19) return; + if (aliasBinding != 19) return; + + data = 5; + if (aliasProperty != 19) return; + if (aliasBinding != 19) return; + + test = true; + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 652404c..8658217 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -164,6 +164,10 @@ private slots: void in(); void sharedAttachedObject(); void objectName(); + void writeRemovesBinding(); + void aliasBindingsAssignCorrectly(); + void aliasBindingsOverrideTarget(); + void aliasWritesOverrideBindings(); void include(); @@ -2671,6 +2675,97 @@ void tst_qdeclarativeecmascript::objectName() delete o; } +void tst_qdeclarativeecmascript::writeRemovesBinding() +{ + QDeclarativeComponent component(&engine, TEST_FILE("writeRemovesBinding.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("test").toBool(), true); + + delete o; +} + +// Test bindings assigned to alias properties actually assign to the alias' target +void tst_qdeclarativeecmascript::aliasBindingsAssignCorrectly() +{ + QDeclarativeComponent component(&engine, TEST_FILE("aliasBindingsAssignCorrectly.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("test").toBool(), true); + + delete o; +} + +// Test bindings assigned to alias properties override a binding on the target (QTBUG-13719) +void tst_qdeclarativeecmascript::aliasBindingsOverrideTarget() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("aliasBindingsOverrideTarget.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("test").toBool(), true); + + delete o; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("aliasBindingsOverrideTarget.2.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("test").toBool(), true); + + delete o; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("aliasBindingsOverrideTarget.3.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("test").toBool(), true); + + delete o; + } +} + +// Test that writes to alias properties override bindings on the alias target (QTBUG-13719) +void tst_qdeclarativeecmascript::aliasWritesOverrideBindings() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("aliasWritesOverrideBindings.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("test").toBool(), true); + + delete o; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("aliasWritesOverrideBindings.2.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("test").toBool(), true); + + delete o; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("aliasWritesOverrideBindings.3.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("test").toBool(), true); + + delete o; + } +} + QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" diff --git a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp index db1f191..4470d65 100644 --- a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp +++ b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp @@ -458,6 +458,7 @@ void tst_qdeclarativeinstruction::dump() i.type = QDeclarativeInstruction::FetchValueType; i.fetchValue.property = 34; i.fetchValue.type = 6; + i.fetchValue.bindingSkipList = 7; data->bytecode << i; } @@ -538,7 +539,7 @@ void tst_qdeclarativeinstruction::dump() << "Index\tLine\tOperation\t\tData1\tData2\tData3\tComments" << "-------------------------------------------------------------------------------" << "0\t\t0\tINIT\t\t\t0\t3\t-1\t-1" - << "1\t\t1\tCREATE\t\t\t0\t\t\t\"Test\"" + << "1\t\t1\tCREATE\t\t\t0\t-1\t\t\"Test\"" << "2\t\t2\tSETID\t\t\t0\t\t\t\"testId\"" << "3\t\t3\tSET_DEFAULT" << "4\t\t4\tCREATE_COMPONENT\t3" @@ -578,7 +579,7 @@ void tst_qdeclarativeinstruction::dump() << "38\t\t40\tFETCH_ATTACHED\t\t23" << "39\t\t42\tFETCH_QLIST\t\t32" << "40\t\t43\tFETCH\t\t\t33" - << "41\t\t44\tFETCH_VALUE\t\t34\t6" + << "41\t\t44\tFETCH_VALUE\t\t34\t6\t7" << "42\t\t45\tPOP" << "43\t\t46\tPOP_QLIST" << "44\t\t47\tPOP_VALUE\t\t35\t8" diff --git a/tests/auto/declarative/qdeclarativeproperty/data/aliasPropertyBindings.qml b/tests/auto/declarative/qdeclarativeproperty/data/aliasPropertyBindings.qml new file mode 100644 index 0000000..a253a58 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeproperty/data/aliasPropertyBindings.qml @@ -0,0 +1,19 @@ +import QtQuick 1.0 + +Item { + id: root + + property real test: 9 + property real test2: 3 + + property real realProperty: test * test + test + property alias aliasProperty: root.realProperty + + states: State { + name: "switch" + PropertyChanges { + target: root + aliasProperty: 32 * test2 + } + } +} diff --git a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp index 0ca0e03..3cc71bb 100644 --- a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp +++ b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp @@ -132,6 +132,7 @@ private slots: // Bugs void crashOnValueProperty(); + void aliasPropertyBindings(); void copy(); private: @@ -1308,6 +1309,74 @@ void tst_qdeclarativeproperty::crashOnValueProperty() QCOMPARE(p.read(), QVariant(20)); } +// QTBUG-13719 +void tst_qdeclarativeproperty::aliasPropertyBindings() +{ + QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyBindings.qml")); + + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("realProperty").toReal(), 90.); + QCOMPARE(object->property("aliasProperty").toReal(), 90.); + + object->setProperty("test", 10); + + QCOMPARE(object->property("realProperty").toReal(), 110.); + QCOMPARE(object->property("aliasProperty").toReal(), 110.); + + QDeclarativeProperty realProperty(object, QLatin1String("realProperty")); + QDeclarativeProperty aliasProperty(object, QLatin1String("aliasProperty")); + + // Check there is a binding on these two properties + QVERIFY(QDeclarativePropertyPrivate::binding(realProperty) != 0); + QVERIFY(QDeclarativePropertyPrivate::binding(aliasProperty) != 0); + + // Check that its the same binding on these two properties + QCOMPARE(QDeclarativePropertyPrivate::binding(realProperty), + QDeclarativePropertyPrivate::binding(aliasProperty)); + + // Change the binding + object->setProperty("state", QString("switch")); + + QVERIFY(QDeclarativePropertyPrivate::binding(realProperty) != 0); + QVERIFY(QDeclarativePropertyPrivate::binding(aliasProperty) != 0); + QCOMPARE(QDeclarativePropertyPrivate::binding(realProperty), + QDeclarativePropertyPrivate::binding(aliasProperty)); + + QCOMPARE(object->property("realProperty").toReal(), 96.); + QCOMPARE(object->property("aliasProperty").toReal(), 96.); + + // Check the old binding really has not effect any more + object->setProperty("test", 4); + + QCOMPARE(object->property("realProperty").toReal(), 96.); + QCOMPARE(object->property("aliasProperty").toReal(), 96.); + + object->setProperty("test2", 9); + + QCOMPARE(object->property("realProperty").toReal(), 288.); + QCOMPARE(object->property("aliasProperty").toReal(), 288.); + + // Revert + object->setProperty("state", QString("")); + + QVERIFY(QDeclarativePropertyPrivate::binding(realProperty) != 0); + QVERIFY(QDeclarativePropertyPrivate::binding(aliasProperty) != 0); + QCOMPARE(QDeclarativePropertyPrivate::binding(realProperty), + QDeclarativePropertyPrivate::binding(aliasProperty)); + + QCOMPARE(object->property("realProperty").toReal(), 20.); + QCOMPARE(object->property("aliasProperty").toReal(), 20.); + + object->setProperty("test2", 3); + + QCOMPARE(object->property("realProperty").toReal(), 20.); + QCOMPARE(object->property("aliasProperty").toReal(), 20.); + + delete object; +} + void tst_qdeclarativeproperty::copy() { PropertyObject object; diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/BindingsSpliceCorrectlyType.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/BindingsSpliceCorrectlyType.qml new file mode 100644 index 0000000..f625d08 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/BindingsSpliceCorrectlyType.qml @@ -0,0 +1,7 @@ +import Test 1.0 + +MyTypeObject { + property bool boldProperty: false + + font.bold: boldProperty +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/BindingsSpliceCorrectlyType4.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/BindingsSpliceCorrectlyType4.qml new file mode 100644 index 0000000..0bdccce --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/BindingsSpliceCorrectlyType4.qml @@ -0,0 +1,7 @@ +import Test 1.0 + +MyTypeObject { + property int dataProperty: 7 + + point: Qt.point(dataProperty, dataProperty) +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/BindingsSpliceCorrectlyType5.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/BindingsSpliceCorrectlyType5.qml new file mode 100644 index 0000000..151c499 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/BindingsSpliceCorrectlyType5.qml @@ -0,0 +1,7 @@ +import Test 1.0 + +MyTypeObject { + property int dataProperty: 7 + + point.x: dataProperty +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.1.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.1.qml new file mode 100644 index 0000000..7012143 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.1.qml @@ -0,0 +1,29 @@ +import Test 1.0 +import QtQuick 1.0 + +BindingsSpliceCorrectlyType { + property bool test: false + + property bool italicProperty: false + + font.italic: italicProperty + + Component.onCompleted: { + // Test initial state + if (font.italic != false) return; + if (font.bold != false) return; + + // Test italic binding worked + italicProperty = true; + + if (font.italic != true) return; + if (font.bold != false) return; + + // Test bold binding worked + boldProperty = true; + if (font.italic != true) return; + if (font.bold != true) return; + + test = true; + } +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.2.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.2.qml new file mode 100644 index 0000000..69dbcab --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.2.qml @@ -0,0 +1,31 @@ +import Test 1.0 +import QtQuick 1.0 + +BindingsSpliceCorrectlyType { + property bool test: false + + property bool italicProperty: false + + font.italic: italicProperty + font.bold: false + + Component.onCompleted: { + // Test initial state + if (font.italic != false) return; + if (font.bold != false) return; + + // Test italic binding worked + italicProperty = true; + + if (font.italic != true) return; + if (font.bold != false) return; + + // Test bold binding was removed by constant write + boldProperty = true; + if (font.italic != true) return; + if (font.bold != false) return; + + test = true; + } +} + diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.3.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.3.qml new file mode 100644 index 0000000..669feb9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.3.qml @@ -0,0 +1,36 @@ +import Test 1.0 +import QtQuick 1.0 + +BindingsSpliceCorrectlyType { + property bool test: false + + property bool italicProperty: false + property bool boldProperty2: false + + font.italic: italicProperty + font.bold: boldProperty2 + + Component.onCompleted: { + // Test initial state + if (font.italic != false) return; + if (font.bold != false) return; + + // Test italic binding worked + italicProperty = true; + + if (font.italic != true) return; + if (font.bold != false) return; + + // Test bold binding was overridden + boldProperty = true; + if (font.italic != true) return; + if (font.bold != false) return; + + boldProperty2 = true; + if (font.italic != true) return; + if (font.bold != true) return; + + test = true; + } +} + diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.4.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.4.qml new file mode 100644 index 0000000..f28584f --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.4.qml @@ -0,0 +1,27 @@ +import Test 1.0 +import QtQuick 1.0 + +BindingsSpliceCorrectlyType4 { + property bool test: false + + property int dataProperty2: 8 + + point.x: dataProperty2 + + Component.onCompleted: { + if (point.x != 8) return; + if (point.y != 4) return; + + dataProperty = 9; + + if (point.x != 8) return; + if (point.y != 4) return; + + dataProperty2 = 13; + + if (point.x != 13) return; + if (point.y != 4) return; + + test = true; + } +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.5.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.5.qml new file mode 100644 index 0000000..1214c83 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/bindingsSpliceCorrectly.5.qml @@ -0,0 +1,27 @@ +import Test 1.0 +import QtQuick 1.0 + +BindingsSpliceCorrectlyType5 { + property bool test: false + + property int dataProperty2: 8 + + point: Qt.point(dataProperty2, dataProperty2); + + Component.onCompleted: { + if (point.x != 8) return; + if (point.y != 8) return; + + dataProperty = 9; + + if (point.x != 8) return; + if (point.y != 8) return; + + dataProperty2 = 13; + + if (point.x != 13) return; + if (point.y != 13) return; + + test = true; + } +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp index a4819f3..c243a75 100644 --- a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp +++ b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp @@ -94,6 +94,7 @@ private slots: void conflictingBindings(); void returnValues(); void varAssignment(); + void bindingsSpliceCorrectly(); private: QDeclarativeEngine engine; @@ -942,6 +943,61 @@ void tst_qdeclarativevaluetypes::varAssignment() delete object; } +// Test bindings splice together correctly +void tst_qdeclarativevaluetypes::bindingsSpliceCorrectly() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("bindingsSpliceCorrectly.1.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test").toBool(), true); + + delete object; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("bindingsSpliceCorrectly.2.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test").toBool(), true); + + delete object; + } + + + { + QDeclarativeComponent component(&engine, TEST_FILE("bindingsSpliceCorrectly.3.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test").toBool(), true); + + delete object; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("bindingsSpliceCorrectly.4.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test").toBool(), true); + + delete object; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("bindingsSpliceCorrectly.5.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test").toBool(), true); + + delete object; + } +} + QTEST_MAIN(tst_qdeclarativevaluetypes) #include "tst_qdeclarativevaluetypes.moc" -- cgit v0.12 From 3b4ff89731d5e63bba91d91c0256626f92538e9d Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 29 Nov 2010 12:32:56 +0200 Subject: Add NetworkServices capability automatically for network apps Any application linking to QtNetwork, QtWebKit, or QtDeclarative is likely to utilize network, so add NetworkServices capabiltity for these applications by default in Symbian. Also increased the default epocheap maximum size for these applications. Task-number: QTBUG-14472 Reviewed-by: Janne Koskinen --- doc/src/platforms/platform-notes.qdoc | 13 +++++++++---- mkspecs/features/qt_functions.prf | 15 +++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/doc/src/platforms/platform-notes.qdoc b/doc/src/platforms/platform-notes.qdoc index 9c5f3c8..177d3f6 100644 --- a/doc/src/platforms/platform-notes.qdoc +++ b/doc/src/platforms/platform-notes.qdoc @@ -737,18 +737,23 @@ \o \c PowerMgmt if QProcess::kill(...) or QProcess::terminate(...) is called. \row \o QtCore \o \c AllFiles when \l{http://developer.symbian.org/wiki/index.php/Capabilities_%28Symbian_Signed%29/AllFiles_Capability}{accessing specific areas.} + \row \o QtDeclarative + \o \c NetworkServices is automatically added for this module. + \row \o QtNetwork + \o \c NetworkServices is automatically added for this module. \row \o QtNetwork - \o \c NetworkServices is basically always required for this module. \o \c ReadUserData is required to include all the phone's SSL certificates in the system's default CA certificate list (for example those added by the user or stored in the SIM card), without this capability only the CA certs built into the phone are used. \row \o QtMultiMedia \o \c UserEnvironment if QAudioInput is used. + \row \o QtWebkit + \o \c NetworkServices is automatically added for this module. \endtable - Note that some modules rely on other modules. If your application uses - QtXmlPatterns, QtWebkit or QtScript it may still require \c NetworkServices - as these modules rely on QtNetwork to go online. + \note Some modules rely on other modules. E.g. QtWebkit and QtDeclarative + depend on QtNetwork and therefore any application that + depends on these modules is also likely to need \c NetworkServices capability. For more information see the documentation of the individual Qt classes. If a class does not mention Symbian capabilities, it requires none. diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index afc708a..59d49c6 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -49,16 +49,23 @@ defineTest(qtAddLibrary) { isEqual(LIB_NAME, QtGui) { # Needed for #include because qs60mainapplication.h includes aknapp.h INCLUDEPATH *= $$MW_LAYER_SYSTEMINCLUDE - } - isEqual(LIB_NAME, QtWebKit) { + } else:isEqual(LIB_NAME, QtWebKit) { # Needed for because relative inclusion problem in toolchain INCLUDEPATH *= $$QMAKE_INCDIR_QT/QtXmlPatterns INCLUDEPATH *= $$QMAKE_INCDIR_QT/QtNetwork - } - isEqual(LIB_NAME, QtXmlPatterns) { + TARGET.CAPABILITY *= NetworkServices + isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 + } else:isEqual(LIB_NAME, QtXmlPatterns) { # Needed for #include because relative inclusion problem in toolchain INCLUDEPATH *= $$QMAKE_INCDIR_QT/QtNetwork + } else:isEqual(LIB_NAME, QtNetwork) { + TARGET.CAPABILITY *= NetworkServices + } else:isEqual(LIB_NAME, QtDeclarative) { + TARGET.CAPABILITY *= NetworkServices + isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 } + export(TARGET.EPOCHEAPSIZE) + export(TARGET.CAPABILITY) } isEmpty(LINKAGE) { if(!debug_and_release|build_pass):CONFIG(debug, debug|release) { -- cgit v0.12 From 87291d518beb131b5b80540d46d53b54c2366a9c Mon Sep 17 00:00:00 2001 From: Karim Pinter Date: Mon, 29 Nov 2010 14:21:23 +0200 Subject: Removes the reseting of the QMenu offset. On s60 when the qmenu is opened on the second time, it restores the position of the last activated menu, so there is no need to reset the offset when the popup() is called again. Task-number: QTBUG-9505 --- src/gui/widgets/qmenu.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 4bea6de..d9233f5 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1795,10 +1795,14 @@ QSize QMenu::sizeHint() const void QMenu::popup(const QPoint &p, QAction *atAction) { Q_D(QMenu); +#ifndef Q_WS_S60 + //on S60 opens the menu at the same position it was activated last time + //there is no need to reset the offset fix for QTBUG-9505 if (d->scroll) { // reset scroll state from last popup d->scroll->scrollOffset = 0; d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone; } +#endif d->tearoffHighlighted = 0; d->motions = 0; d->doChildEffects = true; -- cgit v0.12 From 0b8a04253e4842465427b3fcf6918a220905db0c Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Mon, 29 Nov 2010 15:20:43 +0100 Subject: Fix documentation for QML extended types Fixes the documentation for QML extended types, one should use 'qmlRegisterExtendedType' instead of 'qmlRegisterType'. Reviewed-by: Leonardo Sobral Cunha --- doc/src/declarative/extending.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index 5c1b977..1e6e301 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -594,10 +594,10 @@ the appropriate property on the extension object is used instead. When an extended type is installed, one of the \code template -int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) +int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) template -int qmlRegisterType() +int qmlRegisterExtendedType() \endcode functions should be used instead of the regular \c qmlRegisterType() variations. The arguments are identical to the corresponding non-extension registration functions, -- cgit v0.12 From b5651eacb88739ab4c77d6fe220ec0fd98091849 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 29 Nov 2010 16:13:52 +0200 Subject: Updated language map in localize_deployment.prf Added missing Symbian language codes for which an Qt equivalent was available. Some codes were mapped to language/country pairs. Task-number: QTBUG-15293 Reviewed-by: Janne Koskinen --- mkspecs/common/symbian/symbian.conf | 6 ++++- mkspecs/features/symbian/localize_deployment.prf | 29 +++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index f8586b0..11907cf 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -139,7 +139,11 @@ SYMBIAN_SUPPORTED_LANGUAGES = \ mr mo mn nb pl pt pa ro ru sr \ si sk sl so es sw sv tl ta te \ th bo ti tr tk uk ur vi cy zu \ - nn + nn eu zh gl fa st en_US fr_BE \ + pt_BR en_CA fr_CA el_CY tr_CY \ + en_TW en_HK en_CN en_JP en_TH \ + sv_FI zh_HK es_419 en_ZA fr_CH \ + de_CH it_CH zh_TW # These directories must match what configure uses for QT_INSTALL_PLUGINS and QT_INSTALL_IMPORTS QT_PLUGINS_BASE_DIR = /resource/qt$${QT_LIBINFIX}/plugins diff --git a/mkspecs/features/symbian/localize_deployment.prf b/mkspecs/features/symbian/localize_deployment.prf index 5f52dbc..26a254b 100644 --- a/mkspecs/features/symbian/localize_deployment.prf +++ b/mkspecs/features/symbian/localize_deployment.prf @@ -3,11 +3,13 @@ SYMBIAN_LANG.sq = 35 #Albanian SYMBIAN_LANG.am = 36 #Amharic SYMBIAN_LANG.ar = 37 #Arabic SYMBIAN_LANG.hy = 38 #Armenian +SYMBIAN_LANG.eu = 102 #Basque SYMBIAN_LANG.bn = 41 #Bengali SYMBIAN_LANG.bg = 42 #Bulgarian SYMBIAN_LANG.my = 43 #Burmese SYMBIAN_LANG.be = 40 #Byelorussian SYMBIAN_LANG.ca = 44 #Catalan +SYMBIAN_LANG.zh = 31 #Chinese SYMBIAN_LANG.hr = 45 #Croatian SYMBIAN_LANG.cs = 25 #Czech SYMBIAN_LANG.da = 07 #Danish @@ -17,6 +19,7 @@ SYMBIAN_LANG.et = 49 #Estonian SYMBIAN_LANG.fi = 09 #Finnish SYMBIAN_LANG.fr = 02 #French SYMBIAN_LANG.gd = 52 #Gaelic +SYMBIAN_LANG.gl = 103 #Galician SYMBIAN_LANG.ka = 53 #Georgian SYMBIAN_LANG.de = 03 #German SYMBIAN_LANG.el = 54 #Greek @@ -42,6 +45,8 @@ SYMBIAN_LANG.mr = 72 #Marathi SYMBIAN_LANG.mo = 73 #Moldavian SYMBIAN_LANG.mn = 74 #Mongolian SYMBIAN_LANG.nb = 08 #Norwegian +SYMBIAN_LANG.nn = 75 #Nynorsk +SYMBIAN_LANG.fa = 50 #Persian SYMBIAN_LANG.pl = 27 #Polish SYMBIAN_LANG.pt = 13 #Portuguese SYMBIAN_LANG.pa = 77 #Punjabi @@ -52,6 +57,7 @@ SYMBIAN_LANG.si = 80 #Singhalese SYMBIAN_LANG.sk = 26 #Slovak SYMBIAN_LANG.sl = 28 #Slovenian SYMBIAN_LANG.so = 81 #Somali +SYMBIAN_LANG.st = 101 #South Sotho/Sesotho SYMBIAN_LANG.es = 04 #Spanish SYMBIAN_LANG.sw = 84 #Swahili SYMBIAN_LANG.sv = 06 #Swedish @@ -68,7 +74,28 @@ SYMBIAN_LANG.ur = 94 #Urdu SYMBIAN_LANG.vi = 96 #Vietnamese SYMBIAN_LANG.cy = 97 #Welsh SYMBIAN_LANG.zu = 98 #Zulu -SYMBIAN_LANG.nn = 75 #Nynorsk + +# Regional dialects +SYMBIAN_LANG.en_US = 10 #American English +SYMBIAN_LANG.fr_BE = 21 #Belgian French +SYMBIAN_LANG.pt_BR = 76 #Brazilian Portuguese +SYMBIAN_LANG.en_CA = 46 #Canadian English +SYMBIAN_LANG.fr_CA = 51 #Canadian French +SYMBIAN_LANG.el_CY = 55 #Cyprus Greek +SYMBIAN_LANG.tr_CY = 91 #Cyprus Turkish +SYMBIAN_LANG.en_TW = 157 #English as appropriate for use in Taiwan +SYMBIAN_LANG.en_HK = 158 #English as appropriate for use in Hong Kong +SYMBIAN_LANG.en_CN = 159 #English as appropriate for use in the Peoples Republic of China +SYMBIAN_LANG.en_JP = 160 #English as appropriate for use in Japan +SYMBIAN_LANG.en_TH = 161 #English as appropriate for use in Thailand +SYMBIAN_LANG.sv_FI = 85 #Finland Swedish +SYMBIAN_LANG.zh_HK = 30 #HongKong Chinese +SYMBIAN_LANG.es_419 = 83 #Latin American Spanish +SYMBIAN_LANG.en_ZA = 48 #South African English +SYMBIAN_LANG.fr_CH = 11 #Swiss French +SYMBIAN_LANG.de_CH = 12 #Swiss German +SYMBIAN_LANG.it_CH = 61 #Swiss Italian +SYMBIAN_LANG.zh_TW = 29 #Taiwan Chinese isEmpty(SYMBIAN_MATCHED_LANGUAGES) { matchSymbianLanguages() -- cgit v0.12 From 8e6d4283edc5fcf04a1a624a23e8fc1a9aa7c2d4 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Mon, 29 Nov 2010 19:08:47 +0100 Subject: Removed some new warnigs. --- src/gui/styles/qs60style_s60.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 7b75d40..92f53ff 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -698,7 +698,7 @@ void QS60StylePrivate::deleteStoredSettings() { QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); settings.beginGroup(QLatin1String("QS60Style")); - settings.remove(""); + settings.remove(QString()); settings.endGroup(); } @@ -717,7 +717,6 @@ QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const QT_TRAP_THROWING( CRepository *themeRepository = CRepository::NewLC(personalisationUID); if (themeRepository) { - static const TInt KThemePkgIDDesSize = 23; //size of the stored theme package ID TBuf<32> value; //themeID is currently max of 8 + 1 + 8 characters, but lets have some extra space const TUint32 key = 0x00000002; //active theme key in the repository error = themeRepository->Get(key, value); @@ -747,7 +746,7 @@ QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const return storedColor; } } - settings.remove(""); //if color was invalid, or theme has been changed, just delete all stored settings + settings.remove(QString()); //if color was invalid, or theme has been changed, just delete all stored settings } } #endif -- cgit v0.12 From 3aabc92c72bdd9f7e7bc67dd22dae203033e958a Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Tue, 30 Nov 2010 08:33:25 +1000 Subject: Fix resource leak in QEgl::getCompatibleVisualld() Contributed patch. Task-number: QT-4335 Reviewed-by: Daniel Pope --- src/gui/egl/qegl_x11.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index 15cc109..29415ed 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -165,8 +165,10 @@ VisualID QEgl::getCompatibleVisualId(EGLConfig config) if (chosenVisualInfo) { // Skip size checks if implementation supports non-matching visual // and config (http://bugreports.qt.nokia.com/browse/QTBUG-9444). - if (QEgl::hasExtension("EGL_NV_post_convert_rounding")) + if (QEgl::hasExtension("EGL_NV_post_convert_rounding")) { + XFree(chosenVisualInfo); return visualId; + } int visualRedSize = countBits(chosenVisualInfo->red_mask); int visualGreenSize = countBits(chosenVisualInfo->green_mask); -- cgit v0.12 From d1dbc94fad945e7a80ce0ca0d17b713d3685dc22 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Tue, 30 Nov 2010 09:53:46 +1000 Subject: Add license to example code --- doc/src/snippets/declarative/keynavigation.qml | 39 ++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/doc/src/snippets/declarative/keynavigation.qml b/doc/src/snippets/declarative/keynavigation.qml index d72bb3a..e11cdf1 100644 --- a/doc/src/snippets/declarative/keynavigation.qml +++ b/doc/src/snippets/declarative/keynavigation.qml @@ -1,3 +1,42 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ //![0] import QtQuick 1.0 -- cgit v0.12 From 067d63d03556d361b13f5d9fb9d41b78294fc04c Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 30 Nov 2010 11:08:48 +1000 Subject: Remove expect-fails from passing tests --- .../declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 8658217..14755f32 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -745,11 +745,9 @@ void tst_qdeclarativeecmascript::constantsOverrideBindings() QVERIFY(object != 0); QCOMPARE(object->property("c1").toInt(), 0); - QEXPECT_FAIL("", "QTBUG-13719", Continue); QCOMPARE(object->property("c3").toInt(), 10); object->setProperty("c1", QVariant(9)); QCOMPARE(object->property("c1").toInt(), 9); - QEXPECT_FAIL("", "QTBUG-13719", Continue); QCOMPARE(object->property("c3").toInt(), 10); } } -- cgit v0.12 From 47914053d93abe291ea85ad46e00fa8a6dc7a702 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Tue, 30 Nov 2010 11:55:51 +1000 Subject: Link to List Properties docs from QML Intro page Task-number: QTBUG-15606 --- doc/src/declarative/qdeclarativeintro.qdoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/src/declarative/qdeclarativeintro.qdoc b/doc/src/declarative/qdeclarativeintro.qdoc index 1d807e3..a3773fd 100644 --- a/doc/src/declarative/qdeclarativeintro.qdoc +++ b/doc/src/declarative/qdeclarativeintro.qdoc @@ -233,6 +233,10 @@ Image { } \endcode +Items in the list can be accessed by index. See the \l{list}{list type} documentation +for more details about list properties and their available operations. + + \section2 Default properties Each object type can specify one of its list or object properties as its default property. -- cgit v0.12 From e960316477982d21061ca8894109f1f8426b2dec Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Tue, 30 Nov 2010 12:19:18 +1000 Subject: Fix id documentation Task-number: QTBUG-15604 --- doc/src/declarative/qdeclarativeintro.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/declarative/qdeclarativeintro.qdoc b/doc/src/declarative/qdeclarativeintro.qdoc index a3773fd..4e41fda 100644 --- a/doc/src/declarative/qdeclarativeintro.qdoc +++ b/doc/src/declarative/qdeclarativeintro.qdoc @@ -186,7 +186,7 @@ Item { \section3 The \c id property Each object can be given a special unique property called an \e id. No other object within the -same \l{QML Documents}{QML document} can have the same \c id value. Assigning an id enables the object +same QML component (see \l{QML Documents}) can have the same \c id value. Assigning an id enables the object to be referred to by other objects and scripts. The first Rectangle element below has an \e id, "myRect". The second Rectangle element defines its -- cgit v0.12 From 282441f72a7704aadc5525a360430d0c3d49aea6 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Tue, 30 Nov 2010 11:37:09 +1000 Subject: Don't draw null pixmap in QDeclarativeImage paint function Task-number: QTBUG-15690 Reviewed-by: Martin Jones --- .../graphicsitems/qdeclarativeimage.cpp | 2 +- .../qdeclarativeimage/tst_qdeclarativeimage.cpp | 30 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp index 3b08a9b..aa74716 100644 --- a/src/declarative/graphicsitems/qdeclarativeimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp @@ -461,7 +461,7 @@ QRectF QDeclarativeImage::boundingRect() const void QDeclarativeImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) { Q_D(QDeclarativeImage); - if (d->pix.isNull()) + if (d->pix.pixmap().isNull() ) return; bool oldAA = p->testRenderHint(QPainter::Antialiasing); diff --git a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp index bf779ad..447210d 100644 --- a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp +++ b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp @@ -87,6 +87,7 @@ private slots: void noLoading(); void paintedWidthHeight(); void sourceSize_QTBUG_14303(); + void nullPixmapPaint(); private: template @@ -540,6 +541,35 @@ void tst_qdeclarativeimage::sourceSize_QTBUG_14303() QTRY_COMPARE(sourceSizeSpy.count(), 2); } +static int numberOfWarnings = 0; +static void checkWarnings(QtMsgType, const char *) +{ + numberOfWarnings++; +} + +// QTBUG-15690 +void tst_qdeclarativeimage::nullPixmapPaint() +{ + QString componentStr = QString("import QtQuick 1.0\nImage { width: 10; height:10; fillMode: Image.PreserveAspectFit; source: \"") + + SERVER_ADDR + QString("/no-such-file.png\" }"); + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeImage *image = qobject_cast(component.create()); + + QTRY_VERIFY(image != 0); + + QtMsgHandler previousMsgHandler = qInstallMsgHandler(checkWarnings); + + QPixmap pm(100, 100); + QPainter p(&pm); + + // used to print "QTransform::translate with NaN called" + image->paint(&p, 0, 0); + qInstallMsgHandler(previousMsgHandler); + QVERIFY(numberOfWarnings == 0); + delete image; +} + /* Find an item with the specified objectName. If index is supplied then the item must also evaluate the {index} expression equal to index -- cgit v0.12 From efc41eaa7224c33b5b5af7eae27c93c6748255bc Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 30 Nov 2010 13:48:30 +1000 Subject: Document which header to include for qmlRegister functions. Task-number: QTBUG-15630 Reviewed-by: Bea Lam --- doc/src/declarative/extending.qdoc | 2 ++ doc/src/declarative/qtdeclarative.qdoc | 16 ++++++++++++++++ .../declarative/qtbinding/newelements/imageviewer.h | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index 5c1b977..740f7d1 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -75,6 +75,8 @@ constructor. \endquotation +#include to use qmlRegisterType(). + Types can be registered by libraries, application code, or by plugins (see QDeclarativeExtensionPlugin). diff --git a/doc/src/declarative/qtdeclarative.qdoc b/doc/src/declarative/qtdeclarative.qdoc index f2b2032..b0c6e06 100644 --- a/doc/src/declarative/qtdeclarative.qdoc +++ b/doc/src/declarative/qtdeclarative.qdoc @@ -57,6 +57,8 @@ \relates QDeclarativeEngine Equivalent to \c Q_DECLARE_METATYPE(TYPE) and \c Q_DECLARE_METATYPE(QDeclarativeListProperty) + + #include to use this macro. */ /*! @@ -68,6 +70,8 @@ Current the only supported type info is \c QML_HAS_ATTACHED_PROPERTIES which declares that the \a Type supports \l {Attached Properties}. + + #include to use this macro. */ @@ -86,6 +90,10 @@ "com.mycompany.qmlcomponents": \code + #include + + ... + qmlRegisterType("com.mycompany.qmlcomponents", 1, 0, "Slider"); \endcode @@ -119,6 +127,8 @@ Returns the QML type id. + #include to use this function. + \sa qmlRegisterTypeNotAvailable() */ @@ -154,6 +164,8 @@ Without this, a generic "Game is not a type" message would be given. + #include to use this function. + \sa qmlRegisterUncreatableType() */ @@ -166,6 +178,8 @@ system. Instances of this type cannot be created from the QML system. + #include to use this function. + Returns the QML type id. */ @@ -176,5 +190,7 @@ This template function registers the C++ type in the QML system under the name \a typeName. + #include to use this function. + Returns the QML type id. */ diff --git a/doc/src/snippets/declarative/qtbinding/newelements/imageviewer.h b/doc/src/snippets/declarative/qtbinding/newelements/imageviewer.h index fd9db5e..cec9757 100644 --- a/doc/src/snippets/declarative/qtbinding/newelements/imageviewer.h +++ b/doc/src/snippets/declarative/qtbinding/newelements/imageviewer.h @@ -37,10 +37,10 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +//![0] #include #include -//![0] class ImageViewer : public QDeclarativeItem { Q_OBJECT -- cgit v0.12 From 1de080649c6b810ed6bc05e883795687ecde1f3d Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Fri, 29 Oct 2010 13:05:16 +1000 Subject: Fix Browser.qml warnings Task-number: QTBUG-15720 Reviewed-by: Martin Jones --- src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp | 2 +- .../qdeclarativeviewer/tst_qdeclarativeviewer.cpp | 12 ++++++++++++ tools/qml/browser/Browser.qml | 4 ++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp index abab33c..9c71004 100644 --- a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp +++ b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp @@ -279,7 +279,7 @@ void QDeclarativeFolderListModel::classBegin() void QDeclarativeFolderListModel::componentComplete() { - if (!d->folder.isValid() || !QDir().exists(d->folder.toLocalFile())) + if (!d->folder.isValid() || d->folder.toLocalFile().isEmpty() || !QDir().exists(d->folder.toLocalFile())) setFolder(QUrl(QLatin1String("file://")+QDir::currentPath())); if (!d->folderIndex.isValid()) diff --git a/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp b/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp index 21c7197..f19eb03 100644 --- a/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp +++ b/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp @@ -238,13 +238,25 @@ void tst_QDeclarativeViewer::loading() delete viewer; } +static int numberOfWarnings = 0; +static void checkWarnings(QtMsgType, const char *) +{ + numberOfWarnings++; +} + void tst_QDeclarativeViewer::fileBrowser() { + QtMsgHandler previousMsgHandler = qInstallMsgHandler(checkWarnings); QDeclarativeViewer *viewer = new QDeclarativeViewer(); QVERIFY(viewer); viewer->setUseNativeFileBrowser(false); viewer->openFile(); viewer->show(); + QCoreApplication::processEvents(); + qInstallMsgHandler(previousMsgHandler); + + // QTBUG-15720 + QVERIFY(numberOfWarnings == 0); QApplication::setActiveWindow(viewer); QTest::qWaitForWindowShown(viewer); diff --git a/tools/qml/browser/Browser.qml b/tools/qml/browser/Browser.qml index ebed72f..b9573da 100644 --- a/tools/qml/browser/Browser.qml +++ b/tools/qml/browser/Browser.qml @@ -180,7 +180,7 @@ Rectangle { GradientStop { id: t1; position: 0.0; color: palette.highlight } GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) } } - width: view1.currentItem.width + width: view1.currentItem == null ? 0 : view1.currentItem.width } highlightMoveSpeed: 1000 pressDelay: 100 @@ -230,7 +230,7 @@ Rectangle { GradientStop { id: t1; position: 0.0; color: palette.highlight } GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) } } - width: view1.currentItem.width + width: view1.currentItem == null ? 0 : view1.currentItem.width } highlightMoveSpeed: 1000 pressDelay: 100 -- cgit v0.12 From 46213b30d639505849d079b30e72ef8393e9a748 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 30 Nov 2010 14:30:35 +1000 Subject: Correctly handle CppOwnership even when a QDeclarativeData doesn't exist Task-number: QTBUG-15695 --- src/declarative/qml/qdeclarativeengine.cpp | 4 +- .../tst_qdeclarativeecmascript.cpp | 46 ++++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index c646302..add1ab7 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -897,9 +897,7 @@ void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership own if (!object) return; - // No need to do anything if CppOwnership and there is no QDeclarativeData as - // the current ownership must be CppOwnership - QDeclarativeData *ddata = QDeclarativeData::get(object, ownership == JavaScriptOwnership); + QDeclarativeData *ddata = QDeclarativeData::get(object, true); if (!ddata) return; diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 14755f32..7c0a316 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -135,6 +135,7 @@ private slots: void scriptConnect(); void scriptDisconnect(); void ownership(); + void cppOwnershipReturnValue(); void qlistqobjectMethods(); void strictlyEquals(); void compiled(); @@ -2100,6 +2101,51 @@ void tst_qdeclarativeecmascript::ownership() } } +class CppOwnershipReturnValue : public QObject +{ + Q_OBJECT +public: + CppOwnershipReturnValue() : value(0) {} + + Q_INVOKABLE QObject *create() { + Q_ASSERT(value == 0); + + value = new QObject; + QDeclarativeEngine::setObjectOwnership(value, QDeclarativeEngine::CppOwnership); + return value; + } + + QPointer value; +}; + +// QTBUG-15695. +// Test setObjectOwnership(CppOwnership) works even when there is no QDeclarativeData +void tst_qdeclarativeecmascript::cppOwnershipReturnValue() +{ + CppOwnershipReturnValue source; + + { + QDeclarativeEngine engine; + engine.rootContext()->setContextProperty("source", &source); + + QVERIFY(source.value == 0); + + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 1.0\nQtObject {\nComponent.onCompleted: { var a = source.create(); }\n}\n", QUrl()); + + QObject *object = component.create(); + + QVERIFY(object != 0); + QVERIFY(source.value != 0); + + delete object; + } + + QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion); + + QVERIFY(source.value != 0); +} + class QListQObjectMethodsObject : public QObject { Q_OBJECT -- cgit v0.12 From 16cbe54f41ff4ff9a03ce3973c52be32d63b7138 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 30 Nov 2010 15:13:42 +1000 Subject: Correct ownership semantics for QObject derived types Task-number: QTBUG-15697 --- .../qml/qdeclarativeobjectscriptclass.cpp | 11 +++++-- .../tst_qdeclarativeecmascript.cpp | 37 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index eff59df..b0bc5bb 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -69,7 +69,7 @@ struct ObjectData : public QScriptDeclarativeClass::Object { virtual ~ObjectData() { if (object && !object->parent()) { QDeclarativeData *ddata = QDeclarativeData::get(object, false); - if (ddata && !ddata->indestructible && 0 == --ddata->objectDataRefCount) + if (ddata && !ddata->indestructible && 0 == --ddata->objectDataRefCount) object->deleteLater(); } } @@ -808,7 +808,14 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) } return QScriptDeclarativeClass::Value(engine, rv); } else if (type == -1 || type == qMetaTypeId()) { - return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->scriptValueFromVariant(*((QVariant *)&data))); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(e); + QScriptValue rv = ep->scriptValueFromVariant(*((QVariant *)&data)); + if (rv.isQObject()) { + QObject *object = rv.toQObject(); + if (object) + QDeclarativeData::get(object, true)->setImplicitDestructible(); + } + return QScriptDeclarativeClass::Value(engine, rv); } else { return QScriptDeclarativeClass::Value(); } diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 7c0a316..77fab91 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -136,6 +136,7 @@ private slots: void scriptDisconnect(); void ownership(); void cppOwnershipReturnValue(); + void ownershipCustomReturnValue(); void qlistqobjectMethods(); void strictlyEquals(); void compiled(); @@ -2106,6 +2107,7 @@ class CppOwnershipReturnValue : public QObject Q_OBJECT public: CppOwnershipReturnValue() : value(0) {} + ~CppOwnershipReturnValue() { delete value; } Q_INVOKABLE QObject *create() { Q_ASSERT(value == 0); @@ -2115,6 +2117,14 @@ public: return value; } + Q_INVOKABLE MyQmlObject *createQmlObject() { + Q_ASSERT(value == 0); + + MyQmlObject *rv = new MyQmlObject; + value = rv; + return rv; + } + QPointer value; }; @@ -2146,6 +2156,33 @@ void tst_qdeclarativeecmascript::cppOwnershipReturnValue() QVERIFY(source.value != 0); } +// QTBUG-15697 +void tst_qdeclarativeecmascript::ownershipCustomReturnValue() +{ + CppOwnershipReturnValue source; + + { + QDeclarativeEngine engine; + engine.rootContext()->setContextProperty("source", &source); + + QVERIFY(source.value == 0); + + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 1.0\nQtObject {\nComponent.onCompleted: { var a = source.createQmlObject(); }\n}\n", QUrl()); + + QObject *object = component.create(); + + QVERIFY(object != 0); + QVERIFY(source.value != 0); + + delete object; + } + + QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion); + + QVERIFY(source.value == 0); +} + class QListQObjectMethodsObject : public QObject { Q_OBJECT -- cgit v0.12 From fe3cfced940f41d078380ef7bdebe40d85aa49a2 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Tue, 30 Nov 2010 15:23:45 +1000 Subject: Fix integer overflow in QDeclarativeItemPrivate::origin enumeration Task-number: QTBUG-15694 Reviewed-by: Martin Jones --- src/declarative/graphicsitems/qdeclarativeitem_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h index f85fa27..d8635b9 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem_p.h +++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h @@ -259,7 +259,7 @@ public: QDeclarativeStateGroup *_states(); QDeclarativeStateGroup *_stateGroup; - QDeclarativeItem::TransformOrigin origin:4; + QDeclarativeItem::TransformOrigin origin:5; bool widthValid:1; bool heightValid:1; bool componentComplete:1; -- cgit v0.12 From 840ffbd6187fe2573d8c00481120d4cf30aed351 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 30 Nov 2010 15:54:25 +1000 Subject: Ensure header is considered when positioning content with snapping. When snapping is enabled the header was ignored and content would be aligned with the first item rather than the header, when at the top of the view. Task-number: QTBUG-15710 Reviewed-by: Bea Lam --- .../graphicsitems/qdeclarativegridview.cpp | 37 ++++++++++++---------- .../graphicsitems/qdeclarativelistview.cpp | 6 +++- .../tst_qdeclarativegridview.cpp | 2 +- .../qdeclarativelistview/data/header.qml | 31 ++++++++++++++++++ .../tst_qdeclarativelistview.cpp | 31 ++++++++++++++++++ 5 files changed, 89 insertions(+), 18 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativelistview/data/header.qml diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 6f38f63..4454284 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -219,12 +219,8 @@ public: } } else { qreal pos = (modelIndex / columns) * rowSize(); - if (header) { - qreal headerSize = flow == QDeclarativeGridView::LeftToRight - ? header->item->height() - : header->item->width(); - pos += headerSize; - } + if (header) + pos += headerSize(); return pos; } return 0; @@ -291,11 +287,9 @@ public: if (item->index == -1) continue; qreal itemTop = item->rowPos(); - if (item->index == model->count()-1 || (itemTop+rowSize()/2 >= pos)) + if (itemTop+rowSize()/2 >= pos && itemTop - rowSize()/2 <= pos) return item; } - if (visibleItems.count() && visibleItems.first()->rowPos() <= pos) - return visibleItems.first(); return 0; } @@ -315,6 +309,16 @@ public: return index; } + qreal headerSize() const { + if (!header) + return 0.0; + + return flow == QDeclarativeGridView::LeftToRight + ? header->item->height() + : header->item->width(); + } + + virtual void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) { Q_Q(const QDeclarativeGridView); QDeclarativeFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry); @@ -878,14 +882,11 @@ void QDeclarativeGridViewPrivate::updateHeader() if (header) { if (visibleItems.count()) { qreal startPos = startPosition(); - qreal headerSize = flow == QDeclarativeGridView::LeftToRight - ? header->item->height() - : header->item->width(); if (visibleIndex == 0) { - header->setPosition(0, startPos - headerSize); + header->setPosition(0, startPos - headerSize()); } else { - if (position() <= startPos || header->rowPos() > startPos - headerSize) - header->setPosition(0, startPos - headerSize); + if (position() <= startPos || header->rowPos() > startPos - headerSize()) + header->setPosition(0, startPos - headerSize()); } } else { header->setPosition(0, 0); @@ -920,10 +921,14 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m qreal bottomPos = qMax(bottomItem->rowPos() - highlightRangeEnd, -minExtent); pos = qAbs(data.move + topPos) < qAbs(data.move + bottomPos) ? topPos : bottomPos; } else if (topItem) { - pos = qMax(qMin(topItem->rowPos() - highlightRangeStart, -maxExtent), -minExtent); + if (topItem->index == 0 && header && position()+highlightRangeStart < header->rowPos()+headerSize()/2) + pos = header->rowPos() - highlightRangeStart; + else + pos = qMax(qMin(topItem->rowPos() - highlightRangeStart, -maxExtent), -minExtent); } else if (bottomItem) { pos = qMax(qMin(bottomItem->rowPos() - highlightRangeStart, -maxExtent), -minExtent); } else { + QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent); fixupDuration = oldDuration; return; } diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 450b6af..d1f52be 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -1185,10 +1185,14 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m FxListItem *bottomItem = snapItemAt(position()+highlightRangeEnd); qreal pos; if (topItem) { - pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent); + if (topItem->index == 0 && header && position()+highlightRangeStart < header->position()+header->size()/2) + pos = header->position() - highlightRangeStart; + else + pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent); } else if (bottomItem) { pos = qMax(qMin(bottomItem->position() - highlightRangeStart, -maxExtent), -minExtent); } else { + QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent); fixupDuration = oldDuration; return; } diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index 327bba2..7998e30 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -1263,7 +1263,7 @@ void tst_QDeclarativeGridView::header() QDeclarativeView *canvas = createView(); TestModel model; - for (int i = 0; i < 7; i++) + for (int i = 0; i < 30; i++) model.addItem("Item" + QString::number(i), ""); QDeclarativeContext *ctxt = canvas->rootContext(); diff --git a/tests/auto/declarative/qdeclarativelistview/data/header.qml b/tests/auto/declarative/qdeclarativelistview/data/header.qml new file mode 100644 index 0000000..6da996e --- /dev/null +++ b/tests/auto/declarative/qdeclarativelistview/data/header.qml @@ -0,0 +1,31 @@ +import QtQuick 1.0 + +Rectangle { + width: 240 + height: 320 + color: "#ffffff" + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 30 + width: 240 + Text { + text: index + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + } + ListView { + id: list + objectName: "list" + focus: true + width: 240 + height: 320 + snapMode: ListView.SnapToItem + model: testModel + delegate: myDelegate + header: Text { objectName: "header"; text: "Header"; height: 10 } + } +} diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 37d836d..295a75d 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -98,6 +98,7 @@ private slots: void QTBUG_9791(); void manualHighlight(); void QTBUG_11105(); + void header(); void footer(); void resizeView(); void sizeLessThan1(); @@ -1661,6 +1662,36 @@ void tst_QDeclarativeListView::QTBUG_11105() delete canvas; } +void tst_QDeclarativeListView::header() +{ + QDeclarativeView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 30; 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(); + + QDeclarativeListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QDeclarativeItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QDeclarativeText *header = findItem(contentItem, "header"); + QVERIFY(header); + QCOMPARE(header->y(), 0.0); + + QCOMPARE(listview->contentY(), 0.0); + + model.clear(); + QTRY_COMPARE(header->y(), 0.0); +} + void tst_QDeclarativeListView::footer() { QDeclarativeView *canvas = createView(); -- cgit v0.12 From ec1526a73fef7d95268437204fa8534085940fbc Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 23 Nov 2010 14:30:51 +0000 Subject: Fix compile error on symbian Symbian doesn't have file owners, the resolveUserName / resolveGroupName functions have been correctly moved to unix only scope which caused a compile error. This change makes the QFSFileEngine::owner[Id] return -2 / QString() for symbian directly. Reviewed-by: Markus Goetz --- src/corelib/io/qfsfileengine_unix.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 035e78f..55388e6 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -861,9 +861,13 @@ uint QFSFileEngine::ownerId(FileOwner own) const QString QFSFileEngine::owner(FileOwner own) const { +#ifndef Q_OS_SYMBIAN if (own == OwnerUser) return QFileSystemEngine::resolveUserName(ownerId(own)); return QFileSystemEngine::resolveGroupName(ownerId(own)); +#else + return QString(); +#endif } bool QFSFileEngine::setPermissions(uint perms) -- cgit v0.12 From 9120864d7263cd1ed288770314e387de95d14bf3 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 29 Nov 2010 13:48:03 +0000 Subject: Update with def files merged from master This set of def files is good to merge back, if the merge is done soon. Reviewed-by: Trust Me --- src/s60installs/bwins/QtCoreu.def | 105 +++++++++++++++++++++ src/s60installs/bwins/QtGuiu.def | 156 +++++++++++++++++++++++++++++++- src/s60installs/eabi/QtCoreu.def | 80 ++++++++++++++++ src/s60installs/eabi/QtDeclarativeu.def | 4 +- src/s60installs/eabi/QtGuiu.def | 130 +++++++++++++++++++++++++- 5 files changed, 468 insertions(+), 7 deletions(-) diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def index b0bf2cc..a3c7fbb 100644 --- a/src/s60installs/bwins/QtCoreu.def +++ b/src/s60installs/bwins/QtCoreu.def @@ -4486,4 +4486,109 @@ EXPORTS ?objectNameChanged@QAbstractDeclarativeData@@2P6AXPAV1@PAVQObject@@@ZA @ 4485 NONAME ; void (*QAbstractDeclarativeData::objectNameChanged)(class QAbstractDeclarativeData *, class QObject *) ?queueDeferredActiveObjectsCompletion@QEventDispatcherSymbian@@QAEXXZ @ 4486 NONAME ; void QEventDispatcherSymbian::queueDeferredActiveObjectsCompletion(void) ?reactivateDeferredActiveObjects@QEventDispatcherSymbian@@UAEXXZ @ 4487 NONAME ; void QEventDispatcherSymbian::reactivateDeferredActiveObjects(void) + ??0QAnimationDriver@@IAE@AAVQAnimationDriverPrivate@@PAVQObject@@@Z @ 4488 NONAME ; QAnimationDriver::QAnimationDriver(class QAnimationDriverPrivate &, class QObject *) + ??0QAnimationDriver@@QAE@PAVQObject@@@Z @ 4489 NONAME ; QAnimationDriver::QAnimationDriver(class QObject *) + ??0QAnimationDriverPrivate@@QAE@XZ @ 4490 NONAME ; QAnimationDriverPrivate::QAnimationDriverPrivate(void) + ??0QCoreApplication@@QAE@AAHPAPADH@Z @ 4491 NONAME ; QCoreApplication::QCoreApplication(int &, char * *, int) + ??0QCoreApplicationPrivate@@QAE@AAHPAPADI@Z @ 4492 NONAME ; QCoreApplicationPrivate::QCoreApplicationPrivate(int &, char * *, unsigned int) + ??0QFileInfo@@QAE@PAVQFileInfoPrivate@@@Z @ 4493 NONAME ; QFileInfo::QFileInfo(class QFileInfoPrivate *) + ??0QSystemError@@QAE@HW4ErrorScope@0@@Z @ 4494 NONAME ; QSystemError::QSystemError(int, enum QSystemError::ErrorScope) + ??0QSystemError@@QAE@XZ @ 4495 NONAME ; QSystemError::QSystemError(void) + ??0QUnifiedTimer@@AAE@XZ @ 4496 NONAME ; QUnifiedTimer::QUnifiedTimer(void) + ??0QXmlStreamAttributes@@QAE@XZ @ 4497 NONAME ; QXmlStreamAttributes::QXmlStreamAttributes(void) + ??1QAnimationDriver@@UAE@XZ @ 4498 NONAME ; QAnimationDriver::~QAnimationDriver(void) + ??1QAnimationDriverPrivate@@UAE@XZ @ 4499 NONAME ; QAnimationDriverPrivate::~QAnimationDriverPrivate(void) + ??1QUnifiedTimer@@UAE@XZ @ 4500 NONAME ; QUnifiedTimer::~QUnifiedTimer(void) + ??_EQAnimationDriver@@UAE@I@Z @ 4501 NONAME ; QAnimationDriver::~QAnimationDriver(unsigned int) + ??_EQAnimationDriverPrivate@@UAE@I@Z @ 4502 NONAME ; QAnimationDriverPrivate::~QAnimationDriverPrivate(unsigned int) + ??_EQUnifiedTimer@@UAE@I@Z @ 4503 NONAME ; QUnifiedTimer::~QUnifiedTimer(unsigned int) + ?advance@QAnimationDriver@@QAEXXZ @ 4504 NONAME ; void QAnimationDriver::advance(void) + ?cast@QMetaObject@@QBEPBVQObject@@PBV2@@Z @ 4505 NONAME ; class QObject const * QMetaObject::cast(class QObject const *) const + ?closestPauseAnimationTimeToFinish@QUnifiedTimer@@AAEHXZ @ 4506 NONAME ; int QUnifiedTimer::closestPauseAnimationTimeToFinish(void) + ?connect@QObject@@SA_NPBV1@ABVQMetaMethod@@01W4ConnectionType@Qt@@@Z @ 4507 NONAME ; bool QObject::connect(class QObject const *, class QMetaMethod const &, class QObject const *, class QMetaMethod const &, enum Qt::ConnectionType) + ?contains@QString@@QBE?AVQBool@@ABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4508 NONAME ; class QBool QString::contains(class QStringRef const &, enum Qt::CaseSensitivity) const + ?contains@QStringRef@@QBE?AVQBool@@ABV1@W4CaseSensitivity@Qt@@@Z @ 4509 NONAME ; class QBool QStringRef::contains(class QStringRef const &, enum Qt::CaseSensitivity) const + ?contains@QStringRef@@QBE?AVQBool@@ABVQString@@W4CaseSensitivity@Qt@@@Z @ 4510 NONAME ; class QBool QStringRef::contains(class QString const &, enum Qt::CaseSensitivity) const + ?contains@QStringRef@@QBE?AVQBool@@VQChar@@W4CaseSensitivity@Qt@@@Z @ 4511 NONAME ; class QBool QStringRef::contains(class QChar, enum Qt::CaseSensitivity) const + ?contains@QStringRef@@QBE?AVQBool@@VQLatin1String@@W4CaseSensitivity@Qt@@@Z @ 4512 NONAME ; class QBool QStringRef::contains(class QLatin1String, enum Qt::CaseSensitivity) const + ?count@QString@@QBEHABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4513 NONAME ; int QString::count(class QStringRef const &, enum Qt::CaseSensitivity) const + ?count@QStringRef@@QBEHABV1@W4CaseSensitivity@Qt@@@Z @ 4514 NONAME ; int QStringRef::count(class QStringRef const &, enum Qt::CaseSensitivity) const + ?count@QStringRef@@QBEHABVQString@@W4CaseSensitivity@Qt@@@Z @ 4515 NONAME ; int QStringRef::count(class QString const &, enum Qt::CaseSensitivity) const + ?count@QStringRef@@QBEHVQChar@@W4CaseSensitivity@Qt@@@Z @ 4516 NONAME ; int QStringRef::count(class QChar, enum Qt::CaseSensitivity) const + ?d_func@QAnimationDriver@@AAEPAVQAnimationDriverPrivate@@XZ @ 4517 NONAME ; class QAnimationDriverPrivate * QAnimationDriver::d_func(void) + ?d_func@QAnimationDriver@@ABEPBVQAnimationDriverPrivate@@XZ @ 4518 NONAME ; class QAnimationDriverPrivate const * QAnimationDriver::d_func(void) const + ?disconnect@QObject@@SA_NPBV1@ABVQMetaMethod@@01@Z @ 4519 NONAME ; bool QObject::disconnect(class QObject const *, class QMetaMethod const &, class QObject const *, class QMetaMethod const &) + ?endsWith@QString@@QBE_NABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4520 NONAME ; bool QString::endsWith(class QStringRef const &, enum Qt::CaseSensitivity) const + ?endsWith@QStringRef@@QBE_NABV1@W4CaseSensitivity@Qt@@@Z @ 4521 NONAME ; bool QStringRef::endsWith(class QStringRef const &, enum Qt::CaseSensitivity) const + ?endsWith@QStringRef@@QBE_NABVQString@@W4CaseSensitivity@Qt@@@Z @ 4522 NONAME ; bool QStringRef::endsWith(class QString const &, enum Qt::CaseSensitivity) const + ?endsWith@QStringRef@@QBE_NVQChar@@W4CaseSensitivity@Qt@@@Z @ 4523 NONAME ; bool QStringRef::endsWith(class QChar, enum Qt::CaseSensitivity) const + ?endsWith@QStringRef@@QBE_NVQLatin1String@@W4CaseSensitivity@Qt@@@Z @ 4524 NONAME ; bool QStringRef::endsWith(class QLatin1String, enum Qt::CaseSensitivity) const + ?ensureTimerUpdate@QUnifiedTimer@@SAXXZ @ 4525 NONAME ; void QUnifiedTimer::ensureTimerUpdate(void) + ?error@QSystemError@@QAEHXZ @ 4526 NONAME ; int QSystemError::error(void) + ?getStaticMetaObject@QAnimationDriver@@SAABUQMetaObject@@XZ @ 4527 NONAME ; struct QMetaObject const & QAnimationDriver::getStaticMetaObject(void) + ?indexOf@QString@@QBEHABVQStringRef@@HW4CaseSensitivity@Qt@@@Z @ 4528 NONAME ; int QString::indexOf(class QStringRef const &, int, enum Qt::CaseSensitivity) const + ?indexOf@QStringRef@@QBEHABV1@HW4CaseSensitivity@Qt@@@Z @ 4529 NONAME ; int QStringRef::indexOf(class QStringRef const &, int, enum Qt::CaseSensitivity) const + ?indexOf@QStringRef@@QBEHABVQString@@HW4CaseSensitivity@Qt@@@Z @ 4530 NONAME ; int QStringRef::indexOf(class QString const &, int, enum Qt::CaseSensitivity) const + ?indexOf@QStringRef@@QBEHVQChar@@HW4CaseSensitivity@Qt@@@Z @ 4531 NONAME ; int QStringRef::indexOf(class QChar, int, enum Qt::CaseSensitivity) const + ?indexOf@QStringRef@@QBEHVQLatin1String@@HW4CaseSensitivity@Qt@@@Z @ 4532 NONAME ; int QStringRef::indexOf(class QLatin1String, int, enum Qt::CaseSensitivity) const + ?install@QAnimationDriver@@QAEXXZ @ 4533 NONAME ; void QAnimationDriver::install(void) + ?installAnimationDriver@QUnifiedTimer@@QAEXPAVQAnimationDriver@@@Z @ 4534 NONAME ; void QUnifiedTimer::installAnimationDriver(class QAnimationDriver *) + ?instance@QUnifiedTimer@@SAPAV1@_N@Z @ 4535 NONAME ; class QUnifiedTimer * QUnifiedTimer::instance(bool) + ?isLocalFile@QUrl@@QBE_NXZ @ 4536 NONAME ; bool QUrl::isLocalFile(void) const + ?isRunning@QAnimationDriver@@QBE_NXZ @ 4537 NONAME ; bool QAnimationDriver::isRunning(void) const + ?lastIndexOf@QString@@QBEHABVQStringRef@@HW4CaseSensitivity@Qt@@@Z @ 4538 NONAME ; int QString::lastIndexOf(class QStringRef const &, int, enum Qt::CaseSensitivity) const + ?lastIndexOf@QStringRef@@QBEHABV1@HW4CaseSensitivity@Qt@@@Z @ 4539 NONAME ; int QStringRef::lastIndexOf(class QStringRef const &, int, enum Qt::CaseSensitivity) const + ?lastIndexOf@QStringRef@@QBEHABVQString@@HW4CaseSensitivity@Qt@@@Z @ 4540 NONAME ; int QStringRef::lastIndexOf(class QString const &, int, enum Qt::CaseSensitivity) const + ?lastIndexOf@QStringRef@@QBEHVQChar@@HW4CaseSensitivity@Qt@@@Z @ 4541 NONAME ; int QStringRef::lastIndexOf(class QChar, int, enum Qt::CaseSensitivity) const + ?lastIndexOf@QStringRef@@QBEHVQLatin1String@@HW4CaseSensitivity@Qt@@@Z @ 4542 NONAME ; int QStringRef::lastIndexOf(class QLatin1String, int, enum Qt::CaseSensitivity) const + ?lockInline@QMutex@@QAEXXZ @ 4543 NONAME ; void QMutex::lockInline(void) + ?lockInternal@QMutex@@AAEXXZ @ 4544 NONAME ; void QMutex::lockInternal(void) + ?metaObject@QAnimationDriver@@UBEPBUQMetaObject@@XZ @ 4545 NONAME ; struct QMetaObject const * QAnimationDriver::metaObject(void) const + ?nativeKey@QSharedMemory@@QBE?AVQString@@XZ @ 4546 NONAME ; class QString QSharedMemory::nativeKey(void) const + ?qt_metacall@QAnimationDriver@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 4547 NONAME ; int QAnimationDriver::qt_metacall(enum QMetaObject::Call, int, void * *) + ?qt_metacast@QAnimationDriver@@UAEPAXPBD@Z @ 4548 NONAME ; void * QAnimationDriver::qt_metacast(char const *) + ?registerAnimation@QUnifiedTimer@@SAXPAVQAbstractAnimation@@_N@Z @ 4549 NONAME ; void QUnifiedTimer::registerAnimation(class QAbstractAnimation *, bool) + ?registerRunningAnimation@QUnifiedTimer@@AAEXPAVQAbstractAnimation@@@Z @ 4550 NONAME ; void QUnifiedTimer::registerRunningAnimation(class QAbstractAnimation *) + ?restartAnimationTimer@QUnifiedTimer@@QAEXXZ @ 4551 NONAME ; void QUnifiedTimer::restartAnimationTimer(void) + ?scope@QSystemError@@QAE?AW4ErrorScope@1@XZ @ 4552 NONAME ; enum QSystemError::ErrorScope QSystemError::scope(void) + ?senderSignalIndex@QObject@@IBEHXZ @ 4553 NONAME ; int QObject::senderSignalIndex(void) const + ?setConsistentTiming@QUnifiedTimer@@QAEX_N@Z @ 4554 NONAME ; void QUnifiedTimer::setConsistentTiming(bool) + ?setNativeKey@QSharedMemory@@QAEXABVQString@@@Z @ 4555 NONAME ; void QSharedMemory::setNativeKey(class QString const &) + ?setSlowModeEnabled@QUnifiedTimer@@QAEX_N@Z @ 4556 NONAME ; void QUnifiedTimer::setSlowModeEnabled(bool) + ?setSlowdownFactor@QUnifiedTimer@@QAEXM@Z @ 4557 NONAME ; void QUnifiedTimer::setSlowdownFactor(float) + ?setTimingInterval@QUnifiedTimer@@QAEXH@Z @ 4558 NONAME ; void QUnifiedTimer::setTimingInterval(int) + ?start@QAnimationDriver@@AAEXXZ @ 4559 NONAME ; void QAnimationDriver::start(void) + ?startsWith@QString@@QBE_NABVQStringRef@@W4CaseSensitivity@Qt@@@Z @ 4560 NONAME ; bool QString::startsWith(class QStringRef const &, enum Qt::CaseSensitivity) const + ?startsWith@QStringRef@@QBE_NABV1@W4CaseSensitivity@Qt@@@Z @ 4561 NONAME ; bool QStringRef::startsWith(class QStringRef const &, enum Qt::CaseSensitivity) const + ?startsWith@QStringRef@@QBE_NABVQString@@W4CaseSensitivity@Qt@@@Z @ 4562 NONAME ; bool QStringRef::startsWith(class QString const &, enum Qt::CaseSensitivity) const + ?startsWith@QStringRef@@QBE_NVQChar@@W4CaseSensitivity@Qt@@@Z @ 4563 NONAME ; bool QStringRef::startsWith(class QChar, enum Qt::CaseSensitivity) const + ?startsWith@QStringRef@@QBE_NVQLatin1String@@W4CaseSensitivity@Qt@@@Z @ 4564 NONAME ; bool QStringRef::startsWith(class QLatin1String, enum Qt::CaseSensitivity) const + ?stop@QAnimationDriver@@AAEXXZ @ 4565 NONAME ; void QAnimationDriver::stop(void) + ?swap@QBitArray@@QAEXAAV1@@Z @ 4566 NONAME ; void QBitArray::swap(class QBitArray &) + ?swap@QByteArray@@QAEXAAV1@@Z @ 4567 NONAME ; void QByteArray::swap(class QByteArray &) + ?swap@QRegExp@@QAEXAAV1@@Z @ 4568 NONAME ; void QRegExp::swap(class QRegExp &) + ?swap@QString@@QAEXAAV1@@Z @ 4569 NONAME ; void QString::swap(class QString &) + ?swap@QUrl@@QAEXAAV1@@Z @ 4570 NONAME ; void QUrl::swap(class QUrl &) + ?swap@QVariant@@QAEXAAV1@@Z @ 4571 NONAME ; void QVariant::swap(class QVariant &) + ?timerEvent@QUnifiedTimer@@MAEXPAVQTimerEvent@@@Z @ 4572 NONAME ; void QUnifiedTimer::timerEvent(class QTimerEvent *) + ?toAscii@QStringRef@@QBE?AVQByteArray@@XZ @ 4573 NONAME ; class QByteArray QStringRef::toAscii(void) const + ?toLatin1@QStringRef@@QBE?AVQByteArray@@XZ @ 4574 NONAME ; class QByteArray QStringRef::toLatin1(void) const + ?toLocal8Bit@QStringRef@@QBE?AVQByteArray@@XZ @ 4575 NONAME ; class QByteArray QStringRef::toLocal8Bit(void) const + ?toString@QSystemError@@QAE?AVQString@@XZ @ 4576 NONAME ; class QString QSystemError::toString(void) + ?toUcs4@QStringRef@@QBE?AV?$QVector@I@@XZ @ 4577 NONAME ; class QVector QStringRef::toUcs4(void) const + ?toUtf8@QStringRef@@QBE?AVQByteArray@@XZ @ 4578 NONAME ; class QByteArray QStringRef::toUtf8(void) const + ?tr@QAnimationDriver@@SA?AVQString@@PBD0@Z @ 4579 NONAME ; class QString QAnimationDriver::tr(char const *, char const *) + ?tr@QAnimationDriver@@SA?AVQString@@PBD0H@Z @ 4580 NONAME ; class QString QAnimationDriver::tr(char const *, char const *, int) + ?trUtf8@QAnimationDriver@@SA?AVQString@@PBD0@Z @ 4581 NONAME ; class QString QAnimationDriver::trUtf8(char const *, char const *) + ?trUtf8@QAnimationDriver@@SA?AVQString@@PBD0H@Z @ 4582 NONAME ; class QString QAnimationDriver::trUtf8(char const *, char const *, int) + ?tryLockInline@QMutex@@QAE_NXZ @ 4583 NONAME ; bool QMutex::tryLockInline(void) + ?unlockInline@QMutex@@QAEXXZ @ 4584 NONAME ; void QMutex::unlockInline(void) + ?unlockInternal@QMutex@@AAEXXZ @ 4585 NONAME ; void QMutex::unlockInternal(void) + ?unregisterAnimation@QUnifiedTimer@@SAXPAVQAbstractAnimation@@@Z @ 4586 NONAME ; void QUnifiedTimer::unregisterAnimation(class QAbstractAnimation *) + ?unregisterRunningAnimation@QUnifiedTimer@@AAEXPAVQAbstractAnimation@@@Z @ 4587 NONAME ; void QUnifiedTimer::unregisterRunningAnimation(class QAbstractAnimation *) + ?updateAnimationTimer@QUnifiedTimer@@SAXXZ @ 4588 NONAME ; void QUnifiedTimer::updateAnimationTimer(void) + ?updateAnimationsTime@QUnifiedTimer@@QAEXXZ @ 4589 NONAME ; void QUnifiedTimer::updateAnimationsTime(void) + ?waitForDone@QThreadPool@@QAE_NH@Z @ 4590 NONAME ; bool QThreadPool::waitForDone(int) + ?app_compile_version@QCoreApplicationPrivate@@2HA @ 4591 NONAME ; int QCoreApplicationPrivate::app_compile_version + ?staticMetaObject@QAnimationDriver@@2UQMetaObject@@B @ 4592 NONAME ; struct QMetaObject const QAnimationDriver::staticMetaObject diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index b4a5dfc..8d8f500 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -464,7 +464,7 @@ EXPORTS ??0QRadioButton@@QAE@ABVQString@@PAVQWidget@@@Z @ 463 NONAME ; QRadioButton::QRadioButton(class QString const &, class QWidget *) ??0QRadioButton@@QAE@PAVQWidget@@@Z @ 464 NONAME ; QRadioButton::QRadioButton(class QWidget *) ??0QRasterPixmapData@@QAE@W4PixelType@QPixmapData@@@Z @ 465 NONAME ; QRasterPixmapData::QRasterPixmapData(enum QPixmapData::PixelType) - ??0QRasterWindowSurface@@QAE@PAVQWidget@@@Z @ 466 NONAME ; QRasterWindowSurface::QRasterWindowSurface(class QWidget *) + ??0QRasterWindowSurface@@QAE@PAVQWidget@@@Z @ 466 NONAME ABSENT ; QRasterWindowSurface::QRasterWindowSurface(class QWidget *) ??0QRegExpValidator@@QAE@ABVQRegExp@@PAVQObject@@@Z @ 467 NONAME ; QRegExpValidator::QRegExpValidator(class QRegExp const &, class QObject *) ??0QRegExpValidator@@QAE@PAVQObject@@@Z @ 468 NONAME ; QRegExpValidator::QRegExpValidator(class QObject *) ??0QRegion@@QAE@ABV0@@Z @ 469 NONAME ; QRegion::QRegion(class QRegion const &) @@ -845,7 +845,7 @@ EXPORTS ??0QWidgetResizeHandler@@QAE@PAVQWidget@@0@Z @ 844 NONAME ; QWidgetResizeHandler::QWidgetResizeHandler(class QWidget *, class QWidget *) ??0QWindowStateChangeEvent@@QAE@V?$QFlags@W4WindowState@Qt@@@@@Z @ 845 NONAME ; QWindowStateChangeEvent::QWindowStateChangeEvent(class QFlags) ??0QWindowStateChangeEvent@@QAE@V?$QFlags@W4WindowState@Qt@@@@_N@Z @ 846 NONAME ; QWindowStateChangeEvent::QWindowStateChangeEvent(class QFlags, bool) - ??0QWindowSurface@@QAE@PAVQWidget@@@Z @ 847 NONAME ; QWindowSurface::QWindowSurface(class QWidget *) + ??0QWindowSurface@@QAE@PAVQWidget@@@Z @ 847 NONAME ABSENT ; QWindowSurface::QWindowSurface(class QWidget *) ??0QWindowsStyle@@IAE@AAVQWindowsStylePrivate@@@Z @ 848 NONAME ; QWindowsStyle::QWindowsStyle(class QWindowsStylePrivate &) ??0QWindowsStyle@@QAE@XZ @ 849 NONAME ; QWindowsStyle::QWindowsStyle(void) ??0QWizard@@QAE@PAVQWidget@@V?$QFlags@W4WindowType@Qt@@@@@Z @ 850 NONAME ; QWizard::QWizard(class QWidget *, class QFlags) @@ -12898,4 +12898,156 @@ EXPORTS ?qmljsDebugArgumentsString@QApplicationPrivate@@SA?AVQString@@XZ @ 12897 NONAME ; class QString QApplicationPrivate::qmljsDebugArgumentsString(void) ?convertToPostscriptFontFamilyName@QFontEngine@@SA?AVQByteArray@@ABV2@@Z @ 12898 NONAME ; class QByteArray QFontEngine::convertToPostscriptFontFamilyName(class QByteArray const &) ?lastResortFont@QFont@@QBE?AVQString@@XZ @ 12899 NONAME ; class QString QFont::lastResortFont(void) const + ??0QApplicationPrivate@@QAE@AAHPAPADW4Type@QApplication@@H@Z @ 12900 NONAME ; QApplicationPrivate::QApplicationPrivate(int &, char * *, enum QApplication::Type, int) + ??0QBlittable@@QAE@ABVQSize@@V?$QFlags@W4Capability@QBlittable@@@@@Z @ 12901 NONAME ; QBlittable::QBlittable(class QSize const &, class QFlags) + ??0QBlittablePixmapData@@QAE@XZ @ 12902 NONAME ; QBlittablePixmapData::QBlittablePixmapData(void) + ??0QBlitterPaintEngine@@QAE@PAVQBlittablePixmapData@@@Z @ 12903 NONAME ; QBlitterPaintEngine::QBlitterPaintEngine(class QBlittablePixmapData *) + ??0QGlyphs@@QAE@ABV0@@Z @ 12904 NONAME ; QGlyphs::QGlyphs(class QGlyphs const &) + ??0QGlyphs@@QAE@XZ @ 12905 NONAME ; QGlyphs::QGlyphs(void) + ??0QRasterWindowSurface@@QAE@PAVQWidget@@_N@Z @ 12906 NONAME ; QRasterWindowSurface::QRasterWindowSurface(class QWidget *, bool) + ??0QStaticTextItem@@QAE@ABV0@@Z @ 12907 NONAME ; QStaticTextItem::QStaticTextItem(class QStaticTextItem const &) + ??0QWindowSurface@@QAE@PAVQWidget@@_N@Z @ 12908 NONAME ; QWindowSurface::QWindowSurface(class QWidget *, bool) + ??1QBlittable@@UAE@XZ @ 12909 NONAME ; QBlittable::~QBlittable(void) + ??1QBlittablePixmapData@@UAE@XZ @ 12910 NONAME ; QBlittablePixmapData::~QBlittablePixmapData(void) + ??1QBlitterPaintEngine@@UAE@XZ @ 12911 NONAME ; QBlitterPaintEngine::~QBlitterPaintEngine(void) + ??1QGlyphs@@QAE@XZ @ 12912 NONAME ; QGlyphs::~QGlyphs(void) + ??4QGlyphs@@QAEAAV0@ABV0@@Z @ 12913 NONAME ; class QGlyphs & QGlyphs::operator=(class QGlyphs const &) + ??4QStaticTextItem@@QAEXABV0@@Z @ 12914 NONAME ; void QStaticTextItem::operator=(class QStaticTextItem const &) + ??6@YA?AVQDebug@@V0@PBVQSymbianEvent@@@Z @ 12915 NONAME ; class QDebug operator<<(class QDebug, class QSymbianEvent const *) + ??8QGlyphs@@QBE_NABV0@@Z @ 12916 NONAME ; bool QGlyphs::operator==(class QGlyphs const &) const + ??9QGlyphs@@QBE_NABV0@@Z @ 12917 NONAME ; bool QGlyphs::operator!=(class QGlyphs const &) const + ??HQGlyphs@@ABE?AV0@ABV0@@Z @ 12918 NONAME ; class QGlyphs QGlyphs::operator+(class QGlyphs const &) const + ??MQItemSelectionRange@@QBE_NABV0@@Z @ 12919 NONAME ; bool QItemSelectionRange::operator<(class QItemSelectionRange const &) const + ??YQGlyphs@@AAEAAV0@ABV0@@Z @ 12920 NONAME ; class QGlyphs & QGlyphs::operator+=(class QGlyphs const &) + ??_EQBlittable@@UAE@I@Z @ 12921 NONAME ; QBlittable::~QBlittable(unsigned int) + ??_EQBlittablePixmapData@@UAE@I@Z @ 12922 NONAME ; QBlittablePixmapData::~QBlittablePixmapData(unsigned int) + ??_EQBlitterPaintEngine@@UAE@I@Z @ 12923 NONAME ; QBlitterPaintEngine::~QBlitterPaintEngine(unsigned int) + ?alphaMapBoundingBox@QFontEngine@@UAE?AUglyph_metrics_t@@IABVQTransform@@W4GlyphFormat@1@@Z @ 12924 NONAME ; struct glyph_metrics_t QFontEngine::alphaMapBoundingBox(unsigned int, class QTransform const &, enum QFontEngine::GlyphFormat) + ?alphaMapForGlyph@QFontEngine@@UAE?AVQImage@@IUQFixed@@@Z @ 12925 NONAME ; class QImage QFontEngine::alphaMapForGlyph(unsigned int, struct QFixed) + ?alphaMapForGlyph@QFontEngine@@UAE?AVQImage@@IUQFixed@@ABVQTransform@@@Z @ 12926 NONAME ; class QImage QFontEngine::alphaMapForGlyph(unsigned int, struct QFixed, class QTransform const &) + ?alphaRGBMapForGlyph@QFontEngine@@UAE?AVQImage@@IUQFixed@@HABVQTransform@@@Z @ 12927 NONAME ; class QImage QFontEngine::alphaRGBMapForGlyph(unsigned int, struct QFixed, int, class QTransform const &) + ?begin@QBlitterPaintEngine@@UAE_NPAVQPaintDevice@@@Z @ 12928 NONAME ; bool QBlitterPaintEngine::begin(class QPaintDevice *) + ?blittable@QBlittablePixmapData@@QBEPAVQBlittable@@XZ @ 12929 NONAME ; class QBlittable * QBlittablePixmapData::blittable(void) const + ?brushChanged@QBlitterPaintEngine@@UAEXXZ @ 12930 NONAME ; void QBlitterPaintEngine::brushChanged(void) + ?brushOriginChanged@QBlitterPaintEngine@@UAEXXZ @ 12931 NONAME ; void QBlitterPaintEngine::brushOriginChanged(void) + ?buddy@QAbstractProxyModel@@UBE?AVQModelIndex@@ABV2@@Z @ 12932 NONAME ; class QModelIndex QAbstractProxyModel::buddy(class QModelIndex const &) const + ?buffer@QBlittablePixmapData@@UAEPAVQImage@@XZ @ 12933 NONAME ; class QImage * QBlittablePixmapData::buffer(void) + ?calculateSubPixelPositionCount@QTextureGlyphCache@@IBEHI@Z @ 12934 NONAME ; int QTextureGlyphCache::calculateSubPixelPositionCount(unsigned int) const + ?canFetchMore@QAbstractProxyModel@@UBE_NABVQModelIndex@@@Z @ 12935 NONAME ; bool QAbstractProxyModel::canFetchMore(class QModelIndex const &) const + ?capabilities@QBlittable@@QBE?AV?$QFlags@W4Capability@QBlittable@@@@XZ @ 12936 NONAME ; class QFlags QBlittable::capabilities(void) const + ?clear@QGlyphs@@QAEXXZ @ 12937 NONAME ; void QGlyphs::clear(void) + ?clip@QBlitterPaintEngine@@QAEPBVQClipData@@XZ @ 12938 NONAME ; class QClipData const * QBlitterPaintEngine::clip(void) + ?clip@QBlitterPaintEngine@@UAEXABVQRect@@W4ClipOperation@Qt@@@Z @ 12939 NONAME ; void QBlitterPaintEngine::clip(class QRect const &, enum Qt::ClipOperation) + ?clip@QBlitterPaintEngine@@UAEXABVQRegion@@W4ClipOperation@Qt@@@Z @ 12940 NONAME ; void QBlitterPaintEngine::clip(class QRegion const &, enum Qt::ClipOperation) + ?clip@QBlitterPaintEngine@@UAEXABVQVectorPath@@W4ClipOperation@Qt@@@Z @ 12941 NONAME ; void QBlitterPaintEngine::clip(class QVectorPath const &, enum Qt::ClipOperation) + ?clipBoundingRect@QPainter@@QBE?AVQRectF@@XZ @ 12942 NONAME ; class QRectF QPainter::clipBoundingRect(void) const + ?clipEnabledChanged@QBlitterPaintEngine@@UAEXXZ @ 12943 NONAME ; void QBlitterPaintEngine::clipEnabledChanged(void) + ?compositionModeChanged@QBlitterPaintEngine@@UAEXXZ @ 12944 NONAME ; void QBlitterPaintEngine::compositionModeChanged(void) + ?createExplicitFont@QFontEngine@@UBE?AVQFont@@XZ @ 12945 NONAME ; class QFont QFontEngine::createExplicitFont(void) const + ?createExplicitFontWithName@QFontEngine@@IBE?AVQFont@@ABVQString@@@Z @ 12946 NONAME ; class QFont QFontEngine::createExplicitFontWithName(class QString const &) const + ?createState@QBlitterPaintEngine@@UBEPAVQPainterState@@PAV2@@Z @ 12947 NONAME ; class QPainterState * QBlitterPaintEngine::createState(class QPainterState *) const + ?d_func@QBlittable@@AAEPAVQBlittablePrivate@@XZ @ 12948 NONAME ; class QBlittablePrivate * QBlittable::d_func(void) + ?d_func@QBlittable@@ABEPBVQBlittablePrivate@@XZ @ 12949 NONAME ; class QBlittablePrivate const * QBlittable::d_func(void) const + ?d_func@QBlitterPaintEngine@@AAEPAVQBlitterPaintEnginePrivate@@XZ @ 12950 NONAME ; class QBlitterPaintEnginePrivate * QBlitterPaintEngine::d_func(void) + ?d_func@QBlitterPaintEngine@@ABEPBVQBlitterPaintEnginePrivate@@XZ @ 12951 NONAME ; class QBlitterPaintEnginePrivate const * QBlitterPaintEngine::d_func(void) const + ?detach@QGlyphs@@AAEXXZ @ 12952 NONAME ; void QGlyphs::detach(void) + ?drawEllipse@QBlitterPaintEngine@@UAEXABVQRectF@@@Z @ 12953 NONAME ; void QBlitterPaintEngine::drawEllipse(class QRectF const &) + ?drawGlyphs@QPainter@@QAEXABVQPointF@@ABVQGlyphs@@@Z @ 12954 NONAME ; void QPainter::drawGlyphs(class QPointF const &, class QGlyphs const &) + ?drawImage@QBlitterPaintEngine@@UAEXABVQRectF@@ABVQImage@@0V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 12955 NONAME ; void QBlitterPaintEngine::drawImage(class QRectF const &, class QImage const &, class QRectF const &, class QFlags) + ?drawPixmap@QBlitterPaintEngine@@UAEXABVQRectF@@ABVQPixmap@@0@Z @ 12956 NONAME ; void QBlitterPaintEngine::drawPixmap(class QRectF const &, class QPixmap const &, class QRectF const &) + ?drawRects@QBlitterPaintEngine@@UAEXPBVQRect@@H@Z @ 12957 NONAME ; void QBlitterPaintEngine::drawRects(class QRect const *, int) + ?drawRects@QBlitterPaintEngine@@UAEXPBVQRectF@@H@Z @ 12958 NONAME ; void QBlitterPaintEngine::drawRects(class QRectF const *, int) + ?drawStaticTextItem@QBlitterPaintEngine@@UAEXPAVQStaticTextItem@@@Z @ 12959 NONAME ; void QBlitterPaintEngine::drawStaticTextItem(class QStaticTextItem *) + ?drawTextItem@QBlitterPaintEngine@@UAEXABVQPointF@@ABVQTextItem@@@Z @ 12960 NONAME ; void QBlitterPaintEngine::drawTextItem(class QPointF const &, class QTextItem const &) + ?end@QBlitterPaintEngine@@UAE_NXZ @ 12961 NONAME ; bool QBlitterPaintEngine::end(void) + ?fetchMore@QAbstractProxyModel@@UAEXABVQModelIndex@@@Z @ 12962 NONAME ; void QAbstractProxyModel::fetchMore(class QModelIndex const &) + ?fill@QBlittablePixmapData@@UAEXABVQColor@@@Z @ 12963 NONAME ; void QBlittablePixmapData::fill(class QColor const &) + ?fill@QBlitterPaintEngine@@UAEXABVQVectorPath@@ABVQBrush@@@Z @ 12964 NONAME ; void QBlitterPaintEngine::fill(class QVectorPath const &, class QBrush const &) + ?fill@QImage@@QAEXABVQColor@@@Z @ 12965 NONAME ; void QImage::fill(class QColor const &) + ?fill@QImage@@QAEXW4GlobalColor@Qt@@@Z @ 12966 NONAME ; void QImage::fill(enum Qt::GlobalColor) + ?fillInPendingGlyphs@QTextureGlyphCache@@QAEXXZ @ 12967 NONAME ; void QTextureGlyphCache::fillInPendingGlyphs(void) + ?fillRect@QBlitterPaintEngine@@UAEXABVQRectF@@ABVQBrush@@@Z @ 12968 NONAME ; void QBlitterPaintEngine::fillRect(class QRectF const &, class QBrush const &) + ?fillRect@QBlitterPaintEngine@@UAEXABVQRectF@@ABVQColor@@@Z @ 12969 NONAME ; void QBlitterPaintEngine::fillRect(class QRectF const &, class QColor const &) + ?fillTexture@QImageTextureGlyphCache@@UAEXABUCoord@QTextureGlyphCache@@IUQFixed@@@Z @ 12970 NONAME ; void QImageTextureGlyphCache::fillTexture(struct QTextureGlyphCache::Coord const &, unsigned int, struct QFixed) + ?font@QGlyphs@@QBE?AVQFont@@XZ @ 12971 NONAME ; class QFont QGlyphs::font(void) const + ?fontEngine@QStaticTextItem@@QBEPAVQFontEngine@@XZ @ 12972 NONAME ; class QFontEngine * QStaticTextItem::fontEngine(void) const + ?fromImage@QBlittablePixmapData@@UAEXABVQImage@@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 12973 NONAME ; void QBlittablePixmapData::fromImage(class QImage const &, class QFlags) + ?get@QFontPrivate@@SAPAV1@ABVQFont@@@Z @ 12974 NONAME ; class QFontPrivate * QFontPrivate::get(class QFont const &) + ?getItem@QInputDialog@@SA?AVQString@@PAVQWidget@@ABV2@1ABVQStringList@@H_NPA_NV?$QFlags@W4WindowType@Qt@@@@V?$QFlags@W4InputMethodHint@Qt@@@@@Z @ 12975 NONAME ; class QString QInputDialog::getItem(class QWidget *, class QString const &, class QString const &, class QStringList const &, int, bool, bool *, class QFlags, class QFlags) + ?getText@QInputDialog@@SA?AVQString@@PAVQWidget@@ABV2@1W4EchoMode@QLineEdit@@1PA_NV?$QFlags@W4WindowType@Qt@@@@V?$QFlags@W4InputMethodHint@Qt@@@@@Z @ 12976 NONAME ; class QString QInputDialog::getText(class QWidget *, class QString const &, class QString const &, enum QLineEdit::EchoMode, class QString const &, bool *, class QFlags, class QFlags) + ?glyphIndexes@QGlyphs@@QBE?AV?$QVector@I@@XZ @ 12977 NONAME ; class QVector QGlyphs::glyphIndexes(void) const + ?glyphs@QTextFragment@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 12978 NONAME ; class QList QTextFragment::glyphs(void) const + ?glyphs@QTextLayout@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 12979 NONAME ; class QList QTextLayout::glyphs(void) const + ?glyphs@QTextLine@@ABE?AV?$QList@VQGlyphs@@@@HH@Z @ 12980 NONAME ; class QList QTextLine::glyphs(int, int) const + ?hasAlphaChannel@QBlittablePixmapData@@UBE_NXZ @ 12981 NONAME ; bool QBlittablePixmapData::hasAlphaChannel(void) const + ?hasChildren@QAbstractProxyModel@@UBE_NABVQModelIndex@@@Z @ 12982 NONAME ; bool QAbstractProxyModel::hasChildren(class QModelIndex const &) const + ?hasHeightForWidth@QWidgetPrivate@@UBE_NXZ @ 12983 NONAME ; bool QWidgetPrivate::hasHeightForWidth(void) const + ?hasWidthForHeight@QSizePolicy@@QBE_NXZ @ 12984 NONAME ; bool QSizePolicy::hasWidthForHeight(void) const + ?heightForWidth@QTabWidget@@UBEHH@Z @ 12985 NONAME ; int QTabWidget::heightForWidth(int) const + ?inFontUcs4@QFontMetrics@@QBE_NI@Z @ 12986 NONAME ; bool QFontMetrics::inFontUcs4(unsigned int) const + ?inFontUcs4@QFontMetricsF@@QBE_NI@Z @ 12987 NONAME ; bool QFontMetricsF::inFontUcs4(unsigned int) const + ?lock@QBlittable@@QAEPAVQImage@@XZ @ 12988 NONAME ; class QImage * QBlittable::lock(void) + ?markRasterOverlay@QBlittablePixmapData@@QAEXABVQPointF@@ABVQTextItem@@@Z @ 12989 NONAME ; void QBlittablePixmapData::markRasterOverlay(class QPointF const &, class QTextItem const &) + ?markRasterOverlay@QBlittablePixmapData@@QAEXABVQRectF@@@Z @ 12990 NONAME ; void QBlittablePixmapData::markRasterOverlay(class QRectF const &) + ?markRasterOverlay@QBlittablePixmapData@@QAEXABVQVectorPath@@@Z @ 12991 NONAME ; void QBlittablePixmapData::markRasterOverlay(class QVectorPath const &) + ?markRasterOverlay@QBlittablePixmapData@@QAEXPBVQRect@@H@Z @ 12992 NONAME ; void QBlittablePixmapData::markRasterOverlay(class QRect const *, int) + ?markRasterOverlay@QBlittablePixmapData@@QAEXPBVQRectF@@H@Z @ 12993 NONAME ; void QBlittablePixmapData::markRasterOverlay(class QRectF const *, int) + ?metric@QBlittablePixmapData@@UBEHW4PaintDeviceMetric@QPaintDevice@@@Z @ 12994 NONAME ; int QBlittablePixmapData::metric(enum QPaintDevice::PaintDeviceMetric) const + ?mimeData@QAbstractProxyModel@@UBEPAVQMimeData@@ABV?$QList@VQModelIndex@@@@@Z @ 12995 NONAME ; class QMimeData * QAbstractProxyModel::mimeData(class QList const &) const + ?mimeTypes@QAbstractProxyModel@@UBE?AVQStringList@@XZ @ 12996 NONAME ; class QStringList QAbstractProxyModel::mimeTypes(void) const + ?minimumSizeHint@QCheckBox@@UBE?AVQSize@@XZ @ 12997 NONAME ; class QSize QCheckBox::minimumSizeHint(void) const + ?minimumSizeHint@QRadioButton@@UBE?AVQSize@@XZ @ 12998 NONAME ; class QSize QRadioButton::minimumSizeHint(void) const + ?numberPrefix@QTextListFormat@@QBE?AVQString@@XZ @ 12999 NONAME ; class QString QTextListFormat::numberPrefix(void) const + ?numberSuffix@QTextListFormat@@QBE?AVQString@@XZ @ 13000 NONAME ; class QString QTextListFormat::numberSuffix(void) const + ?opacityChanged@QBlitterPaintEngine@@UAEXXZ @ 13001 NONAME ; void QBlitterPaintEngine::opacityChanged(void) + ?paintEngine@QBlittablePixmapData@@UBEPAVQPaintEngine@@XZ @ 13002 NONAME ; class QPaintEngine * QBlittablePixmapData::paintEngine(void) const + ?penChanged@QBlitterPaintEngine@@UAEXXZ @ 13003 NONAME ; void QBlitterPaintEngine::penChanged(void) + ?positions@QGlyphs@@QBE?AV?$QVector@VQPointF@@@@XZ @ 13004 NONAME ; class QVector QGlyphs::positions(void) const + ?qt_addBitmapToPath@@YAXMMPBEHHHPAVQPainterPath@@@Z @ 13005 NONAME ; void qt_addBitmapToPath(float, float, unsigned char const *, int, int, int, class QPainterPath *) + ?qt_fontdata_from_index@@YA?AVQByteArray@@H@Z @ 13006 NONAME ; class QByteArray qt_fontdata_from_index(int) + ?raster@QBlitterPaintEngine@@ABEPAVQRasterPaintEngine@@XZ @ 13007 NONAME ; class QRasterPaintEngine * QBlitterPaintEngine::raster(void) const + ?reactivateDeferredActiveObjects@QEventDispatcherS60@@UAEXXZ @ 13008 NONAME ; void QEventDispatcherS60::reactivateDeferredActiveObjects(void) + ?removeItem@QGraphicsGridLayout@@QAEXPAVQGraphicsLayoutItem@@@Z @ 13009 NONAME ; void QGraphicsGridLayout::removeItem(class QGraphicsLayoutItem *) + ?renderHintsChanged@QBlitterPaintEngine@@UAEXXZ @ 13010 NONAME ; void QBlitterPaintEngine::renderHintsChanged(void) + ?resetInternalData@QAbstractProxyModel@@IAEXXZ @ 13011 NONAME ; void QAbstractProxyModel::resetInternalData(void) + ?resize@QBlittablePixmapData@@UAEXHH@Z @ 13012 NONAME ; void QBlittablePixmapData::resize(int, int) + ?resizeCache@QTextureGlyphCache@@QAEXHH@Z @ 13013 NONAME ; void QTextureGlyphCache::resizeCache(int, int) + ?setBlittable@QBlittablePixmapData@@QAEXPAVQBlittable@@@Z @ 13014 NONAME ; void QBlittablePixmapData::setBlittable(class QBlittable *) + ?setFont@QGlyphs@@QAEXABVQFont@@@Z @ 13015 NONAME ; void QGlyphs::setFont(class QFont const &) + ?setFontEngine@QStaticTextItem@@QAEXPAVQFontEngine@@@Z @ 13016 NONAME ; void QStaticTextItem::setFontEngine(class QFontEngine *) + ?setGlyphIndexes@QGlyphs@@QAEXABV?$QVector@I@@@Z @ 13017 NONAME ; void QGlyphs::setGlyphIndexes(class QVector const &) + ?setItemData@QAbstractProxyModel@@UAE_NABVQModelIndex@@ABV?$QMap@HVQVariant@@@@@Z @ 13018 NONAME ; bool QAbstractProxyModel::setItemData(class QModelIndex const &, class QMap const &) + ?setNumberPrefix@QTextListFormat@@QAEXABVQString@@@Z @ 13019 NONAME ; void QTextListFormat::setNumberPrefix(class QString const &) + ?setNumberSuffix@QTextListFormat@@QAEXABVQString@@@Z @ 13020 NONAME ; void QTextListFormat::setNumberSuffix(class QString const &) + ?setPositions@QGlyphs@@QAEXABV?$QVector@VQPointF@@@@@Z @ 13021 NONAME ; void QGlyphs::setPositions(class QVector const &) + ?setState@QBlitterPaintEngine@@UAEXPAVQPainterState@@@Z @ 13022 NONAME ; void QBlitterPaintEngine::setState(class QPainterState *) + ?setWidthForHeight@QSizePolicy@@QAEX_N@Z @ 13023 NONAME ; void QSizePolicy::setWidthForHeight(bool) + ?size@QBlittable@@QBE?AVQSize@@XZ @ 13024 NONAME ; class QSize QBlittable::size(void) const + ?sort@QAbstractProxyModel@@UAEXHW4SortOrder@Qt@@@Z @ 13025 NONAME ; void QAbstractProxyModel::sort(int, enum Qt::SortOrder) + ?span@QAbstractProxyModel@@UBE?AVQSize@@ABVQModelIndex@@@Z @ 13026 NONAME ; class QSize QAbstractProxyModel::span(class QModelIndex const &) const + ?state@QBlitterPaintEngine@@QAEPAVQPainterState@@XZ @ 13027 NONAME ; class QPainterState * QBlitterPaintEngine::state(void) + ?state@QBlitterPaintEngine@@QBEPBVQPainterState@@XZ @ 13028 NONAME ; class QPainterState const * QBlitterPaintEngine::state(void) const + ?stroke@QBlitterPaintEngine@@UAEXABVQVectorPath@@ABVQPen@@@Z @ 13029 NONAME ; void QBlitterPaintEngine::stroke(class QVectorPath const &, class QPen const &) + ?subPixelPositionForX@QTextureGlyphCache@@QBE?AUQFixed@@U2@@Z @ 13030 NONAME ; struct QFixed QTextureGlyphCache::subPixelPositionForX(struct QFixed) const + ?supportedDropActions@QAbstractProxyModel@@UBE?AV?$QFlags@W4DropAction@Qt@@@@XZ @ 13031 NONAME ; class QFlags QAbstractProxyModel::supportedDropActions(void) const + ?supportsSubPixelPositions@QFontEngine@@UBE_NXZ @ 13032 NONAME ; bool QFontEngine::supportsSubPixelPositions(void) const + ?swap@QBitmap@@QAEXAAV1@@Z @ 13033 NONAME ; void QBitmap::swap(class QBitmap &) + ?swap@QBrush@@QAEXAAV1@@Z @ 13034 NONAME ; void QBrush::swap(class QBrush &) + ?swap@QIcon@@QAEXAAV1@@Z @ 13035 NONAME ; void QIcon::swap(class QIcon &) + ?swap@QImage@@QAEXAAV1@@Z @ 13036 NONAME ; void QImage::swap(class QImage &) + ?swap@QKeySequence@@QAEXAAV1@@Z @ 13037 NONAME ; void QKeySequence::swap(class QKeySequence &) + ?swap@QPainterPath@@QAEXAAV1@@Z @ 13038 NONAME ; void QPainterPath::swap(class QPainterPath &) + ?swap@QPen@@QAEXAAV1@@Z @ 13039 NONAME ; void QPen::swap(class QPen &) + ?swap@QPicture@@QAEXAAV1@@Z @ 13040 NONAME ; void QPicture::swap(class QPicture &) + ?swap@QPixmap@@QAEXAAV1@@Z @ 13041 NONAME ; void QPixmap::swap(class QPixmap &) + ?swap@QPolygon@@QAEXAAV1@@Z @ 13042 NONAME ; void QPolygon::swap(class QPolygon &) + ?swap@QPolygonF@@QAEXAAV1@@Z @ 13043 NONAME ; void QPolygonF::swap(class QPolygonF &) + ?swap@QRegion@@QAEXAAV1@@Z @ 13044 NONAME ; void QRegion::swap(class QRegion &) + ?textureMapForGlyph@QTextureGlyphCache@@QBE?AVQImage@@IUQFixed@@@Z @ 13045 NONAME ; class QImage QTextureGlyphCache::textureMapForGlyph(unsigned int, struct QFixed) const + ?toImage@QBlittablePixmapData@@UBE?AVQImage@@XZ @ 13046 NONAME ; class QImage QBlittablePixmapData::toImage(void) const + ?transformChanged@QBlitterPaintEngine@@UAEXXZ @ 13047 NONAME ; void QBlitterPaintEngine::transformChanged(void) + ?type@QBlitterPaintEngine@@UBE?AW4Type@QPaintEngine@@XZ @ 13048 NONAME ; enum QPaintEngine::Type QBlitterPaintEngine::type(void) const + ?unlock@QBlittable@@QAEXXZ @ 13049 NONAME ; void QBlittable::unlock(void) + ?unmarkRasterOverlay@QBlittablePixmapData@@QAEXABVQRectF@@@Z @ 13050 NONAME ; void QBlittablePixmapData::unmarkRasterOverlay(class QRectF const &) + ?userData@QStaticTextItem@@QBEPAVQStaticTextUserData@@XZ @ 13051 NONAME ; class QStaticTextUserData * QStaticTextItem::userData(void) const diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index 3864914..5939010 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -3714,4 +3714,84 @@ EXPORTS _Z26qt_symbian_SetupThreadHeapiR24SStdEpocThreadCreateInfo @ 3713 NONAME _ZN24QAbstractDeclarativeData17objectNameChangedE @ 3714 NONAME DATA 4 _ZN23QEventDispatcherSymbian36queueDeferredActiveObjectsCompletionEv @ 3715 NONAME + _ZN11QThreadPool11waitForDoneEi @ 3716 NONAME + _ZN12QSystemError8toStringEv @ 3717 NONAME + _ZN13QSharedMemory12setNativeKeyERK7QString @ 3718 NONAME + _ZN13QUnifiedTimer10timerEventEP11QTimerEvent @ 3719 NONAME + _ZN13QUnifiedTimer17ensureTimerUpdateEv @ 3720 NONAME + _ZN13QUnifiedTimer17registerAnimationEP18QAbstractAnimationb @ 3721 NONAME + _ZN13QUnifiedTimer17setTimingIntervalEi @ 3722 NONAME + _ZN13QUnifiedTimer19unregisterAnimationEP18QAbstractAnimation @ 3723 NONAME + _ZN13QUnifiedTimer20updateAnimationTimerEv @ 3724 NONAME + _ZN13QUnifiedTimer20updateAnimationsTimeEv @ 3725 NONAME + _ZN13QUnifiedTimer21restartAnimationTimerEv @ 3726 NONAME + _ZN13QUnifiedTimer22installAnimationDriverEP16QAnimationDriver @ 3727 NONAME + _ZN13QUnifiedTimer24registerRunningAnimationEP18QAbstractAnimation @ 3728 NONAME + _ZN13QUnifiedTimer26unregisterRunningAnimationEP18QAbstractAnimation @ 3729 NONAME + _ZN13QUnifiedTimer33closestPauseAnimationTimeToFinishEv @ 3730 NONAME + _ZN13QUnifiedTimer8instanceEb @ 3731 NONAME + _ZN13QUnifiedTimerC1Ev @ 3732 NONAME + _ZN13QUnifiedTimerC2Ev @ 3733 NONAME + _ZN16QAnimationDriver11qt_metacallEN11QMetaObject4CallEiPPv @ 3734 NONAME + _ZN16QAnimationDriver11qt_metacastEPKc @ 3735 NONAME + _ZN16QAnimationDriver16staticMetaObjectE @ 3736 NONAME DATA 16 + _ZN16QAnimationDriver19getStaticMetaObjectEv @ 3737 NONAME + _ZN16QAnimationDriver4stopEv @ 3738 NONAME + _ZN16QAnimationDriver5startEv @ 3739 NONAME + _ZN16QAnimationDriver7advanceEv @ 3740 NONAME + _ZN16QAnimationDriver7installEv @ 3741 NONAME + _ZN16QAnimationDriverC2EP7QObject @ 3742 NONAME + _ZN16QAnimationDriverC2ER23QAnimationDriverPrivateP7QObject @ 3743 NONAME + _ZN16QCoreApplicationC1ERiPPci @ 3744 NONAME + _ZN16QCoreApplicationC2ERiPPci @ 3745 NONAME + _ZN23QCoreApplicationPrivate19app_compile_versionE @ 3746 NONAME DATA 4 + _ZN23QCoreApplicationPrivateC1ERiPPcj @ 3747 NONAME + _ZN23QCoreApplicationPrivateC2ERiPPcj @ 3748 NONAME + _ZN6QMutex12lockInternalEv @ 3749 NONAME + _ZN6QMutex14unlockInternalEv @ 3750 NONAME + _ZN7QObject10disconnectEPKS_RK11QMetaMethodS1_S4_ @ 3751 NONAME + _ZN7QObject7connectEPKS_RK11QMetaMethodS1_S4_N2Qt14ConnectionTypeE @ 3752 NONAME + _ZN9QFileInfoC1EP16QFileInfoPrivate @ 3753 NONAME + _ZN9QFileInfoC2EP16QFileInfoPrivate @ 3754 NONAME + _ZNK10QStringRef10startsWithE13QLatin1StringN2Qt15CaseSensitivityE @ 3755 NONAME + _ZNK10QStringRef10startsWithE5QCharN2Qt15CaseSensitivityE @ 3756 NONAME + _ZNK10QStringRef10startsWithERK7QStringN2Qt15CaseSensitivityE @ 3757 NONAME + _ZNK10QStringRef10startsWithERKS_N2Qt15CaseSensitivityE @ 3758 NONAME + _ZNK10QStringRef11lastIndexOfE13QLatin1StringiN2Qt15CaseSensitivityE @ 3759 NONAME + _ZNK10QStringRef11lastIndexOfE5QChariN2Qt15CaseSensitivityE @ 3760 NONAME + _ZNK10QStringRef11lastIndexOfERK7QStringiN2Qt15CaseSensitivityE @ 3761 NONAME + _ZNK10QStringRef11lastIndexOfERKS_iN2Qt15CaseSensitivityE @ 3762 NONAME + _ZNK10QStringRef11toLocal8BitEv @ 3763 NONAME + _ZNK10QStringRef5countE5QCharN2Qt15CaseSensitivityE @ 3764 NONAME + _ZNK10QStringRef5countERK7QStringN2Qt15CaseSensitivityE @ 3765 NONAME + _ZNK10QStringRef5countERKS_N2Qt15CaseSensitivityE @ 3766 NONAME + _ZNK10QStringRef6toUcs4Ev @ 3767 NONAME + _ZNK10QStringRef6toUtf8Ev @ 3768 NONAME + _ZNK10QStringRef7indexOfE13QLatin1StringiN2Qt15CaseSensitivityE @ 3769 NONAME + _ZNK10QStringRef7indexOfE5QChariN2Qt15CaseSensitivityE @ 3770 NONAME + _ZNK10QStringRef7indexOfERK7QStringiN2Qt15CaseSensitivityE @ 3771 NONAME + _ZNK10QStringRef7indexOfERKS_iN2Qt15CaseSensitivityE @ 3772 NONAME + _ZNK10QStringRef7toAsciiEv @ 3773 NONAME + _ZNK10QStringRef8endsWithE13QLatin1StringN2Qt15CaseSensitivityE @ 3774 NONAME + _ZNK10QStringRef8endsWithE5QCharN2Qt15CaseSensitivityE @ 3775 NONAME + _ZNK10QStringRef8endsWithERK7QStringN2Qt15CaseSensitivityE @ 3776 NONAME + _ZNK10QStringRef8endsWithERKS_N2Qt15CaseSensitivityE @ 3777 NONAME + _ZNK10QStringRef8toLatin1Ev @ 3778 NONAME + _ZNK11QMetaObject4castEPK7QObject @ 3779 NONAME + _ZNK13QSharedMemory9nativeKeyEv @ 3780 NONAME + _ZNK16QAnimationDriver10metaObjectEv @ 3781 NONAME + _ZNK16QAnimationDriver9isRunningEv @ 3782 NONAME + _ZNK4QUrl11isLocalFileEv @ 3783 NONAME + _ZNK7QObject17senderSignalIndexEv @ 3784 NONAME + _ZNK7QString10startsWithERK10QStringRefN2Qt15CaseSensitivityE @ 3785 NONAME + _ZNK7QString11lastIndexOfERK10QStringRefiN2Qt15CaseSensitivityE @ 3786 NONAME + _ZNK7QString5countERK10QStringRefN2Qt15CaseSensitivityE @ 3787 NONAME + _ZNK7QString7indexOfERK10QStringRefiN2Qt15CaseSensitivityE @ 3788 NONAME + _ZNK7QString8endsWithERK10QStringRefN2Qt15CaseSensitivityE @ 3789 NONAME + _ZTI13QUnifiedTimer @ 3790 NONAME + _ZTI16QAnimationDriver @ 3791 NONAME + _ZTI23QAnimationDriverPrivate @ 3792 NONAME + _ZTV13QUnifiedTimer @ 3793 NONAME + _ZTV16QAnimationDriver @ 3794 NONAME + _ZTV23QAnimationDriverPrivate @ 3795 NONAME diff --git a/src/s60installs/eabi/QtDeclarativeu.def b/src/s60installs/eabi/QtDeclarativeu.def index 1f69061..b0efab4 100644 --- a/src/s60installs/eabi/QtDeclarativeu.def +++ b/src/s60installs/eabi/QtDeclarativeu.def @@ -1747,8 +1747,8 @@ EXPORTS _ZN21QDeclarativeListModelC1EPKS_P32QDeclarativeListModelWorkerAgent @ 1746 NONAME ABSENT _ZN21QDeclarativeListModelC2EPKS_P32QDeclarativeListModelWorkerAgent @ 1747 NONAME ABSENT _ZNK21QDeclarativeListModel14inWorkerThreadEv @ 1748 NONAME ABSENT - _ZN23QDeclarativeDebugHelper15getScriptEngineEP18QDeclarativeEngine @ 1749 NONAME ABSENT - _ZN23QDeclarativeDebugHelper26setAnimationSlowDownFactorEf @ 1750 NONAME ABSENT + _ZN23QDeclarativeDebugHelper15getScriptEngineEP18QDeclarativeEngine @ 1749 NONAME + _ZN23QDeclarativeDebugHelper26setAnimationSlowDownFactorEf @ 1750 NONAME _ZN17QDeclarativeTimer10classBeginEv @ 1751 NONAME ABSENT _ZN17QDeclarativeTimer10setRunningEb @ 1752 NONAME ABSENT _ZN17QDeclarativeTimer11qt_metacallEN11QMetaObject4CallEiPPv @ 1753 NONAME ABSENT diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index e2aec1d..d6fbdd3 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -3168,7 +3168,7 @@ EXPORTS _ZN14QWindowSurface6bufferEPK7QWidget @ 3167 NONAME _ZN14QWindowSurface6scrollERK7QRegionii @ 3168 NONAME _ZN14QWindowSurface8endPaintERK7QRegion @ 3169 NONAME - _ZN14QWindowSurfaceC2EP7QWidget @ 3170 NONAME + _ZN14QWindowSurfaceC2EP7QWidget @ 3170 NONAME ABSENT _ZN14QWindowSurfaceD0Ev @ 3171 NONAME _ZN14QWindowSurfaceD1Ev @ 3172 NONAME _ZN14QWindowSurfaceD2Ev @ 3173 NONAME @@ -4768,8 +4768,8 @@ EXPORTS _ZN20QRasterWindowSurface13prepareBufferEN6QImage6FormatEP7QWidget @ 4767 NONAME _ZN20QRasterWindowSurface5flushEP7QWidgetRK7QRegionRK6QPoint @ 4768 NONAME _ZN20QRasterWindowSurface6scrollERK7QRegionii @ 4769 NONAME - _ZN20QRasterWindowSurfaceC1EP7QWidget @ 4770 NONAME - _ZN20QRasterWindowSurfaceC2EP7QWidget @ 4771 NONAME + _ZN20QRasterWindowSurfaceC1EP7QWidget @ 4770 NONAME ABSENT + _ZN20QRasterWindowSurfaceC2EP7QWidget @ 4771 NONAME ABSENT _ZN20QRasterWindowSurfaceD0Ev @ 4772 NONAME _ZN20QRasterWindowSurfaceD1Ev @ 4773 NONAME _ZN20QRasterWindowSurfaceD2Ev @ 4774 NONAME @@ -12105,4 +12105,128 @@ EXPORTS _ZN15QStaticTextItemD1Ev @ 12104 NONAME _ZN15QStaticTextItemD2Ev @ 12105 NONAME _ZN19QEventDispatcherS6031reactivateDeferredActiveObjectsEv @ 12106 NONAME + _Z18qt_addBitmapToPathffPKhiiiP12QPainterPath @ 12107 NONAME + _Z22qt_fontdata_from_indexi @ 12108 NONAME + _ZN10QBlittable4lockEv @ 12109 NONAME + _ZN10QBlittable6unlockEv @ 12110 NONAME + _ZN10QBlittableC2ERK5QSize6QFlagsINS_10CapabilityEE @ 12111 NONAME + _ZN10QBlittableD0Ev @ 12112 NONAME + _ZN10QBlittableD1Ev @ 12113 NONAME + _ZN10QBlittableD2Ev @ 12114 NONAME + _ZN11QFontEngine16alphaMapForGlyphEj6QFixed @ 12115 NONAME + _ZN11QFontEngine16alphaMapForGlyphEj6QFixedRK10QTransform @ 12116 NONAME + _ZN11QFontEngine19alphaRGBMapForGlyphEj6QFixediRK10QTransform @ 12117 NONAME + _ZN12QInputDialog7getItemEP7QWidgetRK7QStringS4_RK11QStringListibPb6QFlagsIN2Qt10WindowTypeEES9_INSA_15InputMethodHintEE @ 12118 NONAME + _ZN12QInputDialog7getTextEP7QWidgetRK7QStringS4_N9QLineEdit8EchoModeES4_Pb6QFlagsIN2Qt10WindowTypeEES8_INS9_15InputMethodHintEE @ 12119 NONAME + _ZN14QWindowSurfaceC2EP7QWidgetb @ 12120 NONAME + _ZN18QTextureGlyphCache19fillInPendingGlyphsEv @ 12121 NONAME + _ZN19QAbstractProxyModel11setItemDataERK11QModelIndexRK4QMapIi8QVariantE @ 12122 NONAME + _ZN19QAbstractProxyModel17resetInternalDataEv @ 12123 NONAME + _ZN19QAbstractProxyModel4sortEiN2Qt9SortOrderE @ 12124 NONAME + _ZN19QAbstractProxyModel9fetchMoreERK11QModelIndex @ 12125 NONAME + _ZN19QApplicationPrivateC1ERiPPcN12QApplication4TypeEi @ 12126 NONAME + _ZN19QApplicationPrivateC2ERiPPcN12QApplication4TypeEi @ 12127 NONAME + _ZN19QBlitterPaintEngine10drawPixmapERK6QRectFRK7QPixmapS2_ @ 12128 NONAME + _ZN19QBlitterPaintEngine10penChangedEv @ 12129 NONAME + _ZN19QBlitterPaintEngine11drawEllipseERK6QRectF @ 12130 NONAME + _ZN19QBlitterPaintEngine12brushChangedEv @ 12131 NONAME + _ZN19QBlitterPaintEngine12drawTextItemERK7QPointFRK9QTextItem @ 12132 NONAME + _ZN19QBlitterPaintEngine14opacityChangedEv @ 12133 NONAME + _ZN19QBlitterPaintEngine16transformChangedEv @ 12134 NONAME + _ZN19QBlitterPaintEngine18brushOriginChangedEv @ 12135 NONAME + _ZN19QBlitterPaintEngine18clipEnabledChangedEv @ 12136 NONAME + _ZN19QBlitterPaintEngine18drawStaticTextItemEP15QStaticTextItem @ 12137 NONAME + _ZN19QBlitterPaintEngine18renderHintsChangedEv @ 12138 NONAME + _ZN19QBlitterPaintEngine22compositionModeChangedEv @ 12139 NONAME + _ZN19QBlitterPaintEngine3endEv @ 12140 NONAME + _ZN19QBlitterPaintEngine4clipERK11QVectorPathN2Qt13ClipOperationE @ 12141 NONAME + _ZN19QBlitterPaintEngine4clipERK5QRectN2Qt13ClipOperationE @ 12142 NONAME + _ZN19QBlitterPaintEngine4clipERK7QRegionN2Qt13ClipOperationE @ 12143 NONAME + _ZN19QBlitterPaintEngine4fillERK11QVectorPathRK6QBrush @ 12144 NONAME + _ZN19QBlitterPaintEngine5beginEP12QPaintDevice @ 12145 NONAME + _ZN19QBlitterPaintEngine6strokeERK11QVectorPathRK4QPen @ 12146 NONAME + _ZN19QBlitterPaintEngine8fillRectERK6QRectFRK6QBrush @ 12147 NONAME + _ZN19QBlitterPaintEngine8fillRectERK6QRectFRK6QColor @ 12148 NONAME + _ZN19QBlitterPaintEngine8setStateEP13QPainterState @ 12149 NONAME + _ZN19QBlitterPaintEngine9drawImageERK6QRectFRK6QImageS2_6QFlagsIN2Qt19ImageConversionFlagEE @ 12150 NONAME + _ZN19QBlitterPaintEngine9drawRectsEPK5QRecti @ 12151 NONAME + _ZN19QBlitterPaintEngine9drawRectsEPK6QRectFi @ 12152 NONAME + _ZN19QBlitterPaintEngineC1EP20QBlittablePixmapData @ 12153 NONAME + _ZN19QBlitterPaintEngineC2EP20QBlittablePixmapData @ 12154 NONAME + _ZN19QBlitterPaintEngineD0Ev @ 12155 NONAME + _ZN19QBlitterPaintEngineD1Ev @ 12156 NONAME + _ZN19QBlitterPaintEngineD2Ev @ 12157 NONAME + _ZN19QGraphicsGridLayout10removeItemEP19QGraphicsLayoutItem @ 12158 NONAME + _ZN20QBlittablePixmapData12setBlittableEP10QBlittable @ 12159 NONAME + _ZN20QBlittablePixmapData4fillERK6QColor @ 12160 NONAME + _ZN20QBlittablePixmapData6bufferEv @ 12161 NONAME + _ZN20QBlittablePixmapData6resizeEii @ 12162 NONAME + _ZN20QBlittablePixmapData9fromImageERK6QImage6QFlagsIN2Qt19ImageConversionFlagEE @ 12163 NONAME + _ZN20QBlittablePixmapDataC2Ev @ 12164 NONAME + _ZN20QBlittablePixmapDataD0Ev @ 12165 NONAME + _ZN20QBlittablePixmapDataD1Ev @ 12166 NONAME + _ZN20QBlittablePixmapDataD2Ev @ 12167 NONAME + _ZN20QRasterWindowSurfaceC1EP7QWidgetb @ 12168 NONAME + _ZN20QRasterWindowSurfaceC2EP7QWidgetb @ 12169 NONAME + _ZN23QImageTextureGlyphCache11fillTextureERKN18QTextureGlyphCache5CoordEj6QFixed @ 12170 NONAME + _ZN6QImage4fillEN2Qt11GlobalColorE @ 12171 NONAME + _ZN6QImage4fillERK6QColor @ 12172 NONAME + _ZN7QGlyphs12setPositionsERK7QVectorI7QPointFE @ 12173 NONAME + _ZN7QGlyphs15setGlyphIndexesERK7QVectorIjE @ 12174 NONAME + _ZN7QGlyphs5clearEv @ 12175 NONAME + _ZN7QGlyphs6detachEv @ 12176 NONAME + _ZN7QGlyphs7setFontERK5QFont @ 12177 NONAME + _ZN7QGlyphsC1ERKS_ @ 12178 NONAME + _ZN7QGlyphsC1Ev @ 12179 NONAME + _ZN7QGlyphsC2ERKS_ @ 12180 NONAME + _ZN7QGlyphsC2Ev @ 12181 NONAME + _ZN7QGlyphsD1Ev @ 12182 NONAME + _ZN7QGlyphsD2Ev @ 12183 NONAME + _ZN7QGlyphsaSERKS_ @ 12184 NONAME + _ZN7QGlyphspLERKS_ @ 12185 NONAME + _ZN8QPainter10drawGlyphsERK7QPointFRK7QGlyphs @ 12186 NONAME + _ZNK10QBlittable12capabilitiesEv @ 12187 NONAME + _ZNK10QBlittable4sizeEv @ 12188 NONAME + _ZNK10QTabWidget14heightForWidthEi @ 12189 NONAME + _ZNK11QFontEngine18createExplicitFontEv @ 12190 NONAME + _ZNK11QFontEngine26createExplicitFontWithNameERK7QString @ 12191 NONAME + _ZNK11QTextLayout6glyphsEv @ 12192 NONAME + _ZNK12QFontMetrics10inFontUcs4Ej @ 12193 NONAME + _ZNK12QRadioButton15minimumSizeHintEv @ 12194 NONAME + _ZNK13QFontMetricsF10inFontUcs4Ej @ 12195 NONAME + _ZNK13QTextFragment6glyphsEv @ 12196 NONAME + _ZNK14QWidgetPrivate17hasHeightForWidthEv @ 12197 NONAME + _ZNK16QFileSystemModel5rmdirERK11QModelIndex @ 12198 NONAME + _ZNK18QTextureGlyphCache18textureMapForGlyphEj6QFixed @ 12199 NONAME + _ZNK18QTextureGlyphCache20subPixelPositionForXE6QFixed @ 12200 NONAME + _ZNK18QTextureGlyphCache30calculateSubPixelPositionCountEj @ 12201 NONAME + _ZNK19QAbstractProxyModel11hasChildrenERK11QModelIndex @ 12202 NONAME + _ZNK19QAbstractProxyModel12canFetchMoreERK11QModelIndex @ 12203 NONAME + _ZNK19QAbstractProxyModel20supportedDropActionsEv @ 12204 NONAME + _ZNK19QAbstractProxyModel4spanERK11QModelIndex @ 12205 NONAME + _ZNK19QAbstractProxyModel5buddyERK11QModelIndex @ 12206 NONAME + _ZNK19QAbstractProxyModel8mimeDataERK5QListI11QModelIndexE @ 12207 NONAME + _ZNK19QAbstractProxyModel9mimeTypesEv @ 12208 NONAME + _ZNK19QBlitterPaintEngine11createStateEP13QPainterState @ 12209 NONAME + _ZNK20QBlittablePixmapData11paintEngineEv @ 12210 NONAME + _ZNK20QBlittablePixmapData15hasAlphaChannelEv @ 12211 NONAME + _ZNK20QBlittablePixmapData6metricEN12QPaintDevice17PaintDeviceMetricE @ 12212 NONAME + _ZNK20QBlittablePixmapData7toImageEv @ 12213 NONAME + _ZNK20QBlittablePixmapData9blittableEv @ 12214 NONAME + _ZNK7QGlyphs12glyphIndexesEv @ 12215 NONAME + _ZNK7QGlyphs4fontEv @ 12216 NONAME + _ZNK7QGlyphs9positionsEv @ 12217 NONAME + _ZNK7QGlyphseqERKS_ @ 12218 NONAME + _ZNK7QGlyphsneERKS_ @ 12219 NONAME + _ZNK7QGlyphsplERKS_ @ 12220 NONAME + _ZNK8QPainter16clipBoundingRectEv @ 12221 NONAME + _ZNK9QCheckBox15minimumSizeHintEv @ 12222 NONAME + _ZNK9QTextLine6glyphsEii @ 12223 NONAME + _ZTI10QBlittable @ 12224 NONAME + _ZTI19QBlitterPaintEngine @ 12225 NONAME + _ZTI20QBlittablePixmapData @ 12226 NONAME + _ZTV10QBlittable @ 12227 NONAME + _ZTV19QBlitterPaintEngine @ 12228 NONAME + _ZTV20QBlittablePixmapData @ 12229 NONAME + _Zls6QDebugPK13QSymbianEvent @ 12230 NONAME -- cgit v0.12 From cd3e03f5e70fa6d973949516f50ea05f201aac20 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 29 Nov 2010 13:55:18 +0000 Subject: Fix buffered/unbuffered mode issues on symbian Due to a bug in the symbian file server, files in /resource can't be opened for unbuffered read, only for default mode read. (it doesn't mask the cache control flags when doing the security check) So read will always be done in default mode. Symptom of this was that QML plugin loading failed as the plugin description in /resource could not be read. Buffered or unbuffered writes (i.e. whether the cache should be write through or write behind) are controlled by the QIODevice::Unbuffered flag, therefore it needs to be passed through to the file engine. An optimisation for unix and windows to force unbuffered mode in the file engine is inappropriate (as that is referring to buffering in the standard library, which is bypassed entirely by using the low level RFile to open files on symbian) Reviewed-by: joao --- src/corelib/io/qfile.cpp | 8 +++++++- src/corelib/io/qfsfileengine_unix.cpp | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index fac4ac6..85e78a6 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -993,8 +993,14 @@ bool QFile::open(OpenMode mode) return false; } +#ifdef Q_OS_SYMBIAN + // For symbian, the unbuffered flag is used to control write-behind cache behaviour + if (fileEngine()->open(mode)) +#else // QIODevice provides the buffering, so there's no need to request it from the file engine. - if (fileEngine()->open(mode | QIODevice::Unbuffered)) { + if (fileEngine()->open(mode | QIODevice::Unbuffered)) +#endif + { QIODevice::open(mode); if (mode & Append) seek(size()); diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 55388e6..1e1b35b 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -196,8 +196,8 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) if (openMode & QFile::Unbuffered) { if (openMode & QIODevice::WriteOnly) symbianMode |= 0x00001000; //EFileWriteDirectIO; - if (openMode & QIODevice::ReadOnly) - symbianMode |= 0x00004000; //EFileReadDirectIO; + // ### Unbuffered read is not used, because it prevents file open in /resource + // ### and has no obvious benefits } else { if (openMode & QIODevice::WriteOnly) symbianMode |= 0x00000800; //EFileWriteBuffered; -- cgit v0.12 From f417baad9235e90b5e9aae2fd06d664635c68bec Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 29 Nov 2010 16:48:17 +0000 Subject: Add symbian platform security and case sensitivity test cases On symbian, check that opening files in protected locations either succeeds or fails cleanly as expected by the capabilities the test is compiled with. This acts as a regression test for opening files in /resource, and also checks the other locations behave as expected. On all platforms, check file created with a mixed case filename can be accessed by it's aliases that differ only in case (or not) depending on the OS case sensitivity. For Windows/Symbian, file should be accessible by altered case aliases For other OS, it should not (other OS supported by Qt are unix like) Reviewed-by: mread --- tests/auto/qfile/tst_qfile.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 1bbf230..4421f0d 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -215,6 +215,11 @@ private slots: void resize(); void objectConstructors(); +#ifdef Q_OS_SYMBIAN + void platformSecurity_data(); + void platformSecurity(); +#endif + void caseSensitivity(); // --- Task related tests below this line void task167217(); @@ -400,6 +405,7 @@ void tst_QFile::cleanupTestCase() QFile::remove("qfile_map_testfile"); QFile::remove("readAllBuffer.txt"); QFile::remove("qt_file.tmp"); + QFile::remove("File.txt"); } //------------------------------------------ @@ -3135,5 +3141,91 @@ void tst_QFile::objectConstructors() QVERIFY(!file2->exists()); } +#ifdef Q_OS_SYMBIAN +void tst_QFile::platformSecurity_data() +{ + QTest::addColumn("file"); + QTest::addColumn("readable"); + QTest::addColumn("writable"); + + QString selfname = QCoreApplication::applicationFilePath(); + QString ownprivate = QCoreApplication::applicationDirPath(); + QString owndrive = selfname.left(2); + bool amiprivileged = RProcess().HasCapability(ECapabilityAllFiles); + QTest::newRow("resource") << owndrive + "/resource/apps/tst_qfile.rsc" << true << amiprivileged; + QTest::newRow("sys") << selfname << amiprivileged << false; + QTest::newRow("own private") << ownprivate + "/testfile.txt" << true << true; + QTest::newRow("other private") << owndrive + "/private/10003a3f/import/apps/tst_qfile_reg.rsc" << amiprivileged << amiprivileged; +} + +void tst_QFile::platformSecurity() +{ + QFETCH(QString,file); + QFETCH(bool,readable); + QFETCH(bool,writable); + + { + QFile f(file); + QCOMPARE(f.open(QIODevice::ReadOnly), readable); + } + + { + QFile f(file); + QCOMPARE(f.open(QIODevice::ReadOnly | QIODevice::Unbuffered), readable); + } + + //append mode used to avoid truncating the files. + { + QFile f(file); + QCOMPARE(f.open(QIODevice::WriteOnly | QIODevice::Append), writable); + } + + { + QFile f(file); + QCOMPARE(f.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered), writable); + } + + { + QFile f(file); + QCOMPARE(f.open(QIODevice::ReadWrite), writable); + } + + { + QFile f(file); + QCOMPARE(f.open(QIODevice::ReadWrite | QIODevice::Unbuffered), writable); + } +} +#endif + +void tst_QFile::caseSensitivity() +{ +#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WIN) + const bool caseSensitive = false; +#else + const bool caseSensitive = true; +#endif + QByteArray testData("a little test"); + QString filename("File.txt"); + { + QFile f(filename); + QVERIFY(f.open(QIODevice::WriteOnly)); + QVERIFY(f.write(testData)); + f.close(); + } + QStringList alternates; + QFileInfo fi(filename); + QVERIFY(fi.exists()); + alternates << "file.txt" << "File.TXT" << "fIlE.TxT" << fi.absoluteFilePath().toUpper() << fi.absoluteFilePath().toLower(); + foreach (QString alt, alternates) { + QFileInfo fi2(alt); + QCOMPARE(fi2.exists(), !caseSensitive); + QCOMPARE(fi.size() == fi2.size(), !caseSensitive); + QFile f2(alt); + QCOMPARE(f2.open(QIODevice::ReadOnly), !caseSensitive); + if (caseSensitive) + QCOMPARE(f2.readAll(), testData); + } +} + QTEST_MAIN(tst_QFile) #include "tst_qfile.moc" -- cgit v0.12 From 1555eed6c27a843e0ecb09c15a915c0a3f76fd1e Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 29 Nov 2010 17:45:12 +0000 Subject: QtDeclarative: make autotests compile on symbian Move tests for private classes inside private_tests scope Add missing libraries Add QT_NO_CONCURRENT ifdef around a test case Define Q_DECLARATIVE_PRIVATE_EXPORT as Q_AUTOTEST_EXPORT, so the classes are exported for autotests, previously they were exported on every OS except symbian. (this doesn't affect exports for production builds) Reviewed-by: Miikka Heikkinen --- src/declarative/qml/qdeclarativeglobal_p.h | 2 +- tests/auto/declarative/declarative.pro | 44 ++++++++++++---------- tests/auto/declarative/examples/examples.pro | 2 + .../tst_qdeclarativepixmapcache.cpp | 4 ++ .../qdeclarativeviewer/qdeclarativeviewer.pro | 2 + tests/auto/declarative/qmlvisual/qmlvisual.pro | 1 - tests/auto/declarative/symbianlibs.pri | 9 +++++ 7 files changed, 42 insertions(+), 22 deletions(-) create mode 100644 tests/auto/declarative/symbianlibs.pri diff --git a/src/declarative/qml/qdeclarativeglobal_p.h b/src/declarative/qml/qdeclarativeglobal_p.h index 31fbb1e..b8428b8 100644 --- a/src/declarative/qml/qdeclarativeglobal_p.h +++ b/src/declarative/qml/qdeclarativeglobal_p.h @@ -65,7 +65,7 @@ QT_MODULE(Declarative) } #ifdef Q_OS_SYMBIAN -#define Q_DECLARATIVE_PRIVATE_EXPORT +#define Q_DECLARATIVE_PRIVATE_EXPORT Q_AUTOTEST_EXPORT #else #define Q_DECLARATIVE_PRIVATE_EXPORT Q_DECLARATIVE_EXPORT #endif diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro index f0fcfa9..499c155 100644 --- a/tests/auto/declarative/declarative.pro +++ b/tests/auto/declarative/declarative.pro @@ -8,74 +8,78 @@ SUBDIRS += \ SUBDIRS += \ examples \ parserstress \ + qdeclarativecomponent \ + qdeclarativecontext \ + qdeclarativeengine \ + qdeclarativeerror \ + qdeclarativefolderlistmodel \ + qdeclarativeinfo \ + qdeclarativelayoutitem \ + qdeclarativelistreference \ + qdeclarativemoduleplugin \ + qdeclarativeparticles \ + qdeclarativepixmapcache \ + qdeclarativeqt \ + qdeclarativeview \ + qdeclarativeviewer \ + qdeclarativexmlhttprequest \ + qmlvisual \ + moduleqt47 + +contains(QT_CONFIG, private_tests) { + SUBDIRS += \ qdeclarativeanchors \ qdeclarativeanimatedimage \ qdeclarativeanimations \ qdeclarativebehaviors \ qdeclarativebinding \ qdeclarativeborderimage \ - qdeclarativecomponent \ qdeclarativeconnection \ - qdeclarativecontext \ qdeclarativedebug \ qdeclarativedebugclient \ qdeclarativedebugservice \ qdeclarativedom \ qdeclarativeecmascript \ - qdeclarativeengine \ - qdeclarativeerror \ - qdeclarativefolderlistmodel \ - qdeclarativefontloader \ qdeclarativeflickable \ qdeclarativeflipable \ qdeclarativefocusscope \ + qdeclarativefontloader \ qdeclarativegridview \ qdeclarativeimage \ qdeclarativeimageprovider \ - qdeclarativeinfo \ qdeclarativeinstruction \ qdeclarativeitem \ qdeclarativelanguage \ - qdeclarativelayoutitem \ qdeclarativelistmodel \ - qdeclarativelistreference \ qdeclarativelistview \ qdeclarativeloader \ - qdeclarativemoduleplugin \ qdeclarativemousearea \ - qdeclarativeparticles \ qdeclarativepathview \ - qdeclarativepixmapcache \ qdeclarativepositioners \ qdeclarativeproperty \ qdeclarativepropertymap \ - qdeclarativeqt \ qdeclarativerepeater \ qdeclarativesmoothedanimation \ qdeclarativespringanimation \ + qdeclarativestyledtext \ qdeclarativesqldatabase \ qdeclarativestates \ - qdeclarativestyledtext \ qdeclarativesystempalette \ qdeclarativetext \ qdeclarativetextedit \ qdeclarativetextinput \ qdeclarativetimer \ qdeclarativevaluetypes \ - qdeclarativeview \ - qdeclarativeviewer \ qdeclarativevisualdatamodel \ qdeclarativeworkerscript \ - qdeclarativexmlhttprequest \ qdeclarativexmllistmodel \ - qmlvisual \ - qpacketprotocol \ - moduleqt47 + qpacketprotocol contains(QT_CONFIG, webkit) { SUBDIRS += \ qdeclarativewebview } +} # Tests which should run in Pulse PULSE_TESTS = $$SUBDIRS diff --git a/tests/auto/declarative/examples/examples.pro b/tests/auto/declarative/examples/examples.pro index 97f02af..dafc146 100644 --- a/tests/auto/declarative/examples/examples.pro +++ b/tests/auto/declarative/examples/examples.pro @@ -6,6 +6,8 @@ SOURCES += tst_examples.cpp include(../../../../tools/qml/qml.pri) +include(../symbianlibs.pri) + symbian: { importFiles.files = data importFiles.path = . diff --git a/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp b/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp index 50d0731..1a38e87 100644 --- a/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp +++ b/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp @@ -74,7 +74,9 @@ private slots: void massive(); void cancelcrash(); void shrinkcache(); +#ifndef QT_NO_CONCURRENT void networkCrash(); +#endif private: QDeclarativeEngine engine; QUrl thisfile; @@ -363,6 +365,7 @@ void createNetworkServer() eventLoop.exec(); } +#ifndef QT_NO_CONCURRENT // QT-3957 void tst_qdeclarativepixmapcache::networkCrash() { @@ -377,6 +380,7 @@ void tst_qdeclarativepixmapcache::networkCrash() } future.cancel(); } +#endif QTEST_MAIN(tst_qdeclarativepixmapcache) diff --git a/tests/auto/declarative/qdeclarativeviewer/qdeclarativeviewer.pro b/tests/auto/declarative/qdeclarativeviewer/qdeclarativeviewer.pro index a94992b..8d4b410 100644 --- a/tests/auto/declarative/qdeclarativeviewer/qdeclarativeviewer.pro +++ b/tests/auto/declarative/qdeclarativeviewer/qdeclarativeviewer.pro @@ -6,6 +6,8 @@ include(../../../../tools/qml/qml.pri) SOURCES += tst_qdeclarativeviewer.cpp +include(../symbianlibs.pri) + symbian: { importFiles.files = data importFiles.path = . diff --git a/tests/auto/declarative/qmlvisual/qmlvisual.pro b/tests/auto/declarative/qmlvisual/qmlvisual.pro index d9fce44..84df15c 100644 --- a/tests/auto/declarative/qmlvisual/qmlvisual.pro +++ b/tests/auto/declarative/qmlvisual/qmlvisual.pro @@ -19,7 +19,6 @@ symbian: { qdeclarativepathview \ qdeclarativepositioners \ qdeclarativesmoothedanimation \ - qdeclarativespringfollow \ qdeclarativetext \ qdeclarativetextedit \ qdeclarativetextinput \ diff --git a/tests/auto/declarative/symbianlibs.pri b/tests/auto/declarative/symbianlibs.pri new file mode 100644 index 0000000..4452f67 --- /dev/null +++ b/tests/auto/declarative/symbianlibs.pri @@ -0,0 +1,9 @@ +#additional libs required for orientation sensor +symbian { + !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) { + LIBS += -lsensrvclient -lsensrvutil + } + contains(QT_CONFIG, s60): { + LIBS += -lavkon -lcone + } +} -- cgit v0.12 From 173e6954e13871606a685229af279a2038f9d939 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 30 Nov 2010 14:21:12 +0000 Subject: Fix compile error for qdir autotest on symbian3 Header file is in a different location compared to previous SDK versions Reviewed-by: Miikka Heikkinen --- tests/auto/qdir/qdir.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/qdir/qdir.pro b/tests/auto/qdir/qdir.pro index 55fd031..472e646 100644 --- a/tests/auto/qdir/qdir.pro +++ b/tests/auto/qdir/qdir.pro @@ -16,6 +16,7 @@ wince* { TARGET.UID3 = 0xE0340002 DEFINES += SYMBIAN_SRCDIR_UID=$$lower($$replace(TARGET.UID3,"0x","")) LIBS += -lefsrv + INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE } else { contains(QT_CONFIG, qt3support):QT += qt3support DEFINES += SRCDIR=\\\"$$PWD/\\\" -- cgit v0.12 From 7380e973a5e8dd8633e955792f219f6231b9513e Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 30 Nov 2010 14:24:59 +0000 Subject: Add test generated files to .gitignore The tests/.gitignore, did not inherit from the main one, which causes git to show hundreds of new files when running tests on symbian. Reviewed-by: Markus Goetz --- .gitignore | 14 +++++++++++++- tests/.gitignore | 6 ------ 2 files changed, 13 insertions(+), 7 deletions(-) delete mode 100644 tests/.gitignore diff --git a/.gitignore b/.gitignore index af52197..521cea2 100644 --- a/.gitignore +++ b/.gitignore @@ -119,6 +119,14 @@ translations/*.qm translations/*_untranslated.ts qrc_*.cpp +# Test generated files +QObject.log +tst_* +!tst_*.* +tst_*.log +tst_*.debug +tst_*~ + # xemacs temporary files *.flc @@ -203,7 +211,7 @@ doc-build # --------------------- ABLD.BAT -bld.inf +bld.inf* *.mmp *.mk *.rss @@ -221,6 +229,10 @@ plugin_commonu.def *.sym *.lib +# runonphone crash dumps +d_exc_*.txt +d_exc_*.stk + # Generated by abldfast.bat from devtools. .abldsteps.* diff --git a/tests/.gitignore b/tests/.gitignore deleted file mode 100644 index b203473..0000000 --- a/tests/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -QObject.log -tst_* -!tst_*.* -tst_*.log -tst_*.debug -tst_*~ -- cgit v0.12 From be03dc12478085b3d8ec92a87fe12234169dce3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 30 Nov 2010 20:37:07 +0100 Subject: Fix typo in QFile test If file system isn't case sensitive, open succeeds as should reading, with the read data matching testData. --- tests/auto/qfile/tst_qfile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 4421f0d..d561f53 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -3222,7 +3222,7 @@ void tst_QFile::caseSensitivity() QCOMPARE(fi.size() == fi2.size(), !caseSensitive); QFile f2(alt); QCOMPARE(f2.open(QIODevice::ReadOnly), !caseSensitive); - if (caseSensitive) + if (!caseSensitive) QCOMPARE(f2.readAll(), testData); } } -- cgit v0.12 From 16252a59afa58b0cb4b0ffb02a330dcf002c9750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 30 Nov 2010 20:50:48 +0100 Subject: Fix tst_QFile::caseSensitivity test on Mac Mac's default file system is case-preserving, but case-insensitive, otherwise. --- tests/auto/qfile/tst_qfile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index d561f53..a8715e2 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -3199,7 +3199,7 @@ void tst_QFile::platformSecurity() void tst_QFile::caseSensitivity() { -#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WIN) +#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WIN) || defined(Q_OS_MAC) const bool caseSensitive = false; #else const bool caseSensitive = true; -- cgit v0.12 From 6f18ee7ce50bc9b2688079e923a34c08117b3eb8 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 1 Dec 2010 11:15:46 +1000 Subject: Fix BorderImage painting at sizes less than margin size. If the width < left+right margins or height < top+bottom margins the image was painted with the complete margins, resulting in an ugle pattern. This change reduces the size of the margins proportionately, which gives a much better appearance. Task-number: QTBUG-15736 Reviewed-by: Yann Bodson --- .../graphicsitems/qdeclarativeborderimage.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp index 649c8fb..c0a7d72 100644 --- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp @@ -509,7 +509,7 @@ void QDeclarativeBorderImage::doUpdate() void QDeclarativeBorderImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) { Q_D(QDeclarativeBorderImage); - if (d->pix.isNull()) + if (d->pix.isNull() || d->width() <= 0.0 || d->height() <= 0.0) return; bool oldAA = p->testRenderHint(QPainter::Antialiasing); @@ -518,7 +518,23 @@ void QDeclarativeBorderImage::paint(QPainter *p, const QStyleOptionGraphicsItem p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth); const QDeclarativeScaleGrid *border = d->getScaleGrid(); - QMargins margins(border->left(), border->top(), border->right(), border->bottom()); + int left = border->left(); + int right = border->right(); + qreal borderWidth = left + right; + if (borderWidth > 0.0 && d->width() < borderWidth) { + qreal diff = borderWidth - d->width() - 1; + left -= qRound(diff * qreal(left) / borderWidth); + right -= qRound(diff * qreal(right) / borderWidth); + } + int top = border->top(); + int bottom = border->bottom(); + qreal borderHeight = top + bottom; + if (borderHeight > 0.0 && d->height() < borderHeight) { + qreal diff = borderHeight - d->height() - 1; + top -= qRound(diff * qreal(top) / borderHeight); + bottom -= qRound(diff * qreal(bottom) / borderHeight); + } + QMargins margins(left, top, right, bottom); QTileRules rules((Qt::TileRule)d->horizontalTileMode, (Qt::TileRule)d->verticalTileMode); qDrawBorderPixmap(p, QRect(0, 0, (int)d->width(), (int)d->height()), margins, d->pix, d->pix.rect(), margins, rules); if (d->smooth) { -- cgit v0.12 From fe90d7a3d9f00fa2ea46c0816f63c65f812c360f Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 1 Dec 2010 11:29:23 +1000 Subject: Change pen correctly when drawing cached text Task-number: QTBUG-14568 --- src/declarative/graphicsitems/qdeclarativetextlayout.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp index e8da367..14a1109 100644 --- a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp @@ -361,10 +361,18 @@ void QDeclarativeTextLayout::draw(QPainter *painter, const QPointF &p) d->position = p; } + QPen oldPen = priv->state->pen; + QColor currentColor = oldPen.color(); for (int ii = 0; ii < itemCount; ++ii) { QStaticTextItem &item = d->items[ii]; + if (item.color.isValid() && currentColor != item.color) { + painter->setPen(item.color); + currentColor = item.color; + } priv->extended->drawStaticTextItem(&item); } + if (currentColor != oldPen.color()) + painter->setPen(oldPen); } QT_END_NAMESPACE -- cgit v0.12 From e46bf51f830dcc80932b9219fe608d1bc1a388ad Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 1 Dec 2010 16:03:08 +1000 Subject: Fix license header. --- doc/src/declarative/qmlinuse.qdoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/src/declarative/qmlinuse.qdoc b/doc/src/declarative/qmlinuse.qdoc index 90ce02c..1127b4c 100644 --- a/doc/src/declarative/qmlinuse.qdoc +++ b/doc/src/declarative/qmlinuse.qdoc @@ -7,11 +7,11 @@ ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:FDL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in a -** written agreement between you and Nokia. +** 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 Free Documentation License ** Alternatively, this file may be used under the terms of the GNU Free -- cgit v0.12 From 3f4bfebbf2bd9b1e704acaba2f50194b5e42e432 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 1 Dec 2010 16:14:10 +1000 Subject: Fix license headers --- bin/elf2e32_qtwrapper.pl | 40 ++++++++++++++++++++++++++++++++ doc/src/examples/multicastreceiver.qdoc | 10 ++++---- doc/src/examples/multicastsender.qdoc | 10 ++++---- tests/manual/mkspecs/test.sh | 41 +++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 10 deletions(-) diff --git a/bin/elf2e32_qtwrapper.pl b/bin/elf2e32_qtwrapper.pl index 4eeb098..d91be14 100755 --- a/bin/elf2e32_qtwrapper.pl +++ b/bin/elf2e32_qtwrapper.pl @@ -1,4 +1,44 @@ #!/usr/bin/perl -w +############################################################################# +## +## 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 utilities 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$ +## +############################################################################# # A script to get around some shortcomings in elf2e32, namely: # - Returning 0 even when there are errors. diff --git a/doc/src/examples/multicastreceiver.qdoc b/doc/src/examples/multicastreceiver.qdoc index f769705..9c4dda4 100644 --- a/doc/src/examples/multicastreceiver.qdoc +++ b/doc/src/examples/multicastreceiver.qdoc @@ -7,11 +7,11 @@ ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:FDL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in a -** written agreement between you and Nokia. +** 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 Free Documentation License ** Alternatively, this file may be used under the terms of the GNU Free diff --git a/doc/src/examples/multicastsender.qdoc b/doc/src/examples/multicastsender.qdoc index 271be60..be5fb6a 100644 --- a/doc/src/examples/multicastsender.qdoc +++ b/doc/src/examples/multicastsender.qdoc @@ -7,11 +7,11 @@ ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:FDL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in a -** written agreement between you and Nokia. +** 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 Free Documentation License ** Alternatively, this file may be used under the terms of the GNU Free diff --git a/tests/manual/mkspecs/test.sh b/tests/manual/mkspecs/test.sh index 4b723c0..7e942a4 100755 --- a/tests/manual/mkspecs/test.sh +++ b/tests/manual/mkspecs/test.sh @@ -1,4 +1,45 @@ #!/bin/bash +############################################################################# +## +## 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 manual tests 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$ +## +############################################################################# + if [ "$1" == "--help" ]; then echo "Init a clean git repository somewhere and run this test script from that directory. The first run will" -- cgit v0.12 From ff7df47d6b3a873f37cf8bcdf46e5daa5168a6fc Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 1 Dec 2010 08:24:30 +0100 Subject: Designer: Fix coverity warning (memory leak in widget database). Reviewed-by: Juuso Pakarinen Task-number: QT-4341 --- tools/designer/src/lib/shared/widgetdatabase.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/designer/src/lib/shared/widgetdatabase.cpp b/tools/designer/src/lib/shared/widgetdatabase.cpp index 0c3e949..7ab450d 100644 --- a/tools/designer/src/lib/shared/widgetdatabase.cpp +++ b/tools/designer/src/lib/shared/widgetdatabase.cpp @@ -54,7 +54,8 @@ #include #include -#include + +#include #include #include #include @@ -565,10 +566,10 @@ static QString xmlFromWidgetBox(const QDesignerFormEditorInterface *core, const const bool found = QDesignerWidgetBox::findWidget(core->widgetBox(), className, QString(), &widget); if (!found) return QString(); - DomUI *domUI = QDesignerWidgetBox::xmlToUi(className, widget.domXml(), false); - domUI->setAttributeVersion(QLatin1String("4.0")); - if (!domUI) + QScopedPointer domUI(QDesignerWidgetBox::xmlToUi(className, widget.domXml(), false)); + if (domUI.isNull()) return QString(); + domUI->setAttributeVersion(QLatin1String("4.0")); DomWidget *domWidget = domUI->elementWidget(); if (!domWidget) return QString(); @@ -615,7 +616,6 @@ static QString xmlFromWidgetBox(const QDesignerFormEditorInterface *core, const domUI->write(writer); writer.writeEndDocument(); } - delete domUI; return rc; } -- cgit v0.12 From 1337a3e031477aa4d628d01252557dee622629ff Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 1 Dec 2010 17:30:52 +1000 Subject: ListView header is not visible initially. If the header size was not set explicitly, but determined implicitly from Text height, the view was not positioned so that the header was visible when first shown. Task-number: QTBUG-15599 Reviewed-by: Bea Lam --- .../graphicsitems/qdeclarativegridview.cpp | 16 ++++-- .../graphicsitems/qdeclarativelistview.cpp | 22 ++++--- .../qdeclarativelistview/data/header1.qml | 33 +++++++++++ .../tst_qdeclarativelistview.cpp | 67 ++++++++++++++++------ 4 files changed, 108 insertions(+), 30 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativelistview/data/header1.qml diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 4454284..1615b0f 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1769,8 +1769,10 @@ void QDeclarativeGridView::setFooter(QDeclarativeComponent *footer) d->footer = 0; } d->footerComponent = footer; - d->updateFooter(); - d->updateGrid(); + if (isComponentComplete()) { + d->updateFooter(); + d->updateGrid(); + } emit footerChanged(); } } @@ -1799,9 +1801,11 @@ void QDeclarativeGridView::setHeader(QDeclarativeComponent *header) d->header = 0; } d->headerComponent = header; - d->updateHeader(); - d->updateFooter(); - d->updateGrid(); + if (isComponentComplete()) { + d->updateHeader(); + d->updateFooter(); + d->updateGrid(); + } emit headerChanged(); } } @@ -2226,6 +2230,8 @@ void QDeclarativeGridView::componentComplete() { Q_D(QDeclarativeGridView); QDeclarativeFlickable::componentComplete(); + d->updateHeader(); + d->updateFooter(); d->updateGrid(); if (d->isValid()) { refill(); diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index d1f52be..845da79 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -402,6 +402,8 @@ public: void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) { Q_Q(QDeclarativeListView); QDeclarativeFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry); + if (!q->isComponentComplete()) + return; if (item != contentItem && (!highlight || item != highlight->item)) { if ((orient == QDeclarativeListView::Vertical && newGeometry.height() != oldGeometry.height()) || (orient == QDeclarativeListView::Horizontal && newGeometry.width() != oldGeometry.width())) { @@ -1123,8 +1125,6 @@ void QDeclarativeListViewPrivate::updateHeader() QDeclarativeItemPrivate *itemPrivate = static_cast(QGraphicsItemPrivate::get(item)); itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); header = new FxListItem(item, q); - if (visibleItems.isEmpty()) - visiblePos = header->size(); } } if (header) { @@ -1137,6 +1137,8 @@ void QDeclarativeListViewPrivate::updateHeader() header->setPosition(startPos - header->size()); } } else { + if (itemCount == 0) + visiblePos = header->size(); header->setPosition(0); } } @@ -2215,8 +2217,10 @@ void QDeclarativeListView::setFooter(QDeclarativeComponent *footer) d->footerComponent = footer; d->minExtentDirty = true; d->maxExtentDirty = true; - d->updateFooter(); - d->updateViewport(); + if (isComponentComplete()) { + d->updateFooter(); + d->updateViewport(); + } emit footerChanged(); } } @@ -2247,9 +2251,11 @@ void QDeclarativeListView::setHeader(QDeclarativeComponent *header) d->headerComponent = header; d->minExtentDirty = true; d->maxExtentDirty = true; - d->updateHeader(); - d->updateFooter(); - d->updateViewport(); + if (isComponentComplete()) { + d->updateHeader(); + d->updateFooter(); + d->updateViewport(); + } emit headerChanged(); } } @@ -2659,6 +2665,8 @@ void QDeclarativeListView::componentComplete() Q_D(QDeclarativeListView); QDeclarativeFlickable::componentComplete(); updateSections(); + d->updateHeader(); + d->updateFooter(); if (d->isValid()) { refill(); d->moveReason = QDeclarativeListViewPrivate::SetIndex; diff --git a/tests/auto/declarative/qdeclarativelistview/data/header1.qml b/tests/auto/declarative/qdeclarativelistview/data/header1.qml new file mode 100644 index 0000000..f2ab4c1 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelistview/data/header1.qml @@ -0,0 +1,33 @@ +import QtQuick 1.0 + +Rectangle { + width: 240 + height: 320 + color: "#ffffff" + + ListModel { id: testModel } + + ListView { + id: list + objectName: "list" + width: parent.width + anchors.top: parent.top + anchors.bottom: parent.bottom + model: testModel + delegate: Text { + objectName: "wrapper" + font.pointSize: 20 + text: index + } + footer: Rectangle { + width: parent.width + height: 40 + color: "green" + } + header: Text { objectName: "header"; text: "Header" } + } + + Component.onCompleted: { + for (var i=0; i<30; i++) testModel.append({"name" : i, "val": i}) + } +} diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 295a75d..759caf2 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -1664,32 +1664,63 @@ void tst_QDeclarativeListView::QTBUG_11105() void tst_QDeclarativeListView::header() { - QDeclarativeView *canvas = createView(); + { + QDeclarativeView *canvas = createView(); - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml")); - qApp->processEvents(); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml")); + qApp->processEvents(); - QDeclarativeListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); + QDeclarativeListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); - QDeclarativeItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); + QDeclarativeItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); - QDeclarativeText *header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->y(), 0.0); + QDeclarativeText *header = findItem(contentItem, "header"); + QVERIFY(header); + QCOMPARE(header->y(), 0.0); - QCOMPARE(listview->contentY(), 0.0); + QCOMPARE(listview->contentY(), 0.0); - model.clear(); - QTRY_COMPARE(header->y(), 0.0); + model.clear(); + QTRY_COMPARE(header->y(), 0.0); + + delete canvas; + } + { + QDeclarativeView *canvas = createView(); + + TestModel model; + + QDeclarativeContext *ctxt = canvas->rootContext(); + + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header1.qml")); + qApp->processEvents(); + + QDeclarativeListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QDeclarativeItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QDeclarativeText *header = findItem(contentItem, "header"); + QVERIFY(header); + QCOMPARE(header->y(), 0.0); + + QCOMPARE(listview->contentY(), 0.0); + + model.clear(); + QTRY_COMPARE(header->y(), 0.0); + + delete canvas; + } } void tst_QDeclarativeListView::footer() -- cgit v0.12 From 5822db01277a19d8424b1f0d55868a82c8e719e6 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 1 Dec 2010 08:55:47 +0100 Subject: Fix two minor doc errors Task-number: QTBUG-14929, QTBUG-15739 Reviewed-by: TrustMe --- doc/src/platforms/emb-envvars.qdoc | 2 +- src/corelib/tools/qalgorithms.qdoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/platforms/emb-envvars.qdoc b/doc/src/platforms/emb-envvars.qdoc index 1d109b4..3f318eb 100644 --- a/doc/src/platforms/emb-envvars.qdoc +++ b/doc/src/platforms/emb-envvars.qdoc @@ -112,7 +112,7 @@ device, e.g., \c /dev/mouse for mouse devices and \c /dev/ts for touch panels. - Multiple keyboard drivers can be specified in one go: + Multiple mouse drivers can be specified in one go: \snippet doc/src/snippets/code/doc_src_emb-envvars.qdoc 3 diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc index 898f940..cd33f28 100644 --- a/src/corelib/tools/qalgorithms.qdoc +++ b/src/corelib/tools/qalgorithms.qdoc @@ -266,7 +266,7 @@ \overload - This is the same as qFind(\a{container}.begin(), \a{container}.end(), value); + This is the same as qFind(\a{container}.constBegin(), \a{container}.constEnd(), value); */ /*! \fn void qCount(InputIterator begin, InputIterator end, const T &value, Size &n) -- cgit v0.12 From de30288bb108d70cd66774c3beb7497efb5d0e6d Mon Sep 17 00:00:00 2001 From: aavit Date: Tue, 30 Nov 2010 15:31:09 +0100 Subject: Workaround for certain malformed PNGs that lack the final crc bytes Task-number: QT-4103 Reviewed-by: gunnar --- src/gui/image/qpnghandler.cpp | 80 +++++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 935aba0..a4d669b 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -82,6 +82,41 @@ QT_BEGIN_NAMESPACE Never to grayscale. */ +class QPngHandlerPrivate +{ +public: + enum State { + Ready, + ReadHeader, + ReadingEnd, + Error + }; + + QPngHandlerPrivate(QPngHandler *qq) + : gamma(0.0), quality(2), png_ptr(0), info_ptr(0), + end_info(0), row_pointers(0), state(Ready), q(qq) + { } + + float gamma; + int quality; + QString description; + + png_struct *png_ptr; + png_info *info_ptr; + png_info *end_info; + png_byte **row_pointers; + + bool readPngHeader(); + bool readPngImage(QImage *image); + + QImage::Format readImageFormat(); + + State state; + + QPngHandler *q; +}; + + #if defined(Q_C_CALLBACKS) extern "C" { #endif @@ -118,7 +153,15 @@ private: static void CALLBACK_CALL_TYPE iod_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) { - QIODevice *in = (QIODevice *)png_get_io_ptr(png_ptr); + QPngHandlerPrivate *d = (QPngHandlerPrivate *)png_get_io_ptr(png_ptr); + QIODevice *in = d->q->device(); + + if (d->state == QPngHandlerPrivate::ReadingEnd && in->atEnd() && length == 4) { + // Workaround for certain malformed PNGs that lack the final crc bytes + uchar endcrc[4] = { 0xae, 0x42, 0x60, 0x82 }; + qMemCopy(data, endcrc, 4); + return; + } while (length) { int nr = in->read((char*)data, length); @@ -314,38 +357,6 @@ static void CALLBACK_CALL_TYPE qt_png_warning(png_structp /*png_ptr*/, png_const } #endif -class QPngHandlerPrivate -{ -public: - enum State { - Ready, - ReadHeader, - Error - }; - - QPngHandlerPrivate(QPngHandler *qq) - : gamma(0.0), quality(2), png_ptr(0), info_ptr(0), - end_info(0), row_pointers(0), state(Ready), q(qq) - { } - - float gamma; - int quality; - QString description; - - png_struct *png_ptr; - png_info *info_ptr; - png_info *end_info; - png_byte **row_pointers; - - bool readPngHeader(); - bool readPngImage(QImage *image); - - QImage::Format readImageFormat(); - - State state; - - QPngHandler *q; -}; /*! \internal @@ -379,7 +390,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngHeader() return false; } - png_set_read_fn(png_ptr, q->device(), iod_read_fn); + png_set_read_fn(png_ptr, this, iod_read_fn); png_read_info(png_ptr, info_ptr); #ifndef QT_NO_IMAGE_TEXT @@ -505,6 +516,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngImage(QImage *outImage) } #endif + state = ReadingEnd; png_read_end(png_ptr, end_info); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); delete [] row_pointers; -- cgit v0.12 From 46de147d71f18dbf81617781ee3056fa9549e553 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 1 Dec 2010 11:04:27 +0100 Subject: QGtkStyle: Don't create new GtkAdjustment objects on every draw Use gtk_*_get_adjustment() and gtk_adjustment_configure() to re-use the previously set GtkAdjustment on GtkProgress and GtkRange. Reviewed-by: Jens Bache-Wiig --- src/gui/styles/qgtkstyle.cpp | 54 ++++++++++++++++++++++++++++++------------ src/gui/styles/qgtkstyle_p.cpp | 6 +++++ src/gui/styles/qgtkstyle_p.h | 6 +++++ 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 9cc64b3..f3ec746 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -1706,12 +1706,17 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom fakePos = maximum; else if (scrollBar->sliderPosition > scrollBar->minimum) fakePos = maximum - 1; - GtkObject *adjustment = d->gtk_adjustment_new(fakePos, 0, maximum, 0, 0, 0); - if (horizontal) - d->gtk_range_set_adjustment((GtkRange*)(gtkHScrollBar), (GtkAdjustment*)(adjustment)); - else - d->gtk_range_set_adjustment((GtkRange*)(gtkVScrollBar), (GtkAdjustment*)(adjustment)); + + GtkRange *range = (GtkRange*)(horizontal ? gtkHScrollBar : gtkVScrollBar); + GtkAdjustment *adjustment = d->gtk_range_get_adjustment(range); + + if (adjustment) { + d->gtk_adjustment_configure(adjustment, fakePos, 0, maximum, 0, 0, 0); + } else { + adjustment = (GtkAdjustment*)d->gtk_adjustment_new(fakePos, 0, maximum, 0, 0, 0); + d->gtk_range_set_adjustment(range, adjustment); + } if (scrollBar->subControls & SC_ScrollBarGroove) { GtkStateType state = GTK_STATE_ACTIVE; @@ -1990,15 +1995,29 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom style = scaleWidget->style; if ((option->subControls & SC_SliderGroove) && groove.isValid()) { - GtkObject *adjustment = d->gtk_adjustment_new(slider->sliderPosition, - slider->minimum, - slider->maximum, - slider->singleStep, - slider->singleStep, - slider->pageStep); + + GtkRange *range = (GtkRange*)scaleWidget; + GtkAdjustment *adjustment = d->gtk_range_get_adjustment(range); + if (adjustment) { + d->gtk_adjustment_configure(adjustment, + slider->sliderPosition, + slider->minimum, + slider->maximum, + slider->singleStep, + slider->singleStep, + slider->pageStep); + } else { + adjustment = (GtkAdjustment*)d->gtk_adjustment_new(slider->sliderPosition, + slider->minimum, + slider->maximum, + slider->singleStep, + slider->singleStep, + slider->pageStep); + d->gtk_range_set_adjustment(range, adjustment); + } + int outerSize; - d->gtk_range_set_adjustment ((GtkRange*)(scaleWidget), (GtkAdjustment*)(adjustment)); - d->gtk_range_set_inverted((GtkRange*)(scaleWidget), !horizontal); + d->gtk_range_set_inverted(range, !horizontal); d->gtk_widget_style_get(scaleWidget, "trough-border", &outerSize, NULL); outerSize++; @@ -2998,8 +3017,13 @@ void QGtkStyle::drawControl(ControlElement element, else if (bar->progress > bar->minimum) fakePos = maximum - 1; - GtkObject *adjustment = d->gtk_adjustment_new(fakePos, 0, maximum, 0, 0, 0); - d->gtk_progress_set_adjustment((GtkProgress*)(gtkProgressBar), (GtkAdjustment*)(adjustment)); + GtkAdjustment *adjustment = d->gtk_progress_get_adjustment((GtkProgress*)gtkProgressBar); + if (adjustment) { + d->gtk_adjustment_configure(adjustment, fakePos, 0, maximum, 0, 0, 0); + } else { + adjustment = (GtkAdjustment*)d->gtk_adjustment_new(fakePos, 0, maximum, 0, 0, 0); + d->gtk_progress_set_adjustment((GtkProgress*)(gtkProgressBar), adjustment); + } QRect progressBar; diff --git a/src/gui/styles/qgtkstyle_p.cpp b/src/gui/styles/qgtkstyle_p.cpp index fdbe1f8..dd20253 100644 --- a/src/gui/styles/qgtkstyle_p.cpp +++ b/src/gui/styles/qgtkstyle_p.cpp @@ -121,7 +121,9 @@ Ptr_gtk_combo_box_entry_new QGtkStylePrivate::gtk_combo_box_entry_new = 0; Ptr_gtk_progress_bar_new QGtkStylePrivate::gtk_progress_bar_new = 0; Ptr_gtk_container_add QGtkStylePrivate::gtk_container_add = 0; Ptr_gtk_menu_shell_append QGtkStylePrivate::gtk_menu_shell_append = 0; +Ptr_gtk_progress_get_adjustment QGtkStylePrivate::gtk_progress_get_adjustment = 0; Ptr_gtk_progress_set_adjustment QGtkStylePrivate::gtk_progress_set_adjustment = 0; +Ptr_gtk_range_get_adjustment QGtkStylePrivate::gtk_range_get_adjustment = 0; Ptr_gtk_range_set_adjustment QGtkStylePrivate::gtk_range_set_adjustment = 0; Ptr_gtk_range_set_inverted QGtkStylePrivate::gtk_range_set_inverted = 0; Ptr_gtk_icon_factory_lookup_default QGtkStylePrivate::gtk_icon_factory_lookup_default = 0; @@ -145,6 +147,7 @@ Ptr_gtk_paint_focus QGtkStylePrivate::gtk_paint_focus = 0; Ptr_gtk_paint_arrow QGtkStylePrivate::gtk_paint_arrow = 0; Ptr_gtk_paint_handle QGtkStylePrivate::gtk_paint_handle = 0; Ptr_gtk_paint_expander QGtkStylePrivate::gtk_paint_expander = 0; +Ptr_gtk_adjustment_configure QGtkStylePrivate::gtk_adjustment_configure = 0; Ptr_gtk_adjustment_new QGtkStylePrivate::gtk_adjustment_new = 0; Ptr_gtk_paint_hline QGtkStylePrivate::gtk_paint_hline = 0; Ptr_gtk_paint_vline QGtkStylePrivate::gtk_paint_vline = 0; @@ -376,7 +379,9 @@ void QGtkStylePrivate::resolveGtk() const gtk_entry_new = (Ptr_gtk_entry_new)libgtk.resolve("gtk_entry_new"); gtk_tree_view_new = (Ptr_gtk_tree_view_new)libgtk.resolve("gtk_tree_view_new"); gtk_combo_box_new = (Ptr_gtk_combo_box_new)libgtk.resolve("gtk_combo_box_new"); + gtk_progress_get_adjustment = (Ptr_gtk_progress_get_adjustment)libgtk.resolve("gtk_progress_get_adjustment"); gtk_progress_set_adjustment = (Ptr_gtk_progress_set_adjustment)libgtk.resolve("gtk_progress_set_adjustment"); + gtk_range_get_adjustment = (Ptr_gtk_range_get_adjustment)libgtk.resolve("gtk_range_get_adjustment"); gtk_range_set_adjustment = (Ptr_gtk_range_set_adjustment)libgtk.resolve("gtk_range_set_adjustment"); gtk_range_set_inverted = (Ptr_gtk_range_set_inverted)libgtk.resolve("gtk_range_set_inverted"); gtk_container_add = (Ptr_gtk_container_add)libgtk.resolve("gtk_container_add"); @@ -405,6 +410,7 @@ void QGtkStylePrivate::resolveGtk() const gtk_paint_extension = (Ptr_gtk_paint_extension)libgtk.resolve("gtk_paint_extension"); gtk_paint_hline = (Ptr_gtk_paint_hline)libgtk.resolve("gtk_paint_hline"); gtk_paint_vline = (Ptr_gtk_paint_vline)libgtk.resolve("gtk_paint_vline"); + gtk_adjustment_configure = (Ptr_gtk_adjustment_configure)libgtk.resolve("gtk_adjustment_configure"); gtk_adjustment_new = (Ptr_gtk_adjustment_new)libgtk.resolve("gtk_adjustment_new"); gtk_menu_item_set_submenu = (Ptr_gtk_menu_item_set_submenu)libgtk.resolve("gtk_menu_item_set_submenu"); gtk_settings_get_default = (Ptr_gtk_settings_get_default)libgtk.resolve("gtk_settings_get_default"); diff --git a/src/gui/styles/qgtkstyle_p.h b/src/gui/styles/qgtkstyle_p.h index 4e1d07a..57fa2fc 100644 --- a/src/gui/styles/qgtkstyle_p.h +++ b/src/gui/styles/qgtkstyle_p.h @@ -174,7 +174,9 @@ typedef GtkWidget* (*Ptr_gtk_frame_new)(const gchar *); typedef GtkWidget* (*Ptr_gtk_expander_new)(const gchar*); typedef GtkWidget* (*Ptr_gtk_statusbar_new)(void); typedef GtkSettings* (*Ptr_gtk_settings_get_default)(void); +typedef GtkAdjustment* (*Ptr_gtk_range_get_adjustment)(GtkRange *); typedef void (*Ptr_gtk_range_set_adjustment)(GtkRange *, GtkAdjustment *); +typedef GtkAdjustment* (*Ptr_gtk_progress_get_adjustment)(GtkProgress *); typedef void (*Ptr_gtk_progress_set_adjustment)(GtkProgress *, GtkAdjustment *); typedef void (*Ptr_gtk_range_set_inverted)(GtkRange*, bool); typedef void (*Ptr_gtk_container_add)(GtkContainer *container, GtkWidget *widget); @@ -198,6 +200,7 @@ typedef void (*Ptr_gtk_paint_arrow) (GtkStyle*,GdkWindow*, GtkStateType, GtkSha typedef void (*Ptr_gtk_paint_option) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint); typedef void (*Ptr_gtk_paint_flat_box) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint); typedef void (*Ptr_gtk_paint_extension) (GtkStyle *, GdkWindow *, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint, gint, GtkPositionType); +typedef void (*Ptr_gtk_adjustment_configure) (GtkAdjustment *, double, double, double, double, double, double); typedef GtkObject* (*Ptr_gtk_adjustment_new) (double, double, double, double, double, double); typedef void (*Ptr_gtk_paint_hline) (GtkStyle *, GdkWindow *, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint y); typedef void (*Ptr_gtk_paint_vline) (GtkStyle *, GdkWindow *, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint); @@ -393,7 +396,9 @@ public: static Ptr_gtk_progress_bar_new gtk_progress_bar_new; static Ptr_gtk_container_add gtk_container_add; static Ptr_gtk_menu_shell_append gtk_menu_shell_append; + static Ptr_gtk_progress_get_adjustment gtk_progress_get_adjustment; static Ptr_gtk_progress_set_adjustment gtk_progress_set_adjustment; + static Ptr_gtk_range_get_adjustment gtk_range_get_adjustment; static Ptr_gtk_range_set_adjustment gtk_range_set_adjustment; static Ptr_gtk_range_set_inverted gtk_range_set_inverted; static Ptr_gtk_icon_factory_lookup_default gtk_icon_factory_lookup_default; @@ -416,6 +421,7 @@ public: static Ptr_gtk_paint_arrow gtk_paint_arrow; static Ptr_gtk_paint_handle gtk_paint_handle; static Ptr_gtk_paint_expander gtk_paint_expander; + static Ptr_gtk_adjustment_configure gtk_adjustment_configure; static Ptr_gtk_adjustment_new gtk_adjustment_new; static Ptr_gtk_paint_vline gtk_paint_vline; static Ptr_gtk_paint_hline gtk_paint_hline; -- cgit v0.12 From fa72ccc5076e80c9a4c51501d8ff7c8161abfdeb Mon Sep 17 00:00:00 2001 From: aavit Date: Wed, 1 Dec 2010 11:52:00 +0100 Subject: Improvement of de30288: handle PNGs having 1 to 4 bytes truncated. Task-number: QT-4103 Reviewed-by: trustme --- src/gui/image/qpnghandler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index a4d669b..1a78bae 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -156,10 +156,11 @@ void CALLBACK_CALL_TYPE iod_read_fn(png_structp png_ptr, png_bytep data, png_siz QPngHandlerPrivate *d = (QPngHandlerPrivate *)png_get_io_ptr(png_ptr); QIODevice *in = d->q->device(); - if (d->state == QPngHandlerPrivate::ReadingEnd && in->atEnd() && length == 4) { + if (d->state == QPngHandlerPrivate::ReadingEnd && !in->isSequential() && (in->size() - in->pos()) < 4 && length == 4) { // Workaround for certain malformed PNGs that lack the final crc bytes uchar endcrc[4] = { 0xae, 0x42, 0x60, 0x82 }; qMemCopy(data, endcrc, 4); + in->seek(in->size()); return; } -- cgit v0.12 From 0f8e39459b47b99195eb677e7a32784b325834bd Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Wed, 1 Dec 2010 16:52:17 +0100 Subject: fix line endings --- .../qmlvisual/webview/flickable/flickweb.qml | 70 +++++++++++----------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/tests/auto/declarative/qmlvisual/webview/flickable/flickweb.qml b/tests/auto/declarative/qmlvisual/webview/flickable/flickweb.qml index 6063226..af09389 100644 --- a/tests/auto/declarative/qmlvisual/webview/flickable/flickweb.qml +++ b/tests/auto/declarative/qmlvisual/webview/flickable/flickweb.qml @@ -1,35 +1,35 @@ -import QtQuick 1.0 -import QtWebKit 1.0 - -Flickable { - id: flickable - width: 320 - height: 200 - contentWidth: Math.max(flickable.width,webView.width) - contentHeight: Math.max(flickable.height,webView.height) - pressDelay: 100 - - WebView { - id: webView - transformOrigin: Item.TopLeft - smooth: false // We don't want smooth scaling, since we only scale during (fast) transitions - url: "test.html" - preferredWidth: flickable.width - preferredHeight: flickable.height - contentsScale: 1 - onContentsSizeChanged: { - // zoom out - contentsScale = Math.min(1,flickable.width / contentsSize.width) - } - } - - Rectangle { - id: button - width: 50; height: 50; color: "red" - MouseArea { - anchors.fill: parent - onPressed: button.color = "blue" - onReleased: button.color = "green" - } - } -} +import QtQuick 1.0 +import QtWebKit 1.0 + +Flickable { + id: flickable + width: 320 + height: 200 + contentWidth: Math.max(flickable.width,webView.width) + contentHeight: Math.max(flickable.height,webView.height) + pressDelay: 100 + + WebView { + id: webView + transformOrigin: Item.TopLeft + smooth: false // We don't want smooth scaling, since we only scale during (fast) transitions + url: "test.html" + preferredWidth: flickable.width + preferredHeight: flickable.height + contentsScale: 1 + onContentsSizeChanged: { + // zoom out + contentsScale = Math.min(1,flickable.width / contentsSize.width) + } + } + + Rectangle { + id: button + width: 50; height: 50; color: "red" + MouseArea { + anchors.fill: parent + onPressed: button.color = "blue" + onReleased: button.color = "green" + } + } +} -- cgit v0.12 From 9ec7743776a8d444d29ae4439039beff39fee1bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 1 Dec 2010 16:33:52 +0100 Subject: Restore patch that disappeared in merge e50e811461b54e07184af547f62aa44b3c5bb681 --- src/gui/text/qfontengine_coretext.mm | 4 ++-- src/gui/text/qfontengine_coretext_p.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index 984531b..d270e1f 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -585,9 +585,9 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition return im; } -QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph) +QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) { - QImage im = imageForGlyph(glyph, QFixed(), 0, false); + QImage im = imageForGlyph(glyph, subPixelPosition, 0, false); QImage indexed(im.width(), im.height(), QImage::Format_Indexed8); QVector colors(256); diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h index d86c153..f31c033 100644 --- a/src/gui/text/qfontengine_coretext_p.h +++ b/src/gui/text/qfontengine_coretext_p.h @@ -83,7 +83,7 @@ public: virtual FaceId faceId() const; virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const; virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); - virtual QImage alphaMapForGlyph(glyph_t); + virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); virtual qreal minRightBearing() const; virtual qreal minLeftBearing() const; -- cgit v0.12 From 5fcdba84a8546a31974e4e1ecfaf481e0b9921a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 1 Dec 2010 16:37:51 +0100 Subject: Fix spelling mistake in QEGLPlatformcontext Autocompletion and a hint of dyslexia made me not see this before :) Reviewed-by: paul --- src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp | 2 +- src/plugins/platforms/eglconvenience/qeglplatformcontext.h | 2 +- src/plugins/platforms/eglfs/qeglfsscreen.cpp | 2 +- src/plugins/platforms/openkode/qopenkodewindow.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp index c4adb6f..4b83a22 100644 --- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp +++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp @@ -146,7 +146,7 @@ void* QEGLPlatformContext::getProcAddress(const QString& procName) return (void *)eglGetProcAddress(qPrintable(procName)); } -void QEGLPlatformContext::makeDefaultSaredContext() +void QEGLPlatformContext::makeDefaultSharedContext() { setDefaultSharedContext(this); } diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h index ae1a891..ac53559 100644 --- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h +++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h @@ -56,7 +56,7 @@ public: void swapBuffers(); void* getProcAddress(const QString& procName); - void makeDefaultSaredContext(); + void makeDefaultSharedContext(); QPlatformWindowFormat platformWindowFormat() const; private: diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index cbe6210..db90ff2 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -203,7 +203,7 @@ void QEglFSScreen::createAndSetPlatformContext() attribList[temp++] = EGL_NONE; QEGLPlatformContext *platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API); - platformContext->makeDefaultSaredContext(); + platformContext->makeDefaultSharedContext(); m_platformContext = platformContext; EGLint w,h; // screen size detection diff --git a/src/plugins/platforms/openkode/qopenkodewindow.cpp b/src/plugins/platforms/openkode/qopenkodewindow.cpp index 91c6473..01f8d21 100644 --- a/src/plugins/platforms/openkode/qopenkodewindow.cpp +++ b/src/plugins/platforms/openkode/qopenkodewindow.cpp @@ -158,7 +158,7 @@ QOpenKODEWindow::QOpenKODEWindow(QWidget *tlw) EGLSurface surface = eglCreateWindowSurface(screen->eglDisplay(),m_eglConfig,m_eglWindow,m_eglWindowAttrs.constData()); m_platformGlContext = new QEGLPlatformContext(screen->eglDisplay(), m_eglConfig, m_eglContextAttrs.data(), surface, m_eglApi); - m_platformGlContext->makeDefaultSaredContext(); + m_platformGlContext->makeDefaultSharedContext(); } else { m_platformGlContext = const_cast(static_cast(QPlatformGLContext::defaultSharedContext())); kdDestroyWindow(m_kdWindow); -- cgit v0.12 From c3f22e0b7ee6358ebe063b3aeea4a609e367a5f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 1 Dec 2010 17:04:45 +0100 Subject: Spelling mistakes in Documentation. There are probably more :) Reviewed-by: paul --- src/gui/kernel/qplatformintegration_qpa.cpp | 6 +++--- src/gui/kernel/qplatformwindow_qpa.cpp | 8 ++++---- src/gui/kernel/qplatformwindowformat_qpa.cpp | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp index 2a9bf77..9b6e590 100644 --- a/src/gui/kernel/qplatformintegration_qpa.cpp +++ b/src/gui/kernel/qplatformintegration_qpa.cpp @@ -68,7 +68,7 @@ QPlatformEventLoopIntegration *QPlatformIntegration::createEventLoopIntegration( } /*! - Returns wheter the given platform integration supports OpenGL. + Returns whether the given platform integration supports OpenGL. Default implementation returns false, */ @@ -103,7 +103,7 @@ QPlatformFontDatabase *QPlatformIntegration::fontDatabase() const QPlatformIntegration is the single entry point for windowsystem specific functionality when using the QPA platform. It has factory functions for creating platform specific pixmaps and - windows. The class also controlls the font subsystem. + windows. The class also controls the font subsystem. QPlatformIntegration is a singelton class which gets instansiated in the QApplication constructor. The QPlatformIntegration instance do not have ownership of objects it creates in @@ -147,7 +147,7 @@ QPlatformFontDatabase *QPlatformIntegration::fontDatabase() const \fn QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const Factory function for QWindowSurface. The QWidget parameter is a pointer to the - top level widget(tlw) the window surface is created for. A QPlatformWindow is allways created + top level widget(tlw) the window surface is created for. A QPlatformWindow is always created before the QWindowSurface for tlw where the widget also requires a WindowSurface. It is possible to create top level QWidgets without a QWindowSurface by specifying QPlatformWindowFormat::setWindowSurface(false) for the tlw QPlatformWindowFormat. diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp index 378fc68..29eaa82 100644 --- a/src/gui/kernel/qplatformwindow_qpa.cpp +++ b/src/gui/kernel/qplatformwindow_qpa.cpp @@ -138,7 +138,7 @@ WId QPlatformWindow::winId() const { return WId(0); } feature in Window systems, but can be faked. When this function is called all geometry of this platform window will be relative to the parent. */ -//jl: It would be usefull to have a property on the platform window which indicated if the sub-class +//jl: It would be useful to have a property on the platform window which indicated if the sub-class // supported the setParent. If not, then geometry would be in screen coordinates. void QPlatformWindow::setParent(const QPlatformWindow *parent) { @@ -157,7 +157,7 @@ void QPlatformWindow::setWindowTitle(const QString &title) {} void QPlatformWindow::raise() { qWarning("This plugin does not support raise()"); } /*! - Reimplement to be able to let Qt lower winows to the bottom of the dekstop + Reimplement to be able to let Qt lower windows to the bottom of the desktop */ void QPlatformWindow::lower() { qWarning("This plugin does not support lower()"); } @@ -171,7 +171,7 @@ void QPlatformWindow::setOpacity(qreal level) } /*! - Reimplement to return the glContext assosiated with the window. + Reimplement to return the glContext associated with the window. */ QPlatformGLContext *QPlatformWindow::glContext() const { @@ -194,7 +194,7 @@ QPlatformGLContext *QPlatformWindow::glContext() const QPlatformWindow is used to signal to the windowing system, how Qt persieves its frame. However, it is not concerned with how Qt renders into the window it represents. - Top level QWidgets(tlw) will allways have a QPlatformWindow. However, it is not neccesary for + Top level QWidgets(tlw) will always have a QPlatformWindow. However, it is not necessary for all tlw to have a QWindowSurface. This is the case for QGLWidget. And could be the case for widgets where some 3.party renders into it. diff --git a/src/gui/kernel/qplatformwindowformat_qpa.cpp b/src/gui/kernel/qplatformwindowformat_qpa.cpp index ade6bb3..44b0698 100644 --- a/src/gui/kernel/qplatformwindowformat_qpa.cpp +++ b/src/gui/kernel/qplatformwindowformat_qpa.cpp @@ -108,8 +108,8 @@ public: QWidget has a setter and getter function for QPlatformWindowFormat. These functions can be used by the application programmer to signal what kind of format he wants to the window and glcontext - should have. However, it is not allways possible to furfill these requirements. The application - programmer should therefor check the resulting QPlatformWindowFormat from QPlatformGLContext + should have. However, it is not always possible to fulfill these requirements. The application + programmer should therefore check the resulting QPlatformWindowFormat from QPlatformGLContext to see the format that was actually created. A display format has several characteristics: @@ -639,7 +639,7 @@ QPlatformGLContext *QPlatformWindowFormat::sharedGLContext() const otherwise the QWidget will only have a QPlatformWindow. - This is usefull for ie. QGLWidget where the QPlatformGLContext controlls the surface. + This is useful for ie. QGLWidget where the QPlatformGLContext controls the surface. \sa hasOverlay() */ -- cgit v0.12 From 0274e68767cce6440515a68d6af868725d5577a4 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Tue, 30 Nov 2010 22:44:52 +0100 Subject: QScroller merge, part 1 This merge consists of the actual kinetic scroller implementation, its autotests plus a few examples. QAbstractScrollArea and QAbstractItemView have been extended to support the new scroll events. The complete history is in http://scm.dev.nokia.troll.no/projects/qt/repos/rgriebls-qt-flickgesture/logs/4.7-flickgesture (part 2 is the QML Flickable replacement / part 3 is QWebView support) Task-number: QTBUG-9054 Reviewed-by: Ralf Engels --- doc/src/examples/wheel.qdoc | 109 ++ examples/examples.pro | 1 + examples/scroller/graphicsview/graphicsview.pro | 8 + examples/scroller/graphicsview/main.cpp | 292 ++++ examples/scroller/plot/main.cpp | 183 +++ examples/scroller/plot/plot.pro | 18 + examples/scroller/plot/plotwidget.cpp | 205 +++ examples/scroller/plot/plotwidget.h | 88 + examples/scroller/plot/settingswidget.cpp | 690 ++++++++ examples/scroller/plot/settingswidget.h | 107 ++ examples/scroller/scroller.pro | 11 + examples/scroller/wheel/main.cpp | 119 ++ examples/scroller/wheel/wheel.pro | 16 + examples/scroller/wheel/wheelwidget.cpp | 276 ++++ examples/scroller/wheel/wheelwidget.h | 102 ++ src/corelib/kernel/qcoreevent.cpp | 2 + src/corelib/kernel/qcoreevent.h | 3 + src/gui/itemviews/qabstractitemview.cpp | 39 + src/gui/itemviews/qabstractitemview.h | 1 + src/gui/itemviews/qabstractitemview_p.h | 7 + src/gui/kernel/qevent.cpp | 219 +++ src/gui/kernel/qevent.h | 46 + src/gui/kernel/qevent_p.h | 28 + src/gui/util/qflickgesture.cpp | 677 ++++++++ src/gui/util/qflickgesture_p.h | 113 ++ src/gui/util/qscroller.cpp | 1984 +++++++++++++++++++++++ src/gui/util/qscroller.h | 149 ++ src/gui/util/qscroller_mac.mm | 69 + src/gui/util/qscroller_p.h | 205 +++ src/gui/util/qscrollerproperties.cpp | 418 +++++ src/gui/util/qscrollerproperties.h | 140 ++ src/gui/util/qscrollerproperties_p.h | 94 ++ src/gui/util/util.pri | 12 + src/gui/widgets/qabstractscrollarea.cpp | 105 +- src/gui/widgets/qabstractscrollarea_p.h | 2 + tests/auto/gui.pro | 1 + tests/auto/qscroller/qscroller.pro | 3 + tests/auto/qscroller/tst_qscroller.cpp | 529 ++++++ tools/qml/texteditautoresizer_maemo5.h | 12 +- 39 files changed, 7076 insertions(+), 7 deletions(-) create mode 100644 doc/src/examples/wheel.qdoc create mode 100644 examples/scroller/graphicsview/graphicsview.pro create mode 100644 examples/scroller/graphicsview/main.cpp create mode 100644 examples/scroller/plot/main.cpp create mode 100644 examples/scroller/plot/plot.pro create mode 100644 examples/scroller/plot/plotwidget.cpp create mode 100644 examples/scroller/plot/plotwidget.h create mode 100644 examples/scroller/plot/settingswidget.cpp create mode 100644 examples/scroller/plot/settingswidget.h create mode 100644 examples/scroller/scroller.pro create mode 100644 examples/scroller/wheel/main.cpp create mode 100644 examples/scroller/wheel/wheel.pro create mode 100644 examples/scroller/wheel/wheelwidget.cpp create mode 100644 examples/scroller/wheel/wheelwidget.h create mode 100644 src/gui/util/qflickgesture.cpp create mode 100644 src/gui/util/qflickgesture_p.h create mode 100644 src/gui/util/qscroller.cpp create mode 100644 src/gui/util/qscroller.h create mode 100644 src/gui/util/qscroller_mac.mm create mode 100644 src/gui/util/qscroller_p.h create mode 100644 src/gui/util/qscrollerproperties.cpp create mode 100644 src/gui/util/qscrollerproperties.h create mode 100644 src/gui/util/qscrollerproperties_p.h create mode 100644 tests/auto/qscroller/qscroller.pro create mode 100644 tests/auto/qscroller/tst_qscroller.cpp diff --git a/doc/src/examples/wheel.qdoc b/doc/src/examples/wheel.qdoc new file mode 100644 index 0000000..1ea85fc --- /dev/null +++ b/doc/src/examples/wheel.qdoc @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in a +** written agreement between you and Nokia. +** +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of this +** file. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example scroller/wheel + \title Wheel Scroller Example + + The Wheel Scroller Example shows how to use QScroller, QScrollEvent + and QScrollPrepareEvent to implement smooth scrolling for a + custom Widget. + + \section1 Basics + + The QScroller class is the main part of the smooth scrolling + mechanism in Qt. It keeps track of the current scroll position and + speed and updates the object through events. + QScroller will get touch events via the QFlickGesture. + It will query the target object through a QScrollPrepareEvent for + the scroll area and other information. + QScroller will send QScrollEvents to inform the target object about + the current scroll position. + The target object (usually a QWidget or a QGraphicsObject) will + then need to update it's graphical representation to reflect the + new scroll position. + + \section1 The Wheel Widget class + + To demonstrate how to use the QScroller we implement a QWidget that + looks and works like the wheel of a slot machine. + The wheel can be started via touch events and will continue getting + slower. + Additionally the wheel should appear as if no border exists (which + would seem unnatural) and the scrolling should snap to center one + item. + + In the widget we need to grab the QFlickGesture. The gesture itself + will setAcceptTouchEvents for us, so we don't need to do that here. + + \snippet examples/scroller/wheel/wheelwidget.cpp 0 + + The widget will get gesture events but in addition we also will + get the events from QScroller. + We will need to accept the QScrollPrepareEvent to indicate that + a scrolling should really be started from the given position. + + \snippet examples/scroller/wheel/wheelwidget.cpp 1 + + We should call all three set functions form QScrollPrepareEvent. + + \list + \o \c setViewportSize to indicate our viewport size. Actually the + given code could be improved by giving our size minus the borders. + \o \c setMaxContentPos to indicate the maximum values for the scroll + position. The minimum values are implicitely set to 0. + In our example we give a very high number here and hope that the user + is not patient enough to scroll until the very end. + \o \c setContentPos to indicate the current scroll position. + We give a position in the middle of the huge scroll area. + Actually we give this position every time a new scroll is started so + the user will only reach the end if he continuously scrolls in one + direction which is not very likely. + \endlist + + The handling of the QScrollEvent is a lengthly code not fully shown here. + \snippet examples/scroller/wheel/wheelwidget.cpp 2 + + In principle it does three steps. + \list + \o It calculates and updates the current scroll position as given by + QScroller. + \o It repaints the widget so that the new position is shown. + \o It centers the item as soon as the scrolling stopps. + \endlist + + The following code does the centering. + \snippet examples/scroller/wheel/wheelwidget.cpp 3 + + We check if the scrolling is finished which is indicated in the + QScrollEvent by the \c isLast flag. + We then check if the item is not already centered and if not start a new + scroll by calling QScroller::scrollTo. + + As you can see the QScroller can be used for other things besides simple + scroll areas. +*/ diff --git a/examples/examples.pro b/examples/examples.pro index f233aba..968740d 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -20,6 +20,7 @@ SUBDIRS = \ mainwindows \ painting \ richtext \ + scroller \ sql \ tools \ tutorials \ diff --git a/examples/scroller/graphicsview/graphicsview.pro b/examples/scroller/graphicsview/graphicsview.pro new file mode 100644 index 0000000..dcebe62 --- /dev/null +++ b/examples/scroller/graphicsview/graphicsview.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +SOURCES = main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/scroller/graphicsview +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS graphicsview.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/scroller/graphicsview +INSTALLS += target sources diff --git a/examples/scroller/graphicsview/main.cpp b/examples/scroller/graphicsview/main.cpp new file mode 100644 index 0000000..e28978f --- /dev/null +++ b/examples/scroller/graphicsview/main.cpp @@ -0,0 +1,292 @@ +/**************************************************************************** +** +** 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 examples 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 +#include + +#define NUM_ITEMS 100 +#define NUM_LISTS 10 + +/*! + \class RectObject + Note that it needs to be a QGraphicsObject or else the gestures will not work correctly. +*/ +class RectObject : public QGraphicsObject +{ + Q_OBJECT + +public: + + RectObject(const QString &text, qreal x, qreal y, qreal width, qreal height, QBrush brush, QGraphicsItem *parent = 0) + : QGraphicsObject(parent) + , m_text(text) + , m_rect(x, y, width, height) + , m_pen(brush.color().lighter(), 3.0) + , m_brush(brush) + { + setFlag(QGraphicsItem::ItemClipsToShape, true); + } + + QRectF boundingRect() const + { + // here we only want the size of the children and not the size of the children of the children... + qreal halfpw = m_pen.widthF() / 2; + QRectF rect = m_rect; + if (halfpw > 0.0) + rect.adjust(-halfpw, -halfpw, halfpw, halfpw); + + return rect; + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + Q_UNUSED(option); + Q_UNUSED(widget); + painter->setPen(m_pen); + painter->setBrush(m_brush); + painter->drawRect(m_rect); + + painter->setPen(Qt::black); + QFont f; + f.setPixelSize(m_rect.height()); + painter->setFont(f); + painter->drawText(m_rect, Qt::AlignCenter, m_text); + } + + QString m_text; + QRectF m_rect; + QPen m_pen; + QBrush m_brush; +}; + +class ViewObject : public QGraphicsObject +{ + Q_OBJECT +public: + ViewObject(QGraphicsObject *parent) + : QGraphicsObject(parent) + { } + + QRectF boundingRect() const + { + QRectF rect; + foreach (QGraphicsItem *item, childItems()) + rect |= item->boundingRect().translated(item->pos()); + return rect; + } + + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) + { } +}; + +class ListObject : public QGraphicsObject +{ + Q_OBJECT + +public: + ListObject(const QSizeF &size, bool useTouch) + { + m_size = size; + setFlag(QGraphicsItem::ItemClipsChildrenToShape, true); + // grab gesture via Touch or Mouse events + QScroller::grabGesture(this, useTouch ? QScroller::TouchGesture : QScroller::LeftMouseButtonGesture); + + // this needs to be QGraphicsOBJECT - otherwise gesture recognition + // will not work for the parent of the viewport (in this case the + // list) + m_viewport = new ViewObject(this); + + } + + QGraphicsObject *viewport() const + { + return m_viewport; + } + + bool event(QEvent *e) + { + switch (e->type()) { +// ![2] + case QEvent::ScrollPrepare: { + QScrollPrepareEvent *se = static_cast(e); + se->setViewportSize(m_size); + QRectF br = m_viewport->boundingRect(); + se->setContentPosRange(QRectF(0, 0, + qMax(qreal(0), br.width() - m_size.width()), + qMax(qreal(0), br.height() - m_size.height()))); + se->setContentPos(-m_viewport->pos()); + se->accept(); + return true; + } +// ![1] +// ![2] + case QEvent::Scroll: { + QScrollEvent *se = static_cast(e); + m_viewport->setPos(-se->contentPos() - se->overshootDistance()); + return true; + } +// ![2] + default: + break; + } + return QGraphicsObject::event(e); + } + + bool sceneEvent(QEvent *e) + { + switch (e->type()) { + case QEvent::TouchBegin: { + // We need to return true for the TouchBegin here in the + // top-most graphics object - otherwise gestures in our parent + // objects will NOT work at all (the accept() flag is already + // set due to our setAcceptTouchEvents(true) call in the c'tor + return true; + + } + case QEvent::GraphicsSceneMousePress: { + // We need to return true for the MousePress here in the + // top-most graphics object - otherwise gestures in our parent + // objects will NOT work at all (the accept() flag is already + // set to true by Qt) + return true; + + } + default: + break; + } + return QGraphicsObject::sceneEvent(e); + } + + QRectF boundingRect() const + { + return QRectF(0, 0, m_size.width() + 3, m_size.height()); + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + Q_UNUSED(option); + Q_UNUSED(widget); + painter->setPen(QPen(QColor(100, 100, 100), 3.0)); + painter->drawRect(QRect(1.5, 1.5, m_size.width() - 3, m_size.height() - 3)); + } + + QSizeF m_size; + ViewObject *m_viewport; +}; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(bool useTouch) + { + m_scene = new QGraphicsScene(); + + // -- make the main list + ListObject *mainList = new ListObject(QSizeF(780, 400), useTouch); + mainList->setObjectName(QLatin1String("MainList")); + m_scene->addItem(mainList); +// ![3] + for (int i=0; im_size.width()/3, mainList->m_size.height()), useTouch); + childList->setObjectName(QString("ChildList %1").arg(i)); + fillList(childList); + childList->setParentItem(mainList->viewport()); + childList->setPos(i*mainList->m_size.width()/3, 0); + } + mainList->viewport()->setPos(0, 0); + + + /* + list1->setTransformOriginPoint(200, 200); + list1->setRotation(135); + list1->setPos(20 + 200 * .41, 20 + 200 * .41); + */ +// ![3] + + m_view = new QGraphicsView(m_scene); + setCentralWidget(m_view); + setWindowTitle(tr("Gesture example")); + m_scene->setSceneRect(0, 0, m_view->viewport()->width(), m_view->viewport()->height()); + } + + /** + * Fills the list object \a list with RectObjects. + */ + void fillList(ListObject *list) + { + qreal h = list->m_size.height() / 10; + for (int i=0; im_size.width() - 6, h - 3, QBrush(color), list->viewport()); + rect->setPos(3, h*i+3); + } + list->viewport()->setPos(0, 0); + } + + +protected: + void resizeEvent(QResizeEvent *e) + { + // resize the scene according to our own size to prevent scrolling + m_scene->setSceneRect(0, 0, m_view->viewport()->width(), m_view->viewport()->height()); + QMainWindow::resizeEvent(e); + } + + QGraphicsScene *m_scene; + QGraphicsView *m_view; +}; + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + bool useTouch = (app.arguments().contains(QLatin1String("--touch"))); + MainWindow mw(useTouch); + mw.show(); +#ifdef Q_WS_MAC + mw.raise(); +#endif + return app.exec(); +} + +#include "main.moc" diff --git a/examples/scroller/plot/main.cpp b/examples/scroller/plot/main.cpp new file mode 100644 index 0000000..a4e2add --- /dev/null +++ b/examples/scroller/plot/main.cpp @@ -0,0 +1,183 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "settingswidget.h" +#include "plotwidget.h" + + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow(bool smallscreen, bool touch) + : QMainWindow(), m_touch(touch) + { + m_list = new QListWidget(); + m_list->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + m_list_scroller = installKineticScroller(m_list); + + for (int i = 0; i < 1000; ++i) + new QListWidgetItem(QString("This is a test text %1 %2").arg(i).arg(QString("--------").left(i % 8)), m_list); + + connect(m_list, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(listItemActivated(QListWidgetItem*))); + connect(m_list, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(listItemClicked(QListWidgetItem*))); + connect(m_list, SIGNAL(itemPressed(QListWidgetItem*)), this, SLOT(listItemPressed(QListWidgetItem*))); + connect(m_list, SIGNAL(itemSelectionChanged()), this, SLOT(listItemSelectionChanged())); + connect(m_list, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(listItemCurrentChanged(QListWidgetItem*))); + + m_web = new QWebView(); + m_web_scroller = installKineticScroller(m_web); + + QTimer::singleShot(1000, this, SLOT(loadUrl())); + + m_settings = new SettingsWidget(smallscreen); + installKineticScroller(m_settings); + m_plot = new PlotWidget(smallscreen); + + QStackedWidget *stack = new QStackedWidget(); + stack->addWidget(m_list); + stack->addWidget(m_web); + + QActionGroup *pages = new QActionGroup(this); + pages->setExclusive(true); + QSignalMapper *mapper = new QSignalMapper(this); + connect(mapper, SIGNAL(mapped(int)), stack, SLOT(setCurrentIndex(int))); + + createAction("List", pages, mapper, 0, true); + createAction("Web", pages, mapper, 1); + + if (smallscreen) { + stack->addWidget(m_settings); + stack->addWidget(m_plot); + + createAction("Settings", pages, mapper, 2); + createAction("Plot", pages, mapper, 3); + + setCentralWidget(stack); + } else { + QSplitter *split = new QSplitter(); + m_settings->setMinimumWidth(m_settings->sizeHint().width()); + split->addWidget(stack); + split->addWidget(m_settings); + split->addWidget(m_plot); + setCentralWidget(split); + } + menuBar()->addMenu(QLatin1String("Pages"))->addActions(pages->actions()); + connect(stack, SIGNAL(currentChanged(int)), this, SLOT(pageChanged(int))); + pageChanged(0); + } + +private slots: + void pageChanged(int page) + { + if (page < 0 || page > 1) + return; + switch (page) { + case 0: + m_settings->setScroller(m_list); + m_plot->setScroller(m_list); + break; + case 1: + m_settings->setScroller(m_web); + m_plot->setScroller(m_web); + break; + default: + break; + } + } + + void loadUrl() + { + m_web->load(QUrl("http://www.google.com")); + } + + void listItemActivated(QListWidgetItem *lwi) { qWarning() << "Item ACTIVATED: " << lwi->text(); } + void listItemClicked(QListWidgetItem *lwi) { qWarning() << "Item CLICKED: " << lwi->text(); } + void listItemPressed(QListWidgetItem *lwi) { qWarning() << "Item PRESSED: " << lwi->text(); } + void listItemCurrentChanged(QListWidgetItem *lwi) { qWarning() << "Item CURRENT: " << (lwi ? lwi->text() : QString("(none)")); } + void listItemSelectionChanged() + { + int n = m_list->selectedItems().count(); + qWarning("Item%s SELECTED: %d", n == 1 ? "" : "s", n); + foreach (QListWidgetItem *lwi, m_list->selectedItems()) + qWarning() << " " << lwi->text(); + } + +private: + QAction *createAction(const char *text, QActionGroup *group, QSignalMapper *mapper, int mapping, bool checked = false) + { + QAction *a = new QAction(QLatin1String(text), group); + a->setCheckable(true); + a->setChecked(checked); +#if defined(Q_WS_MAC) + a->setMenuRole(QAction::NoRole); +#endif + mapper->setMapping(a, mapping); + connect(a, SIGNAL(toggled(bool)), mapper, SLOT(map())); + return a; + } + + QScroller *installKineticScroller(QWidget *w) + { + if (QAbstractScrollArea *area = qobject_cast(w)) { + QScroller::grabGesture(area->viewport(), m_touch ? QScroller::TouchGesture : QScroller::LeftMouseButtonGesture); + return QScroller::scroller(area->viewport()); + } else if (QWebView *web = qobject_cast(w)) { + QScroller::grabGesture(web, m_touch ? QScroller::TouchGesture : QScroller::LeftMouseButtonGesture); + } + return QScroller::scroller(w); + } + +private: + QListWidget *m_list; + QWebView *m_web; + QScroller *m_list_scroller, *m_web_scroller; + SettingsWidget *m_settings; + PlotWidget *m_plot; + bool m_touch; +}; + +int main(int argc, char **argv) +{ + QApplication a(argc, argv); + +#if defined(Q_WS_MAEMO_5) || defined(Q_WS_S60) || defined(Q_WS_WINCE) + bool smallscreen = true; +#else + bool smallscreen = false; +#endif + bool touch = false; + + if (a.arguments().contains(QLatin1String("--small"))) + smallscreen = true; + if (a.arguments().contains(QLatin1String("--touch"))) + touch = true; + + MainWindow *mw = new MainWindow(smallscreen, touch); + if (smallscreen) + mw->showMaximized(); + else + mw->show(); +#if defined(Q_WS_MAC) + mw->raise(); +#endif + + return a.exec(); +} + +#include "main.moc" diff --git a/examples/scroller/plot/plot.pro b/examples/scroller/plot/plot.pro new file mode 100644 index 0000000..8c37b04 --- /dev/null +++ b/examples/scroller/plot/plot.pro @@ -0,0 +1,18 @@ +HEADERS = settingswidget.h \ + plotwidget.h +SOURCES = settingswidget.cpp \ + plotwidget.cpp \ + main.cpp + +QT += webkit + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/scroller/plot +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS plot.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/scroller/plot +INSTALLS += target sources + +symbian { + TARGET.UID3 = 0xA000CF66 + include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) +} diff --git a/examples/scroller/plot/plotwidget.cpp b/examples/scroller/plot/plotwidget.cpp new file mode 100644 index 0000000..5f0df67 --- /dev/null +++ b/examples/scroller/plot/plotwidget.cpp @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 +#include +#include +#include +#include +#include +#include +#include + +#include "plotwidget.h" +#include "qscroller.h" + +PlotWidget::PlotWidget(bool /*smallscreen*/) + : QWidget(), m_widget(0) +{ + setWindowTitle(QLatin1String("Plot")); + m_clear = new QPushButton(QLatin1String("Clear"), this); +#if defined(Q_WS_MAEMO_5) + m_clear->setStyle(new QPlastiqueStyle()); + m_clear->setFixedHeight(55); +#endif + connect(m_clear, SIGNAL(clicked()), this, SLOT(reset())); + m_legend = new QLabel(this); + QString legend; + QTextStream ts(&legend); + // ok. this wouldn't pass the w3c html verification... + ts << ""; + ts << ""; + ts << ""; + ts << ""; + ts << ""; + ts << ""; + ts << ""; + ts << "
Velocity X
Velocity Y
Content Position X
Content Position Y
Overshoot Position X
Overshoot Position Y
"; + m_legend->setText(legend); +} + +void PlotWidget::setScroller(QWidget *widget) +{ + if (QAbstractScrollArea *area = qobject_cast(widget)) + widget = area->viewport(); + + if (m_widget) + m_widget->removeEventFilter(this); + m_widget = widget; + reset(); + if (m_widget) + m_widget->installEventFilter(this); +} + +bool PlotWidget::eventFilter(QObject *obj, QEvent *ev) +{ + if (ev->type() == QEvent::Scroll) { + QScrollEvent *se = static_cast(ev); + QScroller *scroller = QScroller::scroller(m_widget); + + QPointF v = scroller->velocity(); + //v.rx() *= scroller->pixelPerMeter().x(); + //v.ry() *= scroller->pixelPerMeter().y(); + + PlotItem pi = { v, se->contentPos(), se->overshootDistance() }; + addPlotItem(pi); + } + + return QWidget::eventFilter(obj, ev); +} + +static inline void doMaxMin(const QPointF &v, qreal &minmaxv) +{ + minmaxv = qMax(minmaxv, qMax(qAbs(v.x()), qAbs(v.y()))); +} + +void PlotWidget::addPlotItem(const PlotItem &pi) +{ + m_plotitems.append(pi); + minMaxVelocity = minMaxPosition = 0; + + while (m_plotitems.size() > 500) + m_plotitems.removeFirst(); + + foreach (const PlotItem &pi, m_plotitems) { + doMaxMin(pi.velocity, minMaxVelocity); + doMaxMin(pi.contentPosition, minMaxPosition); + doMaxMin(pi.overshootPosition, minMaxPosition); + } + update(); +} + +void PlotWidget::reset() +{ + m_plotitems.clear(); + minMaxVelocity = minMaxPosition = 0; + update(); +} + +void PlotWidget::resizeEvent(QResizeEvent *) +{ + QSize cs = m_clear->sizeHint(); + QSize ls = m_legend->sizeHint(); + m_clear->setGeometry(4, 4, cs.width(), cs.height()); + m_legend->setGeometry(4, height() - ls.height() - 4, ls.width(), ls.height()); +} + +void PlotWidget::paintEvent(QPaintEvent *) +{ +#define SCALE(v, mm) ((qreal(1) - (v / mm)) * qreal(0.5) * height()) + + QColor rvColor = Qt::red; + QColor cpColor = Qt::green; + QColor opColor = Qt::blue; + + + QPainter p(this); + //p.setRenderHints(QPainter::Antialiasing); //too slow for 60fps + p.fillRect(rect(), Qt::white); + + p.setPen(Qt::black); + p.drawLine(0, SCALE(0, 1), width(), SCALE(0, 1)); + + if (m_plotitems.isEmpty()) + return; + + int x = 2; + int offset = m_plotitems.size() - width() / 2; + QList::const_iterator it = m_plotitems.constBegin(); + if (offset > 0) + it += (offset - 1); + + const PlotItem *last = &(*it++); + + while (it != m_plotitems.constEnd()) { + p.setPen(rvColor.light()); + p.drawLine(qreal(x - 2), SCALE(last->velocity.x(), minMaxVelocity), + qreal(x), SCALE(it->velocity.x(), minMaxVelocity)); + p.setPen(rvColor.dark()); + p.drawLine(qreal(x - 2), SCALE(last->velocity.y(), minMaxVelocity), + qreal(x), SCALE(it->velocity.y(), minMaxVelocity)); + + p.setPen(cpColor.light()); + p.drawLine(qreal(x - 2), SCALE(last->contentPosition.x(), minMaxPosition), + qreal(x), SCALE(it->contentPosition.x(), minMaxPosition)); + p.setPen(cpColor.dark()); + p.drawLine(qreal(x - 2), SCALE(last->contentPosition.y(), minMaxPosition), + qreal(x), SCALE(it->contentPosition.y(), minMaxPosition)); + + p.setPen(opColor.light()); + p.drawLine(qreal(x - 2), SCALE(last->overshootPosition.x(), minMaxPosition), + qreal(x), SCALE(it->overshootPosition.x(), minMaxPosition)); + p.setPen(opColor.dark()); + p.drawLine(qreal(x - 2), SCALE(last->overshootPosition.y(), minMaxPosition), + qreal(x), SCALE(it->overshootPosition.y(), minMaxPosition)); + + last = &(*it++); + x += 2; + } + + QString toptext = QString("%1 [m/s] / %2 [pix]").arg(minMaxVelocity, 0, 'f', 2).arg(minMaxPosition, 0, 'f', 2); + QString bottomtext = QString("-%1 [m/s] / -%2 [pix]").arg(minMaxVelocity, 0, 'f', 2).arg(minMaxPosition, 0, 'f', 2); + + p.setPen(Qt::black); + p.drawText(rect(), Qt::AlignTop | Qt::AlignHCenter, toptext); + p.drawText(rect(), Qt::AlignBottom | Qt::AlignHCenter, bottomtext); +#undef SCALE +} diff --git a/examples/scroller/plot/plotwidget.h b/examples/scroller/plot/plotwidget.h new file mode 100644 index 0000000..3b4d92d --- /dev/null +++ b/examples/scroller/plot/plotwidget.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef PLOTWIDGET_H +#define PLOTWIDGET_H + +#include +#include + +class QPushButton; +class QLabel; + +class QScroller; + +class PlotWidget : public QWidget +{ + Q_OBJECT + +public: + PlotWidget(bool smallscreen = false); + + void setScroller(QWidget *widget); + +public slots: + void reset(); + +protected: + void resizeEvent(QResizeEvent *); + void paintEvent(QPaintEvent *); + + bool eventFilter(QObject *obj, QEvent *ev); + +private: + + struct PlotItem { + QPointF velocity; + QPointF contentPosition; + QPointF overshootPosition; + }; + + void addPlotItem(const PlotItem &pi); + + QWidget *m_widget; + QList m_plotitems; + qreal minMaxVelocity, minMaxPosition; + QPushButton *m_clear; + QLabel *m_legend; +}; + +#endif diff --git a/examples/scroller/plot/settingswidget.cpp b/examples/scroller/plot/settingswidget.cpp new file mode 100644 index 0000000..af1e621 --- /dev/null +++ b/examples/scroller/plot/settingswidget.cpp @@ -0,0 +1,690 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "math.h" + +#include "settingswidget.h" +#include "qscroller.h" +#include "qscrollerproperties.h" + +class SnapOverlay : public QWidget +{ + Q_OBJECT +public: + SnapOverlay(QWidget *w) + : QWidget(w) + { + setAttribute(Qt::WA_TransparentForMouseEvents); + + if (QAbstractScrollArea *area = qobject_cast(w)) { + connect(area->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(update())); + connect(area->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(update())); + area->viewport()->installEventFilter(this); + } + } + void clear(Qt::Orientation o) + { + m_snap[o].clear(); + update(); + } + + void set(Qt::Orientation o, qreal first, qreal step) + { + m_snap[o] = QList() << -Q_INFINITY << first << step; + update(); + } + + void set(Qt::Orientation o, const QList &list) + { + m_snap[o] = list; + update(); + } + +protected: + bool eventFilter(QObject *o, QEvent *e) + { + if (QAbstractScrollArea *area = qobject_cast(parentWidget())) { + if (area->viewport() == o) { + if (e->type() == QEvent::Move || e->type() == QEvent::Resize) { + setGeometry(area->viewport()->rect()); + } + } + } + return false; + } + + void paintEvent(QPaintEvent *e) + { + if (QAbstractScrollArea *area = qobject_cast(parentWidget())) { + int dx = area->horizontalScrollBar()->value(); + int dy = area->verticalScrollBar()->value(); + + QPainter paint(this); + paint.fillRect(e->rect(), Qt::transparent); + paint.setPen(QPen(Qt::red, 9)); + + if (m_snap[Qt::Horizontal].isEmpty()) { + } else if (m_snap[Qt::Horizontal][0] == -Q_INFINITY) { + int start = int(m_snap[Qt::Horizontal][1]); + int step = int(m_snap[Qt::Horizontal][2]); + if (step > 0) { + for (int i = start; i < area->horizontalScrollBar()->maximum(); i += step) + paint.drawPoint(i - dx, 5); + } + } else { + foreach (qreal r, m_snap[Qt::Horizontal]) + paint.drawPoint(int(r) - dx, 5); + } + paint.setPen(QPen(Qt::green, 9)); + if (m_snap[Qt::Vertical].isEmpty()) { + } else if (m_snap[Qt::Vertical][0] == -Q_INFINITY) { + int start = int(m_snap[Qt::Vertical][1]); + int step = int(m_snap[Qt::Vertical][2]); + if (step > 0) { + for (int i = start; i < area->verticalScrollBar()->maximum(); i += step) + paint.drawPoint(5, i - dy); + } + } else { + foreach (qreal r, m_snap[Qt::Vertical]) + paint.drawPoint(5, int(r) - dy); + } + } + } + +private: + QMap > m_snap; +}; + +struct MetricItem +{ + QScrollerProperties::ScrollMetric metric; + const char *name; + int scaling; + const char *unit; + QVariant min, max; + QVariant step; +}; + +class MetricItemUpdater : public QObject +{ + Q_OBJECT +public: + MetricItemUpdater(MetricItem *item) + : m_item(item) + , m_widget(0) + , m_slider(0) + , m_combo(0) + , m_valueLabel(0) + { + m_frameRateType = QVariant::fromValue(QScrollerProperties::Standard).userType(); + m_overshootPolicyType = QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable).userType(); + + if (m_item->min.type() == QVariant::EasingCurve) { + m_combo = new QComboBox(); + m_combo->addItem("OutQuad", QEasingCurve::OutQuad); + m_combo->addItem("OutCubic", QEasingCurve::OutCubic); + m_combo->addItem("OutQuart", QEasingCurve::OutQuart); + m_combo->addItem("OutQuint", QEasingCurve::OutQuint); + m_combo->addItem("OutExpo", QEasingCurve::OutExpo); + m_combo->addItem("OutSine", QEasingCurve::OutSine); + m_combo->addItem("OutCirc", QEasingCurve::OutCirc); + } else if (m_item->min.userType() == m_frameRateType) { + m_combo = new QComboBox(); + m_combo->addItem("Standard", QScrollerProperties::Standard); + m_combo->addItem("60 FPS", QScrollerProperties::Fps60); + m_combo->addItem("30 FPS", QScrollerProperties::Fps30); + m_combo->addItem("20 FPS", QScrollerProperties::Fps20); + } else if (m_item->min.userType() == m_overshootPolicyType) { + m_combo = new QComboBox(); + m_combo->addItem("When Scrollable", QScrollerProperties::OvershootWhenScrollable); + m_combo->addItem("Always On", QScrollerProperties::OvershootAlwaysOn); + m_combo->addItem("Always Off", QScrollerProperties::OvershootAlwaysOff); + } else { + m_slider = new QSlider(Qt::Horizontal); + m_slider->setSingleStep(1); + m_slider->setMinimum(-1); + m_slider->setMaximum(qRound((m_item->max.toReal() - m_item->min.toReal()) / m_item->step.toReal())); + m_slider->setValue(-1); + m_valueLabel = new QLabel(); + } + m_nameLabel = new QLabel(QLatin1String(m_item->name)); + if (m_item->unit && m_item->unit[0]) + m_nameLabel->setText(m_nameLabel->text() + QLatin1String(" [") + QLatin1String(m_item->unit) + QLatin1String("]")); + m_resetButton = new QToolButton(); + m_resetButton->setText(QLatin1String("Reset")); + m_resetButton->setEnabled(false); + + connect(m_resetButton, SIGNAL(clicked()), this, SLOT(reset())); + if (m_slider) { + connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(controlChanged(int))); + m_slider->setMinimum(0); + } else if (m_combo) { + connect(m_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(controlChanged(int))); + } + } + + void setScroller(QWidget *widget) + { + m_widget = widget; + QScroller *scroller = QScroller::scroller(widget); + QScrollerProperties properties = QScroller::scroller(widget)->scrollerProperties(); + + if (m_slider) + m_slider->setEnabled(scroller); + if (m_combo) + m_combo->setEnabled(scroller); + m_nameLabel->setEnabled(scroller); + if (m_valueLabel) + m_valueLabel->setEnabled(scroller); + m_resetButton->setEnabled(scroller); + + if (!scroller) + return; + + m_default_value = properties.scrollMetric(m_item->metric); + valueChanged(m_default_value); + } + + QWidget *nameLabel() { return m_nameLabel; } + QWidget *valueLabel() { return m_valueLabel; } + QWidget *valueControl() { if (m_combo) return m_combo; else return m_slider; } + QWidget *resetButton() { return m_resetButton; } + +private slots: + void valueChanged(const QVariant &v) + { + m_value = v; + if (m_slider) { + switch (m_item->min.type()) { + case QMetaType::Float: + case QVariant::Double: { + m_slider->setValue(qRound((m_value.toReal() * m_item->scaling - m_item->min.toReal()) / m_item->step.toReal())); + break; + } + case QVariant::Int: { + m_slider->setValue(qRound((m_value.toInt() * m_item->scaling - m_item->min.toInt()) / m_item->step.toInt())); + break; + } + default: break; + } + } else if (m_combo) { + if (m_item->min.type() == QVariant::EasingCurve) { + m_combo->setCurrentIndex(m_combo->findData(v.toEasingCurve().type())); + } else if (m_item->min.userType() == m_overshootPolicyType) { + m_combo->setCurrentIndex(m_combo->findData(v.value())); + } else if (m_item->min.userType() == m_frameRateType) { + m_combo->setCurrentIndex(m_combo->findData(v.value())); + } + } + } + + void controlChanged(int value) + { + bool combo = (m_combo && (sender() == m_combo)); + QString text; + + if (m_slider && !combo) { + switch (m_item->min.type()) { + case QMetaType::Float: + case QVariant::Double: { + qreal d = m_item->min.toReal() + qreal(value) * m_item->step.toReal(); + text = QString::number(d); + m_value = d / qreal(m_item->scaling); + break; + } + case QVariant::Int: { + int i = m_item->min.toInt() + qRound(qreal(value) * m_item->step.toReal()); + text = QString::number(i); + m_value = i / m_item->scaling; + break; + } + default: break; + } + } else if (m_combo && combo) { + if (m_item->min.type() == QVariant::EasingCurve) { + m_value = QVariant(QEasingCurve(static_cast(m_combo->itemData(value).toInt()))); + } else if (m_item->min.userType() == m_overshootPolicyType) { + m_value = QVariant::fromValue(static_cast(m_combo->itemData(value).toInt())); + } else if (m_item->min.userType() == m_frameRateType) { + m_value = QVariant::fromValue(static_cast(m_combo->itemData(value).toInt())); + } + } + if (m_valueLabel) + m_valueLabel->setText(text); + if (m_widget && QScroller::scroller(m_widget)) { + QScrollerProperties properties = QScroller::scroller(m_widget)->scrollerProperties(); + properties.setScrollMetric(m_item->metric, m_value); + QScroller::scroller(m_widget)->setScrollerProperties(properties); + } + + m_resetButton->setEnabled(m_value != m_default_value); + } + + void reset() + { + QScrollerProperties properties = QScroller::scroller(m_widget)->scrollerProperties(); + properties.setScrollMetric(m_item->metric, m_value); + QScroller::scroller(m_widget)->setScrollerProperties(properties); + valueChanged(m_default_value); + } + +private: + MetricItem *m_item; + int m_frameRateType; + int m_overshootPolicyType; + + QWidget *m_widget; + QSlider *m_slider; + QComboBox *m_combo; + QLabel *m_nameLabel, *m_valueLabel; + QToolButton *m_resetButton; + + QVariant m_value, m_default_value; +}; + +#define METRIC(x) QScrollerProperties::x, #x + +MetricItem items[] = { + { METRIC(MousePressEventDelay), 1000, "ms", qreal(0), qreal(2000), qreal(10) }, + { METRIC(DragStartDistance), 1000, "mm", qreal(1), qreal(20), qreal(0.1) }, + { METRIC(DragVelocitySmoothingFactor), 1, "", qreal(0), qreal(1), qreal(0.01) }, + { METRIC(AxisLockThreshold), 1, "", qreal(0), qreal(1), qreal(0.01) }, + + { METRIC(ScrollingCurve), 1, "", QEasingCurve(), 0, 0 }, + { METRIC(DecelerationFactor), 1, "", qreal(0), qreal(3), qreal(0.01) }, + + { METRIC(MinimumVelocity), 1, "m/s", qreal(0), qreal(7), qreal(0.01) }, + { METRIC(MaximumVelocity), 1, "m/s", qreal(0), qreal(7), qreal(0.01) }, + { METRIC(MaximumClickThroughVelocity), 1, "m/s", qreal(0), qreal(7), qreal(0.01) }, + + { METRIC(AcceleratingFlickMaximumTime), 1000, "ms", qreal(100), qreal(5000), qreal(100) }, + { METRIC(AcceleratingFlickSpeedupFactor), 1, "", qreal(1), qreal(7), qreal(0.1) }, + + { METRIC(SnapPositionRatio), 1, "", qreal(0.1), qreal(0.9), qreal(0.1) }, + { METRIC(SnapTime), 1000, "ms", qreal(0), qreal(2000), qreal(10) }, + + { METRIC(OvershootDragResistanceFactor), 1, "", qreal(0), qreal(1), qreal(0.01) }, + { METRIC(OvershootDragDistanceFactor), 1, "", qreal(0), qreal(1), qreal(0.01) }, + { METRIC(OvershootScrollDistanceFactor), 1, "", qreal(0), qreal(1), qreal(0.01) }, + { METRIC(OvershootScrollTime), 1000, "ms", qreal(0), qreal(2000), qreal(10) }, + + { METRIC(HorizontalOvershootPolicy), 1, "", QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable), 0, 0 }, + { METRIC(VerticalOvershootPolicy), 1, "", QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable), 0, 0 }, + { METRIC(FrameRate), 1, "", QVariant::fromValue(QScrollerProperties::Standard), 0, 0 }, +}; + +#undef METRIC + +void SettingsWidget::addToGrid(QGridLayout *grid, QWidget *label, int widgetCount, ...) +{ + va_list args; + va_start(args, widgetCount); + + int rows = grid->rowCount(); + int cols = grid->columnCount(); + + if (label) { + if (m_smallscreen) + grid->addWidget(label, rows++, 0, 1, qMax(cols, widgetCount)); + else + grid->addWidget(label, rows, 0); + } + for (int i = 0; i < widgetCount; i++) { + if (QWidget *w = va_arg(args, QWidget *)) + grid->addWidget(w, rows, m_smallscreen ? i : i + 1); + } + va_end(args); +} + +SettingsWidget::SettingsWidget(bool smallscreen) + : QScrollArea() + , m_widget(0) + , m_snapoverlay(0) + , m_smallscreen(smallscreen) +{ + setWindowTitle(QLatin1String("Settings")); + QWidget *view = new QWidget(); + QVBoxLayout *layout = new QVBoxLayout(view); + QGroupBox *grp; + QGridLayout *grid; + + // GROUP: SCROLL METRICS + + grp = new QGroupBox(QLatin1String("Scroll Metrics")); + grid = new QGridLayout(); + grid->setVerticalSpacing(m_smallscreen ? 4 : 2); + + for (int i = 0; i < int(sizeof(items) / sizeof(items[0])); i++) { + MetricItemUpdater *u = new MetricItemUpdater(items + i); + u->setParent(this); + addToGrid(grid, u->nameLabel(), 3, u->valueControl(), u->valueLabel(), u->resetButton()); + m_metrics.append(u); + } + grp->setLayout(grid); + layout->addWidget(grp); + + // GROUP: SCROLL TO + + grp = new QGroupBox(QLatin1String("Scroll To")); + grid = new QGridLayout(); + grid->setVerticalSpacing(m_smallscreen ? 4 : 2); + + m_scrollx = new QSpinBox(); + m_scrolly = new QSpinBox(); + m_scrolltime = new QSpinBox(); + m_scrolltime->setRange(0, 10000); + m_scrolltime->setValue(1000); + m_scrolltime->setSuffix(QLatin1String(" ms")); + QPushButton *go = new QPushButton(QLatin1String("Go")); + connect(go, SIGNAL(clicked()), this, SLOT(scrollTo())); + connect(m_scrollx, SIGNAL(editingFinished()), this, SLOT(scrollTo())); + connect(m_scrolly, SIGNAL(editingFinished()), this, SLOT(scrollTo())); + connect(m_scrolltime, SIGNAL(editingFinished()), this, SLOT(scrollTo())); + grid->addWidget(new QLabel(QLatin1String("X:")), 0, 0); + grid->addWidget(m_scrollx, 0, 1); + grid->addWidget(new QLabel(QLatin1String("Y:")), 0, 2); + grid->addWidget(m_scrolly, 0, 3); + int row = smallscreen ? 1 : 0; + int col = smallscreen ? 0 : 4; + grid->addWidget(new QLabel(QLatin1String("in")), row, col++); + grid->addWidget(m_scrolltime, row, col++); + if (smallscreen) { + grid->addWidget(go, row, col + 1); + } else { + grid->addWidget(go, row, col); + grid->setColumnStretch(5, 1); + grid->setColumnStretch(6, 1); + } + grid->setColumnStretch(1, 1); + grid->setColumnStretch(3, 1); + grp->setLayout(grid); + layout->addWidget(grp); + + QLayout *snapbox = new QHBoxLayout(); + + // GROUP: SNAP POINTS X + + grp = new QGroupBox(QLatin1String("Snap Positions X")); + QBoxLayout *vbox = new QVBoxLayout(); + vbox->setSpacing(m_smallscreen ? 4 : 2); + m_snapx = new QComboBox(); + m_snapx->addItem(QLatin1String("No Snapping"), NoSnap); + m_snapx->addItem(QLatin1String("Snap to Interval"), SnapToInterval); + m_snapx->addItem(QLatin1String("Snap to List"), SnapToList); + connect(m_snapx, SIGNAL(currentIndexChanged(int)), this, SLOT(snapModeChanged(int))); + vbox->addWidget(m_snapx); + + m_snapxinterval = new QWidget(); + grid = new QGridLayout(); + grid->setVerticalSpacing(m_smallscreen ? 4 : 2); + m_snapxfirst = new QSpinBox(); + connect(m_snapxfirst, SIGNAL(valueChanged(int)), this, SLOT(snapPositionsChanged())); + grid->addWidget(new QLabel("First:"), 0, 0); + grid->addWidget(m_snapxfirst, 0, 1); + m_snapxstep = new QSpinBox(); + connect(m_snapxstep, SIGNAL(valueChanged(int)), this, SLOT(snapPositionsChanged())); + grid->addWidget(new QLabel("Interval:"), 0, 2); + grid->addWidget(m_snapxstep, 0, 3); + m_snapxinterval->setLayout(grid); + vbox->addWidget(m_snapxinterval); + m_snapxinterval->hide(); + + m_snapxlist = new QPlainTextEdit(); + m_snapxlist->setToolTip(QLatin1String("One snap position per line. Empty lines are ignored.")); + m_snapxlist->installEventFilter(this); + connect(m_snapxlist, SIGNAL(textChanged()), this, SLOT(snapPositionsChanged())); + vbox->addWidget(m_snapxlist); + m_snapxlist->hide(); + + vbox->addStretch(100); + grp->setLayout(vbox); + snapbox->addWidget(grp); + + // GROUP: SNAP POINTS Y + + grp = new QGroupBox(QLatin1String("Snap Positions Y")); + vbox = new QVBoxLayout(); + vbox->setSpacing(m_smallscreen ? 4 : 2); + m_snapy = new QComboBox(); + m_snapy->addItem(QLatin1String("No Snapping"), NoSnap); + m_snapy->addItem(QLatin1String("Snap to Interval"), SnapToInterval); + m_snapy->addItem(QLatin1String("Snap to List"), SnapToList); + connect(m_snapy, SIGNAL(currentIndexChanged(int)), this, SLOT(snapModeChanged(int))); + vbox->addWidget(m_snapy); + + m_snapyinterval = new QWidget(); + grid = new QGridLayout(); + grid->setVerticalSpacing(m_smallscreen ? 4 : 2); + m_snapyfirst = new QSpinBox(); + connect(m_snapyfirst, SIGNAL(valueChanged(int)), this, SLOT(snapPositionsChanged())); + grid->addWidget(new QLabel("First:"), 0, 0); + grid->addWidget(m_snapyfirst, 0, 1); + m_snapystep = new QSpinBox(); + connect(m_snapystep, SIGNAL(valueChanged(int)), this, SLOT(snapPositionsChanged())); + grid->addWidget(new QLabel("Interval:"), 0, 2); + grid->addWidget(m_snapystep, 0, 3); + m_snapyinterval->setLayout(grid); + vbox->addWidget(m_snapyinterval); + m_snapyinterval->hide(); + + m_snapylist = new QPlainTextEdit(); + m_snapylist->setToolTip(QLatin1String("One snap position per line. Empty lines are ignored.")); + m_snapylist->installEventFilter(this); + connect(m_snapylist, SIGNAL(textChanged()), this, SLOT(snapPositionsChanged())); + vbox->addWidget(m_snapylist); + m_snapylist->hide(); + + vbox->addStretch(100); + grp->setLayout(vbox); + snapbox->addWidget(grp); + + layout->addLayout(snapbox); + + layout->addStretch(100); + setWidget(view); + setWidgetResizable(true); +} + +void SettingsWidget::setScroller(QWidget *widget) +{ + delete m_snapoverlay; + if (m_widget) + m_widget->removeEventFilter(this); + QAbstractScrollArea *area = qobject_cast(widget); + if (area) + widget = area->viewport(); + m_widget = widget; + m_widget->installEventFilter(this); + m_snapoverlay = new SnapOverlay(area); + QScrollerProperties properties = QScroller::scroller(widget)->scrollerProperties(); + + QMutableListIterator it(m_metrics); + while (it.hasNext()) + it.next()->setScroller(widget); + + if (!widget) + return; + + updateScrollRanges(); +} + +bool SettingsWidget::eventFilter(QObject *o, QEvent *e) +{ + if (o == m_widget && e->type() == QEvent::Resize) + updateScrollRanges(); + return false; +} + +void SettingsWidget::updateScrollRanges() +{ + QScrollPrepareEvent spe(QPoint(0, 0)); + QApplication::sendEvent(m_widget, &spe); + + QSizeF vp = spe.viewportSize(); + QRectF maxc = spe.contentPosRange(); + + m_scrollx->setRange(qRound(-vp.width()), qRound(maxc.width() + vp.width())); + m_scrolly->setRange(qRound(-vp.height()), qRound(maxc.height() + vp.height())); + + m_snapxfirst->setRange(maxc.left(), maxc.right()); + m_snapxstep->setRange(0, maxc.width()); + m_snapyfirst->setRange(maxc.top(), maxc.bottom()); + m_snapystep->setRange(0, maxc.height()); +} + +void SettingsWidget::scrollTo() +{ + if (QApplication::activePopupWidget()) + return; + if ((sender() == m_scrollx) && !m_scrollx->hasFocus()) + return; + if ((sender() == m_scrolly) && !m_scrolly->hasFocus()) + return; + if ((sender() == m_scrolltime) && !m_scrolltime->hasFocus()) + return; + + if (QScroller *scroller = QScroller::scroller(m_widget)) + scroller->scrollTo(QPointF(m_scrollx->value(), m_scrolly->value()), m_scrolltime->value()); +} + +void SettingsWidget::snapModeChanged(int mode) +{ + if (sender() == m_snapx) { + m_snapxmode = static_cast(mode); + m_snapxinterval->setVisible(mode == SnapToInterval); + m_snapxlist->setVisible(mode == SnapToList); + snapPositionsChanged(); + } else if (sender() == m_snapy) { + m_snapymode = static_cast(mode); + m_snapyinterval->setVisible(mode == SnapToInterval); + m_snapylist->setVisible(mode == SnapToList); + snapPositionsChanged(); + } +} + +void SettingsWidget::snapPositionsChanged() +{ + QScroller *s = QScroller::scroller(m_widget); + if (!s) + return; + + switch (m_snapxmode) { + case NoSnap: + s->setSnapPositionsX(QList()); + m_snapoverlay->clear(Qt::Horizontal); + break; + case SnapToInterval: + s->setSnapPositionsX(m_snapxfirst->value(), m_snapxstep->value()); + m_snapoverlay->set(Qt::Horizontal, m_snapxfirst->value(), m_snapxstep->value()); + break; + case SnapToList: + s->setSnapPositionsX(toPositionList(m_snapxlist, m_snapxfirst->minimum(), m_snapxfirst->maximum())); + m_snapoverlay->set(Qt::Horizontal, toPositionList(m_snapxlist, m_snapxfirst->minimum(), m_snapxfirst->maximum())); + break; + } + switch (m_snapymode) { + case NoSnap: + s->setSnapPositionsY(QList()); + m_snapoverlay->clear(Qt::Vertical); + break; + case SnapToInterval: + s->setSnapPositionsY(m_snapyfirst->value(), m_snapystep->value()); + m_snapoverlay->set(Qt::Vertical, m_snapyfirst->value(), m_snapystep->value()); + break; + case SnapToList: + s->setSnapPositionsY(toPositionList(m_snapylist, m_snapyfirst->minimum(), m_snapyfirst->maximum())); + m_snapoverlay->set(Qt::Vertical, toPositionList(m_snapylist, m_snapyfirst->minimum(), m_snapyfirst->maximum())); + break; + } +} + +QList SettingsWidget::toPositionList(QPlainTextEdit *list, int vmin, int vmax) +{ + QList snaps; + QList extrasel; + QTextEdit::ExtraSelection uline; + uline.format.setUnderlineColor(Qt::red); + uline.format.setUnderlineStyle(QTextCharFormat::WaveUnderline); + int line = 0; + + foreach (const QString &str, list->toPlainText().split(QLatin1Char('\n'))) { + ++line; + if (str.isEmpty()) + continue; + bool ok = false; + double d = str.toDouble(&ok); + if (ok && d >= vmin && d <= vmax) { + snaps << d; + } else { + QTextEdit::ExtraSelection esel = uline; + esel.cursor = QTextCursor(list->document()->findBlockByLineNumber(line - 1)); + esel.cursor.select(QTextCursor::LineUnderCursor); + extrasel << esel; + } + } + list->setExtraSelections(extrasel); + return snaps; +} + +#include "settingswidget.moc" diff --git a/examples/scroller/plot/settingswidget.h b/examples/scroller/plot/settingswidget.h new file mode 100644 index 0000000..2fb268c --- /dev/null +++ b/examples/scroller/plot/settingswidget.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef SETTINGSWIDGET_H +#define SETTINGSWIDGET_H + +#include + +class QScroller; +class QGridLayout; +class QSpinBox; +class QComboBox; +class QCheckBox; +class QPlainTextEdit; + +class MetricItemUpdater; +class SnapOverlay; + +class SettingsWidget : public QScrollArea +{ + Q_OBJECT + +public: + SettingsWidget(bool smallscreen = false); + + void setScroller(QWidget *widget); + +protected: + bool eventFilter(QObject *, QEvent *); + +private slots: + void scrollTo(); + void snapModeChanged(int); + void snapPositionsChanged(); + +private: + enum SnapMode { + NoSnap, + SnapToInterval, + SnapToList + }; + + void addToGrid(QGridLayout *grid, QWidget *label, int widgetCount, ...); + QList toPositionList(QPlainTextEdit *list, int vmin, int vmax); + void updateScrollRanges(); + + QWidget *m_widget; + QSpinBox *m_scrollx, *m_scrolly, *m_scrolltime; + QList m_metrics; + + SnapMode m_snapxmode; + QComboBox *m_snapx; + QWidget *m_snapxinterval; + QPlainTextEdit *m_snapxlist; + QSpinBox *m_snapxfirst; + QSpinBox *m_snapxstep; + + SnapMode m_snapymode; + QComboBox *m_snapy; + QWidget *m_snapyinterval; + QPlainTextEdit *m_snapylist; + QSpinBox *m_snapyfirst; + QSpinBox *m_snapystep; + SnapOverlay *m_snapoverlay; + + bool m_smallscreen; +}; + +#endif diff --git a/examples/scroller/scroller.pro b/examples/scroller/scroller.pro new file mode 100644 index 0000000..e830745 --- /dev/null +++ b/examples/scroller/scroller.pro @@ -0,0 +1,11 @@ +TEMPLATE = subdirs +SUBDIRS = graphicsview \ + plot \ + wheel + +# install +sources.files = *.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/scroller +INSTALLS += sources + +symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) diff --git a/examples/scroller/wheel/main.cpp b/examples/scroller/wheel/main.cpp new file mode 100644 index 0000000..4264377 --- /dev/null +++ b/examples/scroller/wheel/main.cpp @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 +#include + +#include "wheelwidget.h" + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow(bool touch) + : QMainWindow() + { + makeSlotMachine(touch); + setCentralWidget(m_slotMachine); + } + + void makeSlotMachine(bool touch) + { + if (QApplication::desktop()->width() > 1000) { + QFont f = font(); + f.setPointSize(f.pointSize() * 2); + setFont(f); + } + + m_slotMachine = new QWidget(this); + QGridLayout *grid = new QGridLayout(m_slotMachine); + grid->setSpacing(20); + + QStringList colors; + colors << "Red" << "Magenta" << "Peach" << "Orange" << "Yellow" << "Citro" << "Green" << "Cyan" << "Blue" << "Violet"; + + m_wheel1 = new StringWheelWidget(touch); + m_wheel1->setItems( colors ); + grid->addWidget( m_wheel1, 0, 0 ); + + m_wheel2 = new StringWheelWidget(touch); + m_wheel2->setItems( colors ); + grid->addWidget( m_wheel2, 0, 1 ); + + m_wheel3 = new StringWheelWidget(touch); + m_wheel3->setItems( colors ); + grid->addWidget( m_wheel3, 0, 2 ); + + QPushButton *shakeButton = new QPushButton(tr("Shake")); + connect(shakeButton, SIGNAL(clicked()), this, SLOT(rotateRandom())); + + grid->addWidget( shakeButton, 1, 0, 1, 3 ); + } + +private slots: + void rotateRandom() + { + m_wheel1->scrollTo(m_wheel1->currentIndex() + (qrand() % 200)); + m_wheel2->scrollTo(m_wheel2->currentIndex() + (qrand() % 200)); + m_wheel3->scrollTo(m_wheel3->currentIndex() + (qrand() % 200)); + } + +private: + QWidget *m_slotMachine; + + StringWheelWidget *m_wheel1; + StringWheelWidget *m_wheel2; + StringWheelWidget *m_wheel3; +}; + +int main(int argc, char **argv) +{ + QApplication a(argc, argv); + + bool touch = a.arguments().contains(QLatin1String("--touch")); + + MainWindow *mw = new MainWindow(touch); + mw->show(); + + return a.exec(); +} + +#include "main.moc" diff --git a/examples/scroller/wheel/wheel.pro b/examples/scroller/wheel/wheel.pro new file mode 100644 index 0000000..1f9b789 --- /dev/null +++ b/examples/scroller/wheel/wheel.pro @@ -0,0 +1,16 @@ +HEADERS = wheelwidget.h +SOURCES = wheelwidget.cpp \ + main.cpp + +QT += webkit + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/scroller/wheel +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS wheel.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/scroller/wheel +INSTALLS += target sources + +symbian { + TARGET.UID3 = 0xA000CF66 + include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) +} diff --git a/examples/scroller/wheel/wheelwidget.cpp b/examples/scroller/wheel/wheelwidget.cpp new file mode 100644 index 0000000..64a459b --- /dev/null +++ b/examples/scroller/wheel/wheelwidget.cpp @@ -0,0 +1,276 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 + +#include "wheelwidget.h" + +#define WHEEL_SCROLL_OFFSET 50000.0 + +AbstractWheelWidget::AbstractWheelWidget(bool touch, QWidget *parent) + : QWidget(parent) + , m_currentItem(0) + , m_itemOffset(0) +{ +// ![0] + QScroller::grabGesture(this, touch ? QScroller::TouchGesture : QScroller::LeftMouseButtonGesture); +// ![0] +} + +AbstractWheelWidget::~AbstractWheelWidget() +{ } + +int AbstractWheelWidget::currentIndex() const +{ + return m_currentItem; +} + +void AbstractWheelWidget::setCurrentIndex(int index) +{ + if (index >= 0 && index < itemCount()) { + m_currentItem = index; + m_itemOffset = 0; + update(); + } +} + +bool AbstractWheelWidget::event(QEvent *e) +{ + switch (e->type()) { +// ![1] + case QEvent::ScrollPrepare: + { + // We set the snap positions as late as possible so that we are sure + // we get the correct itemHeight + QScroller *scroller = QScroller::scroller(this); + scroller->setSnapPositionsY( WHEEL_SCROLL_OFFSET, itemHeight() ); + + QScrollPrepareEvent *se = static_cast(e); + se->setViewportSize(QSizeF(size())); + // we claim a huge scrolling area and a huge content position and + // hope that the user doesn't notice that the scroll area is restricted + se->setContentPosRange(QRectF(0.0, 0.0, 0.0, WHEEL_SCROLL_OFFSET * 2)); + se->setContentPos(QPointF(0.0, WHEEL_SCROLL_OFFSET + m_currentItem * itemHeight() + m_itemOffset)); + se->accept(); + return true; + } +// ![1] +// ![2] + case QEvent::Scroll: + { + QScrollEvent *se = static_cast(e); + + qreal y = se->contentPos().y(); + int iy = y - WHEEL_SCROLL_OFFSET; + int ih = itemHeight(); + +// ![2] + + // -- calculate the current item position and offset and redraw the widget + int ic = itemCount(); + if (ic>0) { + m_currentItem = iy / ih % ic; + m_itemOffset = iy % ih; + + // take care when scrolling backwards. Modulo returns negative numbers + if (m_itemOffset < 0) { + m_itemOffset += ih; + m_currentItem--; + } + + if (m_currentItem < 0) + m_currentItem += ic; + } + // -- repaint + update(); + + se->accept(); + return true; + } + default: + return QWidget::event(e); + } + return true; +} + +void AbstractWheelWidget::paintEvent(QPaintEvent* event) +{ + Q_UNUSED( event ); + + // -- first calculate size and position. + int w = width(); + int h = height(); + + QPainter painter(this); + QPalette palette = QApplication::palette(); + QPalette::ColorGroup colorGroup = isEnabled() ? QPalette::Active : QPalette::Disabled; + + // linear gradient brush + QLinearGradient grad(0.5, 0, 0.5, 1.0); + grad.setColorAt(0, palette.color(colorGroup, QPalette::ButtonText)); + grad.setColorAt(0.2, palette.color(colorGroup, QPalette::Button)); + grad.setColorAt(0.8, palette.color(colorGroup, QPalette::Button)); + grad.setColorAt(1.0, palette.color(colorGroup, QPalette::ButtonText)); + grad.setCoordinateMode( QGradient::ObjectBoundingMode ); + QBrush gBrush( grad ); + + // paint a border and background + painter.setPen(palette.color(colorGroup, QPalette::ButtonText)); + painter.setBrush(gBrush); + // painter.setBrushOrigin( QPointF( 0.0, 0.0 ) ); + painter.drawRect( 0, 0, w-1, h-1 ); + + // paint inner border + painter.setPen(palette.color(colorGroup, QPalette::Button)); + painter.setBrush(Qt::NoBrush); + painter.drawRect( 1, 1, w-3, h-3 ); + + // paint the items + painter.setClipRect( QRect( 3, 3, w-6, h-6 ) ); + painter.setPen(palette.color(colorGroup, QPalette::ButtonText)); + + int iH = itemHeight(); + int iC = itemCount(); + if (iC > 0) { + + m_itemOffset = m_itemOffset % iH; + + for (int i=-h/2/iH; i<=h/2/iH+1; i++) { + + int itemNum = m_currentItem + i; + while (itemNum < 0) + itemNum += iC; + while (itemNum >= iC) + itemNum -= iC; + + paintItem(&painter, itemNum, QRect(6, h/2 +i*iH - m_itemOffset - iH/2, w-6, iH )); + } + } + + // draw a transparent bar over the center + QColor highlight = palette.color(colorGroup, QPalette::Highlight); + highlight.setAlpha(150); + + QLinearGradient grad2(0.5, 0, 0.5, 1.0); + grad2.setColorAt(0, highlight); + grad2.setColorAt(1.0, highlight.lighter()); + grad2.setCoordinateMode( QGradient::ObjectBoundingMode ); + QBrush gBrush2( grad2 ); + + QLinearGradient grad3(0.5, 0, 0.5, 1.0); + grad3.setColorAt(0, highlight); + grad3.setColorAt(1.0, highlight.darker()); + grad3.setCoordinateMode( QGradient::ObjectBoundingMode ); + QBrush gBrush3( grad3 ); + + painter.fillRect( QRect( 0, h/2 - iH/2, w, iH/2 ), gBrush2 ); + painter.fillRect( QRect( 0, h/2, w, iH/2 ), gBrush3 ); +} + +/*! + Rotates the wheel widget to a given index. + You can also give an index greater than itemCount or less than zero in which + case the wheel widget will scroll in the given direction and end up with + (index % itemCount) +*/ +void AbstractWheelWidget::scrollTo(int index) +{ + QScroller *scroller = QScroller::scroller(this); + + scroller->scrollTo(QPointF(0, WHEEL_SCROLL_OFFSET + index * itemHeight()), 5000); +} + +/*! + \class StringWheelWidget + \brief The StringWheelWidget class is an implementation of the AbstractWheelWidget class that draws QStrings as items. + \sa AbstractWheelWidget +*/ + +StringWheelWidget::StringWheelWidget(bool touch) + : AbstractWheelWidget(touch) +{ } + +QStringList StringWheelWidget::items() const +{ + return m_items; +} + +void StringWheelWidget::setItems( const QStringList &items ) +{ + m_items = items; + if (m_currentItem >= items.count()) + m_currentItem = items.count()-1; + update(); +} + + +QSize StringWheelWidget::sizeHint() const +{ + // determine font size + QFontMetrics fm(font()); + + return QSize( fm.width("m") * 10 + 6, fm.height() * 7 + 6 ); +} + +QSize StringWheelWidget::minimumSizeHint() const +{ + QFontMetrics fm(font()); + + return QSize( fm.width("m") * 5 + 6, fm.height() * 3 + 6 ); +} + +void StringWheelWidget::paintItem(QPainter* painter, int index, const QRect &rect) +{ + painter->drawText(rect, Qt::AlignCenter, m_items.at(index)); +} + +int StringWheelWidget::itemHeight() const +{ + QFontMetrics fm(font()); + return fm.height(); +} + +int StringWheelWidget::itemCount() const +{ + return m_items.count(); +} + + diff --git a/examples/scroller/wheel/wheelwidget.h b/examples/scroller/wheel/wheelwidget.h new file mode 100644 index 0000000..818b6ab --- /dev/null +++ b/examples/scroller/wheel/wheelwidget.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef WHEELWIDGET_H +#define WHEELWIDGET_H + +#include +#include + +class QPainter; +class QRect; + +class AbstractWheelWidget : public QWidget { + Q_OBJECT + +public: + AbstractWheelWidget(bool touch, QWidget *parent = 0); + virtual ~AbstractWheelWidget(); + + int currentIndex() const; + void setCurrentIndex(int index); + + bool event(QEvent*); + void paintEvent(QPaintEvent *e); + virtual void paintItem(QPainter* painter, int index, const QRect &rect) = 0; + + virtual int itemHeight() const = 0; + virtual int itemCount() const = 0; + +public slots: + void scrollTo(int index); + +signals: + void stopped(int index); + +protected: + int m_currentItem; + int m_itemOffset; // 0-itemHeight() + qreal m_lastY; +}; + + +class StringWheelWidget : public AbstractWheelWidget { + Q_OBJECT + +public: + StringWheelWidget(bool touch); + + QStringList items() const; + void setItems( const QStringList &items ); + + QSize sizeHint() const; + QSize minimumSizeHint() const; + + void paintItem(QPainter* painter, int index, const QRect &rect); + + int itemHeight() const; + int itemCount() const; + +private: + QStringList m_items; +}; + +#endif // WHEELWIDGET_H diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index d23ea4c..4da5fa9 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -231,6 +231,8 @@ QT_BEGIN_NAMESPACE \value WinIdChange The window system identifer for this native widget has changed \value Gesture A gesture was triggered (QGestureEvent) \value GestureOverride A gesture override was triggered (QGestureEvent) + \value ScrollPrepare The object needs to fill in its geometry information (QScrollPrepareEvent) + \value Scroll The object needs to scroll to the supplied position (QScrollEvent) User events should have values between \c User and \c{MaxUser}: diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index 4c91aaf..08b751c 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -288,6 +288,9 @@ public: Gesture = 198, GestureOverride = 202, #endif + ScrollPrepare = 204, + Scroll = 205, + // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 8af6013..f2d8303 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -62,6 +62,9 @@ #include #endif #include +#ifndef QT_NO_GESTURE +# include +#endif QT_BEGIN_NAMESPACE @@ -191,6 +194,37 @@ void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index } } +// stores and restores the selection and current item when flicking +void QAbstractItemViewPrivate::_q_scrollerStateChanged() +{ + Q_Q(QAbstractItemView); + + if (QScroller *scroller = QScroller::scroller(viewport)) { + switch (scroller->state()) { + case QScroller::Pressed: + // store the current selection in case we start scrolling + if (q->selectionModel()) { + oldSelection = q->selectionModel()->selection(); + oldCurrent = q->selectionModel()->currentIndex(); + } + break; + + case QScroller::Dragging: + // restore the old selection if we really start scrolling + if (q->selectionModel()) { + q->selectionModel()->select(oldSelection, QItemSelectionModel::ClearAndSelect); + q->selectionModel()->setCurrentIndex(oldCurrent, QItemSelectionModel::NoUpdate); + } + // fall through + + default: + oldSelection = QItemSelection(); + oldCurrent = QModelIndex(); + break; + } + } +} + /*! \class QAbstractItemView @@ -1616,6 +1650,11 @@ bool QAbstractItemView::viewportEvent(QEvent *event) case QEvent::WindowDeactivate: d->viewport->update(); break; + case QEvent::ScrollPrepare: + executeDelayedItemsLayout(); + connect(QScroller::scroller(d->viewport), SIGNAL(stateChanged(QScroller::State)), this, SLOT(_q_scrollerStateChanged()), Qt::UniqueConnection); + break; + default: break; } diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h index 0f86f62..6f7db09 100644 --- a/src/gui/itemviews/qabstractitemview.h +++ b/src/gui/itemviews/qabstractitemview.h @@ -359,6 +359,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) Q_PRIVATE_SLOT(d_func(), void _q_headerDataChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_scrollerStateChanged()) friend class QTreeViewPrivate; // needed to compile with MSVC friend class QAccessibleItemRow; diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 03b413a..be20dce 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -114,6 +114,7 @@ public: virtual void _q_modelDestroyed(); virtual void _q_layoutChanged(); void _q_headerDataChanged() { doDelayedItemsLayout(); } + void _q_scrollerStateChanged(); void fetchMore(); @@ -414,6 +415,12 @@ public: QAbstractItemView::ScrollMode verticalScrollMode; QAbstractItemView::ScrollMode horizontalScrollMode; +#ifndef QT_NO_GESTURES + // the selection before the last mouse down. In case we have to restore it for scrolling + QItemSelection oldSelection; + QModelIndex oldCurrent; +#endif + bool currentIndexSet; bool wrapItemText; diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 5633cb8..422aeeb 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -4568,4 +4568,223 @@ const QGestureEventPrivate *QGestureEvent::d_func() const #endif // QT_NO_GESTURES +/*! + \class QScrollPrepareEvent + \since 4.8 + \ingroup events + + \brief The QScrollPrepareEvent class is send in preparation of a scrolling. + + The scroll prepare event is send before scrolling (usually by QScroller) is started. + The object receiving this event should set viewportSize, maxContentPos and contentPos. + It also should accept this event to indicate that scrolling should be started. + + It is not guaranteed that a QScrollEvent will be send after an acceepted + QScrollPrepareEvent, e.g. in a case where the maximum content position is (0,0). + + \sa QScrollEvent, QScroller +*/ + +/*! + Creates new QScrollPrepareEvent + The \a startPos is the position of a touch or mouse event that started the scrolling. +*/ +QScrollPrepareEvent::QScrollPrepareEvent(const QPointF &startPos) + : QEvent(QEvent::ScrollPrepare) +{ + d = reinterpret_cast(new QScrollPrepareEventPrivate()); + d_func()->startPos = startPos; +} + +/*! + Destroys QScrollEvent. +*/ +QScrollPrepareEvent::~QScrollPrepareEvent() +{ + delete reinterpret_cast(d); +} + +/*! + Returns the position of the touch or mouse event that started the scrolling. +*/ +QPointF QScrollPrepareEvent::startPos() const +{ + return d_func()->startPos; +} + +/*! + Returns size of the area that is to be scrolled as set by setViewportSize + + \sa setViewportSize() +*/ +QSizeF QScrollPrepareEvent::viewportSize() const +{ + return d_func()->viewportSize; +} + +/*! + Returns the range of coordinates for the content as set by setContentPosRange(). +*/ +QRectF QScrollPrepareEvent::contentPosRange() const +{ + return d_func()->contentPosRange; +} + +/*! + Returns the current position of the content as set by setContentPos. +*/ +QPointF QScrollPrepareEvent::contentPos() const +{ + return d_func()->contentPos; +} + + +/*! + Sets the size of the area that is to be scrolled to \a size. + + \sa viewportSize() +*/ +void QScrollPrepareEvent::setViewportSize(const QSizeF &size) +{ + d_func()->viewportSize = size; +} + +/*! + Sets the range of content coordinates to \a rect. + + \sa contentPosRange() +*/ +void QScrollPrepareEvent::setContentPosRange(const QRectF &rect) +{ + d_func()->contentPosRange = rect; +} + +/*! + Sets the current content position to \a pos. + + \sa contentPos() +*/ +void QScrollPrepareEvent::setContentPos(const QPointF &pos) +{ + d_func()->contentPos = pos; +} + + +/*! + \internal +*/ +QScrollPrepareEventPrivate *QScrollPrepareEvent::d_func() +{ + return reinterpret_cast(d); +} + +/*! + \internal +*/ +const QScrollPrepareEventPrivate *QScrollPrepareEvent::d_func() const +{ + return reinterpret_cast(d); +} + +/*! + \class QScrollEvent + \since 4.8 + \ingroup events + + \brief The QScrollEvent class is send when scrolling. + + The scroll event is send to indicate that the receiver should be scrolled. + Usually the receiver should be something visual like QWidget or QGraphicsObject. + + Some care should be taken that no conflicting QScrollEvents are sent from two + sources. Using QScroller::scrollTo is save however. + + \sa QScrollPrepareEvent, QScroller +*/ + +/*! + \enum QScrollEvent::ScrollState + + This enum describes the states a scroll event can have. + + \value ScrollStarted Set for the first scroll event of a scroll activity. + + \value ScrollUpdated Set for all but the first and the last scroll event of a scroll activity. + + \value ScrollFinished Set for the last scroll event of a scroll activity. + + \sa QScrollEvent::scrollState() +*/ + +/*! + Creates a new QScrollEvent + \a contentPos is the new content position, \a overshootDistance is the + new overshoot distance while \a scrollState indicates if this scroll + event is the first one, the last one or some event in between. +*/ +QScrollEvent::QScrollEvent(const QPointF &contentPos, const QPointF &overshootDistance, ScrollState scrollState) + : QEvent(QEvent::Scroll) +{ + d = reinterpret_cast(new QScrollEventPrivate()); + d_func()->contentPos = contentPos; + d_func()->overshoot= overshootDistance; + d_func()->state = scrollState; +} + +/*! + Destroys QScrollEvent. +*/ +QScrollEvent::~QScrollEvent() +{ + delete reinterpret_cast(d); +} + +/*! + Returns the new scroll position. +*/ +QPointF QScrollEvent::contentPos() const +{ + return d_func()->contentPos; +} + +/*! + Returns the new overshoot distance. + See QScroller for an explanation of the term overshoot. + + \sa QScroller +*/ +QPointF QScrollEvent::overshootDistance() const +{ + return d_func()->overshoot; +} + +/*! + Returns the current scroll state as a combination of ScrollStateFlag values. + ScrollStarted (or ScrollFinished) will be set, if this scroll event is the first (or last) event in a scrolling activity. + Please note that both values can be set at the same time, if the activity consists of a single QScrollEvent. + All other scroll events in between will have their state set to ScrollUpdated. + + A widget could for example revert selections when scrolling is started and stopped. +*/ +QScrollEvent::ScrollState QScrollEvent::scrollState() const +{ + return d_func()->state; +} + +/*! + \internal +*/ +QScrollEventPrivate *QScrollEvent::d_func() +{ + return reinterpret_cast(d); +} + +/*! + \internal +*/ +const QScrollEventPrivate *QScrollEvent::d_func() const +{ + return reinterpret_cast(d); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 9c70c02..6c0076d 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -880,6 +880,52 @@ private: }; #endif // QT_NO_GESTURES +class QScrollPrepareEventPrivate; +class Q_GUI_EXPORT QScrollPrepareEvent : public QEvent +{ +public: + QScrollPrepareEvent(const QPointF &startPos); + ~QScrollPrepareEvent(); + + QPointF startPos() const; + + QSizeF viewportSize() const; + QRectF contentPosRange() const; + QPointF contentPos() const; + + void setViewportSize(const QSizeF &size); + void setContentPosRange(const QRectF &rect); + void setContentPos(const QPointF &pos); + +private: + QScrollPrepareEventPrivate *d_func(); + const QScrollPrepareEventPrivate *d_func() const; +}; + + +class QScrollEventPrivate; +class Q_GUI_EXPORT QScrollEvent : public QEvent +{ +public: + enum ScrollState + { + ScrollStarted, + ScrollUpdated, + ScrollFinished + }; + + QScrollEvent(const QPointF &contentPos, const QPointF &overshoot, ScrollState scrollState); + ~QScrollEvent(); + + QPointF contentPos() const; + QPointF overshootDistance() const; + ScrollState scrollState() const; + +private: + QScrollEventPrivate *d_func(); + const QScrollEventPrivate *d_func() const; +}; + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index e323aa9..02f41e7 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -178,6 +178,34 @@ public: QUrl url; }; + +class QScrollPrepareEventPrivate +{ +public: + inline QScrollPrepareEventPrivate() + : target(0) + { + } + + QObject* target; + QPointF startPos; + QSizeF viewportSize; + QRectF contentPosRange; + QPointF contentPos; +}; + +class QScrollEventPrivate +{ +public: + inline QScrollEventPrivate() + { + } + + QPointF contentPos; + QPointF overshoot; + QScrollEvent::ScrollState state; +}; + QT_END_NAMESPACE #endif // QEVENT_P_H diff --git a/src/gui/util/qflickgesture.cpp b/src/gui/util/qflickgesture.cpp new file mode 100644 index 0000000..fa04754 --- /dev/null +++ b/src/gui/util/qflickgesture.cpp @@ -0,0 +1,677 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "qgesture.h" +#include "qcoreapplication.h" +#include "qevent.h" +#include "qwidget.h" +#include "qgraphicsitem.h" +#include "qgraphicsscene.h" +#include "qgraphicssceneevent.h" +#include "qgraphicsview.h" +#include "qscroller.h" +#include "private/qevent_p.h" +#include "private/qflickgesture_p.h" +#include "qdebug.h" + +#ifndef QT_NO_GESTURES + +QT_BEGIN_NAMESPACE + +//#define QFLICKGESTURE_DEBUG + +#ifdef QFLICKGESTURE_DEBUG +# define qFGDebug qDebug +#else +# define qFGDebug while (false) qDebug +#endif + +extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); + +static QMouseEvent *copyMouseEvent(QEvent *e) +{ + switch (e->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: { + QMouseEvent *me = static_cast(e); + return new QMouseEvent(me->type(), QPoint(0, 0), me->globalPos(), me->button(), me->buttons(), me->modifiers()); + } + case QEvent::GraphicsSceneMousePress: + case QEvent::GraphicsSceneMouseRelease: + case QEvent::GraphicsSceneMouseMove: { + QGraphicsSceneMouseEvent *me = static_cast(e); +#if 1 + QEvent::Type met = me->type() == QEvent::GraphicsSceneMousePress ? QEvent::MouseButtonPress : + (me->type() == QEvent::GraphicsSceneMouseRelease ? QEvent::MouseButtonRelease : QEvent::MouseMove); + return new QMouseEvent(met, QPoint(0, 0), me->screenPos(), me->button(), me->buttons(), me->modifiers()); +#else + QGraphicsSceneMouseEvent *copy = new QGraphicsSceneMouseEvent(me->type()); + copy->setPos(me->pos()); + copy->setScenePos(me->scenePos()); + copy->setScreenPos(me->screenPos()); + for (int i = 0x1; i <= 0x10; i <<= 1) { + Qt::MouseButton button = Qt::MouseButton(i); + copy->setButtonDownPos(button, me->buttonDownPos(button)); + copy->setButtonDownScenePos(button, me->buttonDownScenePos(button)); + copy->setButtonDownScreenPos(button, me->buttonDownScreenPos(button)); + } + copy->setLastPos(me->lastPos()); + copy->setLastScenePos(me->lastScenePos()); + copy->setLastScreenPos(me->lastScreenPos()); + copy->setButtons(me->buttons()); + copy->setButton(me->button()); + copy->setModifiers(me->modifiers()); + return copy; +#endif + } + default: + return 0; + } +} + +class PressDelayHandler : public QObject +{ +private: + PressDelayHandler(QObject *parent = 0) + : QObject(parent) + , pressDelayTimer(0) + , sendingEvent(false) + , mouseButton(Qt::NoButton) + , mouseTarget(0) + { } + + static PressDelayHandler *inst; + +public: + enum { + UngrabMouseBefore = 1, + RegrabMouseAfterwards = 2 + }; + + static PressDelayHandler *instance() + { + static PressDelayHandler *inst = 0; + if (!inst) + inst = new PressDelayHandler(QCoreApplication::instance()); + return inst; + } + + bool shouldEventBeIgnored(QEvent *) const + { + return sendingEvent; + } + + bool isDelaying() const + { + return !pressDelayEvent.isNull(); + } + + void pressed(QEvent *e, int delay) + { + if (!pressDelayEvent) { + pressDelayEvent.reset(copyMouseEvent(e)); + pressDelayTimer = startTimer(delay); + mouseTarget = QApplication::widgetAt(pressDelayEvent->globalPos()); + mouseButton = pressDelayEvent->button(); + qFGDebug() << "QFG: consuming/delaying mouse press"; + } else { + qFGDebug() << "QFG: NOT consuming/delaying mouse press"; + } + e->setAccepted(true); + } + + bool released(QEvent *e, bool scrollerWasActive, bool scrollerIsActive) + { + // consume this event if the scroller was or is active + bool result = scrollerWasActive || scrollerIsActive; + + // stop the timer + if (pressDelayTimer) { + killTimer(pressDelayTimer); + pressDelayTimer = 0; + } + // we still haven't even sent the press, so do it now + if (pressDelayEvent && mouseTarget && !scrollerIsActive) { + QScopedPointer releaseEvent(copyMouseEvent(e)); + + qFGDebug() << "QFG: re-sending mouse press (due to release) for " << mouseTarget; + sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore); + + qFGDebug() << "QFG: faking mouse release (due to release) for " << mouseTarget; + sendMouseEvent(releaseEvent.data()); + + result = true; // consume this event + } else if (mouseTarget && scrollerIsActive) { + // we grabbed the mouse expicitly when the scroller became active, so undo that now + sendMouseEvent(0, UngrabMouseBefore); + } + pressDelayEvent.reset(0); + mouseTarget = 0; + return result; + } + + void scrollerWasIntercepted() + { + qFGDebug() << "QFG: deleting delayed mouse press, since scroller was only intercepted"; + if (pressDelayEvent) { + // we still haven't even sent the press, so just throw it away now + if (pressDelayTimer) { + killTimer(pressDelayTimer); + pressDelayTimer = 0; + } + pressDelayEvent.reset(0); + } + mouseTarget = 0; + } + + void scrollerBecameActive() + { + if (pressDelayEvent) { + // we still haven't even sent the press, so just throw it away now + qFGDebug() << "QFG: deleting delayed mouse press, since scroller is active now"; + if (pressDelayTimer) { + killTimer(pressDelayTimer); + pressDelayTimer = 0; + } + pressDelayEvent.reset(0); + mouseTarget = 0; + } else if (mouseTarget) { + // we did send a press, so we need to fake a release now + Qt::MouseButtons mouseButtons = QApplication::mouseButtons(); + + // release all pressed mouse buttons + /*for (int i = 0; i < 32; ++i) { + if (mouseButtons & (1 << i)) { + Qt::MouseButton b = static_cast(1 << i); + mouseButtons &= ~b; + QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX); + + qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget; + QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway, + b, mouseButtons, QApplication::keyboardModifiers()); + sendMouseEvent(&re); + } + }*/ + + QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX); + + qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget; + QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway, + mouseButton, QApplication::mouseButtons() & ~mouseButton, + QApplication::keyboardModifiers()); + sendMouseEvent(&re, RegrabMouseAfterwards); + // don't clear the mouseTarget just yet, since we need to explicitly ungrab the mouse on release! + } + } + +protected: + void timerEvent(QTimerEvent *e) + { + if (e->timerId() == pressDelayTimer) { + if (pressDelayEvent && mouseTarget) { + qFGDebug() << "QFG: timer event: re-sending mouse press to " << mouseTarget; + sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore); + } + pressDelayEvent.reset(0); + + if (pressDelayTimer) { + killTimer(pressDelayTimer); + pressDelayTimer = 0; + } + } + } + + void sendMouseEvent(QMouseEvent *me, int flags = 0) + { + if (mouseTarget) { + sendingEvent = true; + + QGraphicsItem *grabber = 0; + if (mouseTarget->parentWidget()) { + if (QGraphicsView *gv = qobject_cast(mouseTarget->parentWidget())) { + if (gv->scene()) + grabber = gv->scene()->mouseGrabberItem(); + } + } + + if (grabber && (flags & UngrabMouseBefore)) { + // GraphicsView Mouse Handling Workaround #1: + // we need to ungrab the mouse before re-sending the press, + // since the scene had already set the mouse grabber to the + // original (and consumed) event's receiver + qFGDebug() << "QFG: ungrabbing" << grabber; + grabber->ungrabMouse(); + } + + if (me) { + QMouseEvent copy(me->type(), mouseTarget->mapFromGlobal(me->globalPos()), me->globalPos(), me->button(), me->buttons(), me->modifiers()); + qt_sendSpontaneousEvent(mouseTarget, ©); + } + + if (grabber && (flags & RegrabMouseAfterwards)) { + // GraphicsView Mouse Handling Workaround #2: + // we need to re-grab the mouse after sending a faked mouse + // release, since we still need the mouse moves for the gesture + // (the scene will clear the item's mouse grabber status on + // release). + qFGDebug() << "QFG: re-grabbing" << grabber; + grabber->grabMouse(); + } + sendingEvent = false; + } + } + + +private: + int pressDelayTimer; + QScopedPointer pressDelayEvent; + bool sendingEvent; + Qt::MouseButton mouseButton; + QPointer mouseTarget; +}; + + +/*! + \internal + \class QFlickGesture + \since 4.8 + \brief The QFlickGesture class describes a flicking gesture made by the user. + \ingroup gestures + The QFlickGesture is more complex than the QPanGesture that uses QScroller and QScrollerProperties + to decide if it is triggered. + This gesture is reacting on touch event as compared to the QMouseFlickGesture. + + \sa {Gestures Programming}, QScroller, QScrollerProperties, QMouseFlickGesture +*/ + +/*! + \internal +*/ +QFlickGesture::QFlickGesture(QObject *receiver, Qt::MouseButton button, QObject *parent) + : QGesture(*new QFlickGesturePrivate, parent) +{ + d_func()->q_ptr = this; + d_func()->receiver = receiver; + d_func()->receiverScroller = (receiver && QScroller::hasScroller(receiver)) ? QScroller::scroller(receiver) : 0; + d_func()->button = button; +} + +QFlickGesture::~QFlickGesture() +{ } + +QFlickGesturePrivate::QFlickGesturePrivate() + : receiverScroller(0), button(Qt::NoButton), macIgnoreWheel(false) +{ } + + +// +// QFlickGestureRecognizer +// + + +QFlickGestureRecognizer::QFlickGestureRecognizer(Qt::MouseButton button) +{ + this->button = button; +} + +/*! \reimp + */ +QGesture *QFlickGestureRecognizer::create(QObject *target) +{ + QGraphicsObject *go = qobject_cast(target); + if (go && button == Qt::NoButton) { + go->setAcceptTouchEvents(true); + } + return new QFlickGesture(target, button); +} + +/*! \internal + The recognize function detects a touch event suitable to start the attached QScroller. + The QFlickGesture will be triggered as soon as the scroller is no longer in the state + QScroller::Inactive or QScroller::Pressed. It will be finished or canceled + at the next QEvent::TouchEnd. + Note that the QScroller might continue scrolling (kinetically) at this point. + */ +QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state, + QObject *watched, + QEvent *event) +{ + Q_UNUSED(watched); + + static QElapsedTimer monotonicTimer; + if (!monotonicTimer.isValid()) + monotonicTimer.start(); + + QFlickGesture *q = static_cast(state); + QFlickGesturePrivate *d = q->d_func(); + + QScroller *scroller = d->receiverScroller; + if (!scroller) + return Ignore; // nothing to do without a scroller? + + QWidget *receiverWidget = qobject_cast(d->receiver); + QGraphicsObject *receiverGraphicsObject = qobject_cast(d->receiver); + + // this is only set for events that we inject into the event loop via sendEvent() + if (PressDelayHandler::instance()->shouldEventBeIgnored(event)) { + //qFGDebug() << state << "QFG: ignored event: " << event->type(); + return Ignore; + } + + const QMouseEvent *me = 0; + const QGraphicsSceneMouseEvent *gsme = 0; + const QTouchEvent *te = 0; + QPoint globalPos; + + // qFGDebug() << "FlickGesture "<receiver<<"event"<type()<<"button"<type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + if (!receiverWidget) + return Ignore; + if (button != Qt::NoButton) { + me = static_cast(event); + globalPos = me->globalPos(); + } + break; + case QEvent::GraphicsSceneMousePress: + case QEvent::GraphicsSceneMouseRelease: + case QEvent::GraphicsSceneMouseMove: + if (!receiverGraphicsObject) + return Ignore; + if (button != Qt::NoButton) { + gsme = static_cast(event); + globalPos = gsme->screenPos(); + } + break; + case QEvent::TouchBegin: + case QEvent::TouchEnd: + case QEvent::TouchUpdate: + if (button == Qt::NoButton) { + te = static_cast(event); + if (!te->touchPoints().isEmpty()) + globalPos = te->touchPoints().at(0).screenPos().toPoint(); + } + break; + +#if defined(Q_WS_MAC) + // the only way to distinguish between real mouse wheels and wheel + // events generated by the native 2 finger swipe gesture is to listen + // for these events (according to Apple's Cocoa Event-Handling Guide) + + case QEvent::NativeGesture: { + QNativeGestureEvent *nge = static_cast(event); + if (nge->gestureType == QNativeGestureEvent::GestureBegin) + d->macIgnoreWheel = true; + else if (nge->gestureType == QNativeGestureEvent::GestureEnd) + d->macIgnoreWheel = false; + break; + } +#endif + + // consume all wheel events if the scroller is active + case QEvent::Wheel: + if (d->macIgnoreWheel || (scroller->state() != QScroller::Inactive)) + return Ignore | ConsumeEventHint; + break; + + // consume all dbl click events if the scroller is active + case QEvent::MouseButtonDblClick: + if (scroller->state() != QScroller::Inactive) + return Ignore | ConsumeEventHint; + break; + + default: + break; + } + + if (!me && !gsme && !te) // Neither mouse nor touch + return Ignore; + + // get the current pointer position in local coordinates. + QPointF point; + QScroller::Input inputType = (QScroller::Input) 0; + + switch (event->type()) { + case QEvent::MouseButtonPress: + if (me && me->button() == button && me->buttons() == button) { + point = me->globalPos(); + inputType = QScroller::InputPress; + } else if (me) { + scroller->stop(); + return CancelGesture; + } + break; + case QEvent::MouseButtonRelease: + if (me && me->button() == button) { + point = me->globalPos(); + inputType = QScroller::InputRelease; + } + break; + case QEvent::MouseMove: +#ifdef Q_OS_SYMBIAN + // Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix + // relies on the windowing system to report the current buttons state. + if (me && (me->buttons() == button || !me->buttons())) { +#else + if (me && me->buttons() == button) { +#endif + point = me->globalPos(); + inputType = QScroller::InputMove; + } + break; + + case QEvent::GraphicsSceneMousePress: + if (gsme && gsme->button() == button && gsme->buttons() == button) { + point = gsme->scenePos(); + inputType = QScroller::InputPress; + } else if (gsme) { + scroller->stop(); + return CancelGesture; + } + break; + case QEvent::GraphicsSceneMouseRelease: + if (gsme && gsme->button() == button) { + point = gsme->scenePos(); + inputType = QScroller::InputRelease; + } + break; + case QEvent::GraphicsSceneMouseMove: +#ifdef Q_OS_SYMBIAN + // Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix + // relies on the windowing system to report the current buttons state. + if (gsme && (gsme->buttons() == button || !me->buttons())) { +#else + if (gsme && gsme->buttons() == button) { +#endif + point = gsme->scenePos(); + inputType = QScroller::InputMove; + } + break; + + case QEvent::TouchBegin: + inputType = QScroller::InputPress; + // fall through + case QEvent::TouchEnd: + if (!inputType) + inputType = QScroller::InputRelease; + // fallthrough + case QEvent::TouchUpdate: + if (!inputType) + inputType = QScroller::InputMove; + + if (te->deviceType() == QTouchEvent::TouchPad) { + if (te->touchPoints().count() != 2) // 2 fingers on pad + return Ignore; + + point = te->touchPoints().at(0).startScenePos() + + ((te->touchPoints().at(0).scenePos() - te->touchPoints().at(0).startScenePos()) + + (te->touchPoints().at(1).scenePos() - te->touchPoints().at(1).startScenePos())) / 2; + } else { // TouchScreen + if (te->touchPoints().count() != 1) // 1 finger on screen + return Ignore; + + point = te->touchPoints().at(0).scenePos(); + } + break; + + default: + break; + } + + // Check for an active scroller at globalPos + if (inputType == QScroller::InputPress) { + foreach (QScroller *as, QScroller::activeScrollers()) { + if (as != scroller) { + QRegion scrollerRegion; + + if (QWidget *w = qobject_cast(as->target())) { + scrollerRegion = QRect(w->mapToGlobal(QPoint(0, 0)), w->size()); + } else if (QGraphicsObject *go = qobject_cast(as->target())) { + if (go->scene() && !go->scene()->views().isEmpty()) { + foreach (QGraphicsView *gv, go->scene()->views()) + scrollerRegion |= gv->mapFromScene(go->mapToScene(go->boundingRect())) + .translated(gv->mapToGlobal(QPoint(0, 0))); + } + } + // active scrollers always have priority + if (scrollerRegion.contains(globalPos)) + return Ignore; + } + } + } + + bool scrollerWasDragging = (scroller->state() == QScroller::Dragging); + bool scrollerWasScrolling = (scroller->state() == QScroller::Scrolling); + + if (inputType) { + if (QWidget *w = qobject_cast(d->receiver)) + point = w->mapFromGlobal(point.toPoint()); + else if (QGraphicsObject *go = qobject_cast(d->receiver)) + point = go->mapFromScene(point); + + // inform the scroller about the new event + scroller->handleInput(inputType, point, monotonicTimer.elapsed()); + } + + // depending on the scroller state return the gesture state + Result result(0); + bool scrollerIsActive = (scroller->state() == QScroller::Dragging || + scroller->state() == QScroller::Scrolling); + + // Consume all mouse events while dragging or scrolling to avoid nasty + // side effects with Qt's standard widgets. + if ((me || gsme) && scrollerIsActive) + result |= ConsumeEventHint; + + // The only problem with this approach is that we consume the + // MouseRelease when we start the scrolling with a flick gesture, so we + // have to fake a MouseRelease "somewhere" to not mess with the internal + // states of Qt's widgets (a QPushButton would stay in 'pressed' state + // forever, if it doesn't receive a MouseRelease). + if (me || gsme) { + if (!scrollerWasDragging && !scrollerWasScrolling && scrollerIsActive) + PressDelayHandler::instance()->scrollerBecameActive(); + else if (scrollerWasScrolling && (scroller->state() == QScroller::Dragging || scroller->state() == QScroller::Inactive)) + PressDelayHandler::instance()->scrollerWasIntercepted(); + } + + if (!inputType) { + result |= Ignore; + } else { + switch (event->type()) { + case QEvent::MouseButtonPress: + case QEvent::GraphicsSceneMousePress: + if (scroller->state() == QScroller::Pressed) { + int pressDelay = int(1000 * scroller->scrollerProperties().scrollMetric(QScrollerProperties::MousePressEventDelay).toReal()); + if (pressDelay > 0) { + result |= ConsumeEventHint; + + PressDelayHandler::instance()->pressed(event, pressDelay); + event->accept(); + } + } + // fall through + case QEvent::TouchBegin: + q->setHotSpot(globalPos); + result |= scrollerIsActive ? TriggerGesture : MayBeGesture; + break; + + case QEvent::MouseMove: + case QEvent::GraphicsSceneMouseMove: + if (PressDelayHandler::instance()->isDelaying()) + result |= ConsumeEventHint; + // fall through + case QEvent::TouchUpdate: + result |= scrollerIsActive ? TriggerGesture : Ignore; + break; + + case QEvent::GraphicsSceneMouseRelease: + case QEvent::MouseButtonRelease: + if (PressDelayHandler::instance()->released(event, scrollerWasDragging || scrollerWasScrolling, scrollerIsActive)) + result |= ConsumeEventHint; + // fall through + case QEvent::TouchEnd: + result |= scrollerIsActive ? FinishGesture : CancelGesture; + break; + + default: + result |= Ignore; + break; + } + } + return result; +} + + +/*! \reimp + */ +void QFlickGestureRecognizer::reset(QGesture *state) +{ + QGestureRecognizer::reset(state); +} + +QT_END_NAMESPACE + +#endif // QT_NO_GESTURES diff --git a/src/gui/util/qflickgesture_p.h b/src/gui/util/qflickgesture_p.h new file mode 100644 index 0000000..c3c263b --- /dev/null +++ b/src/gui/util/qflickgesture_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef QFLICKGESTURE_P_H +#define QFLICKGESTURE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qevent.h" +#include "qgesturerecognizer.h" +#include "private/qgesture_p.h" +#include "qscroller.h" +#include "qscopedpointer.h" + +#ifndef QT_NO_GESTURES + +QT_BEGIN_NAMESPACE + +class QFlickGesturePrivate; +class QGraphicsItem; + +class Q_GUI_EXPORT QFlickGesture : public QGesture +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QFlickGesture) + +public: + QFlickGesture(QObject *receiver, Qt::MouseButton button, QObject *parent = 0); + ~QFlickGesture(); + + friend class QFlickGestureRecognizer; +}; + +class PressDelayHandler; + +class QFlickGesturePrivate : public QGesturePrivate +{ + Q_DECLARE_PUBLIC(QFlickGesture) +public: + QFlickGesturePrivate(); + + QPointer receiver; + QScroller *receiverScroller; + Qt::MouseButton button; // NoButton == Touch + bool macIgnoreWheel; + static PressDelayHandler *pressDelayHandler; +}; + +class QFlickGestureRecognizer : public QGestureRecognizer +{ +public: + QFlickGestureRecognizer(Qt::MouseButton button); + + QGesture *create(QObject *target); + QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event); + void reset(QGesture *state); + +private: + Qt::MouseButton button; // NoButton == Touch +}; + +QT_END_NAMESPACE + +#endif // QT_NO_GESTURES + +#endif // QFLICKGESTURE_P_H diff --git a/src/gui/util/qscroller.cpp b/src/gui/util/qscroller.cpp new file mode 100644 index 0000000..d6b7aaf --- /dev/null +++ b/src/gui/util/qscroller.cpp @@ -0,0 +1,1984 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "qevent.h" +#include "qwidget.h" +#include "qscroller.h" +#include "private/qflickgesture_p.h" +#include "private/qscroller_p.h" +#include "qscrollerproperties.h" +#include "private/qscrollerproperties_p.h" +#include "qnumeric.h" +#include "math.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +QT_BEGIN_NAMESPACE + +bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); + +//#define QSCROLLER_DEBUG + +#ifdef QSCROLLER_DEBUG +# define qScrollerDebug qDebug +#else +# define qScrollerDebug while (false) qDebug +#endif + +QDebug &operator<<(QDebug &dbg, const QScrollerPrivate::ScrollSegment &s) +{ + dbg << "\n Time: start:" << s.startTime << " duration:" << s.deltaTime; + dbg << "\n Pos: start:" << s.startPos << " delta:" << s.deltaPos; + dbg << "\n Curve: type:" << s.curve.type() << " max progress:" << s.maxProgress << "\n"; + return dbg; +} + + +// a few helper operators to make the code below a lot more readable: +// otherwise a lot of ifs would have to be multi-line to check both the x +// and y coordinate separately. + +// returns true only if the abs. value of BOTH x and y are <= f +inline bool operator<=(const QPointF &p, qreal f) +{ + return (qAbs(p.x()) <= f) && (qAbs(p.y()) <= f); +} + +// returns true only if the abs. value of BOTH x and y are < f +inline bool operator<(const QPointF &p, qreal f) +{ + return (qAbs(p.x()) < f) && (qAbs(p.y()) < f); +} + +// returns true if the abs. value of EITHER x or y are >= f +inline bool operator>=(const QPointF &p, qreal f) +{ + return (qAbs(p.x()) >= f) || (qAbs(p.y()) >= f); +} + +// returns true if the abs. value of EITHER x or y are > f +inline bool operator>(const QPointF &p, qreal f) +{ + return (qAbs(p.x()) > f) || (qAbs(p.y()) > f); +} + +// returns a new point with both coordinates having the abs. value of the original one +inline QPointF qAbs(const QPointF &p) +{ + return QPointF(qAbs(p.x()), qAbs(p.y())); +} + +// returns a new point with all components of p1 multiplied by the corresponding components of p2 +inline QPointF operator*(const QPointF &p1, const QPointF &p2) +{ + return QPointF(p1.x() * p2.x(), p1.y() * p2.y()); +} + +// returns a new point with all components of p1 divided by the corresponding components of p2 +inline QPointF operator/(const QPointF &p1, const QPointF &p2) +{ + return QPointF(p1.x() / p2.x(), p1.y() / p2.y()); +} + +inline QPointF clampToRect(const QPointF &p, const QRectF &rect) +{ + qreal x = qBound(rect.left(), p.x(), rect.right()); + qreal y = qBound(rect.top(), p.y(), rect.bottom()); + return QPointF(x, y); +} + +// returns -1, 0 or +1 according to r being <0, ==0 or >0 +inline int qSign(qreal r) +{ + return (r < 0) ? -1 : ((r > 0) ? 1 : 0); +} + +// this version is not mathematically exact, but it just works for every +// easing curve type (even custom ones) + +static qreal differentialForProgress(const QEasingCurve &curve, qreal pos) +{ + const qreal dx = 0.01; + qreal left = (pos < qreal(0.5)) ? pos : pos - qreal(dx); + qreal right = (pos >= qreal(0.5)) ? pos : pos + qreal(dx); + qreal d = (curve.valueForProgress(right) - curve.valueForProgress(left)) / qreal(dx); + + //qScrollerDebug() << "differentialForProgress(type: " << curve.type() << ", pos: " << pos << ") = " << d; + + return d; +} + +// this version is not mathematically exact, but it just works for every +// easing curve type (even custom ones) + +static qreal progressForValue(const QEasingCurve &curve, qreal value) +{ + if (curve.type() >= QEasingCurve::InElastic && + curve.type() < QEasingCurve::Custom) { + qWarning("progressForValue(): QEasingCurves of type %d do not have an inverse, since they are not injective.", curve.type()); + return value; + } + if (value < qreal(0) || value > qreal(1)) + return value; + + qreal progress = value, left(0), right(1); + for (int iterations = 6; iterations; --iterations) { + qreal v = curve.valueForProgress(progress); + if (v < value) + left = progress; + else if (v > value) + right = progress; + else + break; + progress = (left + right) / qreal(2); + } + return progress; +} + + +class QScrollTimer : public QAbstractAnimation +{ +public: + QScrollTimer(QScrollerPrivate *_d) + : d(_d), ignoreUpdate(false), skip(0) + { } + + int duration() const + { + return -1; + } + + void start() + { + // QAbstractAnimation::start() will immediately call + // updateCurrentTime(), but our state is not set correctly yet + ignoreUpdate = true; + QAbstractAnimation::start(); + ignoreUpdate = false; + skip = 0; + } + +protected: + void updateCurrentTime(int /*currentTime*/) + { + if (!ignoreUpdate) { + if (++skip >= d->frameRateSkip()) { + skip = 0; + d->timerTick(); + } + } + } + +private: + QScrollerPrivate *d; + bool ignoreUpdate; + int skip; +}; + +/*! + \class QScroller + \brief The QScroller class enables kinetic scrolling for any scrolling widget or graphics item. + \since 4.8 + + With kinetic scrolling, the user can push the widget in a given + direction and it will continue to scroll in this direction until it is + stopped either by the user or by friction. Aspects of inertia, friction + and other physical concepts can be changed in order to fine-tune an + intuitive user experience. + + The QScroller object is the object that stores the current position and + speed of the scrolling and takes care of updates. + QScroller can be triggered by a flick gesture + + \code + QWidget *w = ...; + QScroller::grabGesture(w, QScroller::LeftMouseButtonGesture); + \endcode + + or directly like this: + + \code + QWidget *w = ...; + QScroller *scroller = QScroller::scroller(w); + scroller->scrollTo(QPointF(100, 100)); + \endcode + + The scrolled QObjects will be receive a QScrollPrepareEvent whenever the scroller needs to + update its geometry information and a QScrollEvent whenever the content of the object should + actually be scrolled. + + The scroller uses the global QAbstractAnimation timer to generate its QScrollEvents, but this + can be slowed down with QScrollerProperties::FrameRate on a per-QScroller basis. + + Several examples in the \c scroller examples directory show how QScroller, + QScrollEvent and the scroller gesture can be used. + + Even though this kinetic scroller has a huge number of settings available via + QScrollerProperties, we recommend that you leave them all at their default, platform optimized + values. In case you really want to change them you can experiment with the \c plot example in + the \c scroller examples directory first. + + \sa QScrollEvent, QScrollPrepareEvent, QScrollerProperties +*/ + + +QMap QScrollerPrivate::allScrollers; +QSet QScrollerPrivate::activeScrollers; + +/*! + Returns \c true if a QScroller object was already created for \a target; \c false otherwise. + + \sa scroller() +*/ +bool QScroller::hasScroller(QObject *target) +{ + return (QScrollerPrivate::allScrollers.value(target)); +} + +/*! + Returns the scroller for the given \a target. + As long as the object exist this function will always return the same QScroller. + If a QScroller does not exist yet for the \a target, it will implicitly be created. + At no point will two QScrollers be active on one object. + + \sa hasScroller(), target() +*/ +QScroller *QScroller::scroller(QObject *target) +{ + if (!target) { + qWarning("QScroller::scroller() was called with a null target."); + return 0; + } + + if (QScrollerPrivate::allScrollers.contains(target)) + return QScrollerPrivate::allScrollers.value(target); + + QScroller *s = new QScroller(target); + QScrollerPrivate::allScrollers.insert(target, s); + return s; +} + +/*! + \overload + This is the const version of scroller(). +*/ +const QScroller *QScroller::scroller(const QObject *target) +{ + return scroller(const_cast(target)); +} + +/*! + Returns an application wide list of currently active, i.e. state() != + QScroller::Inactive, QScroller objects. + This routine is mostly useful when writing your own gesture recognizer. +*/ +QList QScroller::activeScrollers() +{ + return QScrollerPrivate::activeScrollers.toList(); +} + +/*! + Returns the target object of this scroller. + \sa hasScroller(), scroller() + */ +QObject *QScroller::target() const +{ + Q_D(const QScroller); + return d->target; +} + +/*! + \fn QScroller::scrollerPropertiesChanged(const QScrollerProperties &newProperties); + + QScroller emits this signal whenever its scroller properties have been + changed. \a newProperties are the new scroller properties. + + \sa scrollerProperties +*/ + + +/*! \property QScroller::scrollerProperties + \brief The scroller properties of this scroller. + The properties will be used by the QScroller to determine its scrolling behaviour. +*/ +QScrollerProperties QScroller::scrollerProperties() const +{ + Q_D(const QScroller); + return d->properties; +} + +void QScroller::setScrollerProperties(const QScrollerProperties &sp) +{ + Q_D(QScroller); + if (d->properties != sp) { + d->properties = sp; + emit scrollerPropertiesChanged(sp); + + // we need to force the recalculation here, since the overshootPolicy may have changed and + // exisiting segments may include an overshoot animation. + d->recalcScrollingSegments(true); + } +} + + +/*! + Registers a custom scroll gesture recognizer and grabs it for the \a + target and returns the resulting gesture type. If \a scrollGestureType is + set to TouchGesture the gesture will trigger on touch events - if set to + one of LeftMouseButtonGesture, RightMouseButtonGesture or + MiddleMouseButtonGesture it will trigger on mouse events of the + corresponding button. + + Only one scroll gesture can be active on a single object at the same + time, so if you call this function twice on the same object, it will + ungrab the existing gesture before grabbing the new one. + + Please note: To avoid nasty side-effects, all mouse events will be + consumed while the gesture is triggered. Since the mouse press event is + not consumed, the gesture needs to also send a fake mouse release event + at the global position \c{(INT_MIN, INT_MIN)} to make sure that it + doesn't mess with the internal states of the widget that received the + mouse press in the first place (which could e.g. be a QPushButton + inside a QScrollArea). +*/ +Qt::GestureType QScroller::grabGesture(QObject *target, ScrollerGestureType scrollGestureType) +{ + // ensure that a scroller for target is created + QScroller *s = scroller(target); + if (!s) + return Qt::GestureType(0); + + QScrollerPrivate *sp = s->d_ptr; + if (sp->recognizer) + ungrabGesture(target); // ungrab the old gesture + + Qt::MouseButton button; + switch (scrollGestureType) { + case LeftMouseButtonGesture : button = Qt::LeftButton; break; + case RightMouseButtonGesture : button = Qt::RightButton; break; + case MiddleMouseButtonGesture: button = Qt::MiddleButton; break; + default : + case TouchGesture : button = Qt::NoButton; break; // NoButton == Touch + } + + sp->recognizer = new QFlickGestureRecognizer(button); + sp->recognizerType = QGestureRecognizer::registerRecognizer(sp->recognizer); + + if (target->isWidgetType()) { + QWidget *widget = static_cast(target); + widget->grabGesture(sp->recognizerType); + if (scrollGestureType == TouchGesture) + widget->setAttribute(Qt::WA_AcceptTouchEvents); + + } else if(QGraphicsObject *go = qobject_cast(target)) { + if (scrollGestureType == TouchGesture) + go->setAcceptTouchEvents(true); + go->grabGesture(sp->recognizerType); + } + return sp->recognizerType; +} + +/*! + Returns the gesture type currently grabbed for the \a target or 0 if no + gesture is grabbed. +*/ +Qt::GestureType QScroller::grabbedGesture(QObject *target) +{ + QScroller *s = scroller(target); + if (s && s->d_ptr) + return s->d_ptr->recognizerType; + else + return Qt::GestureType(0); +} + +/*! + Ungrabs the gesture for the \a target. +*/ +void QScroller::ungrabGesture(QObject *target) +{ + QScroller *s = scroller(target); + if (!s) + return; + + QScrollerPrivate *sp = s->d_ptr; + if (!sp->recognizer) + return; // nothing to do + + if (target->isWidgetType()) { + QWidget *widget = static_cast(target); + widget->ungrabGesture(sp->recognizerType); + + } else if(QGraphicsObject *go = qobject_cast(target)) { + go->ungrabGesture(sp->recognizerType); + } + + QGestureRecognizer::unregisterRecognizer(sp->recognizerType); + // do not delete the recognizer. The QGestureManager is doing this. + sp->recognizer = 0; +} + +/*! + \internal +*/ +QScroller::QScroller(QObject *target) + : d_ptr(new QScrollerPrivate(this, target)) +{ + Q_ASSERT(target); // you can't create a scroller without a target in any normal way + Q_D(QScroller); + d->init(); +} + +/*! + \internal +*/ +QScroller::~QScroller() +{ + Q_D(QScroller); + QGestureRecognizer::unregisterRecognizer(d->recognizerType); + // do not delete the recognizer. The QGestureManager is doing this. + d->recognizer = 0; + QScrollerPrivate::allScrollers.remove(d->target); + QScrollerPrivate::activeScrollers.remove(this); + + delete d_ptr; +} + + +/*! + \fn QScroller::stateChanged(QScroller::State newState); + + QScroller emits this signal whenever the state changes. \a newState is the new State. + + \sa state +*/ + +/*! + \property QScroller::state + \brief the state of the scroller + + \sa QScroller::State +*/ +QScroller::State QScroller::state() const +{ + Q_D(const QScroller); + return d->state; +} + +/*! + Stops the scroller and resets the state back to Inactive. +*/ +void QScroller::stop() +{ + Q_D(QScroller); + if (d->state != Inactive) { + QPointF here = clampToRect(d->contentPosition, d->contentPosRange); + qreal snapX = d->nextSnapPos(here.x(), 0, Qt::Horizontal); + qreal snapY = d->nextSnapPos(here.y(), 0, Qt::Vertical); + QPointF snap = here; + if (!qIsNaN(snapX)) + snap.setX(snapX); + if (!qIsNaN(snapY)) + snap.setY(snapY); + d->contentPosition = snap; + d->overshootPosition = QPointF(0, 0); + + d->setState(Inactive); + } +} + +/*! + \brief Returns the pixel per meter metric for the scrolled widget. + + The value is reported for both the x and y axis separately by using a QPointF. + + \note Please note that this value should be physically correct, while the actual DPI settings + that Qt returns for the display may be reported wrongly (on purpose) by the underlying + windowing system (e.g. Mac OS X or Maemo 5). +*/ +QPointF QScroller::pixelPerMeter() const +{ + Q_D(const QScroller); + QPointF ppm = d->pixelPerMeter; + + if (QGraphicsObject *go = qobject_cast(d->target)) { + QTransform viewtr; + //TODO: the first view isn't really correct - maybe use an additional field in the prepare event? + if (go->scene() && !go->scene()->views().isEmpty()) + viewtr = go->scene()->views().first()->viewportTransform(); + QTransform tr = go->deviceTransform(viewtr); + if (tr.isScaling()) { + QPointF p0 = tr.map(QPointF(0, 0)); + QPointF px = tr.map(QPointF(1, 0)); + QPointF py = tr.map(QPointF(0, 1)); + ppm.rx() /= QLineF(p0, px).length(); + ppm.ry() /= QLineF(p0, py).length(); + } + } + return ppm; +} + +/*! + \brief Returns the current velocity of the scroller. + + Returns the current scrolling velocity in meter per second when in the state Scrolling. + Returns a null velocity otherwise. + + The velocity is reported for both the x and y axis separately by using a QPointF. + + \sa pixelPerMeter() +*/ +QPointF QScroller::velocity() const +{ + Q_D(const QScroller); + const QScrollerPropertiesPrivate *sp = d->properties.d.data(); + + switch (state()) { + case Dragging: + return d->releaseVelocity; + case Scrolling: { + QPointF vel; + qint64 now = d->monotonicTimer.elapsed(); + + if (!d->xSegments.isEmpty()) { + const QScrollerPrivate::ScrollSegment &s = d->xSegments.head(); + qreal progress = qreal(now - s.startTime) / (qreal(s.deltaTime) / s.maxProgress); + qreal v = qSign(s.deltaPos) * qreal(s.deltaTime) / s.maxProgress / qreal(1000) * sp->decelerationFactor * qreal(0.5) * differentialForProgress(s.curve, progress); + vel.setX(v); + } + + if (!d->ySegments.isEmpty()) { + const QScrollerPrivate::ScrollSegment &s = d->ySegments.head(); + qreal progress = qreal(now - s.startTime) / (qreal(s.deltaTime) / s.maxProgress); + qreal v = qSign(s.deltaPos) * qreal(s.deltaTime) / s.maxProgress / qreal(1000) * sp->decelerationFactor * qreal(0.5) * differentialForProgress(s.curve, progress); + vel.setY(v); + } + //qScrollerDebug() << "Velocity: " << vel; + return vel; + } + default: + return QPointF(0, 0); + } +} + +/*! + \brief Returns the target position for the scroll movement. + + Returns the planned final position for the current scroll movement or the current + position if the scroller is not in the scrolling state. + The result is undefined when the scroller is in the inactive state. + + The target position is in pixel. + + \sa pixelPerMeter(), scrollTo() +*/ +QPointF QScroller::finalPosition() const +{ + Q_D(const QScroller); + return QPointF(d->scrollingSegmentsEndPos(Qt::Horizontal), + d->scrollingSegmentsEndPos(Qt::Vertical)); +} + +/*! + Starts scrolling the widget so that point \a pos is at the top-left position in + the viewport. + + The behaviour when scrolling outside the valid scroll area is undefined. + In this case the scroller might or might not overshoot. + + The scrolling speed will be calculated so that the given position will + be reached after a platform-defined time span (e.g. 1 second for Maemo 5). + + \a pos is given in viewport coordinates. + + \sa ensureVisible() +*/ +void QScroller::scrollTo(const QPointF &pos) +{ + // we could make this adjustable via QScrollerProperties + scrollTo(pos, 300); +} + +/*! \overload + + This version will reach its destination position in \a scrollTime milli seconds. +*/ +void QScroller::scrollTo(const QPointF &pos, int scrollTime) +{ + Q_D(QScroller); + + if (d->state == Pressed || d->state == Dragging ) + return; + + // no need to resend a prepare event if we are already scrolling + if (d->state == Inactive && !d->prepareScrolling(QPointF())) + return; + + QPointF newpos = clampToRect(pos, d->contentPosRange); + qreal snapX = d->nextSnapPos(newpos.x(), 0, Qt::Horizontal); + qreal snapY = d->nextSnapPos(newpos.y(), 0, Qt::Vertical); + if (!qIsNaN(snapX)) + newpos.setX(snapX); + if (!qIsNaN(snapY)) + newpos.setY(snapY); + + qScrollerDebug() << "QScroller::scrollTo(req:" << pos << " [pix] / snap:" << newpos << ", " << scrollTime << " [ms])"; + + if (newpos == d->contentPosition + d->overshootPosition) + return; + + QPointF vel = velocity(); + + if (scrollTime < 0) + scrollTime = 0; + qreal time = qreal(scrollTime) / 1000; + + d->createScrollToSegments(vel.x(), time, newpos.x(), Qt::Horizontal, QScrollerPrivate::ScrollTypeScrollTo); + d->createScrollToSegments(vel.y(), time, newpos.y(), Qt::Vertical, QScrollerPrivate::ScrollTypeScrollTo); + + if (!scrollTime) + d->setContentPositionHelperScrolling(); + d->setState(scrollTime ? Scrolling : Inactive); +} + +/*! + Starts scrolling so that the rectangle \a rect is visible inside the + viewport with additional margins specified in pixels by \a xmargin and \a ymargin around + the rect. + + In cases where it is not possible to fit the rect plus margins inside the viewport the contents + are scrolled so that as much as possible is visible from \a rect. + + The scrolling speed will be calculated so that the given position will + be reached after a platform-defined time span (e.g. 1 second for Maemo 5). + + This function performs the actual scrolling by calling scrollTo(). +*/ +void QScroller::ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin) +{ + // we could make this adjustable via QScrollerProperties + ensureVisible(rect, xmargin, ymargin, 1000); +} + +/*! \overload + + This version will reach its destination position in \a scrollTime milli seconds. +*/ +void QScroller::ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin, int scrollTime) +{ + Q_D(QScroller); + + if (d->state == Pressed || d->state == Dragging ) + return; + + if (d->state == Inactive && !d->prepareScrolling(QPointF())) + return; + + // -- calculate the current pos (or the position after the current scroll) + QPointF startPos = d->contentPosition + d->overshootPosition; + startPos = QPointF(d->scrollingSegmentsEndPos(Qt::Horizontal), + d->scrollingSegmentsEndPos(Qt::Vertical)); + + QRectF marginRect(rect.x() - xmargin, rect.y() - ymargin, + rect.width() + 2 * xmargin, rect.height() + 2 * ymargin); + + QSizeF visible = d->viewportSize; + QRectF visibleRect(startPos, visible); + + qScrollerDebug() << "QScroller::ensureVisible(" << rect << " [pix], " << xmargin << " [pix], " << ymargin << " [pix], " << scrollTime << "[ms])"; + qScrollerDebug() << " --> content position:" << d->contentPosition; + + if (visibleRect.contains(marginRect)) + return; + + QPointF newPos = startPos; + + if (visibleRect.width() < rect.width()) { + // at least try to move the rect into view + if (rect.left() > visibleRect.left()) + newPos.setX(rect.left()); + else if (rect.right() < visibleRect.right()) + newPos.setX(rect.right() - visible.width()); + + } else if (visibleRect.width() < marginRect.width()) { + newPos.setX(rect.center().x() - visibleRect.width() / 2); + } else if (marginRect.left() > visibleRect.left()) { + newPos.setX(marginRect.left()); + } else if (marginRect.right() < visibleRect.right()) { + newPos.setX(marginRect.right() - visible.width()); + } + + if (visibleRect.height() < rect.height()) { + // at least try to move the rect into view + if (rect.top() > visibleRect.top()) + newPos.setX(rect.top()); + else if (rect.bottom() < visibleRect.bottom()) + newPos.setX(rect.bottom() - visible.height()); + + } else if (visibleRect.height() < marginRect.height()) { + newPos.setY(rect.center().y() - visibleRect.height() / 2); + } else if (marginRect.top() > visibleRect.top()) { + newPos.setY(marginRect.top()); + } else if (marginRect.bottom() < visibleRect.bottom()) { + newPos.setY(marginRect.bottom() - visible.height()); + } + + // clamp to maximum content position + newPos = clampToRect(newPos, d->contentPosRange); + if (newPos == startPos) + return; + + scrollTo(newPos, scrollTime); +} + +/*! This function resends the QScrollPrepareEvent. + * Calling resendPrepareEvent triggers a QScrollPrepareEvent from the scroller. + * This will allow the receiver to re-set content position and content size while + * scrolling. + * Calling this function while in the Inactive state is useless as the prepare event + * is send again right before scrolling starts. + */ +void QScroller::resendPrepareEvent() +{ + Q_D(QScroller); + d->prepareScrolling(d->pressPosition); +} + +/*! Set the snap positions for the horizontal axis. + * Set the snap positions to a list of \a positions. + * This will overwrite all previously set snap positions and also a previously + * set snapping interval. + * Snapping can be deactivated by setting an empty list of positions. + */ +void QScroller::setSnapPositionsX(const QList &positions) +{ + Q_D(QScroller); + d->snapPositionsX = positions; + d->snapIntervalX = 0.0; + + d->recalcScrollingSegments(); +} + +/*! Set the snap positions for the horizontal axis. + * Set the snap positions to regular spaced intervals. + * The first snap position will be at \a first from the beginning of the list. The next at \a first + \a interval and so on. + * This can be used to implement a list header. + * This will overwrite all previously set snap positions and also a previously + * set snapping interval. + * Snapping can be deactivated by setting an interval of 0.0 + */ +void QScroller::setSnapPositionsX(qreal first, qreal interval) +{ + Q_D(QScroller); + d->snapFirstX = first; + d->snapIntervalX = interval; + d->snapPositionsX.clear(); + + d->recalcScrollingSegments(); +} + +/*! Set the snap positions for the vertical axis. + * Set the snap positions to a list of \a positions. + * This will overwrite all previously set snap positions and also a previously + * set snapping interval. + * Snapping can be deactivated by setting an empty list of positions. + */ +void QScroller::setSnapPositionsY(const QList &positions) +{ + Q_D(QScroller); + d->snapPositionsY = positions; + d->snapIntervalY = 0.0; + + d->recalcScrollingSegments(); +} + +/*! Set the snap positions for the vertical axis. + * Set the snap positions to regular spaced intervals. + * The first snap position will be at \a first. The next at \a first + \a interval and so on. + * This will overwrite all previously set snap positions and also a previously + * set snapping interval. + * Snapping can be deactivated by setting an interval of 0.0 + */ +void QScroller::setSnapPositionsY(qreal first, qreal interval) +{ + Q_D(QScroller); + d->snapFirstY = first; + d->snapIntervalY = interval; + d->snapPositionsY.clear(); + + d->recalcScrollingSegments(); +} + + + +// -------------- private ------------ + +QScrollerPrivate::QScrollerPrivate(QScroller *q, QObject *_target) + : target(_target) + , recognizer(0) + , recognizerType(Qt::CustomGesture) + , state(QScroller::Inactive) + , firstScroll(true) + , pressTimestamp(0) + , lastTimestamp(0) + , snapFirstX(-1.0) + , snapIntervalX(0.0) + , snapFirstY(-1.0) + , snapIntervalY(0.0) + , scrollTimer(new QScrollTimer(this)) + , q_ptr(q) +{ + connect(target, SIGNAL(destroyed(QObject*)), this, SLOT(targetDestroyed())); +} + +void QScrollerPrivate::init() +{ + setDpiFromWidget(0); + monotonicTimer.start(); +} + +void QScrollerPrivate::sendEvent(QObject *o, QEvent *e) +{ + qt_sendSpontaneousEvent(o, e); +} + +const char *QScrollerPrivate::stateName(QScroller::State state) +{ + switch (state) { + case QScroller::Inactive: return "inactive"; + case QScroller::Pressed: return "pressed"; + case QScroller::Dragging: return "dragging"; + case QScroller::Scrolling: return "scrolling"; + default: return "(invalid)"; + } +} + +const char *QScrollerPrivate::inputName(QScroller::Input input) +{ + switch (input) { + case QScroller::InputPress: return "press"; + case QScroller::InputMove: return "move"; + case QScroller::InputRelease: return "release"; + default: return "(invalid)"; + } +} + +void QScrollerPrivate::targetDestroyed() +{ + scrollTimer->stop(); + delete q_ptr; +} + +void QScrollerPrivate::timerTick() +{ + struct timerevent { + QScroller::State state; + typedef void (QScrollerPrivate::*timerhandler_t)(); + timerhandler_t handler; + }; + + timerevent timerevents[] = { + { QScroller::Dragging, &QScrollerPrivate::timerEventWhileDragging }, + { QScroller::Scrolling, &QScrollerPrivate::timerEventWhileScrolling }, + }; + + for (int i = 0; i < int(sizeof(timerevents) / sizeof(*timerevents)); ++i) { + timerevent *te = timerevents + i; + + if (state == te->state) { + (this->*te->handler)(); + return; + } + } + + scrollTimer->stop(); +} + +/*! + This function is used by gesture recognizers to inform the scroller about a new input event. + The scroller will change its internal state() according to the input event and its attached + scroller properties. Since the scroller doesn't care about the actual kind of input device the + event came from, you need to decompose the event into the \a input type, a \a position and a + milli-second \a timestamp. The \a position needs to be in the target's coordinate system. + The return value is \c true if the event should be consumed by the calling filter or \c false + if the event should be forwarded to the control. + + \note Using grabGesture() should be sufficient for most use cases though. +*/ +bool QScroller::handleInput(Input input, const QPointF &position, qint64 timestamp) +{ + Q_D(QScroller); + + qScrollerDebug() << "QScroller::handleInput(" << input << ", " << d->stateName(d->state) << ", " << position << ", " << timestamp << ")"; + struct statechange { + State state; + Input input; + typedef bool (QScrollerPrivate::*inputhandler_t)(const QPointF &position, qint64 timestamp); + inputhandler_t handler; + }; + + statechange statechanges[] = { + { QScroller::Inactive, InputPress, &QScrollerPrivate::pressWhileInactive }, + { QScroller::Pressed, InputMove, &QScrollerPrivate::moveWhilePressed }, + { QScroller::Pressed, InputRelease, &QScrollerPrivate::releaseWhilePressed }, + { QScroller::Dragging, InputMove, &QScrollerPrivate::moveWhileDragging }, + { QScroller::Dragging, InputRelease, &QScrollerPrivate::releaseWhileDragging }, + { QScroller::Scrolling, InputPress, &QScrollerPrivate::pressWhileScrolling } + }; + + for (int i = 0; i < int(sizeof(statechanges) / sizeof(*statechanges)); ++i) { + statechange *sc = statechanges + i; + + if (d->state == sc->state && input == sc->input) + return (d->*sc->handler)(position - d->overshootPosition, timestamp); + } + return false; +} + +#ifdef Q_WS_MAEMO_5 + +QPointF QScrollerPrivate::realDpi(int screen) +{ + Q_UNUSED(screen); + // The DPI value is hardcoded to 96 on Maemo5: + // https://projects.maemo.org/bugzilla/show_bug.cgi?id=152525 + // This value (260) is only correct for the N900 though, but + // there's no way to get the real DPI at run time. + return QPointF(260, 260); +} + +#elif defined(Q_WS_MAC) + +// implemented in qscroller_mac.mm + +#else + +QPointF QScrollerPrivate::realDpi(int screen) +{ + QWidget *w = QApplication::desktop()->screen(screen); + return QPointF(w->physicalDpiX(), w->physicalDpiY()); +} + +#endif + +/*! \internal + Returns the resolution of the used screen. +*/ +QPointF QScrollerPrivate::dpi() const +{ + return pixelPerMeter / qreal(39.3700787); +} + +/*! \internal + Sets the resolution used for scrolling. + This resolution is only used by the kinetic scroller. If you change this + then the scroller will behave quite different as a lot of the values are + given in physical distances (millimeter). +*/ +void QScrollerPrivate::setDpi(const QPointF &dpi) +{ + pixelPerMeter = dpi * qreal(39.3700787); +} + +/*! \internal + Sets the dpi used for scrolling to the value of the widget. +*/ +void QScrollerPrivate::setDpiFromWidget(QWidget *widget) +{ + QDesktopWidget *dw = QApplication::desktop(); + setDpi(realDpi(widget ? dw->screenNumber(widget) : dw->primaryScreen())); +} + +/*! \internal + Updates the velocity during dragging. + Sets releaseVelocity. +*/ +void QScrollerPrivate::updateVelocity(const QPointF &deltaPixelRaw, qint64 deltaTime) +{ + Q_Q(QScroller); + QPointF ppm = q->pixelPerMeter(); + const QScrollerPropertiesPrivate *sp = properties.d.data(); + QPointF deltaPixel = deltaPixelRaw; + + qScrollerDebug() << "QScroller::updateVelocity(" << deltaPixelRaw << " [delta pix], " << deltaTime << " [delta ms])"; + + // faster than 2.5mm/ms seems bogus (that would be a screen height in ~20 ms) + if (((deltaPixelRaw / qreal(deltaTime)).manhattanLength() / ((ppm.x() + ppm.y()) / 2) * 1000) > qreal(2.5)) + deltaPixel = deltaPixelRaw * qreal(2.5) * ppm / 1000 / (deltaPixelRaw / qreal(deltaTime)).manhattanLength(); + + qreal inversSmoothingFactor = ((qreal(1) - sp->dragVelocitySmoothingFactor) * qreal(deltaTime) / qreal(1000)); + QPointF newv = -deltaPixel / qreal(deltaTime) * qreal(1000) / ppm; + newv = newv * (qreal(1) - inversSmoothingFactor) + releaseVelocity * inversSmoothingFactor; + + if (deltaPixel.x()) + releaseVelocity.setX(qBound(-sp->maximumVelocity, newv.x(), sp->maximumVelocity)); + if (deltaPixel.y()) + releaseVelocity.setY(qBound(-sp->maximumVelocity, newv.y(), sp->maximumVelocity)); + + qScrollerDebug() << " --> new velocity:" << releaseVelocity; +} + +void QScrollerPrivate::pushSegment(ScrollType type, qreal deltaTime, qreal startPos, qreal endPos, QEasingCurve::Type curve, Qt::Orientation orientation, qreal maxProgress) +{ + if (startPos == endPos) + return; + + ScrollSegment s; + if (orientation == Qt::Horizontal && !xSegments.isEmpty()) + s.startTime = xSegments.last().startTime + xSegments.last().deltaTime; + else if (orientation == Qt::Vertical && !ySegments.isEmpty()) + s.startTime = ySegments.last().startTime + ySegments.last().deltaTime; + else + s.startTime = monotonicTimer.elapsed(); + + s.startPos = startPos; + s.deltaPos = endPos - startPos; + s.deltaTime = deltaTime * 1000; + s.maxProgress = maxProgress; + s.curve.setType(curve); + s.type = type; + + if (orientation == Qt::Horizontal) + xSegments.enqueue(s); + else + ySegments.enqueue(s); + + qScrollerDebug() << "+++ Added a new ScrollSegment: " << s; +} + + +/*! \internal + Clears the old segments and recalculates them if the current segments are not longer valid +*/ +void QScrollerPrivate::recalcScrollingSegments(bool forceRecalc) +{ + Q_Q(QScroller); + QPointF ppm = q->pixelPerMeter(); + + releaseVelocity = q->velocity(); + + if (forceRecalc || !scrollingSegmentsValid(Qt::Horizontal)) + createScrollingSegments(releaseVelocity.x(), contentPosition.x() + overshootPosition.x(), ppm.x(), Qt::Horizontal); + + if (forceRecalc || !scrollingSegmentsValid(Qt::Vertical)) + createScrollingSegments(releaseVelocity.y(), contentPosition.y() + overshootPosition.y(), ppm.y(), Qt::Vertical); +} + +/*! \internal + Returns the end position after the current scroll has finished. +*/ +qreal QScrollerPrivate::scrollingSegmentsEndPos(Qt::Orientation orientation) const +{ + const QQueue *segments; + qreal endPos; + + if (orientation == Qt::Horizontal) { + segments = &xSegments; + endPos = contentPosition.x() + overshootPosition.x(); + } else { + segments = &ySegments; + endPos = contentPosition.y() + overshootPosition.y(); + } + + if (!segments->isEmpty()) { + const ScrollSegment &last = segments->last(); + endPos = last.startPos + last.deltaPos; + } + + return endPos; +} + +/*! \internal + Checks if the scroller segment end in a valid position. +*/ +bool QScrollerPrivate::scrollingSegmentsValid(Qt::Orientation orientation) +{ + QQueue *segments; + qreal minPos; + qreal maxPos; + + if (orientation == Qt::Horizontal) { + segments = &xSegments; + minPos = contentPosRange.left(); + maxPos = contentPosRange.right(); + } else { + segments = &ySegments; + minPos = contentPosRange.top(); + maxPos = contentPosRange.bottom(); + } + + if (segments->isEmpty()) + return true; + + const ScrollSegment &last = segments->last(); + qreal endPos = last.startPos + last.deltaPos; + + if (last.type == ScrollTypeScrollTo) + return true; // scrollTo is always valid + + if (last.type == ScrollTypeOvershoot && + endPos != minPos && endPos != maxPos) + return false; + + if (endPos < minPos || endPos > maxPos) + return false; + + if (endPos == minPos || endPos == maxPos) // the begin and the end of the list are always ok + return true; + + qreal nextSnap = nextSnapPos(endPos, 0, orientation); + if (!qIsNaN(nextSnap) && endPos != nextSnap) + return false; + + return true; +} + +/*! \internal + Creates the sections needed to scroll to the specific \a endPos to the segments queue. +*/ +void QScrollerPrivate::createScrollToSegments(qreal v, qreal deltaTime, qreal endPos, Qt::Orientation orientation, ScrollType type) +{ + Q_UNUSED(v); + + if (orientation == Qt::Horizontal) { + xSegments.clear(); + } else { + ySegments.clear(); + } + + qScrollerDebug() << "+++ createScrollToSegments: t:" << deltaTime << "ep:" << endPos << "o:" << int(orientation); + + const QScrollerPropertiesPrivate *sp = properties.d.data(); + + qreal startPos = (orientation == Qt::Horizontal) ? contentPosition.x() + overshootPosition.x() + : contentPosition.y() + overshootPosition.y(); + qreal deltaPos = endPos - startPos; + + pushSegment(type, deltaTime * 0.3, startPos, startPos + deltaPos * 0.5, QEasingCurve::InQuad, orientation); + pushSegment(type, deltaTime * 0.7, startPos + deltaPos * 0.5, endPos, sp->scrollingCurve.type(), orientation); +} + +/*! \internal +*/ +void QScrollerPrivate::createScrollingSegments(qreal v, qreal startPos, qreal ppm, Qt::Orientation orientation) +{ + const QScrollerPropertiesPrivate *sp = properties.d.data(); + + QScrollerProperties::OvershootPolicy policy; + qreal minPos; + qreal maxPos; + qreal viewSize; + + if (orientation == Qt::Horizontal) { + xSegments.clear(); + policy = sp->hOvershootPolicy; + minPos = contentPosRange.left(); + maxPos = contentPosRange.right(); + viewSize = viewportSize.width(); + } else { + ySegments.clear(); + policy = sp->vOvershootPolicy; + minPos = contentPosRange.top(); + maxPos = contentPosRange.bottom(); + viewSize = viewportSize.height(); + } + + bool alwaysOvershoot = (policy == QScrollerProperties::OvershootAlwaysOn); + bool noOvershoot = (policy == QScrollerProperties::OvershootAlwaysOff) || !sp->overshootScrollDistanceFactor; + bool canOvershoot = !noOvershoot && (alwaysOvershoot || maxPos); + + qScrollerDebug() << "+++ createScrollingSegments: s:" << startPos << "maxPos:" << maxPos << "o:" << int(orientation); + + // -- check if we are in overshoot + if (startPos < minPos) { + createScrollToSegments(v, sp->overshootScrollTime * 0.5, minPos, orientation, ScrollTypeOvershoot); + return; + } + + if (startPos > maxPos) { + createScrollToSegments(v, sp->overshootScrollTime * 0.5, maxPos, orientation, ScrollTypeOvershoot); + return; + } + + qScrollerDebug() << "v = " << v << ", decelerationFactor = " << sp->decelerationFactor << ", curveType = " << sp->scrollingCurve.type(); + + // This is only correct for QEasingCurve::OutQuad (linear velocity, + // constant deceleration), but the results look and feel ok for OutExpo + // and OutSine as well + + // v(t) = deltaTime * a * 0.5 * differentialForProgress(t / deltaTime) + // v(0) = vrelease + // v(deltaTime) = 0 + // deltaTime = (2 * vrelease) / (a * differntial(0)) + + // pos(t) = integrate(v(t)dt) + // pos(t) = vrelease * t - 0.5 * a * t * t + // pos(t) = deltaTime * a * 0.5 * progress(t / deltaTime) * deltaTime + // deltaPos = pos(deltaTime) + + qreal deltaTime = (qreal(2) * qAbs(v)) / (sp->decelerationFactor * differentialForProgress(sp->scrollingCurve, 0)); + qreal deltaPos = qSign(v) * deltaTime * deltaTime * qreal(0.5) * sp->decelerationFactor * ppm; + qreal endPos = startPos + deltaPos; + + qScrollerDebug() << " Real Delta:" << deltaPos; + + // -- determine snap points + qreal nextSnap = nextSnapPos(endPos, 0, orientation); + qreal lowerSnapPos = nextSnapPos(startPos, -1, orientation); + qreal higherSnapPos = nextSnapPos(startPos, 1, orientation); + + qScrollerDebug() << " Real Delta:" << lowerSnapPos <<"-"< higherSnapPos || qIsNaN(higherSnapPos)) + higherSnapPos = nextSnap; + if (nextSnap < lowerSnapPos || qIsNaN(lowerSnapPos)) + lowerSnapPos = nextSnap; + + if (qAbs(v) < sp->minimumVelocity) { + + qScrollerDebug() << "### below minimum Vel" << orientation; + + // - no snap points or already at one + if (qIsNaN(nextSnap) || nextSnap == startPos) + return; // nothing to do, no scrolling needed. + + // - decide which point to use + + qreal snapDistance = higherSnapPos - lowerSnapPos; + + qreal pressDistance = (orientation == Qt::Horizontal) ? + lastPosition.x() - pressPosition.x() : + lastPosition.y() - pressPosition.y(); + + // if not dragged far enough, pick the next snap point. + if (sp->snapPositionRatio == 0.0 || qAbs(pressDistance / sp->snapPositionRatio) > snapDistance) + endPos = nextSnap; + else if (pressDistance < 0.0) + endPos = lowerSnapPos; + else + endPos = higherSnapPos; + + deltaPos = endPos - startPos; + pushSegment(ScrollTypeFlick, sp->snapTime * 0.3, startPos, startPos + deltaPos * 0.3, QEasingCurve::InQuad, orientation); + pushSegment(ScrollTypeFlick, sp->snapTime * 0.7, startPos + deltaPos * 0.3, endPos, sp->scrollingCurve.type(), orientation); + return; + } + + // - go to the next snappoint if there is one + if (v > 0 && !qIsNaN(higherSnapPos)) { + // change the time in relation to the changed end position + if (endPos - startPos) + deltaTime *= qAbs((higherSnapPos - startPos) / (endPos - startPos)); + if (deltaTime > sp->snapTime) + deltaTime = sp->snapTime; + endPos = higherSnapPos; + + } else if (v < 0 && !qIsNaN(lowerSnapPos)) { + // change the time in relation to the changed end position + if (endPos - startPos) + deltaTime *= qAbs((lowerSnapPos - startPos) / (endPos - startPos)); + if (deltaTime > sp->snapTime) + deltaTime = sp->snapTime; + endPos = lowerSnapPos; + + // -- check if we are overshooting + } else if (endPos < minPos || endPos > maxPos) { + qreal stopPos = endPos < minPos ? minPos : maxPos; + + qScrollerDebug() << "Overshoot: delta:" << (stopPos - startPos); + + qreal maxProgress = progressForValue(sp->scrollingCurve, qAbs((stopPos - startPos) / deltaPos)); + qScrollerDebug() << "Overshoot maxp:" << maxProgress; + + pushSegment(ScrollTypeFlick, deltaTime * maxProgress, startPos, stopPos, sp->scrollingCurve.type(), orientation, maxProgress); + + if (canOvershoot) { + qreal endV = qSign(v) * deltaTime * sp->decelerationFactor * qreal(0.5) * differentialForProgress(sp->scrollingCurve, maxProgress); + qScrollerDebug() << "Overshoot: velocity" << endV; + qScrollerDebug() << "Overshoot: maxVelocity" << sp->maximumVelocity; + qScrollerDebug() << "Overshoot: viewsize" << viewSize; + qScrollerDebug() << "Overshoot: factor" << sp->overshootScrollDistanceFactor; + + qreal oDistance = viewSize * sp->overshootScrollDistanceFactor * endV / sp->maximumVelocity; + qreal oDeltaTime = sp->overshootScrollTime; + + pushSegment(ScrollTypeOvershoot, oDeltaTime * 0.5, stopPos, stopPos + oDistance, sp->scrollingCurve.type(), orientation); + pushSegment(ScrollTypeOvershoot, oDeltaTime * 0.3, stopPos + oDistance, stopPos + oDistance * 0.3, QEasingCurve::InQuad, orientation); + pushSegment(ScrollTypeOvershoot, oDeltaTime * 0.2, stopPos + oDistance * 0.3, stopPos, QEasingCurve::OutQuad, orientation); + } + return; + } + + pushSegment(ScrollTypeFlick, deltaTime, startPos, endPos, sp->scrollingCurve.type(), orientation); +} + + +/*! Prepares scrolling by sending a QScrollPrepareEvent to the receiver widget. + Returns true if the scrolling was accepted and a target was returned. +*/ +bool QScrollerPrivate::prepareScrolling(const QPointF &position) +{ + QScrollPrepareEvent spe(position); + spe.ignore(); + sendEvent(target, &spe); + + qScrollerDebug() << "QScrollPrepareEvent returned from" << target << "with" << spe.isAccepted() << "mcp:" << spe.contentPosRange() << "cp:" << spe.contentPos(); + if (spe.isAccepted()) { + QPointF oldContentPos = contentPosition + overshootPosition; + QPointF contentDelta = spe.contentPos() - oldContentPos; + + viewportSize = spe.viewportSize(); + contentPosRange = spe.contentPosRange(); + if (contentPosRange.width() < 0) + contentPosRange.setWidth(0); + if (contentPosRange.height() < 0) + contentPosRange.setHeight(0); + contentPosition = clampToRect(spe.contentPos(), contentPosRange); + overshootPosition = spe.contentPos() - contentPosition; + + // - check if the content position was moved + if (contentDelta != QPointF(0, 0)) { + // need to correct all segments + for (int i = 0; i < xSegments.count(); i++) + xSegments[i].startPos -= contentDelta.x(); + + for (int i = 0; i < ySegments.count(); i++) + ySegments[i].startPos -= contentDelta.y(); + } + + if (QWidget *w = qobject_cast(target)) + setDpiFromWidget(w); + if (QGraphicsObject *go = qobject_cast(target)) { + //TODO: the first view isn't really correct - maybe use an additional field in the prepare event? + if (go->scene() && !go->scene()->views().isEmpty()) + setDpiFromWidget(go->scene()->views().first()); + } + + if (state == QScroller::Scrolling) { + recalcScrollingSegments(); + } + return true; + } + + return false; +} + +void QScrollerPrivate::handleDrag(const QPointF &position, qint64 timestamp) +{ + const QScrollerPropertiesPrivate *sp = properties.d.data(); + + QPointF deltaPixel = position - lastPosition; + qint64 deltaTime = timestamp - lastTimestamp; + + if (sp->axisLockThreshold) { + int dx = qAbs(deltaPixel.x()); + int dy = qAbs(deltaPixel.y()); + if (dx || dy) { + bool vertical = (dy > dx); + qreal alpha = qreal(vertical ? dx : dy) / qreal(vertical ? dy : dx); + //qScrollerDebug() << "QScroller::handleDrag() -- axis lock:" << alpha << " / " << axisLockThreshold << "- isvertical:" << vertical << "- dx:" << dx << "- dy:" << dy; + if (alpha <= sp->axisLockThreshold) { + if (vertical) + deltaPixel.setX(0); + else + deltaPixel.setY(0); + } + } + } + + // calculate velocity (if the user would release the mouse NOW) + updateVelocity(deltaPixel, deltaTime); + + // restrict velocity, if content is not scrollable + QRectF max = contentPosRange; + bool canScrollX = (max.width() > 0) || (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn); + bool canScrollY = (max.height() > 0) || (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn); + + if (!canScrollX) { + deltaPixel.setX(0); + releaseVelocity.setX(0); + } + if (!canScrollY) { + deltaPixel.setY(0); + releaseVelocity.setY(0); + } + +// if (firstDrag) { +// // Do not delay the first drag +// setContentPositionHelper(q->contentPosition() - overshootDistance - deltaPixel); +// dragDistance = QPointF(0, 0); +// } else { + dragDistance += deltaPixel; +// } +//qScrollerDebug() << "######################" << deltaPixel << position.y() << lastPosition.y(); + if (canScrollX) + lastPosition.setX(position.x()); + if (canScrollY) + lastPosition.setY(position.y()); + lastTimestamp = timestamp; +} + +bool QScrollerPrivate::pressWhileInactive(const QPointF &position, qint64 timestamp) +{ + if (prepareScrolling(position)) { + const QScrollerPropertiesPrivate *sp = properties.d.data(); + + if (!contentPosRange.isNull() || + (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn) || + (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn)) { + + lastPosition = pressPosition = position; + lastTimestamp = pressTimestamp = timestamp; + setState(QScroller::Pressed); + } + } + return false; +} + +bool QScrollerPrivate::releaseWhilePressed(const QPointF &, qint64) +{ + if (overshootPosition != QPointF(0.0, 0.0)) { + setState(QScroller::Scrolling); + return true; + } else { + setState(QScroller::Inactive); + return false; + } +} + +bool QScrollerPrivate::moveWhilePressed(const QPointF &position, qint64 timestamp) +{ + Q_Q(QScroller); + const QScrollerPropertiesPrivate *sp = properties.d.data(); + QPointF ppm = q->pixelPerMeter(); + + QPointF deltaPixel = position - pressPosition; + + bool moveAborted = false; + bool moveStarted = (((deltaPixel / ppm).manhattanLength()) > sp->dragStartDistance); + + // check the direction of the mouse drag and abort if it's too much in the wrong direction. + if (moveStarted) { + QRectF max = contentPosRange; + bool canScrollX = (max.width() > 0); + bool canScrollY = (max.height() > 0); + + if (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn) + canScrollX = true; + if (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn) + canScrollY = true; + + if (qAbs(deltaPixel.x() / ppm.x()) < qAbs(deltaPixel.y() / ppm.y())) { + if (!canScrollY) + moveAborted = true; + } else { + if (!canScrollX) + moveAborted = true; + } + } + + if (moveAborted) { + setState(QScroller::Inactive); + moveStarted = false; + + } else if (moveStarted) { + setState(QScroller::Dragging); + + // subtract the dragStartDistance + deltaPixel = deltaPixel - deltaPixel * (sp->dragStartDistance / deltaPixel.manhattanLength()); + + if (deltaPixel != QPointF(0, 0)) { + // handleDrag updates lastPosition, lastTimestamp and velocity + handleDrag(pressPosition + deltaPixel, timestamp); + } + } + return moveStarted; +} + +bool QScrollerPrivate::moveWhileDragging(const QPointF &position, qint64 timestamp) +{ + // handleDrag updates lastPosition, lastTimestamp and velocity + handleDrag(position, timestamp); + return true; +} + +void QScrollerPrivate::timerEventWhileDragging() +{ + if (dragDistance != QPointF(0, 0)) { + qScrollerDebug() << "QScroller::timerEventWhileDragging() -- dragDistance:" << dragDistance; + + setContentPositionHelperDragging(-dragDistance); + dragDistance = QPointF(0, 0); + } +} + +bool QScrollerPrivate::releaseWhileDragging(const QPointF &position, qint64 timestamp) +{ + Q_Q(QScroller); + const QScrollerPropertiesPrivate *sp = properties.d.data(); + + // check if we moved at all - this can happen if you stop a running + // scroller with a press and release shortly afterwards + QPointF deltaPixel = position - pressPosition; + if (((deltaPixel / q->pixelPerMeter()).manhattanLength()) > sp->dragStartDistance) { + + // handle accelerating flicks + if ((oldVelocity != QPointF(0, 0)) && sp->acceleratingFlickMaximumTime && + ((timestamp - pressTimestamp) < qint64(sp->acceleratingFlickMaximumTime * 1000))) { + + // - determine if the direction was changed + int signX = 0, signY = 0; + if (releaseVelocity.x()) + signX = (releaseVelocity.x() > 0) == (oldVelocity.x() > 0) ? 1 : -1; + if (releaseVelocity.y()) + signY = (releaseVelocity.y() > 0) == (oldVelocity.y() > 0) ? 1 : -1; + + if (signX > 0) + releaseVelocity.setX(qBound(-sp->maximumVelocity, + oldVelocity.x() * sp->acceleratingFlickSpeedupFactor, + sp->maximumVelocity)); + if (signY > 0) + releaseVelocity.setY(qBound(-sp->maximumVelocity, + oldVelocity.y() * sp->acceleratingFlickSpeedupFactor, + sp->maximumVelocity)); + } + } + + QPointF ppm = q->pixelPerMeter(); + createScrollingSegments(releaseVelocity.x(), contentPosition.x() + overshootPosition.x(), ppm.x(), Qt::Horizontal); + createScrollingSegments(releaseVelocity.y(), contentPosition.y() + overshootPosition.y(), ppm.y(), Qt::Vertical); + + qScrollerDebug() << "QScroller::releaseWhileDragging() -- velocity:" << releaseVelocity << "-- minimum velocity:" << sp->minimumVelocity << "overshoot" << overshootPosition; + + if (xSegments.isEmpty() && ySegments.isEmpty()) + setState(QScroller::Inactive); + else + setState(QScroller::Scrolling); + + return true; +} + +void QScrollerPrivate::timerEventWhileScrolling() +{ + qScrollerDebug() << "QScroller::timerEventWhileScrolling()"; + + setContentPositionHelperScrolling(); + if (xSegments.isEmpty() && ySegments.isEmpty()) + setState(QScroller::Inactive); +} + +bool QScrollerPrivate::pressWhileScrolling(const QPointF &position, qint64 timestamp) +{ + Q_Q(QScroller); + + if ((q->velocity() <= properties.d->maximumClickThroughVelocity) && + (overshootPosition == QPointF(0.0, 0.0))) { + setState(QScroller::Inactive); + return false; + } else { + lastPosition = pressPosition = position; + lastTimestamp = pressTimestamp = timestamp; + setState(QScroller::Pressed); + setState(QScroller::Dragging); + return true; + } +} + +/*! \internal + This function handles all state changes of the scroller. +*/ +void QScrollerPrivate::setState(QScroller::State newstate) +{ + Q_Q(QScroller); + bool sendLastScroll = false; + + if (state == newstate) + return; + + qScrollerDebug() << q << "QScroller::setState(" << stateName(newstate) << ")"; + + switch (newstate) { + case QScroller::Inactive: + scrollTimer->stop(); + + // send the last scroll event (but only after the current state change was finished) + if (!firstScroll) + sendLastScroll = true; + + releaseVelocity = QPointF(0, 0); + break; + + case QScroller::Pressed: + scrollTimer->stop(); + + oldVelocity = releaseVelocity; + releaseVelocity = QPointF(0, 0); + break; + + case QScroller::Dragging: + dragDistance = QPointF(0, 0); + if (state == QScroller::Pressed) + scrollTimer->start(); + break; + + case QScroller::Scrolling: + scrollTimer->start(); + break; + } + + qSwap(state, newstate); + + if (sendLastScroll) { + QScrollEvent se(contentPosition, overshootPosition, QScrollEvent::ScrollFinished); + sendEvent(target, &se); + firstScroll = true; + } + if (state == QScroller::Dragging || state == QScroller::Scrolling) + activeScrollers.insert(q); + else + activeScrollers.remove(q); + emit q->stateChanged(state); +} + + +/*! \internal + Helps when setting the content position. + It will try to move the content by the requested delta but stop in case + when we are coming back from an overshoot or a scrollTo. + It will also indicate a new overshooting condition by the overshootX and oversthootY flags. + + In this cases it will reset the velocity variables and other flags. + + Also keeps track of the current over-shooting value in overshootPosition. + + \a deltaPos is the amount of pixels the current content position should be moved +*/ +void QScrollerPrivate::setContentPositionHelperDragging(const QPointF &deltaPos) +{ + Q_Q(QScroller); + QPointF ppm = q->pixelPerMeter(); + const QScrollerPropertiesPrivate *sp = properties.d.data(); + QPointF v = q->velocity(); + + if (sp->overshootDragResistanceFactor) + overshootPosition /= sp->overshootDragResistanceFactor; + + QPointF oldPos = contentPosition + overshootPosition; + QPointF newPos = oldPos + deltaPos; + + qScrollerDebug() << "QScroller::setContentPositionHelperDragging(" << deltaPos << " [pix])"; + qScrollerDebug() << " --> overshoot:" << overshootPosition << "- old pos:" << oldPos << "- new pos:" << newPos; + + QPointF oldClampedPos = clampToRect(oldPos, contentPosRange); + QPointF newClampedPos = clampToRect(newPos, contentPosRange); + + // --- handle overshooting and stop if the coordinate is going back inside the normal area + bool alwaysOvershootX = (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn); + bool alwaysOvershootY = (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn); + bool noOvershootX = (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOff) || + ((state == QScroller::Dragging) && !sp->overshootDragResistanceFactor) || + !sp->overshootDragDistanceFactor; + bool noOvershootY = (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOff) || + ((state == QScroller::Dragging) && !sp->overshootDragResistanceFactor) || + !sp->overshootDragDistanceFactor; + bool canOvershootX = !noOvershootX && (alwaysOvershootX || contentPosRange.width()); + bool canOvershootY = !noOvershootY && (alwaysOvershootY || contentPosRange.height()); + + qreal oldOvershootX = (canOvershootX) ? oldPos.x() - oldClampedPos.x() : 0; + qreal oldOvershootY = (canOvershootY) ? oldPos.y() - oldClampedPos.y() : 0; + + qreal newOvershootX = (canOvershootX) ? newPos.x() - newClampedPos.x() : 0; + qreal newOvershootY = (canOvershootY) ? newPos.y() - newClampedPos.y() : 0; + + qreal maxOvershootX = viewportSize.width() * sp->overshootDragDistanceFactor; + qreal maxOvershootY = viewportSize.height() * sp->overshootDragDistanceFactor; + + qScrollerDebug() << " --> noOs:" << noOvershootX << "drf:" << sp->overshootDragResistanceFactor << "mdf:" << sp->overshootScrollDistanceFactor << "ossP:"<hOvershootPolicy; + qScrollerDebug() << " --> canOS:" << canOvershootX << "newOS:" << newOvershootX << "maxOS:" << maxOvershootX; + + if (sp->overshootDragResistanceFactor) { + oldOvershootX *= sp->overshootDragResistanceFactor; + oldOvershootY *= sp->overshootDragResistanceFactor; + newOvershootX *= sp->overshootDragResistanceFactor; + newOvershootY *= sp->overshootDragResistanceFactor; + } + + // -- stop at the maximum overshoot distance + + newOvershootX = qBound(-maxOvershootX, newOvershootX, maxOvershootX); + newOvershootY = qBound(-maxOvershootY, newOvershootY, maxOvershootY); + + overshootPosition.setX(newOvershootX); + overshootPosition.setY(newOvershootY); + contentPosition = newClampedPos; + + QScrollEvent se(contentPosition, overshootPosition, firstScroll ? QScrollEvent::ScrollStarted : QScrollEvent::ScrollUpdated); + sendEvent(target, &se); + firstScroll = false; + + qScrollerDebug() << " --> new position:" << newClampedPos << "- new overshoot:" << overshootPosition << + "- overshoot x/y?:" << overshootPosition; +} + + +qreal QScrollerPrivate::nextSegmentPosition(QQueue &segments, qint64 now, qreal oldPos) +{ + qreal pos = oldPos; + + // check the X segments for new positions + while (!segments.isEmpty()) { + const ScrollSegment s = segments.head(); + + if ((s.startTime + s.deltaTime) <= now) { + segments.dequeue(); + pos = s.startPos + s.deltaPos; + } else if (s.startTime <= now) { + qreal progress = qreal(now - s.startTime) / (qreal(s.deltaTime) / s.maxProgress); + pos = s.startPos + s.deltaPos * s.curve.valueForProgress(progress) / s.curve.valueForProgress(s.maxProgress); + break; + } else { + break; + } + } + return pos; +} + +void QScrollerPrivate::setContentPositionHelperScrolling() +{ + qint64 now = monotonicTimer.elapsed(); + QPointF newPos = contentPosition + overshootPosition; + + newPos.setX(nextSegmentPosition(xSegments, now, newPos.x())); + newPos.setY(nextSegmentPosition(ySegments, now, newPos.y())); + + // -- set the position and handle overshoot + qScrollerDebug() << "QScroller::setContentPositionHelperScrolling()"; + qScrollerDebug() << " --> overshoot:" << overshootPosition << "- new pos:" << newPos; + + QPointF newClampedPos = clampToRect(newPos, contentPosRange); + + overshootPosition = newPos - newClampedPos; + contentPosition = newClampedPos; + + QScrollEvent se(contentPosition, overshootPosition, firstScroll ? QScrollEvent::ScrollStarted : QScrollEvent::ScrollUpdated); + sendEvent(target, &se); + firstScroll = false; + + qScrollerDebug() << " --> new position:" << newClampedPos << "- new overshoot:" << overshootPosition; +} + +/*! \internal + * Returns the next snap point in direction. + * If \a direction >0 it will return the next snap point that is larger than the current position. + * If \a direction <0 it will return the next snap point that is smaller than the current position. + * If \a direction ==0 it will return the nearest snap point (or the current position if we are already + * on a snap point. + * Returns the nearest snap position or NaN if no such point could be found. + */ +qreal QScrollerPrivate::nextSnapPos(qreal p, int dir, Qt::Orientation orientation) +{ + qreal bestSnapPos = Q_QNAN; + qreal bestSnapPosDist = Q_INFINITY; + + qreal minPos; + qreal maxPos; + + if (orientation == Qt::Horizontal) { + minPos = contentPosRange.left(); + maxPos = contentPosRange.right(); + } else { + minPos = contentPosRange.top(); + maxPos = contentPosRange.bottom(); + } + + if (orientation == Qt::Horizontal) { + // the snap points in the list + foreach (qreal snapPos, snapPositionsX) { + qreal snapPosDist = snapPos - p; + if ((dir > 0 && snapPosDist < 0) || + (dir < 0 && snapPosDist > 0)) + continue; // wrong direction + if (snapPos < minPos || snapPos > maxPos ) + continue; // invalid + + if (qIsNaN(bestSnapPos) || + qAbs(snapPosDist) < bestSnapPosDist ) { + bestSnapPos = snapPos; + bestSnapPosDist = qAbs(snapPosDist); + } + } + + // the snap point interval + if (snapIntervalX > 0.0) { + qreal first = minPos + snapFirstX; + qreal snapPos; + if (dir > 0) + snapPos = qCeil((p - first) / snapIntervalX) * snapIntervalX + first; + else if (dir < 0) + snapPos = qFloor((p - first) / snapIntervalX) * snapIntervalX + first; + else if (p <= first) + snapPos = first; + else + { + qreal last = qFloor((maxPos - first) / snapIntervalX) * snapIntervalX + first; + if (p >= last) + snapPos = last; + else + snapPos = qRound((p - first) / snapIntervalX) * snapIntervalX + first; + } + + if (snapPos >= first && snapPos <= maxPos ) { + qreal snapPosDist = snapPos - p; + + if (qIsNaN(bestSnapPos) || + qAbs(snapPosDist) < bestSnapPosDist ) { + bestSnapPos = snapPos; + bestSnapPosDist = qAbs(snapPosDist); + } + } + } + + } else { // (orientation == Qt::Vertical) + // the snap points in the list + foreach (qreal snapPos, snapPositionsY) { + qreal snapPosDist = snapPos - p; + if ((dir > 0 && snapPosDist < 0) || + (dir < 0 && snapPosDist > 0)) + continue; // wrong direction + if (snapPos < minPos || snapPos > maxPos ) + continue; // invalid + + if (qIsNaN(bestSnapPos) || + qAbs(snapPosDist) < bestSnapPosDist) { + bestSnapPos = snapPos; + bestSnapPosDist = qAbs(snapPosDist); + } + } + + // the snap point interval + if (snapIntervalY > 0.0) { + qreal first = minPos + snapFirstY; + qreal snapPos; + if (dir > 0) + snapPos = qCeil((p - first) / snapIntervalY) * snapIntervalY + first; + else if (dir < 0) + snapPos = qFloor((p - first) / snapIntervalY) * snapIntervalY + first; + else if (p <= first) + snapPos = first; + else + { + qreal last = qFloor((maxPos - first) / snapIntervalY) * snapIntervalY + first; + if (p >= last) + snapPos = last; + else + snapPos = qRound((p - first) / snapIntervalY) * snapIntervalY + first; + } + + if (snapPos >= first && snapPos <= maxPos ) { + qreal snapPosDist = snapPos - p; + + if (qIsNaN(bestSnapPos) || + qAbs(snapPosDist) < bestSnapPosDist) { + bestSnapPos = snapPos; + bestSnapPosDist = qAbs(snapPosDist); + } + } + } + } + + return bestSnapPos; +} + +/*! + \enum QScroller::State + + This enum contains the different QScroller states. + + \value Inactive The scroller is not scrolling and nothing is pressed. + \value Pressed A touch event was received or the mouse button pressed but the scroll area is currently not dragged. + \value Dragging The scroll area is currently following the touch point or mouse. + \value Scrolling The scroll area is moving on it's own. +*/ + +/*! + \enum QScroller::ScrollerGestureType + + This enum contains the different gesture types that are supported by the QScroller gesture recognizer. + + \value TouchGesture The gesture recognizer will only trigger on touch + events. Specifically it will react on single touch points when using a + touch screen and dual touch points when using a touchpad. + \value LeftMouseButtonGesture The gesture recognizer will only trigger on left mouse button events. + \value MiddleMouseButtonGesture The gesture recognizer will only trigger on middle mouse button events. + \value RightMouseButtonGesture The gesture recognizer will only trigger on right mouse button events. +*/ + +/*! + \enum QScroller::Input + + This enum contains an input device agnostic view of input events that are relevant for QScroller. + + \value InputPress The user pressed the input device (e.g. QEvent::MouseButtonPress, + QEvent::GraphicsSceneMousePress, QEvent::TouchBegin) + + \value InputMove The user moved the input device (e.g. QEvent::MouseMove, + QEvent::GraphicsSceneMouseMove, QEvent::TouchUpdate) + + \value InputRelease The user released the input device (e.g. QEvent::MouseButtonRelease, + QEvent::GraphicsSceneMouseRelease, QEvent::TouchEnd) + +*/ + +QT_END_NAMESPACE diff --git a/src/gui/util/qscroller.h b/src/gui/util/qscroller.h new file mode 100644 index 0000000..34e1125 --- /dev/null +++ b/src/gui/util/qscroller.h @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef QSCROLLER_H +#define QSCROLLER_H + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QWidget; +class QScrollerPrivate; +class QScrollerProperties; +class QFlickGestureRecognizer; +class QMouseFlickGestureRecognizer; + +class Q_GUI_EXPORT QScroller : public QObject +{ + Q_OBJECT + Q_PROPERTY(State state READ state NOTIFY stateChanged) + Q_PROPERTY(QScrollerProperties scrollerProperties READ scrollerProperties WRITE setScrollerProperties NOTIFY scrollerPropertiesChanged) + Q_ENUMS(State) + +public: + enum State + { + Inactive, + Pressed, + Dragging, + Scrolling, + }; + + enum ScrollerGestureType + { + TouchGesture, + LeftMouseButtonGesture, + RightMouseButtonGesture, + MiddleMouseButtonGesture + }; + + enum Input + { + InputPress = 1, + InputMove, + InputRelease + }; + + static bool hasScroller(QObject *target); + + static QScroller *scroller(QObject *target); + static const QScroller *scroller(const QObject *target); + + static Qt::GestureType grabGesture(QObject *target, ScrollerGestureType gestureType = TouchGesture); + static Qt::GestureType grabbedGesture(QObject *target); + static void ungrabGesture(QObject *target); + + static QList activeScrollers(); + + QObject *target() const; + + State state() const; + + bool handleInput(Input input, const QPointF &position, qint64 timestamp = 0); + + void stop(); + QPointF velocity() const; + QPointF finalPosition() const; + QPointF pixelPerMeter() const; + + QScrollerProperties scrollerProperties() const; + + void setSnapPositionsX( const QList &positions ); + void setSnapPositionsX( qreal first, qreal interval ); + void setSnapPositionsY( const QList &positions ); + void setSnapPositionsY( qreal first, qreal interval ); + +public Q_SLOTS: + void setScrollerProperties(const QScrollerProperties &prop); + void scrollTo(const QPointF &pos); + void scrollTo(const QPointF &pos, int scrollTime); + void ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin); + void ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin, int scrollTime); + void resendPrepareEvent(); + +Q_SIGNALS: + void stateChanged(QScroller::State newstate); + void scrollerPropertiesChanged(const QScrollerProperties &); + +private: + QScrollerPrivate *d_ptr; + + QScroller(QObject *target); + virtual ~QScroller(); + + Q_DISABLE_COPY(QScroller) + Q_DECLARE_PRIVATE(QScroller) + + friend class QFlickGestureRecognizer; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSCROLLER_H diff --git a/src/gui/util/qscroller_mac.mm b/src/gui/util/qscroller_mac.mm new file mode 100644 index 0000000..3203036 --- /dev/null +++ b/src/gui/util/qscroller_mac.mm @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#import + +#include "qscroller_p.h" + +#ifdef Q_WS_MAC + +QPointF QScrollerPrivate::realDpi(int screen) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSArray *nsscreens = [NSScreen screens]; + + if (screen < 0 || screen >= int([nsscreens count])) + screen = 0; + + NSScreen *nsscreen = [nsscreens objectAtIndex:screen]; + CGDirectDisplayID display = [[[nsscreen deviceDescription] objectForKey:@"NSScreenNumber"] intValue]; + + CGSize mmsize = CGDisplayScreenSize(display); + if (mmsize.width > 0 && mmsize.height > 0) { + return QPointF(CGDisplayPixelsWide(display) / mmsize.width, + CGDisplayPixelsHigh(display) / mmsize.height) * qreal(25.4); + } else { + return QPointF(); + } + [pool release]; +} + +#endif diff --git a/src/gui/util/qscroller_p.h b/src/gui/util/qscroller_p.h new file mode 100644 index 0000000..98f34f7 --- /dev/null +++ b/src/gui/util/qscroller_p.h @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef QSCROLLER_P_H +#define QSCROLLER_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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QFlickGestureRecognizer; + +class QScrollTimer; + +class QScrollerPrivate : public QObject +{ + Q_OBJECT + Q_DECLARE_PUBLIC(QScroller) + +public: + QScrollerPrivate(QScroller *q, QObject *target); + void init(); + + void sendEvent(QObject *o, QEvent *e); + + void setState(QScroller::State s); + + enum ScrollType { + ScrollTypeFlick = 0, + ScrollTypeScrollTo, + ScrollTypeOvershoot + }; + + struct ScrollSegment { + qint64 startTime; + qint64 deltaTime; + qreal startPos; + qreal deltaPos; + QEasingCurve curve; + qreal maxProgress; + ScrollType type; + }; + + bool pressWhileInactive(const QPointF &position, qint64 timestamp); + bool moveWhilePressed(const QPointF &position, qint64 timestamp); + bool releaseWhilePressed(const QPointF &position, qint64 timestamp); + bool moveWhileDragging(const QPointF &position, qint64 timestamp); + bool releaseWhileDragging(const QPointF &position, qint64 timestamp); + bool pressWhileScrolling(const QPointF &position, qint64 timestamp); + + void timerTick(); + void timerEventWhileDragging(); + void timerEventWhileScrolling(); + + bool prepareScrolling(const QPointF &position); + void handleDrag(const QPointF &position, qint64 timestamp); + + QPointF realDpi(int screen); + QPointF dpi() const; + void setDpi(const QPointF &dpi); + void setDpiFromWidget(QWidget *widget); + + void updateVelocity(const QPointF &deltaPixelRaw, qint64 deltaTime); + void pushSegment(ScrollType type, qreal deltaTime, qreal startPos, qreal endPos, QEasingCurve::Type curve, Qt::Orientation orientation, qreal maxProgress = 1.0); + void recalcScrollingSegments(bool forceRecalc = false); + qreal scrollingSegmentsEndPos(Qt::Orientation orientation) const; + bool scrollingSegmentsValid(Qt::Orientation orientation); + void createScrollToSegments(qreal v, qreal deltaTime, qreal endPos, Qt::Orientation orientation, ScrollType type); + void createScrollingSegments(qreal v, qreal startPos, qreal ppm, Qt::Orientation orientation); + + void setContentPositionHelperDragging(const QPointF &deltaPos); + void setContentPositionHelperScrolling(); + + qreal nextSnapPos(qreal p, int dir, Qt::Orientation orientation); + static qreal nextSegmentPosition(QQueue &segments, qint64 now, qreal oldPos); + + inline int frameRateSkip() const { return properties.d.data()->frameRate; } + + static const char *stateName(QScroller::State state); + static const char *inputName(QScroller::Input input); + +public slots: + void targetDestroyed(); + +public: + // static + static QMap allScrollers; + static QSet activeScrollers; + + // non static + QObject *target; + QScrollerProperties properties; + QFlickGestureRecognizer *recognizer; + Qt::GestureType recognizerType; + + // scroller state: + + // QPointer scrollTarget; + QSizeF viewportSize; + QRectF contentPosRange; + QPointF contentPosition; + QPointF overshootPosition; // the number of pixels we are overshooting (before overshootDragResistanceFactor) + + // state + + bool enabled; + QScroller::State state; + bool firstScroll; // true if we haven't already send a scroll event + + QPointF oldVelocity; // the release velocity of the last drag + + QPointF pressPosition; + QPointF lastPosition; + qint64 pressTimestamp; + qint64 lastTimestamp; + + QPointF dragDistance; // the distance we should move during the next drag timer event + + QQueue xSegments; + QQueue ySegments; + + // snap positions + QList snapPositionsX; + qreal snapFirstX; + qreal snapIntervalX; + QList snapPositionsY; + qreal snapFirstY; + qreal snapIntervalY; + + QPointF pixelPerMeter; + + QElapsedTimer monotonicTimer; + + QPointF releaseVelocity; // the starting velocity of the scrolling state + QScrollTimer *scrollTimer; + + QScroller *q_ptr; +}; + + +QT_END_NAMESPACE + +#endif // QSCROLLER_P_H + diff --git a/src/gui/util/qscrollerproperties.cpp b/src/gui/util/qscrollerproperties.cpp new file mode 100644 index 0000000..4fba489 --- /dev/null +++ b/src/gui/util/qscrollerproperties.cpp @@ -0,0 +1,418 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 +#include +#include +#ifdef Q_WS_WIN +# include +#endif + +#include "qscrollerproperties.h" +#include "private/qscrollerproperties_p.h" + +QT_BEGIN_NAMESPACE + +static QScrollerPropertiesPrivate *userDefaults = 0; +static QScrollerPropertiesPrivate *systemDefaults = 0; + +QScrollerPropertiesPrivate *QScrollerPropertiesPrivate::defaults() +{ + if (!systemDefaults) { + QScrollerPropertiesPrivate spp; +#ifdef Q_WS_MAEMO_5 + spp.mousePressEventDelay = qreal(0); + spp.dragStartDistance = qreal(2.5 / 1000); + spp.dragVelocitySmoothingFactor = qreal(0.15); + spp.axisLockThreshold = qreal(0); + spp.scrollingCurve.setType(QEasingCurve::OutQuad); + spp.decelerationFactor = 1.0; + spp.minimumVelocity = qreal(0.0195); + spp.maximumVelocity = qreal(6.84); + spp.maximumClickThroughVelocity = qreal(0.0684); + spp.acceleratingFlickMaximumTime = qreal(0.125); + spp.acceleratingFlickSpeedupFactor = qreal(3.0); + spp.snapPositionRatio = qreal(0.25); + spp.snapTime = qreal(1); + spp.overshootDragResistanceFactor = qreal(1); + spp.overshootDragDistanceFactor = qreal(0.3); + spp.overshootScrollDistanceFactor = qreal(0.3); + spp.overshootScrollTime = qreal(0.5); + spp.hOvershootPolicy = QScrollerProperties::OvershootWhenScrollable; + spp.vOvershootPolicy = QScrollerProperties::OvershootWhenScrollable; + spp.frameRate = QScrollerProperties::Fps30; +#else + spp.mousePressEventDelay = qreal(0.25); + spp.dragStartDistance = qreal(5.0 / 1000); + spp.dragVelocitySmoothingFactor = qreal(0.02); + spp.axisLockThreshold = qreal(0); + spp.scrollingCurve.setType(QEasingCurve::OutQuad); + spp.decelerationFactor = qreal(0.125); + spp.minimumVelocity = qreal(50.0 / 1000); + spp.maximumVelocity = qreal(500.0 / 1000); + spp.maximumClickThroughVelocity = qreal(66.5 / 1000); + spp.acceleratingFlickMaximumTime = qreal(1.25); + spp.acceleratingFlickSpeedupFactor = qreal(3.0); + spp.snapPositionRatio = qreal(0.5); + spp.snapTime = qreal(0.3); + spp.overshootDragResistanceFactor = qreal(0.5); + spp.overshootDragDistanceFactor = qreal(1); + spp.overshootScrollDistanceFactor = qreal(0.5); + spp.overshootScrollTime = qreal(0.7); +# ifdef Q_WS_WIN + if (QLibrary::resolve(QLatin1String("UxTheme"), "BeginPanningFeedback")) + spp.overshootScrollTime = qreal(0.35); +# endif + spp.hOvershootPolicy = QScrollerProperties::OvershootWhenScrollable; + spp.vOvershootPolicy = QScrollerProperties::OvershootWhenScrollable; + spp.frameRate = QScrollerProperties::Standard; +#endif + systemDefaults = new QScrollerPropertiesPrivate(spp); + } + return new QScrollerPropertiesPrivate(userDefaults ? *userDefaults : *systemDefaults); +} + +/*! + \class QScrollerProperties + \brief The QScrollerProperties class stores the settings for a QScroller. + \since 4.8 + + The QScrollerProperties class stores the parameters used by QScroller. + + The default settings are platform dependant and Qt will emulate the + platform behaviour for kinetic scrolling. + + As a convention the QScrollerProperties are in physical units (meter, + seconds) and will be converted by QScroller using the current DPI. + + \sa QScroller +*/ + +/*! + Constructs new scroller properties. +*/ +QScrollerProperties::QScrollerProperties() + : d(QScrollerPropertiesPrivate::defaults()) +{ +} + +/*! + Constructs a copy of \a sp. +*/ +QScrollerProperties::QScrollerProperties(const QScrollerProperties &sp) + : d(new QScrollerPropertiesPrivate(*sp.d)) +{ +} + +/*! + Assigns \a sp to these scroller properties and returns a reference to these scroller properties. +*/ +QScrollerProperties &QScrollerProperties::operator=(const QScrollerProperties &sp) +{ + *d.data() = *sp.d.data(); + return *this; +} + +/*! + Destroys the scroller properties. +*/ +QScrollerProperties::~QScrollerProperties() +{ +} + +/*! + Returns true if these scroller properties are equal to \a sp; otherwise returns false. +*/ +bool QScrollerProperties::operator==(const QScrollerProperties &sp) const +{ + return *d.data() == *sp.d.data(); +} + +/*! + Returns true if these scroller properties are different from \a sp; otherwise returns false. +*/ +bool QScrollerProperties::operator!=(const QScrollerProperties &sp) const +{ + return !(*d.data() == *sp.d.data()); +} + +bool QScrollerPropertiesPrivate::operator==(const QScrollerPropertiesPrivate &p) const +{ + bool same = true; + same &= (mousePressEventDelay == p.mousePressEventDelay); + same &= (dragStartDistance == p.dragStartDistance); + same &= (dragVelocitySmoothingFactor == p.dragVelocitySmoothingFactor); + same &= (axisLockThreshold == p.axisLockThreshold); + same &= (scrollingCurve == p.scrollingCurve); + same &= (decelerationFactor == p.decelerationFactor); + same &= (minimumVelocity == p.minimumVelocity); + same &= (maximumVelocity == p.maximumVelocity); + same &= (maximumClickThroughVelocity == p.maximumClickThroughVelocity); + same &= (acceleratingFlickMaximumTime == p.acceleratingFlickMaximumTime); + same &= (acceleratingFlickSpeedupFactor == p.acceleratingFlickSpeedupFactor); + same &= (snapPositionRatio == p.snapPositionRatio); + same &= (snapTime == p.snapTime); + same &= (overshootDragResistanceFactor == p.overshootDragResistanceFactor); + same &= (overshootDragDistanceFactor == p.overshootDragDistanceFactor); + same &= (overshootScrollDistanceFactor == p.overshootScrollDistanceFactor); + same &= (overshootScrollTime == p.overshootScrollTime); + same &= (hOvershootPolicy == p.hOvershootPolicy); + same &= (vOvershootPolicy == p.vOvershootPolicy); + same &= (frameRate == p.frameRate); + return same; +} + +/*! + Sets the scroller properties returned by the default constructor to \a sp. + + Use this function to override the platform default properties returned by the default + constructor. If you only want to change the scroller properties of a single scroller, then use + QScroller::setScrollerProperties() + + \note Calling this function will not change the content of already existing + QScrollerProperties objects. + + \sa unsetDefaultScrollerProperties() +*/ +void QScrollerProperties::setDefaultScrollerProperties(const QScrollerProperties &sp) +{ + if (!userDefaults) + userDefaults = new QScrollerPropertiesPrivate(*sp.d); + else + *userDefaults = *sp.d; +} + +/*! + Sets the scroller properties returned by the default constructor back to the platform default + properties. + + \sa setDefaultScrollerProperties() +*/ +void QScrollerProperties::unsetDefaultScrollerProperties() +{ + delete userDefaults; + userDefaults = 0; +} + +/*! + Query the \a metric value of the scroller properties. + + \sa setScrollMetric(), ScrollMetric +*/ +QVariant QScrollerProperties::scrollMetric(ScrollMetric metric) const +{ + switch (metric) { + case MousePressEventDelay: return d->mousePressEventDelay; + case DragStartDistance: return d->dragStartDistance; + case DragVelocitySmoothingFactor: return d->dragVelocitySmoothingFactor; + case AxisLockThreshold: return d->axisLockThreshold; + case ScrollingCurve: return d->scrollingCurve; + case DecelerationFactor: return d->decelerationFactor; + case MinimumVelocity: return d->minimumVelocity; + case MaximumVelocity: return d->maximumVelocity; + case MaximumClickThroughVelocity: return d->maximumClickThroughVelocity; + case AcceleratingFlickMaximumTime: return d->acceleratingFlickMaximumTime; + case AcceleratingFlickSpeedupFactor:return d->acceleratingFlickSpeedupFactor; + case SnapPositionRatio: return d->snapPositionRatio; + case SnapTime: return d->snapTime; + case OvershootDragResistanceFactor: return d->overshootDragResistanceFactor; + case OvershootDragDistanceFactor: return d->overshootDragDistanceFactor; + case OvershootScrollDistanceFactor: return d->overshootScrollDistanceFactor; + case OvershootScrollTime: return d->overshootScrollTime; + case HorizontalOvershootPolicy: return QVariant::fromValue(d->hOvershootPolicy); + case VerticalOvershootPolicy: return QVariant::fromValue(d->vOvershootPolicy); + case FrameRate: return QVariant::fromValue(d->frameRate); + case ScrollMetricCount: break; + } + return QVariant(); +} + +/*! + Set a specific value of the \a metric ScrollerMetric to \a value. + + \sa scrollMetric(), ScrollMetric +*/ +void QScrollerProperties::setScrollMetric(ScrollMetric metric, const QVariant &value) +{ + switch (metric) { + case MousePressEventDelay: d->mousePressEventDelay = value.toReal(); break; + case DragStartDistance: d->dragStartDistance = value.toReal(); break; + case DragVelocitySmoothingFactor: d->dragVelocitySmoothingFactor = qBound(qreal(0), value.toReal(), qreal(1)); break; + case AxisLockThreshold: d->axisLockThreshold = qBound(qreal(0), value.toReal(), qreal(1)); break; + case ScrollingCurve: d->scrollingCurve = value.toEasingCurve(); break; + case DecelerationFactor: d->decelerationFactor = value.toReal(); break; + case MinimumVelocity: d->minimumVelocity = value.toReal(); break; + case MaximumVelocity: d->maximumVelocity = value.toReal(); break; + case MaximumClickThroughVelocity: d->maximumClickThroughVelocity = value.toReal(); break; + case AcceleratingFlickMaximumTime: d->acceleratingFlickMaximumTime = value.toReal(); break; + case AcceleratingFlickSpeedupFactor:d->acceleratingFlickSpeedupFactor = value.toReal(); break; + case SnapPositionRatio: d->snapPositionRatio = qBound(qreal(0), value.toReal(), qreal(1)); break; + case SnapTime: d->snapTime = value.toReal(); break; + case OvershootDragResistanceFactor: d->overshootDragResistanceFactor = value.toReal(); break; + case OvershootDragDistanceFactor: d->overshootDragDistanceFactor = qBound(qreal(0), value.toReal(), qreal(1)); break; + case OvershootScrollDistanceFactor: d->overshootScrollDistanceFactor = qBound(qreal(0), value.toReal(), qreal(1)); break; + case OvershootScrollTime: d->overshootScrollTime = value.toReal(); break; + case HorizontalOvershootPolicy: d->hOvershootPolicy = value.value(); break; + case VerticalOvershootPolicy: d->vOvershootPolicy = value.value(); break; + case FrameRate: d->frameRate = value.value(); break; + case ScrollMetricCount: break; + } +} + +/*! + \enum QScrollerProperties::FrameRates + + This enum describes the available frame rates used while dragging or scrolling. + + \value Fps60 60 frames per second + \value Fps30 30 frames per second + \value Fps20 20 frames per second + \value Standard the default value is 60 frames per second (which corresponds to QAbstractAnimation). +*/ + +/*! + \enum QScrollerProperties::OvershootPolicy + + This enum describes the various modes of overshooting. + + \value OvershootWhenScrollable Overshooting is when the content is scrollable. This is the + default. + + \value OvershootAlwaysOff Overshooting is never enabled (even when the content is scrollable). + + \value OvershootAlwaysOn Overshooting is always enabled (even when the content is not + scrollable). +*/ + +/*! + \enum QScrollerProperties::ScrollMetric + + This enum contains the different scroll metric types. When not indicated otherwise the + setScrollMetric function expects a QVariant of a real value. + + See the QScroller documentation for a further explanation of the concepts behind the different + values. + + \value MousePressEventDelay This is the time a mouse press event will be delayed when starting + a flick gesture in \c{[s]}. If the gesture is triggered within that time, no mouse press or + release will be sent to the scrolled object. If it triggers after that delay the (delayed) + mouse press plus a faked release event (at global postion \c{QPoint(-QWIDGETSIZE_MAX, + -QWIDGETSIZE_MAX)} will be sent. If the gesture is canceled, then both the (delayed) mouse + press plus the real release event will be delivered. + + \value DragStartDistance This is the minimum distance the touch or mouse point needs to be + moved before the flick gesture is triggered in \c m. + + \value DragVelocitySmoothingFactor A value that describes how much new drag velocities are + included in the final scrolling velocity. This value should be in the range between \c 0 and \c + 1. Low values meaning that the last dragging velocity is not very important. + + \value AxisLockThreshold If greater than zero a scroll movement will be restricted to one axis + only if the movement is inside an angle about the axis. The threshold must be in the range \c 0 + to \c 1. + + \value ScrollingCurve The QEasingCurve used when decelerating the scrolling velocity after an + user initiated flick. Please note that this is the easing curve for the positions, \bold{not} + the velocity: the default is QEasingCurve::OutQuad, which results is a linear decrease in + velocity (1st derivative) and a constant deceleration (2nd derivative). + + \value DecelerationFactor This factor influences how long it takes the scroller to decelerate + to 0 velocity. The actual value heavily depends on the chosen ScrollingCurve, but for most + types the value should be in the range from \c 0.1 to \c 2.0 + + \value MinimumVelocity The minimum velocity that is needed after ending the touch or releasing + the mouse to start scrolling in \c{m/s}. + + \value MaximumVelocity This is the maximum velocity that can be reached in \c{m/s}. + + \value MaximumClickThroughVelocity This is the maximum allowed scroll speed for a click-through + in \c{m/s}. This means that a click on a currently (slowly) scrolling object will not only stop + the scrolling but the click event will also be delivered to the UI control - this is very + useful when using exponential-type scrolling curves. + + \value AcceleratingFlickMaximumTime This is the maximum time in \c seconds that a flick gesture + can take to be recognized as an accelerating flick. If set to zero no such gesture will be + detected. An "accelerating flick" is a flick gesture executed on an already scrolling object. + In such cases the scrolling speed is multiplied by AcceleratingFlickSpeedupFactor in order to + accelerate it. + + \value AcceleratingFlickSpeedupFactor The current speed will be multiplied by this number if an + accelerating flick is detected. Should be \c{> 1}. + + \value SnapPositionRatio This is the distance that the user must drag the area beween two snap + points in order to snap it to the next position. e.g. \c{0.33} means that the scroll must only + reach one third of the distance between two snap points to snap to the next one. The ratio must + be in the range \c 0 to \c 1. + + \value SnapTime This is the time factor for the scrolling curve. A lower value means that the + scrolling will take longer. The scrolling distance is independet of this value. + + \value OvershootDragResistanceFactor This value is the factor between the mouse dragging and + the actual scroll area movement (during overshoot). The factor must be in the range \c 0 to \c + 1. + + \value OvershootDragDistanceFactor This is the maximum distance for overshoot movements while + dragging. The actual overshoot distance will be calculated by multiplying this value with the + viewport size of the scrolled object. The factor must be in the range \c 0 to \c 1. + + \value OvershootScrollDistanceFactor This is the maximum distance for overshoot movements while + scrolling. The actual overshoot distance will be calculated by multiplying this value with the + viewport size of the scrolled object. The factor must be in the range \c 0 to \c 1. + + \value OvershootScrollTime This is the time in \c seconds that will be used to play the + complete overshoot animation. + + \value HorizontalOvershootPolicy This is the horizontal overshooting policy (see OvershootPolicy). + + \value VerticalOvershootPolicy This is the horizontal overshooting policy (see OvershootPolicy). + + \value FrameRate This is the frame rate which should be used while dragging or scrolling. + QScroller uses a QAbstractAnimation timer internally to sync all scrolling operations to other + animations that might be active at the same time. If the Standard value of 60 frames per + second is too fast for your use case, you can lower the frames per second with this setting + (while still being in-sync with QAbstractAnimation). Please note that only the values of the + FrameRates enum are allowed here. + + \value ScrollMetricCount This is just used when enumerating the metrics. It is always the last + entry. +*/ + +QT_END_NAMESPACE diff --git a/src/gui/util/qscrollerproperties.h b/src/gui/util/qscrollerproperties.h new file mode 100644 index 0000000..5284876 --- /dev/null +++ b/src/gui/util/qscrollerproperties.h @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef QSCROLLERPROPERTIES_H +#define QSCROLLERPROPERTIES_H + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QScroller; +class QScrollerPrivate; +class QScrollerPropertiesPrivate; + +class Q_GUI_EXPORT QScrollerProperties +{ +public: + QScrollerProperties(); + QScrollerProperties(const QScrollerProperties &sp); + QScrollerProperties &operator=(const QScrollerProperties &sp); + virtual ~QScrollerProperties(); + + bool operator==(const QScrollerProperties &sp) const; + bool operator!=(const QScrollerProperties &sp) const; + + static void setDefaultScrollerProperties(const QScrollerProperties &sp); + static void unsetDefaultScrollerProperties(); + + enum OvershootPolicy + { + OvershootWhenScrollable, + OvershootAlwaysOff, + OvershootAlwaysOn + }; + + enum FrameRates { + Standard, + Fps60, + Fps30, + Fps20 + }; + + enum ScrollMetric + { + MousePressEventDelay, // qreal [s] + DragStartDistance, // qreal [m] + DragVelocitySmoothingFactor, // qreal [0..1/s] (complex calculation involving time) v = v_new* DASF + v_old * (1-DASF) + AxisLockThreshold, // qreal [0..1] atan(|min(dx,dy)|/|max(dx,dy)|) + + ScrollingCurve, // QEasingCurve + DecelerationFactor, // slope of the curve + + MinimumVelocity, // qreal [m/s] + MaximumVelocity, // qreal [m/s] + MaximumClickThroughVelocity, // qreal [m/s] + + AcceleratingFlickMaximumTime, // qreal [s] + AcceleratingFlickSpeedupFactor, // qreal [1..] + + SnapPositionRatio, // qreal [0..1] + SnapTime, // qreal [s] + + OvershootDragResistanceFactor, // qreal [0..1] + OvershootDragDistanceFactor, // qreal [0..1] + OvershootScrollDistanceFactor, // qreal [0..1] + OvershootScrollTime, // qreal [s] + + HorizontalOvershootPolicy, // enum OvershootPolicy + VerticalOvershootPolicy, // enum OvershootPolicy + FrameRate, // enum FrameRates + + ScrollMetricCount + }; + + QVariant scrollMetric(ScrollMetric metric) const; + void setScrollMetric(ScrollMetric metric, const QVariant &value); + +protected: + QScopedPointer d; + +private: + QScrollerProperties(QScrollerPropertiesPrivate &dd); + + friend class QScrollerPropertiesPrivate; + friend class QScroller; + friend class QScrollerPrivate; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QScrollerProperties::OvershootPolicy); +Q_DECLARE_METATYPE(QScrollerProperties::FrameRates); + +QT_END_HEADER + +#endif // QSCROLLERPROPERTIES_H diff --git a/src/gui/util/qscrollerproperties_p.h b/src/gui/util/qscrollerproperties_p.h new file mode 100644 index 0000000..093f615 --- /dev/null +++ b/src/gui/util/qscrollerproperties_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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$ +** +****************************************************************************/ + +#ifndef QSCROLLERPROPERTIES_P_H +#define QSCROLLERPROPERTIES_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 +#include +#include + +QT_BEGIN_NAMESPACE + +class QScrollerPropertiesPrivate +{ +public: + static QScrollerPropertiesPrivate *defaults(); + + bool operator==(const QScrollerPropertiesPrivate &) const; + + qreal mousePressEventDelay; + qreal dragStartDistance; + qreal dragVelocitySmoothingFactor; + qreal axisLockThreshold; + QEasingCurve scrollingCurve; + qreal decelerationFactor; + qreal minimumVelocity; + qreal maximumVelocity; + qreal maximumClickThroughVelocity; + qreal acceleratingFlickMaximumTime; + qreal acceleratingFlickSpeedupFactor; + qreal snapPositionRatio; + qreal snapTime; + qreal overshootDragResistanceFactor; + qreal overshootDragDistanceFactor; + qreal overshootScrollDistanceFactor; + qreal overshootScrollTime; + QScrollerProperties::OvershootPolicy hOvershootPolicy; + QScrollerProperties::OvershootPolicy vOvershootPolicy; + QScrollerProperties::FrameRates frameRate; +}; + +QT_END_NAMESPACE + +#endif // QSCROLLERPROPERTIES_P_H + diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri index f125f82..2814a2d 100644 --- a/src/gui/util/util.pri +++ b/src/gui/util/util.pri @@ -6,6 +6,11 @@ HEADERS += \ util/qcompleter_p.h \ util/qdesktopservices.h \ util/qsystemtrayicon_p.h \ + util/qscroller.h \ + util/qscroller_p.h \ + util/qscrollerproperties.h \ + util/qscrollerproperties_p.h \ + util/qflickgesture_p.h \ util/qundogroup.h \ util/qundostack.h \ util/qundostack_p.h \ @@ -15,6 +20,9 @@ SOURCES += \ util/qsystemtrayicon.cpp \ util/qcompleter.cpp \ util/qdesktopservices.cpp \ + util/qscroller.cpp \ + util/qscrollerproperties.cpp \ + util/qflickgesture.cpp \ util/qundogroup.cpp \ util/qundostack.cpp \ util/qundoview.cpp @@ -57,3 +65,7 @@ symbian { DEFINES += USE_SCHEMEHANDLER } } + +macx { + OBJECTIVE_SOURCES += util/qscroller_mac.mm +} diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 30ce23b..13942ea 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -53,6 +53,8 @@ #include "qpainter.h" #include "qmargins.h" +#include + #include "qabstractscrollarea_p.h" #include @@ -62,6 +64,10 @@ #include #include #endif +#ifdef Q_WS_WIN +# include +# include +#endif QT_BEGIN_NAMESPACE @@ -295,9 +301,14 @@ void QAbstractScrollAreaPrivate::init() q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); layoutChildren(); #ifndef Q_WS_MAC -#ifndef QT_NO_GESTURES +# ifndef QT_NO_GESTURES viewport->grabGesture(Qt::PanGesture); +# endif #endif +#ifdef Q_WS_MAEMO_5 +# ifndef QT_NO_GESTURES + // viewport->grabGesture(Qt::TouchFlickGesture); +# endif #endif } @@ -552,6 +563,11 @@ void QAbstractScrollArea::setViewport(QWidget *widget) d->viewport->grabGesture(Qt::PanGesture); #endif #endif +#ifdef Q_WS_MAEMO_5 +#ifndef QT_NO_GESTURES +// d->viewport->grabGesture(Qt::TouchFlickGesture); +#endif +#endif d->layoutChildren(); if (isVisible()) d->viewport->show(); @@ -986,6 +1002,66 @@ bool QAbstractScrollArea::event(QEvent *e) return false; } #endif // QT_NO_GESTURES + case QEvent::ScrollPrepare: + { + QScrollPrepareEvent *se = static_cast(e); + if( d->canStartScrollingAt(se->startPos().toPoint()) ) { + QScrollBar *hBar = horizontalScrollBar(); + QScrollBar *vBar = verticalScrollBar(); + + se->setViewportSize( QSizeF(viewport()->size()) ); + se->setContentPosRange( QRectF(0, 0, hBar->maximum(), vBar->maximum()) ); + se->setContentPos( QPointF(hBar->value(), vBar->value()) ); + se->accept(); + return true; + } + return false; + } + case QEvent::Scroll: + { + QScrollEvent *se = static_cast(e); + + QScrollBar *hBar = horizontalScrollBar(); + QScrollBar *vBar = verticalScrollBar(); + hBar->setValue(se->contentPos().x()); + vBar->setValue(se->contentPos().y()); + +#ifdef Q_WS_WIN + typedef BOOL (*PtrBeginPanningFeedback)(HWND); + typedef BOOL (*PtrUpdatePanningFeedback)(HWND, LONG, LONG, BOOL); + typedef BOOL (*PtrEndPanningFeedback)(HWND, BOOL); + + static PtrBeginPanningFeedback ptrBeginPanningFeedback = 0; + static PtrUpdatePanningFeedback ptrUpdatePanningFeedback = 0; + static PtrEndPanningFeedback ptrEndPanningFeedback = 0; + + if (!ptrBeginPanningFeedback) + ptrBeginPanningFeedback = (PtrBeginPanningFeedback) QLibrary::resolve(QLatin1String("UxTheme"), "BeginPanningFeedback"); + if (!ptrUpdatePanningFeedback) + ptrUpdatePanningFeedback = (PtrUpdatePanningFeedback) QLibrary::resolve(QLatin1String("UxTheme"), "UpdatePanningFeedback"); + if (!ptrEndPanningFeedback) + ptrEndPanningFeedback = (PtrEndPanningFeedback) QLibrary::resolve(QLatin1String("UxTheme"), "EndPanningFeedback"); + + if (ptrBeginPanningFeedback && ptrUpdatePanningFeedback && ptrEndPanningFeedback) { + WId wid = window()->winId(); + + if (!se->overshootDistance().isNull() && d->overshoot.isNull()) + ptrBeginPanningFeedback(wid); + if (!se->overshootDistance().isNull()) + ptrUpdatePanningFeedback(wid, -se->overshootDistance().x(), -se->overshootDistance().y(), false); + if (se->overshootDistance().isNull() && !d->overshoot.isNull()) + ptrEndPanningFeedback(wid, true); + } else +#endif + { + QPoint delta = d->overshoot - se->overshootDistance().toPoint(); + if (!delta.isNull()) + viewport()->move(viewport()->pos() + delta); + } + d->overshoot = se->overshootDistance().toPoint(); + + return true; + } case QEvent::StyleChange: case QEvent::LayoutDirectionChange: case QEvent::ApplicationLayoutDirectionChange: @@ -1047,6 +1123,9 @@ bool QAbstractScrollArea::viewportEvent(QEvent *e) case QEvent::GestureOverride: return event(e); #endif + case QEvent::ScrollPrepare: + case QEvent::Scroll: + return event(e); default: break; } @@ -1303,6 +1382,30 @@ void QAbstractScrollArea::scrollContentsBy(int, int) viewport()->update(); } +bool QAbstractScrollAreaPrivate::canStartScrollingAt( const QPoint &startPos ) +{ + Q_Q(QAbstractScrollArea); + + // don't start scrolling when a drag mode has been set. + // don't start scrolling on a movable item. + if (QGraphicsView *view = qobject_cast(q)) { + if (view->dragMode() != QGraphicsView::NoDrag) + return false; + + QGraphicsItem *childItem = view->itemAt(startPos); + + if (childItem && (childItem->flags() & QGraphicsItem::ItemIsMovable)) + return false; + } + + // don't start scrolling on a QAbstractSlider + if (qobject_cast(q->viewport()->childAt(startPos))) { + return false; + } + + return true; +} + void QAbstractScrollAreaPrivate::_q_hslide(int x) { Q_Q(QAbstractScrollArea); diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h index 9a0d66f..8dbb3e4 100644 --- a/src/gui/widgets/qabstractscrollarea_p.h +++ b/src/gui/widgets/qabstractscrollarea_p.h @@ -84,11 +84,13 @@ public: int left, top, right, bottom; // viewport margin int xoffset, yoffset; + QPoint overshoot; void init(); void layoutChildren(); // ### Fix for 4.4, talk to Bjoern E or Girish. virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {} + bool canStartScrollingAt( const QPoint &startPos ); void _q_hslide(int); void _q_vslide(int); diff --git a/tests/auto/gui.pro b/tests/auto/gui.pro index c94272c..48b8cec 100644 --- a/tests/auto/gui.pro +++ b/tests/auto/gui.pro @@ -146,6 +146,7 @@ SUBDIRS=\ qregion \ qscrollarea \ qscrollbar \ + qscroller \ qsharedpointer_and_qwidget \ qshortcut \ qsidebar \ diff --git a/tests/auto/qscroller/qscroller.pro b/tests/auto/qscroller/qscroller.pro new file mode 100644 index 0000000..845dcb9 --- /dev/null +++ b/tests/auto/qscroller/qscroller.pro @@ -0,0 +1,3 @@ +load(qttest_p4) + +SOURCES += tst_qscroller.cpp diff --git a/tests/auto/qscroller/tst_qscroller.cpp b/tests/auto/qscroller/tst_qscroller.cpp new file mode 100644 index 0000000..61d3980 --- /dev/null +++ b/tests/auto/qscroller/tst_qscroller.cpp @@ -0,0 +1,529 @@ +/**************************************************************************** +** +** 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 $MODULE$ of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 +#include +// #include + +class tst_QScrollerWidget : public QWidget +{ +public: + tst_QScrollerWidget() + : QWidget() + { + reset(); + } + + void reset() + { + receivedPrepare = false; + receivedScroll = false; + receivedFirst = false; + receivedLast = false; + receivedOvershoot = false; + } + + bool event(QEvent *e) + { + switch (e->type()) { + case QEvent::Gesture: + e->setAccepted(false); // better reject the event or QGestureManager will make trouble + return false; + + case QEvent::ScrollPrepare: + { + receivedPrepare = true; + QScrollPrepareEvent *se = static_cast(e); + se->setViewportSize(QSizeF(100,100)); + se->setContentPosRange(scrollArea); + se->setContentPos(scrollPosition); + se->accept(); + return true; + } + + case QEvent::Scroll: + { + receivedScroll = true; + QScrollEvent *se = static_cast(e); + // qDebug() << "Scroll for"<scrollPos()<<"ov"<overshoot()<<"first"<isFirst()<<"last"<isLast(); + + if (se->scrollState() == QScrollEvent::ScrollStarted) + receivedFirst = true; + if (se->scrollState() == QScrollEvent::ScrollFinished) + receivedLast = true; + + currentPos = se->contentPos(); + overshoot = se->overshootDistance(); + if (!qFuzzyCompare( overshoot.x() + 1.0, 1.0 ) || + !qFuzzyCompare( overshoot.y() + 1.0, 1.0 )) + receivedOvershoot = true; + return true; + } + + default: + return QObject::event(e); + } + } + + + QRectF scrollArea; + QPointF scrollPosition; + + bool receivedPrepare; + bool receivedScroll; + bool receivedFirst; + bool receivedLast; + bool receivedOvershoot; + + QPointF currentPos; + QPointF overshoot; +}; + + +class tst_QScroller : public QObject +{ + Q_OBJECT +public: + tst_QScroller() { } + ~tst_QScroller() { } + +private: + void kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd); + void kineticScrollNoTest( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd); + +private slots: + void staticScrollers(); + void scrollerProperties(); + void scrollTo(); + void scroll(); + void overshoot(); +}; + +/*! \internal + Generates touchBegin, touchUpdate and touchEnd events to trigger scrolling. + Tests some in between states but does not wait until scrolling is finished. +*/ +void tst_QScroller::kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd) +{ + sw->scrollPosition = from; + sw->currentPos= from; + + QScroller *s1 = QScroller::scroller(sw); + QCOMPARE( s1->state(), QScroller::Inactive ); + + QScrollerProperties sp1 = QScroller::scroller(sw)->scrollerProperties(); + int fps = 60; + + QTouchEvent::TouchPoint rawTouchPoint; + rawTouchPoint.setId(0); + + // send the touch begin event + QTouchEvent::TouchPoint touchPoint(0); + touchPoint.setState(Qt::TouchPointPressed); + touchPoint.setPos(touchStart); + touchPoint.setScenePos(touchStart); + touchPoint.setScreenPos(touchStart); + QTouchEvent touchEvent1(QEvent::TouchBegin, + QTouchEvent::TouchScreen, + Qt::NoModifier, + Qt::TouchPointPressed, + (QList() << touchPoint)); + QApplication::sendEvent(sw, &touchEvent1); + + QCOMPARE( s1->state(), QScroller::Pressed ); + + // send the touch update far enough to trigger a scroll + QTest::qWait(200); // we need to wait a little or else the speed would be infinite. now we have around 500 pixel per second. + touchPoint.setPos(touchUpdate); + touchPoint.setScenePos(touchUpdate); + touchPoint.setScreenPos(touchUpdate); + QTouchEvent touchEvent2(QEvent::TouchUpdate, + QTouchEvent::TouchScreen, + Qt::NoModifier, + Qt::TouchPointMoved, + (QList() << touchPoint)); + QApplication::sendEvent(sw, &touchEvent2); + + QCOMPARE( s1->state(), QScroller::Dragging ); + QCOMPARE( sw->receivedPrepare, true ); + + + QTest::qWait(1000 / fps * 2); // wait until the first scroll move + QCOMPARE( sw->receivedFirst, true ); + QCOMPARE( sw->receivedScroll, true ); + QCOMPARE( sw->receivedOvershoot, false ); + + // note that the scrolling goes in a different direction than the mouse move + QPoint calculatedPos = from.toPoint() - touchUpdate - touchStart; + QVERIFY(qAbs(sw->currentPos.x() - calculatedPos.x()) < 1.0); + QVERIFY(qAbs(sw->currentPos.y() - calculatedPos.y()) < 1.0); + + // send the touch end + touchPoint.setPos(touchEnd); + touchPoint.setScenePos(touchEnd); + touchPoint.setScreenPos(touchEnd); + QTouchEvent touchEvent5(QEvent::TouchEnd, + QTouchEvent::TouchScreen, + Qt::NoModifier, + Qt::TouchPointReleased, + (QList() << touchPoint)); + QApplication::sendEvent(sw, &touchEvent5); +} + +/*! \internal + Generates touchBegin, touchUpdate and touchEnd events to trigger scrolling. + This function does not have any in between tests, it does not expect the scroller to actually scroll. +*/ +void tst_QScroller::kineticScrollNoTest( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd) +{ + sw->scrollPosition = from; + sw->currentPos = from; + + QScroller *s1 = QScroller::scroller(sw); + QCOMPARE( s1->state(), QScroller::Inactive ); + + QScrollerProperties sp1 = s1->scrollerProperties(); + int fps = 60; + + QTouchEvent::TouchPoint rawTouchPoint; + rawTouchPoint.setId(0); + + // send the touch begin event + QTouchEvent::TouchPoint touchPoint(0); + touchPoint.setState(Qt::TouchPointPressed); + touchPoint.setPos(touchStart); + touchPoint.setScenePos(touchStart); + touchPoint.setScreenPos(touchStart); + QTouchEvent touchEvent1(QEvent::TouchBegin, + QTouchEvent::TouchScreen, + Qt::NoModifier, + Qt::TouchPointPressed, + (QList() << touchPoint)); + QApplication::sendEvent(sw, &touchEvent1); + + // send the touch update far enough to trigger a scroll + QTest::qWait(200); // we need to wait a little or else the speed would be infinite. now we have around 500 pixel per second. + touchPoint.setPos(touchUpdate); + touchPoint.setScenePos(touchUpdate); + touchPoint.setScreenPos(touchUpdate); + QTouchEvent touchEvent2(QEvent::TouchUpdate, + QTouchEvent::TouchScreen, + Qt::NoModifier, + Qt::TouchPointMoved, + (QList() << touchPoint)); + QApplication::sendEvent(sw, &touchEvent2); + + QTest::qWait(1000 / fps * 2); // wait until the first scroll move + + // send the touch end + touchPoint.setPos(touchEnd); + touchPoint.setScenePos(touchEnd); + touchPoint.setScreenPos(touchEnd); + QTouchEvent touchEvent5(QEvent::TouchEnd, + QTouchEvent::TouchScreen, + Qt::NoModifier, + Qt::TouchPointReleased, + (QList() << touchPoint)); + QApplication::sendEvent(sw, &touchEvent5); +} + + +void tst_QScroller::staticScrollers() +{ + // scrollers + { + QObject *o1 = new QObject(this); + QObject *o2 = new QObject(this); + + // get scroller for object + QScroller *s1 = QScroller::scroller(o1); + QScroller *s2 = QScroller::scroller(o2); + + QVERIFY(s1); + QVERIFY(s2); + QVERIFY(s1 != s2); + + QVERIFY(!QScroller::scroller(static_cast(0))); + QCOMPARE(QScroller::scroller(o1), s1); + + delete o1; + delete o2; + } + + // the same for properties + { + QObject *o1 = new QObject(this); + QObject *o2 = new QObject(this); + + // get scroller for object + QScrollerProperties sp1 = QScroller::scroller(o1)->scrollerProperties(); + QScrollerProperties sp2 = QScroller::scroller(o2)->scrollerProperties(); + + // default properties should be the same + QVERIFY(sp1 == sp2); + + QCOMPARE(QScroller::scroller(o1)->scrollerProperties(), sp1); + + delete o1; + delete o2; + } +} + +void tst_QScroller::scrollerProperties() +{ + QObject *o1 = new QObject(this); + QScrollerProperties sp1 = QScroller::scroller(o1)->scrollerProperties(); + + QScrollerProperties::ScrollMetric metrics[] = + { + QScrollerProperties::MousePressEventDelay, // qreal [s] + QScrollerProperties::DragStartDistance, // qreal [m] + QScrollerProperties::DragVelocitySmoothingFactor, // qreal [0..1/s] (complex calculation involving time) v = v_new* DASF + v_old * (1-DASF) + QScrollerProperties::AxisLockThreshold, // qreal [0..1] atan(|min(dx,dy)|/|max(dx,dy)|) + + QScrollerProperties::DecelerationFactor, // slope of the curve + + QScrollerProperties::MinimumVelocity, // qreal [m/s] + QScrollerProperties::MaximumVelocity, // qreal [m/s] + QScrollerProperties::MaximumClickThroughVelocity, // qreal [m/s] + + QScrollerProperties::AcceleratingFlickMaximumTime, // qreal [s] + QScrollerProperties::AcceleratingFlickSpeedupFactor, // qreal [1..] + + QScrollerProperties::SnapPositionRatio, // qreal [0..1] + QScrollerProperties::SnapTime, // qreal [s] + + QScrollerProperties::OvershootDragResistanceFactor, // qreal [0..1] + QScrollerProperties::OvershootDragDistanceFactor, // qreal [0..1] + QScrollerProperties::OvershootScrollDistanceFactor, // qreal [0..1] + QScrollerProperties::OvershootScrollTime, // qreal [s] + }; + + for (unsigned int i = 0; i < sizeof(metrics) / sizeof(metrics[0]); i++) { + sp1.setScrollMetric(metrics[i], 0.9); + QCOMPARE(sp1.scrollMetric(metrics[i]).toDouble(), 0.9); + } + sp1.setScrollMetric(QScrollerProperties::ScrollingCurve, QEasingCurve(QEasingCurve::OutQuart)); + QCOMPARE(sp1.scrollMetric(QScrollerProperties::ScrollingCurve).toEasingCurve().type(), QEasingCurve::OutQuart); + + sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff)); + QCOMPARE(sp1.scrollMetric(QScrollerProperties::HorizontalOvershootPolicy).value(), QScrollerProperties::OvershootAlwaysOff); + + sp1.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn)); + QCOMPARE(sp1.scrollMetric(QScrollerProperties::VerticalOvershootPolicy).value(), QScrollerProperties::OvershootAlwaysOn); + + sp1.setScrollMetric(QScrollerProperties::FrameRate, QVariant::fromValue(QScrollerProperties::Fps20)); + QCOMPARE(sp1.scrollMetric(QScrollerProperties::FrameRate).value(), QScrollerProperties::Fps20); +} + +void tst_QScroller::scrollTo() +{ + { + tst_QScrollerWidget *sw = new tst_QScrollerWidget(); + sw->scrollArea = QRectF( 0, 0, 1000, 1000 ); + sw->scrollPosition = QPointF( 500, 500 ); + + QScroller *s1 = QScroller::scroller(sw); + QCOMPARE( s1->state(), QScroller::Inactive ); + + // a normal scroll + s1->scrollTo(QPointF(100,100), 100); + QTest::qWait(200); + + QCOMPARE( sw->receivedPrepare, true ); + QCOMPARE( sw->receivedScroll, true ); + QCOMPARE( sw->receivedFirst, true ); + QCOMPARE( sw->receivedLast, true ); + QCOMPARE( sw->receivedOvershoot, false ); + QVERIFY(qFuzzyCompare( sw->currentPos.x(), 100 )); + QVERIFY(qFuzzyCompare( sw->currentPos.y(), 100 )); + + delete sw; + } +} + +void tst_QScroller::scroll() +{ +#ifndef QT_NO_GESTURES + + // -- good case. normal scroll + + tst_QScrollerWidget *sw = new tst_QScrollerWidget(); + sw->scrollArea = QRectF(0, 0, 1000, 1000); + QScroller::grabGesture(sw, QScroller::TouchGesture); + sw->setGeometry(100, 100, 400, 300); + + QScroller *s1 = QScroller::scroller(sw); + kineticScroll(sw, QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200)); + // now we should be scrolling + QCOMPARE( s1->state(), QScroller::Scrolling ); + + // wait until finished, check that no further first scroll is send + sw->receivedFirst = false; + sw->receivedScroll = false; + while (s1->state() == QScroller::Scrolling) + QTest::qWait(100); + + QCOMPARE( sw->receivedFirst, false ); + QCOMPARE( sw->receivedScroll, true ); + QCOMPARE( sw->receivedLast, true ); + QVERIFY(sw->currentPos.x() < 400); + QVERIFY(sw->currentPos.y() < 400); + + // -- try to scroll when nothing to scroll + + sw->reset(); + sw->scrollArea = QRectF(0, 0, 0, 1000); + kineticScrollNoTest(sw, QPointF(0, 500), QPoint(0, 0), QPoint(100, 0), QPoint(200, 0)); + + while (s1->state() != QScroller::Inactive) + QTest::qWait(20); + + QCOMPARE(sw->currentPos.x(), 0.0); + QCOMPARE(sw->currentPos.y(), 500.0); + + delete sw; +#endif +} + +void tst_QScroller::overshoot() +{ +#ifndef QT_NO_GESTURES + tst_QScrollerWidget *sw = new tst_QScrollerWidget(); + sw->scrollArea = QRectF(0, 0, 1000, 1000); + QScroller::grabGesture(sw, QScroller::TouchGesture); + sw->setGeometry(100, 100, 400, 300); + + QScroller *s1 = QScroller::scroller(sw); + QScrollerProperties sp1 = s1->scrollerProperties(); + + sp1.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor, 0.5); + sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.2); + sp1.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.2); + + // -- try to scroll with overshoot (when scrollable good case) + + sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable)); + s1->setScrollerProperties(sp1); + kineticScrollNoTest(sw, QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); + + while (s1->state() != QScroller::Inactive) + QTest::qWait(20); + + //qDebug() << "Overshoot fuzzy: "<currentPos; + QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); + QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); + QCOMPARE( sw->receivedOvershoot, true ); + + // -- try to scroll with overshoot (when scrollable bad case) + sw->reset(); + sw->scrollArea = QRectF(0, 0, 0, 1000); + + sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable)); + s1->setScrollerProperties(sp1); + kineticScrollNoTest(sw, QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); + + while (s1->state() != QScroller::Inactive) + QTest::qWait(20); + + //qDebug() << "Overshoot fuzzy: "<currentPos; + QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); + QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); + QCOMPARE( sw->receivedOvershoot, false ); + + // -- try to scroll with overshoot (always on) + sw->reset(); + sw->scrollArea = QRectF(0, 0, 0, 1000); + + sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn)); + s1->setScrollerProperties(sp1); + kineticScrollNoTest(sw, QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); + + while (s1->state() != QScroller::Inactive) + QTest::qWait(20); + + //qDebug() << "Overshoot fuzzy: "<currentPos; + + QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); + QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); + QCOMPARE( sw->receivedOvershoot, true ); + + // -- try to scroll with overshoot (always off) + sw->reset(); + sw->scrollArea = QRectF(0, 0, 1000, 1000); + + sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff)); + s1->setScrollerProperties(sp1); + kineticScrollNoTest(sw, QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); + + while (s1->state() != QScroller::Inactive) + QTest::qWait(20); + + QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); + QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); + QCOMPARE( sw->receivedOvershoot, false ); + + // -- try to scroll with overshoot (always on but max overshoot = 0) + sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.0); + sp1.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.0); + sw->reset(); + sw->scrollArea = QRectF(0, 0, 1000, 1000); + + sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn)); + s1->setScrollerProperties(sp1); + kineticScrollNoTest(sw, QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); + + while (s1->state() != QScroller::Inactive) + QTest::qWait(20); + + QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); + QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); + QCOMPARE( sw->receivedOvershoot, false ); + + + delete sw; +#endif +} + + +QTEST_MAIN(tst_QScroller) + +#include "tst_qscroller.moc" diff --git a/tools/qml/texteditautoresizer_maemo5.h b/tools/qml/texteditautoresizer_maemo5.h index bb5567a..fd35ca5 100644 --- a/tools/qml/texteditautoresizer_maemo5.h +++ b/tools/qml/texteditautoresizer_maemo5.h @@ -41,7 +41,7 @@ #include #include -#include +#include #include #include @@ -102,11 +102,11 @@ void TextEditAutoResizer::textEditChanged() QPoint scrollto = area->widget()->mapFrom(edit, cursor.center()); QPoint margin(10 + cursor.width(), 2 * cursor.height()); - if (QAbstractKineticScroller *scroller = area->property("kineticScroller").value()) { - scroller->ensureVisible(scrollto, margin.x(), margin.y()); - } else { - area->ensureVisible(scrollto.x(), scrollto.y(), margin.x(), margin.y()); - } +#ifdef Q_WS_MAEMO_5 + QScroller::scroller(area)->ensureVisible(scrollto, margin.x(), margin.y()); +#else + area->ensureVisible(scrollto.x(), scrollto.y(), margin.x(), margin.y()); +#endif } } -- cgit v0.12 From 2770b1277744bb676e96e4ae8c89acd645ec895d Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Thu, 2 Dec 2010 01:12:33 +0100 Subject: Fix code style issues in QScroller --- src/gui/util/qscroller.cpp | 4 ++-- src/gui/util/qscrollerproperties.cpp | 4 ++-- src/gui/widgets/qabstractscrollarea.cpp | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/gui/util/qscroller.cpp b/src/gui/util/qscroller.cpp index d6b7aaf..5aa2b71 100644 --- a/src/gui/util/qscroller.cpp +++ b/src/gui/util/qscroller.cpp @@ -422,7 +422,7 @@ Qt::GestureType QScroller::grabGesture(QObject *target, ScrollerGestureType scro if (scrollGestureType == TouchGesture) widget->setAttribute(Qt::WA_AcceptTouchEvents); - } else if(QGraphicsObject *go = qobject_cast(target)) { + } else if (QGraphicsObject *go = qobject_cast(target)) { if (scrollGestureType == TouchGesture) go->setAcceptTouchEvents(true); go->grabGesture(sp->recognizerType); @@ -460,7 +460,7 @@ void QScroller::ungrabGesture(QObject *target) QWidget *widget = static_cast(target); widget->ungrabGesture(sp->recognizerType); - } else if(QGraphicsObject *go = qobject_cast(target)) { + } else if (QGraphicsObject *go = qobject_cast(target)) { go->ungrabGesture(sp->recognizerType); } diff --git a/src/gui/util/qscrollerproperties.cpp b/src/gui/util/qscrollerproperties.cpp index 4fba489..d21f131 100644 --- a/src/gui/util/qscrollerproperties.cpp +++ b/src/gui/util/qscrollerproperties.cpp @@ -262,7 +262,7 @@ QVariant QScrollerProperties::scrollMetric(ScrollMetric metric) const case FrameRate: return QVariant::fromValue(d->frameRate); case ScrollMetricCount: break; } - return QVariant(); + return QVariant(); } /*! @@ -404,7 +404,7 @@ void QScrollerProperties::setScrollMetric(ScrollMetric metric, const QVariant &v \value VerticalOvershootPolicy This is the horizontal overshooting policy (see OvershootPolicy). - \value FrameRate This is the frame rate which should be used while dragging or scrolling. + \value FrameRate This is the frame rate which should be used while dragging or scrolling. QScroller uses a QAbstractAnimation timer internally to sync all scrolling operations to other animations that might be active at the same time. If the Standard value of 60 frames per second is too fast for your use case, you can lower the frames per second with this setting diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 13942ea..030f544 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -1005,13 +1005,13 @@ bool QAbstractScrollArea::event(QEvent *e) case QEvent::ScrollPrepare: { QScrollPrepareEvent *se = static_cast(e); - if( d->canStartScrollingAt(se->startPos().toPoint()) ) { + if (d->canStartScrollingAt(se->startPos().toPoint())) { QScrollBar *hBar = horizontalScrollBar(); QScrollBar *vBar = verticalScrollBar(); - se->setViewportSize( QSizeF(viewport()->size()) ); - se->setContentPosRange( QRectF(0, 0, hBar->maximum(), vBar->maximum()) ); - se->setContentPos( QPointF(hBar->value(), vBar->value()) ); + se->setViewportSize(QSizeF(viewport()->size())); + se->setContentPosRange(QRectF(0, 0, hBar->maximum(), vBar->maximum())); + se->setContentPos(QPointF(hBar->value(), vBar->value())); se->accept(); return true; } -- cgit v0.12 From 03ff62841c5dae85fde40982a65980a91c5f3109 Mon Sep 17 00:00:00 2001 From: Christopher Ham Date: Thu, 2 Dec 2010 13:12:18 +1000 Subject: Rectangle should not paint with negative width or height Task-number: QTBUG-15250 Reviewed-by: Martin Jones --- src/declarative/graphicsitems/qdeclarativerectangle.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativerectangle.cpp b/src/declarative/graphicsitems/qdeclarativerectangle.cpp index dedb3f7..59d1a84 100644 --- a/src/declarative/graphicsitems/qdeclarativerectangle.cpp +++ b/src/declarative/graphicsitems/qdeclarativerectangle.cpp @@ -470,6 +470,8 @@ void QDeclarativeRectangle::generateBorderedRect() void QDeclarativeRectangle::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) { Q_D(QDeclarativeRectangle); + if (width() <= 0 || height() <= 0) + return; if (d->radius > 0 || (d->pen && d->pen->isValid()) || (d->gradient && d->gradient->gradient()) ) { drawRect(*p); -- cgit v0.12 From b5a2e8bc3e49ed13d44d4273f5e65cda97c55db1 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 2 Dec 2010 13:07:29 +1000 Subject: Ensure semi-transparent rects paint correctly with radius == size/2. The margins could overlap, which caused overpainting. Ensure the margins are always <= width or height /2. Task-number: QTBUG-14657 Reviewed-by: Yann Bodson --- src/declarative/graphicsitems/qdeclarativerectangle.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativerectangle.cpp b/src/declarative/graphicsitems/qdeclarativerectangle.cpp index 59d1a84..99b36a8 100644 --- a/src/declarative/graphicsitems/qdeclarativerectangle.cpp +++ b/src/declarative/graphicsitems/qdeclarativerectangle.cpp @@ -541,6 +541,12 @@ void QDeclarativeRectangle::drawRect(QPainter &p) Q_ASSERT(d->rectImage.width() == 2*xOffset + 1); Q_ASSERT(d->rectImage.height() == 2*yOffset + 1); + // check whether we've eliminated the center completely + if (2*xOffset > width()+pw) + xOffset = (width()+pw)/2; + if (2*yOffset > height()+pw) + yOffset = (height()+pw)/2; + QMargins margins(xOffset, yOffset, xOffset, yOffset); QTileRules rules(Qt::StretchTile, Qt::StretchTile); //NOTE: even though our item may have qreal-based width and height, qDrawBorderPixmap only supports QRects -- cgit v0.12 From afbf017b8929d1215851dc43823de61fb1ffa400 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 2 Dec 2010 16:55:28 +1000 Subject: Update TextInput when echoMode changes. Task-number: QTBUG-15779 Reviewed-by: Martin Jones --- src/declarative/graphicsitems/qdeclarativetextinput.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 0deacf8..f8421a3 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -771,7 +771,7 @@ void QDeclarativeTextInput::setEchoMode(QDeclarativeTextInput::EchoMode echo) imHints &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); setInputMethodHints(imHints); d->control->setEchoMode((uint)echo); - update(); + q_textChanged(); emit echoModeChanged(echoMode()); } -- cgit v0.12 From 34f199a1267ea923df33690b50920ef3383b85c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 2 Dec 2010 08:38:49 +0100 Subject: Fix spelling in comment --- src/gui/kernel/qwidget_qpa.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp index 1f2a764..617d984 100644 --- a/src/gui/kernel/qwidget_qpa.cpp +++ b/src/gui/kernel/qwidget_qpa.cpp @@ -789,7 +789,7 @@ void QWidgetPrivate::createTLSysExtra() void QWidgetPrivate::deleteTLSysExtra() { if (extra && extra->topextra) { - //the toplevel might have a context with a "qglcontext assosiated with it. We need to + //the toplevel might have a context with a "qglcontext associated with it. We need to //delete the qglcontext before we delete the qplatformglcontext. //One unfortunate thing about this is that we potentially create a glContext just to //delete it straight afterwards. -- cgit v0.12 From d4b73604d545da4ab802f22a55fbf420f4bf5baa Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Thu, 2 Dec 2010 15:16:58 +1000 Subject: Append qml import path individually for each available drive on Symbian Task-number: QTBUG-15405 Reviewed-by: Jason Barron --- src/declarative/declarative.pro | 5 ++++- src/declarative/qml/qdeclarativeimport.cpp | 30 +++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/declarative/declarative.pro b/src/declarative/declarative.pro index 299ca06..93ad861 100644 --- a/src/declarative/declarative.pro +++ b/src/declarative/declarative.pro @@ -25,7 +25,10 @@ include(graphicsitems/graphicsitems.pri) include(qml/qml.pri) include(debugger/debugger.pri) -symbian:TARGET.UID3=0x2001E623 +symbian: { + TARGET.UID3=0x2001E623 + LIBS += -lefsrv +} DEFINES += QT_NO_OPENTYPE INCLUDEPATH += ../3rdparty/harfbuzz/src diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp index 6f5216a..acc13de 100644 --- a/src/declarative/qml/qdeclarativeimport.cpp +++ b/src/declarative/qml/qdeclarativeimport.cpp @@ -51,6 +51,10 @@ #include #include +#ifdef Q_OS_SYMBIAN +#include "private/qcore_symbian_p.h" +#endif + QT_BEGIN_NAMESPACE DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE) @@ -658,8 +662,32 @@ QDeclarativeImportDatabase::QDeclarativeImportDatabase(QDeclarativeEngine *e) // Search order is applicationDirPath(), $QML_IMPORT_PATH, QLibraryInfo::ImportsPath - addImportPath(QLibraryInfo::location(QLibraryInfo::ImportsPath)); + QString installImportsPath = QLibraryInfo::location(QLibraryInfo::ImportsPath); +#if defined(Q_OS_SYMBIAN) + // Append imports path for all available drives in Symbian + if (installImportsPath.at(1) != QChar(QLatin1Char(':'))) { + QString tempPath = installImportsPath; + if (tempPath.at(tempPath.length() - 1) != QDir::separator()) { + tempPath += QDir::separator(); + } + RFs& fs = qt_s60GetRFs(); + TPtrC tempPathPtr(reinterpret_cast (tempPath.constData())); + TFindFile finder(fs); + TInt err = finder.FindByDir(tempPathPtr, tempPathPtr); + while (err == KErrNone) { + QString foundDir(reinterpret_cast(finder.File().Ptr()), + finder.File().Length()); + foundDir = QDir(foundDir).canonicalPath(); + addImportPath(foundDir); + err = finder.Find(); + } + } else { + addImportPath(installImportsPath); + } +#else + addImportPath(installImportsPath); +#endif // env import paths QByteArray envImportPath = qgetenv("QML_IMPORT_PATH"); if (!envImportPath.isEmpty()) { -- cgit v0.12 From 02e1f4e83dc8e3c4ab957095167b3d34c51ba3c1 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Thu, 2 Dec 2010 10:01:36 +0100 Subject: Fix compile on QWS --- src/gui/util/qflickgesture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/util/qflickgesture.cpp b/src/gui/util/qflickgesture.cpp index fa04754..eb0cc8d 100644 --- a/src/gui/util/qflickgesture.cpp +++ b/src/gui/util/qflickgesture.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ #include "qgesture.h" -#include "qcoreapplication.h" +#include "qapplication.h" #include "qevent.h" #include "qwidget.h" #include "qgraphicsitem.h" -- cgit v0.12 From 8f56e42ed665b90e084239a0560fc9c9688d0c3b Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 2 Dec 2010 10:18:27 +0100 Subject: Make QtScript examples compile Assumptions were made that "#include " would pull in the necessary QtCore headers as well, but we shouldn't rely on that. --- examples/script/customclass/main.cpp | 2 ++ examples/script/helloscript/main.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/examples/script/customclass/main.cpp b/examples/script/customclass/main.cpp index cc79d6e..a9e8ba9 100644 --- a/examples/script/customclass/main.cpp +++ b/examples/script/customclass/main.cpp @@ -38,6 +38,8 @@ ** ****************************************************************************/ +#include +#include #include #include "bytearrayclass.h" diff --git a/examples/script/helloscript/main.cpp b/examples/script/helloscript/main.cpp index 3013e7c..6eac741 100644 --- a/examples/script/helloscript/main.cpp +++ b/examples/script/helloscript/main.cpp @@ -39,8 +39,11 @@ ****************************************************************************/ #include +#include #include #include +#include +#include #include //! [0] -- cgit v0.12 From 697f2f96eccaaf9feb2f6e92603e86e30e67cdb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 2 Dec 2010 11:07:59 +0100 Subject: Restore patch that got lost in merge The merge was: e50e811461b54e07184af547f62aa44b3c5bb681 The parts of these commits was lost in the manual merge: 46d2d05e3a95eefae1c72f55d57cbea4ce27d14e 8e8bae1f4faf676b6104bbf9039ad10f139fa7e8 344a4dcfe847dd778c33d1a852381672dd331409 e45c4387ae16627d61e30a58ae901d888d375aa7 And I also added a license header to qfontengine_coretext.mm Reviewed-by: paul --- src/gui/text/qfontengine_coretext.mm | 67 +++++++++++++++++++++++++++++++++-- src/gui/text/qfontengine_coretext_p.h | 2 +- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index d270e1f..dcc8329 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 "qfontengine_coretext_p.h" #include @@ -7,6 +48,8 @@ #if !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) +QT_BEGIN_NAMESPACE + QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning) : QFontEngineMulti(0) { @@ -117,6 +160,11 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay continue; Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl); + CFRange stringRange = CTRunGetStringRange(run); + UniChar endGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location + stringRange.length - 1); + bool endWithPDF = QChar::direction(endGlyph) == QChar::DirPDF; + if (endWithPDF) + glyphCount++; if (!outOBounds && outGlyphs + glyphCount - initialGlyph > *nglyphs) { outOBounds = true; @@ -129,6 +177,9 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay CTFontRef runFont = static_cast(CFDictionaryGetValue(runAttribs, NSFontAttributeName)); const uint fontIndex = (fontIndexForFont(runFont) << 24); //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont)); + if (endWithPDF) + glyphCount--; + QVarLengthArray cgglyphs(0); const CGGlyph *tmpGlyphs = CTRunGetGlyphsPtr(run); if (!tmpGlyphs) { @@ -196,6 +247,16 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay (fontDef.styleStrategy & QFont::ForceIntegerMetrics) ? QFixed::fromReal(lastGlyphAdvance.width).round() : QFixed::fromReal(lastGlyphAdvance.width); + + if (endWithPDF) { + logClusters[stringRange.location + stringRange.length - 1] = glyphCount; + outGlyphs[glyphCount] = 0xFFFF; + outAdvances_x[glyphCount] = 0; + outAdvances_y[glyphCount] = 0; + outAttributes[glyphCount].clusterStart = true; + outAttributes[glyphCount].dontPrint = true; + glyphCount++; + } } outGlyphs += glyphCount; outAttributes += glyphCount; @@ -566,7 +627,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition CGContextSetFont(ctx, cgFont); qreal pos_x = -br.x.toReal() + subPixelPosition.toReal(); - qreal pos_y = im.height()+br.y.toReal(); + qreal pos_y = im.height() + br.y.toReal() - 1; CGContextSetTextPosition(ctx, pos_x, pos_y); CGSize advance; @@ -585,7 +646,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition return im; } -QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) +QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition) { QImage im = imageForGlyph(glyph, subPixelPosition, 0, false); @@ -663,5 +724,7 @@ void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metric // ### } +QT_END_NAMESPACE + #endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h index f31c033..b4450fa 100644 --- a/src/gui/text/qfontengine_coretext_p.h +++ b/src/gui/text/qfontengine_coretext_p.h @@ -83,7 +83,7 @@ public: virtual FaceId faceId() const; virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const; virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); - virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); + virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition); virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); virtual qreal minRightBearing() const; virtual qreal minLeftBearing() const; -- cgit v0.12 From 187a42d1ee1a86e6e0ecd79f39c86d4f790bf98f Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 2 Dec 2010 14:50:02 +0200 Subject: Cleaned up sis_targets.prf Removed the unnecessary checks for the case where pkg file doesn't exist are no longer needed as we now have dependencies to pkg files and no sis creation targets are generated if pkg is not generated. Also improved documentation a bit and added the missing ok_installer_sis target generation. Reviewed-by: Janne Koskinen --- doc/src/platforms/symbian-introduction.qdoc | 9 ++++ mkspecs/features/symbian/sis_targets.prf | 84 +++++++++++++---------------- 2 files changed, 45 insertions(+), 48 deletions(-) diff --git a/doc/src/platforms/symbian-introduction.qdoc b/doc/src/platforms/symbian-introduction.qdoc index 9da94c4..cce2be3 100644 --- a/doc/src/platforms/symbian-introduction.qdoc +++ b/doc/src/platforms/symbian-introduction.qdoc @@ -144,8 +144,17 @@ Smart installer will attempt to download missing dependencies in addition to just installing the application. + Note: The application \c .sis contained in smart installer \c .sis + will be recreated and signed with same certificates as + smart installer \c .sis. + \row \o \c ok_installer_sis \o Otherwise similar to \c installer_sis target, except + the application sis will not be recreated. This is useful + when application \c .sis needs to be separately signed before + including it into smart installer \c .sis. \row \o \c unsigned_installer_sis \o Create unsigned \l{Smart Installer}{smart installer} \c .sis file for project. + Note: The application \c .sis contained in smart installer + \c .sis will also be unsigned. \row \o \c stub_sis \o Create a stub sis to allow upgradability of projects that are deployed in ROM \endtable diff --git a/mkspecs/features/symbian/sis_targets.prf b/mkspecs/features/symbian/sis_targets.prf index ad81803..024378b 100644 --- a/mkspecs/features/symbian/sis_targets.prf +++ b/mkspecs/features/symbian/sis_targets.prf @@ -33,19 +33,16 @@ equals(GENERATE_SIS_TARGETS, true) { make_cache_name = .make.cache sis_target.target = sis - sis_target.commands = $(if $(wildcard $${baseTarget}_template.pkg), \ - $(if $(wildcard $$make_cache_name), \ - $(MAKE) -f $(MAKEFILE) ok_sis MAKEFILES=$$make_cache_name \ + sis_target.commands = $(if $(wildcard $$make_cache_name), \ + $(MAKE) -f $(MAKEFILE) ok_sis MAKEFILES=$$make_cache_name \ + , \ + $(if $(QT_SIS_TARGET), \ + $(MAKE) -f $(MAKEFILE) ok_sis \ , \ - $(if $(QT_SIS_TARGET), \ - $(MAKE) -f $(MAKEFILE) ok_sis \ - , \ - $(MAKE) -f $(MAKEFILE) fail_sis_nocache \ - ) \ + $(MAKE) -f $(MAKEFILE) fail_sis_nocache \ ) \ - , \ - $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ ) + sis_target.depends += $${baseTarget}_template.pkg ok_sis_target.target = ok_sis @@ -53,19 +50,16 @@ equals(GENERATE_SIS_TARGETS, true) { $(QT_SIS_TARGET) $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE) unsigned_sis_target.target = unsigned_sis - unsigned_sis_target.commands = $(if $(wildcard $${baseTarget}_template.pkg), \ - $(if $(wildcard $$make_cache_name), \ - $(MAKE) -f $(MAKEFILE) ok_unsigned_sis MAKEFILES=$$make_cache_name \ - , \ - $(if $(QT_SIS_TARGET), \ - $(MAKE) -f $(MAKEFILE) ok_unsigned_sis \ + unsigned_sis_target.commands = $(if $(wildcard $$make_cache_name), \ + $(MAKE) -f $(MAKEFILE) ok_unsigned_sis MAKEFILES=$$make_cache_name \ , \ - $(MAKE) -f $(MAKEFILE) fail_sis_nocache \ - ) \ - ) \ - , \ - $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ - ) + $(if $(QT_SIS_TARGET), \ + $(MAKE) -f $(MAKEFILE) ok_unsigned_sis \ + , \ + $(MAKE) -f $(MAKEFILE) fail_sis_nocache \ + ) \ + ) + unsigned_sis_target.depends += $${baseTarget}_template.pkg ok_unsigned_sis_target.target = ok_unsigned_sis @@ -74,49 +68,39 @@ equals(GENERATE_SIS_TARGETS, true) { target_sis_target.target = $${baseTarget}.sis target_sis_target.commands = $(MAKE) -f $(MAKEFILE) sis + # The installer_sis target has dependency to sis target, so it will regenerate sis package. + # To create smart installer wrapper for for an existing sis package, use ok_installer_sis target directly. installer_sis_target.target = installer_sis - installer_sis_target.commands = $(if $(wildcard $${baseTarget}_installer.pkg), \ - $(MAKE) -f $(MAKEFILE) ok_installer_sis \ - , \ - $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ - ) + installer_sis_target.commands = $(MAKE) -f $(MAKEFILE) ok_installer_sis installer_sis_target.depends = $${baseTarget}_installer.pkg sis ok_installer_sis_target.target = ok_installer_sis ok_installer_sis_target.commands = createpackage $(QT_SIS_OPTIONS) $${baseTarget}_installer.pkg - \ $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE) + ok_installer_sis_target.depends = $${baseTarget}_installer.pkg unsigned_installer_sis_target.target = unsigned_installer_sis - unsigned_installer_sis_target.commands = $(if $(wildcard $${baseTarget}_installer.pkg), \ - $(MAKE) -f $(MAKEFILE) ok_unsigned_installer_sis \ - , \ - $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ - ) + unsigned_installer_sis_target.commands = $(MAKE) -f $(MAKEFILE) ok_unsigned_installer_sis unsigned_installer_sis_target.depends = $${baseTarget}_installer.pkg unsigned_sis ok_unsigned_installer_sis_target.target = ok_unsigned_installer_sis ok_unsigned_installer_sis_target.commands = createpackage $(QT_SIS_OPTIONS) -o $${baseTarget}_installer.pkg - - fail_sis_nopkg_target.target = fail_sis_nopkg - fail_sis_nopkg_target.commands = "$(error PKG file does not exist, 'sis' and 'installer_sis' target are only supported for executables or projects with DEPLOYMENT statement)" + ok_unsigned_installer_sis_target.depends = $${baseTarget}_installer.pkg fail_sis_nocache_target.target = fail_sis_nocache fail_sis_nocache_target.commands = "$(error Project has to be built or QT_SIS_TARGET environment variable has to be set before calling 'SIS' target)" stub_sis_target.target = stub_sis - stub_sis_target.commands = $(if $(wildcard $${baseTarget}_template.pkg), \ - $(if $(wildcard $$make_cache_name), \ - $(MAKE) -f $(MAKEFILE) ok_stub_sis MAKEFILES=$$make_cache_name \ + stub_sis_target.commands = $(if $(wildcard $$make_cache_name), \ + $(MAKE) -f $(MAKEFILE) ok_stub_sis MAKEFILES=$$make_cache_name \ + , \ + $(if $(QT_SIS_TARGET), \ + $(MAKE) -f $(MAKEFILE) ok_stub_sis \ , \ - $(if $(QT_SIS_TARGET), \ - $(MAKE) -f $(MAKEFILE) ok_stub_sis \ - , \ - $(MAKE) -f $(MAKEFILE) fail_sis_nocache \ - ) \ + $(MAKE) -f $(MAKEFILE) fail_sis_nocache \ ) \ - , \ - $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ ) + stub_sis_target.depends += $${baseTarget}_stub.pkg ok_stub_sis_target.target = ok_stub_sis @@ -132,7 +116,6 @@ equals(GENERATE_SIS_TARGETS, true) { ok_installer_sis_target \ unsigned_installer_sis_target \ ok_unsigned_installer_sis_target \ - fail_sis_nopkg_target \ fail_sis_nocache_target \ stub_sis_target \ ok_stub_sis_target @@ -178,10 +161,14 @@ equals(GENERATE_SIS_TARGETS, true) { target_sis_target.commands = $(MAKE) -f $(MAKEFILE) sis installer_sis_target.target = installer_sis - installer_sis_target.commands = $$QMAKE_CREATEPACKAGE $(QT_SIS_OPTIONS) $${baseTarget}_installer.pkg - \ - $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE) + installer_sis_target.commands = $(MAKE) -f $(MAKEFILE) ok_installer_sis installer_sis_target.depends = $${baseTarget}_installer.pkg sis + ok_installer_sis_target.target = ok_installer_sis + ok_installer_sis_target.commands = $$QMAKE_CREATEPACKAGE $(QT_SIS_OPTIONS) $${baseTarget}_installer.pkg - \ + $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE) + ok_installer_sis_target.depends = $${baseTarget}_installer.pkg + unsigned_installer_sis_target.target = unsigned_installer_sis unsigned_installer_sis_target.commands = $$QMAKE_CREATEPACKAGE $(QT_SIS_OPTIONS) -o $${baseTarget}_installer.pkg unsigned_installer_sis_target.depends = $${baseTarget}_installer.pkg unsigned_sis @@ -197,6 +184,7 @@ equals(GENERATE_SIS_TARGETS, true) { unsigned_sis_target \ target_sis_target \ installer_sis_target \ + ok_installer_sis_target \ unsigned_installer_sis_target QMAKE_DISTCLEAN += $${sis_destdir}/$${baseTarget}.sis -- cgit v0.12 From 63a2c0a429674506c5a5d9e37571033608e9704b Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 2 Dec 2010 14:24:03 +0000 Subject: Update def files refreeze on top of master def files (we have added some exports to QtCore) Reviewed-by: Trust Me --- src/s60installs/bwins/QtCoreu.def | 7 ++++++- src/s60installs/eabi/QtCoreu.def | 4 ++++ src/s60installs/eabi/QtDeclarativeu.def | 2 +- src/s60installs/eabi/QtGuiu.def | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def index b678b4e..84aa246 100644 --- a/src/s60installs/bwins/QtCoreu.def +++ b/src/s60installs/bwins/QtCoreu.def @@ -4585,4 +4585,9 @@ EXPORTS ?advance@QAnimationDriver@@QAEXXZ @ 4584 NONAME ; void QAnimationDriver::advance(void) ?start@QAnimationDriver@@AAEXXZ @ 4585 NONAME ; void QAnimationDriver::start(void) ?unlockInline@QMutex@@QAEXXZ @ 4586 NONAME ; void QMutex::unlockInline(void) - + ??0QSystemError@@QAE@HW4ErrorScope@0@@Z @ 4587 NONAME ; QSystemError::QSystemError(int, enum QSystemError::ErrorScope) + ??0QSystemError@@QAE@XZ @ 4588 NONAME ; QSystemError::QSystemError(void) + ?error@QSystemError@@QAEHXZ @ 4589 NONAME ; int QSystemError::error(void) + ?scope@QSystemError@@QAE?AW4ErrorScope@1@XZ @ 4590 NONAME ; enum QSystemError::ErrorScope QSystemError::scope(void) + ?toString@QSystemError@@QAE?AVQString@@XZ @ 4591 NONAME ; class QString QSystemError::toString(void) + ??0QFileInfo@@QAE@PAVQFileInfoPrivate@@@Z @ 4592 NONAME ; QFileInfo::QFileInfo(class QFileInfoPrivate *) diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index 02e72a1..130d9c0 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -3791,4 +3791,8 @@ EXPORTS _ZTV13QUnifiedTimer @ 3790 NONAME _ZTV16QAnimationDriver @ 3791 NONAME _ZTV23QAnimationDriverPrivate @ 3792 NONAME + _ZN12QSystemError8toStringEv @ 3793 NONAME + _ZN5QChar21currentUnicodeVersionEv @ 3794 NONAME + _ZN9QFileInfoC1EP16QFileInfoPrivate @ 3795 NONAME + _ZN9QFileInfoC2EP16QFileInfoPrivate @ 3796 NONAME diff --git a/src/s60installs/eabi/QtDeclarativeu.def b/src/s60installs/eabi/QtDeclarativeu.def index bb0bd5a..b0efab4 100644 --- a/src/s60installs/eabi/QtDeclarativeu.def +++ b/src/s60installs/eabi/QtDeclarativeu.def @@ -1883,6 +1883,6 @@ EXPORTS _ZThn8_N29QDeclarativeAbstractAnimation9setTargetERK20QDeclarativeProperty @ 1882 NONAME ABSENT _ZThn8_N29QDeclarativeAbstractAnimationD0Ev @ 1883 NONAME ABSENT _ZThn8_N29QDeclarativeAbstractAnimationD1Ev @ 1884 NONAME ABSENT - _ZN23QDeclarativeDebugHelper15enableDebuggingEv @ 1885 NONAME ABSENT + _ZN23QDeclarativeDebugHelper15enableDebuggingEv @ 1885 NONAME _ZN27QDeclarativePropertyPrivate7connectEPK7QObjectiS2_iiPi @ 1886 NONAME ABSENT diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 703d11b..926ed52 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -12105,7 +12105,7 @@ EXPORTS _ZN15QStaticTextItemD1Ev @ 12104 NONAME _ZN15QStaticTextItemD2Ev @ 12105 NONAME _ZN19QEventDispatcherS6031reactivateDeferredActiveObjectsEv @ 12106 NONAME - _Z18qt_addBitmapToPathffPKhiiiP12QPainterPath @ 12107 NONAME ABSENT + _Z18qt_addBitmapToPathffPKhiiiP12QPainterPath @ 12107 NONAME _Z22qt_fontdata_from_indexi @ 12108 NONAME _ZN10QBlittable4lockEv @ 12109 NONAME _ZN10QBlittable6unlockEv @ 12110 NONAME -- cgit v0.12 From fdf3be5b6b5db75833e0a7e9a90445ddd794fe4d Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Thu, 2 Dec 2010 15:39:29 +0100 Subject: Simple fixes for CI gate --- examples/scroller/plot/main.cpp | 40 ++++++++++++++++++++++++++++++++++++++ src/gui/util/qscroller.cpp | 2 +- src/gui/util/qscroller.h | 2 +- src/gui/util/qscrollerproperties.h | 4 ++-- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/examples/scroller/plot/main.cpp b/examples/scroller/plot/main.cpp index a4e2add..acf83ee 100644 --- a/examples/scroller/plot/main.cpp +++ b/examples/scroller/plot/main.cpp @@ -1,3 +1,43 @@ +/**************************************************************************** +** +** 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 QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 #include diff --git a/src/gui/util/qscroller.cpp b/src/gui/util/qscroller.cpp index 5aa2b71..b7b5903 100644 --- a/src/gui/util/qscroller.cpp +++ b/src/gui/util/qscroller.cpp @@ -367,7 +367,7 @@ void QScroller::setScrollerProperties(const QScrollerProperties &sp) emit scrollerPropertiesChanged(sp); // we need to force the recalculation here, since the overshootPolicy may have changed and - // exisiting segments may include an overshoot animation. + // existing segments may include an overshoot animation. d->recalcScrollingSegments(true); } } diff --git a/src/gui/util/qscroller.h b/src/gui/util/qscroller.h index 34e1125..7d7e1ca 100644 --- a/src/gui/util/qscroller.h +++ b/src/gui/util/qscroller.h @@ -71,7 +71,7 @@ public: Inactive, Pressed, Dragging, - Scrolling, + Scrolling }; enum ScrollerGestureType diff --git a/src/gui/util/qscrollerproperties.h b/src/gui/util/qscrollerproperties.h index 5284876..e292d8d 100644 --- a/src/gui/util/qscrollerproperties.h +++ b/src/gui/util/qscrollerproperties.h @@ -132,8 +132,8 @@ private: QT_END_NAMESPACE -Q_DECLARE_METATYPE(QScrollerProperties::OvershootPolicy); -Q_DECLARE_METATYPE(QScrollerProperties::FrameRates); +Q_DECLARE_METATYPE(QScrollerProperties::OvershootPolicy) +Q_DECLARE_METATYPE(QScrollerProperties::FrameRates) QT_END_HEADER -- cgit v0.12 From 680ead8c93e2cc27aa4b3957be61c3c0256e287f Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 2 Dec 2010 17:09:38 +0200 Subject: Changed various DEPLOYMENT variable ".sources" suffixes to ".files" Starting from Qt 4.8, ".files" is the correct variable suffix to use for declaring deployment files. Reviewed-by: Janne Koskinen --- mkspecs/features/symbian/default_post.prf | 6 +++--- qmake/generators/symbian/symbiancommon.cpp | 4 ++-- src/s60installs/s60installs.pro | 2 +- tests/benchmarks/script/sunspider/sunspider.pro | 2 +- tests/benchmarks/script/v8/v8.pro | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mkspecs/features/symbian/default_post.prf b/mkspecs/features/symbian/default_post.prf index ec6ecd0..a2ac377 100644 --- a/mkspecs/features/symbian/default_post.prf +++ b/mkspecs/features/symbian/default_post.prf @@ -10,11 +10,11 @@ contains(TEMPLATE, ".*app") { } contains(DESTDIR, "/.*") { - default_bin_deployment.sources += $$DESTDIR/$$symbianRemoveSpecialCharacters($$basename(TARGET)).exe + default_bin_deployment.files += $$DESTDIR/$$symbianRemoveSpecialCharacters($$basename(TARGET)).exe } else:isEmpty(DESTDIR) { - default_bin_deployment.sources += $$OUT_PWD/$$symbianRemoveSpecialCharacters($$basename(TARGET)).exe + default_bin_deployment.files += $$OUT_PWD/$$symbianRemoveSpecialCharacters($$basename(TARGET)).exe } else { - default_bin_deployment.sources += $$OUT_PWD/$$DESTDIR/$$symbianRemoveSpecialCharacters($$basename(TARGET)).exe + default_bin_deployment.files += $$OUT_PWD/$$DESTDIR/$$symbianRemoveSpecialCharacters($$basename(TARGET)).exe } default_bin_deployment.path += /sys/bin diff --git a/qmake/generators/symbian/symbiancommon.cpp b/qmake/generators/symbian/symbiancommon.cpp index 602bcc2..01a59b0 100644 --- a/qmake/generators/symbian/symbiancommon.cpp +++ b/qmake/generators/symbian/symbiancommon.cpp @@ -408,8 +408,8 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, // ### FIXME: remove epocBuild check once makefile based mkspecs support localized resource generation if (epocBuild && symbianLocalizationList.size()) { // Add localized resources to DEPLOYMENT if default resource deployment is done - addLocalizedResourcesToDeployment("default_resource_deployment.sources", symbianLocalizationList); - addLocalizedResourcesToDeployment("default_reg_deployment.sources", symbianLocalizationList); + addLocalizedResourcesToDeployment("default_resource_deployment.files", symbianLocalizationList); + addLocalizedResourcesToDeployment("default_reg_deployment.files", symbianLocalizationList); } // deploy files specified by DEPLOYMENT variable diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index fc364bc..0710b53 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -88,7 +88,7 @@ symbian: { } !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) { - feedback_plugin.sources = $$QT_BUILD_TREE/plugins/s60/feedback/qtactilefeedback$${QT_LIBINFIX}.dll + feedback_plugin.files = $$QT_BUILD_TREE/plugins/s60/feedback/qtactilefeedback$${QT_LIBINFIX}.dll feedback_plugin.path = c:$$QT_PLUGINS_BASE_DIR/feedback DEPLOYMENT += feedback_plugin } diff --git a/tests/benchmarks/script/sunspider/sunspider.pro b/tests/benchmarks/script/sunspider/sunspider.pro index 431505b..aab4cdb 100644 --- a/tests/benchmarks/script/sunspider/sunspider.pro +++ b/tests/benchmarks/script/sunspider/sunspider.pro @@ -9,7 +9,7 @@ QT = core script !symbian:DEFINES += SRCDIR=\\\"$$PWD\\\" wince*|symbian: { -testFiles.sources = tests +testFiles.files = tests testFiles.path = . DEPLOYMENT += testFiles } diff --git a/tests/benchmarks/script/v8/v8.pro b/tests/benchmarks/script/v8/v8.pro index e55fd7f..f36bda5 100644 --- a/tests/benchmarks/script/v8/v8.pro +++ b/tests/benchmarks/script/v8/v8.pro @@ -9,7 +9,7 @@ QT = core script !symbian:DEFINES += SRCDIR=\\\"$$PWD\\\" wince*|symbian: { -testFiles.sources = tests +testFiles.files = tests testFiles.path = . DEPLOYMENT += testFiles } -- cgit v0.12 From e0ecd0d3d6f0cf32061ccf3631a4038c255b41fe Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Fri, 3 Dec 2010 10:12:59 +1000 Subject: Update QML visual tests Reintroducing text tests to X11, and updating a few tests where the behaviour of the items has subtly changed (and it was deemed acceptable) Task-number: QTBUG-14792 --- .../qmlvisual/ListView/data/listview.5.png | Bin 1663 -> 1661 bytes .../qmlvisual/ListView/data/listview.6.png | Bin 1666 -> 1674 bytes .../qmlvisual/ListView/data/listview.qml | 234 ++--- .../data-X11/colorAnimation-visual.0.png | Bin 0 -> 622 bytes .../data-X11/colorAnimation-visual.1.png | Bin 0 -> 627 bytes .../data-X11/colorAnimation-visual.2.png | Bin 0 -> 626 bytes .../data-X11/colorAnimation-visual.3.png | Bin 0 -> 625 bytes .../data-X11/colorAnimation-visual.qml | 951 +++++++++++++++++++++ .../data/usingRepeater.0.png | Bin 1199 -> 1203 bytes .../qdeclarativepositioners/data/usingRepeater.qml | 62 +- .../qdeclarativespringanimation/data/follow.0.png | Bin 941 -> 950 bytes .../qdeclarativespringanimation/data/follow.1.png | Bin 975 -> 983 bytes .../qdeclarativespringanimation/data/follow.2.png | Bin 1235 -> 1243 bytes .../qdeclarativespringanimation/data/follow.3.png | Bin 1225 -> 1235 bytes .../qdeclarativespringanimation/data/follow.4.png | Bin 1247 -> 1253 bytes .../qdeclarativespringanimation/data/follow.5.png | Bin 1243 -> 1249 bytes .../qdeclarativespringanimation/data/follow.6.png | Bin 1234 -> 1241 bytes .../qdeclarativespringanimation/data/follow.7.png | Bin 1242 -> 1251 bytes .../qdeclarativespringanimation/data/follow.qml | 852 +++++++++--------- .../baseline/data-X11/parentanchor.0.png | Bin 1313 -> 1313 bytes .../baseline/data-X11/parentanchor.qml | 60 +- .../qdeclarativetext/elide/data-X11/elide.0.png | Bin 483 -> 481 bytes .../qdeclarativetext/elide/data-X11/elide.1.png | Bin 483 -> 481 bytes .../qdeclarativetext/elide/data-X11/elide.qml | 130 +-- .../qdeclarativetext/elide/data-X11/elide2.0.png | Bin 1189 -> 1187 bytes .../qdeclarativetext/elide/data-X11/elide2.1.png | Bin 1068 -> 1066 bytes .../qdeclarativetext/elide/data-X11/elide2.qml | 194 ++--- .../elide/data-X11/multilength.0.png | Bin 747 -> 742 bytes .../elide/data-X11/multilength.1.png | Bin 814 -> 810 bytes .../elide/data-X11/multilength.2.png | Bin 809 -> 805 bytes .../elide/data-X11/multilength.3.png | Bin 527 -> 529 bytes .../elide/data-X11/multilength.4.png | Bin 526 -> 528 bytes .../elide/data-X11/multilength.qml | 552 ++++++------ .../qdeclarativetext/font/data-X11/plaintext.0.png | Bin 13140 -> 13194 bytes .../font/data-X11/plaintext2.0.png | Bin 1503 -> 1510 bytes .../qdeclarativetext/font/data-X11/richtext.0.png | Bin 9297 -> 9415 bytes .../qdeclarativetext/font/data-X11/richtext2.0.png | Bin 10626 -> 10671 bytes .../qdeclarativetextedit/data-X11/qt-669.0.png | Bin 688 -> 692 bytes .../qdeclarativetextedit/data-X11/qt-669.1.png | Bin 693 -> 696 bytes .../qdeclarativetextedit/data-X11/qt-669.2.png | Bin 695 -> 699 bytes .../qdeclarativetextedit/data-X11/qt-669.3.png | Bin 694 -> 698 bytes .../qdeclarativetextedit/data-X11/qt-669.4.png | Bin 688 -> 692 bytes .../qdeclarativetextedit/data-X11/qt-669.qml | 528 ++++++------ .../qdeclarativetextedit/data-X11/wrap.0.png | Bin 3493 -> 3481 bytes .../qdeclarativetextedit/data-X11/wrap.1.png | Bin 3617 -> 3606 bytes .../qdeclarativetextedit/data-X11/wrap.2.png | Bin 3688 -> 3676 bytes .../qdeclarativetextedit/data-X11/wrap.3.png | Bin 3766 -> 3754 bytes .../qdeclarativetextedit/data-X11/wrap.4.png | Bin 3839 -> 3828 bytes .../qdeclarativetextedit/data-X11/wrap.5.png | Bin 3940 -> 3927 bytes .../qdeclarativetextedit/data-X11/wrap.6.png | Bin 3943 -> 3930 bytes .../qdeclarativetextedit/data-X11/wrap.7.png | Bin 3943 -> 3930 bytes .../qdeclarativetextedit/data-X11/wrap.qml | 842 +++++++++--------- .../qdeclarativetextinput/data-X11/echoMode.1.png | Bin 339 -> 342 bytes .../qdeclarativetextinput/data-X11/echoMode.2.png | Bin 446 -> 445 bytes .../qdeclarativetextinput/data-X11/echoMode.3.png | Bin 510 -> 508 bytes .../qdeclarativetextinput/data-X11/echoMode.qml | 270 +++--- .../qdeclarativetextinput/data-X11/hAlign.0.png | Bin 3661 -> 3685 bytes .../qdeclarativetextinput/data-X11/hAlign.qml | 48 +- tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp | 7 +- 59 files changed, 2838 insertions(+), 1892 deletions(-) create mode 100644 tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.0.png create mode 100644 tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.1.png create mode 100644 tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.2.png create mode 100644 tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.3.png create mode 100644 tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.qml diff --git a/tests/auto/declarative/qmlvisual/ListView/data/listview.5.png b/tests/auto/declarative/qmlvisual/ListView/data/listview.5.png index d1f06fa..63a594e 100644 Binary files a/tests/auto/declarative/qmlvisual/ListView/data/listview.5.png and b/tests/auto/declarative/qmlvisual/ListView/data/listview.5.png differ diff --git a/tests/auto/declarative/qmlvisual/ListView/data/listview.6.png b/tests/auto/declarative/qmlvisual/ListView/data/listview.6.png index 9e6e29c..05e24c6 100644 Binary files a/tests/auto/declarative/qmlvisual/ListView/data/listview.6.png and b/tests/auto/declarative/qmlvisual/ListView/data/listview.6.png differ diff --git a/tests/auto/declarative/qmlvisual/ListView/data/listview.qml b/tests/auto/declarative/qmlvisual/ListView/data/listview.qml index b1ffe8f..059128d 100644 --- a/tests/auto/declarative/qmlvisual/ListView/data/listview.qml +++ b/tests/auto/declarative/qmlvisual/ListView/data/listview.qml @@ -1550,7 +1550,7 @@ VisualTest { } Frame { msec: 4240 - hash: "ad913e53e63c030ffdf4560766722760" + hash: "84b477b46c313d6dcb0a77628182905b" } Mouse { type: 5 @@ -1570,7 +1570,7 @@ VisualTest { } Frame { msec: 4256 - hash: "ef31f8a4d5bde5a2e308d19ee6d5e759" + hash: "281c0499db31ca78175ca7af6292b853" } Mouse { type: 5 @@ -1582,7 +1582,7 @@ VisualTest { } Frame { msec: 4272 - hash: "3ba07527f66e8bea5a8fb7647b0b4f3f" + hash: "5c29d61f037e4636988fdc99ee2ed8a4" } Mouse { type: 5 @@ -1594,7 +1594,7 @@ VisualTest { } Frame { msec: 4288 - hash: "70e5fe656f5fd843383964825690b678" + hash: "a18f5e9f7be932dcd1bcb4c7fe0797e8" } Mouse { type: 5 @@ -1614,7 +1614,7 @@ VisualTest { } Frame { msec: 4304 - hash: "b7d8738be4cd6caa63dbecdb0f810a2f" + hash: "85a4130b4a57ef79e90d350cf4816801" } Mouse { type: 5 @@ -1626,7 +1626,7 @@ VisualTest { } Frame { msec: 4320 - hash: "d6312191f9d7bbddc07f9253d8a93469" + hash: "364dd89fd6f96e1c77723436c7078a7b" } Mouse { type: 5 @@ -1638,7 +1638,7 @@ VisualTest { } Frame { msec: 4336 - hash: "b182da64886cf4f444296e5fde26701e" + hash: "3e37312c45aa92de34d9661f9b482c48" } Mouse { type: 5 @@ -1650,7 +1650,7 @@ VisualTest { } Frame { msec: 4352 - hash: "ebefef14b6fb990e0c6900884528bbd3" + hash: "dc2d63ad430ea6214f962629793925f3" } Mouse { type: 5 @@ -1662,7 +1662,7 @@ VisualTest { } Frame { msec: 4368 - hash: "9a3451ed091b1bb6b975a9c5506b1ea4" + hash: "188fe1e6af9d02b2680426127ef1d39e" } Mouse { type: 5 @@ -1674,7 +1674,7 @@ VisualTest { } Frame { msec: 4384 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Mouse { type: 5 @@ -1686,7 +1686,7 @@ VisualTest { } Frame { msec: 4400 - hash: "eaaf9ea1d7fcf4a2a9dd58b1b5bb3cae" + hash: "bb74813667f49b15978aa78843436205" } Mouse { type: 5 @@ -1698,7 +1698,7 @@ VisualTest { } Frame { msec: 4416 - hash: "7ca8e3d76cf913d85f84f0b96acde829" + hash: "8e88500470517ed1d7c3ca10edd4e230" } Mouse { type: 5 @@ -1710,7 +1710,7 @@ VisualTest { } Frame { msec: 4432 - hash: "7cfef56b24a552c6d4ecb3d0b88a1d08" + hash: "614dc45593db51f467adeda87d84f9a4" } Mouse { type: 5 @@ -1730,7 +1730,7 @@ VisualTest { } Frame { msec: 4448 - hash: "d032b257259810b4fe514c63ca5c9e4b" + hash: "b170583b9b284debdd04af643752aa6b" } Mouse { type: 5 @@ -1742,7 +1742,7 @@ VisualTest { } Frame { msec: 4464 - hash: "568f6a57e6f1644b0dc245d03a1d7b85" + hash: "dba0394b92f3ee166bc397439a86e6dc" } Mouse { type: 5 @@ -1754,87 +1754,87 @@ VisualTest { } Frame { msec: 4480 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4496 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4512 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4528 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4544 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4560 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4576 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4592 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4608 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4624 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4640 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4656 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4672 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4688 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4704 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4720 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4736 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4752 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4768 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4784 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4800 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4816 @@ -1842,11 +1842,11 @@ VisualTest { } Frame { msec: 4832 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Frame { msec: 4848 - hash: "5cb4cf2c527d821db2a5072dd3702653" + hash: "74b499d5d764bf53efbee8932bab3cc3" } Mouse { type: 5 @@ -1866,7 +1866,7 @@ VisualTest { } Frame { msec: 4864 - hash: "d48ecbd0661e08b2117fe2fd96ffeb2c" + hash: "95ab953fc04389396da9a38d97262d98" } Mouse { type: 5 @@ -1878,7 +1878,7 @@ VisualTest { } Frame { msec: 4880 - hash: "7cfef56b24a552c6d4ecb3d0b88a1d08" + hash: "614dc45593db51f467adeda87d84f9a4" } Mouse { type: 5 @@ -1890,7 +1890,7 @@ VisualTest { } Frame { msec: 4896 - hash: "5b12e9d17d9d464b055601db9cf0da44" + hash: "0d884cdb22e3668203d07c72055bcb85" } Mouse { type: 5 @@ -1902,7 +1902,7 @@ VisualTest { } Frame { msec: 4912 - hash: "25333e1f0cc9cfc664fd7369af544c06" + hash: "23bd71236829253fb3ef18ebc9dd3136" } Mouse { type: 5 @@ -1914,39 +1914,39 @@ VisualTest { } Frame { msec: 4928 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 4944 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 4960 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 4976 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 4992 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 5008 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 5024 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 5040 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 5056 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Mouse { type: 3 @@ -1958,179 +1958,179 @@ VisualTest { } Frame { msec: 5072 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 5088 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 5104 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 5120 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 5136 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 5152 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 5168 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 5184 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 5200 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 5216 - hash: "04290d8d62436c8a812f886e0a56ec1b" + hash: "bdb784f5ccf428f8b8a9d29310069808" } Frame { msec: 5232 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5248 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5264 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5280 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5296 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5312 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5328 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5344 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5360 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5376 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5392 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5408 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5424 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5440 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5456 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5472 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5488 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5504 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5520 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5536 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5552 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5568 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5584 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5600 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5616 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5632 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5648 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5664 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5680 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5696 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5712 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5728 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5744 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5760 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5776 @@ -2138,90 +2138,90 @@ VisualTest { } Frame { msec: 5792 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5808 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5824 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5840 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5856 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5872 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5888 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5904 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5920 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5936 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5952 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5968 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 5984 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 6000 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 6016 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 6032 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 6048 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 6064 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 6080 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 6096 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 6112 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } Frame { msec: 6128 - hash: "dbd87bf02d698b7f053d307ef0c98452" + hash: "9ba43cbdd92c077f64e4a59c6c1c42ac" } } diff --git a/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.0.png b/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.0.png new file mode 100644 index 0000000..99748a7 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.0.png differ diff --git a/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.1.png b/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.1.png new file mode 100644 index 0000000..5393dd8 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.1.png differ diff --git a/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.2.png b/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.2.png new file mode 100644 index 0000000..8c17bf7 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.2.png differ diff --git a/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.3.png b/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.3.png new file mode 100644 index 0000000..1317eef Binary files /dev/null and b/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.3.png differ diff --git a/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.qml b/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.qml new file mode 100644 index 0000000..930f08f --- /dev/null +++ b/tests/auto/declarative/qmlvisual/animation/colorAnimation/data-X11/colorAnimation-visual.qml @@ -0,0 +1,951 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "colorAnimation-visual.0.png" + } + Frame { + msec: 32 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 48 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 64 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 80 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 96 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 112 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 128 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 144 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 160 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 176 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 192 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 208 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 224 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 240 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 256 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 272 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 288 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 304 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 320 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 336 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 352 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 368 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 384 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 400 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 416 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 432 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 448 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 464 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 480 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 496 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 512 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 93; y: 136 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 528 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 544 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 560 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 576 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 592 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 93; y: 136 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 608 + hash: "acc736435c9f84aa82941ba561bc5dbc" + } + Frame { + msec: 624 + hash: "e5bda0daf98288ce18db6ce06eda3ba0" + } + Frame { + msec: 640 + hash: "d35008f75b8c992f80fb16ba7203649d" + } + Frame { + msec: 656 + hash: "14f43e0784ddf42ea8550db88c501bf1" + } + Frame { + msec: 672 + hash: "02276e158b5391480b1bdeaadf1fb903" + } + Frame { + msec: 688 + hash: "35d9513eb97a2c482b7cd197de910934" + } + Frame { + msec: 704 + hash: "faf0fd681e60bb2489099f5df772b6cd" + } + Frame { + msec: 720 + hash: "a863d3e346f94785a3a392fdc91526eb" + } + Frame { + msec: 736 + hash: "fdf328d3f6eb8410da59a91345e41a44" + } + Frame { + msec: 752 + hash: "83514a3b10d5be8f6c3b128d0f3e0b1c" + } + Frame { + msec: 768 + hash: "ead0eae76cd00189075964671effbaea" + } + Frame { + msec: 784 + hash: "24d2457fcd51490fda23071bf9929d12" + } + Frame { + msec: 800 + hash: "1478683446cf543dacbe31d0b76a98a6" + } + Frame { + msec: 816 + hash: "99f7da1f31fe920f6c02add4042ae925" + } + Frame { + msec: 832 + hash: "22def892006cf66667770b0f17baf6c0" + } + Frame { + msec: 848 + hash: "6a36d5a77099bfd58baf285478ff04e4" + } + Frame { + msec: 864 + hash: "6258150666b59b20ab476724c07fc20c" + } + Frame { + msec: 880 + hash: "f1636315bc950a6dd400d9c7ed263b88" + } + Frame { + msec: 896 + hash: "18447ea8dc2e8da956788e5b3cf3790a" + } + Frame { + msec: 912 + hash: "1d2a6e65997a73e9e670356c8e8b63b2" + } + Frame { + msec: 928 + hash: "bed0242c0f9ef229d1392835286d5782" + } + Frame { + msec: 944 + hash: "88923c190e9e5beadef8a409c06df9d6" + } + Frame { + msec: 960 + hash: "2d133e7ee60c97386f57838b3f0976c7" + } + Frame { + msec: 976 + image: "colorAnimation-visual.1.png" + } + Frame { + msec: 992 + hash: "395195716d76bc0be7b2033ed37a7a1c" + } + Frame { + msec: 1008 + hash: "243dbffcf416926242bbcb7348974c4c" + } + Frame { + msec: 1024 + hash: "a755068679616d8ac65c2aa7431f2a19" + } + Frame { + msec: 1040 + hash: "e8249b35a47eb492cbdf2d91cc8426f0" + } + Frame { + msec: 1056 + hash: "15f3da1c0e6f0779b96859d51171dd27" + } + Frame { + msec: 1072 + hash: "258c0c756aac3de743b43051f2aace6b" + } + Frame { + msec: 1088 + hash: "a58b9fdf301d72b2cc5c93934cc8927b" + } + Frame { + msec: 1104 + hash: "a9181d30870d472521f8904818ce520f" + } + Frame { + msec: 1120 + hash: "7f9e94069ccf3897c26a71bd7becd903" + } + Frame { + msec: 1136 + hash: "bdf305c2f46cdb86dbf57b1e0cc5a65b" + } + Frame { + msec: 1152 + hash: "fe5b6865d7e4fc7d1d42c1e74f8666f7" + } + Frame { + msec: 1168 + hash: "734f0de45a6e34c9eab7ef606196f96a" + } + Frame { + msec: 1184 + hash: "02a361c4534fdf7f286dc3e6dc23275c" + } + Frame { + msec: 1200 + hash: "e649155ad69999c14b92f6561e4d1185" + } + Frame { + msec: 1216 + hash: "01af177084fab755d622973f64b92018" + } + Frame { + msec: 1232 + hash: "097cc4a082dfab995d213a3a73883c97" + } + Frame { + msec: 1248 + hash: "d7b4239a3280b1eb8e885e3f422df8e9" + } + Frame { + msec: 1264 + hash: "59893977994e34e83f91e7ce3ad65d6d" + } + Frame { + msec: 1280 + hash: "b68e3fbb5cdcd6bd96df7dec558db42b" + } + Frame { + msec: 1296 + hash: "94ad0580648f36a1e18a9ea7e249b04d" + } + Frame { + msec: 1312 + hash: "750a4c01d2f5806a89a1c6cc6a9b9a68" + } + Frame { + msec: 1328 + hash: "4f109f50f388f1bfa4bc6b03b3e6e514" + } + Frame { + msec: 1344 + hash: "c6168d5cf27a533e8ee636637667be47" + } + Frame { + msec: 1360 + hash: "f8120547bed987aa34c00da5a01a4d1e" + } + Frame { + msec: 1376 + hash: "cbff526136fa2c128c8b898fbbef9e5c" + } + Frame { + msec: 1392 + hash: "f29e52398fab1a239a63df4c32f2fc69" + } + Frame { + msec: 1408 + hash: "7178bfe86fd2fd513218b33760460f8d" + } + Frame { + msec: 1424 + hash: "ca83285bc8ac633403896fe976896eb0" + } + Frame { + msec: 1440 + hash: "96ba486c09cc69d5aa38c46c00df1181" + } + Frame { + msec: 1456 + hash: "b88eab335842787869f4a14824c19dd8" + } + Frame { + msec: 1472 + hash: "065aa59012729e1e1a246a2083142690" + } + Frame { + msec: 1488 + hash: "dd0e98c8398861002c5f178c5f9f612d" + } + Frame { + msec: 1504 + hash: "04192c2b545948048eccf4d81bbde198" + } + Frame { + msec: 1520 + hash: "bb7502c7208281ef9fd41714ab88a1a8" + } + Frame { + msec: 1536 + hash: "5397195471890d08b703dca101e5bc7c" + } + Frame { + msec: 1552 + hash: "4c678cdbebb2ffd2cbf012ca77800cde" + } + Frame { + msec: 1568 + hash: "0d7a34ecd0c7f52b2c015037bf1902c6" + } + Frame { + msec: 1584 + hash: "fd9d5048be749ac4369fda2d018b43ae" + } + Frame { + msec: 1600 + hash: "93ee03795cd57ae6f7fe3a020b039ad4" + } + Frame { + msec: 1616 + hash: "5e1118963f219c39761ca7fbf564a9ca" + } + Frame { + msec: 1632 + hash: "8f40038741903150136170503649d941" + } + Frame { + msec: 1648 + hash: "b087b7d0aa6224821f8e18718ff5e77d" + } + Frame { + msec: 1664 + hash: "aa46b04a3c67dc772265ed2901955565" + } + Frame { + msec: 1680 + hash: "ac024bf2aeb4becdf31a09fe0a6db8f3" + } + Frame { + msec: 1696 + hash: "13745a174e4d06e2108a5bf125ba50cc" + } + Frame { + msec: 1712 + hash: "bd972f0d8e230eca0b3fea1b8c960c08" + } + Frame { + msec: 1728 + hash: "cbdbec802a58e7ced0cf45b3ab0bc0ba" + } + Frame { + msec: 1744 + hash: "5128584c50305c7d218b81b8367fa3d5" + } + Frame { + msec: 1760 + hash: "a71461d3593f3685620668916de870bd" + } + Frame { + msec: 1776 + hash: "74ebac8f32cf044b58d9883dbcd9a722" + } + Frame { + msec: 1792 + hash: "fedc5b638f339b90fe59b478721e65b7" + } + Frame { + msec: 1808 + hash: "8593a81be812edf54ec94da8ae9c1314" + } + Frame { + msec: 1824 + hash: "4e9b083075bc5e9287a8abc982778b56" + } + Frame { + msec: 1840 + hash: "1d6f02aa99afa47d77fc49ab894b365a" + } + Frame { + msec: 1856 + hash: "a204feec783b3b05de4c209c21745826" + } + Frame { + msec: 1872 + hash: "665a2a8ff00b9663157802767f504754" + } + Frame { + msec: 1888 + hash: "624fb09ebe60cb87d767faf8d2420b1e" + } + Frame { + msec: 1904 + hash: "e5af0cdc33f3275a25abb09e9165f310" + } + Frame { + msec: 1920 + hash: "02bafb5a81ca66f7670ac93de5123860" + } + Frame { + msec: 1936 + image: "colorAnimation-visual.2.png" + } + Frame { + msec: 1952 + hash: "b5abd0dff1ab076faac7cc226e83f5d0" + } + Frame { + msec: 1968 + hash: "b759acc35bccff8efc2e6fe276ddc0f7" + } + Frame { + msec: 1984 + hash: "ce52e18c1f7732768779863b45314ff5" + } + Frame { + msec: 2000 + hash: "99d30652559dd6931e0c95543eeaa149" + } + Frame { + msec: 2016 + hash: "ffbd9a00e05e085b89296d19d5caec57" + } + Frame { + msec: 2032 + hash: "9c9d658b9c25602816b8066bf19105db" + } + Frame { + msec: 2048 + hash: "2b7fd058e6601e22a30bb7106b1c683b" + } + Frame { + msec: 2064 + hash: "f4c7e26b19ee0a3e7c9688685eb7bd05" + } + Frame { + msec: 2080 + hash: "0dc6d593bceff56b7f81f2a49d37fefb" + } + Frame { + msec: 2096 + hash: "9bfd7ad5091ccbdde43c593e133a7b10" + } + Frame { + msec: 2112 + hash: "2703b617937914a90ea42ebf249d79ee" + } + Frame { + msec: 2128 + hash: "b77e2983138254016c4cca53100f46fa" + } + Frame { + msec: 2144 + hash: "60c4dd24187d1281081479e586f02b37" + } + Frame { + msec: 2160 + hash: "62f2511abd99ef1231c9fa4b91d4abfe" + } + Frame { + msec: 2176 + hash: "e309b3353fd174e883d309571caddc98" + } + Frame { + msec: 2192 + hash: "1e2d6a134c7b12dde551b148ef4f088c" + } + Frame { + msec: 2208 + hash: "e5dc5450604a491cc24a0dcf5c278b58" + } + Frame { + msec: 2224 + hash: "c8dae97c10e1962c1e6a51ab3ab8579e" + } + Frame { + msec: 2240 + hash: "4e1b7e06f55fb084080689b474f1fe1d" + } + Frame { + msec: 2256 + hash: "b4639c907fa937bf15fac62421170cd8" + } + Frame { + msec: 2272 + hash: "c250208a0caeb5f6cb4d3aac3d7d350b" + } + Frame { + msec: 2288 + hash: "a73351eabecf0d71149efe31f197413e" + } + Frame { + msec: 2304 + hash: "479425f1b7aff79e4dfb7fca534af018" + } + Frame { + msec: 2320 + hash: "046d0f0040a52d1f26ba9f7c5de06ef4" + } + Frame { + msec: 2336 + hash: "655778bf13c6080903150b0eb43a7edc" + } + Frame { + msec: 2352 + hash: "72da0bbe81514870655fdd3354adac60" + } + Frame { + msec: 2368 + hash: "defe0bdf675c65fff55aaaced1e4dae7" + } + Frame { + msec: 2384 + hash: "c988628b6c3d3780e9a865c7694926cd" + } + Frame { + msec: 2400 + hash: "5ab17563655231089edd986ff13d6012" + } + Frame { + msec: 2416 + hash: "c1adff1d2e5800ed466d1691d3b17382" + } + Frame { + msec: 2432 + hash: "70129ba01fbb19592b9dc0d0a3b3e7df" + } + Frame { + msec: 2448 + hash: "0000829ef7ed908bf430d42904d59cc2" + } + Frame { + msec: 2464 + hash: "843d2927f50ab87b4a86b7a6aaeed91f" + } + Frame { + msec: 2480 + hash: "da86d21756025e7de8050586d5e2a1f8" + } + Frame { + msec: 2496 + hash: "48dd1bd6580133b0793fee327ea4f1e6" + } + Frame { + msec: 2512 + hash: "f0618193dcd0ba2837249515a1898b1c" + } + Frame { + msec: 2528 + hash: "a530184e57251065286c0cbba7301e9c" + } + Frame { + msec: 2544 + hash: "64a1d7203973d65dd342793007a61c58" + } + Frame { + msec: 2560 + hash: "5b830dfc6ba442772de87d75d5a578de" + } + Frame { + msec: 2576 + hash: "5563b056b0409b65f60dd16dd0dd890e" + } + Frame { + msec: 2592 + hash: "b8bcf9ad2ca8720c11563a23d8280804" + } + Frame { + msec: 2608 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2624 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2640 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2656 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2672 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2688 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2704 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2720 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2736 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2752 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2768 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2784 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2800 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2816 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2832 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2848 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2864 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2880 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2896 + image: "colorAnimation-visual.3.png" + } + Frame { + msec: 2912 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2928 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2944 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2960 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2976 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 2992 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3008 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3024 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3040 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3056 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3072 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3088 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3104 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3120 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3136 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3152 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3168 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3184 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3200 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3216 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3232 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3248 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3264 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3280 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3296 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3312 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3328 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3344 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3360 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3376 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3392 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3408 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3424 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3440 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3456 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3472 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3488 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3504 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3520 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3536 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3552 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3568 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3584 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3600 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3616 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3632 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Key { + type: 6 + key: 16777249 + modifiers: 67108864 + text: "" + autorep: false + count: 1 + } + Frame { + msec: 3648 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3664 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } + Frame { + msec: 3680 + hash: "8c0fcda4f8956394c53fc4ba18caa850" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.0.png b/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.0.png index 75a6c49..f5b5622 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.qml b/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.qml index 3365d40..3869b73 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.qml @@ -10,126 +10,126 @@ VisualTest { } Frame { msec: 32 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 48 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 64 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 80 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 96 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 112 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 128 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 144 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 160 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 176 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 192 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 208 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 224 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 240 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 256 - hash: "1a396cf01a6c31155609532654653599" + hash: "3b670c14311188b82f37aa260fb1a8de" } Frame { msec: 272 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 288 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 304 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 320 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 336 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 352 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 368 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 384 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 400 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 416 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 432 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 448 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 464 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 480 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 496 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } Frame { msec: 512 - hash: "8a4565aee33d40840bda26b65b6a0d90" + hash: "07b267d5a8c194322d339e1ad609f199" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.0.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.0.png index ae89849..6525dbb 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.1.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.1.png index 7b7db05..5b8d209 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.2.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.2.png index 7c1442f..cf012ba 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.2.png and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.3.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.3.png index c01c980..57e77a4 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.3.png and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.4.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.4.png index 8806e4c..24d26bd 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.4.png and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.5.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.5.png index b331119..a540734 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.5.png and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.5.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.6.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.6.png index 76e3c6f..17da643 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.6.png and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.6.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.7.png b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.7.png index 141753c..e03cfe4 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.7.png and b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.7.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.qml b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.qml index 4548e5b..2cbd278 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativespringanimation/data/follow.qml @@ -10,239 +10,239 @@ VisualTest { } Frame { msec: 32 - hash: "e94ba580322887dbbbf9cb6309e39c23" + hash: "2ddcb50f5d285eb80a8136f0cf4cf85a" } Frame { msec: 48 - hash: "787a59cda2c0b27d8959026e6d1b9427" + hash: "519d93a844e05f8215139d91c9aef58b" } Frame { msec: 64 - hash: "9ca724d4b31aa16015b5cbb50eea0c3a" + hash: "9f075a5547e4dc67cbe2ace2766395bb" } Frame { msec: 80 - hash: "8a2c62a0190da1b7c1bade243baea6b8" + hash: "8fc48f74a51d45b4ea1fb7bd1d48002f" } Frame { msec: 96 - hash: "e129bebca7ad348c3134569d8eee4efc" + hash: "a28fc4be5a5bb9ff36f796d9b071f02c" } Frame { msec: 112 - hash: "fd6387415e1c02fe6d17d9c3aa1d1ed8" + hash: "ebc14c2905f3596ec451dd96409e6001" } Frame { msec: 128 - hash: "a82a4042fdca7c30facd2c4740c455f7" + hash: "4f270bdcff44006a56055edb1cda522a" } Frame { msec: 144 - hash: "62195722eb3acbfbad137ec71fd50bfe" + hash: "571f347e764bf38985768c85c2a13ba1" } Frame { msec: 160 - hash: "449819cdc880d59650732b5447ec6237" + hash: "b1aa23268167b7e2a1190288926f52c0" } Frame { msec: 176 - hash: "552a838ebcacc0e08fa93b64a2433831" + hash: "06d548aef9a678edbf3ab4d3ce62a647" } Frame { msec: 192 - hash: "3984992606d54f05eb31dd0974af2183" + hash: "daf6af0ae78f39566913c656450a66e5" } Frame { msec: 208 - hash: "3fd7225bbb0215ca8b6397580f2352a5" + hash: "f101cd0c026ee0ed6ccef7a4aed302a0" } Frame { msec: 224 - hash: "0fd8f26f40a9049de1cf2a9493d579d1" + hash: "b3caa673f072c53d31d71109c9b33357" } Frame { msec: 240 - hash: "d08f0c57f071dc42e79fc5e0e3c32eeb" + hash: "8596f1d305d6b8f97b9feda9e69bdefe" } Frame { msec: 256 - hash: "084c2db330ee82cd032df248ecc9629d" + hash: "23c23df2c130aafb2092fe47a958a4cd" } Frame { msec: 272 - hash: "98da0d7f280d7fc4579c970c9a173b51" + hash: "66a4f2d8213264437a5f4d6cf10cd442" } Frame { msec: 288 - hash: "4c819c54ced1b6ef0574417a7e11f2e7" + hash: "6392490111813bad0a9467cc0c1746ed" } Frame { msec: 304 - hash: "3dc5f7b412cb176c3b23d37cda3ef87c" + hash: "c115a47e0ecab63b881e2ec492d24e68" } Frame { msec: 320 - hash: "c368a01b43d94205c03f9c750c37f330" + hash: "c2a2b57e6f9ea2975c0846124d2dbc66" } Frame { msec: 336 - hash: "8842bd0c8b17cac4fc9df84835999174" + hash: "8286c315dfda4241607b2de1154f869d" } Frame { msec: 352 - hash: "26829e9c7ca44dfcb0c03852f4158a18" + hash: "3f0f7cae80357176892ff7628ec3153a" } Frame { msec: 368 - hash: "ecffdb0888f1721e27b163e1f29a1950" + hash: "d13bde4a5b5ed8202f92ae33913166c9" } Frame { msec: 384 - hash: "eaead96f2683c464a12df8aadba20691" + hash: "b70cc32134b1b0d31a5e7f145af09495" } Frame { msec: 400 - hash: "1e931963925bd208dce1ec9011372a3b" + hash: "03ebc2ff317ac840f4508e8701d66955" } Frame { msec: 416 - hash: "1c3fd049001c1e883f21d0d1e0e32cba" + hash: "8dff08e72365e8e2fee8088c386dedca" } Frame { msec: 432 - hash: "e8c3422ca637750ac52565594737d092" + hash: "720f3bbaf3fa3e3a064747d5689e47a0" } Frame { msec: 448 - hash: "b1c36322cf89e15a80af7c43f2aebca1" + hash: "350e3ebfcfef96969ef5b8d5944f7e62" } Frame { msec: 464 - hash: "f676c3171495f7bb2cb1812cfebaa17a" + hash: "1e4e6e68b3a8eac0c5cd039164eec166" } Frame { msec: 480 - hash: "255119e2efa99c8e31fee611aaaa5137" + hash: "62a10c4250ad025139a3f9e72109e8e1" } Frame { msec: 496 - hash: "e0bd32e3d44cfc2351db105f4595f18a" + hash: "23cfd643adfc98f6a06c7e7b15dac954" } Frame { msec: 512 - hash: "b7f23b8f3769f929b42491efda7ebe19" + hash: "3a78930d5b86b886723fad85e77dd075" } Frame { msec: 528 - hash: "718cee11d869a8a8c5191cc0c09f2d30" + hash: "64dc878e2f527e80403c766e61fe14a6" } Frame { msec: 544 - hash: "fbdbf92f8c5f507605ff50abc594682b" + hash: "d79160989d2584044042271e79a88e69" } Frame { msec: 560 - hash: "c07fdc69c72b40d3c8dd1cc499008888" + hash: "22cbaea4affc88433834c7d0dc1f1644" } Frame { msec: 576 - hash: "38e17ecd537dc0f51211ad672a2ebb21" + hash: "77cb616902257e1f239a0e6bfaabb33c" } Frame { msec: 592 - hash: "2cbdc8728ef779c62f9938672986658a" + hash: "a2fe73dced03b23c4acb9aae9b774b41" } Frame { msec: 608 - hash: "7fb66509d5d1df34861e9c70f9a579f0" + hash: "230e21d3a9ed0e185593677233af1275" } Frame { msec: 624 - hash: "410b89392e859058718a08b79ec3d8fa" + hash: "4e10ecffac4e06d624855d3f8917f76c" } Frame { msec: 640 - hash: "9bd90f80700217d08dafed93b81ee9cf" + hash: "84f49d56baace4a02e50d3eafaea04ec" } Frame { msec: 656 - hash: "6d83671504a4274887b4e0d9bd2b24e7" + hash: "e3cd0b334551a9f91723eb2c876d335a" } Frame { msec: 672 - hash: "51ff7bd3fd4a776af33fce7b935b145c" + hash: "259330f3ec390c9926d9c2ddc2d77319" } Frame { msec: 688 - hash: "20f27392368b63b248bcd455cf3c9106" + hash: "cc659623bfa385d282d608684d7cdc2b" } Frame { msec: 704 - hash: "1a5ab296bd55aa215c9b04a7ff6c73a1" + hash: "47ed75d077143a6bfa0e10158550c542" } Frame { msec: 720 - hash: "020fd7b14e8662fc006b0c39adca7c6a" + hash: "0de93bbd9f9ee63e97968089321003e1" } Frame { msec: 736 - hash: "2619120bdb25a153963bdf05c4a16d44" + hash: "b33d867d4399879256a01344ce0b81f2" } Frame { msec: 752 - hash: "fd321314031efeb9ce71146764289d9f" + hash: "97c31fce937d11f62bebc6169b464a42" } Frame { msec: 768 - hash: "378a71f09445dfff284db919787cbf87" + hash: "ea4166b8a4001bca3f27af30f251267f" } Frame { msec: 784 - hash: "d59eefe82ab8a00c903141dd9ea767ef" + hash: "b56d270b7893565f8d7ed2a0bfe10d60" } Frame { msec: 800 - hash: "0a65004d69a4567f2a5c7e84dab3a905" + hash: "88a42559fe22b45cff379258dd40ced9" } Frame { msec: 816 - hash: "92a4631716a51ff484ca14d9cfe05b2e" + hash: "4ee1a711cb8d26087e1b75a3166ca5f0" } Frame { msec: 832 - hash: "87203f627cf410cad56d6ba38a140efa" + hash: "9b88a00d041092e79b4a08bccbaca0e1" } Frame { msec: 848 - hash: "054cc085998cc059a6b7b4a7300dd36b" + hash: "afea397b3d740dc42f0313624fc10efd" } Frame { msec: 864 - hash: "af3fefeb908a0485c723d36f61eff0a4" + hash: "39fd8e4cefbd9fed283d62a7aecded22" } Frame { msec: 880 - hash: "3f905d1e1ea79858b5a9bbfeab4eb255" + hash: "916b783d2379ac054c749e7b6eae7ddf" } Frame { msec: 896 - hash: "f935f1fc5f26a201098d894fca9a4d1f" + hash: "fccd44740ff7ffb0f2adccf00a7588bd" } Frame { msec: 912 - hash: "42b003dbb531da514716b9c32bdd3614" + hash: "c064f20703a13543e8273d251fd645fe" } Frame { msec: 928 - hash: "a82fed83ee4efee7896b639c7691b13a" + hash: "1b9b0755101841e3d1cbe208d81575d5" } Frame { msec: 944 - hash: "31ad8cbf875233ea495330b0d3d4d2dd" + hash: "1eb5e4a301b565012bc8f6af8e879eb9" } Frame { msec: 960 - hash: "00586f2f1d49fa81f90f7b06614311b4" + hash: "032db65eb5c405e433f88df3975c322b" } Frame { msec: 976 @@ -250,175 +250,175 @@ VisualTest { } Frame { msec: 992 - hash: "5d71ff48b865ad4266eb8292f981b04e" + hash: "fdb67e11d7cc767b2389a8bbef752c7e" } Frame { msec: 1008 - hash: "df599d934d131c92b209284277009efb" + hash: "ed89cb161336c61b13e3514fdf816023" } Frame { msec: 1024 - hash: "5aaf33d11eb70ffdfe89246c637caed7" + hash: "331b873c5367e0aaa62af85cb54a6a96" } Frame { msec: 1040 - hash: "9648cf623a66ded145c4fd23a42917b3" + hash: "cde4503f02f0c3732e310a7d0418cd1e" } Frame { msec: 1056 - hash: "9d33c2cc44ceac5a527ddcf809a51df6" + hash: "f8c028c591fc1495d5bec8763da6f011" } Frame { msec: 1072 - hash: "6d0ad2e0d012e53a03e246e6d5e49e13" + hash: "9dc68483218335afe41aa3cd052a98b5" } Frame { msec: 1088 - hash: "d33fa68796e38b19f44571d11c1bcd33" + hash: "31105c455418a3284700cf9c88571507" } Frame { msec: 1104 - hash: "636680f49bbf30b0fac31a6c581f18dd" + hash: "72724947167a1ac600aaa1d7f331f7ec" } Frame { msec: 1120 - hash: "66801dbc39301e6b46b244fe502e0340" + hash: "a4a1243326de6b9e93948fcb22fecac4" } Frame { msec: 1136 - hash: "f8fa6a033483279e78636f26493b10ac" + hash: "c3e26e62f12dd658f21a0330fefb0533" } Frame { msec: 1152 - hash: "11b46611550173df42986dee4339d907" + hash: "15d85b4a9ad761a911bbaa3e0c4b2b61" } Frame { msec: 1168 - hash: "5c9afdb519006079ee8d28b2b60d0b76" + hash: "bce1400b437cc43b8ff57b1a5fbc9551" } Frame { msec: 1184 - hash: "9a55c38b2cd8abf25fbe448c7ef80971" + hash: "5d05848afcd8f697c1b3762f00a759f6" } Frame { msec: 1200 - hash: "27ebdf1424e892b35c93ec009d942407" + hash: "6c83f68ea72cd54793149f4c9e759d44" } Frame { msec: 1216 - hash: "2d9e3f0ae56f7337012b51c4dd173108" + hash: "5206b93666e51cee3e25a7a85e27b5b8" } Frame { msec: 1232 - hash: "e6f89ca892131d68ff1f4ca95c95d807" + hash: "a3ef5c76efece4455e5ad12bcc8bd8f5" } Frame { msec: 1248 - hash: "f75791f1b12a217d37acb09bdb114cc5" + hash: "c36c6ee7b6c8074f5dc1af7446fad1ad" } Frame { msec: 1264 - hash: "94c5ab1460fb1b0f957a9718b45bca36" + hash: "bb0887f1f10548bb53f0dc1ffeec25ee" } Frame { msec: 1280 - hash: "e246c8a0ec3d01ea20258b24a5673fe1" + hash: "ebffe547a7c3528e5deddc590510506d" } Frame { msec: 1296 - hash: "529de7735e73409dff266d8c1275215c" + hash: "18962faef1a1a1207a3c6783116154a2" } Frame { msec: 1312 - hash: "330400763a670580570cb62241ebec62" + hash: "8aaa876e4a6c4de04e557f35ddd4fb61" } Frame { msec: 1328 - hash: "ae444d1de9c509fc6f74136ca90f927a" + hash: "c66123bb4e01ce267629f5b50d147db1" } Frame { msec: 1344 - hash: "c43631ca8ee90ea5dc7664be5bc45429" + hash: "334e5acf84d90e70ca3085b9d5e057a7" } Frame { msec: 1360 - hash: "b366ac4a5b66c331a7667e9df0fc4eda" + hash: "9bb49ddcc775307c3c1159908323e010" } Frame { msec: 1376 - hash: "1c7f4c47a9c57a34787cc9703e99bff1" + hash: "1b3cfb8b6b6c39a34ea86a66ea1cc6b1" } Frame { msec: 1392 - hash: "5555535609d512e8d34549b6624f74b8" + hash: "d2a68c6eb2b05390ab1049137f96f227" } Frame { msec: 1408 - hash: "be59df714541923494b59f31f57e310e" + hash: "91e254fd2376ba35a283b18b947ca1a8" } Frame { msec: 1424 - hash: "63e434f053032e54298f6e61c8d4da7d" + hash: "fe94e2e8b4978390e9e8cbfe77dfc241" } Frame { msec: 1440 - hash: "b0bb838637eceb6f8993ebc5b887afed" + hash: "e3d32b73c5c50e7aa59f4e4725de170e" } Frame { msec: 1456 - hash: "fc39f33add4ebcaf578558ecd4aea281" + hash: "a73b90254d7da5557cc3941db0017a65" } Frame { msec: 1472 - hash: "3f36faa7cc1e5898d4d5890c47633ff3" + hash: "9aa49cce5d63f8dd6409995ac6d91d63" } Frame { msec: 1488 - hash: "4b328002b4461869b1f7de48e7291902" + hash: "0ba674df46accec28a3c1b81e656adc7" } Frame { msec: 1504 - hash: "26252c63924d2abcaebea2c7caf1d7aa" + hash: "025a45417b8c75d47b5dac6c5ef913e9" } Frame { msec: 1520 - hash: "a9a6023484ae439be86b2c2ff59dc40b" + hash: "742527b97c7f580b0b7ff9d6aa105d31" } Frame { msec: 1536 - hash: "620dab11bd4aab84cc0d949c48dd9a5d" + hash: "965ec8315d45894e704fcc5a3efc8c55" } Frame { msec: 1552 - hash: "3b45ef80ee3e6fbbd3533bfa0d666e2f" + hash: "6abdd59e6bd2c31124eab254418a5322" } Frame { msec: 1568 - hash: "b33306abcb6a8402e491b7216495c778" + hash: "9f6d06b176c55fa292e7f0ef4b5cd1cb" } Frame { msec: 1584 - hash: "3cc52e8649a02e87785f1dc63f5c1efd" + hash: "05eba8c6e02c0d4af49e59b3346c9e68" } Frame { msec: 1600 - hash: "fe21141f48da685213ed9d7641b2e7a0" + hash: "3c4215f6253aba836516cd51368bc471" } Frame { msec: 1616 - hash: "205aac4e822e20bd32f637256250f3c8" + hash: "c6339a290007c0106cb18ecef5b7392b" } Frame { msec: 1632 - hash: "124df0948f36aaf6151556d301f4b930" + hash: "39a4bcd2ce84035f9db70f196ca00971" } Frame { msec: 1648 - hash: "c1701edd5eaf143fd1dbdc4a5324b48a" + hash: "b75a4be472583c3b893fc894ebe7d4d8" } Frame { msec: 1664 - hash: "117402df55367c918a3835958f4ab1d6" + hash: "d1efebbe748c43b3c1241753612e100d" } Mouse { type: 2 @@ -430,67 +430,67 @@ VisualTest { } Frame { msec: 1680 - hash: "73e3b86a1da28490cae4b03fdceefe19" + hash: "f6f3ad64fb71ffb68a5ea0375cc94bae" } Frame { msec: 1696 - hash: "172e329fb47d6db0180242990a84fe3b" + hash: "778ecbafb5d235edde1683cabe3c3cfe" } Frame { msec: 1712 - hash: "82cf704cdfd406bab22689bc888ddc8d" + hash: "5a41b9196fe4a97e6ba2400806299bd8" } Frame { msec: 1728 - hash: "4c288f198a06d1b2815d34c3c8f97051" + hash: "1c8ddbc5910e35be389a1cb34fab9dec" } Frame { msec: 1744 - hash: "6404d81456bb95a6b1c1ae55a181e40e" + hash: "5e8b236c00087a067d366afde67184f3" } Frame { msec: 1760 - hash: "b2b4b3de77e2b7fd58d3da1ad52355a9" + hash: "72fe42361833054cd9388bb98ac9b150" } Frame { msec: 1776 - hash: "95388037c1f79a9dab951031f1d7c307" + hash: "bbe9f0b030efa716f34a05f0af929c66" } Frame { msec: 1792 - hash: "c4ee57d9bffbb5f0ff173db48eadf2e3" + hash: "cd393fc19a30d896bfe62aa0000308f8" } Frame { msec: 1808 - hash: "703ac9672a9c55cf08e6381ef76ac13c" + hash: "c390f5b1bcff54de203490d8f2616fcd" } Frame { msec: 1824 - hash: "ea7726d2a2923290398262c8f70d511e" + hash: "b5da2ea467c334dd13c75b811b94efb1" } Frame { msec: 1840 - hash: "5d1af6cbdb4ee5b00045751204408632" + hash: "49887c9312c3a4dfc2d9719f47c83a15" } Frame { msec: 1856 - hash: "a52aa37b10a05382f1b136896b7e00e8" + hash: "7f077703e49f154d01c12a44f53469c5" } Frame { msec: 1872 - hash: "a5acc1a45c95a67725e5e15084b7be18" + hash: "7be4130ed767f0e0bf41c3bebf050cac" } Frame { msec: 1888 - hash: "c9fac8b5a4110493958d49b073ea96ed" + hash: "cc1590486c172000557b76c6eadb51e0" } Frame { msec: 1904 - hash: "6fca3a5c6d1cfbf1b905aca25b7785c5" + hash: "7ccd05236d9c1f8af0e9645404326122" } Frame { msec: 1920 - hash: "a40e5e2744d1d84c8b9a45525801a745" + hash: "2da165bf7e868b53b85bb630649ddc3e" } Frame { msec: 1936 @@ -498,239 +498,239 @@ VisualTest { } Frame { msec: 1952 - hash: "b2f980ab19d44ee98ab3e82a19adfe2d" + hash: "2b6a24b6ceeaa956527c872af70fb5f9" } Frame { msec: 1968 - hash: "e01732623930aebefd76ab62c81dc722" + hash: "8c882de21f4ed0fb68433c19b114c3f8" } Frame { msec: 1984 - hash: "3a59c6851bc89eb31100092b1ceddbd9" + hash: "f75226c58726a687079d0d24e865ee6f" } Frame { msec: 2000 - hash: "2949de19eacb9f35816aa7ba69614f2c" + hash: "2fa9b69fe85b4e1361ba260545c10e06" } Frame { msec: 2016 - hash: "f2c4c1f4429cbb6bd10f2318b2cb6904" + hash: "6d513bc03f2798fbce1a0790969da6b5" } Frame { msec: 2032 - hash: "2c48af64162e7e028cd536dba03eab71" + hash: "7e359e605483493e9a865f6eb912c394" } Frame { msec: 2048 - hash: "7fe13b8f9253f720b6591b396cfba2d1" + hash: "497c7c82c24408dcaff5ec981d3d4f35" } Frame { msec: 2064 - hash: "559947a03e650575a764801366cc504b" + hash: "8738b024cf75ef970ffe20166e85141c" } Frame { msec: 2080 - hash: "a8d09f6c862fd5ec2dcf34f06d1ef744" + hash: "014b805eb1ecf2ea1cd61727bfd1ca08" } Frame { msec: 2096 - hash: "e3bb4b62209631ff84134f2243bfdb42" + hash: "a81cde60979300f397054ea017382114" } Frame { msec: 2112 - hash: "a1956a9d1939bc154ea0c88d596948cc" + hash: "c46183b5224e762335eea98d9da65465" } Frame { msec: 2128 - hash: "c98a375727860da1e827d4dd74af8f63" + hash: "11afbb88994f298a1fed6575fae3d7fd" } Frame { msec: 2144 - hash: "df4edcbb2ef5348341ff55c808609b6c" + hash: "0195fa503143561d9ae3ffe68739ca3f" } Frame { msec: 2160 - hash: "6287564be85b7cbadc6bb6f0232bc837" + hash: "6d298df37d2116eb9a62b58853cb3344" } Frame { msec: 2176 - hash: "9826fdb48f7ea770fa5f198ec49d7cb7" + hash: "1660865f00ea9adf94c8e56c7a8a73b2" } Frame { msec: 2192 - hash: "56f82641a5591df9bb929cc0d32eb95d" + hash: "9835b5527b84e8e8a8fea2bdf9653a99" } Frame { msec: 2208 - hash: "526c55e555fb2e58796561efa3568c50" + hash: "ec1158b83daa9e98437abc9ce90b70f0" } Frame { msec: 2224 - hash: "6b4b74613421c1841a17c369cb316754" + hash: "11ce5e37747e05ff5f5071b13324ce9e" } Frame { msec: 2240 - hash: "37f785c30947d5eec113dcf6af649abf" + hash: "6d7d427d5a15a31fd395f26c94ea455e" } Frame { msec: 2256 - hash: "5ff2c975dd9e261c764537c836627c4d" + hash: "828949e0fbdb7c79719fb533febb5b35" } Frame { msec: 2272 - hash: "efe554981583749c3d09988bce7fed02" + hash: "7ef7f73ef6a59c9210cfa37df3894cb1" } Frame { msec: 2288 - hash: "0f7204b4afb0ea5d58e49650e8027c0c" + hash: "e74bec397b32ba2934ffdde23a3d60c6" } Frame { msec: 2304 - hash: "817291f91f4b309710ad3aed53a7d47a" + hash: "09c2ca9c22e9b77bc166b4567b29bca7" } Frame { msec: 2320 - hash: "c15c9cd03089090cf8a777c1f0d88de7" + hash: "44d87983f33c4e03f4be70b406bb9bd9" } Frame { msec: 2336 - hash: "05f45cb8d0856dcc81091351615e35d6" + hash: "92844b36c2f30e618f04bfbc5cfbcad6" } Frame { msec: 2352 - hash: "99785a16fed6d6409b4b47ec55afb56b" + hash: "0245f39a8966c4addb3f8dbcee93cd3f" } Frame { msec: 2368 - hash: "39032cb4432ee9536af500673fccf526" + hash: "eb1e81cfa29295d4b1522c69d4501f51" } Frame { msec: 2384 - hash: "9057653e3cd6042831037d3590e7595b" + hash: "2af9c3bea11b25c0f6c2b780d533a968" } Frame { msec: 2400 - hash: "76c772eb2ab8f117c260c9c96bc99e1d" + hash: "5062e9ab29c4a7a9657a4d29249ca822" } Frame { msec: 2416 - hash: "b6474665b8f8bcdd76d1a38efecad889" + hash: "d7652ddc85d3be3bb3a2fc268ae9bc29" } Frame { msec: 2432 - hash: "106c2d2efafad0181e3ded3a6805f2c6" + hash: "7c924bf2ad6167db439723679b373a3a" } Frame { msec: 2448 - hash: "5275fa4ffef6c1909f9d03bb1e7b9cae" + hash: "a93b61dd26a2ca72100b747ac3ed81b6" } Frame { msec: 2464 - hash: "0c1043c0087d60000dc7259d4ac03618" + hash: "5fedc849d3d21e0acf0ab4a4815a1285" } Frame { msec: 2480 - hash: "645748569b4f5cb9b206b0808bb7d23d" + hash: "4313d2458f4bede8d3b02ac60135e728" } Frame { msec: 2496 - hash: "dd95dfa80e1b3ff511e7c75efd0d87ce" + hash: "0f09e81d89262b569c56a9c876f3898d" } Frame { msec: 2512 - hash: "86b3dd03b04d7610837cdc67cad07e0a" + hash: "ea932789ded14fc5c8bae565b67d004c" } Frame { msec: 2528 - hash: "8264f67ac92e4ebcfe4cc8e954f8c5d2" + hash: "fd1f7b9b51f1284fee4d777ef83bba3f" } Frame { msec: 2544 - hash: "6bf52377d822b09eb28a1ec36d3a36a9" + hash: "e98b884a1ec8ce4b4dc20749b85b571e" } Frame { msec: 2560 - hash: "7ae1d65cdaf7fa71eb4ec318b37bb0aa" + hash: "d144072bb87bb88750b9df9cd92f7a4b" } Frame { msec: 2576 - hash: "860f5ce9844c90cf9e6a6d383ff0972f" + hash: "9d8ad80d3367292d7e89d67cf49862b8" } Frame { msec: 2592 - hash: "5502229c038dfc59d966f69ae6ed8957" + hash: "c09b89e71e862da15d2b9edb0e00aa7b" } Frame { msec: 2608 - hash: "21843c027bc1434ae60b3bb0fced2c54" + hash: "551277add3f8f09951d9c8f55ccd40f7" } Frame { msec: 2624 - hash: "962df45680949c3eb6c968f98cd76b20" + hash: "1d0be0e7108516869374a9b985fd7543" } Frame { msec: 2640 - hash: "f313c26fa76a0edce61244bdf92528e4" + hash: "12e7cfb6c4a26af54c4b35182294a7b7" } Frame { msec: 2656 - hash: "b7bbde239e98cbd66b1e51b54b747f51" + hash: "a666a5a59d5854973668798eb8d508ba" } Frame { msec: 2672 - hash: "62340707fbc832fcb805c8f80ab353d1" + hash: "420d2e21461dc45f134b7dfa11d04d25" } Frame { msec: 2688 - hash: "d008a3f7af1810ff70b68b38a4cd0f0d" + hash: "95f848874899fb58a81c62b5921cf857" } Frame { msec: 2704 - hash: "e651dd628af24faf34d716beb392b052" + hash: "fa3ea7a0f90ca549cc9a857f0647b061" } Frame { msec: 2720 - hash: "a97733963c7a7616b25741545b07ffba" + hash: "cbc5338de6157cd5dad511b246f5093b" } Frame { msec: 2736 - hash: "3e017cc1db720cf16521bd17308e4f44" + hash: "e26b43c83197abab3746830bbfacc0f4" } Frame { msec: 2752 - hash: "13652ebaa610cca71486517e2eed21a5" + hash: "5225e854ff2763e562dee2810331d560" } Frame { msec: 2768 - hash: "09f0f500c6f7d11be39c31f9e589b38a" + hash: "a1d114ea67233ac4c6351e18e3afa64e" } Frame { msec: 2784 - hash: "b87968cbc60ddc6a5f5699e830410eab" + hash: "bc9f12af2d0816bb84fd5040ed29bdad" } Frame { msec: 2800 - hash: "50e65b043d1f07a321a08ee4c25204f6" + hash: "d9337da38caa4ad3385249602a830df3" } Frame { msec: 2816 - hash: "122d1ffa1510468e8c4067e0f511588f" + hash: "6ce20e0c89181b0f11e609b248da71d7" } Frame { msec: 2832 - hash: "585f6c25caaafb99a22a23d8a998d202" + hash: "bbc8337950a78c7bfa48aab2635120a8" } Frame { msec: 2848 - hash: "9b245a00ad576666c10f509d8a80a61e" + hash: "0e28ade7f52f3c27e1dbdd6e98be8c7d" } Frame { msec: 2864 - hash: "9b245a00ad576666c10f509d8a80a61e" + hash: "0e28ade7f52f3c27e1dbdd6e98be8c7d" } Frame { msec: 2880 - hash: "3c5d3d10bacc093afc6a9c0b5aa4cddc" + hash: "b496af17513d60d4028bd7402fbfba93" } Frame { msec: 2896 @@ -738,215 +738,215 @@ VisualTest { } Frame { msec: 2912 - hash: "31926d69c2309fdf13fbd7f0e9868c3d" + hash: "29aa7ce0fb1aa350753d3ec6da05bdf9" } Frame { msec: 2928 - hash: "eb3acacce5dd31b0e94b59b9e546ccae" + hash: "fde474797d8105d9d004a7020e010fa4" } Frame { msec: 2944 - hash: "9a51cff3276d75803a0a6e480f7ecb70" + hash: "5a553d9a4bd2ef5d86f5eb37a863d28f" } Frame { msec: 2960 - hash: "fbbd8b9d519993a699815d935bcd2b9f" + hash: "2dcbf6c84abd49529f0b5d85bfb74808" } Frame { msec: 2976 - hash: "0314190c6de73f9f374a4eaed0709645" + hash: "e96ec3b7d37bbf4c9ca297ad5afde31c" } Frame { msec: 2992 - hash: "8ca1a203bdb5446094eb948aeb0a333e" + hash: "9d824068affe32c143226b0b530206fc" } Frame { msec: 3008 - hash: "301e1b86ce38e11ad9d0d7aba0909985" + hash: "3e85f0ace68cffed47f4c9b00145f0f0" } Frame { msec: 3024 - hash: "922095867d0a91b73ab7a63df2041279" + hash: "540b8e1e2bee7d2ba5e29fd3b1086cd1" } Frame { msec: 3040 - hash: "ba8275f3ba4633bf64a1f81f630c90f1" + hash: "0786585d11934c5e4a7e965eaac9a152" } Frame { msec: 3056 - hash: "efe39545279a7bd015d2de75d2b9d8b1" + hash: "8271705df2ca697f4343007a7810d4ac" } Frame { msec: 3072 - hash: "78926c3c0c6fcf89b9291f9902710964" + hash: "b98e1cd20ab2e4239f35d04df5e5175a" } Frame { msec: 3088 - hash: "ea63dcb7f00d3ddede0d8be59ad9d6bc" + hash: "ab1a7eaa5c5d919ee76cba405d0dd4cd" } Frame { msec: 3104 - hash: "286ad493301b713a49e378f123482a53" + hash: "52682386448379a395dc6c541224b7d4" } Frame { msec: 3120 - hash: "a4bbbb8bb88188d3e99996502e3eebd1" + hash: "31dffcb9da94dfc085ab8c561404c248" } Frame { msec: 3136 - hash: "a6100e79f3dc5af594e86ab6cd8dfb76" + hash: "f3703eed8ebf9ece776ebe51e4c60ae6" } Frame { msec: 3152 - hash: "d9e3f777dc89bcf1b7f712206db768e2" + hash: "1126b90345bb42691cd17f37ecec6bdb" } Frame { msec: 3168 - hash: "768045c600c0aa0b1e9e6f012733c600" + hash: "7a63ab96d1c8d4992c03a6f59bba4e7e" } Frame { msec: 3184 - hash: "d8b4caa641ddee786f7898359efe9d07" + hash: "91f4a00c9a7ea6164b334aa4b90da862" } Frame { msec: 3200 - hash: "f7c3b76d5bb7c263ac9447eaad685158" + hash: "485471140f6a5336837377612e7a85bf" } Frame { msec: 3216 - hash: "f7f97db815d653ec29fa31b87f72af2a" + hash: "96881b4021aff05020e0a9342fbae75d" } Frame { msec: 3232 - hash: "18524623762487b60943312cd8bd4388" + hash: "9891326646c3da4ff250aab69c862f96" } Frame { msec: 3248 - hash: "5823dee5dd56e9f7515601f9629ccbae" + hash: "f00f36bbb5a828824c596ee6f85bec2f" } Frame { msec: 3264 - hash: "5823dee5dd56e9f7515601f9629ccbae" + hash: "f00f36bbb5a828824c596ee6f85bec2f" } Frame { msec: 3280 - hash: "5823dee5dd56e9f7515601f9629ccbae" + hash: "f00f36bbb5a828824c596ee6f85bec2f" } Frame { msec: 3296 - hash: "5823dee5dd56e9f7515601f9629ccbae" + hash: "f00f36bbb5a828824c596ee6f85bec2f" } Frame { msec: 3312 - hash: "18524623762487b60943312cd8bd4388" + hash: "9891326646c3da4ff250aab69c862f96" } Frame { msec: 3328 - hash: "430995770b655054aaeda383df8e27f7" + hash: "c766238db55f4704c2f29a6be6ee6907" } Frame { msec: 3344 - hash: "16a3a00f2b89aed676f80d63c4933ec3" + hash: "0254665427dcbd1c155bc954cc7aa7cd" } Frame { msec: 3360 - hash: "6c55aa62079ec546522edbf69c37b270" + hash: "33ae1012816b997ef5c61c03ccfcc590" } Frame { msec: 3376 - hash: "0d68ca3ccecdd831013950cc7405e46e" + hash: "4c7857bbbcb9aa812fc2503af2b395cf" } Frame { msec: 3392 - hash: "9da2511bc8b434218695fa74ed543439" + hash: "3a570e4af992d35e55923cea23c3c11b" } Frame { msec: 3408 - hash: "05afdd0b99dab81a500cdc2b2f0786fe" + hash: "533ef554538005512ce37c73c6def722" } Frame { msec: 3424 - hash: "e6f8882d146ae60bcc6ea47ff41a637b" + hash: "f863fa215d0642708bfa82780c766dc4" } Frame { msec: 3440 - hash: "154542ed0e88321294f382501819aefc" + hash: "fcca3ec34521c4b9087a102ba1e47293" } Frame { msec: 3456 - hash: "8f47b6980c387c5020145bf04645fd2d" + hash: "47d67cd74cb96b12801842b288a8b9ff" } Frame { msec: 3472 - hash: "b34b055c7602f1f4e1cde875b258120c" + hash: "34c5ea76f297ec68cba70521caa468e4" } Frame { msec: 3488 - hash: "5a697f675575f05e297d4877604b9a47" + hash: "7be247cc7a4032ff0478fca1a2aace8a" } Frame { msec: 3504 - hash: "729dff1d1b357d19fc81804ec8940d0e" + hash: "3ade2a1a48edef15f522b9fc016e137e" } Frame { msec: 3520 - hash: "c6f3fee46baa94a6139d2ee40254b160" + hash: "8b37b9d123504931d82bb06f6981bade" } Frame { msec: 3536 - hash: "af0e700bb8ae34834510830f8b44afdb" + hash: "5eb39825003f405f353f629e236b3395" } Frame { msec: 3552 - hash: "9c87bb54c2dfe58c2da9194dae6f7502" + hash: "c4550722260c4a30ab1176c7e5cb62bf" } Frame { msec: 3568 - hash: "2132356a92c75d725f9feafb8201b142" + hash: "bd33e3ecd4b59cd659588c0298b61095" } Frame { msec: 3584 - hash: "50d855d2595eeae2bfd6aaa8c2fa0454" + hash: "4b3a62bff0019df7412aa2e1c07c0a23" } Frame { msec: 3600 - hash: "5fde3c62d6e53a9056e3586f9dcda59e" + hash: "a9b98adcc3350febbb89dbf725b81436" } Frame { msec: 3616 - hash: "8f04460254a1e9fb949d5165894cd92a" + hash: "66eb8c84e75141d1575caf7d3cbc1ceb" } Frame { msec: 3632 - hash: "2b514c5e3b20d30f9c7e71092c69f081" + hash: "238f2b1dc5bf5b65e827c860f9ee76b5" } Frame { msec: 3648 - hash: "2c1ba6224037790e15f5c0f2864ace4d" + hash: "6d1fed0697370b2a2163c369fe559739" } Frame { msec: 3664 - hash: "0d5b8e7bd5f560888aacaf2b3c6827a8" + hash: "04ea478c785586d900bbe3472371bbc7" } Frame { msec: 3680 - hash: "ae25004530e7df134414018e4a34780e" + hash: "ba429e711c9363eebfb20e641fa44c84" } Frame { msec: 3696 - hash: "1a8fd9eaf9a91f1b42924f8986fbed9a" + hash: "0129dfba166ffcbaa15087467c864068" } Frame { msec: 3712 - hash: "2ea6de2025d40ed5beeff12a5b70ccc9" + hash: "3fb340c874eee94e8baa1453b37c3fb5" } Frame { msec: 3728 - hash: "624e417718d3cac1e4b7e4ce258ce6ea" + hash: "068c51d99c458f3edefe3371f46de260" } Frame { msec: 3744 - hash: "8b56d29391257c7be8966af6be26ea9f" + hash: "dd1e04ed3d610c2712158d73ee2c5b9d" } Mouse { type: 3 @@ -958,27 +958,27 @@ VisualTest { } Frame { msec: 3760 - hash: "5c0d977d8b446d9191bde57335cf1062" + hash: "840154afb9e7e0c859c66667bb6944b6" } Frame { msec: 3776 - hash: "100be2b21d069e3a5dbb694a90da4d4f" + hash: "239c2e33800e386b468a95341d0e23f4" } Frame { msec: 3792 - hash: "caab03f6c81080dd8fdbedb4e94ae4a5" + hash: "0a00515f2d297362862c1a5cf6519845" } Frame { msec: 3808 - hash: "3328a4d06f2f80a7e9ccf2ff21522fca" + hash: "f855df3495e44291aed8f085163c804b" } Frame { msec: 3824 - hash: "a534e6cc28daf3eff6a9cf8379bd6375" + hash: "b4eb31e48c65550bb78d175b48e0e9fb" } Frame { msec: 3840 - hash: "6686f9c1a814c6a6b785b70f94937b68" + hash: "70243664f9db83614e5972fc18ee81a1" } Frame { msec: 3856 @@ -986,239 +986,239 @@ VisualTest { } Frame { msec: 3872 - hash: "d3f1c3593375ca5c022a1361a7ec70bd" + hash: "c48ce2a4cf28ab706b9c097bddc74c27" } Frame { msec: 3888 - hash: "67843e6192e2ecaa3820c37dc2f93106" + hash: "754a957e0df02839dd2fe33fefb7a721" } Frame { msec: 3904 - hash: "19a022f678e5b8f4ebdff936162323dc" + hash: "ec3ebe7b941af9bf2163634d7f15e8aa" } Frame { msec: 3920 - hash: "34e55ae70c9e156db339ae15642359c3" + hash: "a76423ff2184cd9dac47abf7ae52ce5a" } Frame { msec: 3936 - hash: "3784778c817f9d9bb73d990cfe12685a" + hash: "559bec54f51c36c6e90004ca5e77c23c" } Frame { msec: 3952 - hash: "0403fdf79e3ba339c7e3786db0c9c0f0" + hash: "dc6fdd6a867a675afcb58f7052605614" } Frame { msec: 3968 - hash: "93e4a0d5645d1cfc916f1e8422655555" + hash: "b2fb0dbbec01490243f37fe5f80ab6c7" } Frame { msec: 3984 - hash: "29080bfabb87160b7c51385fb36b474b" + hash: "2bc1df7a913b1948ee7bb77eeaa55aa2" } Frame { msec: 4000 - hash: "9da2d83edc9d35f00fb8a159e79de4d9" + hash: "82c6430d85c6a94c4b55a9529d2bc78f" } Frame { msec: 4016 - hash: "5505a42d4788f00cfc7499fbfda851ce" + hash: "463e70dc9a9bdabdc158199bdcd7d2fa" } Frame { msec: 4032 - hash: "bdd3040ab16fa9ffdd2fbc66b06699f8" + hash: "c1e9553327f060b70caa713bf3015342" } Frame { msec: 4048 - hash: "2a347e30a20c693a9440caa60ade0a0f" + hash: "42f7f505d4e5ef316240e4f287a039bf" } Frame { msec: 4064 - hash: "0307f1857c091a639d47f112ce1a2f5a" + hash: "200500f600ffe43c5ad4d057bcfc0831" } Frame { msec: 4080 - hash: "778d18e539bbd562ebe39283a6315df1" + hash: "22e78edb813f7830776b2603b0aaae5c" } Frame { msec: 4096 - hash: "0369cf6c3d1f5db2e92ee1f7c5d3b8ed" + hash: "32ebf3490832fd0693b1b922b4501251" } Frame { msec: 4112 - hash: "9f7413587ab50f1abf776bf180ec2d6f" + hash: "1be622caa5ef94f87e2ec8297b6e1caa" } Frame { msec: 4128 - hash: "7d04a27236485808e571e8a39f23ea17" + hash: "d1480529e0cb94c51c412109663e5fab" } Frame { msec: 4144 - hash: "a1dff63b723473d5a4c9c59975a2fb81" + hash: "e55e627d6d13b647f35233f18f0cbe89" } Frame { msec: 4160 - hash: "9795ea70a3b9d3b7805221a58c19e5da" + hash: "87d7b349cd2898de7686e5f1a14f6338" } Frame { msec: 4176 - hash: "f1392c489e21107136eb8e0d1e8b427e" + hash: "2ac974836ee5e6092b55fcda20d7c35d" } Frame { msec: 4192 - hash: "95c225ef07171a96335e99078195b06a" + hash: "53867256c1dac4de2f02af1ae000b49f" } Frame { msec: 4208 - hash: "d46ef3e7f9cec06e8c18afc0d07be4f3" + hash: "08623509e9e5089fdaa1af2bf9a77eb1" } Frame { msec: 4224 - hash: "b017f5b51d423bb0fca0d6df3aaded8b" + hash: "e4692f42c12593ee865048aef00cbeb2" } Frame { msec: 4240 - hash: "60584d085b0cd6fbc436773be678597e" + hash: "981ad6459e3e7483bb323ab4bc514630" } Frame { msec: 4256 - hash: "117951465dfd5c386826b295560d2dec" + hash: "79e8adfcdc9d6dae0d2b6a69e8e322fa" } Frame { msec: 4272 - hash: "1b70137da5f4e024593999e93121fe8b" + hash: "58f967a607972faa9daa13402eeb9912" } Frame { msec: 4288 - hash: "bd50dffd41941fef127f39b55c4748e0" + hash: "1fd5b002b049132565b6a963fb7b3bb6" } Frame { msec: 4304 - hash: "8eec34d8e1d2e22d11b85a671cd4d3aa" + hash: "a16c96598f47404ec5f4ef55e87a1e70" } Frame { msec: 4320 - hash: "9e3c97cfad5002ef5f3fcc365aeb7bd0" + hash: "3c632899804812c93c7edd3e3f3d2bac" } Frame { msec: 4336 - hash: "28e1cf1ee033915ea2ee39c9ab00a73d" + hash: "af0eb810e0273f9bacb082d9f90612df" } Frame { msec: 4352 - hash: "99101a156a553f441f00221f6facbf1f" + hash: "728d7ac4a5410482c7d86d03c2d8a996" } Frame { msec: 4368 - hash: "419023e5d59d16c26b35bee7d3cea559" + hash: "416e76064f2be71a03eddddf61a33cb0" } Frame { msec: 4384 - hash: "485d23519293975b04031fe4baa5c276" + hash: "c41f20b4ac9a7b34eefd066f77ea351a" } Frame { msec: 4400 - hash: "c8bc60735e0ede26dbaf228294853f9a" + hash: "821d51db415a210b09ebdf8d861aadf2" } Frame { msec: 4416 - hash: "ada3680b807d59843e3adf6640704066" + hash: "9394266815a52f1779858bb088d557dc" } Frame { msec: 4432 - hash: "3e28f3adf9241512cd0d6918d81ffffb" + hash: "cc475d1589665414e5aef051ec237ef4" } Frame { msec: 4448 - hash: "8f339acc33cbc89ae1c62391ce021bb3" + hash: "a95f3b8128faa7820f36391fa9bd579f" } Frame { msec: 4464 - hash: "d303960c0853a90557d64a04b8283c94" + hash: "d52687293a11891c364de52525039203" } Frame { msec: 4480 - hash: "f907dbdacf2cfa9fdf8f9c8dead5b4c4" + hash: "5333dc4f65b2f1e066edcd23f7621bd7" } Frame { msec: 4496 - hash: "30c6e6f283f4a3f538cdda9c2e92de8c" + hash: "797bb5e27b2fe2b733a54402433901b4" } Frame { msec: 4512 - hash: "04d2ac55774b43107a43a7d33764199b" + hash: "84c610cdff7f8b04a34977216e37847d" } Frame { msec: 4528 - hash: "cddf3e111cbc59e721725daa1d8a0c31" + hash: "0317f0406a566b2851c8bda62900e40c" } Frame { msec: 4544 - hash: "15b1b63cd1695207ebf9f04387be0739" + hash: "6538ecd7abd35234c5cc5c2a17249fc1" } Frame { msec: 4560 - hash: "690769b9bbe86a3c5b1fbdee39615fbd" + hash: "f9019150a132eb5f5cfafcd5337aff7a" } Frame { msec: 4576 - hash: "2bd640d8ddbf878d808f22656fef1ed9" + hash: "0f0136fffbc65c02cee249ece4c8c0ef" } Frame { msec: 4592 - hash: "a654f1e4519bf883d554276ebbe96323" + hash: "0027e0d236b8b33a451a0cc35e81b4ce" } Frame { msec: 4608 - hash: "68f0313cfc3f51a0bb9b47c5407c19b6" + hash: "ac2f86b2d4f29f223fb78440d67ccd31" } Frame { msec: 4624 - hash: "77f29806b084de4cabf7ab9bf1a93d5e" + hash: "a6eb112a10c849e337f816ee408f22a6" } Frame { msec: 4640 - hash: "f9991189e3282d107b98fb0ae5f5ef00" + hash: "dafbb01f2615a2513310478ebe484a05" } Frame { msec: 4656 - hash: "0cd1f2f6e347d48feea1b26a4968dec7" + hash: "17c400c4c29652dc278980ab578b75b3" } Frame { msec: 4672 - hash: "e75a6f6a088e2289042572a161ffb0e9" + hash: "48696c02a2a4839b893a4c0b431b78a3" } Frame { msec: 4688 - hash: "5a541081444c0a71128223a4c4c3144c" + hash: "04e05c7e722e53299d24cd0f1b7d17ee" } Frame { msec: 4704 - hash: "6813d442cc610f346a5441ed0cd723e5" + hash: "55d158f13ffc7ccde5ee368656d2830b" } Frame { msec: 4720 - hash: "24ec539bc57899819915f833f26deacd" + hash: "fa478e1575acedae023322a520171a5b" } Frame { msec: 4736 - hash: "3a7ed1b4b533b817674aa141c420cd61" + hash: "e2147ddd6e19fde80bb76da24011400c" } Frame { msec: 4752 - hash: "d0a643fae97bb152e97ca60e96299003" + hash: "44ee0144db4c55aa90d2a931d83a895e" } Frame { msec: 4768 - hash: "c84093931520f4661eff6645091a294b" + hash: "552e87bbce4ad48006c899052a2c8cad" } Frame { msec: 4784 - hash: "81e7ceaece82505a4a16ead195a66162" + hash: "3b6efe225303566f751c3f884ac8c069" } Frame { msec: 4800 - hash: "315764d20b647f6ab1ba30239a69bf72" + hash: "3a7175916d1dc103506061607b910550" } Frame { msec: 4816 @@ -1226,239 +1226,239 @@ VisualTest { } Frame { msec: 4832 - hash: "d1824ced8af34ad9edb36a58ae9aa7f5" + hash: "b2e5d5c14b02a13bca62673f87e85627" } Frame { msec: 4848 - hash: "167b9a49fbb94908e09e7e9c9147cd8b" + hash: "bd89a911d6fb13e4e841f8ee5b8b42af" } Frame { msec: 4864 - hash: "442d5f0906840de526d59a80ada322c0" + hash: "89795784185e83d0299e656f2eec73c8" } Frame { msec: 4880 - hash: "78206c4d4d23c7c1ba888b9062b09432" + hash: "5b6d6fe78f341bdf0eb4bedfe3d975d0" } Frame { msec: 4896 - hash: "e898202cfebbff1952efc6e01254d855" + hash: "e246bc451ee48e16ef6dee20d6256e9c" } Frame { msec: 4912 - hash: "ab31dc7bbad2b0552359866bb8d92f0c" + hash: "8c1bc37b1b268743aa314247ea949ef5" } Frame { msec: 4928 - hash: "f093304e88964376baf9721d53d4fb49" + hash: "04f34203c34dc87efc708bfb232663df" } Frame { msec: 4944 - hash: "3ef76f3e1c44d13c3a469bd192ff7b5d" + hash: "d37a48545e81970d16951e3388f0ff8c" } Frame { msec: 4960 - hash: "5d3b6d0d91f8cc5b89e39407bc3b5a15" + hash: "9411e846c9f59cc915288efb59d4c9de" } Frame { msec: 4976 - hash: "3c73573f12f49b34e1d990a55ad913fa" + hash: "6ee179741ac74837708afb55943f15bd" } Frame { msec: 4992 - hash: "d1bac071b01a1c6fddab90cdc435fad4" + hash: "f626fc3166bd5b01171271ae9bfa9b22" } Frame { msec: 5008 - hash: "36a219aadec910f1dbef616c641e1d2b" + hash: "e22898b2c0c566bbf531223234f98327" } Frame { msec: 5024 - hash: "5871fc67d361cc988551592ee21dfb23" + hash: "1343d90c5eae70713cd49110fe61237b" } Frame { msec: 5040 - hash: "6e65ee6c814b9a9da205c36925e663bf" + hash: "493d9322da6d01979a3f1a120c265f8c" } Frame { msec: 5056 - hash: "290b20fa8e91d34000d7c2d81745f6d2" + hash: "defccc76caf3a7c7c67e8abf5ccc2def" } Frame { msec: 5072 - hash: "19e7405a9083a8143f7bb040f8837b29" + hash: "fe3cad9227fcfa7ba2238465078f2ac7" } Frame { msec: 5088 - hash: "c0a0fa2b4c1ceb6c70594994a1ac8713" + hash: "66ebfeee3a63323c7d8b949db9aafd7e" } Frame { msec: 5104 - hash: "c236224c16743fb606deb78bcb8afc8d" + hash: "805820b382d005894f9a615004b97b0d" } Frame { msec: 5120 - hash: "7d44db15eb300b4338ffc26e9bcfce20" + hash: "eee1620f47bb071de8a9c788d1fd258e" } Frame { msec: 5136 - hash: "067a79148a194c45c6f32d85316a1e11" + hash: "f5a7d9a81fcfc8cfb9e7cc8ead0f1ff8" } Frame { msec: 5152 - hash: "9075c379044476994a87f0fdcce8e332" + hash: "249903ee123090b27019350f120c8b79" } Frame { msec: 5168 - hash: "b2316988fbd51096a4f512e71fe7d0a2" + hash: "019793a363c905809af32bf34ef52ec0" } Frame { msec: 5184 - hash: "280f70877d93af5f84e178aad6a102d8" + hash: "4f5ad5a3ebb6eca73dd7567199d07b08" } Frame { msec: 5200 - hash: "3eef4ae7e43a8cf1cd9dd562237296f8" + hash: "fdc1b42d50c7a5c45458498788ff0abd" } Frame { msec: 5216 - hash: "e3184f77ce3a47ca4dca6386f42d7fec" + hash: "cc091469598cad28d0a00690f1acb412" } Frame { msec: 5232 - hash: "a2a5df66fe4808ea8d466cac84ba910c" + hash: "5c8757e1f8f34a31d8b3717b64b84c07" } Frame { msec: 5248 - hash: "9f8a0e54788112d6c30482e840504f35" + hash: "5da75559f60eac1b9f518ed55a174e5b" } Frame { msec: 5264 - hash: "ae69cf84798844f9f360c86790feaecd" + hash: "1214c08daec4dcfb27690fdc18f2ac28" } Frame { msec: 5280 - hash: "0244526572acb6266db5b7eb9d29c6fc" + hash: "87d92c1ba694d0cf187d8616b0f622f0" } Frame { msec: 5296 - hash: "8fb53d60b95ddb5aef27442934ea9983" + hash: "d4af63638fe69b6c4f087a935351057e" } Frame { msec: 5312 - hash: "930fcfde491b4f5681e3861764003895" + hash: "0573c41f34c2c117cada987e4ee813a5" } Frame { msec: 5328 - hash: "bcdcd0a637112d113ebe11dc18823237" + hash: "f179ef4b7bf0f915e25ffd8168a9126f" } Frame { msec: 5344 - hash: "65a564d5a5afbc14c0cdad4d52753507" + hash: "1618bf7c94e7898392eb5ffbf44b8aff" } Frame { msec: 5360 - hash: "0c5056d438d2d54938f31ef5f996673a" + hash: "5af24b902e3729d544f70c77e189b8a7" } Frame { msec: 5376 - hash: "11c157ad2236fc390ffbdf339366cbc1" + hash: "4e5789404e58113cc2d8aa737a03ab58" } Frame { msec: 5392 - hash: "6cb341b1f281a97a35c2e41bfd4c4d9d" + hash: "e4bf91a249e47597e959bbaf25f0724d" } Frame { msec: 5408 - hash: "553a945f7f19f70ddae4ebe88e52a79b" + hash: "39a3e3d6269522ed57a0e37319ab94d5" } Frame { msec: 5424 - hash: "d10b42b4095a2474e66a5a322f72e936" + hash: "f2e2e47922e7e058e14537a0455cd77f" } Frame { msec: 5440 - hash: "0f943d61e8072d70eddee8aa1ba0de5a" + hash: "64abb3f2c9e05fd1dd7490d11c74f06a" } Frame { msec: 5456 - hash: "3df18e237b666e78d57857739b759e6d" + hash: "a9bf45c29536ca34c42aa916747b485b" } Frame { msec: 5472 - hash: "1ddc0bfdb2ca7b6dee63f1024e62f26e" + hash: "da21839b6635e5c4e0a589d163e62752" } Frame { msec: 5488 - hash: "aaa397714528f41238059e3a88833abc" + hash: "f31e49258bcbb2a144daa320e4567df1" } Frame { msec: 5504 - hash: "c94bd69f925c782656afc5f9618180a6" + hash: "f96c5b39f94bf2ac1e3f4de96767d720" } Frame { msec: 5520 - hash: "824ff8c0e1ab43e3c0eaa79b7cc19b9c" + hash: "281b90d1056803093cc37f30465f0e73" } Frame { msec: 5536 - hash: "6c440a0b2293811335bdbf2c4f25f47d" + hash: "d63a2424e1947328957ad8f5f0bec043" } Frame { msec: 5552 - hash: "bfc7936cdf833d5b720ec9baca740112" + hash: "bd510a0de7df02b1b5741824b6f90944" } Frame { msec: 5568 - hash: "375fa305dbae2872dc9b20e59381cc0c" + hash: "47dc4e5ff91cb84c89dd0fc0459f75f2" } Frame { msec: 5584 - hash: "fffd6173aa49e74164dc17a238bcd830" + hash: "4bc46b5e116dd30e1db4d4bb650ed6ed" } Frame { msec: 5600 - hash: "44d9007e00fab161fd393b653255d7f4" + hash: "c6964b89f1962f120028057d1c588694" } Frame { msec: 5616 - hash: "f669ee25c58b4fa20a01705d334f0065" + hash: "39a77544a1c88b68cb63da9a8910a35e" } Frame { msec: 5632 - hash: "2dbb7d57711b67d5d9e1b81f70e22d34" + hash: "bd8ac21d7a507a8e195437ccac254ecc" } Frame { msec: 5648 - hash: "19351b91448265cb95c1670ee283c611" + hash: "7b39b2667a8f8efae20ec8696e35dbc4" } Frame { msec: 5664 - hash: "19351b91448265cb95c1670ee283c611" + hash: "7b39b2667a8f8efae20ec8696e35dbc4" } Frame { msec: 5680 - hash: "3a24b99d048348a21f4e4bd69393de89" + hash: "8628f4f24670d17965fec40a02e0196f" } Frame { msec: 5696 - hash: "35a6fe955a52950bbfa954a453e4008e" + hash: "515903d9896a853cb18cc7b7c45c1cce" } Frame { msec: 5712 - hash: "896f4ec28c976237b34fb2725a44460e" + hash: "b7a3f70bedcb3f90a2e294b447e05f70" } Frame { msec: 5728 - hash: "ed3008ea950ec84c57518e573ea36d15" + hash: "8e8b104ef82b1e219021aa38276f8b45" } Frame { msec: 5744 - hash: "3447c7be992759f772c1db2033eead99" + hash: "70abe79da860bebd2d17a8c7abb20b4e" } Frame { msec: 5760 - hash: "b7133225daa03563d3f5b1dac5f56a23" + hash: "d99af176fb6cf9d9cbcf7cf4286a165c" } Frame { msec: 5776 @@ -1466,239 +1466,239 @@ VisualTest { } Frame { msec: 5792 - hash: "adc55f2fcf312a90b025a75fa80aa079" + hash: "67809c7daad6716d0a664c52de9906ce" } Frame { msec: 5808 - hash: "3ac85cad400d2b8e4f33798f4f6b7b42" + hash: "29a27fd59b7316ce305803482686ea58" } Frame { msec: 5824 - hash: "1c115efd84ccbe489d24c3c521c4a61c" + hash: "25b9ca40d1d6208d026e5c965923f8fb" } Frame { msec: 5840 - hash: "39518f1bbc0c4aba6ff517bc3dc7c279" + hash: "126b1542415aea11dbb35492be4f66aa" } Frame { msec: 5856 - hash: "7bd28d32996f4de61c415d3217da16d0" + hash: "26ca7034536e0e690236797df740f19a" } Frame { msec: 5872 - hash: "f5d06e25d775bf8db07e95625a712733" + hash: "fec9db60af63a4712b0da037cf1d89cd" } Frame { msec: 5888 - hash: "4820ea6ea3be88af2f86111c547a19d7" + hash: "d9b7e2729c75ca0c0f33b542525c4880" } Frame { msec: 5904 - hash: "fa6e681c368118b7f135a47ae8fc12ff" + hash: "89149d16b893ea432b6d0fb05ead48cb" } Frame { msec: 5920 - hash: "f6b30e618aeeb837d2b3eca270b0a060" + hash: "8e389d2ca706277ce06e1da557e2e6c1" } Frame { msec: 5936 - hash: "ac8504bde8d3063a8bf02b9d4b69d755" + hash: "fc5c74473410da1ddd451c5901572172" } Frame { msec: 5952 - hash: "9670537bb77caa8e23fda7bbfa96ca60" + hash: "54514970eadff9362d31499a737e4c95" } Frame { msec: 5968 - hash: "8cd292865ce5c1d240e9ddc93881a0ed" + hash: "d5953bc29532ec49c20ee552c8756ba1" } Frame { msec: 5984 - hash: "de112013e526203d151c46e6cfba9f92" + hash: "5f03be3ed5824e6a6f8f371ce6a47997" } Frame { msec: 6000 - hash: "cd61066e697de8c055aaa168791c2d8c" + hash: "0431e2ec4765167d0099c59df400f3fd" } Frame { msec: 6016 - hash: "cd61066e697de8c055aaa168791c2d8c" + hash: "0431e2ec4765167d0099c59df400f3fd" } Frame { msec: 6032 - hash: "e68b27ff14aac03c827fd43ac488d23e" + hash: "403e1f235770f2b7c8b1b2e86aea69a5" } Frame { msec: 6048 - hash: "e68b27ff14aac03c827fd43ac488d23e" + hash: "403e1f235770f2b7c8b1b2e86aea69a5" } Frame { msec: 6064 - hash: "1f61d857a8c26587fbda5895c603441a" + hash: "32ff9f959598972f5a264418587dca1f" } Frame { msec: 6080 - hash: "1e0dffdd02e05ade1ae444427d4aa345" + hash: "b4c7c07e52a684f7ce21e47a4d66356a" } Frame { msec: 6096 - hash: "9a416ee7a1de9ac45ab2d609233c9520" + hash: "e0f214bed2c3a31f473952929b8f3ea9" } Frame { msec: 6112 - hash: "dfa35bf1cd908011c3214a506bcbdcb8" + hash: "15328b8a205965f3f29fc63a6a8ac8ed" } Frame { msec: 6128 - hash: "bd502dc72dce4af3036f7af9ed7cf9e9" + hash: "72c46ed63633e6879373f4783df25d8b" } Frame { msec: 6144 - hash: "8cd5edce652013a2ed4bf95693259538" + hash: "ae73e0adbdaacc648c2e97840cef4194" } Frame { msec: 6160 - hash: "a38ed1532a40210ad7da4c0d4d1a7195" + hash: "df9451c6634d72e6f794e962b3591086" } Frame { msec: 6176 - hash: "8ac8a8df937da526bbffb9a3590d89ac" + hash: "773e10bbd133e64457e7ddbc73a10fc2" } Frame { msec: 6192 - hash: "07527cb9a4494e11f4c9f99eb72598b9" + hash: "c79abb97eb86761b69053d77156dffd4" } Frame { msec: 6208 - hash: "655b0327ef0f8711810714ba50f2f8cc" + hash: "d927934b19ffd55ea7cea1916983351a" } Frame { msec: 6224 - hash: "4c1ce8b4eb16c69614e2560c04ad48cf" + hash: "ae5058d935c1e44d103be66921b19e77" } Frame { msec: 6240 - hash: "7a382ae4e6a48826eaa2c83ee7a73fb2" + hash: "b6a1446b6be054d5785ba52ac23f8aa8" } Frame { msec: 6256 - hash: "5acd5f250c5b32d9006ed68dfecbfa1c" + hash: "3dffbffded44249fdbe58aecd24ab97f" } Frame { msec: 6272 - hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + hash: "56445ab8554a23a786b70e4fd9f40451" } Frame { msec: 6288 - hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + hash: "56445ab8554a23a786b70e4fd9f40451" } Frame { msec: 6304 - hash: "07e5f1277558bfe7638b00cf9d967baf" + hash: "257ce16f529b99f28beb2e57625f52ee" } Frame { msec: 6320 - hash: "07e5f1277558bfe7638b00cf9d967baf" + hash: "257ce16f529b99f28beb2e57625f52ee" } Frame { msec: 6336 - hash: "07e5f1277558bfe7638b00cf9d967baf" + hash: "257ce16f529b99f28beb2e57625f52ee" } Frame { msec: 6352 - hash: "07e5f1277558bfe7638b00cf9d967baf" + hash: "257ce16f529b99f28beb2e57625f52ee" } Frame { msec: 6368 - hash: "07e5f1277558bfe7638b00cf9d967baf" + hash: "257ce16f529b99f28beb2e57625f52ee" } Frame { msec: 6384 - hash: "877aca1c64e588845329ca8a38222604" + hash: "cb2b0ddbc7b8485fbf32a537e5a98d0e" } Frame { msec: 6400 - hash: "877aca1c64e588845329ca8a38222604" + hash: "cb2b0ddbc7b8485fbf32a537e5a98d0e" } Frame { msec: 6416 - hash: "877aca1c64e588845329ca8a38222604" + hash: "cb2b0ddbc7b8485fbf32a537e5a98d0e" } Frame { msec: 6432 - hash: "877aca1c64e588845329ca8a38222604" + hash: "cb2b0ddbc7b8485fbf32a537e5a98d0e" } Frame { msec: 6448 - hash: "877aca1c64e588845329ca8a38222604" + hash: "cb2b0ddbc7b8485fbf32a537e5a98d0e" } Frame { msec: 6464 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6480 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6496 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6512 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6528 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6544 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6560 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6576 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6592 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6608 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6624 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6640 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6656 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6672 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6688 - hash: "b0f28e923f93dcdcea8460ca9d8cd674" + hash: "fa87436d5e51122022a005d815f97c32" } Frame { msec: 6704 - hash: "228920e994ebf71d542c71ce8263614e" + hash: "da52e87ccd157c0330c07e480b8b0c06" } Frame { msec: 6720 - hash: "228920e994ebf71d542c71ce8263614e" + hash: "da52e87ccd157c0330c07e480b8b0c06" } Frame { msec: 6736 @@ -1706,58 +1706,58 @@ VisualTest { } Frame { msec: 6752 - hash: "228920e994ebf71d542c71ce8263614e" + hash: "da52e87ccd157c0330c07e480b8b0c06" } Frame { msec: 6768 - hash: "228920e994ebf71d542c71ce8263614e" + hash: "da52e87ccd157c0330c07e480b8b0c06" } Frame { msec: 6784 - hash: "228920e994ebf71d542c71ce8263614e" + hash: "da52e87ccd157c0330c07e480b8b0c06" } Frame { msec: 6800 - hash: "228920e994ebf71d542c71ce8263614e" + hash: "da52e87ccd157c0330c07e480b8b0c06" } Frame { msec: 6816 - hash: "228920e994ebf71d542c71ce8263614e" + hash: "da52e87ccd157c0330c07e480b8b0c06" } Frame { msec: 6832 - hash: "07e5f1277558bfe7638b00cf9d967baf" + hash: "257ce16f529b99f28beb2e57625f52ee" } Key { type: 6 key: 16777249 - modifiers: 67108864 + modifiers: 0 text: "" autorep: false count: 1 } Frame { msec: 6848 - hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + hash: "56445ab8554a23a786b70e4fd9f40451" } Frame { msec: 6864 - hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + hash: "56445ab8554a23a786b70e4fd9f40451" } Frame { msec: 6880 - hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + hash: "56445ab8554a23a786b70e4fd9f40451" } Frame { msec: 6896 - hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + hash: "56445ab8554a23a786b70e4fd9f40451" } Frame { msec: 6912 - hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + hash: "56445ab8554a23a786b70e4fd9f40451" } Frame { msec: 6928 - hash: "3189e5a89d7b2ba1e6a06f6e3070e8c1" + hash: "56445ab8554a23a786b70e4fd9f40451" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-X11/parentanchor.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-X11/parentanchor.0.png index d85498b..823199c 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-X11/parentanchor.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-X11/parentanchor.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-X11/parentanchor.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-X11/parentanchor.qml index 26cd97b..4bf0697 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-X11/parentanchor.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/baseline/data-X11/parentanchor.qml @@ -10,122 +10,122 @@ VisualTest { } Frame { msec: 32 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 48 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 64 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 80 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 96 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 112 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 128 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 144 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 160 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 176 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 192 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 208 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 224 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 240 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 256 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 272 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 288 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 304 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 320 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 336 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 352 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 368 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 384 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 400 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 416 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 432 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 448 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 464 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 480 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } Frame { msec: 496 - hash: "8e36621abce059cb8579dd04b28e8d58" + hash: "7e082fa05e000cc20fcda7cb61d98edd" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.0.png index 16202c4..53d3c12 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.1.png index 16202c4..53d3c12 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.qml index c911b0a9..7aadc15 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.qml @@ -10,239 +10,239 @@ VisualTest { } Frame { msec: 32 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 48 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 64 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 80 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 96 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 112 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 128 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 144 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 160 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 176 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 192 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 208 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 224 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 240 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 256 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 272 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 288 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 304 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 320 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 336 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 352 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 368 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 384 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 400 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 416 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 432 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 448 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 464 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 480 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 496 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 512 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 528 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 544 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 560 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 576 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 592 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 608 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 624 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 640 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 656 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 672 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 688 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 704 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 720 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 736 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 752 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 768 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 784 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 800 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 816 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 832 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 848 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 864 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 880 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 896 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 912 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 928 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 944 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 960 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 976 @@ -251,29 +251,29 @@ VisualTest { Key { type: 6 key: 16777249 - modifiers: 67108864 + modifiers: 0 text: "" autorep: false count: 1 } Frame { msec: 992 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 1008 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 1024 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 1040 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } Frame { msec: 1056 - hash: "bfcbea92ed5278c01642fd3cd6d3175c" + hash: "40d4596fcecc4e6a214decccc581a75f" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide2.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide2.0.png index 38b9668..2f4c84a 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide2.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide2.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide2.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide2.1.png index 801ec2b..ae786a2 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide2.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide2.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide2.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide2.qml index 5275c05..6e9057c 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide2.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide2.qml @@ -10,239 +10,239 @@ VisualTest { } Frame { msec: 32 - hash: "0922fd48af050774d53e0b3815d57d8e" + hash: "716f5d150bd8757952d7b4ba327fb8bd" } Frame { msec: 48 - hash: "0922fd48af050774d53e0b3815d57d8e" + hash: "716f5d150bd8757952d7b4ba327fb8bd" } Frame { msec: 64 - hash: "0922fd48af050774d53e0b3815d57d8e" + hash: "716f5d150bd8757952d7b4ba327fb8bd" } Frame { msec: 80 - hash: "0922fd48af050774d53e0b3815d57d8e" + hash: "716f5d150bd8757952d7b4ba327fb8bd" } Frame { msec: 96 - hash: "0922fd48af050774d53e0b3815d57d8e" + hash: "716f5d150bd8757952d7b4ba327fb8bd" } Frame { msec: 112 - hash: "0922fd48af050774d53e0b3815d57d8e" + hash: "716f5d150bd8757952d7b4ba327fb8bd" } Frame { msec: 128 - hash: "6ed734d7092a34e440628dc70db97ac5" + hash: "8ec55fba2017a56c641c7baca5345b8b" } Frame { msec: 144 - hash: "6ed734d7092a34e440628dc70db97ac5" + hash: "8ec55fba2017a56c641c7baca5345b8b" } Frame { msec: 160 - hash: "6ed734d7092a34e440628dc70db97ac5" + hash: "8ec55fba2017a56c641c7baca5345b8b" } Frame { msec: 176 - hash: "6ed734d7092a34e440628dc70db97ac5" + hash: "8ec55fba2017a56c641c7baca5345b8b" } Frame { msec: 192 - hash: "a74b735016141dccf2c84fe9ee1e3ab2" + hash: "79dc1645a5486ddfa3d957f3bd4ffbda" } Frame { msec: 208 - hash: "a74b735016141dccf2c84fe9ee1e3ab2" + hash: "79dc1645a5486ddfa3d957f3bd4ffbda" } Frame { msec: 224 - hash: "a74b735016141dccf2c84fe9ee1e3ab2" + hash: "79dc1645a5486ddfa3d957f3bd4ffbda" } Frame { msec: 240 - hash: "a74b735016141dccf2c84fe9ee1e3ab2" + hash: "79dc1645a5486ddfa3d957f3bd4ffbda" } Frame { msec: 256 - hash: "047416b9368fb352b7da1e073d863e96" + hash: "476eae8ca9f6698cf67e2d20c5c24b66" } Frame { msec: 272 - hash: "047416b9368fb352b7da1e073d863e96" + hash: "476eae8ca9f6698cf67e2d20c5c24b66" } Frame { msec: 288 - hash: "047416b9368fb352b7da1e073d863e96" + hash: "476eae8ca9f6698cf67e2d20c5c24b66" } Frame { msec: 304 - hash: "047416b9368fb352b7da1e073d863e96" + hash: "476eae8ca9f6698cf67e2d20c5c24b66" } Frame { msec: 320 - hash: "f2d62e8675b8bba924b27db689c9cd7f" + hash: "bef1a9585daf30f1739a190ffa2e4b46" } Frame { msec: 336 - hash: "f2d62e8675b8bba924b27db689c9cd7f" + hash: "bef1a9585daf30f1739a190ffa2e4b46" } Frame { msec: 352 - hash: "f2d62e8675b8bba924b27db689c9cd7f" + hash: "bef1a9585daf30f1739a190ffa2e4b46" } Frame { msec: 368 - hash: "f2d62e8675b8bba924b27db689c9cd7f" + hash: "bef1a9585daf30f1739a190ffa2e4b46" } Frame { msec: 384 - hash: "f2d62e8675b8bba924b27db689c9cd7f" + hash: "bef1a9585daf30f1739a190ffa2e4b46" } Frame { msec: 400 - hash: "9498a80d60ab24d82ffb935979e1cf1b" + hash: "156dfc4e9fbc1af5e8c6c48ecd2afe8f" } Frame { msec: 416 - hash: "9498a80d60ab24d82ffb935979e1cf1b" + hash: "156dfc4e9fbc1af5e8c6c48ecd2afe8f" } Frame { msec: 432 - hash: "9498a80d60ab24d82ffb935979e1cf1b" + hash: "156dfc4e9fbc1af5e8c6c48ecd2afe8f" } Frame { msec: 448 - hash: "9498a80d60ab24d82ffb935979e1cf1b" + hash: "156dfc4e9fbc1af5e8c6c48ecd2afe8f" } Frame { msec: 464 - hash: "ee3cb45a15460f4235fc22ca97e0303d" + hash: "2fe675a360e61452c31dda42070c137f" } Frame { msec: 480 - hash: "ee3cb45a15460f4235fc22ca97e0303d" + hash: "2fe675a360e61452c31dda42070c137f" } Frame { msec: 496 - hash: "ee3cb45a15460f4235fc22ca97e0303d" + hash: "2fe675a360e61452c31dda42070c137f" } Frame { msec: 512 - hash: "ee3cb45a15460f4235fc22ca97e0303d" + hash: "2fe675a360e61452c31dda42070c137f" } Frame { msec: 528 - hash: "94464db418aec12b451e9dc106deec73" + hash: "0f1bac7c35b9f5bdbce10fb577c9cf28" } Frame { msec: 544 - hash: "94464db418aec12b451e9dc106deec73" + hash: "0f1bac7c35b9f5bdbce10fb577c9cf28" } Frame { msec: 560 - hash: "94464db418aec12b451e9dc106deec73" + hash: "0f1bac7c35b9f5bdbce10fb577c9cf28" } Frame { msec: 576 - hash: "94464db418aec12b451e9dc106deec73" + hash: "0f1bac7c35b9f5bdbce10fb577c9cf28" } Frame { msec: 592 - hash: "94464db418aec12b451e9dc106deec73" + hash: "0f1bac7c35b9f5bdbce10fb577c9cf28" } Frame { msec: 608 - hash: "22b23a55986e912cf38239d5e68f0c4a" + hash: "c79f68e9481f91f6f6a6816a655efc24" } Frame { msec: 624 - hash: "22b23a55986e912cf38239d5e68f0c4a" + hash: "c79f68e9481f91f6f6a6816a655efc24" } Frame { msec: 640 - hash: "22b23a55986e912cf38239d5e68f0c4a" + hash: "c79f68e9481f91f6f6a6816a655efc24" } Frame { msec: 656 - hash: "22b23a55986e912cf38239d5e68f0c4a" + hash: "c79f68e9481f91f6f6a6816a655efc24" } Frame { msec: 672 - hash: "3836d0aaf354d147dc6ffe3ace184ba5" + hash: "9a189e9d9249fb04fd98c4e91aba1cb5" } Frame { msec: 688 - hash: "3836d0aaf354d147dc6ffe3ace184ba5" + hash: "9a189e9d9249fb04fd98c4e91aba1cb5" } Frame { msec: 704 - hash: "3836d0aaf354d147dc6ffe3ace184ba5" + hash: "9a189e9d9249fb04fd98c4e91aba1cb5" } Frame { msec: 720 - hash: "3836d0aaf354d147dc6ffe3ace184ba5" + hash: "9a189e9d9249fb04fd98c4e91aba1cb5" } Frame { msec: 736 - hash: "3836d0aaf354d147dc6ffe3ace184ba5" + hash: "9a189e9d9249fb04fd98c4e91aba1cb5" } Frame { msec: 752 - hash: "20ccea5bc4c15401a7c660b1801488dd" + hash: "42c1ac48858ab5901601dc5a950a398f" } Frame { msec: 768 - hash: "20ccea5bc4c15401a7c660b1801488dd" + hash: "42c1ac48858ab5901601dc5a950a398f" } Frame { msec: 784 - hash: "20ccea5bc4c15401a7c660b1801488dd" + hash: "42c1ac48858ab5901601dc5a950a398f" } Frame { msec: 800 - hash: "20ccea5bc4c15401a7c660b1801488dd" + hash: "42c1ac48858ab5901601dc5a950a398f" } Frame { msec: 816 - hash: "31ffa9cfd6f60a33ed3b052e45ee5080" + hash: "f05bf4e3cc562c5a900fb389a7c093de" } Frame { msec: 832 - hash: "31ffa9cfd6f60a33ed3b052e45ee5080" + hash: "f05bf4e3cc562c5a900fb389a7c093de" } Frame { msec: 848 - hash: "31ffa9cfd6f60a33ed3b052e45ee5080" + hash: "f05bf4e3cc562c5a900fb389a7c093de" } Frame { msec: 864 - hash: "31ffa9cfd6f60a33ed3b052e45ee5080" + hash: "f05bf4e3cc562c5a900fb389a7c093de" } Frame { msec: 880 - hash: "7138b38fcff27e85aaf3179c6e81ac69" + hash: "1b5d1234aa02009ec447ac8fefc403bb" } Frame { msec: 896 - hash: "7138b38fcff27e85aaf3179c6e81ac69" + hash: "1b5d1234aa02009ec447ac8fefc403bb" } Frame { msec: 912 - hash: "7138b38fcff27e85aaf3179c6e81ac69" + hash: "1b5d1234aa02009ec447ac8fefc403bb" } Frame { msec: 928 - hash: "7138b38fcff27e85aaf3179c6e81ac69" + hash: "1b5d1234aa02009ec447ac8fefc403bb" } Frame { msec: 944 - hash: "7138b38fcff27e85aaf3179c6e81ac69" + hash: "1b5d1234aa02009ec447ac8fefc403bb" } Frame { msec: 960 - hash: "78854022288d4cd50bb9141896403d35" + hash: "ec7cfc539d7bde448c631da211de8f44" } Frame { msec: 976 @@ -250,151 +250,151 @@ VisualTest { } Frame { msec: 992 - hash: "78854022288d4cd50bb9141896403d35" + hash: "ec7cfc539d7bde448c631da211de8f44" } Frame { msec: 1008 - hash: "78854022288d4cd50bb9141896403d35" + hash: "ec7cfc539d7bde448c631da211de8f44" } Frame { msec: 1024 - hash: "8730d8adb4029b157e39b90e3cb2b879" + hash: "646394dd534a32bc3a066e606cc485f3" } Frame { msec: 1040 - hash: "8730d8adb4029b157e39b90e3cb2b879" + hash: "646394dd534a32bc3a066e606cc485f3" } Frame { msec: 1056 - hash: "8730d8adb4029b157e39b90e3cb2b879" + hash: "646394dd534a32bc3a066e606cc485f3" } Frame { msec: 1072 - hash: "8730d8adb4029b157e39b90e3cb2b879" + hash: "646394dd534a32bc3a066e606cc485f3" } Frame { msec: 1088 - hash: "9edb542976d1acd86be3d516276dee1f" + hash: "6b66b968aaed1896e2e9fafe27bba50f" } Frame { msec: 1104 - hash: "9edb542976d1acd86be3d516276dee1f" + hash: "6b66b968aaed1896e2e9fafe27bba50f" } Frame { msec: 1120 - hash: "9edb542976d1acd86be3d516276dee1f" + hash: "6b66b968aaed1896e2e9fafe27bba50f" } Frame { msec: 1136 - hash: "9edb542976d1acd86be3d516276dee1f" + hash: "6b66b968aaed1896e2e9fafe27bba50f" } Frame { msec: 1152 - hash: "9edb542976d1acd86be3d516276dee1f" + hash: "6b66b968aaed1896e2e9fafe27bba50f" } Frame { msec: 1168 - hash: "1a394542b01712fbd67b78a69733b324" + hash: "869f75182b9a4b452da1689a5921085f" } Frame { msec: 1184 - hash: "1a394542b01712fbd67b78a69733b324" + hash: "869f75182b9a4b452da1689a5921085f" } Frame { msec: 1200 - hash: "1a394542b01712fbd67b78a69733b324" + hash: "869f75182b9a4b452da1689a5921085f" } Frame { msec: 1216 - hash: "1a394542b01712fbd67b78a69733b324" + hash: "869f75182b9a4b452da1689a5921085f" } Frame { msec: 1232 - hash: "4825f9a6679fdee8efe89507d384c07c" + hash: "b2017890ac543b9224e85a44157d9fbb" } Frame { msec: 1248 - hash: "4825f9a6679fdee8efe89507d384c07c" + hash: "b2017890ac543b9224e85a44157d9fbb" } Frame { msec: 1264 - hash: "4825f9a6679fdee8efe89507d384c07c" + hash: "b2017890ac543b9224e85a44157d9fbb" } Frame { msec: 1280 - hash: "4825f9a6679fdee8efe89507d384c07c" + hash: "b2017890ac543b9224e85a44157d9fbb" } Frame { msec: 1296 - hash: "4825f9a6679fdee8efe89507d384c07c" + hash: "b2017890ac543b9224e85a44157d9fbb" } Frame { msec: 1312 - hash: "0ed5382fd2e370bad934647d7abf293f" + hash: "acac3eb92619e01b3470511cef1a91c8" } Frame { msec: 1328 - hash: "0ed5382fd2e370bad934647d7abf293f" + hash: "acac3eb92619e01b3470511cef1a91c8" } Frame { msec: 1344 - hash: "0ed5382fd2e370bad934647d7abf293f" + hash: "acac3eb92619e01b3470511cef1a91c8" } Frame { msec: 1360 - hash: "0ed5382fd2e370bad934647d7abf293f" + hash: "acac3eb92619e01b3470511cef1a91c8" } Frame { msec: 1376 - hash: "6206435ab4d05d5d5f84b362d45c30f9" + hash: "7f6d45b22e5cb86a7fb45d3f9bcebfc1" } Frame { msec: 1392 - hash: "6206435ab4d05d5d5f84b362d45c30f9" + hash: "7f6d45b22e5cb86a7fb45d3f9bcebfc1" } Frame { msec: 1408 - hash: "6206435ab4d05d5d5f84b362d45c30f9" + hash: "7f6d45b22e5cb86a7fb45d3f9bcebfc1" } Frame { msec: 1424 - hash: "6206435ab4d05d5d5f84b362d45c30f9" + hash: "7f6d45b22e5cb86a7fb45d3f9bcebfc1" } Frame { msec: 1440 - hash: "b0eb92df767e7cb61cc69d7363041263" + hash: "481f661e2613242d253498e467c91105" } Frame { msec: 1456 - hash: "b0eb92df767e7cb61cc69d7363041263" + hash: "481f661e2613242d253498e467c91105" } Frame { msec: 1472 - hash: "b0eb92df767e7cb61cc69d7363041263" + hash: "481f661e2613242d253498e467c91105" } Frame { msec: 1488 - hash: "b0eb92df767e7cb61cc69d7363041263" + hash: "481f661e2613242d253498e467c91105" } Frame { msec: 1504 - hash: "b0eb92df767e7cb61cc69d7363041263" + hash: "481f661e2613242d253498e467c91105" } Frame { msec: 1520 - hash: "0306262c9594536e0eecf3d67e5910cf" + hash: "4c342918351f0165ce63129afbd60074" } Frame { msec: 1536 - hash: "0306262c9594536e0eecf3d67e5910cf" + hash: "4c342918351f0165ce63129afbd60074" } Frame { msec: 1552 - hash: "0306262c9594536e0eecf3d67e5910cf" + hash: "4c342918351f0165ce63129afbd60074" } Frame { msec: 1568 - hash: "0306262c9594536e0eecf3d67e5910cf" + hash: "4c342918351f0165ce63129afbd60074" } Frame { msec: 1584 @@ -443,7 +443,7 @@ VisualTest { Key { type: 6 key: 16777249 - modifiers: 0 + modifiers: 67108864 text: "" autorep: false count: 1 diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.0.png index 730925e..bf41ce8 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.1.png index ddd6cc5..683a452 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.2.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.2.png index 4679774..6b4a280 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.2.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.3.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.3.png index 51018b4..ddf5431 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.3.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.4.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.4.png index f5ed905..7e56a3c 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.4.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.qml index faf7240..7b17ab2 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.qml @@ -10,239 +10,239 @@ VisualTest { } Frame { msec: 32 - hash: "12cd5401549bc43283d6c46964528b9b" + hash: "b5dfa53607ab952a07d77b4d6bd53a4a" } Frame { msec: 48 - hash: "ae042a0f3c6e32550288a9b0e6a0ce0d" + hash: "c9b99388f7570a65162026739c365edd" } Frame { msec: 64 - hash: "9124b4e5f5dd374e44f3f57fe3d6809b" + hash: "6f612fe36fa8028a75f6149390bd3585" } Frame { msec: 80 - hash: "54dabe45069a00c8759bb5560c9b269f" + hash: "efada1cf68ff7dae90962e7540c79b53" } Frame { msec: 96 - hash: "0d908ef6e3ea15455e35a9ebbc90c735" + hash: "f42b6952937376ae34f7ef493e86aee6" } Frame { msec: 112 - hash: "de5fcf719cd096b99a531e7af9b26e35" + hash: "008b0419f3ec6dbb16220a8e484a1ec8" } Frame { msec: 128 - hash: "d48ccb7c22c2606ef814cd5abd3888f3" + hash: "ecb3c1cb02f7a01d4343dad1a066fa6f" } Frame { msec: 144 - hash: "2ec7418477158ee60afe123fa2b7ce4b" + hash: "ce5adf6c5c4d5e385ce7e461e380b00e" } Frame { msec: 160 - hash: "418d6d46726c688bee6f415eb2ff2e43" + hash: "79b8fefae0ac2784391c15c0221bd99d" } Frame { msec: 176 - hash: "e754141341d9f81366f21820e46bd1ca" + hash: "259da9a4c2bb9c89d16dd1943645e836" } Frame { msec: 192 - hash: "89b4b5f7563bfdb5d1e636a5462e0d8e" + hash: "40ee5004fed2af60ab5fc4983bd2dacd" } Frame { msec: 208 - hash: "46c3a7d4700a9599d474b7de1ab44a18" + hash: "935314bef478d43e30b6cbdcb33ba72b" } Frame { msec: 224 - hash: "c50698470bc6c1ea04633b9e819a2d4d" + hash: "9860af14b459925078467f334bf41e42" } Frame { msec: 240 - hash: "dc7d5345363cad6ee007f162f9ea75e2" + hash: "d9955eabd55559d7bef3f4cd96b42a35" } Frame { msec: 256 - hash: "3b9ccb93f6375ea401c1fc3bcdf847d5" + hash: "7fa3de8afdeb61c6e2e87cde2e96152f" } Frame { msec: 272 - hash: "6d034da407af9e27ce70e9dbfee3bb38" + hash: "0deea16d1f6d18f1e9c57546b485fe75" } Frame { msec: 288 - hash: "3bce938e5db4c2295cd25a6e2b33738c" + hash: "231a71ad0981525d9eb15643bc397130" } Frame { msec: 304 - hash: "68266f4f9da256b9df499285ebb842fb" + hash: "119e67ab3b30bd9a716ad81bbb10d626" } Frame { msec: 320 - hash: "a9c912fd159baadc4afcd963f857e91b" + hash: "4f29d912920ab6b8973a2c392a19ea53" } Frame { msec: 336 - hash: "85cb9086774297b2772e71229f7d84fc" + hash: "8544592eb1d48a55cfd0e274c05622cb" } Frame { msec: 352 - hash: "585e6f2d28ec70d10741a52fb68d718c" + hash: "eca3de3a1f3e388a0029ea03327e4b21" } Frame { msec: 368 - hash: "bfd552ccaccc569d2478ac4d92fe2eb0" + hash: "7672135d842f0f6f3a06c19e320b9431" } Frame { msec: 384 - hash: "748d57dff4cdc09a842353e51de41e5a" + hash: "49b5720ebbb03a9c61aebdc6eaf6b2a8" } Frame { msec: 400 - hash: "e0012622a4ef1d5b2090c02020b676c2" + hash: "7d2ddf271385fef343412c43a41d88da" } Frame { msec: 416 - hash: "8e4d4a808564a8ba80578600104f230d" + hash: "3df6034ff296ab1242146ba7298a9dd8" } Frame { msec: 432 - hash: "d92e44d8e1f7651a9d256e9e4f3e8168" + hash: "5a52202453c359370c017a397cbc6f20" } Frame { msec: 448 - hash: "d99b016a0dfdb332dbb1a2c10f53bc05" + hash: "649d58d817e37e7b14d3080998dbc126" } Frame { msec: 464 - hash: "3ce4357881a34f4c9e2f0d684218e253" + hash: "f00b682156bde560b571e0044eff150a" } Frame { msec: 480 - hash: "07ee4bb59f7ee591bd7a6f117d9f1aa6" + hash: "0e5ce3806c60e7a67e72ee9f4c334454" } Frame { msec: 496 - hash: "f66ce51f2eece9f0fa89c41340245976" + hash: "9d8c0e6a6a66560752abc68de10a6ec0" } Frame { msec: 512 - hash: "a9d2b2d4f6ae5e071897d17469a5bad3" + hash: "ffd81c8901cdf67ec3fa574b606eba89" } Frame { msec: 528 - hash: "55db2dbd65cae186d59cb2edb5841880" + hash: "56b7098e63f8cc1d8957829e7779ae73" } Frame { msec: 544 - hash: "576297445ee3f89994538fcd8c8b102c" + hash: "7d7417b2b2c07c93bf5d951fddf4363b" } Frame { msec: 560 - hash: "6ca41b83b8ff27f97c71a23d1c7f9765" + hash: "a2dd725545042e9b6a366d809d2cfc4f" } Frame { msec: 576 - hash: "7e41ef79cae5966821106df39f6a748d" + hash: "8fd5ccba4b997a96f7773936afc4fc92" } Frame { msec: 592 - hash: "9e8b750bbb3680f90d6bbddb6e394d5e" + hash: "85f29eae877f93c4617a37b5c445c605" } Frame { msec: 608 - hash: "9a61dddcc33ff2b778097b5edb706912" + hash: "a8eb3ebef75081964a6beba533eba89b" } Frame { msec: 624 - hash: "395d015e538dde494059df392379ba26" + hash: "8c3e3f4833419e7df6de0c9443390751" } Frame { msec: 640 - hash: "d1db5dc62ca702f4241e45811aebe6f3" + hash: "537f3d9760f6cc0c07452ea3f334a008" } Frame { msec: 656 - hash: "18f1a038041bd8a51f3375ca64084251" + hash: "93a1851ca2afb595ad684a7f613e860c" } Frame { msec: 672 - hash: "6c0f6360156cb806a8b30cafc69013af" + hash: "fd353e60da99a884f60a2d1ab6e4be46" } Frame { msec: 688 - hash: "69525e71fe8fe9847ff956e40c2c45ec" + hash: "21cff9dcfa9e7bb4a44d75338e314d0e" } Frame { msec: 704 - hash: "ac7ae453f35a05e760976df6d91206e2" + hash: "64153f5d57b7191f5e957f22dcdff6d3" } Frame { msec: 720 - hash: "c96358482f0900a906b2fc4742981e3a" + hash: "211d8e9b6427129e4b9292fc862edfb6" } Frame { msec: 736 - hash: "2cccb8f6a63f21d01cd3b61a97730bf8" + hash: "35f96f202391dc805b0bbb45d7efb1bf" } Frame { msec: 752 - hash: "bf01c0cb968768199f3158e6cefcb09f" + hash: "0336a1ba71d4bf7b4cbf98812ba1ae9c" } Frame { msec: 768 - hash: "0ac63c33649462f06979de77c042476c" + hash: "c5ec3a61d64228efe448b0d5c0004baa" } Frame { msec: 784 - hash: "61931edba8d1abcdc07bb43e17446f4e" + hash: "9154774bce1d89b84c0f525e282bc95d" } Frame { msec: 800 - hash: "e8122f997a4076055d8addda88c4ad6e" + hash: "8d07794b2b17971ff69ff7961c441765" } Frame { msec: 816 - hash: "cc7e654138605c25cb21aa8966361cf4" + hash: "086c711c3794f8ad8d634ed6483f3caf" } Frame { msec: 832 - hash: "177aaec34c677b21798de1e024860490" + hash: "af591122aee8c949957ae19136505a57" } Frame { msec: 848 - hash: "d0fe9544e55f6876908d9c118366f038" + hash: "c84db4548f53ae95023e56fad3c4aea3" } Frame { msec: 864 - hash: "f713b7e11bf61a0f0a06e6aedb36b7f1" + hash: "d7a7bb5cfb91923db8d72d9a12f0016c" } Frame { msec: 880 - hash: "b703bd46b9f355711318882194f28d52" + hash: "7171788040f36bf1c878678906a84290" } Frame { msec: 896 - hash: "047dad73e6c845704f3de6b317ce9290" + hash: "d2016d9ba6b29c7dfb5d64e506e7f980" } Frame { msec: 912 - hash: "8c48b0963af8d71fc245373083c14a93" + hash: "75945e6719cea6aaf021fcd28dfe4da0" } Frame { msec: 928 - hash: "d11944e0d9035b6eff85ca9fc5adc2c0" + hash: "e203a20fc8dda077ff217ac74895b8f6" } Frame { msec: 944 - hash: "d650943a979c7bf52fff77063406c46d" + hash: "1acb696745e0ead2f8c9d807787ce225" } Frame { msec: 960 - hash: "13d533b5b3b01be7dbad7b8403ce1c24" + hash: "b8d60fcd3e262dc33d623a741fdafb0b" } Frame { msec: 976 @@ -250,239 +250,239 @@ VisualTest { } Frame { msec: 992 - hash: "ba51fa05accf637b31328ab0a11e4b61" + hash: "0acda3300bec26515f7ddfd33af6ca84" } Frame { msec: 1008 - hash: "25c783c07b5eb03c351274c3b6494e24" + hash: "12f5c647778c868638845fd66c825f51" } Frame { msec: 1024 - hash: "5665113db0b932b07ac707875e5d77e6" + hash: "e87432496a570b68c18d563fd3e55b7c" } Frame { msec: 1040 - hash: "aceeb64e5935f1889828f3487767db3e" + hash: "332a165345a53198ec22a69e12a7cd6c" } Frame { msec: 1056 - hash: "7c66c51a9fd694940a93a7acf036e6d3" + hash: "92f7d768af912807dca6ad16006d84e9" } Frame { msec: 1072 - hash: "8b699d11b0a8c7df7df448f5c27a0bc2" + hash: "50c330c7e9ed8f08e4b496b322fed388" } Frame { msec: 1088 - hash: "c592cebdfadf68eecbddb0add92afa42" + hash: "554317004bc31ba56c970fac294577df" } Frame { msec: 1104 - hash: "e175f718809eea5b38a1de46f061871f" + hash: "3c6391b4296451f1ca1db737e4d928c3" } Frame { msec: 1120 - hash: "3182ba22228e8cd056db81eea4678b5d" + hash: "8274fa399e0b132582389c909775e8cb" } Frame { msec: 1136 - hash: "e09776f37769f34bd2d856c6af3a1e53" + hash: "f66504b79f0415652f4c6720a2643afe" } Frame { msec: 1152 - hash: "085f9dd2539b950d9f62bdcdf4f3b172" + hash: "53ce26d4f839451868c70133c3f0dff2" } Frame { msec: 1168 - hash: "3c290084b9c251e039aef4df8581ed31" + hash: "715b6a5090e0a947cbbd5f8902088177" } Frame { msec: 1184 - hash: "893f5dc3cd01ace8d31ebc63e0d7e132" + hash: "3715a52358febdbfa4aeefe56b4b173e" } Frame { msec: 1200 - hash: "5cadde434641daffa52965659a4a056f" + hash: "d89459730ea136a34135fded35bc2247" } Frame { msec: 1216 - hash: "741d34abca5ba1a2e5678f3ca272dbd3" + hash: "ba8471a6c2449a05dfe411b86a38ff35" } Frame { msec: 1232 - hash: "96dd3f940c637b085026e224021239bd" + hash: "5c477b14e0ff59e5d7db360005deaea7" } Frame { msec: 1248 - hash: "df8334c4ce1ca5f2317a771e787aea96" + hash: "becdcaa9d4f78d94e3f3af87467798bd" } Frame { msec: 1264 - hash: "aeef63be208b75c9246248025c977b75" + hash: "2b1f5c5c6a9f26e6b359cf786591d480" } Frame { msec: 1280 - hash: "8722a8e9b1cca4cf20ec31da27f38614" + hash: "9b1cbb944a941fd2869ac193e9701582" } Frame { msec: 1296 - hash: "bdc1392f8e1a55e7c970502785024a89" + hash: "e1c67be1ec2030529335c02099a3d9cc" } Frame { msec: 1312 - hash: "ed2be797ca3d623ca532fea7ca5b1f2c" + hash: "4f4ecadaa0afad0e38530067ee7688b9" } Frame { msec: 1328 - hash: "bb79d75488df131bf5443371c6b4464f" + hash: "13f13cb8ea96d764c93ab43f538af2a7" } Frame { msec: 1344 - hash: "0b7dd91d5bc8290d4be1a0af6b2756c2" + hash: "cd33ccd1ac45f1f83cf93cfbdefa415a" } Frame { msec: 1360 - hash: "4f1c88a745105934fb94a6a3e3620602" + hash: "8c84a3842a8da763c4b398e49a13831f" } Frame { msec: 1376 - hash: "c5a3b476c66e9b6a33f93d5114303669" + hash: "3b47b3c27171032450a421ae8ecc786d" } Frame { msec: 1392 - hash: "3104791545798f8e43ca976c893d078f" + hash: "524517523cb15d7886c6dbfa8724ea95" } Frame { msec: 1408 - hash: "3c8c329b4c757ab37054cbcc93840a75" + hash: "3ae90a6ed20fe62da9fb81b51d6d9a1e" } Frame { msec: 1424 - hash: "36b1fc7d93664005449d818dd063c8e7" + hash: "70c0880f0d0d1deefc22baebbeda06c3" } Frame { msec: 1440 - hash: "25927d84d7394e912977d25ddf555ddf" + hash: "d97f6cda6df39ffe1db076204191bba6" } Frame { msec: 1456 - hash: "6f226e26d6a40b3688923fb833ce0fd9" + hash: "d170a0b8339bd0c29b664403ce8b3286" } Frame { msec: 1472 - hash: "75aaa5301fc8d716371d9fcec6491e81" + hash: "fd962a3a4e2fbe03f6730136cdc2a824" } Frame { msec: 1488 - hash: "fb87bcb1b620d48d6bfa6eeb94025907" + hash: "75bcbfc7d7bf3139538347b17b41cf12" } Frame { msec: 1504 - hash: "88231c28ef82974f8eb47060e64176d0" + hash: "0fcba8fa11a2f3fc7ebcefee6e9dafcd" } Frame { msec: 1520 - hash: "06db390a17fc2fa4a93012a168801d05" + hash: "621f80511b2ce7106b1d285045f505ca" } Frame { msec: 1536 - hash: "41400211939574696e04bcd615130f34" + hash: "be6896d8de4bbb8b7ef9e1d34f6f7f32" } Frame { msec: 1552 - hash: "ca979c24603d8cd31583c1670f15b1a9" + hash: "a770cffe72c2791d6d76c16926f98f2f" } Frame { msec: 1568 - hash: "515a32b5c4567c8dec3004c41214daa1" + hash: "7e8222f9831e235c7d044b5188a20dd1" } Frame { msec: 1584 - hash: "d4fbe8e354db8b1b5fc543daf7007fdb" + hash: "a740dfb5ae432712abb4f5f9479a22fa" } Frame { msec: 1600 - hash: "ec6351064566a120836cb115bb81e46a" + hash: "a731135b3ac067712081b959f27d8784" } Frame { msec: 1616 - hash: "74dcd99e1ba3e5e8447d2695e4c4acd9" + hash: "c6cdb85a28bdc970cf2a30f0e2cef763" } Frame { msec: 1632 - hash: "7a751f44c384b87b0c2f633932587795" + hash: "4c901d5879cd4e1602b4f3560745f0b1" } Frame { msec: 1648 - hash: "04e45b241cf498777835f74feeea0c15" + hash: "ef64a09b2bd30a6c618ac59a8cacd628" } Frame { msec: 1664 - hash: "66096d2ef700bb64771fa192219e034a" + hash: "816f55f5b0b8e3baa52e274ae737ee30" } Frame { msec: 1680 - hash: "1dd2437b0f63a8acaa8c62819d7de10e" + hash: "90db19b8b2d820d36d7a45518f730014" } Frame { msec: 1696 - hash: "89e6b25fc16c5d1eba04cd0f7bd2f910" + hash: "f94248d3df175536a4a6b88722763d75" } Frame { msec: 1712 - hash: "7cd23dbc40340bc3652255d4a65ce7ec" + hash: "d1aa57e0666a7d9b5b0dc7b021a1387c" } Frame { msec: 1728 - hash: "5f94c6ba73d2dbeb8ec90b17cb7fab6f" + hash: "77b17a540862f5ec6b2256408fd3637f" } Frame { msec: 1744 - hash: "e8e01bc97bbd349e2f64a59d13ca25a3" + hash: "e9b9a37996f5825006565f5b56e755ea" } Frame { msec: 1760 - hash: "a0cf054ef1005191637173a22e325891" + hash: "1ce712e1755047d17d5cf3c97cff1c96" } Frame { msec: 1776 - hash: "fa8b35c0141049d691735b26eb9410ac" + hash: "95c21bab93788ed45280e61c51173a99" } Frame { msec: 1792 - hash: "c55b4d3a3ee530480d0a0e0aa52f340f" + hash: "6f62ae9bba2b1d2ea67f13d63157bd7c" } Frame { msec: 1808 - hash: "b2639e3e32e513c991525a87448e805d" + hash: "b5f11412bdb100f88a1f29aa577316e5" } Frame { msec: 1824 - hash: "d66f25378bbec3eca675a90795567825" + hash: "d4e2468ed0935687e370fcf70059f57f" } Frame { msec: 1840 - hash: "13bb009108dfcdc861a16ab33a3c4f3a" + hash: "e7b5970ef9f327a8e7905f1a16c3f1a3" } Frame { msec: 1856 - hash: "3a09ccaf62d8929def529260da98dc7a" + hash: "c5b9694fe2d7952d6ef03ff5febec00b" } Frame { msec: 1872 - hash: "79564d7447732fcfdbb81ff2bcd85a4f" + hash: "0604da4b328d80162fd88bdfcf2a8a68" } Frame { msec: 1888 - hash: "149c65ef5ec18af4fd264fa284bfa027" + hash: "cbeffb3c86fcd7b52672382d6a186692" } Frame { msec: 1904 - hash: "e5370728e870ac9f907aafbd17526631" + hash: "deb96a6469b351f5e70d3032ad250df9" } Frame { msec: 1920 - hash: "98034cff5b93c905bbc53cf9582bc4be" + hash: "d4bcb6da72c0b7f2e0e55be917eb5720" } Frame { msec: 1936 @@ -490,239 +490,239 @@ VisualTest { } Frame { msec: 1952 - hash: "05c3a8016110ad576c349964af3d4d05" + hash: "c044b96932667fd56ca8c87ec70791a3" } Frame { msec: 1968 - hash: "91caa4f007dfd1ab7994a11bf4b4fa94" + hash: "f197116b796c3647986337515c04a812" } Frame { msec: 1984 - hash: "d1fb233313ef6e7be742a504e171f6c0" + hash: "3d06fad059276fd5f8f58faeac482d52" } Frame { msec: 2000 - hash: "0e20bbd3c80189a6d8ea23205bf7b278" + hash: "841ab0655e2bd498d51605fd37607378" } Frame { msec: 2016 - hash: "6f2b8de20e5800bda7a533353bb5805a" + hash: "5968dd4f704d72f264704ae6d6a416cf" } Frame { msec: 2032 - hash: "e25e8c3e7df20b0b7e8f25fba5d2608a" + hash: "5daf3758175963e409ad7ea18d40a894" } Frame { msec: 2048 - hash: "8802faef3121ac361b448b42b89d2176" + hash: "37750cd0aca54fc6fa6651213a4a8aa0" } Frame { msec: 2064 - hash: "567c710da8f36b51192a8994611a50a8" + hash: "b64411f26c1bde823daa4caf96402887" } Frame { msec: 2080 - hash: "d45309aabf9c510234276c28ef4e3c35" + hash: "cf6d68046e9b7cc39305bfbdbd64a6eb" } Frame { msec: 2096 - hash: "ef698cc1ea8eee480c57f38a8f704e6b" + hash: "47f89ab15314ce63dc3828aa4ae16d54" } Frame { msec: 2112 - hash: "5301682074b5343d18748cf6e7bada1c" + hash: "a7116055b3b33ad02bae75f2db016314" } Frame { msec: 2128 - hash: "dd5220c0d94b747cd462e35e41945ae8" + hash: "0a0443c4927d3d8d3373c311b89ead0d" } Frame { msec: 2144 - hash: "0d1c246956283f80eff128bbb5241e03" + hash: "6be5e906e9127471bb11e98ba9d68d4c" } Frame { msec: 2160 - hash: "7b57a3c6ee9b8ae316e2a2d7a1ab630d" + hash: "759c0e5e8a435846bf4471075df9ce1b" } Frame { msec: 2176 - hash: "61780d8d53f21b275f9ee795c5519cbf" + hash: "b7648957a2fdcca31b863907ea5cbc4f" } Frame { msec: 2192 - hash: "1876746b0b6bdc40c808c3afb0ad00e8" + hash: "7e9ead6f87c989160681fe87eb44224b" } Frame { msec: 2208 - hash: "6f7e9a1d8240b037501b486245eb5c33" + hash: "f7ab3534218320a49b8cc14b39d23a38" } Frame { msec: 2224 - hash: "8a5f3d8d9e0147072690740d567f8a2a" + hash: "44ac6d8e7fd3facac856b532bea9b0dd" } Frame { msec: 2240 - hash: "2ea7f42b92e407b50ebf82c841e77f7f" + hash: "238d68eb27eaacddcf428706fca95cad" } Frame { msec: 2256 - hash: "7ce3e829b75be2f2f72952c614748b51" + hash: "8568076d97d416810f1e91acd33bbba0" } Frame { msec: 2272 - hash: "112cbf9bf521c2fb0f0573081feb6051" + hash: "3649d85321ac7674d8c3dd77815aaf32" } Frame { msec: 2288 - hash: "c6d16bde84f714d3f14a105deb68e989" + hash: "0c6dab9f7d575265d554093b88ee7e17" } Frame { msec: 2304 - hash: "f1e3f7416233bc8b3bce90672185cbd2" + hash: "6387cb408d048d7b139f3d9aed2f14d6" } Frame { msec: 2320 - hash: "009fd4bfc354c91f3766bcf32732b027" + hash: "de2fa29a82cec9d9f22d50bba257f5de" } Frame { msec: 2336 - hash: "67220a780fc2cd8e9fbd314c5f000f7c" + hash: "ba77a0dc547202e129e899998c7e0909" } Frame { msec: 2352 - hash: "c306d1be1dc40fb115b583a83497fbb0" + hash: "0acde6d2435444611f7d5fc67d336d4b" } Frame { msec: 2368 - hash: "f6bedbbffec4447da8fda2d75169644c" + hash: "1032d38e48cc3485c7a50bcf3ae949d0" } Frame { msec: 2384 - hash: "be4f28bd814ce3688bd7a28a2dc71606" + hash: "571649ca193507216f344405d8cb9636" } Frame { msec: 2400 - hash: "130ec2ff6e06927a02df769743de19b5" + hash: "968aa311380ef783852b4a642d61d0c3" } Frame { msec: 2416 - hash: "34ffeec40133a30903809a30d9108887" + hash: "b440b4f5f2cb4a061b69e9a99bca0417" } Frame { msec: 2432 - hash: "133a89cf6c784106066b96f51e43f43a" + hash: "c1a2c2fd58f52c6a6f3e5dc2c1e9e8cf" } Frame { msec: 2448 - hash: "6336801efb0d62e5b790ff67b76754a5" + hash: "2eab036693343475b799188c98f18bad" } Frame { msec: 2464 - hash: "04d50179982fdf346a33e346eeb9eb62" + hash: "9b0e2eb4c5ed398dfe5ac82c83d38065" } Frame { msec: 2480 - hash: "5432d629a9bce20e041841d79acf91ab" + hash: "d6459b44113b2514a036a39449579918" } Frame { msec: 2496 - hash: "afbdef35aae3d79f0ba992a34c46b1dc" + hash: "99e24ed5413be65aee179d7fdd0aa473" } Frame { msec: 2512 - hash: "18a051efc4bf47515d2220549970fa69" + hash: "43c7a5fe622eee2202ab1061155da474" } Frame { msec: 2528 - hash: "a0cde51080347ba164227c8a40cf37c1" + hash: "78bc6de01b343c19ce11bcb5ce5db091" } Frame { msec: 2544 - hash: "b2eeabc7208b7a3f9e5a7d16f984be86" + hash: "77463f64f99952f37467b4cae5a75a73" } Frame { msec: 2560 - hash: "ee5c97a5bd22b22a4e18998b6d056517" + hash: "39181ec3e10fba5d73221e3ef725661d" } Frame { msec: 2576 - hash: "84f4575d2c4ba3a91ef72cb8caf64e63" + hash: "f23732daf5b25cbfa79256ad21739537" } Frame { msec: 2592 - hash: "bd14115e10086864de3ab6a7bc13f9a2" + hash: "171b8149512f9a1fc44c4076ae8e6891" } Frame { msec: 2608 - hash: "9b3672f731fad142ae7e3621a325cf21" + hash: "1c30c5284764d3aba948f417dc67ea95" } Frame { msec: 2624 - hash: "17d1887942d2b7297b6f3a2545ec8bf2" + hash: "5b40de40cc84f75a3038a2adafea6688" } Frame { msec: 2640 - hash: "c5c8b41e74b90fcb9d4da432fa01e361" + hash: "11e918309ac265c0dddc34b05ddd2beb" } Frame { msec: 2656 - hash: "a2992b652305077906db9dcbb90c1a23" + hash: "a18c91eae3fd3154c12e46717248577a" } Frame { msec: 2672 - hash: "bfb30aa4caa43833eca59ceaaca04084" + hash: "839199f3940822a38fc2b44161ee0840" } Frame { msec: 2688 - hash: "cbb06915ae6176ef52fdb518fb5a12de" + hash: "8b62f8b4c353981788111a9434995a18" } Frame { msec: 2704 - hash: "a894d34c39b274149a9391a5956f0666" + hash: "db7ee2d5e4905959c836d5162bd241c0" } Frame { msec: 2720 - hash: "7dcc1008d2287ca15f726854e5e204f2" + hash: "cb770a4cd0f56108ef703147e74338ae" } Frame { msec: 2736 - hash: "811db22f9a25dd594f59d97adb41b9ce" + hash: "bdaaedef0c17b19cc283eba699799073" } Frame { msec: 2752 - hash: "6535cb3f4cf2839158f172bd0c1baf88" + hash: "8a7f5f87493ba387c14056f9a598e320" } Frame { msec: 2768 - hash: "1919a3d079c06fbb00b6a23d4a47951a" + hash: "3974497b297fa233f3821abba2bdd6ce" } Frame { msec: 2784 - hash: "69f3525379f7628c4435d2681a2a0bb8" + hash: "41a5744b7747765764829328217e80ea" } Frame { msec: 2800 - hash: "4ce4253e733c24a1a988de018916d0b2" + hash: "4d380bb823659cdfc1d3517234144b72" } Frame { msec: 2816 - hash: "7610bee04c98b9af5e6ae34f4a1a4a09" + hash: "4699cc1dad5c6d5c84137ee5c5db52a4" } Frame { msec: 2832 - hash: "5e2a2c16c0a218afc3eb9095f3432f41" + hash: "22a34c810c640b378708079761d16c9b" } Frame { msec: 2848 - hash: "0124a41ff860d31b3e36973226db2916" + hash: "0c76a943b24dc9538416b05a678c7c94" } Frame { msec: 2864 - hash: "a1126e1d8cce43dfb571803a62f790de" + hash: "575a20b793f899d50a95121708263283" } Frame { msec: 2880 - hash: "6eee371fe5cc8b052ca49bb5e3509307" + hash: "830757417bbff5d6950177aa3617516a" } Frame { msec: 2896 @@ -730,239 +730,239 @@ VisualTest { } Frame { msec: 2912 - hash: "331bcae7bd6aeaede3556cf926bd1a0c" + hash: "1b83db1121bb3436621d3f22758af76d" } Frame { msec: 2928 - hash: "a7561f3a6ce4fee43e4b06dfe5ee7844" + hash: "b2a6d502e9ed62f67c29b8ae7b857116" } Frame { msec: 2944 - hash: "712e52e72cc01ae29cd7e736a78f94b3" + hash: "e9e06068090c076021e508772ae85b5a" } Frame { msec: 2960 - hash: "d34a4414fca4ef7a2cce288d438bfcc1" + hash: "5c7288791d73792b914e99a38b7b455c" } Frame { msec: 2976 - hash: "1c2c5241aee7efcc9a6adcbe01f56609" + hash: "ad2b35c647da055a1088e476f250ea78" } Frame { msec: 2992 - hash: "90a8547113c36002f62405aac41de5b1" + hash: "7cc9bbd4a2ed2ba1646b10a68c11241f" } Frame { msec: 3008 - hash: "5726801ea37dcfd2c087c9523b360b55" + hash: "f633c12a9d078c4a1405ee399bd75e6f" } Frame { msec: 3024 - hash: "a371d1f9ef687f50d433b0efb6bb57c9" + hash: "e4638bb2b40ed7c31630412010bccef1" } Frame { msec: 3040 - hash: "75e0e2728e2160dcc012a21c759c62d0" + hash: "76fdd98f79c08d9211c42b79f953315a" } Frame { msec: 3056 - hash: "428e6d8adbd0e85790365d7537dc37c8" + hash: "df754dffbe6429aa7222e7a37d1956c5" } Frame { msec: 3072 - hash: "798babedde2192b4ac9becc5bae3ea62" + hash: "68edef9b10728f0785cc74dfe92c3e03" } Frame { msec: 3088 - hash: "39745e87e8e96993fccfed6710c3c14f" + hash: "627ac43eb191db77345ab1a08bfd7e7a" } Frame { msec: 3104 - hash: "08624110f2bba4e676b4a339ead23f78" + hash: "c38698cc4c2de1eb96855f0b6398fd7f" } Frame { msec: 3120 - hash: "1d45fc90eb70a3c21d503284637355de" + hash: "6264db59fa7dd4498cedac94b856d90e" } Frame { msec: 3136 - hash: "37c6eed126e265f4a60a1bc92879e18e" + hash: "b550d8181dbf88c5079e2fb6310f0309" } Frame { msec: 3152 - hash: "a25f2accf6e19eb293a5540efa9447ec" + hash: "6ffecf31343192ae352c42c6ba978fd3" } Frame { msec: 3168 - hash: "5212d86075595cb1a9c47cf683ac411a" + hash: "445e7056bfb7726fcf1b0b6411400ec0" } Frame { msec: 3184 - hash: "8f43028def9e949ca3a15fdec9932a59" + hash: "9648c06d3a89c054587fa1e86c727fd0" } Frame { msec: 3200 - hash: "90b55602b8aa530d634db72c202f2d75" + hash: "8d0af1ad33c06cfceaba1a0ca84cf0a0" } Frame { msec: 3216 - hash: "f5a84978918f8987b49ce500959d81ef" + hash: "f8f0c27738b186f17a9dd106481e85c5" } Frame { msec: 3232 - hash: "588382357311925157e12ae7a576426c" + hash: "44e5893cd28e2d70afbfbb779f2dd154" } Frame { msec: 3248 - hash: "ce3e9a93f60579f77f6503637cb316d0" + hash: "dc0d1baafa24423402caf63d6fcd6189" } Frame { msec: 3264 - hash: "63c2ba78f5a81375fe79c5b2b2030b55" + hash: "12c17a563b37bf633dce6fc6793d1cd9" } Frame { msec: 3280 - hash: "7dceb950e0cae31bddeca1d279a688f3" + hash: "a8647172101b59753ea6aa40ec4570dc" } Frame { msec: 3296 - hash: "c6681bcf60562b16eb515f6b0bfdc751" + hash: "e21afb74f793bef8c1b03d252b5700a8" } Frame { msec: 3312 - hash: "cd2b41f01af6b80622158bf38a13c609" + hash: "2e10ccbdee088b17172a479a8a859d56" } Frame { msec: 3328 - hash: "69401bc38be274791a26f6ea161eb296" + hash: "f111c24e1e8d643543519fd703811f24" } Frame { msec: 3344 - hash: "425238342219c4fc66c4a0a8b16c5345" + hash: "dd9aeec2ed05f9c68e1726a91e90e127" } Frame { msec: 3360 - hash: "a501082add225fa59f468808d34d1c16" + hash: "043923ed2dee91815d0dce6cd38834e9" } Frame { msec: 3376 - hash: "58bba6d1eb3166e7ac9bfe36cd9a4fa9" + hash: "07e0dbb223355b2921eb0597235ee820" } Frame { msec: 3392 - hash: "293df1a2bdd526e97d5783f46f74262c" + hash: "0fba3e9a08d83405df35c632f9dc051e" } Frame { msec: 3408 - hash: "6808ee202e8eae3c72474126b59aa0dc" + hash: "a0a5a515ec395bdf4912ab24c8780339" } Frame { msec: 3424 - hash: "7ef977f275851649324e333d58777156" + hash: "4e04e0246eb952cfae716214084cc1ed" } Frame { msec: 3440 - hash: "12007edff45f9cc21a2f633052e4b9d6" + hash: "e7e989234e360e7c0cb44e7be4d654e8" } Frame { msec: 3456 - hash: "bc1d362d3a42ab3610136727605222dc" + hash: "139b3309ac9e25b2165342bfb202169f" } Frame { msec: 3472 - hash: "6bfead8d9644f5abdd3b896714521002" + hash: "b4008ee73b92abad9c5fd7c83cb864cf" } Frame { msec: 3488 - hash: "341c311e4b08d69a053c1faffc208838" + hash: "b801a917995bd41eee2f4e4fed3006c5" } Frame { msec: 3504 - hash: "54e4c8001d06c7c48180865598f5f5df" + hash: "a0ea151cd2a2056a45ff5428239b37f4" } Frame { msec: 3520 - hash: "e69c142bf2a6cf85194de5df91e54886" + hash: "01df418b5ba99271d3a2e8807de78899" } Frame { msec: 3536 - hash: "fb9fda1e790c64aea264a6af0020ce33" + hash: "047fd42df7a5ba0f939930c2021df5fe" } Frame { msec: 3552 - hash: "74c27a13090e8eb78bc157daff840e07" + hash: "4336498cee8b516e79297a073257e008" } Frame { msec: 3568 - hash: "f9a8c1764b0a1625ce336e80a91db00e" + hash: "ce404ce21bc91ff8dc61bd95b9e1d5ac" } Frame { msec: 3584 - hash: "11fd6f7cee3971ebce744f20da77139f" + hash: "06b5c263105ec574f10e70002c29adee" } Frame { msec: 3600 - hash: "6cea030cfc1c53772f14d760d046d7f8" + hash: "6a224a56bbeaeb703afa0c2a7f2daf7d" } Frame { msec: 3616 - hash: "599cf14ec73f6812ffb49312d3d8f742" + hash: "65259fcbdb9edfefc4fcbd1ab5f62542" } Frame { msec: 3632 - hash: "879798ae161f1550096abdfa113e3eac" + hash: "93be4111a6aa21d85ab354bbd41e5b31" } Frame { msec: 3648 - hash: "4cc9b679554a2a8b809a88504c17f86a" + hash: "2e4edcdc4807466620c9671d329a0977" } Frame { msec: 3664 - hash: "943bca80ab42c1856aa095add705a3fe" + hash: "e3232d08b83e3e9917b6f4eabc86df72" } Frame { msec: 3680 - hash: "0386a55ebc0cd32b4b7727eac2908a59" + hash: "f27caa5d738b4778d4343f7b197c5dac" } Frame { msec: 3696 - hash: "74ed8ea60f1c1b3fb097eb7f5bca43e8" + hash: "dcf3032bc798daf1dc6bb7d608e2dffb" } Frame { msec: 3712 - hash: "225f78966947d20268f1bea32093c0c9" + hash: "9f2d4ba31ab4ec10b43b7de19197994e" } Frame { msec: 3728 - hash: "d2ed6af6fbdfbdcd9c82a588b72c5f6b" + hash: "4bf6419de081524ecdeb4c07b376f06d" } Frame { msec: 3744 - hash: "3c0e45078e5223335a4204fb8904d116" + hash: "3fdd8166873e768e1346e52a1b4a6554" } Frame { msec: 3760 - hash: "58ad3d7030b079cdedf1a84d6c6a59fc" + hash: "7b25b2f1b2694a87095fba46d505684f" } Frame { msec: 3776 - hash: "2c8ce9f237a2c373584b661defe84e7f" + hash: "d8246057d4b0306747ba449d5247dd21" } Frame { msec: 3792 - hash: "c2f2ae8c7481036ddda01776db61ef0a" + hash: "e45c06fbf48923393f672381f0256513" } Frame { msec: 3808 - hash: "7236e9d1e086479acd5047070a4ae700" + hash: "fef8f1bf977d6567eebe14ccafd36853" } Frame { msec: 3824 - hash: "7f95776ac1804971cc939f8f1f0fee70" + hash: "04152eab971eac3fbba26f15ba09d329" } Frame { msec: 3840 - hash: "d6d76b50b7d2ec522a51d2512a5aeff8" + hash: "5039cb5183587fe46ef30c5d0f8c9584" } Frame { msec: 3856 @@ -970,99 +970,99 @@ VisualTest { } Frame { msec: 3872 - hash: "29b8b535c9321752a68b17400c7133ac" + hash: "5d62550ba4502c3eae3f62ce5b8e9374" } Frame { msec: 3888 - hash: "846f4f5718bce8dc7a333d8603bfe729" + hash: "859ab80ee7d563a158970d1f3360c7dd" } Frame { msec: 3904 - hash: "b285f6a417bfb46add698f4193b39552" + hash: "4f900b694d6e552c9287472ca58be35a" } Frame { msec: 3920 - hash: "b79708e4aa2b05a1c285dd075127460d" + hash: "6b3aa5a3071ea5ec911bae3dee02a496" } Frame { msec: 3936 - hash: "0cdded9c7796292cd38a3bc2fdc65597" + hash: "d1b1536b5162e5367db66bb21ccebdcd" } Frame { msec: 3952 - hash: "6f8855c20666a58bbf4ade762403180e" + hash: "8c8dd0b84be58a3257dbd0210a7b21ab" } Frame { msec: 3968 - hash: "1a7979b578c8b330099a5e840d5d2bd8" + hash: "f96cb092836d67c81fdfd3668005e912" } Frame { msec: 3984 - hash: "30fb74a2bf4e1ec57332713994e405cd" + hash: "7b06694d2fd4dd2def94b11a1e46a391" } Frame { msec: 4000 - hash: "1c7df42f90a867350adca840106d3ba1" + hash: "cef499e6c1665d2bd4a4322d4334234a" } Frame { msec: 4016 - hash: "5509a232afe047f365465ef8fd9f0af0" + hash: "664503d5cef2676e287c363a488e91f1" } Frame { msec: 4032 - hash: "2149d59ffd7c07bdc0bcb2d8ad9b1ca3" + hash: "cefa44e348ea0d6955a71c7eb0a9b45c" } Frame { msec: 4048 - hash: "4b8848019eaf4af67db4db09b98b183e" + hash: "0ee5684bf4d5b54c5bc9aeefcb98a3d1" } Frame { msec: 4064 - hash: "e3f6f9db89bd81ce68f8dfd401f1baa8" + hash: "fb6667f1c516187cfb93774469ea8165" } Frame { msec: 4080 - hash: "6e8d991c83094c89025148bc0943e554" + hash: "fba776d4d3056bf64e335de876e118be" } Frame { msec: 4096 - hash: "ed4d8bde61581cdcf6128c65d427846c" + hash: "a49aa08c4bd8a1ae9420e0962cf77e01" } Frame { msec: 4112 - hash: "c63d0baaa43c4f6a0f0150ecf268b06d" + hash: "bff31d464ae9fc68adf0c8072b637592" } Frame { msec: 4128 - hash: "b36c6a0092f400bb99b2c68a0ba4e6ce" + hash: "23bd0afacb2d9bd009c9b5006dc6adf1" } Frame { msec: 4144 - hash: "b4b1059c1e00ee77fda538f9e71a6206" + hash: "d918e94e5be77741d1172fbf960db07e" } Frame { msec: 4160 - hash: "e7c36e10dee12ea2d22d7c17cde9d8ca" + hash: "9abce75f201e20a730e79a672bf837e8" } Frame { msec: 4176 - hash: "78d070c37bbc707e38db98896f997349" + hash: "aae93f5e2a2c6e06dbe78bea4e6b1283" } Frame { msec: 4192 - hash: "e56cb5fbb7713a66ef1f1577eff20db8" + hash: "66cba82f479ae6536800b05f6d694884" } Frame { msec: 4208 - hash: "17e466af39cdde893cf93fa38392bb90" + hash: "d79d43b820c4a53735cfb84288dd5efd" } Frame { msec: 4224 - hash: "75bf32afe1071794bba58623d7165a22" + hash: "fe0237b64a2ef664ce2c3028b730fdc4" } Frame { msec: 4240 - hash: "6de50f6748021b99731f6cb25d6d6ec3" + hash: "771b02756dadb0a1f268166138f7cad4" } Frame { msec: 4256 @@ -1258,66 +1258,66 @@ VisualTest { } Frame { msec: 5024 - hash: "f803bd7bdc97bb8bbb5103a54901d756" + hash: "c95868a45ccb031ea1d440bedd1fc33f" } Frame { msec: 5040 - hash: "de956b3223e24a615713c35faa403128" + hash: "eb78d75fbf3ef0b88c072f69ac3f490d" } Frame { msec: 5056 - hash: "9124b4e5f5dd374e44f3f57fe3d6809b" + hash: "6f612fe36fa8028a75f6149390bd3585" } Frame { msec: 5072 - hash: "5b8313c622796aa87248b38ab336bcf8" + hash: "7906071fe656ccf18d24c100950b6a7a" } Frame { msec: 5088 - hash: "de6477fc7e6b8f14a7a51f9cf762ee79" + hash: "064a0b9a0adb235fd52a6d53b65c9d1c" } Frame { msec: 5104 - hash: "0d908ef6e3ea15455e35a9ebbc90c735" + hash: "f42b6952937376ae34f7ef493e86aee6" } Frame { msec: 5120 - hash: "bd1d7ad510cd5e04283f6167a5a8e2df" + hash: "3444491cc10b0ae2f298ac3aefcda77c" } Frame { msec: 5136 - hash: "2ec7418477158ee60afe123fa2b7ce4b" + hash: "ce5adf6c5c4d5e385ce7e461e380b00e" } Frame { msec: 5152 - hash: "04c671070b1eba13380aa2fbb672d3a1" + hash: "6b6c1a422f778935b400c9a170439ec4" } Frame { msec: 5168 - hash: "ce031ba5b388dfaff34674eb71f790f2" + hash: "fdaff741a826c10cb9799adc70d92145" } Frame { msec: 5184 - hash: "e754141341d9f81366f21820e46bd1ca" + hash: "259da9a4c2bb9c89d16dd1943645e836" } Frame { msec: 5200 - hash: "acf56542617bc742ad729709645ac919" + hash: "fd2903f4b3d7086981a89e87e460a7ba" } Frame { msec: 5216 - hash: "c50698470bc6c1ea04633b9e819a2d4d" + hash: "9860af14b459925078467f334bf41e42" } Frame { msec: 5232 - hash: "c156d3540c3cf6d406b72696fd6e9148" + hash: "ae2b8b255d48c12a954f02c63e0d5aa4" } Frame { msec: 5248 - hash: "82a04f09cd35db0dbf012797625368e4" + hash: "c33e9369e76654433e97b2b72cca7911" } Frame { msec: 5264 - hash: "3b9ccb93f6375ea401c1fc3bcdf847d5" + hash: "7fa3de8afdeb61c6e2e87cde2e96152f" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/plaintext.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/plaintext.0.png index 56d98ff..b4e1d3a 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/plaintext.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/plaintext.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/plaintext2.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/plaintext2.0.png index 1ab1eb5..4177b9e 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/plaintext2.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/plaintext2.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/richtext.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/richtext.0.png index 68921f6..36e5d35 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/richtext.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/richtext.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/richtext2.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/richtext2.0.png index c9450c7..34f8e38 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/richtext2.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/font/data-X11/richtext2.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.0.png index 59fc0fc..19a7ea1 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.1.png index 2747b50..e25493f 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.2.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.2.png index 74efe73..5800e13 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.2.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.3.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.3.png index 02f6e17..29e8168 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.3.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.4.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.4.png index 59fc0fc..19a7ea1 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.4.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.qml index 760a831..955ebbd 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.qml @@ -10,95 +10,95 @@ VisualTest { } Frame { msec: 32 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 48 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 64 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 80 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 96 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 112 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 128 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 144 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 160 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 176 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 192 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 208 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 224 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 240 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 256 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 272 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 288 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 304 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 320 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 336 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 352 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 368 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 384 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Key { type: 6 @@ -110,15 +110,15 @@ VisualTest { } Frame { msec: 400 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 416 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 432 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Key { type: 7 @@ -130,27 +130,27 @@ VisualTest { } Frame { msec: 448 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 464 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 480 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 496 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 512 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 528 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Key { type: 6 @@ -162,15 +162,15 @@ VisualTest { } Frame { msec: 544 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Frame { msec: 560 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Frame { msec: 576 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Key { type: 7 @@ -182,27 +182,27 @@ VisualTest { } Frame { msec: 592 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Frame { msec: 608 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Frame { msec: 624 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Frame { msec: 640 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Frame { msec: 656 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Frame { msec: 672 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Key { type: 6 @@ -214,19 +214,19 @@ VisualTest { } Frame { msec: 688 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Frame { msec: 704 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Frame { msec: 720 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Frame { msec: 736 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Key { type: 7 @@ -238,23 +238,23 @@ VisualTest { } Frame { msec: 752 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Frame { msec: 768 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Frame { msec: 784 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Frame { msec: 800 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Frame { msec: 816 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Key { type: 6 @@ -266,19 +266,19 @@ VisualTest { } Frame { msec: 832 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Frame { msec: 848 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Frame { msec: 864 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Frame { msec: 880 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Key { type: 7 @@ -290,19 +290,19 @@ VisualTest { } Frame { msec: 896 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Frame { msec: 912 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Frame { msec: 928 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Frame { msec: 944 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Key { type: 6 @@ -314,7 +314,7 @@ VisualTest { } Frame { msec: 960 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 976 @@ -322,11 +322,11 @@ VisualTest { } Frame { msec: 992 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 1008 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Key { type: 7 @@ -338,23 +338,23 @@ VisualTest { } Frame { msec: 1024 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 1040 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 1056 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 1072 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 1088 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Key { type: 6 @@ -366,15 +366,15 @@ VisualTest { } Frame { msec: 1104 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Frame { msec: 1120 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Frame { msec: 1136 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Key { type: 7 @@ -386,23 +386,23 @@ VisualTest { } Frame { msec: 1152 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Frame { msec: 1168 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Frame { msec: 1184 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Frame { msec: 1200 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Frame { msec: 1216 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Key { type: 6 @@ -414,19 +414,19 @@ VisualTest { } Frame { msec: 1232 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Frame { msec: 1248 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Frame { msec: 1264 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Frame { msec: 1280 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Key { type: 7 @@ -438,19 +438,19 @@ VisualTest { } Frame { msec: 1296 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Frame { msec: 1312 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Frame { msec: 1328 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Frame { msec: 1344 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Key { type: 6 @@ -462,19 +462,19 @@ VisualTest { } Frame { msec: 1360 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 1376 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 1392 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 1408 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Key { type: 7 @@ -486,23 +486,23 @@ VisualTest { } Frame { msec: 1424 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 1440 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 1456 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 1472 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 1488 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Key { type: 6 @@ -514,15 +514,15 @@ VisualTest { } Frame { msec: 1504 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1520 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1536 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Key { type: 7 @@ -534,79 +534,79 @@ VisualTest { } Frame { msec: 1552 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1568 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1584 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1600 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1616 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1632 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1648 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1664 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1680 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1696 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1712 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1728 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1744 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1760 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1776 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1792 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1808 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1824 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Frame { msec: 1840 - hash: "64f5712c1f96345f2a2ad103e6fbd734" + hash: "79ad12250ec5379ed79ad01604968fe0" } Key { type: 6 @@ -618,23 +618,23 @@ VisualTest { } Frame { msec: 1856 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 1872 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 1888 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 1904 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 1920 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 1936 @@ -642,15 +642,15 @@ VisualTest { } Frame { msec: 1952 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 1968 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 1984 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Key { type: 7 @@ -662,23 +662,23 @@ VisualTest { } Frame { msec: 2000 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 2016 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 2032 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 2048 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Frame { msec: 2064 - hash: "7f895d1255301397298cd6b92282e4f7" + hash: "0a110e257ae412b8440a17be98a6b7f5" } Key { type: 6 @@ -690,23 +690,23 @@ VisualTest { } Frame { msec: 2080 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Frame { msec: 2096 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Frame { msec: 2112 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Frame { msec: 2128 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Frame { msec: 2144 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Key { type: 7 @@ -718,23 +718,23 @@ VisualTest { } Frame { msec: 2160 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Frame { msec: 2176 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Frame { msec: 2192 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Frame { msec: 2208 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Frame { msec: 2224 - hash: "6ec9e863238467c249f62bdd38b68490" + hash: "162c39ecb50d0a2a03953cca07c493ff" } Key { type: 6 @@ -746,11 +746,11 @@ VisualTest { } Frame { msec: 2240 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Frame { msec: 2256 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Key { type: 7 @@ -762,23 +762,23 @@ VisualTest { } Frame { msec: 2272 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Frame { msec: 2288 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Frame { msec: 2304 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Frame { msec: 2320 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Frame { msec: 2336 - hash: "fe998f3c7c780fddfa6a595936d2e78e" + hash: "0386e92fe3ea2eda40b6f785419cf9f7" } Key { type: 6 @@ -790,15 +790,15 @@ VisualTest { } Frame { msec: 2352 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 2368 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 2384 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Key { type: 7 @@ -810,55 +810,55 @@ VisualTest { } Frame { msec: 2400 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 2416 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 2432 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 2448 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 2464 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 2480 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 2496 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 2512 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 2528 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 2544 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 2560 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 2576 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Frame { msec: 2592 - hash: "a7415d0abcc670ba02c2a00b3b5fc647" + hash: "671d2393c31db71d33cd29482294b855" } Key { type: 6 @@ -870,23 +870,23 @@ VisualTest { } Frame { msec: 2608 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Frame { msec: 2624 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Frame { msec: 2640 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Frame { msec: 2656 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Frame { msec: 2672 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Key { type: 7 @@ -898,23 +898,23 @@ VisualTest { } Frame { msec: 2688 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Frame { msec: 2704 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Frame { msec: 2720 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Frame { msec: 2736 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Frame { msec: 2752 - hash: "9eda76efdd179847e89b9e96ead51e4a" + hash: "59923f379655d063d27641c88064c071" } Key { type: 6 @@ -926,15 +926,15 @@ VisualTest { } Frame { msec: 2768 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Frame { msec: 2784 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Frame { msec: 2800 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Key { type: 7 @@ -946,19 +946,19 @@ VisualTest { } Frame { msec: 2816 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Frame { msec: 2832 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Frame { msec: 2848 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Frame { msec: 2864 - hash: "1bcb9bc9d6606329ad5376ea6f608bf8" + hash: "5815bbb03307e196fa567ae273366394" } Key { type: 6 @@ -970,7 +970,7 @@ VisualTest { } Frame { msec: 2880 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Frame { msec: 2896 @@ -978,11 +978,11 @@ VisualTest { } Frame { msec: 2912 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Frame { msec: 2928 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Key { type: 7 @@ -994,23 +994,23 @@ VisualTest { } Frame { msec: 2944 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Frame { msec: 2960 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Frame { msec: 2976 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Frame { msec: 2992 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Frame { msec: 3008 - hash: "1465f1f32ba4a6180ab3460298febe26" + hash: "7f418dcd1c4ef954cbb66e16361b8871" } Key { type: 6 @@ -1022,23 +1022,23 @@ VisualTest { } Frame { msec: 3024 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3040 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3056 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3072 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3088 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Key { type: 7 @@ -1050,155 +1050,155 @@ VisualTest { } Frame { msec: 3104 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3120 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3136 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3152 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3168 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3184 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3200 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3216 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3232 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3248 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3264 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3280 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3296 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3312 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3328 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3344 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3360 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3376 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3392 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3408 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3424 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3440 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3456 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3472 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3488 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3504 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3520 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3536 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3552 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3568 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3584 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3600 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3616 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3632 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3648 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3664 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3680 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Frame { msec: 3696 - hash: "89f3a1c5080d5d742e4455a8818a715c" + hash: "ff9e0c6cfbbbd68708698875037ac3d3" } Key { type: 6 @@ -1210,27 +1210,27 @@ VisualTest { } Frame { msec: 3712 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3728 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3744 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3760 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3776 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3792 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Key { type: 7 @@ -1242,15 +1242,15 @@ VisualTest { } Frame { msec: 3808 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3824 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3840 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3856 @@ -1258,114 +1258,114 @@ VisualTest { } Frame { msec: 3872 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3888 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3904 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3920 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3936 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3952 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3968 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 3984 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4000 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4016 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4032 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4048 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4064 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4080 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4096 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4112 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4128 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4144 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4160 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4176 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4192 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4208 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4224 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4240 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4256 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4272 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4288 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } Frame { msec: 4304 - hash: "0051b27d72a917e2af72c4b953877d42" + hash: "5efa0360e73361a50a5fb4e2b7a650b5" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.0.png index d63f753..da3b971 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.1.png index bb7daa3..8ea0787 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.2.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.2.png index bcad242..33328db 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.2.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.3.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.3.png index 7be45e7..222ba53 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.3.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.4.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.4.png index 42f7f51..970e73d 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.4.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.5.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.5.png index 147632a..4dc64a1 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.5.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.5.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.6.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.6.png index d624a71..99d451c 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.6.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.6.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.7.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.7.png index d624a71..99d451c 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.7.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.7.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.qml index 72f68e7..13834f0 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/wrap.qml @@ -18,7 +18,7 @@ VisualTest { } Frame { msec: 32 - hash: "3e34b9a8c5df08caa18f37289c25138f" + hash: "ca07773bf0df96be1f23d13c4d6e2bfd" } Key { type: 7 @@ -30,11 +30,11 @@ VisualTest { } Frame { msec: 48 - hash: "3e34b9a8c5df08caa18f37289c25138f" + hash: "ca07773bf0df96be1f23d13c4d6e2bfd" } Frame { msec: 64 - hash: "3e34b9a8c5df08caa18f37289c25138f" + hash: "ca07773bf0df96be1f23d13c4d6e2bfd" } Key { type: 7 @@ -46,11 +46,11 @@ VisualTest { } Frame { msec: 80 - hash: "3e34b9a8c5df08caa18f37289c25138f" + hash: "ca07773bf0df96be1f23d13c4d6e2bfd" } Frame { msec: 96 - hash: "3e34b9a8c5df08caa18f37289c25138f" + hash: "ca07773bf0df96be1f23d13c4d6e2bfd" } Key { type: 6 @@ -62,15 +62,15 @@ VisualTest { } Frame { msec: 112 - hash: "4242081446f2a3122bbd4f8c03a67e5c" + hash: "fc223de2e1f35db08d9689bc41f02304" } Frame { msec: 128 - hash: "4242081446f2a3122bbd4f8c03a67e5c" + hash: "fc223de2e1f35db08d9689bc41f02304" } Frame { msec: 144 - hash: "4242081446f2a3122bbd4f8c03a67e5c" + hash: "fc223de2e1f35db08d9689bc41f02304" } Key { type: 6 @@ -82,15 +82,15 @@ VisualTest { } Frame { msec: 160 - hash: "79c4a9defe89f99b3f6b3c25bd81fc7e" + hash: "dc208fb5236b0a2a54bf9aaf7a9d60cd" } Frame { msec: 176 - hash: "79c4a9defe89f99b3f6b3c25bd81fc7e" + hash: "dc208fb5236b0a2a54bf9aaf7a9d60cd" } Frame { msec: 192 - hash: "79c4a9defe89f99b3f6b3c25bd81fc7e" + hash: "dc208fb5236b0a2a54bf9aaf7a9d60cd" } Key { type: 7 @@ -102,11 +102,11 @@ VisualTest { } Frame { msec: 208 - hash: "79c4a9defe89f99b3f6b3c25bd81fc7e" + hash: "dc208fb5236b0a2a54bf9aaf7a9d60cd" } Frame { msec: 224 - hash: "79c4a9defe89f99b3f6b3c25bd81fc7e" + hash: "dc208fb5236b0a2a54bf9aaf7a9d60cd" } Key { type: 6 @@ -118,7 +118,7 @@ VisualTest { } Frame { msec: 240 - hash: "0bee22de7793974cadec12dfb5df16aa" + hash: "c017468afd522089b5c9f42dd61be1b4" } Key { type: 7 @@ -130,19 +130,19 @@ VisualTest { } Frame { msec: 256 - hash: "0bee22de7793974cadec12dfb5df16aa" + hash: "c017468afd522089b5c9f42dd61be1b4" } Frame { msec: 272 - hash: "0bee22de7793974cadec12dfb5df16aa" + hash: "c017468afd522089b5c9f42dd61be1b4" } Frame { msec: 288 - hash: "0bee22de7793974cadec12dfb5df16aa" + hash: "c017468afd522089b5c9f42dd61be1b4" } Frame { msec: 304 - hash: "0bee22de7793974cadec12dfb5df16aa" + hash: "c017468afd522089b5c9f42dd61be1b4" } Key { type: 7 @@ -154,11 +154,11 @@ VisualTest { } Frame { msec: 320 - hash: "0bee22de7793974cadec12dfb5df16aa" + hash: "c017468afd522089b5c9f42dd61be1b4" } Frame { msec: 336 - hash: "0bee22de7793974cadec12dfb5df16aa" + hash: "c017468afd522089b5c9f42dd61be1b4" } Key { type: 6 @@ -170,19 +170,19 @@ VisualTest { } Frame { msec: 352 - hash: "07393d1c1bb6da436700881ebcd38195" + hash: "84b1f1bf26af0da07006bb102d22693f" } Frame { msec: 368 - hash: "07393d1c1bb6da436700881ebcd38195" + hash: "84b1f1bf26af0da07006bb102d22693f" } Frame { msec: 384 - hash: "07393d1c1bb6da436700881ebcd38195" + hash: "84b1f1bf26af0da07006bb102d22693f" } Frame { msec: 400 - hash: "07393d1c1bb6da436700881ebcd38195" + hash: "84b1f1bf26af0da07006bb102d22693f" } Key { type: 7 @@ -194,19 +194,19 @@ VisualTest { } Frame { msec: 416 - hash: "07393d1c1bb6da436700881ebcd38195" + hash: "84b1f1bf26af0da07006bb102d22693f" } Frame { msec: 432 - hash: "07393d1c1bb6da436700881ebcd38195" + hash: "84b1f1bf26af0da07006bb102d22693f" } Frame { msec: 448 - hash: "07393d1c1bb6da436700881ebcd38195" + hash: "84b1f1bf26af0da07006bb102d22693f" } Frame { msec: 464 - hash: "07393d1c1bb6da436700881ebcd38195" + hash: "84b1f1bf26af0da07006bb102d22693f" } Key { type: 6 @@ -218,19 +218,19 @@ VisualTest { } Frame { msec: 480 - hash: "b12a4550ae068d157d340c008047d6f1" + hash: "a16f5aa01bd07de4ef7f868b7b6116f7" } Frame { msec: 496 - hash: "b12a4550ae068d157d340c008047d6f1" + hash: "a16f5aa01bd07de4ef7f868b7b6116f7" } Frame { msec: 512 - hash: "b12a4550ae068d157d340c008047d6f1" + hash: "a16f5aa01bd07de4ef7f868b7b6116f7" } Frame { msec: 528 - hash: "b12a4550ae068d157d340c008047d6f1" + hash: "a16f5aa01bd07de4ef7f868b7b6116f7" } Key { type: 6 @@ -250,23 +250,23 @@ VisualTest { } Frame { msec: 544 - hash: "f291de0963549b92d607f38d2d08c551" + hash: "e25e16d0d7b223b243d466630b901f68" } Frame { msec: 560 - hash: "f291de0963549b92d607f38d2d08c551" + hash: "e25e16d0d7b223b243d466630b901f68" } Frame { msec: 576 - hash: "f291de0963549b92d607f38d2d08c551" + hash: "e25e16d0d7b223b243d466630b901f68" } Frame { msec: 592 - hash: "f291de0963549b92d607f38d2d08c551" + hash: "e25e16d0d7b223b243d466630b901f68" } Frame { msec: 608 - hash: "f291de0963549b92d607f38d2d08c551" + hash: "e25e16d0d7b223b243d466630b901f68" } Key { type: 7 @@ -286,19 +286,19 @@ VisualTest { } Frame { msec: 624 - hash: "b7eedae59cc521aa8222596cd97bf129" + hash: "a53520edb9c117aa53abc42fce3505be" } Frame { msec: 640 - hash: "b7eedae59cc521aa8222596cd97bf129" + hash: "a53520edb9c117aa53abc42fce3505be" } Frame { msec: 656 - hash: "b7eedae59cc521aa8222596cd97bf129" + hash: "a53520edb9c117aa53abc42fce3505be" } Frame { msec: 672 - hash: "b7eedae59cc521aa8222596cd97bf129" + hash: "a53520edb9c117aa53abc42fce3505be" } Key { type: 7 @@ -310,11 +310,11 @@ VisualTest { } Frame { msec: 688 - hash: "b7eedae59cc521aa8222596cd97bf129" + hash: "a53520edb9c117aa53abc42fce3505be" } Frame { msec: 704 - hash: "b7eedae59cc521aa8222596cd97bf129" + hash: "a53520edb9c117aa53abc42fce3505be" } Key { type: 6 @@ -326,23 +326,23 @@ VisualTest { } Frame { msec: 720 - hash: "98ef281d984841075f2fc82cebcba3a9" + hash: "a7ef30038b24e8bf946bdd38aaac6430" } Frame { msec: 736 - hash: "98ef281d984841075f2fc82cebcba3a9" + hash: "a7ef30038b24e8bf946bdd38aaac6430" } Frame { msec: 752 - hash: "98ef281d984841075f2fc82cebcba3a9" + hash: "a7ef30038b24e8bf946bdd38aaac6430" } Frame { msec: 768 - hash: "98ef281d984841075f2fc82cebcba3a9" + hash: "a7ef30038b24e8bf946bdd38aaac6430" } Frame { msec: 784 - hash: "98ef281d984841075f2fc82cebcba3a9" + hash: "a7ef30038b24e8bf946bdd38aaac6430" } Key { type: 7 @@ -354,7 +354,7 @@ VisualTest { } Frame { msec: 800 - hash: "98ef281d984841075f2fc82cebcba3a9" + hash: "a7ef30038b24e8bf946bdd38aaac6430" } Key { type: 6 @@ -366,15 +366,15 @@ VisualTest { } Frame { msec: 816 - hash: "e7b8f24ba55765e2fc1f386d510b402f" + hash: "026b29fc03bd22e15ff725d34dee91eb" } Frame { msec: 832 - hash: "e7b8f24ba55765e2fc1f386d510b402f" + hash: "026b29fc03bd22e15ff725d34dee91eb" } Frame { msec: 848 - hash: "e7b8f24ba55765e2fc1f386d510b402f" + hash: "026b29fc03bd22e15ff725d34dee91eb" } Key { type: 7 @@ -386,15 +386,15 @@ VisualTest { } Frame { msec: 864 - hash: "e7b8f24ba55765e2fc1f386d510b402f" + hash: "026b29fc03bd22e15ff725d34dee91eb" } Frame { msec: 880 - hash: "e7b8f24ba55765e2fc1f386d510b402f" + hash: "026b29fc03bd22e15ff725d34dee91eb" } Frame { msec: 896 - hash: "e7b8f24ba55765e2fc1f386d510b402f" + hash: "026b29fc03bd22e15ff725d34dee91eb" } Key { type: 6 @@ -406,19 +406,19 @@ VisualTest { } Frame { msec: 912 - hash: "38a3062cb4f23993416f83ff6acbe189" + hash: "2b1cef34dff32e36e3c44f2ffb2be66e" } Frame { msec: 928 - hash: "38a3062cb4f23993416f83ff6acbe189" + hash: "2b1cef34dff32e36e3c44f2ffb2be66e" } Frame { msec: 944 - hash: "38a3062cb4f23993416f83ff6acbe189" + hash: "2b1cef34dff32e36e3c44f2ffb2be66e" } Frame { msec: 960 - hash: "38a3062cb4f23993416f83ff6acbe189" + hash: "2b1cef34dff32e36e3c44f2ffb2be66e" } Frame { msec: 976 @@ -426,7 +426,7 @@ VisualTest { } Frame { msec: 992 - hash: "38a3062cb4f23993416f83ff6acbe189" + hash: "2b1cef34dff32e36e3c44f2ffb2be66e" } Key { type: 6 @@ -446,23 +446,23 @@ VisualTest { } Frame { msec: 1008 - hash: "daef9995a008f0ca672adc98315a6b9f" + hash: "f619bc4148876effc459127009d4cc3a" } Frame { msec: 1024 - hash: "daef9995a008f0ca672adc98315a6b9f" + hash: "f619bc4148876effc459127009d4cc3a" } Frame { msec: 1040 - hash: "daef9995a008f0ca672adc98315a6b9f" + hash: "f619bc4148876effc459127009d4cc3a" } Frame { msec: 1056 - hash: "daef9995a008f0ca672adc98315a6b9f" + hash: "f619bc4148876effc459127009d4cc3a" } Frame { msec: 1072 - hash: "daef9995a008f0ca672adc98315a6b9f" + hash: "f619bc4148876effc459127009d4cc3a" } Key { type: 7 @@ -474,31 +474,31 @@ VisualTest { } Frame { msec: 1088 - hash: "daef9995a008f0ca672adc98315a6b9f" + hash: "f619bc4148876effc459127009d4cc3a" } Frame { msec: 1104 - hash: "daef9995a008f0ca672adc98315a6b9f" + hash: "f619bc4148876effc459127009d4cc3a" } Frame { msec: 1120 - hash: "daef9995a008f0ca672adc98315a6b9f" + hash: "f619bc4148876effc459127009d4cc3a" } Frame { msec: 1136 - hash: "daef9995a008f0ca672adc98315a6b9f" + hash: "f619bc4148876effc459127009d4cc3a" } Frame { msec: 1152 - hash: "daef9995a008f0ca672adc98315a6b9f" + hash: "f619bc4148876effc459127009d4cc3a" } Frame { msec: 1168 - hash: "daef9995a008f0ca672adc98315a6b9f" + hash: "f619bc4148876effc459127009d4cc3a" } Frame { msec: 1184 - hash: "daef9995a008f0ca672adc98315a6b9f" + hash: "f619bc4148876effc459127009d4cc3a" } Key { type: 6 @@ -510,23 +510,23 @@ VisualTest { } Frame { msec: 1200 - hash: "da27d35f241ccc7c1ee2832e491fa726" + hash: "c7fbee3129141e8493b7bc4f85fdc2d0" } Frame { msec: 1216 - hash: "da27d35f241ccc7c1ee2832e491fa726" + hash: "c7fbee3129141e8493b7bc4f85fdc2d0" } Frame { msec: 1232 - hash: "da27d35f241ccc7c1ee2832e491fa726" + hash: "c7fbee3129141e8493b7bc4f85fdc2d0" } Frame { msec: 1248 - hash: "da27d35f241ccc7c1ee2832e491fa726" + hash: "c7fbee3129141e8493b7bc4f85fdc2d0" } Frame { msec: 1264 - hash: "da27d35f241ccc7c1ee2832e491fa726" + hash: "c7fbee3129141e8493b7bc4f85fdc2d0" } Key { type: 7 @@ -546,11 +546,11 @@ VisualTest { } Frame { msec: 1280 - hash: "7136f5cfcca4a86b8764667895efa813" + hash: "f2a45d80148ee1b5f1cd8cb6ddd0c5ed" } Frame { msec: 1296 - hash: "7136f5cfcca4a86b8764667895efa813" + hash: "f2a45d80148ee1b5f1cd8cb6ddd0c5ed" } Key { type: 6 @@ -562,15 +562,15 @@ VisualTest { } Frame { msec: 1312 - hash: "b99aec3d97f4442378a18ac88d50b97d" + hash: "147efa341e4dc39cdd555c2c81e5c603" } Frame { msec: 1328 - hash: "b99aec3d97f4442378a18ac88d50b97d" + hash: "147efa341e4dc39cdd555c2c81e5c603" } Frame { msec: 1344 - hash: "b99aec3d97f4442378a18ac88d50b97d" + hash: "147efa341e4dc39cdd555c2c81e5c603" } Key { type: 7 @@ -582,11 +582,11 @@ VisualTest { } Frame { msec: 1360 - hash: "b99aec3d97f4442378a18ac88d50b97d" + hash: "147efa341e4dc39cdd555c2c81e5c603" } Frame { msec: 1376 - hash: "b99aec3d97f4442378a18ac88d50b97d" + hash: "147efa341e4dc39cdd555c2c81e5c603" } Key { type: 7 @@ -598,19 +598,19 @@ VisualTest { } Frame { msec: 1392 - hash: "b99aec3d97f4442378a18ac88d50b97d" + hash: "147efa341e4dc39cdd555c2c81e5c603" } Frame { msec: 1408 - hash: "b99aec3d97f4442378a18ac88d50b97d" + hash: "147efa341e4dc39cdd555c2c81e5c603" } Frame { msec: 1424 - hash: "b99aec3d97f4442378a18ac88d50b97d" + hash: "147efa341e4dc39cdd555c2c81e5c603" } Frame { msec: 1440 - hash: "b99aec3d97f4442378a18ac88d50b97d" + hash: "147efa341e4dc39cdd555c2c81e5c603" } Key { type: 6 @@ -622,23 +622,23 @@ VisualTest { } Frame { msec: 1456 - hash: "c32293903502fd1964cfbc10515b2ef7" + hash: "d5b19a6d767a08f488cc8fc5c427a2dd" } Frame { msec: 1472 - hash: "c32293903502fd1964cfbc10515b2ef7" + hash: "d5b19a6d767a08f488cc8fc5c427a2dd" } Frame { msec: 1488 - hash: "c32293903502fd1964cfbc10515b2ef7" + hash: "d5b19a6d767a08f488cc8fc5c427a2dd" } Frame { msec: 1504 - hash: "c32293903502fd1964cfbc10515b2ef7" + hash: "d5b19a6d767a08f488cc8fc5c427a2dd" } Frame { msec: 1520 - hash: "c32293903502fd1964cfbc10515b2ef7" + hash: "d5b19a6d767a08f488cc8fc5c427a2dd" } Key { type: 7 @@ -650,11 +650,11 @@ VisualTest { } Frame { msec: 1536 - hash: "c32293903502fd1964cfbc10515b2ef7" + hash: "d5b19a6d767a08f488cc8fc5c427a2dd" } Frame { msec: 1552 - hash: "c32293903502fd1964cfbc10515b2ef7" + hash: "d5b19a6d767a08f488cc8fc5c427a2dd" } Key { type: 6 @@ -666,23 +666,23 @@ VisualTest { } Frame { msec: 1568 - hash: "47371eb93a2a8fac7afb53990fac9130" + hash: "bf6265ca859f700fb07f8b992255787d" } Frame { msec: 1584 - hash: "47371eb93a2a8fac7afb53990fac9130" + hash: "bf6265ca859f700fb07f8b992255787d" } Frame { msec: 1600 - hash: "47371eb93a2a8fac7afb53990fac9130" + hash: "bf6265ca859f700fb07f8b992255787d" } Frame { msec: 1616 - hash: "47371eb93a2a8fac7afb53990fac9130" + hash: "bf6265ca859f700fb07f8b992255787d" } Frame { msec: 1632 - hash: "47371eb93a2a8fac7afb53990fac9130" + hash: "bf6265ca859f700fb07f8b992255787d" } Key { type: 6 @@ -702,23 +702,23 @@ VisualTest { } Frame { msec: 1648 - hash: "5c22c2566b437497dd6fd908135ec39e" + hash: "329e4cd26283eb08188d96b2b0325733" } Frame { msec: 1664 - hash: "5c22c2566b437497dd6fd908135ec39e" + hash: "329e4cd26283eb08188d96b2b0325733" } Frame { msec: 1680 - hash: "5c22c2566b437497dd6fd908135ec39e" + hash: "329e4cd26283eb08188d96b2b0325733" } Frame { msec: 1696 - hash: "5c22c2566b437497dd6fd908135ec39e" + hash: "329e4cd26283eb08188d96b2b0325733" } Frame { msec: 1712 - hash: "5c22c2566b437497dd6fd908135ec39e" + hash: "329e4cd26283eb08188d96b2b0325733" } Key { type: 6 @@ -730,15 +730,15 @@ VisualTest { } Frame { msec: 1728 - hash: "29b4e69de4c83ccdee6ef116ab3785ee" + hash: "7b5ac2afafbbaf1e13c70a11461820ad" } Frame { msec: 1744 - hash: "29b4e69de4c83ccdee6ef116ab3785ee" + hash: "7b5ac2afafbbaf1e13c70a11461820ad" } Frame { msec: 1760 - hash: "29b4e69de4c83ccdee6ef116ab3785ee" + hash: "7b5ac2afafbbaf1e13c70a11461820ad" } Key { type: 7 @@ -750,7 +750,7 @@ VisualTest { } Frame { msec: 1776 - hash: "29b4e69de4c83ccdee6ef116ab3785ee" + hash: "7b5ac2afafbbaf1e13c70a11461820ad" } Key { type: 6 @@ -762,11 +762,11 @@ VisualTest { } Frame { msec: 1792 - hash: "5ab8ecb0ca9fed70f1d8add6b7b3972d" + hash: "bcfa1aa48767f70541a70cb5f85792ba" } Frame { msec: 1808 - hash: "5ab8ecb0ca9fed70f1d8add6b7b3972d" + hash: "bcfa1aa48767f70541a70cb5f85792ba" } Key { type: 7 @@ -778,19 +778,19 @@ VisualTest { } Frame { msec: 1824 - hash: "5ab8ecb0ca9fed70f1d8add6b7b3972d" + hash: "bcfa1aa48767f70541a70cb5f85792ba" } Frame { msec: 1840 - hash: "5ab8ecb0ca9fed70f1d8add6b7b3972d" + hash: "bcfa1aa48767f70541a70cb5f85792ba" } Frame { msec: 1856 - hash: "5ab8ecb0ca9fed70f1d8add6b7b3972d" + hash: "bcfa1aa48767f70541a70cb5f85792ba" } Frame { msec: 1872 - hash: "5ab8ecb0ca9fed70f1d8add6b7b3972d" + hash: "bcfa1aa48767f70541a70cb5f85792ba" } Key { type: 7 @@ -802,15 +802,15 @@ VisualTest { } Frame { msec: 1888 - hash: "5ab8ecb0ca9fed70f1d8add6b7b3972d" + hash: "bcfa1aa48767f70541a70cb5f85792ba" } Frame { msec: 1904 - hash: "5ab8ecb0ca9fed70f1d8add6b7b3972d" + hash: "bcfa1aa48767f70541a70cb5f85792ba" } Frame { msec: 1920 - hash: "5ab8ecb0ca9fed70f1d8add6b7b3972d" + hash: "bcfa1aa48767f70541a70cb5f85792ba" } Frame { msec: 1936 @@ -818,7 +818,7 @@ VisualTest { } Frame { msec: 1952 - hash: "5ab8ecb0ca9fed70f1d8add6b7b3972d" + hash: "bcfa1aa48767f70541a70cb5f85792ba" } Key { type: 6 @@ -830,27 +830,27 @@ VisualTest { } Frame { msec: 1968 - hash: "2a43f5ac0c7bdf38e367b0cdb0bccea9" + hash: "e89f7cf38b3b596298d6c649a1207469" } Frame { msec: 1984 - hash: "2a43f5ac0c7bdf38e367b0cdb0bccea9" + hash: "e89f7cf38b3b596298d6c649a1207469" } Frame { msec: 2000 - hash: "2a43f5ac0c7bdf38e367b0cdb0bccea9" + hash: "e89f7cf38b3b596298d6c649a1207469" } Frame { msec: 2016 - hash: "2a43f5ac0c7bdf38e367b0cdb0bccea9" + hash: "e89f7cf38b3b596298d6c649a1207469" } Frame { msec: 2032 - hash: "2a43f5ac0c7bdf38e367b0cdb0bccea9" + hash: "e89f7cf38b3b596298d6c649a1207469" } Frame { msec: 2048 - hash: "2a43f5ac0c7bdf38e367b0cdb0bccea9" + hash: "e89f7cf38b3b596298d6c649a1207469" } Key { type: 6 @@ -862,7 +862,7 @@ VisualTest { } Frame { msec: 2064 - hash: "0f28c7855c7fde3390d16a2638e23bd0" + hash: "18e71331b42a115f7f9d5c09e235b944" } Key { type: 7 @@ -874,15 +874,15 @@ VisualTest { } Frame { msec: 2080 - hash: "0f28c7855c7fde3390d16a2638e23bd0" + hash: "18e71331b42a115f7f9d5c09e235b944" } Frame { msec: 2096 - hash: "0f28c7855c7fde3390d16a2638e23bd0" + hash: "18e71331b42a115f7f9d5c09e235b944" } Frame { msec: 2112 - hash: "0f28c7855c7fde3390d16a2638e23bd0" + hash: "18e71331b42a115f7f9d5c09e235b944" } Key { type: 7 @@ -894,27 +894,27 @@ VisualTest { } Frame { msec: 2128 - hash: "0f28c7855c7fde3390d16a2638e23bd0" + hash: "18e71331b42a115f7f9d5c09e235b944" } Frame { msec: 2144 - hash: "0f28c7855c7fde3390d16a2638e23bd0" + hash: "18e71331b42a115f7f9d5c09e235b944" } Frame { msec: 2160 - hash: "0f28c7855c7fde3390d16a2638e23bd0" + hash: "18e71331b42a115f7f9d5c09e235b944" } Frame { msec: 2176 - hash: "0f28c7855c7fde3390d16a2638e23bd0" + hash: "18e71331b42a115f7f9d5c09e235b944" } Frame { msec: 2192 - hash: "0f28c7855c7fde3390d16a2638e23bd0" + hash: "18e71331b42a115f7f9d5c09e235b944" } Frame { msec: 2208 - hash: "0f28c7855c7fde3390d16a2638e23bd0" + hash: "18e71331b42a115f7f9d5c09e235b944" } Key { type: 6 @@ -926,23 +926,23 @@ VisualTest { } Frame { msec: 2224 - hash: "b56e002e5eddde0245f7ad4c75339968" + hash: "3630abd7cc6ab303d08f30dea7b1eec1" } Frame { msec: 2240 - hash: "b56e002e5eddde0245f7ad4c75339968" + hash: "3630abd7cc6ab303d08f30dea7b1eec1" } Frame { msec: 2256 - hash: "b56e002e5eddde0245f7ad4c75339968" + hash: "3630abd7cc6ab303d08f30dea7b1eec1" } Frame { msec: 2272 - hash: "b56e002e5eddde0245f7ad4c75339968" + hash: "3630abd7cc6ab303d08f30dea7b1eec1" } Frame { msec: 2288 - hash: "b56e002e5eddde0245f7ad4c75339968" + hash: "3630abd7cc6ab303d08f30dea7b1eec1" } Key { type: 6 @@ -954,7 +954,7 @@ VisualTest { } Frame { msec: 2304 - hash: "0bdd50e3c8b382b464c82d791ae6c1e5" + hash: "83e7b8c680cda95ec0a669b8030a3efd" } Key { type: 7 @@ -966,15 +966,15 @@ VisualTest { } Frame { msec: 2320 - hash: "0bdd50e3c8b382b464c82d791ae6c1e5" + hash: "83e7b8c680cda95ec0a669b8030a3efd" } Frame { msec: 2336 - hash: "0bdd50e3c8b382b464c82d791ae6c1e5" + hash: "83e7b8c680cda95ec0a669b8030a3efd" } Frame { msec: 2352 - hash: "0bdd50e3c8b382b464c82d791ae6c1e5" + hash: "83e7b8c680cda95ec0a669b8030a3efd" } Key { type: 6 @@ -986,11 +986,11 @@ VisualTest { } Frame { msec: 2368 - hash: "b61b475b84c6e6a149f6262fc560b741" + hash: "cc826833607ae754e633d21ca67a6b5a" } Frame { msec: 2384 - hash: "b61b475b84c6e6a149f6262fc560b741" + hash: "cc826833607ae754e633d21ca67a6b5a" } Key { type: 7 @@ -1002,15 +1002,15 @@ VisualTest { } Frame { msec: 2400 - hash: "b61b475b84c6e6a149f6262fc560b741" + hash: "cc826833607ae754e633d21ca67a6b5a" } Frame { msec: 2416 - hash: "b61b475b84c6e6a149f6262fc560b741" + hash: "cc826833607ae754e633d21ca67a6b5a" } Frame { msec: 2432 - hash: "b61b475b84c6e6a149f6262fc560b741" + hash: "cc826833607ae754e633d21ca67a6b5a" } Key { type: 7 @@ -1022,15 +1022,15 @@ VisualTest { } Frame { msec: 2448 - hash: "b61b475b84c6e6a149f6262fc560b741" + hash: "cc826833607ae754e633d21ca67a6b5a" } Frame { msec: 2464 - hash: "b61b475b84c6e6a149f6262fc560b741" + hash: "cc826833607ae754e633d21ca67a6b5a" } Frame { msec: 2480 - hash: "b61b475b84c6e6a149f6262fc560b741" + hash: "cc826833607ae754e633d21ca67a6b5a" } Key { type: 6 @@ -1042,19 +1042,19 @@ VisualTest { } Frame { msec: 2496 - hash: "1acd6152f317a6c8f6aca52ccf62a8c6" + hash: "2b4c812fac4e84909cc8fc70d8966a27" } Frame { msec: 2512 - hash: "1acd6152f317a6c8f6aca52ccf62a8c6" + hash: "2b4c812fac4e84909cc8fc70d8966a27" } Frame { msec: 2528 - hash: "1acd6152f317a6c8f6aca52ccf62a8c6" + hash: "2b4c812fac4e84909cc8fc70d8966a27" } Frame { msec: 2544 - hash: "1acd6152f317a6c8f6aca52ccf62a8c6" + hash: "2b4c812fac4e84909cc8fc70d8966a27" } Key { type: 7 @@ -1066,27 +1066,27 @@ VisualTest { } Frame { msec: 2560 - hash: "1acd6152f317a6c8f6aca52ccf62a8c6" + hash: "2b4c812fac4e84909cc8fc70d8966a27" } Frame { msec: 2576 - hash: "1acd6152f317a6c8f6aca52ccf62a8c6" + hash: "2b4c812fac4e84909cc8fc70d8966a27" } Frame { msec: 2592 - hash: "1acd6152f317a6c8f6aca52ccf62a8c6" + hash: "2b4c812fac4e84909cc8fc70d8966a27" } Frame { msec: 2608 - hash: "1acd6152f317a6c8f6aca52ccf62a8c6" + hash: "2b4c812fac4e84909cc8fc70d8966a27" } Frame { msec: 2624 - hash: "1acd6152f317a6c8f6aca52ccf62a8c6" + hash: "2b4c812fac4e84909cc8fc70d8966a27" } Frame { msec: 2640 - hash: "1acd6152f317a6c8f6aca52ccf62a8c6" + hash: "2b4c812fac4e84909cc8fc70d8966a27" } Key { type: 6 @@ -1098,19 +1098,19 @@ VisualTest { } Frame { msec: 2656 - hash: "90ab887de5fbf34f4d45e13c4b211490" + hash: "c1aabf4b43cbae0d7654ba78fc870fdd" } Frame { msec: 2672 - hash: "90ab887de5fbf34f4d45e13c4b211490" + hash: "c1aabf4b43cbae0d7654ba78fc870fdd" } Frame { msec: 2688 - hash: "90ab887de5fbf34f4d45e13c4b211490" + hash: "c1aabf4b43cbae0d7654ba78fc870fdd" } Frame { msec: 2704 - hash: "90ab887de5fbf34f4d45e13c4b211490" + hash: "c1aabf4b43cbae0d7654ba78fc870fdd" } Key { type: 7 @@ -1122,15 +1122,15 @@ VisualTest { } Frame { msec: 2720 - hash: "90ab887de5fbf34f4d45e13c4b211490" + hash: "c1aabf4b43cbae0d7654ba78fc870fdd" } Frame { msec: 2736 - hash: "90ab887de5fbf34f4d45e13c4b211490" + hash: "c1aabf4b43cbae0d7654ba78fc870fdd" } Frame { msec: 2752 - hash: "90ab887de5fbf34f4d45e13c4b211490" + hash: "c1aabf4b43cbae0d7654ba78fc870fdd" } Key { type: 6 @@ -1142,23 +1142,23 @@ VisualTest { } Frame { msec: 2768 - hash: "fc91281749bf1a844a19f20d87a17126" + hash: "a707dd726c777a661e4f12d27a75cf63" } Frame { msec: 2784 - hash: "fc91281749bf1a844a19f20d87a17126" + hash: "a707dd726c777a661e4f12d27a75cf63" } Frame { msec: 2800 - hash: "fc91281749bf1a844a19f20d87a17126" + hash: "a707dd726c777a661e4f12d27a75cf63" } Frame { msec: 2816 - hash: "fc91281749bf1a844a19f20d87a17126" + hash: "a707dd726c777a661e4f12d27a75cf63" } Frame { msec: 2832 - hash: "fc91281749bf1a844a19f20d87a17126" + hash: "a707dd726c777a661e4f12d27a75cf63" } Key { type: 6 @@ -1178,15 +1178,15 @@ VisualTest { } Frame { msec: 2848 - hash: "dcf6e510866fa20e54255c2c980d7b4b" + hash: "bdaa69c1074f9820901ce31ea24383ca" } Frame { msec: 2864 - hash: "dcf6e510866fa20e54255c2c980d7b4b" + hash: "bdaa69c1074f9820901ce31ea24383ca" } Frame { msec: 2880 - hash: "dcf6e510866fa20e54255c2c980d7b4b" + hash: "bdaa69c1074f9820901ce31ea24383ca" } Frame { msec: 2896 @@ -1202,11 +1202,11 @@ VisualTest { } Frame { msec: 2912 - hash: "a26b06714f951084f2ee5ee4b4e67e43" + hash: "f703f87031be4f9d7409fb145343c02b" } Frame { msec: 2928 - hash: "a26b06714f951084f2ee5ee4b4e67e43" + hash: "f703f87031be4f9d7409fb145343c02b" } Key { type: 7 @@ -1218,11 +1218,11 @@ VisualTest { } Frame { msec: 2944 - hash: "a26b06714f951084f2ee5ee4b4e67e43" + hash: "f703f87031be4f9d7409fb145343c02b" } Frame { msec: 2960 - hash: "a26b06714f951084f2ee5ee4b4e67e43" + hash: "f703f87031be4f9d7409fb145343c02b" } Key { type: 7 @@ -1234,35 +1234,35 @@ VisualTest { } Frame { msec: 2976 - hash: "a26b06714f951084f2ee5ee4b4e67e43" + hash: "f703f87031be4f9d7409fb145343c02b" } Frame { msec: 2992 - hash: "a26b06714f951084f2ee5ee4b4e67e43" + hash: "f703f87031be4f9d7409fb145343c02b" } Frame { msec: 3008 - hash: "a26b06714f951084f2ee5ee4b4e67e43" + hash: "f703f87031be4f9d7409fb145343c02b" } Frame { msec: 3024 - hash: "a26b06714f951084f2ee5ee4b4e67e43" + hash: "f703f87031be4f9d7409fb145343c02b" } Frame { msec: 3040 - hash: "a26b06714f951084f2ee5ee4b4e67e43" + hash: "f703f87031be4f9d7409fb145343c02b" } Frame { msec: 3056 - hash: "a26b06714f951084f2ee5ee4b4e67e43" + hash: "f703f87031be4f9d7409fb145343c02b" } Frame { msec: 3072 - hash: "a26b06714f951084f2ee5ee4b4e67e43" + hash: "f703f87031be4f9d7409fb145343c02b" } Frame { msec: 3088 - hash: "a26b06714f951084f2ee5ee4b4e67e43" + hash: "f703f87031be4f9d7409fb145343c02b" } Key { type: 6 @@ -1274,23 +1274,23 @@ VisualTest { } Frame { msec: 3104 - hash: "832c43553cea6d22b7664ef6f145d1c6" + hash: "cb2660df955b757b00661a1acb5f22d2" } Frame { msec: 3120 - hash: "832c43553cea6d22b7664ef6f145d1c6" + hash: "cb2660df955b757b00661a1acb5f22d2" } Frame { msec: 3136 - hash: "832c43553cea6d22b7664ef6f145d1c6" + hash: "cb2660df955b757b00661a1acb5f22d2" } Frame { msec: 3152 - hash: "832c43553cea6d22b7664ef6f145d1c6" + hash: "cb2660df955b757b00661a1acb5f22d2" } Frame { msec: 3168 - hash: "832c43553cea6d22b7664ef6f145d1c6" + hash: "cb2660df955b757b00661a1acb5f22d2" } Key { type: 7 @@ -1302,23 +1302,23 @@ VisualTest { } Frame { msec: 3184 - hash: "832c43553cea6d22b7664ef6f145d1c6" + hash: "cb2660df955b757b00661a1acb5f22d2" } Frame { msec: 3200 - hash: "832c43553cea6d22b7664ef6f145d1c6" + hash: "cb2660df955b757b00661a1acb5f22d2" } Frame { msec: 3216 - hash: "832c43553cea6d22b7664ef6f145d1c6" + hash: "cb2660df955b757b00661a1acb5f22d2" } Frame { msec: 3232 - hash: "832c43553cea6d22b7664ef6f145d1c6" + hash: "cb2660df955b757b00661a1acb5f22d2" } Frame { msec: 3248 - hash: "832c43553cea6d22b7664ef6f145d1c6" + hash: "cb2660df955b757b00661a1acb5f22d2" } Key { type: 6 @@ -1330,15 +1330,15 @@ VisualTest { } Frame { msec: 3264 - hash: "081c183901aadcc6406f4ad9f41efa7e" + hash: "8ea510d25195956fa42eabfe3bb9f230" } Frame { msec: 3280 - hash: "081c183901aadcc6406f4ad9f41efa7e" + hash: "8ea510d25195956fa42eabfe3bb9f230" } Frame { msec: 3296 - hash: "081c183901aadcc6406f4ad9f41efa7e" + hash: "8ea510d25195956fa42eabfe3bb9f230" } Key { type: 7 @@ -1350,15 +1350,15 @@ VisualTest { } Frame { msec: 3312 - hash: "081c183901aadcc6406f4ad9f41efa7e" + hash: "8ea510d25195956fa42eabfe3bb9f230" } Frame { msec: 3328 - hash: "081c183901aadcc6406f4ad9f41efa7e" + hash: "8ea510d25195956fa42eabfe3bb9f230" } Frame { msec: 3344 - hash: "081c183901aadcc6406f4ad9f41efa7e" + hash: "8ea510d25195956fa42eabfe3bb9f230" } Key { type: 6 @@ -1370,23 +1370,23 @@ VisualTest { } Frame { msec: 3360 - hash: "9bd3c76a58f942880f40566cfbaa2e99" + hash: "26b58aef7b1f50a5d261718e8266a3fb" } Frame { msec: 3376 - hash: "9bd3c76a58f942880f40566cfbaa2e99" + hash: "26b58aef7b1f50a5d261718e8266a3fb" } Frame { msec: 3392 - hash: "9bd3c76a58f942880f40566cfbaa2e99" + hash: "26b58aef7b1f50a5d261718e8266a3fb" } Frame { msec: 3408 - hash: "9bd3c76a58f942880f40566cfbaa2e99" + hash: "26b58aef7b1f50a5d261718e8266a3fb" } Frame { msec: 3424 - hash: "9bd3c76a58f942880f40566cfbaa2e99" + hash: "26b58aef7b1f50a5d261718e8266a3fb" } Key { type: 7 @@ -1398,15 +1398,15 @@ VisualTest { } Frame { msec: 3440 - hash: "9bd3c76a58f942880f40566cfbaa2e99" + hash: "26b58aef7b1f50a5d261718e8266a3fb" } Frame { msec: 3456 - hash: "9bd3c76a58f942880f40566cfbaa2e99" + hash: "26b58aef7b1f50a5d261718e8266a3fb" } Frame { msec: 3472 - hash: "9bd3c76a58f942880f40566cfbaa2e99" + hash: "26b58aef7b1f50a5d261718e8266a3fb" } Key { type: 6 @@ -1418,19 +1418,19 @@ VisualTest { } Frame { msec: 3488 - hash: "204a2ee8a33e5452d47d95ad4142d417" + hash: "012854de1c9d1a772994d02f52bdcd7c" } Frame { msec: 3504 - hash: "204a2ee8a33e5452d47d95ad4142d417" + hash: "012854de1c9d1a772994d02f52bdcd7c" } Frame { msec: 3520 - hash: "204a2ee8a33e5452d47d95ad4142d417" + hash: "012854de1c9d1a772994d02f52bdcd7c" } Frame { msec: 3536 - hash: "204a2ee8a33e5452d47d95ad4142d417" + hash: "012854de1c9d1a772994d02f52bdcd7c" } Key { type: 7 @@ -1442,11 +1442,11 @@ VisualTest { } Frame { msec: 3552 - hash: "204a2ee8a33e5452d47d95ad4142d417" + hash: "012854de1c9d1a772994d02f52bdcd7c" } Frame { msec: 3568 - hash: "204a2ee8a33e5452d47d95ad4142d417" + hash: "012854de1c9d1a772994d02f52bdcd7c" } Key { type: 6 @@ -1458,27 +1458,27 @@ VisualTest { } Frame { msec: 3584 - hash: "4729d1f555fe604d4660f02673f9c5f3" + hash: "660a31e1c0d573f4155cfa8fe2323413" } Frame { msec: 3600 - hash: "4729d1f555fe604d4660f02673f9c5f3" + hash: "660a31e1c0d573f4155cfa8fe2323413" } Frame { msec: 3616 - hash: "4729d1f555fe604d4660f02673f9c5f3" + hash: "660a31e1c0d573f4155cfa8fe2323413" } Frame { msec: 3632 - hash: "4729d1f555fe604d4660f02673f9c5f3" + hash: "660a31e1c0d573f4155cfa8fe2323413" } Frame { msec: 3648 - hash: "4729d1f555fe604d4660f02673f9c5f3" + hash: "660a31e1c0d573f4155cfa8fe2323413" } Frame { msec: 3664 - hash: "4729d1f555fe604d4660f02673f9c5f3" + hash: "660a31e1c0d573f4155cfa8fe2323413" } Key { type: 6 @@ -1490,7 +1490,7 @@ VisualTest { } Frame { msec: 3680 - hash: "2c0e0951ce4839b302a6e2735adc6c09" + hash: "bea00f5e628e40b679eb8829c16c6260" } Key { type: 7 @@ -1502,23 +1502,23 @@ VisualTest { } Frame { msec: 3696 - hash: "2c0e0951ce4839b302a6e2735adc6c09" + hash: "bea00f5e628e40b679eb8829c16c6260" } Frame { msec: 3712 - hash: "2c0e0951ce4839b302a6e2735adc6c09" + hash: "bea00f5e628e40b679eb8829c16c6260" } Frame { msec: 3728 - hash: "2c0e0951ce4839b302a6e2735adc6c09" + hash: "bea00f5e628e40b679eb8829c16c6260" } Frame { msec: 3744 - hash: "2c0e0951ce4839b302a6e2735adc6c09" + hash: "bea00f5e628e40b679eb8829c16c6260" } Frame { msec: 3760 - hash: "2c0e0951ce4839b302a6e2735adc6c09" + hash: "bea00f5e628e40b679eb8829c16c6260" } Key { type: 7 @@ -1530,23 +1530,23 @@ VisualTest { } Frame { msec: 3776 - hash: "2c0e0951ce4839b302a6e2735adc6c09" + hash: "bea00f5e628e40b679eb8829c16c6260" } Frame { msec: 3792 - hash: "2c0e0951ce4839b302a6e2735adc6c09" + hash: "bea00f5e628e40b679eb8829c16c6260" } Frame { msec: 3808 - hash: "2c0e0951ce4839b302a6e2735adc6c09" + hash: "bea00f5e628e40b679eb8829c16c6260" } Frame { msec: 3824 - hash: "2c0e0951ce4839b302a6e2735adc6c09" + hash: "bea00f5e628e40b679eb8829c16c6260" } Frame { msec: 3840 - hash: "2c0e0951ce4839b302a6e2735adc6c09" + hash: "bea00f5e628e40b679eb8829c16c6260" } Frame { msec: 3856 @@ -1554,15 +1554,15 @@ VisualTest { } Frame { msec: 3872 - hash: "2c0e0951ce4839b302a6e2735adc6c09" + hash: "bea00f5e628e40b679eb8829c16c6260" } Frame { msec: 3888 - hash: "2c0e0951ce4839b302a6e2735adc6c09" + hash: "bea00f5e628e40b679eb8829c16c6260" } Frame { msec: 3904 - hash: "2c0e0951ce4839b302a6e2735adc6c09" + hash: "bea00f5e628e40b679eb8829c16c6260" } Key { type: 6 @@ -1574,23 +1574,23 @@ VisualTest { } Frame { msec: 3920 - hash: "28c2ffe2ad35010dc077625cde7d21b6" + hash: "c5c60cd10a1106161cde5f51dbdec5ad" } Frame { msec: 3936 - hash: "28c2ffe2ad35010dc077625cde7d21b6" + hash: "c5c60cd10a1106161cde5f51dbdec5ad" } Frame { msec: 3952 - hash: "28c2ffe2ad35010dc077625cde7d21b6" + hash: "c5c60cd10a1106161cde5f51dbdec5ad" } Frame { msec: 3968 - hash: "28c2ffe2ad35010dc077625cde7d21b6" + hash: "c5c60cd10a1106161cde5f51dbdec5ad" } Frame { msec: 3984 - hash: "28c2ffe2ad35010dc077625cde7d21b6" + hash: "c5c60cd10a1106161cde5f51dbdec5ad" } Key { type: 7 @@ -1602,11 +1602,11 @@ VisualTest { } Frame { msec: 4000 - hash: "28c2ffe2ad35010dc077625cde7d21b6" + hash: "c5c60cd10a1106161cde5f51dbdec5ad" } Frame { msec: 4016 - hash: "28c2ffe2ad35010dc077625cde7d21b6" + hash: "c5c60cd10a1106161cde5f51dbdec5ad" } Key { type: 6 @@ -1618,15 +1618,15 @@ VisualTest { } Frame { msec: 4032 - hash: "6f206482adcd45a2b0d8d3c8b85f53c6" + hash: "41c26e6a4c911f9ecd082c4d3366806b" } Frame { msec: 4048 - hash: "6f206482adcd45a2b0d8d3c8b85f53c6" + hash: "41c26e6a4c911f9ecd082c4d3366806b" } Frame { msec: 4064 - hash: "6f206482adcd45a2b0d8d3c8b85f53c6" + hash: "41c26e6a4c911f9ecd082c4d3366806b" } Key { type: 7 @@ -1638,7 +1638,7 @@ VisualTest { } Frame { msec: 4080 - hash: "6f206482adcd45a2b0d8d3c8b85f53c6" + hash: "41c26e6a4c911f9ecd082c4d3366806b" } Key { type: 6 @@ -1650,19 +1650,19 @@ VisualTest { } Frame { msec: 4096 - hash: "4685a786f36cb821a69b0ac059145a5f" + hash: "e212938ce981ed4e8d7a993468bc9377" } Frame { msec: 4112 - hash: "4685a786f36cb821a69b0ac059145a5f" + hash: "e212938ce981ed4e8d7a993468bc9377" } Frame { msec: 4128 - hash: "4685a786f36cb821a69b0ac059145a5f" + hash: "e212938ce981ed4e8d7a993468bc9377" } Frame { msec: 4144 - hash: "4685a786f36cb821a69b0ac059145a5f" + hash: "e212938ce981ed4e8d7a993468bc9377" } Key { type: 7 @@ -1674,15 +1674,15 @@ VisualTest { } Frame { msec: 4160 - hash: "4685a786f36cb821a69b0ac059145a5f" + hash: "e212938ce981ed4e8d7a993468bc9377" } Frame { msec: 4176 - hash: "4685a786f36cb821a69b0ac059145a5f" + hash: "e212938ce981ed4e8d7a993468bc9377" } Frame { msec: 4192 - hash: "4685a786f36cb821a69b0ac059145a5f" + hash: "e212938ce981ed4e8d7a993468bc9377" } Key { type: 6 @@ -1694,23 +1694,23 @@ VisualTest { } Frame { msec: 4208 - hash: "d0efb89ee3e2d2b18429b57dcfe13f33" + hash: "55df0528a97d77d0a4b513aeedd34440" } Frame { msec: 4224 - hash: "d0efb89ee3e2d2b18429b57dcfe13f33" + hash: "55df0528a97d77d0a4b513aeedd34440" } Frame { msec: 4240 - hash: "d0efb89ee3e2d2b18429b57dcfe13f33" + hash: "55df0528a97d77d0a4b513aeedd34440" } Frame { msec: 4256 - hash: "d0efb89ee3e2d2b18429b57dcfe13f33" + hash: "55df0528a97d77d0a4b513aeedd34440" } Frame { msec: 4272 - hash: "d0efb89ee3e2d2b18429b57dcfe13f33" + hash: "55df0528a97d77d0a4b513aeedd34440" } Key { type: 6 @@ -1722,7 +1722,7 @@ VisualTest { } Frame { msec: 4288 - hash: "cbe0bb714b2e9b63af978f666292d8f0" + hash: "2165091c97a891560bf3afab879e6dbc" } Key { type: 7 @@ -1734,15 +1734,15 @@ VisualTest { } Frame { msec: 4304 - hash: "cbe0bb714b2e9b63af978f666292d8f0" + hash: "2165091c97a891560bf3afab879e6dbc" } Frame { msec: 4320 - hash: "cbe0bb714b2e9b63af978f666292d8f0" + hash: "2165091c97a891560bf3afab879e6dbc" } Frame { msec: 4336 - hash: "cbe0bb714b2e9b63af978f666292d8f0" + hash: "2165091c97a891560bf3afab879e6dbc" } Key { type: 7 @@ -1754,23 +1754,23 @@ VisualTest { } Frame { msec: 4352 - hash: "cbe0bb714b2e9b63af978f666292d8f0" + hash: "2165091c97a891560bf3afab879e6dbc" } Frame { msec: 4368 - hash: "cbe0bb714b2e9b63af978f666292d8f0" + hash: "2165091c97a891560bf3afab879e6dbc" } Frame { msec: 4384 - hash: "cbe0bb714b2e9b63af978f666292d8f0" + hash: "2165091c97a891560bf3afab879e6dbc" } Frame { msec: 4400 - hash: "cbe0bb714b2e9b63af978f666292d8f0" + hash: "2165091c97a891560bf3afab879e6dbc" } Frame { msec: 4416 - hash: "cbe0bb714b2e9b63af978f666292d8f0" + hash: "2165091c97a891560bf3afab879e6dbc" } Key { type: 6 @@ -1782,15 +1782,15 @@ VisualTest { } Frame { msec: 4432 - hash: "d15a45a86874daaff5f2e6afae43b2f4" + hash: "a3d7968e13768c4ec538fe9ba7edf142" } Frame { msec: 4448 - hash: "d15a45a86874daaff5f2e6afae43b2f4" + hash: "a3d7968e13768c4ec538fe9ba7edf142" } Frame { msec: 4464 - hash: "d15a45a86874daaff5f2e6afae43b2f4" + hash: "a3d7968e13768c4ec538fe9ba7edf142" } Key { type: 7 @@ -1802,23 +1802,23 @@ VisualTest { } Frame { msec: 4480 - hash: "d15a45a86874daaff5f2e6afae43b2f4" + hash: "a3d7968e13768c4ec538fe9ba7edf142" } Frame { msec: 4496 - hash: "d15a45a86874daaff5f2e6afae43b2f4" + hash: "a3d7968e13768c4ec538fe9ba7edf142" } Frame { msec: 4512 - hash: "d15a45a86874daaff5f2e6afae43b2f4" + hash: "a3d7968e13768c4ec538fe9ba7edf142" } Frame { msec: 4528 - hash: "d15a45a86874daaff5f2e6afae43b2f4" + hash: "a3d7968e13768c4ec538fe9ba7edf142" } Frame { msec: 4544 - hash: "d15a45a86874daaff5f2e6afae43b2f4" + hash: "a3d7968e13768c4ec538fe9ba7edf142" } Key { type: 6 @@ -1830,19 +1830,19 @@ VisualTest { } Frame { msec: 4560 - hash: "b0c3ef9c5331af8768b23537d1d38311" + hash: "3b18ada8637d4024acfe88718765f71c" } Frame { msec: 4576 - hash: "b0c3ef9c5331af8768b23537d1d38311" + hash: "3b18ada8637d4024acfe88718765f71c" } Frame { msec: 4592 - hash: "b0c3ef9c5331af8768b23537d1d38311" + hash: "3b18ada8637d4024acfe88718765f71c" } Frame { msec: 4608 - hash: "b0c3ef9c5331af8768b23537d1d38311" + hash: "3b18ada8637d4024acfe88718765f71c" } Key { type: 7 @@ -1854,19 +1854,19 @@ VisualTest { } Frame { msec: 4624 - hash: "b0c3ef9c5331af8768b23537d1d38311" + hash: "3b18ada8637d4024acfe88718765f71c" } Frame { msec: 4640 - hash: "b0c3ef9c5331af8768b23537d1d38311" + hash: "3b18ada8637d4024acfe88718765f71c" } Frame { msec: 4656 - hash: "b0c3ef9c5331af8768b23537d1d38311" + hash: "3b18ada8637d4024acfe88718765f71c" } Frame { msec: 4672 - hash: "b0c3ef9c5331af8768b23537d1d38311" + hash: "3b18ada8637d4024acfe88718765f71c" } Key { type: 6 @@ -1878,19 +1878,19 @@ VisualTest { } Frame { msec: 4688 - hash: "3be1d2faec1ab5d3d1ab72c25db95059" + hash: "c419775870b0c5e41b5156c840e6a298" } Frame { msec: 4704 - hash: "3be1d2faec1ab5d3d1ab72c25db95059" + hash: "c419775870b0c5e41b5156c840e6a298" } Frame { msec: 4720 - hash: "3be1d2faec1ab5d3d1ab72c25db95059" + hash: "c419775870b0c5e41b5156c840e6a298" } Frame { msec: 4736 - hash: "3be1d2faec1ab5d3d1ab72c25db95059" + hash: "c419775870b0c5e41b5156c840e6a298" } Key { type: 7 @@ -1902,15 +1902,15 @@ VisualTest { } Frame { msec: 4752 - hash: "3be1d2faec1ab5d3d1ab72c25db95059" + hash: "c419775870b0c5e41b5156c840e6a298" } Frame { msec: 4768 - hash: "3be1d2faec1ab5d3d1ab72c25db95059" + hash: "c419775870b0c5e41b5156c840e6a298" } Frame { msec: 4784 - hash: "3be1d2faec1ab5d3d1ab72c25db95059" + hash: "c419775870b0c5e41b5156c840e6a298" } Key { type: 6 @@ -1922,7 +1922,7 @@ VisualTest { } Frame { msec: 4800 - hash: "db999862fcf827930098b3f129ff567f" + hash: "81a744f02650728c7557a27c94056e64" } Frame { msec: 4816 @@ -1938,19 +1938,19 @@ VisualTest { } Frame { msec: 4832 - hash: "db999862fcf827930098b3f129ff567f" + hash: "81a744f02650728c7557a27c94056e64" } Frame { msec: 4848 - hash: "db999862fcf827930098b3f129ff567f" + hash: "81a744f02650728c7557a27c94056e64" } Frame { msec: 4864 - hash: "db999862fcf827930098b3f129ff567f" + hash: "81a744f02650728c7557a27c94056e64" } Frame { msec: 4880 - hash: "db999862fcf827930098b3f129ff567f" + hash: "81a744f02650728c7557a27c94056e64" } Key { type: 6 @@ -1962,19 +1962,19 @@ VisualTest { } Frame { msec: 4896 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 4912 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 4928 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 4944 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Key { type: 7 @@ -1986,207 +1986,207 @@ VisualTest { } Frame { msec: 4960 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 4976 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 4992 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5008 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5024 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5040 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5056 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5072 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5088 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5104 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5120 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5136 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5152 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5168 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5184 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5200 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5216 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5232 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5248 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5264 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5280 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5296 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5312 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5328 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5344 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5360 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5376 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5392 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5408 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5424 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5440 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5456 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5472 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5488 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5504 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5520 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5536 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5552 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5568 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5584 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5600 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5616 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5632 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5648 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5664 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5680 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5696 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5712 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5728 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5744 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5760 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5776 @@ -2194,239 +2194,239 @@ VisualTest { } Frame { msec: 5792 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5808 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5824 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5840 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5856 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5872 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5888 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5904 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5920 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5936 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5952 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5968 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 5984 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6000 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6016 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6032 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6048 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6064 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6080 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6096 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6112 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6128 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6144 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6160 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6176 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6192 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6208 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6224 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6240 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6256 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6272 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6288 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6304 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6320 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6336 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6352 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6368 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6384 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6400 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6416 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6432 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6448 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6464 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6480 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6496 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6512 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6528 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6544 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6560 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6576 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6592 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6608 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6624 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6640 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6656 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6672 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6688 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6704 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6720 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6736 @@ -2434,34 +2434,34 @@ VisualTest { } Frame { msec: 6752 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6768 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6784 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6800 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6816 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6832 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6848 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } Frame { msec: 6864 - hash: "6557c4982e2c23d0ef5ec8a594df7277" + hash: "ed1520bf20159e60c6a75bbf07f3a6ee" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.1.png index 914f1b1..c9e17f9 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.2.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.2.png index dd2b946..32a5600 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.2.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.3.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.3.png index 629b84b..a63fd07 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.3.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.qml index 211ca68..c752f0f 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.qml @@ -274,15 +274,15 @@ VisualTest { } Frame { msec: 864 - hash: "a1c7aeece2891f3ca0103761ffa7f424" + hash: "24a0a2f12031b23a98d65178f0d6d58d" } Frame { msec: 880 - hash: "a1c7aeece2891f3ca0103761ffa7f424" + hash: "24a0a2f12031b23a98d65178f0d6d58d" } Frame { msec: 896 - hash: "a1c7aeece2891f3ca0103761ffa7f424" + hash: "24a0a2f12031b23a98d65178f0d6d58d" } Key { type: 7 @@ -294,19 +294,19 @@ VisualTest { } Frame { msec: 912 - hash: "a1c7aeece2891f3ca0103761ffa7f424" + hash: "24a0a2f12031b23a98d65178f0d6d58d" } Frame { msec: 928 - hash: "a1c7aeece2891f3ca0103761ffa7f424" + hash: "24a0a2f12031b23a98d65178f0d6d58d" } Frame { msec: 944 - hash: "a1c7aeece2891f3ca0103761ffa7f424" + hash: "24a0a2f12031b23a98d65178f0d6d58d" } Frame { msec: 960 - hash: "a1c7aeece2891f3ca0103761ffa7f424" + hash: "24a0a2f12031b23a98d65178f0d6d58d" } Frame { msec: 976 @@ -322,19 +322,19 @@ VisualTest { } Frame { msec: 992 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Frame { msec: 1008 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Frame { msec: 1024 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Frame { msec: 1040 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Key { type: 7 @@ -346,51 +346,51 @@ VisualTest { } Frame { msec: 1056 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Frame { msec: 1072 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Frame { msec: 1088 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Frame { msec: 1104 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Frame { msec: 1120 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Frame { msec: 1136 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Frame { msec: 1152 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Frame { msec: 1168 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Frame { msec: 1184 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Frame { msec: 1200 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Frame { msec: 1216 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Frame { msec: 1232 - hash: "7a4ebe5f0875ded07b44c9ff2d6a4d75" + hash: "7dde2dd8afe7283dd0601b12831f8946" } Key { type: 6 @@ -402,15 +402,15 @@ VisualTest { } Frame { msec: 1248 - hash: "b7cdd294253e065c06fabc60895a29c2" + hash: "e098aa83b3287f67aba57e134e871d62" } Frame { msec: 1264 - hash: "b7cdd294253e065c06fabc60895a29c2" + hash: "e098aa83b3287f67aba57e134e871d62" } Frame { msec: 1280 - hash: "b7cdd294253e065c06fabc60895a29c2" + hash: "e098aa83b3287f67aba57e134e871d62" } Key { type: 7 @@ -422,15 +422,15 @@ VisualTest { } Frame { msec: 1296 - hash: "b7cdd294253e065c06fabc60895a29c2" + hash: "e098aa83b3287f67aba57e134e871d62" } Frame { msec: 1312 - hash: "b7cdd294253e065c06fabc60895a29c2" + hash: "e098aa83b3287f67aba57e134e871d62" } Frame { msec: 1328 - hash: "b7cdd294253e065c06fabc60895a29c2" + hash: "e098aa83b3287f67aba57e134e871d62" } Key { type: 6 @@ -442,39 +442,39 @@ VisualTest { } Frame { msec: 1344 - hash: "d8669a3194f485aaef3a1421f7fd50f6" + hash: "3f0a9e0cfd6937c943273bc1d39ce336" } Frame { msec: 1360 - hash: "d8669a3194f485aaef3a1421f7fd50f6" + hash: "3f0a9e0cfd6937c943273bc1d39ce336" } Frame { msec: 1376 - hash: "d8669a3194f485aaef3a1421f7fd50f6" + hash: "3f0a9e0cfd6937c943273bc1d39ce336" } Frame { msec: 1392 - hash: "d8669a3194f485aaef3a1421f7fd50f6" + hash: "3f0a9e0cfd6937c943273bc1d39ce336" } Frame { msec: 1408 - hash: "d8669a3194f485aaef3a1421f7fd50f6" + hash: "3f0a9e0cfd6937c943273bc1d39ce336" } Frame { msec: 1424 - hash: "d8669a3194f485aaef3a1421f7fd50f6" + hash: "3f0a9e0cfd6937c943273bc1d39ce336" } Frame { msec: 1440 - hash: "d8669a3194f485aaef3a1421f7fd50f6" + hash: "3f0a9e0cfd6937c943273bc1d39ce336" } Frame { msec: 1456 - hash: "d8669a3194f485aaef3a1421f7fd50f6" + hash: "3f0a9e0cfd6937c943273bc1d39ce336" } Frame { msec: 1472 - hash: "d8669a3194f485aaef3a1421f7fd50f6" + hash: "3f0a9e0cfd6937c943273bc1d39ce336" } Key { type: 7 @@ -486,7 +486,7 @@ VisualTest { } Frame { msec: 1488 - hash: "d8669a3194f485aaef3a1421f7fd50f6" + hash: "3f0a9e0cfd6937c943273bc1d39ce336" } Key { type: 6 @@ -498,19 +498,19 @@ VisualTest { } Frame { msec: 1504 - hash: "b53fd36f58dc692856e6a789371aaf33" + hash: "b78259d22dd86c1dd7ba722795e7e155" } Frame { msec: 1520 - hash: "b53fd36f58dc692856e6a789371aaf33" + hash: "b78259d22dd86c1dd7ba722795e7e155" } Frame { msec: 1536 - hash: "b53fd36f58dc692856e6a789371aaf33" + hash: "b78259d22dd86c1dd7ba722795e7e155" } Frame { msec: 1552 - hash: "b53fd36f58dc692856e6a789371aaf33" + hash: "b78259d22dd86c1dd7ba722795e7e155" } Key { type: 7 @@ -522,27 +522,27 @@ VisualTest { } Frame { msec: 1568 - hash: "b53fd36f58dc692856e6a789371aaf33" + hash: "b78259d22dd86c1dd7ba722795e7e155" } Frame { msec: 1584 - hash: "b53fd36f58dc692856e6a789371aaf33" + hash: "b78259d22dd86c1dd7ba722795e7e155" } Frame { msec: 1600 - hash: "b53fd36f58dc692856e6a789371aaf33" + hash: "b78259d22dd86c1dd7ba722795e7e155" } Frame { msec: 1616 - hash: "b53fd36f58dc692856e6a789371aaf33" + hash: "b78259d22dd86c1dd7ba722795e7e155" } Frame { msec: 1632 - hash: "b53fd36f58dc692856e6a789371aaf33" + hash: "b78259d22dd86c1dd7ba722795e7e155" } Frame { msec: 1648 - hash: "b53fd36f58dc692856e6a789371aaf33" + hash: "b78259d22dd86c1dd7ba722795e7e155" } Key { type: 6 @@ -554,23 +554,23 @@ VisualTest { } Frame { msec: 1664 - hash: "98de66666f6ea1a87bd493db3f67a7c6" + hash: "1402f8182c74124a1fb34ecd78fa4819" } Frame { msec: 1680 - hash: "98de66666f6ea1a87bd493db3f67a7c6" + hash: "1402f8182c74124a1fb34ecd78fa4819" } Frame { msec: 1696 - hash: "98de66666f6ea1a87bd493db3f67a7c6" + hash: "1402f8182c74124a1fb34ecd78fa4819" } Frame { msec: 1712 - hash: "98de66666f6ea1a87bd493db3f67a7c6" + hash: "1402f8182c74124a1fb34ecd78fa4819" } Frame { msec: 1728 - hash: "98de66666f6ea1a87bd493db3f67a7c6" + hash: "1402f8182c74124a1fb34ecd78fa4819" } Key { type: 6 @@ -582,7 +582,7 @@ VisualTest { } Frame { msec: 1744 - hash: "696807419ef2b228dfb9d85dd79dd293" + hash: "93d5b02d77829aef8f8afa0f5a9e93d1" } Key { type: 7 @@ -594,15 +594,15 @@ VisualTest { } Frame { msec: 1760 - hash: "696807419ef2b228dfb9d85dd79dd293" + hash: "93d5b02d77829aef8f8afa0f5a9e93d1" } Frame { msec: 1776 - hash: "696807419ef2b228dfb9d85dd79dd293" + hash: "93d5b02d77829aef8f8afa0f5a9e93d1" } Frame { msec: 1792 - hash: "696807419ef2b228dfb9d85dd79dd293" + hash: "93d5b02d77829aef8f8afa0f5a9e93d1" } Key { type: 7 @@ -614,19 +614,19 @@ VisualTest { } Frame { msec: 1808 - hash: "696807419ef2b228dfb9d85dd79dd293" + hash: "93d5b02d77829aef8f8afa0f5a9e93d1" } Frame { msec: 1824 - hash: "696807419ef2b228dfb9d85dd79dd293" + hash: "93d5b02d77829aef8f8afa0f5a9e93d1" } Frame { msec: 1840 - hash: "696807419ef2b228dfb9d85dd79dd293" + hash: "93d5b02d77829aef8f8afa0f5a9e93d1" } Frame { msec: 1856 - hash: "696807419ef2b228dfb9d85dd79dd293" + hash: "93d5b02d77829aef8f8afa0f5a9e93d1" } Key { type: 6 @@ -638,19 +638,19 @@ VisualTest { } Frame { msec: 1872 - hash: "4c0a528609872cf65180d336bbca4231" + hash: "1f3b2da0ad387187f202857ed9bb4934" } Frame { msec: 1888 - hash: "4c0a528609872cf65180d336bbca4231" + hash: "1f3b2da0ad387187f202857ed9bb4934" } Frame { msec: 1904 - hash: "4c0a528609872cf65180d336bbca4231" + hash: "1f3b2da0ad387187f202857ed9bb4934" } Frame { msec: 1920 - hash: "4c0a528609872cf65180d336bbca4231" + hash: "1f3b2da0ad387187f202857ed9bb4934" } Key { type: 7 @@ -666,23 +666,23 @@ VisualTest { } Frame { msec: 1952 - hash: "4c0a528609872cf65180d336bbca4231" + hash: "1f3b2da0ad387187f202857ed9bb4934" } Frame { msec: 1968 - hash: "4c0a528609872cf65180d336bbca4231" + hash: "1f3b2da0ad387187f202857ed9bb4934" } Frame { msec: 1984 - hash: "4c0a528609872cf65180d336bbca4231" + hash: "1f3b2da0ad387187f202857ed9bb4934" } Frame { msec: 2000 - hash: "4c0a528609872cf65180d336bbca4231" + hash: "1f3b2da0ad387187f202857ed9bb4934" } Frame { msec: 2016 - hash: "4c0a528609872cf65180d336bbca4231" + hash: "1f3b2da0ad387187f202857ed9bb4934" } Key { type: 6 @@ -694,11 +694,11 @@ VisualTest { } Frame { msec: 2032 - hash: "03b670f413abfa1811d4020de969b2ea" + hash: "f2fd02bca5f5bf26013957e11d3f11ce" } Frame { msec: 2048 - hash: "03b670f413abfa1811d4020de969b2ea" + hash: "f2fd02bca5f5bf26013957e11d3f11ce" } Key { type: 7 @@ -710,11 +710,11 @@ VisualTest { } Frame { msec: 2064 - hash: "03b670f413abfa1811d4020de969b2ea" + hash: "f2fd02bca5f5bf26013957e11d3f11ce" } Frame { msec: 2080 - hash: "03b670f413abfa1811d4020de969b2ea" + hash: "f2fd02bca5f5bf26013957e11d3f11ce" } Key { type: 6 @@ -726,19 +726,19 @@ VisualTest { } Frame { msec: 2096 - hash: "6d478c62fa5bb37f0178e94914473174" + hash: "550f7f60df621c951ce7d5271aabc41f" } Frame { msec: 2112 - hash: "6d478c62fa5bb37f0178e94914473174" + hash: "550f7f60df621c951ce7d5271aabc41f" } Frame { msec: 2128 - hash: "6d478c62fa5bb37f0178e94914473174" + hash: "550f7f60df621c951ce7d5271aabc41f" } Frame { msec: 2144 - hash: "6d478c62fa5bb37f0178e94914473174" + hash: "550f7f60df621c951ce7d5271aabc41f" } Key { type: 6 @@ -758,19 +758,19 @@ VisualTest { } Frame { msec: 2160 - hash: "2f9803e906ce38a6ade3874bbeb27216" + hash: "d2aca851dde9f96747d3f54fb831144a" } Frame { msec: 2176 - hash: "2f9803e906ce38a6ade3874bbeb27216" + hash: "d2aca851dde9f96747d3f54fb831144a" } Frame { msec: 2192 - hash: "2f9803e906ce38a6ade3874bbeb27216" + hash: "d2aca851dde9f96747d3f54fb831144a" } Frame { msec: 2208 - hash: "2f9803e906ce38a6ade3874bbeb27216" + hash: "d2aca851dde9f96747d3f54fb831144a" } Key { type: 6 @@ -782,7 +782,7 @@ VisualTest { } Frame { msec: 2224 - hash: "d93582b0c7de46d5ff1c9959c158bfe7" + hash: "9ed75a4dc5b88fe1c1531833db1dd364" } Key { type: 7 @@ -794,23 +794,23 @@ VisualTest { } Frame { msec: 2240 - hash: "d93582b0c7de46d5ff1c9959c158bfe7" + hash: "9ed75a4dc5b88fe1c1531833db1dd364" } Frame { msec: 2256 - hash: "d93582b0c7de46d5ff1c9959c158bfe7" + hash: "9ed75a4dc5b88fe1c1531833db1dd364" } Frame { msec: 2272 - hash: "d93582b0c7de46d5ff1c9959c158bfe7" + hash: "9ed75a4dc5b88fe1c1531833db1dd364" } Frame { msec: 2288 - hash: "d93582b0c7de46d5ff1c9959c158bfe7" + hash: "9ed75a4dc5b88fe1c1531833db1dd364" } Frame { msec: 2304 - hash: "d93582b0c7de46d5ff1c9959c158bfe7" + hash: "9ed75a4dc5b88fe1c1531833db1dd364" } Key { type: 7 @@ -822,11 +822,11 @@ VisualTest { } Frame { msec: 2320 - hash: "d93582b0c7de46d5ff1c9959c158bfe7" + hash: "9ed75a4dc5b88fe1c1531833db1dd364" } Frame { msec: 2336 - hash: "d93582b0c7de46d5ff1c9959c158bfe7" + hash: "9ed75a4dc5b88fe1c1531833db1dd364" } Key { type: 6 @@ -838,27 +838,27 @@ VisualTest { } Frame { msec: 2352 - hash: "8accfa30ddc59803d8f9d2f60dd6a891" + hash: "39079b642f00ea767114d5a831be939a" } Frame { msec: 2368 - hash: "8accfa30ddc59803d8f9d2f60dd6a891" + hash: "39079b642f00ea767114d5a831be939a" } Frame { msec: 2384 - hash: "8accfa30ddc59803d8f9d2f60dd6a891" + hash: "39079b642f00ea767114d5a831be939a" } Frame { msec: 2400 - hash: "8accfa30ddc59803d8f9d2f60dd6a891" + hash: "39079b642f00ea767114d5a831be939a" } Frame { msec: 2416 - hash: "8accfa30ddc59803d8f9d2f60dd6a891" + hash: "39079b642f00ea767114d5a831be939a" } Frame { msec: 2432 - hash: "8accfa30ddc59803d8f9d2f60dd6a891" + hash: "39079b642f00ea767114d5a831be939a" } Key { type: 7 @@ -870,19 +870,19 @@ VisualTest { } Frame { msec: 2448 - hash: "8accfa30ddc59803d8f9d2f60dd6a891" + hash: "39079b642f00ea767114d5a831be939a" } Frame { msec: 2464 - hash: "8accfa30ddc59803d8f9d2f60dd6a891" + hash: "39079b642f00ea767114d5a831be939a" } Frame { msec: 2480 - hash: "8accfa30ddc59803d8f9d2f60dd6a891" + hash: "39079b642f00ea767114d5a831be939a" } Frame { msec: 2496 - hash: "8accfa30ddc59803d8f9d2f60dd6a891" + hash: "39079b642f00ea767114d5a831be939a" } Key { type: 6 @@ -894,15 +894,15 @@ VisualTest { } Frame { msec: 2512 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2528 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2544 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Key { type: 7 @@ -914,87 +914,87 @@ VisualTest { } Frame { msec: 2560 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2576 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2592 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2608 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2624 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2640 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2656 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2672 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2688 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2704 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2720 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2736 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2752 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2768 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2784 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2800 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2816 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2832 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2848 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2864 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2880 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2896 @@ -1002,42 +1002,42 @@ VisualTest { } Frame { msec: 2912 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2928 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2944 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2960 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2976 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 2992 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 3008 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 3024 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 3040 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } Frame { msec: 3056 - hash: "a444ce402f5dc0d892f66a88b8252301" + hash: "92035cf4d7df9e637567c7834f23b030" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/hAlign.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/hAlign.0.png index a12db0a..4c04a1b 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/hAlign.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/hAlign.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/hAlign.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/hAlign.qml index acc646c..74ee95f 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/hAlign.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/hAlign.qml @@ -10,98 +10,98 @@ VisualTest { } Frame { msec: 32 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 48 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 64 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 80 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 96 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 112 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 128 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 144 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 160 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 176 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 192 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 208 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 224 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 240 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 256 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 272 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 288 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 304 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 320 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 336 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 352 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 368 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 384 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } Frame { msec: 400 - hash: "fe5a0e7ac7ea0796d8cf3e49b513669d" + hash: "93758371bdc69b81077989e911f62fb0" } } diff --git a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp index ef0d4dc..fe23e09 100644 --- a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp +++ b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp @@ -104,13 +104,8 @@ void tst_qmlvisual::visual_data() QStringList files; files << findQmlFiles(QDir(QT_TEST_SOURCE_DIR)); if (qgetenv("QMLVISUAL_ALL") != "1") { -#if defined(Q_WS_X11) - //Text on X11 varies per version - and the CI system is currently using something outdated. - foreach(const QString &str, files.filter(QRegExp(".*text.*"))) - files.removeAll(str); -#endif #if defined(Q_WS_MAC) - //Text on Mac also varies per version. Only check the text on 10.6 + //Text on Mac varies per version. Only check the text on 10.6 if(QSysInfo::MacintoshVersion != QSysInfo::MV_10_6) foreach(const QString &str, files.filter(QRegExp(".*text.*"))) files.removeAll(str); -- cgit v0.12 From 89f4a877c401e1ab18d3ed520d17440b3e9078e7 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Thu, 2 Dec 2010 14:20:50 +1000 Subject: Mention that image providers should be added before loading QML files --- src/declarative/qml/qdeclarativeengine.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 7ac3a68..a8404f0 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -678,6 +678,9 @@ QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const requests. See the QDeclarativeImageProvider documentation for details on implementing and using image providers. + All required image providers should be added to the engine before any + QML sources files are loaded. + Note that images loaded from a QDeclarativeImageProvider are cached by QPixmapCache, similar to any image loaded by QML. -- cgit v0.12 From fe63d0ee5671ec4f0a1926ad8875b9f11789b105 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Fri, 3 Dec 2010 10:50:43 +1000 Subject: Add 'Writing New Components' docs, and document the connect() function. The 'Writing QML Components' is mainly a restructuring of the 'Extending types from QML' page. It also documents the signal connect() function that was previously undocumented. Task-number: QTBUG-15718, QTBUG-15138 --- doc/src/declarative/basictypes.qdoc | 4 +- doc/src/declarative/declarativeui.qdoc | 4 +- doc/src/declarative/dynamicobjects.qdoc | 3 + doc/src/declarative/extending-tutorial.qdoc | 4 +- doc/src/declarative/extending.qdoc | 617 +++++++++++---------- doc/src/declarative/javascriptblocks.qdoc | 19 + doc/src/declarative/pics/qml-extending-types.png | Bin 0 -> 738 bytes doc/src/declarative/qtbinding.qdoc | 2 +- doc/src/declarative/tutorial.qdoc | 4 +- doc/src/examples/qml-examples.qdoc | 3 +- .../integrating-javascript/connectjs.qml | 57 ++ .../declarative/integrating-javascript/script.js | 47 ++ .../qml-extending-types/components/Button.qml | 53 ++ .../qml-extending-types/components/application.qml | 49 ++ .../qml-extending-types/methods/app.qml | 55 ++ .../qml-extending-types/properties/ImageViewer.qml | 52 ++ .../properties/alias-override.qml | 48 ++ .../qml-extending-types/properties/alias.qml | 51 ++ .../properties/alias/ImageViewer.qml | 52 ++ .../properties/alias/application.qml | 54 ++ .../qml-extending-types/properties/application.qml | 50 ++ .../properties/property-signals.qml | 49 ++ .../qml-extending-types/signals/Button.qml | 55 ++ .../qml-extending-types/signals/basic.qml | 55 ++ .../qml-extending-types/signals/connectdynamic.qml | 61 ++ .../qml-extending-types/signals/connectslots.qml | 56 ++ .../qml-extending-types/signals/no-parameters.qml | 49 ++ .../qml-extending-types/signals/parameters.qml | 50 ++ .../modelviews/visualitemmodel/visualitemmodel.qml | 7 + .../ui-components/tabwidget/TabWidget.qml | 4 +- 30 files changed, 1296 insertions(+), 318 deletions(-) create mode 100644 doc/src/declarative/pics/qml-extending-types.png create mode 100644 doc/src/snippets/declarative/integrating-javascript/connectjs.qml create mode 100644 doc/src/snippets/declarative/integrating-javascript/script.js create mode 100644 doc/src/snippets/declarative/qml-extending-types/components/Button.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/components/application.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/methods/app.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/properties/ImageViewer.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/properties/alias-override.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/properties/alias.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/properties/alias/ImageViewer.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/properties/alias/application.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/properties/application.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/properties/property-signals.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/signals/Button.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/signals/basic.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/signals/connectdynamic.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/signals/connectslots.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/signals/no-parameters.qml create mode 100644 doc/src/snippets/declarative/qml-extending-types/signals/parameters.qml diff --git a/doc/src/declarative/basictypes.qdoc b/doc/src/declarative/basictypes.qdoc index 71192bf..034b7d1 100644 --- a/doc/src/declarative/basictypes.qdoc +++ b/doc/src/declarative/basictypes.qdoc @@ -33,7 +33,7 @@ the \l {QML Elements}. Some of these types can also be used for defining - \c property values in QML. See \l{Extending types from QML} for the + \c property values in QML. See \l{Writing QML Components: Properties, Methods and Signals} for the list of types that can be used for \c property values. \annotatedlist qmlbasictypes @@ -380,7 +380,7 @@ \c child1, \c child2 and \c child3 will be added to the children list in the order in which they appear. - List \l {Adding new properties}{properties} can be created as a + List \l {Adding Properties}{properties} can be created as a \c variant type, or as a \c list type, where \c Type is the type of the object in the list: diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index 01e1302..5d9eaaf 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -91,9 +91,10 @@ Module. \list \o \l{QML Documents} \o \l{Property Binding} +\o \l{Anchor-based Layout in QML} +\o \l{Writing QML Components: Properties, Methods and Signals} \o \l{QML Scope} \o \l{QML Modules} -\o \l{Anchor-based Layout in QML} \endlist \section1 User Interaction @@ -118,7 +119,6 @@ Module. \list \o \l{Qt Declarative UI Runtime} \o \l{Integrating JavaScript} -\o \l{Extending types from QML} \o \l{Dynamic Object Management in QML} \endlist diff --git a/doc/src/declarative/dynamicobjects.qdoc b/doc/src/declarative/dynamicobjects.qdoc index daf2ae1..fcc9fd4 100644 --- a/doc/src/declarative/dynamicobjects.qdoc +++ b/doc/src/declarative/dynamicobjects.qdoc @@ -102,6 +102,9 @@ Notice in both instances, \l {Component::createObject()}{createObject()} is call When using files with relative paths, the path should be relative to the file where \l {QML:Qt::createComponent()}{Qt.createComponent()} is executed. +To connect signals to (or receive signals from) dynamically created objects, use the signal +\c connect() method. See \l {Connecting signals to methods and other signals} for more information. + \section2 Creating an object from a string of QML diff --git a/doc/src/declarative/extending-tutorial.qdoc b/doc/src/declarative/extending-tutorial.qdoc index dff1d9c..c998c5c 100644 --- a/doc/src/declarative/extending-tutorial.qdoc +++ b/doc/src/declarative/extending-tutorial.qdoc @@ -285,8 +285,8 @@ int-type property to store an identifier for each chart: } \endcode -We can also use various other property types. QML has built-in support for the following -types listed in the \l{Extending Types from QML} document, including the following: +We can also use various other property types. QML has built-in support for the types +listed in the \l{Adding Properties} documentation, which includes the following: \list \o bool, unsigned int, int, float, double, qreal diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index 740f7d1..fc5c586 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -82,8 +82,8 @@ Types can be registered by libraries, application code, or by plugins Once registered, all \l {Qt's Property System}{properties} of the supported types are available in QML. QML has intrinsic support for -properties of the types listed in the \l{Extending Types from QML} -document, including the following: +properties of the types listed in the \l{Adding Properties} +document, which includes the following: \list \o bool, unsigned int, int, float, double, qreal @@ -429,7 +429,7 @@ onChanged, regardless of the name used for the NOTIFY signal in C++. We recommend using Changed() for the NOTIFY signal in C++. -See also \l {Extending Types from QML}. +See also \l {Writing QML Components: Properties, Methods and Signals} \section1 Methods @@ -637,147 +637,177 @@ public: /*! \page qml-extending-types.html -\title Extending Types from QML +\title Writing QML Components: Properties, Methods and Signals -Many of the elements available for use in QML are implemented in -\l {Extending QML in C++}{C++}. These types are know as "core types". QML -allows programmers to build new, fully functional elements without using C++. -Existing core types can be extended, and new types defined entirely in the QML -language. +One of the key concepts in QML is the ability to define your own QML components that suit +the purposes of your application. The standard \l {QML Elements} provide the essential components +for creating a QML application; beyond these, you can write your own custom components that can +be created and reused, without the use of C++. -\tableofcontents +Components are the building blocks of a QML project. When writing a QML application, whether +large or small, it is best to separate QML code into smaller components that perform specific +sets of operations, instead of creating mammoth QML files with large, combined functionality +that is more difficult to manage and may contain duplicated code. + + +\section1 Defining New Components -\section1 Adding new properties +A component is a reusable type with a well-defined interface, built entirely in QML. +Any snippet of QML code can become a component, by placing the code in a file ".qml" where + is the new component name, beginning with an uppercase letter. These QML files automatically +become available as new QML element types to other QML components and applications in the same directory. -New properties can be added to an existing type using the \c property keyword. -These new properties are -available for use within QML, and also appear as regular Qt properties on the -C++ object, accessible through the regular property access mechanisms. +For example, one of the simplest and most common components you can build in QML is a +button-type component. Below, we implement this component as a \l Rectangle with a clickable +\l MouseArea, in a file named \c Button.qml: -Like all properties in QML, custom properties are typed. The type is used to -define the property's behavior, and also determines the C++ type of the created -Qt property. The following table shows the list of types available when -declaring a new property, and the corresponding C++ type. +\snippet doc/src/snippets/declarative/qml-extending-types/components/Button.qml 0 + +Now this component can be reused by another file within the same directory. Since the file is +named \c Button.qml, the component is referred to as \c Button: \table -\header \o QML Type Name \o C++ Type Name -\row \o int \o int -\row \o bool \o bool -\row \o double \o double -\row \o real \o double -\row \o string \o QString -\row \o url \o QUrl -\row \o color \o QColor -\row \o date \o QDateTime -\row \o variant \o QVariant +\row +\o \snippet doc/src/snippets/declarative/qml-extending-types/components/application.qml 0 +\o \image qml-extending-types.png \endtable -From QML you can also declare object and list properties using any element name -like this: +The root object in \c Button.qml defines the attributes that are available to users of the +\c Button component. In this case, the root object is a \l Rectangle, so any properties, methods +and signals of \l Rectangle are made available, allowing \c application.qml to +customize the \c width, \c height, \c radius and \c color properties of \c Button objects. -\code - property QtObject objectProperty - property Item itemProperty - property MyCustomType customProperty - property list listOfItemsProperty -\endcode -Custom types must be registered with qmlRegisterType() to be usable as a property -type. Also note that list properties cannot be modified like ordinary JavaScript -arrays; see the \l {list}{list type documentation} for details. +If \c Button.qml was not in the same directory, \c application.qml would need to load it as a +\l {Modules}{module} from a specific filesystem path or \l{QDeclarativeExtensionPlugin}{plugin}. +Also, note the letter case of the component file name is significant on some (notably UNIX) +filesystems. It is recommended the file name case matches the case of the QML component name +exactly - for example, \c Box.qml and not \c BoX.qml - regardless of the platform to which the +QML component will be deployed. + +To write a useful component, it is generally necessary to provide it with custom attributes that store and +communicate specific data. This is achieved by adding the following attributes to your components: + +\list +\o \bold Properties that can be accessed externally to modify an object (for example, \l Item has + \l {Item::}{width} and \l {Item::}{height} properties) and used in \l {Property Binding} +\o \bold Methods of JavaScript code can be invoked internally or externally (for example, + \l Animation has a \l {Animation::}{start()} method) +\o \bold Signals to notify other objects when an event has occurred (for example, MouseArea has a + \c clicked signal) +\endlist + +The following sections show how these attributes can be added to QML components. -QML supports two methods for adding a new property to a type: a new property -definition, and a property alias. These are shown below. -\section2 Property definitions +\section1 Adding Properties -Property definitions add a new property to an existing type. The storage of the -property is managed by QML. The defined property may be read, written and bound -to and from. +A property is a value of a QML component that can be read and modified by other objects. For +example, a \l Rectangle component has \l {Item::}{width}, \l {Item::}{height} and \l +{Rectangle::}{color} properties. Significantly, properties be used with \l {Property Binding}, where +a property value is automatically updated using the value of another property. The syntax for defining a new property is: + \code - [default] property [: defaultValue] +[default] property [: defaultValue] \endcode -This declaration may appear anywhere within a type body, but it is customary to -include it at the top. Attempting to declare two properties with the same name -in the same type block is an error. However, a new property may reuse the name -of an existing property on the type. This should be done with caution, as the -existing property will be hidden, and become inaccessible. +A \c property declaration can appear anywhere within a QML component definition, but it is customary +to place it at the top. A component cannot declare more than one property with the same name. (It is +possible to have a property name that is the same as an existing property in a type, but this is not +recommended as the existing property becomes hidden and inaccessible.) -The must be one of the QML type names shown in the above table. -Additionally, an optional default value of the property can be provided. The -default value is a convenient shortcut, but is behaviorally identical to doing -it in two steps, like this: +Below is an example. The \c ImageViewer component has defined a \c string type property named +\c currentImage, and its initial value is "default-image.png". This property is used to set the image +displayed in the child \l Image object. Another file, \c application.qml, can create +an \c ImageViewer object and read or modify the \c currentImage value: -\code - // Use default value - property int myProperty: 10 +\table +\row +\o \snippet doc/src/snippets/declarative/qml-extending-types/properties/ImageViewer.qml 0 +\o \snippet doc/src/snippets/declarative/qml-extending-types/properties/application.qml 0 +\endtable - // Longer, but behaviorally identical - property int myProperty - myProperty: 10 -\endcode +It is optional for a property to have a default value. The default value is a convenient shortcut, and is +behaviorally identical to doing it in two steps, like this: + +\qml +// Use default value +property int myProperty: 10 + +// Longer, but behaviorally identical +property int myProperty +myProperty: 10 +\endqml -If a default value is not supplied or set later in the file, each type has a -default value for when none is explicitly set. Below are the default values -of some of the types. For the remaining types the default values are undefined. + +\section2 Supported property types + +All QML properties are typed. The examples above show properties with \c int and \c string types; +notice that the type of the property must be declared. The type is used to determine the property +behavior, and how the property is defined in C++. + +A number of property types are supported by default. These are listed in the table below, +with their default values and the corresponding C++ type: \table -\header \o QML Type \o Default Value -\row \o bool \o false -\row \o int \o 0 -\row \o double, real \o 0.0 -\row \o string, url \o "" (an empty string) -\row \o color \o #000000 (black) +\header \o QML Type Name \o Default value \o C++ Type Name +\row \o int \o 0 \o int +\row \o bool \o \c false \o bool +\row \o double \o 0.0 \o double +\row \o real \o 0.0 \o double +\row \o string \o "" (empty string) \o QString +\row \o url \o "" (empty url) \o QUrl +\row \o color \o #000000 (black) \o QColor +\row \o date \o \c undefined \o QDateTime +\row \o variant \o \c undefined \o QVariant \endtable -The following example shows how to declare a new "innerColor" property that -controls the color of the inner rectangle. +QML object types can also be used as property types. This includes +\l {Defining new QML elements}{custom QML types} implemented in C++. Such properties are +defined like this: -\code - Rectangle { - property color innerColor: "black" - - color: "red"; width: 100; height: 100 - Rectangle { - anchors.centerIn: parent - width: parent.width - 10 - height: parent.height - 10 - color: innerColor - } - } -\endcode +\qml +property Item itemProperty +property QtObject objectProperty +property MyCustomType customProperty +\endqml +Such object-type properties default to an \c undefined value. -\section3 Property signal handlers +\l{list}{List properties} are created with the \c list syntax, and default to an empty +list: -Adding a property to an item automatically adds a \e{value-changed} -signal handler to the item. The signal hander is named -\c{onChanged}, with the first letter of the property -name being upper case. +\qml +property list listOfItems +\endqml -Signal handlers can have arbitrary JavaScript code assigned. The following -example shows how to output to a text console a new value of property -\c{innerColor} whenever the value of this property changes. +Note that list properties cannot be modified like ordinary JavaScript +arrays. See the \l {list}{list type documentation} for details. -\code - Rectangle { - id: rect - property color innerColor: "black" +For details about accessing and manipulating QML properties from C++, see \l {Using QML with C++}. - onInnerColorChanged: { console.log(rect.innerColor); } - } -\endcode +\section2 Property change signals + +Adding a \c property to an item automatically adds a \e {value changed} +signal handler to the item. To connect to this signal, use a \l {Signal Handlers}{signal handler} +named with the \c onChanged syntax, using upper case for the first letter of the +property name. + +For example, the following \c onMyNumberChanged signal handler is automatically called whenever the +\c myNumber property changes: + +\snippet doc/src/snippets/declarative/qml-extending-types/properties/property-signals.qml 0 -\section3 Setting default properties + +\section2 Default properties The optional \c default attribute for a property marks it as the \e {default property} for a type. This allows other items to specify the default property's value -as child elements. For example, the \l Item element's default property is its -\l{Item::children}{children} property. This allows the children of an \l Item +as child elements. For example, the \l Item element's default property is its +\l{Item::children}{children} property. This allows the children of an \l Item to be set like this: \qml @@ -787,7 +817,7 @@ Item { } \endqml -If the \l{Item::children}{children} property was not the default property for +If the \l{Item::children}{children} property was not the default property for \l Item, its value would have to be set like this instead: \qml @@ -804,21 +834,20 @@ demonstration of using default properties. Specifying a default property overrides any existing default property (for example, any default property inherited from a parent item). Using the -default attribute twice in the same type block is an error. +\c default attribute twice in the same type block is an error. -\target qml-property-aliases \section2 Property aliases Property aliases are a more advanced form of property declaration. Unlike a -property definition, that allocates a new, unique storage space for the +property definition, which allocates a new, unique storage space for the property, a property alias connects the newly declared property (called the -aliasing property) to an existing property (the aliased property). Read +aliasing property) as a direct reference to an existing property (the aliased property). Read operations on the aliasing property act as read operations on the aliased property, and write operations on the aliasing property as write operations on the aliased property. -A property alias declaration looks a lot like a property definition: +A property alias declaration looks a lot like an ordinary property definition: \code [default] property alias : \endcode @@ -829,7 +858,7 @@ value, a property alias includes a compulsory alias reference. The alias reference is used to locate the aliased property. While similar to a property binding, the alias reference syntax is highly restricted. -An alias reference takes one of the following forms +An alias reference takes one of the following forms: \code . @@ -838,61 +867,58 @@ An alias reference takes one of the following forms where must refer to an object id within the same component as the type declaring the alias, and, optionally, refers to a property on that object. -Here is the property definition example rewritten to use property aliases. -\code -Rectangle { - property alias innerColor: innerRect.color - - color: "red"; width: 100; height: 100 - Rectangle { - id: innerRect - anchors.centerIn: parent - width: parent.width - 10 - height: parent.height - 10 - color: "black" - } -} -\endcode +For example, below is a \c Button.qml component with a \c buttonText aliased property which is +connected to the child Text object's \c text property: + +\snippet doc/src/snippets/declarative/qml-extending-types/properties/alias.qml 0 + +The following code would create a \c Button with a defined text string for the +child \l Text object: -Aliases are most useful when \l {Defining new Components}. Consequently -they have several apparent limitations that only make sense in this context. +\qml +Button { buttonText: "This is a button" } +\endqml + +Here, modifying \c buttonText directly modifies the \c textItem.text value; it does not +change some other value that then updates \c textItem.text. + +In this case, the use of aliased properties is essential. If \c buttonText was not an alias, +changing its value would not actually change the displayed text at all, as +\l {Property Binding}{property bindings} are not bi-directional: the \c buttonText value would +change when \c textItem.text changes, but not the other way around. + +Aliased properties are also useful for allowing external objects to directly modify and +access child objects in a component. For example, here is a modified version of the \c ImageViewer +component shown \l {Adding Properties}{earlier} on this page. The \c currentImage property has +been changed to an alias to the child \l Image object: + +\table +\row +\o \snippet doc/src/snippets/declarative/qml-extending-types/properties/alias/ImageViewer.qml 0 +\o \snippet doc/src/snippets/declarative/qml-extending-types/properties/alias/application.qml 0 +\endtable + +Instead of being limited to setting the \l Image source, \c application.qml can now directly +access and modify the child \l Image object and its properties. + +Obviously, exposing child objects in this manner should be done with care, as it allows external +objects to modify them freely. However, this use of aliased properties can be quite useful in +particular situations, such as for the \l {declarative/ui-components/tabwidget}{TabWidget} +example, where new tab items are actually parented to a child object that displays the current tab. + + +\section3 Considerations for property aliases Aliases are only activated once the component specifying them is completed. The most obvious consequence of this is that the component itself cannot generally -use the aliased property directly. For example, this will not work: +use the aliased property directly during creation. For example, this will not work: \code // Does NOT work - property alias innerColor: innerRect.color - innerColor: "black" + property alias buttonText: textItem.text + buttonText: "Some text" // buttonText is not yet defined when this value is set \endcode -This behavior is required to allow type developers to redefine the behavior -of existing property names while continuing to use the existing behavior within -the type they are building, something that is not possible with property -definitions. In the example used so far, this could allows the developer to fix -the external rectangle's color as "red" and redefine the "color" property to -refer to the inner rectangle, like this: - -\code -Rectangle { - property alias color: innerRect.color - - color: "red"; width: 100; height: 100 - Rectangle { - id: innerRect - anchors.centerIn: parent - width: parent.width - 10 - height: parent.height - 10 - color: "black" - } -} -\endcode - -Users of this type would not be able to affect the color of the red rectangle, -but would find using the "color" property, rather than the strange new -"innerColor" property, much more familiar. - A second, much less significant, consequence of the delayed activation of aliases is that an alias reference cannot refer to another aliasing property declared within the same component. This will not work: @@ -900,198 +926,177 @@ declared within the same component. This will not work: \code // Does NOT work id: root - property alias innerColor: innerRect.color - property alias innerColor2: root.innerColor + property alias buttonText: textItem.text + property alias buttonText2: root.buttonText \endcode -From outside the component, aliasing properties appear as regular Qt properties -and consequently can be used in alias references. +At the time the component is created, the \c buttonText value has not yet been assigned, +so \c root.buttonText would refer to an undefined value. (From outside the component, +however, aliasing properties appear as regular Qt properties and consequently can be +used in alias references.) -\section1 Adding new signals +It is possible for an aliased property to have the same name as an existing property. For example, +the following component has a \c color alias property, named the same as the built-in +\l {Rectangle::color} property: -New signals can be added to an existing type. These new signals are available -for use within QML, and also appear as regular Qt signals on the C++ object that -can be used in Qt signal/slot connections. +\snippet doc/src/snippets/declarative/qml-extending-types/properties/alias-override.qml 0 + +Any objects that use this component and refer to its \c color property will be +referring to the alias rather than the ordinary \l {Rectangle::color} property. Internally, +however, the rectangle can correctly set this property to "red" and refer to the actual defined +property rather than the alias. + + +\section1 Adding Methods + +A QML component can define methods of JavaScript code. These methods can be invoked +either internally or by other objects. + +The syntax for defining a method is: -The syntax for defining a new signal is: \code -signal [([ [, ...]])] +function ([[, ...]]) { } \endcode This declaration may appear anywhere within a type body, but it is customary to -include it at the top. Attempting to declare two signals or methods with the -same name in the same type block is an error. However, a new signal may reuse -the name of an existing signal on the type. This should be done with caution, -as the existing signal may be hidden and become inaccessible. +include it at the top. Attempting to declare two methods or signals with the +same name in the same type block is an error. However, a new method may reuse +the name of an existing method on the type. (This should be done with caution, +as the existing method may be hidden and become inaccessible.) -The options for parameter types are the same as for property types (see -\l {Adding new properties}. If this signal has no parameters, the parameter -list may be omitted entirely. +Unlike \l{Adding Signals}{signals}, method parameter types do not have to be declared as they +default to the \c variant type. The body of the method is written in JavaScript and may access +the parameters by name. -Here are three examples of signal declarations: -\code - Item { - signal clicked - signal hovered() - signal performAction(string action, variant actionArgument) - } -\endcode +Here is an example of a component with a \c say() method that accepts a single \c text argument: -Adding a signal to an item automatically adds a signal handler to it. -The signal hander is named on, with the first letter of the -signal name being upper cased. The above example item would now have the -following signal handlers: +\snippet doc/src/snippets/declarative/qml-extending-types/methods/app.qml 0 -\list - \o onClicked - \o onHovered - \o onPerformAction -\endlist +A method can be connected to a signal so that it is automatically invoked whenever the signal +is emitted. See \l {Connecting signals to methods and other signals} below. + +Also see \l {Integrating JavaScript} for more information on using JavaScript with QML. -\section1 Adding new methods -New methods can be added to an existing type. These new methods are available -for use within QML, and also appear as regular Qt slots on the C++ object that -can be used in Qt signal/slot connections. +\section1 Adding Signals + +Signals provide a way to notify other objects when an event has occurred. For example, the MouseArea +\c clicked signal notifies other objects that the mouse has been clicked within the area. + +The syntax for defining a new signal is: \code -function ([[, ...]]) { } +signal [([ [, ...]])] \endcode This declaration may appear anywhere within a type body, but it is customary to -include it at the top. Attempting to declare two methods or signals with the -same name in the same type block is an error. However, a new method may reuse -the name of an existing method on the type. This should be done with caution, -as the existing method may be hidden and become inaccessible. +include it at the top. Attempting to declare two signals or methods with the +same name in the same type block is an error. However, a new signal may reuse +the name of an existing signal on the type. (This should be done with caution, +as the existing signal may be hidden and become inaccessible.) -Methods parameters are not typed. In C++ these parameters are of type QVariant. -The body of the method is written in JavaScript and may access the parameters by -name. +Here are three examples of signal declarations: -This example adds a new method that behaves like a child: \code Item { - function say(text) { - console.log("You said " + text); - } + signal clicked + signal hovered() + signal performAction(string action, variant actionArgument) } \endcode -This may be connected to via QObject::connect() or called directly from C++ using -QMetaObject::invokeMethod(): +If the signal has no parameters, the "()" brackets are optional. If parameters are used, the +parameter types must be declared, as for the \c string and \c variant arguments for the \c +performAction signal above; the allowed parameter types are the same as those listed in the \l +{Adding Properties} section on this page. -\code - QDeclarativeEngine engine; - QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext()); - QDeclarativeComponent component(&engine, QUrl::fromLocalFile("main.qml")); - QObject *object = component.create(context); - QVariant str("Hello"); - QMetaObject::invokeMethod(object, "say", Q_ARG(QVariant, str)); -\endcode - -Return values of type QVariant are also supported via Q_RETURN_ARG. - -\section1 Defining new Components -\target components +Adding a signal to an item automatically adds a \l {Signal Handlers}{signal handler} as well. +The signal hander is named \c on, with the first letter of the signal being upper +cased. The above example item would now have the following signal handlers: -A component is a reusable type with a well-defined interface built entirely in -QML. Components appear as regular QML elements, and can be used interchangeably -with core types. Components allow developers to create new types to be reused -in other projects without the use of C++. Components can also help to reduce -duplication inside one project by limiting the need for large numbers of -copy-and-pasted blocks. +\list +\o onClicked +\o onHovered +\o onPerformAction +\endlist -Any snippet of QML code can become a component, just by placing it in the file ".qml" -where is the new element name, and begins with an uppercase letter. Note that -the case of all characters in the are significant on some filesystems, notably -UNIX filesystems. It is recommended that the case of the filename matches the case of -the component name in QML exactly, regardless of the platform the QML will be deployed to. +To emit a signal, simply invoke it in the same way as a method. Below left, when the \l MouseArea is +clicked, it emits the parent \c buttonClicked signal by invoking \c rect.buttonClicked(). The +signal is received by \c application.qml through an \c onButtonClicked signal handler: -These QML files automatically become available as new QML element types -to other QML components and applications in the same directory. +\table +\row +\o \snippet doc/src/snippets/declarative/qml-extending-types/signals/basic.qml 0 +\o \snippet doc/src/snippets/declarative/qml-extending-types/signals/no-parameters.qml 0 +\endtable -For example, here we show how a component named "Box" is defined and used -multiple times by an application. +If the signal has parameters, they are accessible by parameter name in the signal handler. +In the example below, \c buttonClicked is emitted with \c xPos and \c yPos parameters instead: \table \row -\o application.qml -\code -Rectangle { - width: 100; height: 400; - Box { x: 0; y: 0 } - Box { x: 0; y: 150 } - Box { x: 0; y: 300 } -} -\endcode -\o Box.qml -\code -Rectangle { - width: 100; height: 100; - color: "blue" -} -\endcode +\o \snippet doc/src/snippets/declarative/qml-extending-types/signals/Button.qml 0 +\o \snippet doc/src/snippets/declarative/qml-extending-types/signals/parameters.qml 0 \endtable -Components may be collected into \l {Modules} that gives the -developer more freedom than just putting files in the same directory. -\section2 Building reusable components +\section2 Connecting signals to methods and other signals -A component type built to be reused by others must have a well defined -interface. In QML, an interface consists of a defined collection of -properties, signals and methods. Users of a component have access to all the -properties, signals and methods defined on the root element of the component. +Signal objects have a \c connect() method that can be used to a connect a signal to a method or +another signal. When a signal is connected to a method, the method is automatically invoked +whenever the signal is emitted. (In Qt terminology, the method is a \e slot that is connected +to the \e signal; all methods defined in QML are created as Qt slots.) This enables a signal +to be received by a method instead of a \l {Signal Handlers}{signal handler}. -In the component example above, the root element of the "Box" component is a -Rect. As the Rect type has a "color" property, this property is accessible to -users of the Box component. For example, the application.qml can be modified -to show three different colored boxes like this: -\code -Rectangle { - width: 100; height: 400; - Box { x: 0; y: 0; color: "red"; } - Box { x: 0; y: 150; color: "yellow"; } - Box { x: 0; y: 300; color: "green"; } -} -\endcode +For example, the \c application.qml above could be rewritten as: -As expected, adding additional properties to the root element of Box, makes them -available externally. Here we add a "text" property: +\snippet doc/src/snippets/declarative/qml-extending-types/signals/connectslots.qml 0 -\table -\row -\o application.qml -\code -Rectangle { - width: 100; height: 400; - Box { x: 0; y: 0; color: "red"; text: "stop" } - Box { x: 0; y: 150; color: "yellow"; text: "slow" } - Box { x: 0; y: 300; color: "green"; text: "go" } -} -\endcode -\o Box.qml -\code -Rectangle { - property alias text: myText.text - width: 100; height: 100; - color: "blue" - Text { - id: myText - anchors.centerIn: parent +The \c myMethod() method will be called whenever the \c buttonClicked signal is received. + +In many cases it is sufficient to receive signals through signal handlers rather than using +the \c connect() function; the above example does not provide any improvements over using a +simple \c onButtonClicked handler. However, if you are \l{Dynamic Object Management in QML}{creating objects dynamically}, +or \l {Integrating JavaScript}{integrating JavaScript code}, then you will find the +\c connect() method useful. For example, the component below creates three \c Button +objects dynamically, and connects the \c buttonClicked signal of each object to the +\c myMethod() function: + +\snippet doc/src/snippets/declarative/qml-extending-types/signals/connectdynamic.qml 0 + +In the same way, you could connect a signal to methods defined in a dynamically +created object, or \l {Receiving QML Signals in JavaScript}{connect a signal to a JavaScript method}. + +There is also a corresponding \c disconnect() method for removing connected signals. The following +code removes the connection created in \c application.qml above: + +\qml +// application.qml +Item { + ... + + function removeSignal() { + button.clicked.disconnect(item.myMethod) } } -\endcode -\endtable +\endqml + + +\section3 Forwarding signals + +The \c connect() method can also connect a signal to other signals. This has the effect +of "forwarding" a signal: it is automatically emitted whenever the relevant signal is emitted. For +example, the MouseArea \c onClicked handler in \c Button.qml above could have been replaced with +a call to \c connect(): + +\qml +MouseArea { + anchors.fill: parent + Component.onCompleted: clicked.connect(item.buttonClicked) +} +\endqml -Methods and signals may be added in the same way. +Whenever the \l MouseArea \c clicked signal is emitted, the \c rect.buttonClicked signal will +automatically be emitted as well. -As all external methods, signals and properties are accessible to external -users, developers should ensure that setting these properties does not have -any undesirable side-effects. For most resilience, root level properties should -only be used for literal default values. When a root level property must be -used inside the component - such as the children property - property aliases -can be used to redirect this property to a "safe" location for external users. -Try to think of the root level properties as being "owned" by the components -user, rather than the component itself. */ diff --git a/doc/src/declarative/javascriptblocks.qdoc b/doc/src/declarative/javascriptblocks.qdoc index b6fad5b..16d0633 100644 --- a/doc/src/declarative/javascriptblocks.qdoc +++ b/doc/src/declarative/javascriptblocks.qdoc @@ -207,6 +207,25 @@ changes. See \l {Property Binding} for more information. +\section1 Receiving QML Signals in JavaScript + +To receive a QML signal, use the signal's \c connect() method to connect it to a JavaScript +function. + +For example, the following code connects the MouseArea \c clicked signal to the \c jsFunction() +in \c script.js: + +\table +\row +\o \snippet doc/src/snippets/declarative/integrating-javascript/connectjs.qml 0 +\o \snippet doc/src/snippets/declarative/integrating-javascript/script.js 0 +\endtable + +The \c jsFunction() will now be called whenever MouseArea's \c clicked signal is emitted. + +See \l {Connecting signals to methods and other signals} for more information. + + \section1 QML JavaScript Restrictions QML executes standard JavaScript code, with the following restrictions: diff --git a/doc/src/declarative/pics/qml-extending-types.png b/doc/src/declarative/pics/qml-extending-types.png new file mode 100644 index 0000000..6990d7c Binary files /dev/null and b/doc/src/declarative/pics/qml-extending-types.png differ diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc index c3ce6d0..71f41bc 100644 --- a/doc/src/declarative/qtbinding.qdoc +++ b/doc/src/declarative/qtbinding.qdoc @@ -230,7 +230,7 @@ Also see the QDeclarativeContext documentation for more information. \section2 Defining new QML elements -While new QML elements can be \l {Defining new Components}{defined in QML}, they can also be +While new QML elements can be \l {Defining New Components}{defined in QML}, they can also be defined by C++ classes; in fact, many of the core \l {QML Elements} are implemented through C++ classes. When you create a QML object using one of these elements, you are simply creating an instance of a QObject-based C++ class and setting its properties. diff --git a/doc/src/declarative/tutorial.qdoc b/doc/src/declarative/tutorial.qdoc index 8467478..d8139b4 100644 --- a/doc/src/declarative/tutorial.qdoc +++ b/doc/src/declarative/tutorial.qdoc @@ -124,7 +124,7 @@ Our color picker is made of six cells with different colors. To avoid writing the same code multiple times for each cell, we create a new \c Cell component. A component provides a way of defining a new type that we can re-use in other QML files. A QML component is like a black-box and interacts with the outside world through properties, signals and functions and is generally -defined in its own QML file. (For more details, see \l {Defining new Components}). +defined in its own QML file. (For more details, see \l {Defining New Components}). The component's filename must always start with a capital letter. Here is the QML code for \c Cell.qml: @@ -144,7 +144,7 @@ An \l Item is the most basic visual element in QML and is often used as a contai We declare a \c cellColor property. This property is accessible from \e outside our component, this allows us to instantiate the cells with different colors. -This property is just an alias to an existing property - the color of the rectangle that compose the cell (see \l{Adding new properties}). +This property is just an alias to an existing property - the color of the rectangle that compose the cell (see \l{Adding Properties}). \snippet examples/declarative/tutorials/helloworld/Cell.qml 5 diff --git a/doc/src/examples/qml-examples.qdoc b/doc/src/examples/qml-examples.qdoc index ca24c66..0834527 100644 --- a/doc/src/examples/qml-examples.qdoc +++ b/doc/src/examples/qml-examples.qdoc @@ -663,7 +663,8 @@ \example declarative/ui-components/tabwidget This example shows how to create a tab widget. It also demonstrates how - \l {Setting default properties}{default properties} can be used to collect and + \l {Property aliases}{property aliases} and + \l {Default Properties}{default properties} can be used to collect and assemble the child items declared within an \l Item. \image qml-tabwidget-example.png diff --git a/doc/src/snippets/declarative/integrating-javascript/connectjs.qml b/doc/src/snippets/declarative/integrating-javascript/connectjs.qml new file mode 100644 index 0000000..d84b827 --- /dev/null +++ b/doc/src/snippets/declarative/integrating-javascript/connectjs.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick 1.0 +import "script.js" as MyScript + +Item { + id: item + width: 200; height: 200 + + MouseArea { + id: mouseArea + anchors.fill: parent + } + + Component.onCompleted: { + mouseArea.clicked.connect(MyScript.jsFunction) + } +} +//![0] diff --git a/doc/src/snippets/declarative/integrating-javascript/script.js b/doc/src/snippets/declarative/integrating-javascript/script.js new file mode 100644 index 0000000..f7099f8 --- /dev/null +++ b/doc/src/snippets/declarative/integrating-javascript/script.js @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +// script.js + +function jsFunction() { + console.log("Called JavaScript function!") +} +//![0] + diff --git a/doc/src/snippets/declarative/qml-extending-types/components/Button.qml b/doc/src/snippets/declarative/qml-extending-types/components/Button.qml new file mode 100644 index 0000000..43fe0e2 --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/components/Button.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +// Button.qml +import QtQuick 1.0 + +Rectangle { + width: 100; height: 100 + color: "red" + + MouseArea { + anchors.fill: parent + onClicked: console.log("Button clicked!") + } +} +//![0] diff --git a/doc/src/snippets/declarative/qml-extending-types/components/application.qml b/doc/src/snippets/declarative/qml-extending-types/components/application.qml new file mode 100644 index 0000000..0c3b0df --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/components/application.qml @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +// application.qml +import QtQuick 1.0 + +Column { + Button { width: 50; height: 50 } + Button { x: 50; width: 100; height: 50; color: "blue" } + Button { width: 50; height: 50; radius: 8 } +} +//![0] diff --git a/doc/src/snippets/declarative/qml-extending-types/methods/app.qml b/doc/src/snippets/declarative/qml-extending-types/methods/app.qml new file mode 100644 index 0000000..3b5f008 --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/methods/app.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 1.0 +//![0] +Rectangle { + id: rect + width: 100; height: 100 + + function say(text) { + console.log("You said: " + text); + } + + MouseArea { + anchors.fill: parent + onClicked: rect.say("Mouse clicked") + } +} +//![0] diff --git a/doc/src/snippets/declarative/qml-extending-types/properties/ImageViewer.qml b/doc/src/snippets/declarative/qml-extending-types/properties/ImageViewer.qml new file mode 100644 index 0000000..e37db9c --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/properties/ImageViewer.qml @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +// ImageViewer.qml +import QtQuick 1.0 + +Item { + id: item + width: 200; height: 200 + + property string currentImage: "default-image.png" + + Image { source: item.currentImage } +} +//![0] diff --git a/doc/src/snippets/declarative/qml-extending-types/properties/alias-override.qml b/doc/src/snippets/declarative/qml-extending-types/properties/alias-override.qml new file mode 100644 index 0000000..aab2748 --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/properties/alias-override.qml @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 1.0 +//![0] +Rectangle { + property alias color: childRect.color + color: "red" + + Rectangle { id: childRect } +} +//![0] diff --git a/doc/src/snippets/declarative/qml-extending-types/properties/alias.qml b/doc/src/snippets/declarative/qml-extending-types/properties/alias.qml new file mode 100644 index 0000000..1bda447 --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/properties/alias.qml @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +// Button.qml +import QtQuick 1.0 + +Item { + property alias buttonText: textItem.text + + width: 200; height: 50 + + Text { id: textItem } +} +//![0] diff --git a/doc/src/snippets/declarative/qml-extending-types/properties/alias/ImageViewer.qml b/doc/src/snippets/declarative/qml-extending-types/properties/alias/ImageViewer.qml new file mode 100644 index 0000000..7f50674 --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/properties/alias/ImageViewer.qml @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +// ImageViewer.qml +import QtQuick 1.0 + +Item { + id: item + width: 200; height: 200 + + property alias currentImage: image + + Image { id: image } +} +//![0] diff --git a/doc/src/snippets/declarative/qml-extending-types/properties/alias/application.qml b/doc/src/snippets/declarative/qml-extending-types/properties/alias/application.qml new file mode 100644 index 0000000..3592e60 --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/properties/alias/application.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +// application.qml +import QtQuick 1.0 + +ImageViewer { + id: viewer + + currentImage.source: "http://qt.nokia.com/logo.png" + currentImage.width: width + currentImage.height: height + currentImage.fillMode: Image.Tile + + Text { text: currentImage.source } +} +//![0] diff --git a/doc/src/snippets/declarative/qml-extending-types/properties/application.qml b/doc/src/snippets/declarative/qml-extending-types/properties/application.qml new file mode 100644 index 0000000..4978f05 --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/properties/application.qml @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick 1.0 + +ImageViewer { + id: viewer + + currentImage: "http://qt.nokia.com/logo.png" + + Text { text: viewer.currentImage } +} +//![0] diff --git a/doc/src/snippets/declarative/qml-extending-types/properties/property-signals.qml b/doc/src/snippets/declarative/qml-extending-types/properties/property-signals.qml new file mode 100644 index 0000000..1d1b325 --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/properties/property-signals.qml @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 1.0 +//![0] +Item { + property int myNumber + + onMyNumberChanged: { console.log("myNumber has changed:", myNumber); } + + Component.onCompleted: myNumber = 100 +} +//![0] diff --git a/doc/src/snippets/declarative/qml-extending-types/signals/Button.qml b/doc/src/snippets/declarative/qml-extending-types/signals/Button.qml new file mode 100644 index 0000000..9272572 --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/signals/Button.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 1.0 + +//![0] +// Button.qml +Rectangle { + id: rect + width: 100; height: 100 + + signal buttonClicked(int xPos, int yPos) + + MouseArea { + anchors.fill: parent + onClicked: rect.buttonClicked(mouse.x, mouse.y) + } +} +//![0] diff --git a/doc/src/snippets/declarative/qml-extending-types/signals/basic.qml b/doc/src/snippets/declarative/qml-extending-types/signals/basic.qml new file mode 100644 index 0000000..272c972 --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/signals/basic.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +// Button.qml +import QtQuick 1.0 + +Rectangle { + id: rect + width: 100; height: 100 + + signal buttonClicked + + MouseArea { + anchors.fill: parent + onClicked: rect.buttonClicked() + } +} +//![0] diff --git a/doc/src/snippets/declarative/qml-extending-types/signals/connectdynamic.qml b/doc/src/snippets/declarative/qml-extending-types/signals/connectdynamic.qml new file mode 100644 index 0000000..4b1f217 --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/signals/connectdynamic.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 1.0 +//![0] +Item { + id: item + width: 300; height: 100 + + function myMethod() { + console.log("Button was clicked!") + } + + Row { id: row } + + Component.onCompleted: { + var component = Qt.createComponent("Button.qml") + for (var i=0; i<3; i++) { + var button = component.createObject(row) + button.border.width = 1 + button.buttonClicked.connect(myMethod) + } + } +} +//![0] diff --git a/doc/src/snippets/declarative/qml-extending-types/signals/connectslots.qml b/doc/src/snippets/declarative/qml-extending-types/signals/connectslots.qml new file mode 100644 index 0000000..ae14281 --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/signals/connectslots.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 1.0 +//![0] +Item { + id: item + width: 200; height: 200 + + function myMethod() { + console.log("Button was clicked!") + } + + Button { + id: button + anchors.fill: parent + Component.onCompleted: buttonClicked.connect(item.myMethod) + } +} +//![0] diff --git a/doc/src/snippets/declarative/qml-extending-types/signals/no-parameters.qml b/doc/src/snippets/declarative/qml-extending-types/signals/no-parameters.qml new file mode 100644 index 0000000..742ab18 --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/signals/no-parameters.qml @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +// application.qml +import QtQuick 1.0 + +Button { + width: 100; height: 100 + onButtonClicked: console.log("Mouse was clicked") +} +//![0] + diff --git a/doc/src/snippets/declarative/qml-extending-types/signals/parameters.qml b/doc/src/snippets/declarative/qml-extending-types/signals/parameters.qml new file mode 100644 index 0000000..f513f5f --- /dev/null +++ b/doc/src/snippets/declarative/qml-extending-types/signals/parameters.qml @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 1.0 +//![0] +// application.qml +Button { + width: 100; height: 100 + onButtonClicked: { + console.log("Mouse clicked at " + xPos + "," + yPos) + } +} +//![0] + diff --git a/examples/declarative/modelviews/visualitemmodel/visualitemmodel.qml b/examples/declarative/modelviews/visualitemmodel/visualitemmodel.qml index 15f2f11..f6564f7 100644 --- a/examples/declarative/modelviews/visualitemmodel/visualitemmodel.qml +++ b/examples/declarative/modelviews/visualitemmodel/visualitemmodel.qml @@ -55,16 +55,22 @@ Rectangle { width: view.width; height: view.height color: "#FFFEF0" Text { text: "Page 1"; font.bold: true; anchors.centerIn: parent } + + Component.onDestruction: print("destroyed 1") } Rectangle { width: view.width; height: view.height color: "#F0FFF7" Text { text: "Page 2"; font.bold: true; anchors.centerIn: parent } + + Component.onDestruction: print("destroyed 2") } Rectangle { width: view.width; height: view.height color: "#F4F0FF" Text { text: "Page 3"; font.bold: true; anchors.centerIn: parent } + + Component.onDestruction: print("destroyed 3") } } @@ -76,6 +82,7 @@ Rectangle { highlightRangeMode: ListView.StrictlyEnforceRange orientation: ListView.Horizontal snapMode: ListView.SnapOneItem; flickDeceleration: 2000 + cacheBuffer: 200 } Rectangle { diff --git a/examples/declarative/ui-components/tabwidget/TabWidget.qml b/examples/declarative/ui-components/tabwidget/TabWidget.qml index f066fd2..2a74c46 100644 --- a/examples/declarative/ui-components/tabwidget/TabWidget.qml +++ b/examples/declarative/ui-components/tabwidget/TabWidget.qml @@ -45,8 +45,8 @@ Item { // Setting the default property to stack.children means any child items // of the TabWidget are actually added to the 'stack' item's children. - // See the "Extending Types from QML" documentation for details on default - // properties. + // See the "Writing QML Components: Properties, Methods and Signals" + // documentation for details on default properties. default property alias content: stack.children property int current: 0 -- cgit v0.12 From 2a67cbb031608e73b0e02a12ea26de6d43c9250d Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Fri, 3 Dec 2010 15:15:51 +1000 Subject: Give qmlviewer a minimum size if root object has no size. de8c9d69fa7c7cc50e9a238e58f6e9370f158fc4 ensured the window was at least partly visible on Windows and Linux but it did not work on Mac. Task-number: QTBUG-15783 Reviewed-by: Alan Alpert --- tools/qml/qmlruntime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index 7ea77d1..a368bc1 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -1520,7 +1520,7 @@ void QDeclarativeViewer::updateSizeHints(bool initial) //qWarning() << "USH: R2V: setting free size "; layout()->setSizeConstraint(QLayout::SetNoConstraint); layout()->activate(); - setMinimumSize(QSize(1,1)); + setMinimumSize(minimumSizeHint()); setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); canvas->setMinimumSize(QSize(0,0)); canvas->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); -- cgit v0.12 From d55ea5c4b4d1d80ab94c3ef3a59b15359373c84a Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Fri, 3 Dec 2010 18:52:03 +1000 Subject: Do not use openGL on Mac OS X for QML visual tests It appears to lead to sporadic crashes in the CI system. Task-number: QTBUG-14792 --- tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp index fe23e09..3ca6d93 100644 --- a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp +++ b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp @@ -133,6 +133,9 @@ void tst_qmlvisual::visual() QFETCH(QString, testdata); QStringList arguments; +#ifdef Q_WS_MAC + arguments << "-no-opengl"; +#endif arguments << "-script" << testdata << "-scriptopts" << "play,testimages,testerror,testskip,exitoncomplete,exitonfailure" << file; @@ -236,6 +239,9 @@ void action(Mode mode, const QString &file) QString testdata = tst_qmlvisual::toTestScript(file,mode); QStringList arguments; +#ifdef Q_WS_MAC + arguments << "-no-opengl"; +#endif switch (mode) { case Test: // Don't run qml -- cgit v0.12 From 3f7c80d105d18a3b901a7f3077d8faaea63e0659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Fri, 3 Dec 2010 10:01:28 +0100 Subject: Fix integer overflow in bitfield UnfeasibleConstraint is 4, and that does not fit in 2 bits. Spotted by Thiago Reviewed-by: Thiago --- src/gui/graphicsview/qgridlayoutengine_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgridlayoutengine_p.h b/src/gui/graphicsview/qgridlayoutengine_p.h index 44efbba..1b2e2ec 100644 --- a/src/gui/graphicsview/qgridlayoutengine_p.h +++ b/src/gui/graphicsview/qgridlayoutengine_p.h @@ -433,7 +433,7 @@ private: // Lazily computed from the above user input mutable int q_cachedEffectiveFirstRows[NOrientations]; mutable int q_cachedEffectiveLastRows[NOrientations]; - mutable quint8 q_cachedConstraintOrientation : 2; + mutable quint8 q_cachedConstraintOrientation : 3; // Layout item input mutable QLayoutStyleInfo q_cachedDataForStyleInfo; -- cgit v0.12 From 5b7b11238b0edbf1d0177732acc50fe0459c42c7 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Fri, 3 Dec 2010 19:11:41 +1000 Subject: Update visual tests for the recent qmlviewer change Changing the minimum size of the viewer changes the size of some of the visual test outputs which were really small. Task-number: QTBUG-14792 --- .../qmlvisual/focusscope/data/test2.0.png | Bin 305 -> 439 bytes .../qmlvisual/focusscope/data/test2.1.png | Bin 305 -> 439 bytes .../qmlvisual/focusscope/data/test2.qml | 154 ++--- .../data/usingRepeater.0.png | Bin 1203 -> 1747 bytes .../qdeclarativepositioners/data/usingRepeater.qml | 62 +- .../align/data-X11/multilineAlign.0.png | Bin 762 -> 791 bytes .../align/data-X11/multilineAlign.qml | 118 ++-- .../qdeclarativetext/data-X11/qtbug_14865.0.png | Bin 303 -> 465 bytes .../qdeclarativetext/data-X11/qtbug_14865.1.png | Bin 303 -> 465 bytes .../qdeclarativetext/data-X11/qtbug_14865.qml | 216 +++---- .../qdeclarativetext/elide/data-X11/elide.0.png | Bin 481 -> 581 bytes .../qdeclarativetext/elide/data-X11/elide.1.png | Bin 481 -> 581 bytes .../qdeclarativetext/elide/data-X11/elide.qml | 128 ++-- .../elide/data-X11/multilength.0.png | Bin 742 -> 903 bytes .../elide/data-X11/multilength.1.png | Bin 810 -> 967 bytes .../elide/data-X11/multilength.2.png | Bin 805 -> 962 bytes .../elide/data-X11/multilength.3.png | Bin 529 -> 678 bytes .../elide/data-X11/multilength.4.png | Bin 528 -> 676 bytes .../elide/data-X11/multilength.5.png | Bin 399 -> 542 bytes .../elide/data-X11/multilength.qml | 646 ++++++++++----------- .../qdeclarativetextedit/data-X11/qt-669.0.png | Bin 692 -> 855 bytes .../qdeclarativetextedit/data-X11/qt-669.1.png | Bin 696 -> 863 bytes .../qdeclarativetextedit/data-X11/qt-669.2.png | Bin 699 -> 865 bytes .../qdeclarativetextedit/data-X11/qt-669.3.png | Bin 698 -> 862 bytes .../qdeclarativetextedit/data-X11/qt-669.4.png | Bin 692 -> 855 bytes .../qdeclarativetextedit/data-X11/qt-669.qml | 528 ++++++++--------- .../qdeclarativetextinput/data-X11/echoMode.0.png | Bin 256 -> 358 bytes .../qdeclarativetextinput/data-X11/echoMode.1.png | Bin 342 -> 446 bytes .../qdeclarativetextinput/data-X11/echoMode.2.png | Bin 445 -> 553 bytes .../qdeclarativetextinput/data-X11/echoMode.3.png | Bin 508 -> 622 bytes .../qdeclarativetextinput/data-X11/echoMode.qml | 374 ++++++------ 31 files changed, 1113 insertions(+), 1113 deletions(-) diff --git a/tests/auto/declarative/qmlvisual/focusscope/data/test2.0.png b/tests/auto/declarative/qmlvisual/focusscope/data/test2.0.png index 22d7496..396bf2d 100644 Binary files a/tests/auto/declarative/qmlvisual/focusscope/data/test2.0.png and b/tests/auto/declarative/qmlvisual/focusscope/data/test2.0.png differ diff --git a/tests/auto/declarative/qmlvisual/focusscope/data/test2.1.png b/tests/auto/declarative/qmlvisual/focusscope/data/test2.1.png index 22d7496..396bf2d 100644 Binary files a/tests/auto/declarative/qmlvisual/focusscope/data/test2.1.png and b/tests/auto/declarative/qmlvisual/focusscope/data/test2.1.png differ diff --git a/tests/auto/declarative/qmlvisual/focusscope/data/test2.qml b/tests/auto/declarative/qmlvisual/focusscope/data/test2.qml index 62eff17..8669071 100644 --- a/tests/auto/declarative/qmlvisual/focusscope/data/test2.qml +++ b/tests/auto/declarative/qmlvisual/focusscope/data/test2.qml @@ -10,239 +10,239 @@ VisualTest { } Frame { msec: 32 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 48 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 64 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 80 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 96 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 112 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 128 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 144 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 160 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 176 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 192 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 208 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 224 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 240 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 256 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 272 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 288 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 304 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 320 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 336 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 352 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 368 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 384 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 400 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 416 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 432 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 448 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 464 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 480 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 496 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 512 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 528 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 544 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 560 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 576 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 592 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 608 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 624 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 640 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 656 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 672 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 688 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 704 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 720 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 736 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 752 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 768 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 784 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 800 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 816 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 832 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 848 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 864 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 880 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 896 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 912 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 928 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 944 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 960 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 976 @@ -250,74 +250,74 @@ VisualTest { } Frame { msec: 992 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1008 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1024 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1040 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1056 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1072 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1088 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1104 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1120 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1136 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1152 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1168 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1184 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1200 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1216 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1232 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1248 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } Frame { msec: 1264 - hash: "4823f4520db0c1f64d887f172b3efa17" + hash: "f4041fcc91346361df95e344a0ee8e2d" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.0.png b/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.0.png index f5b5622..0efb20a 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.qml b/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.qml index 3869b73..365c25f 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativepositioners/data/usingRepeater.qml @@ -10,126 +10,126 @@ VisualTest { } Frame { msec: 32 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 48 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 64 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 80 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 96 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 112 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 128 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 144 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 160 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 176 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 192 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 208 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 224 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 240 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 256 - hash: "3b670c14311188b82f37aa260fb1a8de" + hash: "e76f50af76d6ee5925b183f9e2316b78" } Frame { msec: 272 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 288 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 304 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 320 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 336 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 352 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 368 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 384 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 400 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 416 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 432 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 448 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 464 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 480 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 496 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } Frame { msec: 512 - hash: "07b267d5a8c194322d339e1ad609f199" + hash: "c98a904eb5da750f4cabf787e253b2ec" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-X11/multilineAlign.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-X11/multilineAlign.0.png index 38f2051..666d272 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-X11/multilineAlign.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-X11/multilineAlign.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-X11/multilineAlign.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-X11/multilineAlign.qml index d431bb8..75e6859 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-X11/multilineAlign.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-X11/multilineAlign.qml @@ -10,238 +10,238 @@ VisualTest { } Frame { msec: 32 - hash: "d80fd046c582a26230e547471f290f12" + hash: "377fd9e347a2e6e0930d1422ce744c5c" } Frame { msec: 48 - hash: "d80fd046c582a26230e547471f290f12" + hash: "377fd9e347a2e6e0930d1422ce744c5c" } Frame { msec: 64 - hash: "d80fd046c582a26230e547471f290f12" + hash: "377fd9e347a2e6e0930d1422ce744c5c" } Frame { msec: 80 - hash: "d80fd046c582a26230e547471f290f12" + hash: "377fd9e347a2e6e0930d1422ce744c5c" } Frame { msec: 96 - hash: "d80fd046c582a26230e547471f290f12" + hash: "377fd9e347a2e6e0930d1422ce744c5c" } Frame { msec: 112 - hash: "d80fd046c582a26230e547471f290f12" + hash: "377fd9e347a2e6e0930d1422ce744c5c" } Frame { msec: 128 - hash: "d80fd046c582a26230e547471f290f12" + hash: "377fd9e347a2e6e0930d1422ce744c5c" } Frame { msec: 144 - hash: "d80fd046c582a26230e547471f290f12" + hash: "377fd9e347a2e6e0930d1422ce744c5c" } Frame { msec: 160 - hash: "d80fd046c582a26230e547471f290f12" + hash: "377fd9e347a2e6e0930d1422ce744c5c" } Frame { msec: 176 - hash: "f9e466557e920150c638621536d94e5b" + hash: "36106ba13106d262c02c67e82bba1443" } Frame { msec: 192 - hash: "f9e466557e920150c638621536d94e5b" + hash: "36106ba13106d262c02c67e82bba1443" } Frame { msec: 208 - hash: "f9e466557e920150c638621536d94e5b" + hash: "36106ba13106d262c02c67e82bba1443" } Frame { msec: 224 - hash: "f9e466557e920150c638621536d94e5b" + hash: "36106ba13106d262c02c67e82bba1443" } Frame { msec: 240 - hash: "f9e466557e920150c638621536d94e5b" + hash: "36106ba13106d262c02c67e82bba1443" } Frame { msec: 256 - hash: "f9e466557e920150c638621536d94e5b" + hash: "36106ba13106d262c02c67e82bba1443" } Frame { msec: 272 - hash: "f9e466557e920150c638621536d94e5b" + hash: "36106ba13106d262c02c67e82bba1443" } Frame { msec: 288 - hash: "f9e466557e920150c638621536d94e5b" + hash: "36106ba13106d262c02c67e82bba1443" } Frame { msec: 304 - hash: "f9e466557e920150c638621536d94e5b" + hash: "36106ba13106d262c02c67e82bba1443" } Frame { msec: 320 - hash: "f9e466557e920150c638621536d94e5b" + hash: "36106ba13106d262c02c67e82bba1443" } Frame { msec: 336 - hash: "40b5718a9370c332f254a3ead05dfe5b" + hash: "509d31a486ae2f83055b52ec12f33e76" } Frame { msec: 352 - hash: "40b5718a9370c332f254a3ead05dfe5b" + hash: "509d31a486ae2f83055b52ec12f33e76" } Frame { msec: 368 - hash: "40b5718a9370c332f254a3ead05dfe5b" + hash: "509d31a486ae2f83055b52ec12f33e76" } Frame { msec: 384 - hash: "40b5718a9370c332f254a3ead05dfe5b" + hash: "509d31a486ae2f83055b52ec12f33e76" } Frame { msec: 400 - hash: "40b5718a9370c332f254a3ead05dfe5b" + hash: "509d31a486ae2f83055b52ec12f33e76" } Frame { msec: 416 - hash: "40b5718a9370c332f254a3ead05dfe5b" + hash: "509d31a486ae2f83055b52ec12f33e76" } Frame { msec: 432 - hash: "40b5718a9370c332f254a3ead05dfe5b" + hash: "509d31a486ae2f83055b52ec12f33e76" } Frame { msec: 448 - hash: "40b5718a9370c332f254a3ead05dfe5b" + hash: "509d31a486ae2f83055b52ec12f33e76" } Frame { msec: 464 - hash: "40b5718a9370c332f254a3ead05dfe5b" + hash: "509d31a486ae2f83055b52ec12f33e76" } Frame { msec: 480 - hash: "40b5718a9370c332f254a3ead05dfe5b" + hash: "509d31a486ae2f83055b52ec12f33e76" } Frame { msec: 496 - hash: "3249c560c69e915020f9632acd1c5eca" + hash: "09b9249750ba637ef659cbc7b9a6055f" } Frame { msec: 512 - hash: "3249c560c69e915020f9632acd1c5eca" + hash: "09b9249750ba637ef659cbc7b9a6055f" } Frame { msec: 528 - hash: "3249c560c69e915020f9632acd1c5eca" + hash: "09b9249750ba637ef659cbc7b9a6055f" } Frame { msec: 544 - hash: "3249c560c69e915020f9632acd1c5eca" + hash: "09b9249750ba637ef659cbc7b9a6055f" } Frame { msec: 560 - hash: "3249c560c69e915020f9632acd1c5eca" + hash: "09b9249750ba637ef659cbc7b9a6055f" } Frame { msec: 576 - hash: "3249c560c69e915020f9632acd1c5eca" + hash: "09b9249750ba637ef659cbc7b9a6055f" } Frame { msec: 592 - hash: "3249c560c69e915020f9632acd1c5eca" + hash: "09b9249750ba637ef659cbc7b9a6055f" } Frame { msec: 608 - hash: "3249c560c69e915020f9632acd1c5eca" + hash: "09b9249750ba637ef659cbc7b9a6055f" } Frame { msec: 624 - hash: "3249c560c69e915020f9632acd1c5eca" + hash: "09b9249750ba637ef659cbc7b9a6055f" } Frame { msec: 640 - hash: "3249c560c69e915020f9632acd1c5eca" + hash: "09b9249750ba637ef659cbc7b9a6055f" } Frame { msec: 656 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 672 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 688 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 704 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 720 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 736 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 752 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 768 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 784 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 800 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 816 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 832 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 848 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 864 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 880 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 896 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 912 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 928 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 944 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } Frame { msec: 960 - hash: "2df61c56ba08ef258a0d493760127a8d" + hash: "1ac7017fcf7c9775b66ed1fb78930a45" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/data-X11/qtbug_14865.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/data-X11/qtbug_14865.0.png index 026d06c..6119f92 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/data-X11/qtbug_14865.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/data-X11/qtbug_14865.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/data-X11/qtbug_14865.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/data-X11/qtbug_14865.1.png index 026d06c..6119f92 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/data-X11/qtbug_14865.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/data-X11/qtbug_14865.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/data-X11/qtbug_14865.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/data-X11/qtbug_14865.qml index 26d0656..481c9aa 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/data-X11/qtbug_14865.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/data-X11/qtbug_14865.qml @@ -10,239 +10,239 @@ VisualTest { } Frame { msec: 32 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 48 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 64 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 80 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 96 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 112 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 128 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 144 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 160 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 176 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 192 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 208 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 224 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 240 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 256 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 272 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 288 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 304 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 320 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 336 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 352 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 368 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 384 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 400 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 416 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 432 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 448 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 464 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 480 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 496 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 512 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 528 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 544 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 560 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 576 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 592 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 608 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 624 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 640 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 656 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 672 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 688 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 704 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 720 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 736 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 752 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 768 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 784 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 800 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 816 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 832 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 848 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 864 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 880 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 896 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 912 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 928 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 944 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 960 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 976 @@ -250,198 +250,198 @@ VisualTest { } Frame { msec: 992 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 1008 - hash: "4235bd6abcbdf6621c4c41153fbaada5" + hash: "bd09363ea401e07a38d216bf29806592" } Frame { msec: 1024 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1040 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1056 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1072 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1088 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1104 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1120 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1136 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1152 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1168 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1184 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1200 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1216 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1232 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1248 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1264 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1280 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1296 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1312 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1328 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1344 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1360 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1376 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1392 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1408 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1424 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1440 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1456 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1472 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1488 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1504 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1520 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1536 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1552 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1568 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1584 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1600 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1616 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1632 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1648 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1664 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1680 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1696 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1712 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1728 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1744 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } Frame { msec: 1760 - hash: "3ccd3d26158a50d8f0567bafd7a23e06" + hash: "a3e4ab9c6151c9acb4c9dd41c9c2c596" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.0.png index 53d3c12..f2e6117 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.1.png index 53d3c12..f2e6117 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.qml index 7aadc15..f306f5c 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/elide.qml @@ -10,239 +10,239 @@ VisualTest { } Frame { msec: 32 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 48 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 64 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 80 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 96 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 112 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 128 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 144 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 160 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 176 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 192 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 208 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 224 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 240 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 256 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 272 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 288 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 304 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 320 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 336 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 352 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 368 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 384 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 400 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 416 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 432 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 448 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 464 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 480 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 496 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 512 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 528 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 544 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 560 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 576 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 592 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 608 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 624 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 640 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 656 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 672 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 688 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 704 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 720 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 736 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 752 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 768 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 784 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 800 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 816 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 832 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 848 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 864 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 880 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 896 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 912 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 928 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 944 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 960 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 976 @@ -258,22 +258,22 @@ VisualTest { } Frame { msec: 992 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 1008 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 1024 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 1040 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } Frame { msec: 1056 - hash: "40d4596fcecc4e6a214decccc581a75f" + hash: "a2003f5b238564e9b68b38db156431d2" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.0.png index bf41ce8..f71c1ac 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.1.png index 683a452..93c16dc 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.2.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.2.png index 6b4a280..acec1ee 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.2.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.3.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.3.png index ddf5431..f380c08 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.3.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.4.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.4.png index 7e56a3c..18142dd 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.4.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.5.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.5.png index 5005724..c7f59b8 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.5.png and b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.5.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.qml index 7b17ab2..6e802f4 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/elide/data-X11/multilength.qml @@ -10,239 +10,239 @@ VisualTest { } Frame { msec: 32 - hash: "b5dfa53607ab952a07d77b4d6bd53a4a" + hash: "fde26fa3d17fb92d676afe61ca6a2170" } Frame { msec: 48 - hash: "c9b99388f7570a65162026739c365edd" + hash: "54c7a0ea10fa212959dc4f7606c31f3c" } Frame { msec: 64 - hash: "6f612fe36fa8028a75f6149390bd3585" + hash: "e73c4521144b2c810f15239e6d8fa468" } Frame { msec: 80 - hash: "efada1cf68ff7dae90962e7540c79b53" + hash: "31a68bfd57846795db57bb30d1d60341" } Frame { msec: 96 - hash: "f42b6952937376ae34f7ef493e86aee6" + hash: "55edcaeed37c1390eee2619d52a2eb03" } Frame { msec: 112 - hash: "008b0419f3ec6dbb16220a8e484a1ec8" + hash: "2c27d9c3dc215c68630495e255c1670e" } Frame { msec: 128 - hash: "ecb3c1cb02f7a01d4343dad1a066fa6f" + hash: "b27dd9260f6da3ab414076e83bf5a2bd" } Frame { msec: 144 - hash: "ce5adf6c5c4d5e385ce7e461e380b00e" + hash: "bfcbba7e970af922ee87fbbe936eaa84" } Frame { msec: 160 - hash: "79b8fefae0ac2784391c15c0221bd99d" + hash: "75af84ff6f21648737cef4a215410cc6" } Frame { msec: 176 - hash: "259da9a4c2bb9c89d16dd1943645e836" + hash: "71fd1fe13a14632ff54ad7a87be68bca" } Frame { msec: 192 - hash: "40ee5004fed2af60ab5fc4983bd2dacd" + hash: "69f553a1893403dc6fc82d3c9c47f501" } Frame { msec: 208 - hash: "935314bef478d43e30b6cbdcb33ba72b" + hash: "9456b12d49cc2a1f9212dba98a83c8ab" } Frame { msec: 224 - hash: "9860af14b459925078467f334bf41e42" + hash: "cfd826f91f6f880816d505c93a8f125a" } Frame { msec: 240 - hash: "d9955eabd55559d7bef3f4cd96b42a35" + hash: "d8e3291525eff9f905102ed7654f986b" } Frame { msec: 256 - hash: "7fa3de8afdeb61c6e2e87cde2e96152f" + hash: "044c1f37e37a68fbfbb9ddbc2da4300a" } Frame { msec: 272 - hash: "0deea16d1f6d18f1e9c57546b485fe75" + hash: "d640cba5f14d9c065bec6f6c23f2831f" } Frame { msec: 288 - hash: "231a71ad0981525d9eb15643bc397130" + hash: "9e15b68dace4b39b937dfea8777ae503" } Frame { msec: 304 - hash: "119e67ab3b30bd9a716ad81bbb10d626" + hash: "7ea72711e3f8bdd1087181e127e093c7" } Frame { msec: 320 - hash: "4f29d912920ab6b8973a2c392a19ea53" + hash: "c45dae8eb1768c8aba2d92dea4f268a2" } Frame { msec: 336 - hash: "8544592eb1d48a55cfd0e274c05622cb" + hash: "181ebf6597be2d9e54c1d01a5ab54b46" } Frame { msec: 352 - hash: "eca3de3a1f3e388a0029ea03327e4b21" + hash: "094b6cc486b60882836a9ba35411ae7d" } Frame { msec: 368 - hash: "7672135d842f0f6f3a06c19e320b9431" + hash: "031f1bcb864b4507bf93caab88756317" } Frame { msec: 384 - hash: "49b5720ebbb03a9c61aebdc6eaf6b2a8" + hash: "42b4d89a1026327f180ecc414dcd0ef0" } Frame { msec: 400 - hash: "7d2ddf271385fef343412c43a41d88da" + hash: "a99c5d1d434687e2f16e7054bcff8a69" } Frame { msec: 416 - hash: "3df6034ff296ab1242146ba7298a9dd8" + hash: "91cf18d3f8538ee8550f7e190911b072" } Frame { msec: 432 - hash: "5a52202453c359370c017a397cbc6f20" + hash: "1c11a328d74bc7bf77da10f094db8d4a" } Frame { msec: 448 - hash: "649d58d817e37e7b14d3080998dbc126" + hash: "e4da6dc99c962e8f37dc8d99669616d0" } Frame { msec: 464 - hash: "f00b682156bde560b571e0044eff150a" + hash: "628d4c1455f58a304887050c0552499a" } Frame { msec: 480 - hash: "0e5ce3806c60e7a67e72ee9f4c334454" + hash: "dd17a403f45bcd1001cb08e7f4ae8443" } Frame { msec: 496 - hash: "9d8c0e6a6a66560752abc68de10a6ec0" + hash: "1ed042d0289fc6167143ddcd92f708f6" } Frame { msec: 512 - hash: "ffd81c8901cdf67ec3fa574b606eba89" + hash: "b55abb6249925cf06439b3177310dcfc" } Frame { msec: 528 - hash: "56b7098e63f8cc1d8957829e7779ae73" + hash: "251c3346640a2aa7a9c18ca84ff2d5bb" } Frame { msec: 544 - hash: "7d7417b2b2c07c93bf5d951fddf4363b" + hash: "6f5e18d84c4107213599b57bf7284c4b" } Frame { msec: 560 - hash: "a2dd725545042e9b6a366d809d2cfc4f" + hash: "2179c1d7d7acb3c2f6354b493cfe74e0" } Frame { msec: 576 - hash: "8fd5ccba4b997a96f7773936afc4fc92" + hash: "bbc757e8f3c08f93ffcdd68b392c8cdb" } Frame { msec: 592 - hash: "85f29eae877f93c4617a37b5c445c605" + hash: "7eefd9c7291c1a23679efd42f2c29539" } Frame { msec: 608 - hash: "a8eb3ebef75081964a6beba533eba89b" + hash: "fa375510d3850614aebceb2bc31ab4de" } Frame { msec: 624 - hash: "8c3e3f4833419e7df6de0c9443390751" + hash: "f643c5ba39bb90f396f00c0a9df995c8" } Frame { msec: 640 - hash: "537f3d9760f6cc0c07452ea3f334a008" + hash: "c6b7792f780b00b1b07c0ce948dff13b" } Frame { msec: 656 - hash: "93a1851ca2afb595ad684a7f613e860c" + hash: "d43d82ee9b0da8f237469c555b48bee8" } Frame { msec: 672 - hash: "fd353e60da99a884f60a2d1ab6e4be46" + hash: "addaa9d2aa8f54d6a4e82dc7e029f19d" } Frame { msec: 688 - hash: "21cff9dcfa9e7bb4a44d75338e314d0e" + hash: "b12af2fd05a1ccd4664c5093456bae01" } Frame { msec: 704 - hash: "64153f5d57b7191f5e957f22dcdff6d3" + hash: "982d3505c51fc1bac026c744e2d1db11" } Frame { msec: 720 - hash: "211d8e9b6427129e4b9292fc862edfb6" + hash: "a67a0705ce893dcafdcfc3a7fe71f608" } Frame { msec: 736 - hash: "35f96f202391dc805b0bbb45d7efb1bf" + hash: "6e00f746695ca67fb4c4462740b13c8f" } Frame { msec: 752 - hash: "0336a1ba71d4bf7b4cbf98812ba1ae9c" + hash: "bc4235d556a1e18d591b9afd87b29826" } Frame { msec: 768 - hash: "c5ec3a61d64228efe448b0d5c0004baa" + hash: "830ebf4b9214f1dc31975c83cf49d31e" } Frame { msec: 784 - hash: "9154774bce1d89b84c0f525e282bc95d" + hash: "bac049ae3d6676db8bca99620c9f5bd3" } Frame { msec: 800 - hash: "8d07794b2b17971ff69ff7961c441765" + hash: "0f9623c23e4e45126078c3c93015d26c" } Frame { msec: 816 - hash: "086c711c3794f8ad8d634ed6483f3caf" + hash: "bedde76baa8905970ea5fa8da62355a6" } Frame { msec: 832 - hash: "af591122aee8c949957ae19136505a57" + hash: "018b9b1444d921b8cfd823265556c8f6" } Frame { msec: 848 - hash: "c84db4548f53ae95023e56fad3c4aea3" + hash: "2be3e0693f54ffefd24e44f552d59e3f" } Frame { msec: 864 - hash: "d7a7bb5cfb91923db8d72d9a12f0016c" + hash: "c8c99f68125df2a1f41f6b44fdcc0406" } Frame { msec: 880 - hash: "7171788040f36bf1c878678906a84290" + hash: "3e18d6a24a1c6983f3f2ce984d22dbe4" } Frame { msec: 896 - hash: "d2016d9ba6b29c7dfb5d64e506e7f980" + hash: "aa336c4e5ace2b33689ca280de2299db" } Frame { msec: 912 - hash: "75945e6719cea6aaf021fcd28dfe4da0" + hash: "fd7245f879bbd72b6e72c563a588eea7" } Frame { msec: 928 - hash: "e203a20fc8dda077ff217ac74895b8f6" + hash: "e484656517fcb5763c0c8992b22efe91" } Frame { msec: 944 - hash: "1acb696745e0ead2f8c9d807787ce225" + hash: "fbd58b050963fc7cdbd5ae89aa7a4a70" } Frame { msec: 960 - hash: "b8d60fcd3e262dc33d623a741fdafb0b" + hash: "b47ad6fb8b364e3c2764bf31e62f21e0" } Frame { msec: 976 @@ -250,239 +250,239 @@ VisualTest { } Frame { msec: 992 - hash: "0acda3300bec26515f7ddfd33af6ca84" + hash: "ac1a6692030ed80cd34c082ac70ea06e" } Frame { msec: 1008 - hash: "12f5c647778c868638845fd66c825f51" + hash: "068a6b82a35d94e3db3eae772c7da56a" } Frame { msec: 1024 - hash: "e87432496a570b68c18d563fd3e55b7c" + hash: "8252bb45e74bc09e1d5e6b3951fbb08e" } Frame { msec: 1040 - hash: "332a165345a53198ec22a69e12a7cd6c" + hash: "a5d7ad9287238780cb45c61bb70d6cd4" } Frame { msec: 1056 - hash: "92f7d768af912807dca6ad16006d84e9" + hash: "e0307f3a1193af0df0cd52d7dac44db9" } Frame { msec: 1072 - hash: "50c330c7e9ed8f08e4b496b322fed388" + hash: "d649cf0c4a768dba1a0380b64bc7e48b" } Frame { msec: 1088 - hash: "554317004bc31ba56c970fac294577df" + hash: "3fd512a0860c17abbb6ed71488cd7255" } Frame { msec: 1104 - hash: "3c6391b4296451f1ca1db737e4d928c3" + hash: "26032efe6efd1de4b5fae23ce4e28a0a" } Frame { msec: 1120 - hash: "8274fa399e0b132582389c909775e8cb" + hash: "846652a87d93e397d1a84b187b7aafea" } Frame { msec: 1136 - hash: "f66504b79f0415652f4c6720a2643afe" + hash: "4dfdaa030da4c72a0e1a19bfd70b5856" } Frame { msec: 1152 - hash: "53ce26d4f839451868c70133c3f0dff2" + hash: "365ad99db7302dfe078f4283af13f5ca" } Frame { msec: 1168 - hash: "715b6a5090e0a947cbbd5f8902088177" + hash: "f378a096243bd2c6f7e33e0baf24716a" } Frame { msec: 1184 - hash: "3715a52358febdbfa4aeefe56b4b173e" + hash: "e972a84715d314e8814cb7fcab1ad379" } Frame { msec: 1200 - hash: "d89459730ea136a34135fded35bc2247" + hash: "8826dbafd12ba2a7437623c8967f2699" } Frame { msec: 1216 - hash: "ba8471a6c2449a05dfe411b86a38ff35" + hash: "effa889b33b97f665a21d6562acc45fc" } Frame { msec: 1232 - hash: "5c477b14e0ff59e5d7db360005deaea7" + hash: "6ebb408651cf5fbb2fa8788e0ec544d6" } Frame { msec: 1248 - hash: "becdcaa9d4f78d94e3f3af87467798bd" + hash: "c4f45fd05b7b4f00acf80f768e99af38" } Frame { msec: 1264 - hash: "2b1f5c5c6a9f26e6b359cf786591d480" + hash: "735a7c461f6b10cd967b03c173bfd81d" } Frame { msec: 1280 - hash: "9b1cbb944a941fd2869ac193e9701582" + hash: "608cf5ebac88726ffe7e66d763d74e27" } Frame { msec: 1296 - hash: "e1c67be1ec2030529335c02099a3d9cc" + hash: "6322c5aebdf814bfc5bfaef8b6bb4d91" } Frame { msec: 1312 - hash: "4f4ecadaa0afad0e38530067ee7688b9" + hash: "730b7cef2e0cf57a4721e77e6849b862" } Frame { msec: 1328 - hash: "13f13cb8ea96d764c93ab43f538af2a7" + hash: "13879c0772938e39d820b6fc10e0f7e5" } Frame { msec: 1344 - hash: "cd33ccd1ac45f1f83cf93cfbdefa415a" + hash: "0710bf8a2beff02009d4bb02f2404b7b" } Frame { msec: 1360 - hash: "8c84a3842a8da763c4b398e49a13831f" + hash: "2cd38c2cbf3d8b7eb3a50b9db4bb8f7f" } Frame { msec: 1376 - hash: "3b47b3c27171032450a421ae8ecc786d" + hash: "4e988a74a3846171f86d4d69ce3407d9" } Frame { msec: 1392 - hash: "524517523cb15d7886c6dbfa8724ea95" + hash: "82cc4b40fe1190de5a2cbbf3f11ac7b0" } Frame { msec: 1408 - hash: "3ae90a6ed20fe62da9fb81b51d6d9a1e" + hash: "f15bd345b992b39167165a640ad45794" } Frame { msec: 1424 - hash: "70c0880f0d0d1deefc22baebbeda06c3" + hash: "be5ca66da00327ecc9f5dde2aa3660d2" } Frame { msec: 1440 - hash: "d97f6cda6df39ffe1db076204191bba6" + hash: "f97a1e863c36477d31a78342c7aa21b7" } Frame { msec: 1456 - hash: "d170a0b8339bd0c29b664403ce8b3286" + hash: "d137a2a6ae95aba3f7a2b2a0560718a5" } Frame { msec: 1472 - hash: "fd962a3a4e2fbe03f6730136cdc2a824" + hash: "e7529db7cf310e41eb0ac42ab86ae317" } Frame { msec: 1488 - hash: "75bcbfc7d7bf3139538347b17b41cf12" + hash: "66914e90881a4a8751ba5391ac41a70b" } Frame { msec: 1504 - hash: "0fcba8fa11a2f3fc7ebcefee6e9dafcd" + hash: "249863a5ef1a14ca0eb4397d206dfc1e" } Frame { msec: 1520 - hash: "621f80511b2ce7106b1d285045f505ca" + hash: "26095384b724a5e704c7b627930f4e22" } Frame { msec: 1536 - hash: "be6896d8de4bbb8b7ef9e1d34f6f7f32" + hash: "98281eed5ae9d9f933e47a8fba8709f1" } Frame { msec: 1552 - hash: "a770cffe72c2791d6d76c16926f98f2f" + hash: "d9b50c54255edb300e36af2648ef8f30" } Frame { msec: 1568 - hash: "7e8222f9831e235c7d044b5188a20dd1" + hash: "9bde860d92f5ec979fa5c274fd1c13a1" } Frame { msec: 1584 - hash: "a740dfb5ae432712abb4f5f9479a22fa" + hash: "39c13a42f920f57d9f9fe85ebc4e68fa" } Frame { msec: 1600 - hash: "a731135b3ac067712081b959f27d8784" + hash: "e80bd130bad05078212089586d6c2731" } Frame { msec: 1616 - hash: "c6cdb85a28bdc970cf2a30f0e2cef763" + hash: "753732b5309fd8dd7daa16761dd7dad0" } Frame { msec: 1632 - hash: "4c901d5879cd4e1602b4f3560745f0b1" + hash: "2eb56a98f728b224f7db073c6ea3c3b9" } Frame { msec: 1648 - hash: "ef64a09b2bd30a6c618ac59a8cacd628" + hash: "21ab167d173e244ffb471faddf704e81" } Frame { msec: 1664 - hash: "816f55f5b0b8e3baa52e274ae737ee30" + hash: "9964a0386ae349b909424f588d8decf5" } Frame { msec: 1680 - hash: "90db19b8b2d820d36d7a45518f730014" + hash: "cee42f46df4c879fa6fc378481ec728c" } Frame { msec: 1696 - hash: "f94248d3df175536a4a6b88722763d75" + hash: "4779aeed276cbe4112484d189d1baf8b" } Frame { msec: 1712 - hash: "d1aa57e0666a7d9b5b0dc7b021a1387c" + hash: "d482cd14db734f5fed2eaec7d8c0c555" } Frame { msec: 1728 - hash: "77b17a540862f5ec6b2256408fd3637f" + hash: "1f8b0681711c46afcf8af66df6d7caf8" } Frame { msec: 1744 - hash: "e9b9a37996f5825006565f5b56e755ea" + hash: "44b0e6d69fcd2b7acb499dfdfced026b" } Frame { msec: 1760 - hash: "1ce712e1755047d17d5cf3c97cff1c96" + hash: "b6e25c4a276917b7f7f9189e65d965a8" } Frame { msec: 1776 - hash: "95c21bab93788ed45280e61c51173a99" + hash: "07e5da936f8d5c84606fcdc49fc6aca2" } Frame { msec: 1792 - hash: "6f62ae9bba2b1d2ea67f13d63157bd7c" + hash: "f27a54a8d37ec62f54e083f1ca65aada" } Frame { msec: 1808 - hash: "b5f11412bdb100f88a1f29aa577316e5" + hash: "074403259022efd08fcbd9d3a3052c79" } Frame { msec: 1824 - hash: "d4e2468ed0935687e370fcf70059f57f" + hash: "a126762087c8f94beef81216b6010f0c" } Frame { msec: 1840 - hash: "e7b5970ef9f327a8e7905f1a16c3f1a3" + hash: "96b8c7cebbb9676ea4f028907de71bbf" } Frame { msec: 1856 - hash: "c5b9694fe2d7952d6ef03ff5febec00b" + hash: "e6f073522d0af8e504fdb7df971f5e0a" } Frame { msec: 1872 - hash: "0604da4b328d80162fd88bdfcf2a8a68" + hash: "9223ed285f322fae3ba2b52afb408586" } Frame { msec: 1888 - hash: "cbeffb3c86fcd7b52672382d6a186692" + hash: "b24575dd4c0b0da0b99a03c46209ed3a" } Frame { msec: 1904 - hash: "deb96a6469b351f5e70d3032ad250df9" + hash: "5c82bc860f64183e66aead451ee5b893" } Frame { msec: 1920 - hash: "d4bcb6da72c0b7f2e0e55be917eb5720" + hash: "3172ab9c62b0870d6894b13720e54918" } Frame { msec: 1936 @@ -490,239 +490,239 @@ VisualTest { } Frame { msec: 1952 - hash: "c044b96932667fd56ca8c87ec70791a3" + hash: "5f8e85839f9ac82f46a17f871c3fffbc" } Frame { msec: 1968 - hash: "f197116b796c3647986337515c04a812" + hash: "245219fb6c4aa37d8cba7b5e1f74265f" } Frame { msec: 1984 - hash: "3d06fad059276fd5f8f58faeac482d52" + hash: "b68cfc5366c4ed8d1e5950a1facf0d85" } Frame { msec: 2000 - hash: "841ab0655e2bd498d51605fd37607378" + hash: "dd5c2d2470cc87d57d35ecc9ae8a3528" } Frame { msec: 2016 - hash: "5968dd4f704d72f264704ae6d6a416cf" + hash: "1a15d7f02b35d046305b40f9e6a6839d" } Frame { msec: 2032 - hash: "5daf3758175963e409ad7ea18d40a894" + hash: "d44c382ea28d429e6f8bbef9ae17338a" } Frame { msec: 2048 - hash: "37750cd0aca54fc6fa6651213a4a8aa0" + hash: "63598cb09d5ecbeb991c6db778c5c002" } Frame { msec: 2064 - hash: "b64411f26c1bde823daa4caf96402887" + hash: "b3fcd0180ecd01e2ad0c0114b3dfbf78" } Frame { msec: 2080 - hash: "cf6d68046e9b7cc39305bfbdbd64a6eb" + hash: "8d441044f5f10da23708d7ddf0472989" } Frame { msec: 2096 - hash: "47f89ab15314ce63dc3828aa4ae16d54" + hash: "6e87518a368c39d68521046773c2f922" } Frame { msec: 2112 - hash: "a7116055b3b33ad02bae75f2db016314" + hash: "59e377ccc851ee361e3874ad5ec18e55" } Frame { msec: 2128 - hash: "0a0443c4927d3d8d3373c311b89ead0d" + hash: "57a9b0431c7db130bfe4d6603f98c1f5" } Frame { msec: 2144 - hash: "6be5e906e9127471bb11e98ba9d68d4c" + hash: "526c93727c6321782a373ea6952a8784" } Frame { msec: 2160 - hash: "759c0e5e8a435846bf4471075df9ce1b" + hash: "fcd0a4605e27ecb0bac18686e7846b3b" } Frame { msec: 2176 - hash: "b7648957a2fdcca31b863907ea5cbc4f" + hash: "d697892f9944c67b5aadd7ad641e3ee5" } Frame { msec: 2192 - hash: "7e9ead6f87c989160681fe87eb44224b" + hash: "f46fd7e568d0995c518749ec0f5a0882" } Frame { msec: 2208 - hash: "f7ab3534218320a49b8cc14b39d23a38" + hash: "31cd2243fb23d4332c02e91f9956f648" } Frame { msec: 2224 - hash: "44ac6d8e7fd3facac856b532bea9b0dd" + hash: "3b29a9c0121ff127b69abba9c0b13c2c" } Frame { msec: 2240 - hash: "238d68eb27eaacddcf428706fca95cad" + hash: "ecd789e744ebb5dee7f25ebb089407bf" } Frame { msec: 2256 - hash: "8568076d97d416810f1e91acd33bbba0" + hash: "c99a6dfad8d750b7e67c1e3ef1021cbb" } Frame { msec: 2272 - hash: "3649d85321ac7674d8c3dd77815aaf32" + hash: "82d18b0c193f0ada9cae68e9f6ad5ff5" } Frame { msec: 2288 - hash: "0c6dab9f7d575265d554093b88ee7e17" + hash: "a09e8144b06db76f5849561d880f037e" } Frame { msec: 2304 - hash: "6387cb408d048d7b139f3d9aed2f14d6" + hash: "3e6922ca54c809a32ed5ef72e19d7ff0" } Frame { msec: 2320 - hash: "de2fa29a82cec9d9f22d50bba257f5de" + hash: "28e46da32bf34b3e1cd3d351e4c40317" } Frame { msec: 2336 - hash: "ba77a0dc547202e129e899998c7e0909" + hash: "297aeeaadc5f3268d95320bc3b33a429" } Frame { msec: 2352 - hash: "0acde6d2435444611f7d5fc67d336d4b" + hash: "31721528cdb17b03d3d6ca9f9a91370b" } Frame { msec: 2368 - hash: "1032d38e48cc3485c7a50bcf3ae949d0" + hash: "52fd1721330321daaea0b56122a72e5b" } Frame { msec: 2384 - hash: "571649ca193507216f344405d8cb9636" + hash: "739c5179b9739021dbb522d01812388c" } Frame { msec: 2400 - hash: "968aa311380ef783852b4a642d61d0c3" + hash: "4ae07f58d3a514f5c08f314c5dd445c4" } Frame { msec: 2416 - hash: "b440b4f5f2cb4a061b69e9a99bca0417" + hash: "4305ea97d47bac3fb0eebf9181b3ce48" } Frame { msec: 2432 - hash: "c1a2c2fd58f52c6a6f3e5dc2c1e9e8cf" + hash: "21c99059dba068bc145896217cc0883c" } Frame { msec: 2448 - hash: "2eab036693343475b799188c98f18bad" + hash: "0a514ae5d36acc07c7809a7b4f21ed8e" } Frame { msec: 2464 - hash: "9b0e2eb4c5ed398dfe5ac82c83d38065" + hash: "550ce887f462ace686bc6a9021c5cb73" } Frame { msec: 2480 - hash: "d6459b44113b2514a036a39449579918" + hash: "b65857dcfa0b1281dd5b9821a12dd8e8" } Frame { msec: 2496 - hash: "99e24ed5413be65aee179d7fdd0aa473" + hash: "5a6bb448a570e1a3eef142b8054f3717" } Frame { msec: 2512 - hash: "43c7a5fe622eee2202ab1061155da474" + hash: "b38e2f6b4063e1b8a40292017c5ed4ec" } Frame { msec: 2528 - hash: "78bc6de01b343c19ce11bcb5ce5db091" + hash: "fa7545e6e3fc92d62af2f7651077da5b" } Frame { msec: 2544 - hash: "77463f64f99952f37467b4cae5a75a73" + hash: "ebf0c79720a5692b761b62c4ba360875" } Frame { msec: 2560 - hash: "39181ec3e10fba5d73221e3ef725661d" + hash: "cb5356376d97308a4d102c9a53e93abe" } Frame { msec: 2576 - hash: "f23732daf5b25cbfa79256ad21739537" + hash: "879f434f4901bdcb166294336c60e26a" } Frame { msec: 2592 - hash: "171b8149512f9a1fc44c4076ae8e6891" + hash: "3ab575ac04bdd455346c0460aed413a0" } Frame { msec: 2608 - hash: "1c30c5284764d3aba948f417dc67ea95" + hash: "8f08366cb474ca2a1988ebba9d65ecaa" } Frame { msec: 2624 - hash: "5b40de40cc84f75a3038a2adafea6688" + hash: "2939cf0235f98aeaf48b3f28964cdddd" } Frame { msec: 2640 - hash: "11e918309ac265c0dddc34b05ddd2beb" + hash: "9cf4b339914e48f896dda17e08759472" } Frame { msec: 2656 - hash: "a18c91eae3fd3154c12e46717248577a" + hash: "3f5568ac7a4386f1d5072f1cda0c35b8" } Frame { msec: 2672 - hash: "839199f3940822a38fc2b44161ee0840" + hash: "107edbf8181f79cd7847d0154b6eda11" } Frame { msec: 2688 - hash: "8b62f8b4c353981788111a9434995a18" + hash: "9254497b95b89a7d40903edb04a3764a" } Frame { msec: 2704 - hash: "db7ee2d5e4905959c836d5162bd241c0" + hash: "7e7d25a2ee3fbfd67a3b8fecb9fe9202" } Frame { msec: 2720 - hash: "cb770a4cd0f56108ef703147e74338ae" + hash: "03759f59bbd2be573acd6c03eb088edd" } Frame { msec: 2736 - hash: "bdaaedef0c17b19cc283eba699799073" + hash: "58689762be6c7d3d6de6f23580ec8886" } Frame { msec: 2752 - hash: "8a7f5f87493ba387c14056f9a598e320" + hash: "0d4e315f9b079a30e6a4294a667f9ebc" } Frame { msec: 2768 - hash: "3974497b297fa233f3821abba2bdd6ce" + hash: "3f3dfa1c8d160238dae2da79a6a569f3" } Frame { msec: 2784 - hash: "41a5744b7747765764829328217e80ea" + hash: "b3cd7c3034e2a34c4ae9ed7f3144b2cc" } Frame { msec: 2800 - hash: "4d380bb823659cdfc1d3517234144b72" + hash: "c27d3a9057d1f15c6e0b2d427ac12ad2" } Frame { msec: 2816 - hash: "4699cc1dad5c6d5c84137ee5c5db52a4" + hash: "9b25ab315d9bfc582e41c05e88812cbe" } Frame { msec: 2832 - hash: "22a34c810c640b378708079761d16c9b" + hash: "e75671bfb99741dcff476690ede42166" } Frame { msec: 2848 - hash: "0c76a943b24dc9538416b05a678c7c94" + hash: "7dd3307fb41277ebcc4339cdb7747d7c" } Frame { msec: 2864 - hash: "575a20b793f899d50a95121708263283" + hash: "a148bce140f1637e27ae5f0207b75351" } Frame { msec: 2880 - hash: "830757417bbff5d6950177aa3617516a" + hash: "64e57a31c1baa16bcf47f2202fd6e2ed" } Frame { msec: 2896 @@ -730,239 +730,239 @@ VisualTest { } Frame { msec: 2912 - hash: "1b83db1121bb3436621d3f22758af76d" + hash: "83381c54b1923356c403cad2ae2c3519" } Frame { msec: 2928 - hash: "b2a6d502e9ed62f67c29b8ae7b857116" + hash: "e110f28619c2ec7c1c8d479793b93e54" } Frame { msec: 2944 - hash: "e9e06068090c076021e508772ae85b5a" + hash: "996a9a698f1a7c673eeef67501d7b81b" } Frame { msec: 2960 - hash: "5c7288791d73792b914e99a38b7b455c" + hash: "6cf2465c8b7c70343a26e981e6492212" } Frame { msec: 2976 - hash: "ad2b35c647da055a1088e476f250ea78" + hash: "3a9078adf3d4ca207c97b62ad525998f" } Frame { msec: 2992 - hash: "7cc9bbd4a2ed2ba1646b10a68c11241f" + hash: "0bf0d9a6a202119daa6a44f17d03b9ed" } Frame { msec: 3008 - hash: "f633c12a9d078c4a1405ee399bd75e6f" + hash: "6dfadc21810c9176dad599a6f7f672b9" } Frame { msec: 3024 - hash: "e4638bb2b40ed7c31630412010bccef1" + hash: "f1f866c6245bd6fd8141abfb8a040d46" } Frame { msec: 3040 - hash: "76fdd98f79c08d9211c42b79f953315a" + hash: "84329287c7555bc6207039ea632632b2" } Frame { msec: 3056 - hash: "df754dffbe6429aa7222e7a37d1956c5" + hash: "da7e80527f58c93bce9267958ce4c5d7" } Frame { msec: 3072 - hash: "68edef9b10728f0785cc74dfe92c3e03" + hash: "cd8eea7543ebc42971b3f41ea21dd4ed" } Frame { msec: 3088 - hash: "627ac43eb191db77345ab1a08bfd7e7a" + hash: "b9abb526dc3447370d847a5bca868b50" } Frame { msec: 3104 - hash: "c38698cc4c2de1eb96855f0b6398fd7f" + hash: "b8d63ac8331a9375ca06adacb56d12ea" } Frame { msec: 3120 - hash: "6264db59fa7dd4498cedac94b856d90e" + hash: "20fcdd73a4cc2abebbc462c32fb9b2c8" } Frame { msec: 3136 - hash: "b550d8181dbf88c5079e2fb6310f0309" + hash: "3f656f80771828ee6696a2e0a0626ae4" } Frame { msec: 3152 - hash: "6ffecf31343192ae352c42c6ba978fd3" + hash: "0d99110edca4f8ec544d10d680d27092" } Frame { msec: 3168 - hash: "445e7056bfb7726fcf1b0b6411400ec0" + hash: "48026f803bd17f56d13dd946fb359e3a" } Frame { msec: 3184 - hash: "9648c06d3a89c054587fa1e86c727fd0" + hash: "40759d794139327e2e66685c9fcb047b" } Frame { msec: 3200 - hash: "8d0af1ad33c06cfceaba1a0ca84cf0a0" + hash: "419953a3f882008e82bd733e63e66ab6" } Frame { msec: 3216 - hash: "f8f0c27738b186f17a9dd106481e85c5" + hash: "ddcd288b0a825ef6899755fbad56f2dd" } Frame { msec: 3232 - hash: "44e5893cd28e2d70afbfbb779f2dd154" + hash: "bc203d9f0f32efdd177353b9589bd127" } Frame { msec: 3248 - hash: "dc0d1baafa24423402caf63d6fcd6189" + hash: "a4ae6c449b53545a683cd33bc9274d59" } Frame { msec: 3264 - hash: "12c17a563b37bf633dce6fc6793d1cd9" + hash: "59e7c218b5a1b857469972f966489a43" } Frame { msec: 3280 - hash: "a8647172101b59753ea6aa40ec4570dc" + hash: "521fc5833ab0e3088200e1fea9a887b0" } Frame { msec: 3296 - hash: "e21afb74f793bef8c1b03d252b5700a8" + hash: "bd2386f85afb7516d147bff4c07e239f" } Frame { msec: 3312 - hash: "2e10ccbdee088b17172a479a8a859d56" + hash: "5298fdee07ff2ff34121f064fed3db4e" } Frame { msec: 3328 - hash: "f111c24e1e8d643543519fd703811f24" + hash: "311a8f163cebf7bafcb47c8e6db40ed1" } Frame { msec: 3344 - hash: "dd9aeec2ed05f9c68e1726a91e90e127" + hash: "ad6342bed57257a1616a74e19f2bb484" } Frame { msec: 3360 - hash: "043923ed2dee91815d0dce6cd38834e9" + hash: "4eb186c5f4963dc72b3dbc3a9da4df65" } Frame { msec: 3376 - hash: "07e0dbb223355b2921eb0597235ee820" + hash: "58f1f128001dd1ce0d405595acbaab2a" } Frame { msec: 3392 - hash: "0fba3e9a08d83405df35c632f9dc051e" + hash: "ba4a39b66cac22fceba9c4ecfdbae363" } Frame { msec: 3408 - hash: "a0a5a515ec395bdf4912ab24c8780339" + hash: "bbfde54a4de637bc1c54248e2e342544" } Frame { msec: 3424 - hash: "4e04e0246eb952cfae716214084cc1ed" + hash: "ddc3b4e87782e0472630e2f9f8a57099" } Frame { msec: 3440 - hash: "e7e989234e360e7c0cb44e7be4d654e8" + hash: "1bf1212686520da772fc18ca7684a924" } Frame { msec: 3456 - hash: "139b3309ac9e25b2165342bfb202169f" + hash: "706ec5a3b48123d3b5113d55b71f7968" } Frame { msec: 3472 - hash: "b4008ee73b92abad9c5fd7c83cb864cf" + hash: "62b08db0c3c4f1313bcf4a1e7b90badb" } Frame { msec: 3488 - hash: "b801a917995bd41eee2f4e4fed3006c5" + hash: "ae8409fed9d8919b1af2b4d0eafce670" } Frame { msec: 3504 - hash: "a0ea151cd2a2056a45ff5428239b37f4" + hash: "9f6ed6ada78e42f06f33514e363c736f" } Frame { msec: 3520 - hash: "01df418b5ba99271d3a2e8807de78899" + hash: "97e9a504c2c4ba5329a616810fc19505" } Frame { msec: 3536 - hash: "047fd42df7a5ba0f939930c2021df5fe" + hash: "348b6d15b8ef6862818b4fbdb938f241" } Frame { msec: 3552 - hash: "4336498cee8b516e79297a073257e008" + hash: "c1845df466f5690a8d7a439d33a27f7d" } Frame { msec: 3568 - hash: "ce404ce21bc91ff8dc61bd95b9e1d5ac" + hash: "aee2486331275b9f4116b61588ce169e" } Frame { msec: 3584 - hash: "06b5c263105ec574f10e70002c29adee" + hash: "efca3eaffa3421d68d788ee3f0ec068c" } Frame { msec: 3600 - hash: "6a224a56bbeaeb703afa0c2a7f2daf7d" + hash: "35f2940b51ed8c4734c23a43bf6fe448" } Frame { msec: 3616 - hash: "65259fcbdb9edfefc4fcbd1ab5f62542" + hash: "92b7d34480b7fab4dd39bbccfa8455a5" } Frame { msec: 3632 - hash: "93be4111a6aa21d85ab354bbd41e5b31" + hash: "4408049f405ecf5c3c696780390e2155" } Frame { msec: 3648 - hash: "2e4edcdc4807466620c9671d329a0977" + hash: "29aa30678d5c87c79ac67198e4dd7bd4" } Frame { msec: 3664 - hash: "e3232d08b83e3e9917b6f4eabc86df72" + hash: "2f88ac156017b20795f01716d9e9f2e8" } Frame { msec: 3680 - hash: "f27caa5d738b4778d4343f7b197c5dac" + hash: "4d72dec4a2e8edcff806c11f3742cf07" } Frame { msec: 3696 - hash: "dcf3032bc798daf1dc6bb7d608e2dffb" + hash: "3f5ebad282a4aa9c03a17d32aea03151" } Frame { msec: 3712 - hash: "9f2d4ba31ab4ec10b43b7de19197994e" + hash: "a8d289d15353d45159607377de285732" } Frame { msec: 3728 - hash: "4bf6419de081524ecdeb4c07b376f06d" + hash: "af2d2fcfa4510e0d26ea90fc7711b0cf" } Frame { msec: 3744 - hash: "3fdd8166873e768e1346e52a1b4a6554" + hash: "aed6897bc8b2163822a052e1cc9ad36b" } Frame { msec: 3760 - hash: "7b25b2f1b2694a87095fba46d505684f" + hash: "bf7077614b5045f79c8697bab1e83839" } Frame { msec: 3776 - hash: "d8246057d4b0306747ba449d5247dd21" + hash: "e5c8c0bf1fce3a964f4bb911ffee0bdb" } Frame { msec: 3792 - hash: "e45c06fbf48923393f672381f0256513" + hash: "bcfe4aebc880809f56d480f23b17dfd1" } Frame { msec: 3808 - hash: "fef8f1bf977d6567eebe14ccafd36853" + hash: "2ce342f7864ab26124093edc88585c97" } Frame { msec: 3824 - hash: "04152eab971eac3fbba26f15ba09d329" + hash: "8be15d95125e03a0282e897096abb443" } Frame { msec: 3840 - hash: "5039cb5183587fe46ef30c5d0f8c9584" + hash: "a4486f30becceca3ec3cc5c8718af82a" } Frame { msec: 3856 @@ -970,239 +970,239 @@ VisualTest { } Frame { msec: 3872 - hash: "5d62550ba4502c3eae3f62ce5b8e9374" + hash: "38de7ed0d05015f9b06a4bb278fc96c1" } Frame { msec: 3888 - hash: "859ab80ee7d563a158970d1f3360c7dd" + hash: "1cd9a38bb1fc8b06d5c05cd28719d4b3" } Frame { msec: 3904 - hash: "4f900b694d6e552c9287472ca58be35a" + hash: "682ba6e2eb83ce1b6bf8526b21cf2694" } Frame { msec: 3920 - hash: "6b3aa5a3071ea5ec911bae3dee02a496" + hash: "3da075fccb3d26f30530a69f86d999a8" } Frame { msec: 3936 - hash: "d1b1536b5162e5367db66bb21ccebdcd" + hash: "b0fb39798dfa94d0898e5e0d7afd1277" } Frame { msec: 3952 - hash: "8c8dd0b84be58a3257dbd0210a7b21ab" + hash: "7e41bbe233d6bc7354ba4516edec4841" } Frame { msec: 3968 - hash: "f96cb092836d67c81fdfd3668005e912" + hash: "1d3f24f20ba123940d97f09949cfcc0f" } Frame { msec: 3984 - hash: "7b06694d2fd4dd2def94b11a1e46a391" + hash: "abc7a82d91e28c5a3ee9ffd663c8c7bd" } Frame { msec: 4000 - hash: "cef499e6c1665d2bd4a4322d4334234a" + hash: "e685c0218a3d80584013806707693eb0" } Frame { msec: 4016 - hash: "664503d5cef2676e287c363a488e91f1" + hash: "6ff98dc7eb0453f058a5d4cadf86ddf4" } Frame { msec: 4032 - hash: "cefa44e348ea0d6955a71c7eb0a9b45c" + hash: "5a3d0c2c95cb85678f32a8b68dc8d399" } Frame { msec: 4048 - hash: "0ee5684bf4d5b54c5bc9aeefcb98a3d1" + hash: "d5bde2f063d524ac0e7bcef26d543668" } Frame { msec: 4064 - hash: "fb6667f1c516187cfb93774469ea8165" + hash: "64e7bc5e0798ecd009fd05cbc1523977" } Frame { msec: 4080 - hash: "fba776d4d3056bf64e335de876e118be" + hash: "3c87a9ee92661da2aacc09b71dd393ca" } Frame { msec: 4096 - hash: "a49aa08c4bd8a1ae9420e0962cf77e01" + hash: "bf4806e0e8cb73cded37ca97966078d7" } Frame { msec: 4112 - hash: "bff31d464ae9fc68adf0c8072b637592" + hash: "a5956031dac15dba64bf49c9d308c9c7" } Frame { msec: 4128 - hash: "23bd0afacb2d9bd009c9b5006dc6adf1" + hash: "51395284acf731266eaed86387ad768a" } Frame { msec: 4144 - hash: "d918e94e5be77741d1172fbf960db07e" + hash: "489ab28b773d48b8fdf9cf674b1da87f" } Frame { msec: 4160 - hash: "9abce75f201e20a730e79a672bf837e8" + hash: "4c6a5b7442a4ff241329157657b8c9f7" } Frame { msec: 4176 - hash: "aae93f5e2a2c6e06dbe78bea4e6b1283" + hash: "629faa780676c705ca8349b8765ed38b" } Frame { msec: 4192 - hash: "66cba82f479ae6536800b05f6d694884" + hash: "28654cb8801bea906a4f181004ed0e85" } Frame { msec: 4208 - hash: "d79d43b820c4a53735cfb84288dd5efd" + hash: "2abf774ccf33e6d0af4a8c4154e2ab2a" } Frame { msec: 4224 - hash: "fe0237b64a2ef664ce2c3028b730fdc4" + hash: "f1cbdf35081b08b676d1661834829c9a" } Frame { msec: 4240 - hash: "771b02756dadb0a1f268166138f7cad4" + hash: "a49ef4ec40d59be1e872c6f8bcdbbb4c" } Frame { msec: 4256 - hash: "cbd224a02668f57413b6999dfb141723" + hash: "dab02c8afd3914177bfdf29e68b54291" } Frame { msec: 4272 - hash: "f770a74ce40615095798b244af3cc097" + hash: "7bdca9571a346117277b0de6fa1f6e5e" } Frame { msec: 4288 - hash: "faea3d28eb65656392860d888ec087b1" + hash: "11dc19768b1a4a787f46082a583c068c" } Frame { msec: 4304 - hash: "1f1d5ee10403184ab83ec5c1f94c4290" + hash: "5e72d13702108d55d650a01c1caf2cfb" } Frame { msec: 4320 - hash: "501253b40939d98beac9db85d3cd5b4b" + hash: "e5a379841ae54f07d54c4baa78fa7b69" } Frame { msec: 4336 - hash: "0819ece70a98a3ea4371947375b52d46" + hash: "88d2363709d377cad251dc956b0ff866" } Frame { msec: 4352 - hash: "2b5f64e4a03aa416a4cf172c99aec498" + hash: "5e6db7322e69f41d37efdd35a769df4e" } Frame { msec: 4368 - hash: "931a6fa175b8d540fc745d425a9b93b3" + hash: "cc781d136bb48a1a41bd9243327bacc3" } Frame { msec: 4384 - hash: "fa6f54fae79a428029fbd0ae6481bcc5" + hash: "69612d6379a204fa1e1c6d7b58f78370" } Frame { msec: 4400 - hash: "7796756dfd30688ed74c2e6e0b05ca5a" + hash: "a81c15225bc81a19e22375532a5457ab" } Frame { msec: 4416 - hash: "b42cfbfe1527412b977b8e2c7506cdf0" + hash: "a97bb0ac528a1377ef8f6bf655795b69" } Frame { msec: 4432 - hash: "c81300e8d29770c0efd2ab91d75a669a" + hash: "7fa6d66219c66ae8aec43e44626b427a" } Frame { msec: 4448 - hash: "923494f5147a85432e6efbcf5b79e26a" + hash: "99f47bc80b706692f16c6c5fa3c0c85d" } Frame { msec: 4464 - hash: "3aaffee732cb243bbda5df938f487b2d" + hash: "55d6cf7f545c74ed59a8bf040f9d5d58" } Frame { msec: 4480 - hash: "ce8e33f621c7f5cd5047da86bdef4084" + hash: "1a07d14fa7866c5268e622d0925cbf4d" } Frame { msec: 4496 - hash: "55e2bc371ea853ee4f3ba22e35c20e8e" + hash: "a41b281563c401d0e4ff55f4a3c45e18" } Frame { msec: 4512 - hash: "e8bec4813a6c8f212c70019f907ba904" + hash: "6bff67c2f53a4e620c63eea539f4abe0" } Frame { msec: 4528 - hash: "aae9dd25ca9935c478e5d9fa629c6f70" + hash: "a5f06e5ff2fd7f390279f7df822c8297" } Frame { msec: 4544 - hash: "30828a796072deb6e6505090dbc2c840" + hash: "213b174770c13105b89a1d88cd2f0b7c" } Frame { msec: 4560 - hash: "c8ebeb539a6ebb2ca47544f7f1617da9" + hash: "dde34ca92317a54ddaa2f9bff515d91c" } Frame { msec: 4576 - hash: "3ad9a23b57b0938a430c636910dc312f" + hash: "12446cca2aae19fd721cda11bbb51bae" } Frame { msec: 4592 - hash: "1a12587ebbae18dd761c70c4ed845fa5" + hash: "f4d00502cab0a843563fcfd336b74596" } Frame { msec: 4608 - hash: "f1d6ee0cd7aaa221d151c2d32e963358" + hash: "b6ae2b396adf6068ef3a6027e4b175db" } Frame { msec: 4624 - hash: "e9bbf398abc09d9740dce4e3843c53f4" + hash: "370dabffdfc0bebf5d25abfaefff399c" } Frame { msec: 4640 - hash: "f839c105f1897f028611d557b11f5814" + hash: "fd496e8c03f85a872bd5ee6e8a85db7f" } Frame { msec: 4656 - hash: "b923b46ccfe53ceb7ea228b12f44842d" + hash: "0999335427d63f318e166ea8662c4c22" } Frame { msec: 4672 - hash: "8e3708a8f2ba63f7cb01b8d66d1b3dec" + hash: "5a4eb9267cd35a71f6c2daaca1a582be" } Frame { msec: 4688 - hash: "68659fce94c9d019a1d5da6273186674" + hash: "4270d7a26d56f1d805b647c5ec7cc6ce" } Frame { msec: 4704 - hash: "56797caf6f2987b7d03c0401871d87e3" + hash: "334f1e3c8520196016352bf4d00fbc18" } Frame { msec: 4720 - hash: "de0d89aaa5b1ce0ed99d2906b63e7434" + hash: "2bf704e85c197c776a188927a80deaad" } Frame { msec: 4736 - hash: "e3802a76b64eeaeae06b23134b5198a9" + hash: "e2c5c42e55dc185977bd5049eb4bd3d2" } Frame { msec: 4752 - hash: "1a3ddf57aa429a407705ae268441c5b5" + hash: "7ead4353fdc135d6b959be0ce22955e3" } Frame { msec: 4768 - hash: "319b09c0e4a8c0d1f507594b53a407c4" + hash: "ab42998e1e17ac8637d76dc0cf356c7a" } Frame { msec: 4784 - hash: "fd54c9ee19133b0f75c56e4d6472cdad" + hash: "030f34f8caf0814eaaf18ea5fda669dd" } Frame { msec: 4800 - hash: "e6b983b491133a41b753411c587c69ec" + hash: "6e12a04ac25553142875a10a5c8e46e8" } Frame { msec: 4816 @@ -1210,114 +1210,114 @@ VisualTest { } Frame { msec: 4832 - hash: "2760407d7defa4738d7b9ecb243f41a9" + hash: "e2f2ab9a3fe6a3a375341010c91017bd" } Frame { msec: 4848 - hash: "1ff562f05454980d4f677e783ba4bf75" + hash: "9301889debd3932772a1c81314eb1ef2" } Frame { msec: 4864 - hash: "43ad6e0926f812af5553e3a8492404e9" + hash: "671feec6eb1166c612a22405db9c044e" } Frame { msec: 4880 - hash: "b9c34d52c0c44dcdf8a2ca8a0e20ae65" + hash: "648215ffa5448dc173165d24389c014e" } Frame { msec: 4896 - hash: "4fd7f6d183626686569462a9828837d2" + hash: "a70806b54806f29d0e240cd63d86b77e" } Frame { msec: 4912 - hash: "3b904440f68aa0009707b5f3a0c2af74" + hash: "4bf9ffe611c52c21fbdb84221d3d4dba" } Frame { msec: 4928 - hash: "cc58910f0881ec5b3cb2eec404c19e16" + hash: "ae78202b0ebd4c13a92d468a7470bdc9" } Frame { msec: 4944 - hash: "8b638f369c3629530d91e6acac8c5fdf" + hash: "fb0c3d6c3e3479abb6a1b44b1a5f3785" } Frame { msec: 4960 - hash: "b403e21b14646ac0cdaee2027125c0ad" + hash: "48906c21e17479807f736d7f7713f6b0" } Frame { msec: 4976 - hash: "d037545cc68b7582c400c8c9da49ff2a" + hash: "a661a461542b3078dd1dad25bf6d8414" } Frame { msec: 4992 - hash: "551435ecb008ff217eb65a5a77a28090" + hash: "387deb0df0c59cfb120313946c4e5c9a" } Frame { msec: 5008 - hash: "a1684c1c0938386bbfb309969114beee" + hash: "f2473c6e4877f3035f0b511ff2d27684" } Frame { msec: 5024 - hash: "c95868a45ccb031ea1d440bedd1fc33f" + hash: "f88d3767ccd773930ef9d99dfd0e8c17" } Frame { msec: 5040 - hash: "eb78d75fbf3ef0b88c072f69ac3f490d" + hash: "aef8a93d2caafec839d425184176bcc7" } Frame { msec: 5056 - hash: "6f612fe36fa8028a75f6149390bd3585" + hash: "e73c4521144b2c810f15239e6d8fa468" } Frame { msec: 5072 - hash: "7906071fe656ccf18d24c100950b6a7a" + hash: "a66856750cc5aa7a21ffb6e0a9c94306" } Frame { msec: 5088 - hash: "064a0b9a0adb235fd52a6d53b65c9d1c" + hash: "22bce57e360790c356564a0568ec3bee" } Frame { msec: 5104 - hash: "f42b6952937376ae34f7ef493e86aee6" + hash: "55edcaeed37c1390eee2619d52a2eb03" } Frame { msec: 5120 - hash: "3444491cc10b0ae2f298ac3aefcda77c" + hash: "51d8495324954f1bd62caa67d15e9ab2" } Frame { msec: 5136 - hash: "ce5adf6c5c4d5e385ce7e461e380b00e" + hash: "bfcbba7e970af922ee87fbbe936eaa84" } Frame { msec: 5152 - hash: "6b6c1a422f778935b400c9a170439ec4" + hash: "a7652fe427ca7b8ef37dbf9a6097f8af" } Frame { msec: 5168 - hash: "fdaff741a826c10cb9799adc70d92145" + hash: "d5ab00fc274a7fd568af514c55f24e04" } Frame { msec: 5184 - hash: "259da9a4c2bb9c89d16dd1943645e836" + hash: "71fd1fe13a14632ff54ad7a87be68bca" } Frame { msec: 5200 - hash: "fd2903f4b3d7086981a89e87e460a7ba" + hash: "761f9b41ce4136619f89c73746ab176e" } Frame { msec: 5216 - hash: "9860af14b459925078467f334bf41e42" + hash: "cfd826f91f6f880816d505c93a8f125a" } Frame { msec: 5232 - hash: "ae2b8b255d48c12a954f02c63e0d5aa4" + hash: "33fbc77640cc73c17a0f68db5f70ddec" } Frame { msec: 5248 - hash: "c33e9369e76654433e97b2b72cca7911" + hash: "ef925f6709f7603d8acddbbe3e3b0426" } Frame { msec: 5264 - hash: "7fa3de8afdeb61c6e2e87cde2e96152f" + hash: "044c1f37e37a68fbfbb9ddbc2da4300a" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.0.png index 19a7ea1..8d74b8d 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.1.png index e25493f..8a642d2 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.2.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.2.png index 5800e13..5698741 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.2.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.3.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.3.png index 29e8168..7f56f34 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.3.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.4.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.4.png index 19a7ea1..8d74b8d 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.4.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.qml index 955ebbd..a4ba005 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/qt-669.qml @@ -10,95 +10,95 @@ VisualTest { } Frame { msec: 32 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 48 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 64 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 80 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 96 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 112 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 128 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 144 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 160 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 176 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 192 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 208 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 224 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 240 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 256 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 272 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 288 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 304 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 320 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 336 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 352 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 368 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 384 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Key { type: 6 @@ -110,15 +110,15 @@ VisualTest { } Frame { msec: 400 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 416 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 432 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Key { type: 7 @@ -130,27 +130,27 @@ VisualTest { } Frame { msec: 448 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 464 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 480 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 496 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 512 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 528 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Key { type: 6 @@ -162,15 +162,15 @@ VisualTest { } Frame { msec: 544 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Frame { msec: 560 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Frame { msec: 576 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Key { type: 7 @@ -182,27 +182,27 @@ VisualTest { } Frame { msec: 592 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Frame { msec: 608 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Frame { msec: 624 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Frame { msec: 640 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Frame { msec: 656 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Frame { msec: 672 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Key { type: 6 @@ -214,19 +214,19 @@ VisualTest { } Frame { msec: 688 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Frame { msec: 704 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Frame { msec: 720 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Frame { msec: 736 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Key { type: 7 @@ -238,23 +238,23 @@ VisualTest { } Frame { msec: 752 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Frame { msec: 768 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Frame { msec: 784 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Frame { msec: 800 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Frame { msec: 816 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Key { type: 6 @@ -266,19 +266,19 @@ VisualTest { } Frame { msec: 832 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Frame { msec: 848 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Frame { msec: 864 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Frame { msec: 880 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Key { type: 7 @@ -290,19 +290,19 @@ VisualTest { } Frame { msec: 896 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Frame { msec: 912 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Frame { msec: 928 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Frame { msec: 944 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Key { type: 6 @@ -314,7 +314,7 @@ VisualTest { } Frame { msec: 960 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 976 @@ -322,11 +322,11 @@ VisualTest { } Frame { msec: 992 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 1008 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Key { type: 7 @@ -338,23 +338,23 @@ VisualTest { } Frame { msec: 1024 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 1040 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 1056 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 1072 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 1088 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Key { type: 6 @@ -366,15 +366,15 @@ VisualTest { } Frame { msec: 1104 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Frame { msec: 1120 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Frame { msec: 1136 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Key { type: 7 @@ -386,23 +386,23 @@ VisualTest { } Frame { msec: 1152 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Frame { msec: 1168 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Frame { msec: 1184 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Frame { msec: 1200 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Frame { msec: 1216 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Key { type: 6 @@ -414,19 +414,19 @@ VisualTest { } Frame { msec: 1232 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Frame { msec: 1248 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Frame { msec: 1264 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Frame { msec: 1280 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Key { type: 7 @@ -438,19 +438,19 @@ VisualTest { } Frame { msec: 1296 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Frame { msec: 1312 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Frame { msec: 1328 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Frame { msec: 1344 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Key { type: 6 @@ -462,19 +462,19 @@ VisualTest { } Frame { msec: 1360 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 1376 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 1392 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 1408 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Key { type: 7 @@ -486,23 +486,23 @@ VisualTest { } Frame { msec: 1424 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 1440 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 1456 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 1472 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 1488 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Key { type: 6 @@ -514,15 +514,15 @@ VisualTest { } Frame { msec: 1504 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1520 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1536 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Key { type: 7 @@ -534,79 +534,79 @@ VisualTest { } Frame { msec: 1552 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1568 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1584 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1600 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1616 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1632 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1648 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1664 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1680 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1696 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1712 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1728 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1744 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1760 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1776 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1792 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1808 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1824 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Frame { msec: 1840 - hash: "79ad12250ec5379ed79ad01604968fe0" + hash: "da047993eb77afffee6b8f0f210ca2d6" } Key { type: 6 @@ -618,23 +618,23 @@ VisualTest { } Frame { msec: 1856 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 1872 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 1888 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 1904 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 1920 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 1936 @@ -642,15 +642,15 @@ VisualTest { } Frame { msec: 1952 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 1968 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 1984 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Key { type: 7 @@ -662,23 +662,23 @@ VisualTest { } Frame { msec: 2000 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 2016 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 2032 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 2048 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Frame { msec: 2064 - hash: "0a110e257ae412b8440a17be98a6b7f5" + hash: "6f08f7b6337d5ebb305579bb71ba31d8" } Key { type: 6 @@ -690,23 +690,23 @@ VisualTest { } Frame { msec: 2080 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Frame { msec: 2096 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Frame { msec: 2112 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Frame { msec: 2128 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Frame { msec: 2144 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Key { type: 7 @@ -718,23 +718,23 @@ VisualTest { } Frame { msec: 2160 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Frame { msec: 2176 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Frame { msec: 2192 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Frame { msec: 2208 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Frame { msec: 2224 - hash: "162c39ecb50d0a2a03953cca07c493ff" + hash: "b80db720c6371aeaf99f4787fec2c5a3" } Key { type: 6 @@ -746,11 +746,11 @@ VisualTest { } Frame { msec: 2240 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Frame { msec: 2256 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Key { type: 7 @@ -762,23 +762,23 @@ VisualTest { } Frame { msec: 2272 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Frame { msec: 2288 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Frame { msec: 2304 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Frame { msec: 2320 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Frame { msec: 2336 - hash: "0386e92fe3ea2eda40b6f785419cf9f7" + hash: "c8b5e39f4930399527236905cdbcb546" } Key { type: 6 @@ -790,15 +790,15 @@ VisualTest { } Frame { msec: 2352 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 2368 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 2384 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Key { type: 7 @@ -810,55 +810,55 @@ VisualTest { } Frame { msec: 2400 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 2416 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 2432 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 2448 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 2464 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 2480 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 2496 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 2512 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 2528 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 2544 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 2560 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 2576 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Frame { msec: 2592 - hash: "671d2393c31db71d33cd29482294b855" + hash: "3624b85c9362dfeff911cd5426f11ada" } Key { type: 6 @@ -870,23 +870,23 @@ VisualTest { } Frame { msec: 2608 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Frame { msec: 2624 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Frame { msec: 2640 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Frame { msec: 2656 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Frame { msec: 2672 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Key { type: 7 @@ -898,23 +898,23 @@ VisualTest { } Frame { msec: 2688 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Frame { msec: 2704 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Frame { msec: 2720 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Frame { msec: 2736 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Frame { msec: 2752 - hash: "59923f379655d063d27641c88064c071" + hash: "fa22742b8778a3b63ce7d6699dbf7482" } Key { type: 6 @@ -926,15 +926,15 @@ VisualTest { } Frame { msec: 2768 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Frame { msec: 2784 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Frame { msec: 2800 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Key { type: 7 @@ -946,19 +946,19 @@ VisualTest { } Frame { msec: 2816 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Frame { msec: 2832 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Frame { msec: 2848 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Frame { msec: 2864 - hash: "5815bbb03307e196fa567ae273366394" + hash: "b069c174a1b9589ed3137cd01f870b17" } Key { type: 6 @@ -970,7 +970,7 @@ VisualTest { } Frame { msec: 2880 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Frame { msec: 2896 @@ -978,11 +978,11 @@ VisualTest { } Frame { msec: 2912 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Frame { msec: 2928 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Key { type: 7 @@ -994,23 +994,23 @@ VisualTest { } Frame { msec: 2944 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Frame { msec: 2960 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Frame { msec: 2976 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Frame { msec: 2992 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Frame { msec: 3008 - hash: "7f418dcd1c4ef954cbb66e16361b8871" + hash: "53f9d63bacad27fd73c2f84b82599dbc" } Key { type: 6 @@ -1022,23 +1022,23 @@ VisualTest { } Frame { msec: 3024 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3040 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3056 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3072 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3088 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Key { type: 7 @@ -1050,155 +1050,155 @@ VisualTest { } Frame { msec: 3104 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3120 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3136 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3152 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3168 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3184 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3200 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3216 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3232 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3248 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3264 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3280 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3296 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3312 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3328 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3344 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3360 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3376 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3392 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3408 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3424 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3440 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3456 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3472 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3488 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3504 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3520 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3536 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3552 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3568 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3584 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3600 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3616 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3632 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3648 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3664 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3680 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Frame { msec: 3696 - hash: "ff9e0c6cfbbbd68708698875037ac3d3" + hash: "9294b20b7160322e1f2eecaee6ebf856" } Key { type: 6 @@ -1210,27 +1210,27 @@ VisualTest { } Frame { msec: 3712 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3728 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3744 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3760 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3776 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3792 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Key { type: 7 @@ -1242,15 +1242,15 @@ VisualTest { } Frame { msec: 3808 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3824 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3840 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3856 @@ -1258,114 +1258,114 @@ VisualTest { } Frame { msec: 3872 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3888 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3904 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3920 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3936 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3952 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3968 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 3984 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4000 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4016 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4032 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4048 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4064 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4080 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4096 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4112 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4128 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4144 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4160 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4176 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4192 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4208 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4224 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4240 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4256 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4272 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4288 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } Frame { msec: 4304 - hash: "5efa0360e73361a50a5fb4e2b7a650b5" + hash: "80122e3e0d124c01b2769c1c88aa4a13" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.0.png index a6593c9..63b1779 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.1.png index c9e17f9..7924652 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.2.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.2.png index 32a5600..e77bfde 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.2.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.3.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.3.png index a63fd07..67d7e52 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.3.png and b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.qml index c752f0f..ee29db6 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/echoMode.qml @@ -10,7 +10,7 @@ VisualTest { } Frame { msec: 32 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Key { type: 6 @@ -22,83 +22,83 @@ VisualTest { } Frame { msec: 48 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 64 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 80 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 96 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 112 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 128 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 144 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 160 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 176 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 192 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 208 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 224 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 240 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 256 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 272 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 288 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 304 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 320 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 336 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Frame { msec: 352 - hash: "eff6a4491bc00e5570ea73a1371f63fc" + hash: "75bcecaf83ffc9b851894db0be2c02bc" } Key { type: 6 @@ -110,23 +110,23 @@ VisualTest { } Frame { msec: 368 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 384 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 400 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 416 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 432 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Key { type: 7 @@ -138,27 +138,27 @@ VisualTest { } Frame { msec: 448 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 464 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 480 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 496 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 512 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 528 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Key { type: 7 @@ -170,43 +170,43 @@ VisualTest { } Frame { msec: 544 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 560 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 576 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 592 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 608 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 624 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 640 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 656 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 672 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Frame { msec: 688 - hash: "00097f2bb5cf4ea412db48acb93ffd76" + hash: "1a9f4d47e3982ce68eee8446fd735487" } Key { type: 6 @@ -218,23 +218,23 @@ VisualTest { } Frame { msec: 704 - hash: "94e683223900efc840296b86ce934ec3" + hash: "9ab137169f2ea0f4b140a6e668f59ad2" } Frame { msec: 720 - hash: "94e683223900efc840296b86ce934ec3" + hash: "9ab137169f2ea0f4b140a6e668f59ad2" } Frame { msec: 736 - hash: "94e683223900efc840296b86ce934ec3" + hash: "9ab137169f2ea0f4b140a6e668f59ad2" } Frame { msec: 752 - hash: "94e683223900efc840296b86ce934ec3" + hash: "9ab137169f2ea0f4b140a6e668f59ad2" } Frame { msec: 768 - hash: "94e683223900efc840296b86ce934ec3" + hash: "9ab137169f2ea0f4b140a6e668f59ad2" } Key { type: 7 @@ -246,23 +246,23 @@ VisualTest { } Frame { msec: 784 - hash: "94e683223900efc840296b86ce934ec3" + hash: "9ab137169f2ea0f4b140a6e668f59ad2" } Frame { msec: 800 - hash: "94e683223900efc840296b86ce934ec3" + hash: "9ab137169f2ea0f4b140a6e668f59ad2" } Frame { msec: 816 - hash: "94e683223900efc840296b86ce934ec3" + hash: "9ab137169f2ea0f4b140a6e668f59ad2" } Frame { msec: 832 - hash: "94e683223900efc840296b86ce934ec3" + hash: "9ab137169f2ea0f4b140a6e668f59ad2" } Frame { msec: 848 - hash: "94e683223900efc840296b86ce934ec3" + hash: "9ab137169f2ea0f4b140a6e668f59ad2" } Key { type: 6 @@ -274,15 +274,15 @@ VisualTest { } Frame { msec: 864 - hash: "24a0a2f12031b23a98d65178f0d6d58d" + hash: "3080734a2da042b87ef9177cbb314835" } Frame { msec: 880 - hash: "24a0a2f12031b23a98d65178f0d6d58d" + hash: "3080734a2da042b87ef9177cbb314835" } Frame { msec: 896 - hash: "24a0a2f12031b23a98d65178f0d6d58d" + hash: "3080734a2da042b87ef9177cbb314835" } Key { type: 7 @@ -294,19 +294,19 @@ VisualTest { } Frame { msec: 912 - hash: "24a0a2f12031b23a98d65178f0d6d58d" + hash: "3080734a2da042b87ef9177cbb314835" } Frame { msec: 928 - hash: "24a0a2f12031b23a98d65178f0d6d58d" + hash: "3080734a2da042b87ef9177cbb314835" } Frame { msec: 944 - hash: "24a0a2f12031b23a98d65178f0d6d58d" + hash: "3080734a2da042b87ef9177cbb314835" } Frame { msec: 960 - hash: "24a0a2f12031b23a98d65178f0d6d58d" + hash: "3080734a2da042b87ef9177cbb314835" } Frame { msec: 976 @@ -322,19 +322,19 @@ VisualTest { } Frame { msec: 992 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Frame { msec: 1008 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Frame { msec: 1024 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Frame { msec: 1040 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Key { type: 7 @@ -346,51 +346,51 @@ VisualTest { } Frame { msec: 1056 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Frame { msec: 1072 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Frame { msec: 1088 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Frame { msec: 1104 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Frame { msec: 1120 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Frame { msec: 1136 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Frame { msec: 1152 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Frame { msec: 1168 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Frame { msec: 1184 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Frame { msec: 1200 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Frame { msec: 1216 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Frame { msec: 1232 - hash: "7dde2dd8afe7283dd0601b12831f8946" + hash: "e591963b05361595383b1a60eec289cb" } Key { type: 6 @@ -402,15 +402,15 @@ VisualTest { } Frame { msec: 1248 - hash: "e098aa83b3287f67aba57e134e871d62" + hash: "8a528bf3110bace8275f6fe33ce528b9" } Frame { msec: 1264 - hash: "e098aa83b3287f67aba57e134e871d62" + hash: "8a528bf3110bace8275f6fe33ce528b9" } Frame { msec: 1280 - hash: "e098aa83b3287f67aba57e134e871d62" + hash: "8a528bf3110bace8275f6fe33ce528b9" } Key { type: 7 @@ -422,15 +422,15 @@ VisualTest { } Frame { msec: 1296 - hash: "e098aa83b3287f67aba57e134e871d62" + hash: "8a528bf3110bace8275f6fe33ce528b9" } Frame { msec: 1312 - hash: "e098aa83b3287f67aba57e134e871d62" + hash: "8a528bf3110bace8275f6fe33ce528b9" } Frame { msec: 1328 - hash: "e098aa83b3287f67aba57e134e871d62" + hash: "8a528bf3110bace8275f6fe33ce528b9" } Key { type: 6 @@ -442,39 +442,39 @@ VisualTest { } Frame { msec: 1344 - hash: "3f0a9e0cfd6937c943273bc1d39ce336" + hash: "03d56caa0c86b5544d1f5148e0dccd92" } Frame { msec: 1360 - hash: "3f0a9e0cfd6937c943273bc1d39ce336" + hash: "03d56caa0c86b5544d1f5148e0dccd92" } Frame { msec: 1376 - hash: "3f0a9e0cfd6937c943273bc1d39ce336" + hash: "03d56caa0c86b5544d1f5148e0dccd92" } Frame { msec: 1392 - hash: "3f0a9e0cfd6937c943273bc1d39ce336" + hash: "03d56caa0c86b5544d1f5148e0dccd92" } Frame { msec: 1408 - hash: "3f0a9e0cfd6937c943273bc1d39ce336" + hash: "03d56caa0c86b5544d1f5148e0dccd92" } Frame { msec: 1424 - hash: "3f0a9e0cfd6937c943273bc1d39ce336" + hash: "03d56caa0c86b5544d1f5148e0dccd92" } Frame { msec: 1440 - hash: "3f0a9e0cfd6937c943273bc1d39ce336" + hash: "03d56caa0c86b5544d1f5148e0dccd92" } Frame { msec: 1456 - hash: "3f0a9e0cfd6937c943273bc1d39ce336" + hash: "03d56caa0c86b5544d1f5148e0dccd92" } Frame { msec: 1472 - hash: "3f0a9e0cfd6937c943273bc1d39ce336" + hash: "03d56caa0c86b5544d1f5148e0dccd92" } Key { type: 7 @@ -486,7 +486,7 @@ VisualTest { } Frame { msec: 1488 - hash: "3f0a9e0cfd6937c943273bc1d39ce336" + hash: "03d56caa0c86b5544d1f5148e0dccd92" } Key { type: 6 @@ -498,19 +498,19 @@ VisualTest { } Frame { msec: 1504 - hash: "b78259d22dd86c1dd7ba722795e7e155" + hash: "d9aac9ed4ca0ad97b440db3ac7384001" } Frame { msec: 1520 - hash: "b78259d22dd86c1dd7ba722795e7e155" + hash: "d9aac9ed4ca0ad97b440db3ac7384001" } Frame { msec: 1536 - hash: "b78259d22dd86c1dd7ba722795e7e155" + hash: "d9aac9ed4ca0ad97b440db3ac7384001" } Frame { msec: 1552 - hash: "b78259d22dd86c1dd7ba722795e7e155" + hash: "d9aac9ed4ca0ad97b440db3ac7384001" } Key { type: 7 @@ -522,27 +522,27 @@ VisualTest { } Frame { msec: 1568 - hash: "b78259d22dd86c1dd7ba722795e7e155" + hash: "d9aac9ed4ca0ad97b440db3ac7384001" } Frame { msec: 1584 - hash: "b78259d22dd86c1dd7ba722795e7e155" + hash: "d9aac9ed4ca0ad97b440db3ac7384001" } Frame { msec: 1600 - hash: "b78259d22dd86c1dd7ba722795e7e155" + hash: "d9aac9ed4ca0ad97b440db3ac7384001" } Frame { msec: 1616 - hash: "b78259d22dd86c1dd7ba722795e7e155" + hash: "d9aac9ed4ca0ad97b440db3ac7384001" } Frame { msec: 1632 - hash: "b78259d22dd86c1dd7ba722795e7e155" + hash: "d9aac9ed4ca0ad97b440db3ac7384001" } Frame { msec: 1648 - hash: "b78259d22dd86c1dd7ba722795e7e155" + hash: "d9aac9ed4ca0ad97b440db3ac7384001" } Key { type: 6 @@ -554,23 +554,23 @@ VisualTest { } Frame { msec: 1664 - hash: "1402f8182c74124a1fb34ecd78fa4819" + hash: "a2e8a6a742b11b4f30a2d75df14d5f47" } Frame { msec: 1680 - hash: "1402f8182c74124a1fb34ecd78fa4819" + hash: "a2e8a6a742b11b4f30a2d75df14d5f47" } Frame { msec: 1696 - hash: "1402f8182c74124a1fb34ecd78fa4819" + hash: "a2e8a6a742b11b4f30a2d75df14d5f47" } Frame { msec: 1712 - hash: "1402f8182c74124a1fb34ecd78fa4819" + hash: "a2e8a6a742b11b4f30a2d75df14d5f47" } Frame { msec: 1728 - hash: "1402f8182c74124a1fb34ecd78fa4819" + hash: "a2e8a6a742b11b4f30a2d75df14d5f47" } Key { type: 6 @@ -582,7 +582,7 @@ VisualTest { } Frame { msec: 1744 - hash: "93d5b02d77829aef8f8afa0f5a9e93d1" + hash: "021641e69fef4720acf6af15d4a2da82" } Key { type: 7 @@ -594,15 +594,15 @@ VisualTest { } Frame { msec: 1760 - hash: "93d5b02d77829aef8f8afa0f5a9e93d1" + hash: "021641e69fef4720acf6af15d4a2da82" } Frame { msec: 1776 - hash: "93d5b02d77829aef8f8afa0f5a9e93d1" + hash: "021641e69fef4720acf6af15d4a2da82" } Frame { msec: 1792 - hash: "93d5b02d77829aef8f8afa0f5a9e93d1" + hash: "021641e69fef4720acf6af15d4a2da82" } Key { type: 7 @@ -614,19 +614,19 @@ VisualTest { } Frame { msec: 1808 - hash: "93d5b02d77829aef8f8afa0f5a9e93d1" + hash: "021641e69fef4720acf6af15d4a2da82" } Frame { msec: 1824 - hash: "93d5b02d77829aef8f8afa0f5a9e93d1" + hash: "021641e69fef4720acf6af15d4a2da82" } Frame { msec: 1840 - hash: "93d5b02d77829aef8f8afa0f5a9e93d1" + hash: "021641e69fef4720acf6af15d4a2da82" } Frame { msec: 1856 - hash: "93d5b02d77829aef8f8afa0f5a9e93d1" + hash: "021641e69fef4720acf6af15d4a2da82" } Key { type: 6 @@ -638,19 +638,19 @@ VisualTest { } Frame { msec: 1872 - hash: "1f3b2da0ad387187f202857ed9bb4934" + hash: "46ece14e3a61aefcb28b3c888ac7ea59" } Frame { msec: 1888 - hash: "1f3b2da0ad387187f202857ed9bb4934" + hash: "46ece14e3a61aefcb28b3c888ac7ea59" } Frame { msec: 1904 - hash: "1f3b2da0ad387187f202857ed9bb4934" + hash: "46ece14e3a61aefcb28b3c888ac7ea59" } Frame { msec: 1920 - hash: "1f3b2da0ad387187f202857ed9bb4934" + hash: "46ece14e3a61aefcb28b3c888ac7ea59" } Key { type: 7 @@ -666,23 +666,23 @@ VisualTest { } Frame { msec: 1952 - hash: "1f3b2da0ad387187f202857ed9bb4934" + hash: "46ece14e3a61aefcb28b3c888ac7ea59" } Frame { msec: 1968 - hash: "1f3b2da0ad387187f202857ed9bb4934" + hash: "46ece14e3a61aefcb28b3c888ac7ea59" } Frame { msec: 1984 - hash: "1f3b2da0ad387187f202857ed9bb4934" + hash: "46ece14e3a61aefcb28b3c888ac7ea59" } Frame { msec: 2000 - hash: "1f3b2da0ad387187f202857ed9bb4934" + hash: "46ece14e3a61aefcb28b3c888ac7ea59" } Frame { msec: 2016 - hash: "1f3b2da0ad387187f202857ed9bb4934" + hash: "46ece14e3a61aefcb28b3c888ac7ea59" } Key { type: 6 @@ -694,11 +694,11 @@ VisualTest { } Frame { msec: 2032 - hash: "f2fd02bca5f5bf26013957e11d3f11ce" + hash: "ffa55ac51f20c82725cadbb445908fd2" } Frame { msec: 2048 - hash: "f2fd02bca5f5bf26013957e11d3f11ce" + hash: "ffa55ac51f20c82725cadbb445908fd2" } Key { type: 7 @@ -710,11 +710,11 @@ VisualTest { } Frame { msec: 2064 - hash: "f2fd02bca5f5bf26013957e11d3f11ce" + hash: "ffa55ac51f20c82725cadbb445908fd2" } Frame { msec: 2080 - hash: "f2fd02bca5f5bf26013957e11d3f11ce" + hash: "ffa55ac51f20c82725cadbb445908fd2" } Key { type: 6 @@ -726,19 +726,19 @@ VisualTest { } Frame { msec: 2096 - hash: "550f7f60df621c951ce7d5271aabc41f" + hash: "e9e2edb9176cb57506a3f130fca15d1e" } Frame { msec: 2112 - hash: "550f7f60df621c951ce7d5271aabc41f" + hash: "e9e2edb9176cb57506a3f130fca15d1e" } Frame { msec: 2128 - hash: "550f7f60df621c951ce7d5271aabc41f" + hash: "e9e2edb9176cb57506a3f130fca15d1e" } Frame { msec: 2144 - hash: "550f7f60df621c951ce7d5271aabc41f" + hash: "e9e2edb9176cb57506a3f130fca15d1e" } Key { type: 6 @@ -758,19 +758,19 @@ VisualTest { } Frame { msec: 2160 - hash: "d2aca851dde9f96747d3f54fb831144a" + hash: "87c3cf93b47a766d6373ecaec7239dd4" } Frame { msec: 2176 - hash: "d2aca851dde9f96747d3f54fb831144a" + hash: "87c3cf93b47a766d6373ecaec7239dd4" } Frame { msec: 2192 - hash: "d2aca851dde9f96747d3f54fb831144a" + hash: "87c3cf93b47a766d6373ecaec7239dd4" } Frame { msec: 2208 - hash: "d2aca851dde9f96747d3f54fb831144a" + hash: "87c3cf93b47a766d6373ecaec7239dd4" } Key { type: 6 @@ -782,7 +782,7 @@ VisualTest { } Frame { msec: 2224 - hash: "9ed75a4dc5b88fe1c1531833db1dd364" + hash: "1fb4aa190807d169d1ceaff7d9fa92ad" } Key { type: 7 @@ -794,23 +794,23 @@ VisualTest { } Frame { msec: 2240 - hash: "9ed75a4dc5b88fe1c1531833db1dd364" + hash: "1fb4aa190807d169d1ceaff7d9fa92ad" } Frame { msec: 2256 - hash: "9ed75a4dc5b88fe1c1531833db1dd364" + hash: "1fb4aa190807d169d1ceaff7d9fa92ad" } Frame { msec: 2272 - hash: "9ed75a4dc5b88fe1c1531833db1dd364" + hash: "1fb4aa190807d169d1ceaff7d9fa92ad" } Frame { msec: 2288 - hash: "9ed75a4dc5b88fe1c1531833db1dd364" + hash: "1fb4aa190807d169d1ceaff7d9fa92ad" } Frame { msec: 2304 - hash: "9ed75a4dc5b88fe1c1531833db1dd364" + hash: "1fb4aa190807d169d1ceaff7d9fa92ad" } Key { type: 7 @@ -822,11 +822,11 @@ VisualTest { } Frame { msec: 2320 - hash: "9ed75a4dc5b88fe1c1531833db1dd364" + hash: "1fb4aa190807d169d1ceaff7d9fa92ad" } Frame { msec: 2336 - hash: "9ed75a4dc5b88fe1c1531833db1dd364" + hash: "1fb4aa190807d169d1ceaff7d9fa92ad" } Key { type: 6 @@ -838,27 +838,27 @@ VisualTest { } Frame { msec: 2352 - hash: "39079b642f00ea767114d5a831be939a" + hash: "e9cd789b114befb4637fcff39d4413b0" } Frame { msec: 2368 - hash: "39079b642f00ea767114d5a831be939a" + hash: "e9cd789b114befb4637fcff39d4413b0" } Frame { msec: 2384 - hash: "39079b642f00ea767114d5a831be939a" + hash: "e9cd789b114befb4637fcff39d4413b0" } Frame { msec: 2400 - hash: "39079b642f00ea767114d5a831be939a" + hash: "e9cd789b114befb4637fcff39d4413b0" } Frame { msec: 2416 - hash: "39079b642f00ea767114d5a831be939a" + hash: "e9cd789b114befb4637fcff39d4413b0" } Frame { msec: 2432 - hash: "39079b642f00ea767114d5a831be939a" + hash: "e9cd789b114befb4637fcff39d4413b0" } Key { type: 7 @@ -870,19 +870,19 @@ VisualTest { } Frame { msec: 2448 - hash: "39079b642f00ea767114d5a831be939a" + hash: "e9cd789b114befb4637fcff39d4413b0" } Frame { msec: 2464 - hash: "39079b642f00ea767114d5a831be939a" + hash: "e9cd789b114befb4637fcff39d4413b0" } Frame { msec: 2480 - hash: "39079b642f00ea767114d5a831be939a" + hash: "e9cd789b114befb4637fcff39d4413b0" } Frame { msec: 2496 - hash: "39079b642f00ea767114d5a831be939a" + hash: "e9cd789b114befb4637fcff39d4413b0" } Key { type: 6 @@ -894,15 +894,15 @@ VisualTest { } Frame { msec: 2512 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2528 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2544 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Key { type: 7 @@ -914,87 +914,87 @@ VisualTest { } Frame { msec: 2560 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2576 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2592 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2608 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2624 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2640 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2656 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2672 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2688 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2704 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2720 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2736 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2752 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2768 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2784 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2800 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2816 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2832 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2848 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2864 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2880 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2896 @@ -1002,42 +1002,42 @@ VisualTest { } Frame { msec: 2912 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2928 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2944 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2960 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2976 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 2992 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 3008 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 3024 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 3040 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } Frame { msec: 3056 - hash: "92035cf4d7df9e637567c7834f23b030" + hash: "15f91fda9bcc8a2a9ebf3b9c32f61efb" } } -- cgit v0.12 From a3967216f29b3ec8303c7aa71959dd30ae18ecc3 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 3 Dec 2010 11:06:29 +0200 Subject: Unify epocroot usage in createpackage and patch_capabilities scripts Some tools calls required epoc32/tools to be in path and some didn't. Now all tools calls will use tools from under %EPOCROOT%epoc32/tools if EPOCROOT env variable is defined. Reviewed-by: Janne Koskinen --- bin/createpackage.pl | 15 +++++++-------- bin/patch_capabilities.pl | 16 ++++++++++++---- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/bin/createpackage.pl b/bin/createpackage.pl index 6b83585..87ed29e 100755 --- a/bin/createpackage.pl +++ b/bin/createpackage.pl @@ -144,11 +144,13 @@ unless (GetOptions('i|install' => \$install, } my $epocroot = $ENV{EPOCROOT}; +my $epocToolsDir = ""; if ($epocroot ne "") { $epocroot =~ s,\\,/,g; if ($epocroot =~ m,[^/]$,) { $epocroot = $epocroot."/"; } + $epocToolsDir = "${epocroot}epoc32/tools/"; } my $certfilepath = abs_path(dirname($certfile)); @@ -341,7 +343,7 @@ if($stub) { mkpath($systeminstall); my $stub_sis_name = $systeminstall."/".$stub_sis_name; # Create stub SIS. - system ("${epocroot}epoc32/tools/makesis -s $pkgoutput $stub_sis_name"); + system ("${epocToolsDir}makesis -s $pkgoutput $stub_sis_name"); } else { if ($certtext eq "Self Signed" && !@certificates @@ -358,11 +360,8 @@ if($stub) { # Create SIS. # The 'and' is because system uses 0 to indicate success. - if($epocroot) { - system ("${epocroot}epoc32/tools/makesis $pkgoutput $unsigned_sis_name") and die ("ERROR: makesis failed"); - } else { - system ("makesis $pkgoutput $unsigned_sis_name") and die ("ERROR: makesis failed"); - } + system ("${epocToolsDir}makesis $pkgoutput $unsigned_sis_name") and die ("ERROR: makesis failed"); + print("\n"); my $targetInsert = ""; @@ -389,7 +388,7 @@ if($stub) { my $relcert = File::Spec->abs2rel($certificate); my $relkey = File::Spec->abs2rel($key); # The 'and' is because system uses 0 to indicate success. - system ("signsis $unsigned_sis_name $signed_sis_name $relcert $relkey $passphrase") and die ("ERROR: signsis failed"); + system ("${epocToolsDir}signsis $unsigned_sis_name $signed_sis_name $relcert $relkey $passphrase") and die ("ERROR: signsis failed"); # Check if creating signed SIS Succeeded stat($signed_sis_name); @@ -402,7 +401,7 @@ if($stub) { my $relcert = File::Spec->abs2rel(File::Spec->rel2abs( $row->[0], $certfilepath)); my $relkey = File::Spec->abs2rel(File::Spec->rel2abs( $row->[1], $certfilepath)); - system ("signsis $signed_sis_name $signed_sis_name $relcert $relkey $row->[2]"); + system ("${epocToolsDir}signsis $signed_sis_name $signed_sis_name $relcert $relkey $row->[2]"); print ("\tAdditionally signed the SIS with certificate: $row->[0]!\n"); } diff --git a/bin/patch_capabilities.pl b/bin/patch_capabilities.pl index df71339..c3fb89f 100755 --- a/bin/patch_capabilities.pl +++ b/bin/patch_capabilities.pl @@ -78,6 +78,16 @@ sub trim($) { return $string; } +my $epocroot = $ENV{EPOCROOT}; +my $epocToolsDir = ""; +if ($epocroot ne "") { + $epocroot =~ s,\\,/,g; + if ($epocroot =~ m,[^/]$,) { + $epocroot = $epocroot."/"; + } + $epocToolsDir = "${epocroot}epoc32/tools/"; +} + my $nullDevice = "/dev/null"; $nullDevice = "NUL" if ($^O =~ /MSWin/); @@ -237,7 +247,7 @@ if (@ARGV) } print ("\n"); - my $baseCommandToExecute = "elftran -vid 0x0 -capability \"%s\" "; + my $baseCommandToExecute = "${epocToolsDir}elftran -vid 0x0 -capability \"%s\" "; # Actually set the capabilities of the listed binaries. foreach my $binaryPath(@binaries) @@ -256,7 +266,7 @@ if (@ARGV) # Test which capabilities are present and then restrict them to the allowed set. # This avoid raising the capabilities of apps that already have none. my $dllCaps; - open($dllCaps, "elftran -dump s $binaryPath |") or die ("ERROR: Could not execute elftran"); + open($dllCaps, "${epocToolsDir}elftran -dump s $binaryPath |") or die ("ERROR: Could not execute elftran"); my $capsFound = 0; my $originalVid; my @capabilitiesToSet; @@ -329,8 +339,6 @@ if (@ARGV) system ("$commandToExecute > $nullDevice"); $somethingPatched = true; } - ## Create another command line to check that the set capabilities are correct. - #$commandToExecute = "elftran -dump s ".$binaryPath; } if ($checkFailed) { -- cgit v0.12 From 9988c66e0bc1877d27bb89fbf034bb0e05091a52 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 3 Dec 2010 10:44:54 +0000 Subject: Fix compile error Missing QT_BEGIN_NAMESPACE caused error when the namespace macros are defined. Reviewed-by: mread --- src/corelib/kernel/qsystemerror.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/kernel/qsystemerror.cpp b/src/corelib/kernel/qsystemerror.cpp index d2350b5..953ed95 100644 --- a/src/corelib/kernel/qsystemerror.cpp +++ b/src/corelib/kernel/qsystemerror.cpp @@ -51,6 +51,8 @@ #include #endif +QT_BEGIN_NAMESPACE + #if !defined(Q_OS_WIN) && !defined(QT_NO_THREAD) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) && \ defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L namespace { -- cgit v0.12 From 2eec8cbb2227db6e84a268d53591dd2ef026cbeb Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Fri, 3 Dec 2010 13:38:11 +0100 Subject: purge vestiges of imageformat-plugins The imageformat-plugins variable is never referenced by the .pr[io] for building Qt. Its presence in configure.exe appears to be a vestige of an earlier state of affairs. As a reminder, jpeg, mng, tiff and gif can be built into QtGui or built as plugins. The default is plugin. During configuration, this can be overridden by adding, for example, "no-jpeg" to disable support altogether or "jpeg" to build into QtGui. Merge-request: 961 Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 8 -------- tools/configure/configureapp.h | 2 -- 2 files changed, 10 deletions(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index f4fd7c6..9649aba 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -2471,15 +2471,11 @@ void Configure::generateOutputVars() qtConfig += "no-gif"; else if (dictionary[ "GIF" ] == "yes") qtConfig += "gif"; - else if (dictionary[ "GIF" ] == "plugin") - qmakeFormatPlugins += "gif"; if (dictionary[ "TIFF" ] == "no") qtConfig += "no-tiff"; else if (dictionary[ "TIFF" ] == "yes") qtConfig += "tiff"; - else if (dictionary[ "TIFF" ] == "plugin") - qmakeFormatPlugins += "tiff"; if (dictionary[ "LIBTIFF" ] == "system") qtConfig += "system-tiff"; @@ -2487,8 +2483,6 @@ void Configure::generateOutputVars() qtConfig += "no-jpeg"; else if (dictionary[ "JPEG" ] == "yes") qtConfig += "jpeg"; - else if (dictionary[ "JPEG" ] == "plugin") - qmakeFormatPlugins += "jpeg"; if (dictionary[ "LIBJPEG" ] == "system") qtConfig += "system-jpeg"; @@ -2807,8 +2801,6 @@ void Configure::generateOutputVars() qmakeVars += QString("styles += ") + qmakeStyles.join(" "); if (!qmakeStylePlugins.isEmpty()) qmakeVars += QString("style-plugins += ") + qmakeStylePlugins.join(" "); - if (!qmakeFormatPlugins.isEmpty()) - qmakeVars += QString("imageformat-plugins += ") + qmakeFormatPlugins.join(" "); if (dictionary["QMAKESPEC"].endsWith("-g++")) { QString includepath = qgetenv("INCLUDE"); diff --git a/tools/configure/configureapp.h b/tools/configure/configureapp.h index b3c07f7..32d1860 100644 --- a/tools/configure/configureapp.h +++ b/tools/configure/configureapp.h @@ -122,8 +122,6 @@ private: QStringList qmakeStyles; QStringList qmakeStylePlugins; - QStringList qmakeFormatPlugins; - QStringList qmakeVars; QStringList qmakeDefines; // makeList[0] for qt and qtmain -- cgit v0.12 From c343e2139b1764008b812ee6cc3a2a980fa4d147 Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Tue, 30 Nov 2010 10:20:37 +0000 Subject: QGraphicsLayoutItem - fix invalidating sizehint-with-constraints cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Jan-Arve Sæther --- src/gui/graphicsview/qgraphicslayout.cpp | 7 +++++-- src/gui/graphicsview/qgraphicslayoutitem.cpp | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/gui/graphicsview/qgraphicslayout.cpp index 86b4589..3e95735 100644 --- a/src/gui/graphicsview/qgraphicslayout.cpp +++ b/src/gui/graphicsview/qgraphicslayout.cpp @@ -307,10 +307,13 @@ void QGraphicsLayout::invalidate() // does not call the base implementation? In addition, updateGeometry() // does more than we need. layoutItem->d_func()->sizeHintCacheDirty = true; - layoutItem = layoutItem->parentLayoutItem(); + layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; + layoutItem = layoutItem->parentLayoutItem(); } - if (layoutItem) + if (layoutItem) { layoutItem->d_func()->sizeHintCacheDirty = true; + layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; + } bool postIt = layoutItem ? !layoutItem->isLayout() : false; if (postIt) { diff --git a/src/gui/graphicsview/qgraphicslayoutitem.cpp b/src/gui/graphicsview/qgraphicslayoutitem.cpp index 016cfbf..df13039 100644 --- a/src/gui/graphicsview/qgraphicslayoutitem.cpp +++ b/src/gui/graphicsview/qgraphicslayoutitem.cpp @@ -128,6 +128,7 @@ QGraphicsLayoutItemPrivate::~QGraphicsLayoutItemPrivate() void QGraphicsLayoutItemPrivate::init() { sizeHintCacheDirty = true; + sizeHintWithConstraintCacheDirty = true; sizePolicy = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); } @@ -828,6 +829,7 @@ void QGraphicsLayoutItem::updateGeometry() { Q_D(QGraphicsLayoutItem); d->sizeHintCacheDirty = true; + d->sizeHintWithConstraintCacheDirty = true; } /*! -- cgit v0.12 From 401ce2a3be40047bdbc3e66be1d88e371a316e16 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 24 Nov 2010 12:47:25 +0100 Subject: build lrelease as part of the "libs" part. currently it is a bootstrapped tool like moc, rcc and uic in src/tools/, so just force it into the same group. every qt build includes the libs part, so this will resolve the translation part's dependency. --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 059aa1a..e5f5745 100755 --- a/configure +++ b/configure @@ -8530,8 +8530,8 @@ PART_ROOTS= for part in $CFG_BUILD_PARTS; do case "$part" in tools) PART_ROOTS="$PART_ROOTS tools" ;; - libs) PART_ROOTS="$PART_ROOTS src" ;; - translations) PART_ROOTS="$PART_ROOTS tools/linguist/lrelease translations" ;; + libs) PART_ROOTS="$PART_ROOTS src tools/linguist/lrelease" ;; + translations) PART_ROOTS="$PART_ROOTS translations" ;; examples) PART_ROOTS="$PART_ROOTS examples demos" ;; *) ;; esac -- cgit v0.12 From 64836cf058266ac6251d6ff9ae24df655159ac27 Mon Sep 17 00:00:00 2001 From: Oleh Vasyura Date: Mon, 22 Nov 2010 15:26:06 +0200 Subject: Synchronized configure.exe OpenGL options with Unix configure Windows configure tool and Linux configure script use different options for OpenGL modules. Windows configure tool uses -opengl-es-cm and -opengl-es-2. Linux configure script uses -opengl where can be as "desktop", "es1", "es2" and are more common. Windows configure tool is changed to understand Linux OpenGL configure options as well. The old options are retained for compatibility but not documented any more. Reviewed-by: ossi --- tools/configure/configureapp.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 9649aba..050ad62 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -741,6 +741,23 @@ void Configure::parseCmdLine() } else if (configCmdLine.at(i) == "-opengl-es-2") { dictionary[ "OPENGL" ] = "yes"; dictionary[ "OPENGL_ES_2" ] = "yes"; + } else if (configCmdLine.at(i) == "-opengl") { + dictionary[ "OPENGL" ] = "yes"; + i++; + if (i == argCount) + break; + + if (configCmdLine.at(i) == "es1") { + dictionary[ "OPENGL_ES_CM" ] = "yes"; + } else if ( configCmdLine.at(i) == "es2" ) { + dictionary[ "OPENGL_ES_2" ] = "yes"; + } else if ( configCmdLine.at(i) == "desktop" ) { + dictionary[ "OPENGL_ES_2" ] = "yes"; + } else { + cout << "Argument passed to -opengl option is not valid." << endl; + dictionary[ "DONE" ] = "error"; + break; + } } // OpenVG Support ------------------------------------------- @@ -1735,6 +1752,11 @@ bool Configure::displayHelp() desc("QT3SUPPORT", "no","-no-qt3support", "Disables the Qt 3 support functionality.\n"); desc("OPENGL", "no","-no-opengl", "Disables OpenGL functionality\n"); + desc("OPENGL", "no","-opengl ", "Enable OpenGL support with specified API version.\n" + "Available values for :"); + desc("", "", "", " desktop - Enable support for Desktop OpenGL", ' '); + desc("OPENGL_ES_CM", "no", "", " es1 - Enable support for OpenGL ES Common Profile", ' '); + desc("OPENGL_ES_2", "no", "", " es2 - Enable support for OpenGL ES 2.0", ' '); desc("OPENVG", "no","-no-openvg", "Disables OpenVG functionality\n"); desc("OPENVG", "yes","-openvg", "Enables OpenVG functionality"); @@ -1895,8 +1917,7 @@ bool Configure::displayHelp() desc("CETEST", "no", "-no-cetest", "Do not compile Windows CE remote test application"); desc("CETEST", "yes", "-cetest", "Compile Windows CE remote test application"); desc( "-signature ", "Use file for signing the target project"); - desc("OPENGL_ES_CM", "no", "-opengl-es-cm", "Enable support for OpenGL ES Common"); - desc("OPENGL_ES_2", "no", "-opengl-es-2", "Enable support for OpenGL ES 2.0"); + desc("DIRECTSHOW", "no", "-phonon-wince-ds9", "Enable Phonon Direct Show 9 backend for Windows CE"); // Qt\Symbian only options go below here ----------------------------------------------------------------------------- -- cgit v0.12 From 0359135db3ece1eced29b7c867c10f9bd3b7c4bf Mon Sep 17 00:00:00 2001 From: Oleh Vasyura Date: Wed, 17 Nov 2010 14:31:29 +0200 Subject: Adding -dont-process option to Unix configure script This option is supported by Windows configure tool and used in Symbian releases. Reviewed-by: ossi --- configure | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/configure b/configure index e5f5745..5687505 100755 --- a/configure +++ b/configure @@ -800,6 +800,7 @@ CFG_ALSA=auto CFG_PULSEAUDIO=auto CFG_COREWLAN=auto CFG_ICD=auto +CFG_NOPROCESS=no # initalize variables used for installation QT_INSTALL_PREFIX= @@ -2236,6 +2237,12 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; + dont-process) + CFG_NOPROCESS=yes + ;; + process) + CFG_NOPROCESS=no + ;; audio-backend) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_AUDIO_BACKEND="$VAL" @@ -8397,11 +8404,13 @@ EXEC="" #------------------------------------------------------------------------------- echo "Finding project files. Please wait..." -"$outpath/bin/qmake" -prl -r "${relpath}/projects.pro" -if [ -f "${relpath}/projects.pro" ]; then - mkfile="${outpath}/Makefile" - [ -f "$mkfile" ] && chmod +w "$mkfile" - QTDIR="$outpath" "$outpath/bin/qmake" -spec "$XQMAKESPEC" "${relpath}/projects.pro" -o "$mkfile" +if [ "$CFG_NOPROCESS" != "yes" ]; then + "$outpath/bin/qmake" -prl -r "${relpath}/projects.pro" + if [ -f "${relpath}/projects.pro" ]; then + mkfile="${outpath}/Makefile" + [ -f "$mkfile" ] && chmod +w "$mkfile" + QTDIR="$outpath" "$outpath/bin/qmake" -spec "$XQMAKESPEC" "${relpath}/projects.pro" -o "$mkfile" + fi fi # .projects -> projects to process @@ -8558,13 +8567,17 @@ for file in .projects .projects.3; do *winmain/winmain.pro) [ "$XPLATFORM_MINGW" = "yes" ] || continue SPEC=$XQMAKESPEC ;; - *s60main/s60main.pro) if [ -z "`echo "$XPLATFORM" | grep "symbian" >/dev/null`" ]; then + *s60main/s60main.pro) if [ "$CFG_NOPROCESS" = "yes" ] || [ -z "`echo "$XPLATFORM" | grep "symbian" >/dev/null`"]; then continue fi;; *examples/activeqt/*) continue ;; */qmake/qmake.pro) continue ;; *tools/bootstrap*|*tools/moc*|*tools/rcc*|*tools/uic*|*linguist/lrelease*) SPEC=$QMAKESPEC ;; - *) SPEC=$XQMAKESPEC ;; + *) if [ "$CFG_NOPROCESS" = "yes" ]; then + continue + else + SPEC=$XQMAKESPEC + fi;; esac dir=`dirname "$a" | sed -e "s;$sepath;.;g"` test -d "$dir" || mkdir -p "$dir" -- cgit v0.12 From 62385d41ba287908439fb97ab079951e136a9039 Mon Sep 17 00:00:00 2001 From: Oleh Vasyura Date: Wed, 17 Nov 2010 14:34:30 +0200 Subject: VFP type on ARM option in Linux configure script Windows configuration tool uses -fpu option for VFP types. This option is used in Symbian releases but is not supported by Linux configure script. Reviewed-by: ossi --- configure | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 5687505..6eb2a99 100755 --- a/configure +++ b/configure @@ -840,6 +840,9 @@ QT_LIBS_GLIB= QT_CFLAGS_GSTREAMER= QT_LIBS_GSTREAMER= +#flag for Symbian fpu settings +QT_CFLAGS_FPU= + # flags for libconnsettings0 (used for Maemo ICD bearer management plugin) QT_CFLAGS_CONNSETTINGS= QT_LIBS_CONNSETTINGS= @@ -1072,6 +1075,16 @@ while [ "$#" -gt 0 ]; do VAL=`echo $1 | sed 's,-D,,'` fi ;; + -fpu) + VAR="fpu" + # this option may or may not be followed by an argument + if [ -z "$2" ] || echo "$2" | grep '^-' >/dev/null 2>&1; then + VAL=no + else + shift + VAL=$1 + fi + ;; -I?*|-I) VAR="add_ipath" if [ "$1" = "-I" ]; then @@ -2250,6 +2263,11 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; + fpu) + if [ "$VAL" != "no" ]; then + QT_CFLAGS_FPU=$VAL + fi + ;; *) UNKNOWN_OPT=yes ;; @@ -7944,6 +7962,12 @@ if [ "$CFG_DEV" = "yes" ]; then QT_CONFIG="$QT_CONFIG private_tests" fi +if [ -z "$QT_CFLAGS_FPU" ]; then + if echo "$XPLATFORM" | grep "symbian-sbsv2" > /dev/null 2>&1; then + QT_CFLAGS_FPU=softvfp + fi +fi + # Make the application arch follow the Qt arch for single arch builds. # (for multiple-arch builds, set CONFIG manually in the application .pro file) if [ `echo "$CFG_MAC_ARCHS" | wc -w` -eq 1 ]; then @@ -7977,10 +8001,11 @@ if [ -n "$QT_GCC_MAJOR_VERSION" ]; then echo "QT_GCC_MINOR_VERSION = $QT_GCC_MINOR_VERSION" >> "$QTCONFIG.tmp" echo "QT_GCC_PATCH_VERSION = $QT_GCC_PATCH_VERSION" >> "$QTCONFIG.tmp" fi -if echo "$XPLATFORM" | grep "symbian-sbsv2" > /dev/null 2>&1; then +if [ -n "$QT_CFLAGS_FPU" ]; then echo "#Qt for symbian FPU settings" >> "$QTCONFIG.tmp" - echo "MMP_RULES += \"ARMFPU softvfp\"" >> "$QTCONFIG.tmp" + echo "MMP_RULES += \"ARMFPU $QT_CFLAGS_FPU\"" >> "$QTCONFIG.tmp" fi + # replace qconfig.pri if it differs from the newly created temp file if cmp -s "$QTCONFIG.tmp" "$QTCONFIG"; then rm -f "$QTCONFIG.tmp" -- cgit v0.12 From b611d84da963372b180b98e0e76761b60f7f23f4 Mon Sep 17 00:00:00 2001 From: Oleh Vasyura Date: Mon, 22 Nov 2010 15:26:06 +0200 Subject: Disable OpenGL on Symbian only by default instead of always Reviewed-by: ossi --- configure | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 6eb2a99..9ffb8a2 100755 --- a/configure +++ b/configure @@ -6670,10 +6670,12 @@ else QCONFIG_FLAGS="$QCONFIG_FLAGS QT_STYLE_S60" fi -# Disable OpenGL on Symbian. +# Just check if OpenGL is not set by command argumets for Symbian. case "$XPLATFORM" in symbian*) - CFG_OPENGL="no" + if [ "$CFG_OPENGL" = "auto" ]; then + CFG_OPENGL="no" + fi ;; esac -- cgit v0.12 From 3f517783d4ce31f970e6e1f2d4ff5add9073da3d Mon Sep 17 00:00:00 2001 From: Oleh Vasyura Date: Wed, 24 Nov 2010 12:29:59 +0100 Subject: Enable Phonon on Symbian by default. Always enable Phonon on Symbian unless it was explicitly disabled. Reviewed-by: ossi --- configure | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure b/configure index 9ffb8a2..86c14dd 100755 --- a/configure +++ b/configure @@ -4903,6 +4903,9 @@ case "$XPLATFORM" in *symbian*) if [ "$CFG_LARGEFILE" = auto ]; then CFG_LARGEFILE=no fi + if [ "$CFG_PHONON" = auto ]; then + CFG_PHONON=yes + fi if test -z "$EPOCROOT"; then echo "Please export EPOCROOT. It should point to the sdk install dir" -- cgit v0.12 From f424c3460f135aee2facc111869b678d65f125a6 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 22 Nov 2010 12:08:39 +0100 Subject: fix misleading uppercasing deprecation warning don't complain about uppercasing in the function's name if the real problem is that it's not defined at all. this is also slighly more efficient, as we try to lowercase only as a fallback now. Reviewed-by: joerg --- qmake/project.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qmake/project.cpp b/qmake/project.cpp index 2586c57..d967a63 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -1813,11 +1813,10 @@ QMakeProject::doProjectExpand(QString func, QList args_list, for(int i = 0; i < args_list.size(); ++i) args += args_list[i].join(QString(Option::field_sep)); - QString lfunc = func.toLower(); - if (!lfunc.isSharedWith(func)) + ExpandFunc func_t = qmake_expandFunctions().value(func); + if (!func_t && (func_t = qmake_expandFunctions().value(func.toLower()))) warn_msg(WarnDeprecated, "%s:%d: Using uppercased builtin functions is deprecated.", parser.file.toLatin1().constData(), parser.line_no); - ExpandFunc func_t = qmake_expandFunctions().value(lfunc); debug_msg(1, "Running project expand: %s(%s) [%d]", func.toLatin1().constData(), args.join("::").toLatin1().constData(), func_t); -- cgit v0.12 From b552f7c8b5cdc455b87a2688ac0df47fcdf7ac35 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 3 Dec 2010 13:54:22 +0100 Subject: rebuild configure --- configure.exe | Bin 1325568 -> 1325568 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/configure.exe b/configure.exe index f8d520a..068701f 100755 Binary files a/configure.exe and b/configure.exe differ -- cgit v0.12 From d1f9a534da288884f443a975f428b0cfe0a7b29b Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Fri, 3 Dec 2010 14:48:53 +0100 Subject: Touch events do not work on Mac OS 10.5 --- tests/auto/qscroller/tst_qscroller.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/auto/qscroller/tst_qscroller.cpp b/tests/auto/qscroller/tst_qscroller.cpp index 61d3980..4179fee 100644 --- a/tests/auto/qscroller/tst_qscroller.cpp +++ b/tests/auto/qscroller/tst_qscroller.cpp @@ -382,10 +382,13 @@ void tst_QScroller::scrollTo() void tst_QScroller::scroll() { -#ifndef QT_NO_GESTURES +#if defined(Q_OS_MACX) && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6) + QSKIP("Mac OS X < 10.6 does not support QTouchEvents"); + return; +#endif +#ifndef QT_NO_GESTURES // -- good case. normal scroll - tst_QScrollerWidget *sw = new tst_QScrollerWidget(); sw->scrollArea = QRectF(0, 0, 1000, 1000); QScroller::grabGesture(sw, QScroller::TouchGesture); @@ -426,6 +429,11 @@ void tst_QScroller::scroll() void tst_QScroller::overshoot() { +#if defined(Q_OS_MACX) && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6) + QSKIP("Mac OS X < 10.6 does not support QTouchEvents"); + return; +#endif + #ifndef QT_NO_GESTURES tst_QScrollerWidget *sw = new tst_QScrollerWidget(); sw->scrollArea = QRectF(0, 0, 1000, 1000); -- cgit v0.12 From 205d607c3387d074fb87f8deb77a8f515ae2e189 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Sat, 4 Dec 2010 00:13:34 +0100 Subject: Make it compile on Mac OS X 10.5 --- tests/auto/qscroller/tst_qscroller.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qscroller/tst_qscroller.cpp b/tests/auto/qscroller/tst_qscroller.cpp index 4179fee..b4e4ddf 100644 --- a/tests/auto/qscroller/tst_qscroller.cpp +++ b/tests/auto/qscroller/tst_qscroller.cpp @@ -383,7 +383,7 @@ void tst_QScroller::scrollTo() void tst_QScroller::scroll() { #if defined(Q_OS_MACX) && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6) - QSKIP("Mac OS X < 10.6 does not support QTouchEvents"); + QSKIP("Mac OS X < 10.6 does not support QTouchEvents", SkipAll); return; #endif @@ -430,7 +430,7 @@ void tst_QScroller::scroll() void tst_QScroller::overshoot() { #if defined(Q_OS_MACX) && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6) - QSKIP("Mac OS X < 10.6 does not support QTouchEvents"); + QSKIP("Mac OS X < 10.6 does not support QTouchEvents", SkipAll); return; #endif -- cgit v0.12 From 53dd7206a7a2ba4393d558bf76fa23f4a4e05183 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Tue, 30 Nov 2010 23:00:07 +0100 Subject: QScroller merge, part 2 This merge consists of a QScroller based Flickable/Listview/Gridview replacement for QML. The complete history is in http://scm.dev.nokia.troll.no/projects/qt/repos/rgriebls-qt-flickgesture/logs/4.7-flickgesture (part 1 is the actual QScroller implementation / part 3 is QWebView support) Task-number: QTBUG-13390 Reviewed-by: Ralf Engels --- .../graphicsitems/qdeclarativeflickable.cpp | 1169 +++++----------- .../graphicsitems/qdeclarativeflickable_p.h | 22 +- .../graphicsitems/qdeclarativeflickable_p_p.h | 103 +- .../graphicsitems/qdeclarativegridview.cpp | 1202 +++++++--------- .../graphicsitems/qdeclarativegridview_p.h | 9 +- .../graphicsitems/qdeclarativelistview.cpp | 1428 +++++++++----------- .../graphicsitems/qdeclarativelistview_p.h | 9 +- .../tst_qdeclarativeflickable.cpp | 4 +- .../tst_qdeclarativegridview.cpp | 2 + .../tst_qdeclarativelistview.cpp | 8 +- 10 files changed, 1530 insertions(+), 2426 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 98c213c..96f54a8 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -44,14 +44,12 @@ #include #include #include -#include -QT_BEGIN_NAMESPACE +#include +#include -// FlickThreshold determines how far the "mouse" must have moved -// before we perform a flick. -static const int FlickThreshold = 20; +QT_BEGIN_NAMESPACE QDeclarativeFlickableVisibleArea::QDeclarativeFlickableVisibleArea(QDeclarativeFlickable *parent) : QObject(parent), flickable(parent), m_xPosition(0.), m_widthRatio(0.) @@ -79,6 +77,11 @@ qreal QDeclarativeFlickableVisibleArea::yPosition() const return m_yPosition; } +/*! \internal + Updates the page position and ratio values and sends out the appropriate position + and ratio changed signals. + Will be called by updateBeginningEnd. +*/ void QDeclarativeFlickableVisibleArea::updateVisible() { QDeclarativeFlickablePrivate *p = static_cast(QGraphicsItemPrivate::get(flickable)); @@ -90,9 +93,11 @@ void QDeclarativeFlickableVisibleArea::updateVisible() // Vertical const qreal viewheight = flickable->height(); - const qreal maxyextent = -flickable->maxYExtent() + flickable->minYExtent(); - qreal pagePos = (-p->vData.move.value() + flickable->minYExtent()) / (maxyextent + viewheight); - qreal pageSize = viewheight / (maxyextent + viewheight); + const qreal maxyextent = flickable->maxYExtent(); + qreal pagePos = (p->contentItem->pos().y() + flickable->minYExtent()) / maxyextent; + qreal pageSize = viewheight / maxyextent; + + // qDebug() << "updateVisible" << viewheight << "ext:" << flickable->minYExtent() <<"-"<maxYExtent() << "pagesize:"<width(); - const qreal maxxextent = -flickable->maxXExtent() + flickable->minXExtent(); - pagePos = (-p->hData.move.value() + flickable->minXExtent()) / (maxxextent + viewwidth); - pageSize = viewwidth / (maxxextent + viewwidth); + const qreal maxxextent = flickable->maxXExtent(); + pagePos = (p->contentItem->pos().x() + flickable->minXExtent()) / maxxextent; + pageSize = viewwidth / maxxextent; if (pageSize != m_widthRatio) { m_widthRatio = pageSize; @@ -131,15 +136,19 @@ void QDeclarativeFlickableVisibleArea::updateVisible() QDeclarativeFlickablePrivate::QDeclarativeFlickablePrivate() : contentItem(new QDeclarativeItem) - , hData(this, &QDeclarativeFlickablePrivate::setRoundedViewportX) - , vData(this, &QDeclarativeFlickablePrivate::setRoundedViewportY) - , flickingHorizontally(false), flickingVertically(false) - , hMoved(false), vMoved(false) - , movingHorizontally(false), movingVertically(false) - , stealMouse(false), pressed(false), interactive(true), calcVelocity(false) - , deceleration(500), maxVelocity(2000), reportedVelocitySmoothing(100) - , delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(600) - , vTime(0), visibleArea(0) + , updateScrollerValuesRequested(false) + , duringScrollEvent(false) + , isUserGenerated(false) + , isFlicking(false) + , isMoving(false) + , movingHorizontally(false) + , movingVertically(false) + , atBeginningX(true) + , atBeginningY(true) + , atEndX(false) + , atEndY(false) + , interactive(true) + , visibleArea(0) , flickableDirection(QDeclarativeFlickable::AutoFlickDirection) , boundsBehavior(QDeclarativeFlickable::DragAndOvershootBounds) { @@ -150,45 +159,39 @@ void QDeclarativeFlickablePrivate::init() Q_Q(QDeclarativeFlickable); QDeclarative_setParent_noEvent(contentItem, q); contentItem->setParentItem(q); - static int timelineUpdatedIdx = -1; - static int timelineCompletedIdx = -1; - static int flickableTickedIdx = -1; - static int flickableMovementEndingIdx = -1; - if (timelineUpdatedIdx == -1) { - timelineUpdatedIdx = QDeclarativeTimeLine::staticMetaObject.indexOfSignal("updated()"); - timelineCompletedIdx = QDeclarativeTimeLine::staticMetaObject.indexOfSignal("completed()"); - flickableTickedIdx = QDeclarativeFlickable::staticMetaObject.indexOfSlot("ticked()"); - flickableMovementEndingIdx = QDeclarativeFlickable::staticMetaObject.indexOfSlot("movementEnding()"); - } - QMetaObject::connect(&timeline, timelineUpdatedIdx, - q, flickableTickedIdx, Qt::DirectConnection); - QMetaObject::connect(&timeline, timelineCompletedIdx, - q, flickableMovementEndingIdx, Qt::DirectConnection); + q->setAcceptedMouseButtons(Qt::LeftButton); - q->setFiltersChildEvents(true); - QDeclarativeItemPrivate *viewportPrivate = static_cast(QGraphicsItemPrivate::get(contentItem)); - viewportPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); - lastPosTime.invalidate(); + q->setAcceptTouchEvents(true); + + QScroller::grabGesture(q, QScroller::LeftMouseButtonGesture); + QScroller *scroller = QScroller::scroller(q); + + QScrollerProperties sp = scroller->scrollerProperties(); + sp.setScrollMetric(QScrollerProperties::MousePressEventDelay, 0); + sp.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 1.0); + sp.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 1.0); + scroller->setScrollerProperties(sp); + + QObject::connect(scroller, SIGNAL(stateChanged(QScroller::State)), q, SLOT(scrollerStateChanged(QScroller::State))); } -/* - Returns the amount to overshoot by given a velocity. - Will be roughly in range 0 - size/4 +/*! /internal + Requests a prepare event to be send to the scroller informing it about changed + positions or scroll area bounds. */ -qreal QDeclarativeFlickablePrivate::overShootDistance(qreal velocity, qreal size) +void QDeclarativeFlickablePrivate::updateScrollerValues() { - if (maxVelocity <= 0) - return 0.0; - - velocity = qAbs(velocity); - if (velocity > maxVelocity) - velocity = maxVelocity; - qreal dist = size / 4 * velocity / maxVelocity; - return dist; + Q_Q(QDeclarativeFlickable); + //qDebug() << "DeclarativeFlickablePrivate::updateScrollerValues" << duringScrollEvent; + if (!duringScrollEvent) + QScroller::scroller(q)->resendPrepareEvent(); + else + updateScrollerValuesRequested = true; } void QDeclarativeFlickablePrivate::itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeom, const QRectF &oldGeom) { + // TODO Q_Q(QDeclarativeFlickable); if (item == contentItem) { if (newGeom.x() != oldGeom.x()) @@ -198,149 +201,41 @@ void QDeclarativeFlickablePrivate::itemGeometryChanged(QDeclarativeItem *item, c } } -void QDeclarativeFlickablePrivate::flickX(qreal velocity) -{ - Q_Q(QDeclarativeFlickable); - flick(hData, q->minXExtent(), q->maxXExtent(), q->width(), fixupX_callback, velocity); -} - -void QDeclarativeFlickablePrivate::flickY(qreal velocity) -{ - Q_Q(QDeclarativeFlickable); - flick(vData, q->minYExtent(), q->maxYExtent(), q->height(), fixupY_callback, velocity); -} - -void QDeclarativeFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, - QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity) -{ - Q_Q(QDeclarativeFlickable); - qreal maxDistance = -1; - bool overShoot = boundsBehavior == QDeclarativeFlickable::DragAndOvershootBounds; - // -ve velocity means list is moving up - if (velocity > 0) { - if (data.move.value() < minExtent) - maxDistance = qAbs(minExtent - data.move.value() + (overShoot?overShootDistance(velocity,vSize):0)); - data.flickTarget = minExtent; - } else { - if (data.move.value() > maxExtent) - maxDistance = qAbs(maxExtent - data.move.value()) + (overShoot?overShootDistance(velocity,vSize):0); - data.flickTarget = maxExtent; - } - if (maxDistance > 0) { - qreal v = velocity; - if (maxVelocity != -1 && maxVelocity < qAbs(v)) { - if (v < 0) - v = -maxVelocity; - else - v = maxVelocity; - } - timeline.reset(data.move); - timeline.accel(data.move, v, deceleration, maxDistance); - timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this)); - if (!flickingHorizontally && q->xflick()) { - flickingHorizontally = true; - emit q->flickingChanged(); - emit q->flickingHorizontallyChanged(); - if (!flickingVertically) - emit q->flickStarted(); - } - if (!flickingVertically && q->yflick()) { - flickingVertically = true; - emit q->flickingChanged(); - emit q->flickingVerticallyChanged(); - if (!flickingHorizontally) - emit q->flickStarted(); - } - } else { - timeline.reset(data.move); - fixup(data, minExtent, maxExtent); - } -} - -void QDeclarativeFlickablePrivate::fixupY_callback(void *data) -{ - ((QDeclarativeFlickablePrivate *)data)->fixupY(); -} - -void QDeclarativeFlickablePrivate::fixupX_callback(void *data) -{ - ((QDeclarativeFlickablePrivate *)data)->fixupX(); -} - -void QDeclarativeFlickablePrivate::fixupX() -{ - Q_Q(QDeclarativeFlickable); - fixup(hData, q->minXExtent(), q->maxXExtent()); -} - -void QDeclarativeFlickablePrivate::fixupY() +/*! \internal + Updates the atBeginning and atEnd flags and sends out the changed signals +*/ +void QDeclarativeFlickablePrivate::updateBeginningEnd() { Q_Q(QDeclarativeFlickable); - fixup(vData, q->minYExtent(), q->maxYExtent()); -} -void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent) -{ - if (data.move.value() > minExtent || maxExtent > minExtent) { - timeline.reset(data.move); - if (data.move.value() != minExtent) { - if (fixupDuration) { - qreal dist = minExtent - data.move; - timeline.move(data.move, minExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4); - timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4); - } else { - timeline.set(data.move, minExtent); - } - } - } else if (data.move.value() < maxExtent) { - timeline.reset(data.move); - if (fixupDuration) { - qreal dist = maxExtent - data.move; - timeline.move(data.move, maxExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4); - timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4); - } else { - timeline.set(data.move, minExtent); - } - } - vTime = timeline.time(); -} + bool boundaryChanged = false; -void QDeclarativeFlickablePrivate::updateBeginningEnd() -{ - Q_Q(QDeclarativeFlickable); - bool atBoundaryChange = false; + bool newAtBeginningX = -contentItem->pos().x() <= q->minXExtent(); + bool newAtEndX = -contentItem->pos().x() >= (q->maxXExtent() - width()); + bool newAtBeginningY = -contentItem->pos().y() <= q->minYExtent(); + bool newAtEndY = -contentItem->pos().y() >= (q->maxYExtent() - height()); - // Vertical - const int maxyextent = int(-q->maxYExtent()); - const qreal ypos = -vData.move.value(); - bool atBeginning = (ypos <= -q->minYExtent()); - bool atEnd = (maxyextent <= ypos); - - if (atBeginning != vData.atBeginning) { - vData.atBeginning = atBeginning; - atBoundaryChange = true; + // Horizontal + if (newAtBeginningX != atBeginningX) { + atBeginningX = newAtBeginningX; + boundaryChanged = true; } - if (atEnd != vData.atEnd) { - vData.atEnd = atEnd; - atBoundaryChange = true; + if (newAtEndX != atEndX) { + atEndX = newAtEndX; + boundaryChanged = true; } - // Horizontal - const int maxxextent = int(-q->maxXExtent()); - const qreal xpos = -hData.move.value(); - atBeginning = (xpos <= -q->minXExtent()); - atEnd = (maxxextent <= xpos); - - if (atBeginning != hData.atBeginning) { - hData.atBeginning = atBeginning; - atBoundaryChange = true; + // Vertical + if (newAtBeginningY != atBeginningY) { + atBeginningY = newAtBeginningY; + boundaryChanged = true; } - if (atEnd != hData.atEnd) { - hData.atEnd = atEnd; - atBoundaryChange = true; + if (newAtEndY != atEndY) { + atEndY = newAtEndY; + boundaryChanged = true; } - if (atBoundaryChange) + if (boundaryChanged) emit q->isAtBoundaryChanged(); if (visibleArea) @@ -484,13 +379,14 @@ qreal QDeclarativeFlickable::contentX() const void QDeclarativeFlickable::setContentX(qreal pos) { Q_D(QDeclarativeFlickable); - d->timeline.reset(d->hData.move); - d->vTime = d->timeline.time(); - movementXEnding(); - if (-pos != d->hData.move.value()) { - d->hData.move.setValue(-pos); - viewportMoved(); - } + QScroller::scroller(this)->stop(); + + if (pos == -d->contentItem->x()) + return; + viewportAboutToMove(QPointF(pos, contentY())); + d->contentItem->setX(-pos); + viewportMoved(); + emit contentXChanged(); } qreal QDeclarativeFlickable::contentY() const @@ -502,13 +398,14 @@ qreal QDeclarativeFlickable::contentY() const void QDeclarativeFlickable::setContentY(qreal pos) { Q_D(QDeclarativeFlickable); - d->timeline.reset(d->vData.move); - d->vTime = d->timeline.time(); - movementYEnding(); - if (-pos != d->vData.move.value()) { - d->vData.move.setValue(-pos); - viewportMoved(); - } + QScroller::scroller(this)->stop(); + + if (pos == -d->contentItem->y()) + return; + viewportAboutToMove(QPointF(contentX(), pos)); + d->contentItem->setY(-pos); + viewportMoved(); + emit contentYChanged(); } /*! @@ -535,16 +432,7 @@ void QDeclarativeFlickable::setInteractive(bool interactive) Q_D(QDeclarativeFlickable); if (interactive != d->interactive) { d->interactive = interactive; - if (!interactive && (d->flickingHorizontally || d->flickingVertically)) { - d->timeline.clear(); - d->vTime = d->timeline.time(); - d->flickingHorizontally = false; - d->flickingVertically = false; - emit flickingChanged(); - emit flickingHorizontallyChanged(); - emit flickingVerticallyChanged(); - emit flickEnded(); - } + QScroller::scroller(this)->stop(); emit interactiveChanged(); } } @@ -554,19 +442,15 @@ void QDeclarativeFlickable::setInteractive(bool interactive) \qmlproperty real Flickable::verticalVelocity The instantaneous velocity of movement along the x and y axes, in pixels/sec. - - The reported velocity is smoothed to avoid erratic output. */ qreal QDeclarativeFlickable::horizontalVelocity() const { - Q_D(const QDeclarativeFlickable); - return d->hData.smoothVelocity.value(); + return QScroller::scroller(this)->velocity().x(); } qreal QDeclarativeFlickable::verticalVelocity() const { - Q_D(const QDeclarativeFlickable); - return d->vData.smoothVelocity.value(); + return QScroller::scroller(this)->velocity().y(); } /*! @@ -581,30 +465,25 @@ qreal QDeclarativeFlickable::verticalVelocity() const bool QDeclarativeFlickable::isAtXEnd() const { Q_D(const QDeclarativeFlickable); - return d->hData.atEnd; + return d->atEndX; } bool QDeclarativeFlickable::isAtXBeginning() const { Q_D(const QDeclarativeFlickable); - return d->hData.atBeginning; + return d->atBeginningX; } bool QDeclarativeFlickable::isAtYEnd() const { Q_D(const QDeclarativeFlickable); - return d->vData.atEnd; + return d->atEndY; } bool QDeclarativeFlickable::isAtYBeginning() const { Q_D(const QDeclarativeFlickable); - return d->vData.atBeginning; -} - -void QDeclarativeFlickable::ticked() -{ - viewportMoved(); + return d->atBeginningY; } /*! @@ -639,6 +518,52 @@ QDeclarativeFlickableVisibleArea *QDeclarativeFlickable::visibleArea() return d->visibleArea; } +void QDeclarativeFlickable::scrollerStateChanged(QScroller::State state) +{ + Q_D(QDeclarativeFlickable); + + //qDebug() << "scrollerStateChanged" << int(state); + + switch (state) { + case QScroller::Inactive: + d->isUserGenerated = false; + // fall through + case QScroller::Pressed: + if (d->isMoving) { + d->isMoving = false; + emit movingChanged(); + emit movementEnded(); + } + if (d->isFlicking) { + d->isFlicking = false; + emit flickingChanged(); + emit flickEnded(); + } + break; + + case QScroller::Dragging: + d->isUserGenerated = true; + if (!d->isMoving) { + d->isMoving = true; + emit movingChanged(); + emit movementStarted(); + } + break; + + case QScroller::Scrolling: + QScroller::scroller(this)->resendPrepareEvent(); // sometimes snappoints depend on the scrolling direction. + if (d->isUserGenerated) { + if (!d->isFlicking) { + emit flickStarted(); + emit flickingChanged(); + } + d->isFlicking = true; + } + break; + } +} + + /*! \qmlproperty enumeration Flickable::flickableDirection @@ -669,409 +594,92 @@ void QDeclarativeFlickable::setFlickableDirection(FlickableDirection direction) } } -void QDeclarativeFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event) -{ - if (interactive && timeline.isActive() && (qAbs(hData.velocity) > 10 || qAbs(vData.velocity) > 10)) - stealMouse = true; // If we've been flicked then steal the click. - else - stealMouse = false; - pressed = true; - timeline.clear(); - hData.velocity = 0; - vData.velocity = 0; - hData.dragStartOffset = 0; - vData.dragStartOffset = 0; - lastPos = QPoint(); - QDeclarativeItemPrivate::start(lastPosTime); - pressPos = event->pos(); - hData.pressPos = hData.move.value(); - vData.pressPos = vData.move.value(); - flickingHorizontally = false; - flickingVertically = false; - QDeclarativeItemPrivate::start(pressTime); - QDeclarativeItemPrivate::start(velocityTime); -} - -void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) -{ - Q_Q(QDeclarativeFlickable); - if (!interactive || !lastPosTime.isValid()) - return; - bool rejectY = false; - bool rejectX = false; - - bool stealY = false; - bool stealX = false; - - if (q->yflick()) { - int dy = int(event->pos().y() - pressPos.y()); - if (qAbs(dy) > QApplication::startDragDistance() || QDeclarativeItemPrivate::elapsed(pressTime) > 200) { - if (!vMoved) - vData.dragStartOffset = dy; - qreal newY = dy + vData.pressPos - vData.dragStartOffset; - const qreal minY = q->minYExtent(); - const qreal maxY = q->maxYExtent(); - if (newY > minY) - newY = minY + (newY - minY) / 2; - if (newY < maxY && maxY - minY <= 0) - newY = maxY + (newY - maxY) / 2; - if (boundsBehavior == QDeclarativeFlickable::StopAtBounds && (newY > minY || newY < maxY)) { - rejectY = true; - if (newY < maxY) { - newY = maxY; - rejectY = false; - } - if (newY > minY) { - newY = minY; - rejectY = false; - } - } - if (!rejectY && stealMouse) { - vData.move.setValue(qRound(newY)); - vMoved = true; - } - if (qAbs(dy) > QApplication::startDragDistance()) - stealY = true; - } - } - - if (q->xflick()) { - int dx = int(event->pos().x() - pressPos.x()); - if (qAbs(dx) > QApplication::startDragDistance() || QDeclarativeItemPrivate::elapsed(pressTime) > 200) { - if (!hMoved) - hData.dragStartOffset = dx; - qreal newX = dx + hData.pressPos - hData.dragStartOffset; - const qreal minX = q->minXExtent(); - const qreal maxX = q->maxXExtent(); - if (newX > minX) - newX = minX + (newX - minX) / 2; - if (newX < maxX && maxX - minX <= 0) - newX = maxX + (newX - maxX) / 2; - if (boundsBehavior == QDeclarativeFlickable::StopAtBounds && (newX > minX || newX < maxX)) { - rejectX = true; - if (newX < maxX) { - newX = maxX; - rejectX = false; - } - if (newX > minX) { - newX = minX; - rejectX = false; - } - } - if (!rejectX && stealMouse) { - hData.move.setValue(qRound(newX)); - hMoved = true; - } - - if (qAbs(dx) > QApplication::startDragDistance()) - stealX = true; - } - } - - stealMouse = stealX || stealY; - - if (!lastPos.isNull()) { - qreal elapsed = qreal(QDeclarativeItemPrivate::restart(lastPosTime)) / 1000.; - if (elapsed <= 0) - elapsed = 1; - if (q->yflick()) { - qreal diff = event->pos().y() - lastPos.y(); - // average to reduce the effect of spurious moves - vData.velocity += diff / elapsed; - vData.velocity /= 2; - } - - if (q->xflick()) { - qreal diff = event->pos().x() - lastPos.x(); - // average to reduce the effect of spurious moves - hData.velocity += diff / elapsed; - hData.velocity /= 2; - } - } - - if (rejectY) vData.velocity = 0; - if (rejectX) hData.velocity = 0; - - if (hMoved || vMoved) { - q->movementStarting(); - q->viewportMoved(); - } - - lastPos = event->pos(); -} - -void QDeclarativeFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - Q_Q(QDeclarativeFlickable); - stealMouse = false; - q->setKeepMouseGrab(false); - pressed = false; - if (!lastPosTime.isValid()) - return; - - if (QDeclarativeItemPrivate::elapsed(lastPosTime) > 100) { - // if we drag then pause before release we should not cause a flick. - hData.velocity = 0.0; - vData.velocity = 0.0; - } - - vTime = timeline.time(); - if (qAbs(vData.velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) - flickY(vData.velocity); - else - fixupY(); - - if (qAbs(hData.velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) - flickX(hData.velocity); - else - fixupX(); - - lastPosTime.invalidate(); - - if (!timeline.isActive()) - q->movementEnding(); -} - -void QDeclarativeFlickable::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - Q_D(QDeclarativeFlickable); - if (d->interactive) { - d->handleMousePressEvent(event); - event->accept(); - } else { - QDeclarativeItem::mousePressEvent(event); - } -} - -void QDeclarativeFlickable::mouseMoveEvent(QGraphicsSceneMouseEvent *event) -{ - Q_D(QDeclarativeFlickable); - if (d->interactive) { - d->handleMouseMoveEvent(event); - if (d->stealMouse) - setKeepMouseGrab(true); - event->accept(); - } else { - QDeclarativeItem::mouseMoveEvent(event); - } -} - -void QDeclarativeFlickable::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - Q_D(QDeclarativeFlickable); - if (d->interactive) { - d->clearDelayedPress(); - d->handleMouseReleaseEvent(event); - event->accept(); - ungrabMouse(); - } else { - QDeclarativeItem::mouseReleaseEvent(event); - } -} - -void QDeclarativeFlickable::wheelEvent(QGraphicsSceneWheelEvent *event) -{ - Q_D(QDeclarativeFlickable); - if (!d->interactive) { - QDeclarativeItem::wheelEvent(event); - } else if (yflick()) { - if (event->delta() > 0) - d->vData.velocity = qMax(event->delta() - d->vData.smoothVelocity.value(), qreal(250.0)); - else - d->vData.velocity = qMin(event->delta() - d->vData.smoothVelocity.value(), qreal(-250.0)); - d->flickingVertically = false; - d->flickY(d->vData.velocity); - if (d->flickingVertically) { - d->vMoved = true; - movementStarting(); - } - event->accept(); - } else if (xflick()) { - if (event->delta() > 0) - d->hData.velocity = qMax(event->delta() - d->hData.smoothVelocity.value(), qreal(250.0)); - else - d->hData.velocity = qMin(event->delta() - d->hData.smoothVelocity.value(), qreal(-250.0)); - d->flickingHorizontally = false; - d->flickX(d->hData.velocity); - if (d->flickingHorizontally) { - d->hMoved = true; - movementStarting(); - } - event->accept(); - } else { - QDeclarativeItem::wheelEvent(event); - } -} - -void QDeclarativeFlickablePrivate::captureDelayedPress(QGraphicsSceneMouseEvent *event) -{ - Q_Q(QDeclarativeFlickable); - if (!q->scene() || pressDelay <= 0) - return; - delayedPressTarget = q->scene()->mouseGrabberItem(); - delayedPressEvent = new QGraphicsSceneMouseEvent(event->type()); - delayedPressEvent->setAccepted(false); - for (int i = 0x1; i <= 0x10; i <<= 1) { - if (event->buttons() & i) { - Qt::MouseButton button = Qt::MouseButton(i); - delayedPressEvent->setButtonDownPos(button, event->buttonDownPos(button)); - delayedPressEvent->setButtonDownScenePos(button, event->buttonDownScenePos(button)); - delayedPressEvent->setButtonDownScreenPos(button, event->buttonDownScreenPos(button)); - } - } - delayedPressEvent->setButtons(event->buttons()); - delayedPressEvent->setButton(event->button()); - delayedPressEvent->setPos(event->pos()); - delayedPressEvent->setScenePos(event->scenePos()); - delayedPressEvent->setScreenPos(event->screenPos()); - delayedPressEvent->setLastPos(event->lastPos()); - delayedPressEvent->setLastScenePos(event->lastScenePos()); - delayedPressEvent->setLastScreenPos(event->lastScreenPos()); - delayedPressEvent->setModifiers(event->modifiers()); - delayedPressTimer.start(pressDelay, q); -} - -void QDeclarativeFlickablePrivate::clearDelayedPress() -{ - if (delayedPressEvent) { - delayedPressTimer.stop(); - delete delayedPressEvent; - delayedPressEvent = 0; - } -} - -void QDeclarativeFlickablePrivate::setRoundedViewportX(qreal x) -{ - contentItem->setX(qRound(x)); -} - -void QDeclarativeFlickablePrivate::setRoundedViewportY(qreal y) -{ - contentItem->setY(qRound(y)); -} - -void QDeclarativeFlickable::timerEvent(QTimerEvent *event) +/*! \internal + Returns the minimum horizontal content position. + Note: this function will be overloaded. + */ +qreal QDeclarativeFlickable::minXExtent() const { - Q_D(QDeclarativeFlickable); - if (event->timerId() == d->delayedPressTimer.timerId()) { - d->delayedPressTimer.stop(); - if (d->delayedPressEvent) { - QDeclarativeItem *grabber = scene() ? qobject_cast(scene()->mouseGrabberItem()) : 0; - if (!grabber || grabber != this) { - // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay) - // so we reset the grabber - if (scene()->mouseGrabberItem() == d->delayedPressTarget) - d->delayedPressTarget->ungrabMouse(); - //Use the event handler that will take care of finding the proper item to propagate the event - QApplication::sendEvent(scene(), d->delayedPressEvent); - } - delete d->delayedPressEvent; - d->delayedPressEvent = 0; - } - } + return 0.0; } +/*! \internal + Returns the minimum vertical content position. + Note: this function will be overloaded. + */ qreal QDeclarativeFlickable::minYExtent() const { return 0.0; } - -qreal QDeclarativeFlickable::minXExtent() const +/*! \internal + Returns the maximum horizontal content position. + */ +qreal QDeclarativeFlickable::maxXExtent() const { - return 0.0; + Q_D(const QDeclarativeFlickable); + return qMax(0.0, d->contentItem->width()); } -/* returns -ve */ -qreal QDeclarativeFlickable::maxXExtent() const +/*! \internal + Returns the maximum vertical content position. + */ +qreal QDeclarativeFlickable::maxYExtent() const { - return width() - vWidth(); + Q_D(const QDeclarativeFlickable); + return qMax(0.0, d->contentItem->height()); } -/* returns -ve */ -qreal QDeclarativeFlickable::maxYExtent() const + +/*! \internal + This function is called before the viewport starts to move. + This is a good chance to fill up some buffers. + */ +void QDeclarativeFlickable::viewportAboutToMove(QPointF newPos) { - return height() - vHeight(); + Q_UNUSED(newPos); } +/*! \internal + This function is called after the viewport was moved (and the + move finished) + */ void QDeclarativeFlickable::viewportMoved() { Q_D(QDeclarativeFlickable); - - qreal prevX = d->lastFlickablePosition.x(); - qreal prevY = d->lastFlickablePosition.y(); - d->velocityTimeline.clear(); - if (d->pressed || d->calcVelocity) { - int elapsed = QDeclarativeItemPrivate::restart(d->velocityTime); - if (elapsed > 0) { - qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / elapsed; - qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / elapsed; - d->velocityTimeline.move(d->hData.smoothVelocity, horizontalVelocity, d->reportedVelocitySmoothing); - d->velocityTimeline.move(d->hData.smoothVelocity, 0, d->reportedVelocitySmoothing); - d->velocityTimeline.move(d->vData.smoothVelocity, verticalVelocity, d->reportedVelocitySmoothing); - d->velocityTimeline.move(d->vData.smoothVelocity, 0, d->reportedVelocitySmoothing); - } - } else { - if (d->timeline.time() > d->vTime) { - qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / (d->timeline.time() - d->vTime); - qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / (d->timeline.time() - d->vTime); - d->hData.smoothVelocity.setValue(horizontalVelocity); - d->vData.smoothVelocity.setValue(verticalVelocity); - } - } - - d->lastFlickablePosition = QPointF(d->hData.move.value(), d->vData.move.value()); - - d->vTime = d->timeline.time(); d->updateBeginningEnd(); } void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry, - const QRectF &oldGeometry) + const QRectF &oldGeometry) { Q_D(QDeclarativeFlickable); QDeclarativeItem::geometryChanged(newGeometry, oldGeometry); bool changed = false; if (newGeometry.width() != oldGeometry.width()) { - if (xflick()) - changed = true; - if (d->hData.viewSize < 0) { - d->contentItem->setWidth(width()); - emit contentWidthChanged(); - } - // Make sure that we're entirely in view. - if (!d->pressed && !d->movingHorizontally && !d->movingVertically) { - int oldDuration = d->fixupDuration; - d->fixupDuration = 0; - d->fixupX(); - d->fixupDuration = oldDuration; - } + changed = true; + // strangely this causes problems + // d->contentItem->setWidth(newGeometry.width()); + emit contentWidthChanged(); } if (newGeometry.height() != oldGeometry.height()) { - if (yflick()) - changed = true; - if (d->vData.viewSize < 0) { - d->contentItem->setHeight(height()); - emit contentHeightChanged(); - } - // Make sure that we're entirely in view. - if (!d->pressed && !d->movingHorizontally && !d->movingVertically) { - int oldDuration = d->fixupDuration; - d->fixupDuration = 0; - d->fixupY(); - d->fixupDuration = oldDuration; - } + changed = true; + // strangely this causes problems + // d->contentItem->setHeight(newGeometry.height()); + emit contentHeightChanged(); } - if (changed) - d->updateBeginningEnd(); -} + if (changed) { + QScroller *scroller = QScroller::scroller(this); -void QDeclarativeFlickable::cancelFlick() -{ - Q_D(QDeclarativeFlickable); - d->timeline.reset(d->hData.move); - d->timeline.reset(d->vData.move); - movementEnding(); + //qDebug() << "xxx geometryChanged: "<state() == QScroller::Inactive) + scroller->ensureVisible( QRectF(0.0, 0.0, + d->contentItem->width(), d->contentItem->height() ), 0, 0, 0 ); + else + d->updateScrollerValues(); + d->updateBeginningEnd(); + } } void QDeclarativeFlickablePrivate::data_append(QDeclarativeListProperty *prop, QObject *o) @@ -1157,10 +765,12 @@ QDeclarativeListProperty QDeclarativeFlickable::flickableChildr of the flickable, and flicks will not overshoot. \o Flickable.DragOverBounds - the contents can be dragged beyond the boundary of the Flickable, but flicks will not overshoot. - \o Flickable.DragAndOvershootBounds (default) - the contents can be dragged + \o Flickable.DragAndOvershootBounds - the contents can be dragged beyond the boundary of the Flickable, and can overshoot the boundary when flicked. \endlist + + The default is platform dependant. */ QDeclarativeFlickable::BoundsBehavior QDeclarativeFlickable::boundsBehavior() const { @@ -1174,6 +784,23 @@ void QDeclarativeFlickable::setBoundsBehavior(BoundsBehavior b) if (b == d->boundsBehavior) return; d->boundsBehavior = b; + + QScroller *scroller = QScroller::scroller(this); + QScrollerProperties props = scroller->scrollerProperties(); + if (b == StopAtBounds) { + props.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.0); + props.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.0); + + } else if (b == DragOverBounds) { + props.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 1.0); + props.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.0); + + } else { + props.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 1.0); + props.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 1.0); + } + scroller->setScrollerProperties(props); + emit boundsBehaviorChanged(); } @@ -1197,26 +824,27 @@ void QDeclarativeFlickable::setBoundsBehavior(BoundsBehavior b) qreal QDeclarativeFlickable::contentWidth() const { Q_D(const QDeclarativeFlickable); - return d->hData.viewSize; + return d->contentItem->width(); } void QDeclarativeFlickable::setContentWidth(qreal w) { Q_D(QDeclarativeFlickable); - if (d->hData.viewSize == w) + if (d->contentItem->width() == w) return; - d->hData.viewSize = w; + if (w < 0) d->contentItem->setWidth(width()); else d->contentItem->setWidth(w); + // Make sure that we're entirely in view. - if (!d->pressed && !d->movingHorizontally && !d->movingVertically) { - int oldDuration = d->fixupDuration; - d->fixupDuration = 0; - d->fixupX(); - d->fixupDuration = oldDuration; - } + QScroller *scroller = QScroller::scroller(this); + if (scroller->state() == QScroller::Inactive) + scroller->ensureVisible( QRectF(0.0, 0.0, d->contentItem->width(), d->contentItem->height() ), 0, 0, 0 ); + else + d->updateScrollerValues(); + emit contentWidthChanged(); d->updateBeginningEnd(); } @@ -1224,170 +852,142 @@ void QDeclarativeFlickable::setContentWidth(qreal w) qreal QDeclarativeFlickable::contentHeight() const { Q_D(const QDeclarativeFlickable); - return d->vData.viewSize; + return d->contentItem->height(); } void QDeclarativeFlickable::setContentHeight(qreal h) { Q_D(QDeclarativeFlickable); - if (d->vData.viewSize == h) + if (d->contentItem->height() == h) return; - d->vData.viewSize = h; + if (h < 0) d->contentItem->setHeight(height()); else d->contentItem->setHeight(h); + // Make sure that we're entirely in view. - if (!d->pressed && !d->movingHorizontally && !d->movingVertically) { - int oldDuration = d->fixupDuration; - d->fixupDuration = 0; - d->fixupY(); - d->fixupDuration = oldDuration; - } + QScroller *scroller = QScroller::scroller(this); + if (scroller->state() == QScroller::Inactive) { + scroller->ensureVisible( QRectF(minXExtent(), minYExtent(), + d->contentItem->width(), d->contentItem->height() ), 0, 0, 0 ); + } else + d->updateScrollerValues(); + emit contentHeightChanged(); d->updateBeginningEnd(); } -qreal QDeclarativeFlickable::vWidth() const +bool QDeclarativeFlickable::event(QEvent *event) { - Q_D(const QDeclarativeFlickable); - if (d->hData.viewSize < 0) - return width(); - else - return d->hData.viewSize; -} + Q_D(QDeclarativeFlickable); -qreal QDeclarativeFlickable::vHeight() const -{ - Q_D(const QDeclarativeFlickable); - if (d->vData.viewSize < 0) - return height(); - else - return d->vData.viewSize; -} + switch (event->type()) { + case QEvent::ScrollPrepare: { + if (!d->interactive) + return false; + + QScrollPrepareEvent *se = static_cast(event); + se->setViewportSize(QSizeF(d->width(), d->height())); + + QRectF contentPosRange(QPointF(minXExtent(), minYExtent()), + QPointF(maxXExtent() - d->width(), maxYExtent() - d->height())); + if (d->flickableDirection == HorizontalFlick) + contentPosRange.setHeight(0); + if (d->flickableDirection == VerticalFlick) + contentPosRange.setWidth(0); + se->setContentPosRange(contentPosRange); + se->setContentPos(-d->contentItem->pos()); + + //qDebug() << "QDeclarativeFlickable::event: ScPrEv " << this + // << " pos:" << se->contentPos() + // << " range:" << se->contentPosRange(); + + se->accept(); + d->updateScrollerValuesRequested = false; + return true; + } + case QEvent::Scroll: { + d->duringScrollEvent = true; -bool QDeclarativeFlickable::xflick() const -{ - Q_D(const QDeclarativeFlickable); - if (d->flickableDirection == QDeclarativeFlickable::AutoFlickDirection) - return vWidth() != width(); - return d->flickableDirection & QDeclarativeFlickable::HorizontalFlick; -} + QScrollEvent *se = static_cast(event); -bool QDeclarativeFlickable::yflick() const -{ - Q_D(const QDeclarativeFlickable); - if (d->flickableDirection == QDeclarativeFlickable::AutoFlickDirection) - return vHeight() != height(); - return d->flickableDirection & QDeclarativeFlickable::VerticalFlick; -} + /* + qDebug() << "QDeclarativeFlickable::event: Scroll " + << " scrollerPos:" << se->contentPos() + << " pos:" << -d->contentItem->pos() + << " overshoot:" << se->overshootDistance() + << " newPos: " << (se->contentPos() + se->overshootDistance()); + */ -bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) -{ - Q_D(QDeclarativeFlickable); - QGraphicsSceneMouseEvent mouseEvent(event->type()); - QRectF myRect = mapToScene(QRectF(0, 0, width(), height())).boundingRect(); - - QGraphicsScene *s = scene(); - QDeclarativeItem *grabber = s ? qobject_cast(s->mouseGrabberItem()) : 0; - bool stealThisEvent = d->stealMouse; - if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) { - mouseEvent.setAccepted(false); - for (int i = 0x1; i <= 0x10; i <<= 1) { - if (event->buttons() & i) { - Qt::MouseButton button = Qt::MouseButton(i); - mouseEvent.setButtonDownPos(button, mapFromScene(event->buttonDownPos(button))); - } - } - mouseEvent.setScenePos(event->scenePos()); - mouseEvent.setLastScenePos(event->lastScenePos()); - mouseEvent.setPos(mapFromScene(event->scenePos())); - mouseEvent.setLastPos(mapFromScene(event->lastScenePos())); - - switch(mouseEvent.type()) { - case QEvent::GraphicsSceneMouseMove: - d->handleMouseMoveEvent(&mouseEvent); - break; - case QEvent::GraphicsSceneMousePress: - if (d->delayedPressEvent) - return false; - - d->handleMousePressEvent(&mouseEvent); - d->captureDelayedPress(event); - stealThisEvent = d->stealMouse; // Update stealThisEvent in case changed by function call above - break; - case QEvent::GraphicsSceneMouseRelease: - if (d->delayedPressEvent) { - // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay) - // so we reset the grabber - if (s->mouseGrabberItem() == d->delayedPressTarget) - d->delayedPressTarget->ungrabMouse(); - //Use the event handler that will take care of finding the proper item to propagate the event - QApplication::sendEvent(scene(), d->delayedPressEvent); - d->clearDelayedPress(); - // We send the release - scene()->sendEvent(s->mouseGrabberItem(), event); - // And the event has been consumed - return true; - } - d->handleMouseReleaseEvent(&mouseEvent); - break; - default: - break; - } - grabber = qobject_cast(s->mouseGrabberItem()); - if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) { - d->clearDelayedPress(); - grabMouse(); - } + QPointF oldPos = -d->contentItem->pos(); + QPointF newPos = se->contentPos() + se->overshootDistance(); + QPointF delta = newPos - oldPos; - return stealThisEvent || d->delayedPressEvent; - } else if (d->lastPosTime.isValid()) { - d->lastPosTime.invalidate(); - } - if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) { - d->clearDelayedPress(); - d->stealMouse = false; - d->pressed = false; + viewportAboutToMove(newPos); + d->contentItem->setPos(-newPos); + viewportMoved(); + if (delta.x()) + emit contentXChanged(); + if (delta.y()) + emit contentYChanged(); + + d->duringScrollEvent = false; + if (d->updateScrollerValuesRequested) + QScroller::scroller(this)->resendPrepareEvent(); + + bool newMovingHorizontally = delta.x() != 0; + bool newMovingVertically = delta.y() != 0; + if (se->scrollState() == QScrollEvent::ScrollFinished) { + newMovingHorizontally = false; + newMovingVertically = false; + } + + if (newMovingHorizontally != d->movingHorizontally) { + d->movingHorizontally = newMovingHorizontally; + emit movingHorizontallyChanged(); + } + if (newMovingVertically != d->movingVertically) { + d->movingVertically = newMovingVertically; + emit movingVerticallyChanged(); + } + + if (newMovingHorizontally) + emit horizontalVelocityChanged(); + if (newMovingVertically) + emit verticalVelocityChanged(); + + se->accept(); + return true; } - return false; -} - -bool QDeclarativeFlickable::sceneEventFilter(QGraphicsItem *i, QEvent *e) -{ - Q_D(QDeclarativeFlickable); - if (!isVisible() || !d->interactive) - return QDeclarativeItem::sceneEventFilter(i, e); - switch (e->type()) { - case QEvent::GraphicsSceneMousePress: - case QEvent::GraphicsSceneMouseMove: - case QEvent::GraphicsSceneMouseRelease: - return sendMouseEvent(static_cast(e)); default: break; } - - return QDeclarativeItem::sceneEventFilter(i, e); + return QDeclarativeItem::event(event); } /*! \qmlproperty real Flickable::maximumFlickVelocity - This property holds the maximum velocity that the user can flick the view in pixels/second. + This property holds the maximum velocity that the user can flick the view in pixel per second - The default is 2000 pixels/s + The default is platform dependant. */ qreal QDeclarativeFlickable::maximumFlickVelocity() const { - Q_D(const QDeclarativeFlickable); - return d->maxVelocity; + // 4000 ~ the conversion factor from [m/s] to [pix/s] on a 100dpi screen + return 4000 * QScroller::scroller(const_cast(this))->scrollerProperties().scrollMetric(QScrollerProperties::MaximumVelocity).toDouble(); } void QDeclarativeFlickable::setMaximumFlickVelocity(qreal v) { - Q_D(QDeclarativeFlickable); - if (v == d->maxVelocity) + // 4000 ~ the conversion factor from [m/s] to [pix/s] on a 100dpi screen + v /= qreal(4000); + QScrollerProperties props = QScroller::scroller(this)->scrollerProperties(); + qreal oldV = props.scrollMetric(QScrollerProperties::MaximumVelocity).toReal(); + if (v == oldV) return; - d->maxVelocity = v; + props.setScrollMetric(QScrollerProperties::MaximumVelocity, v); + QScroller::scroller(this)->setScrollerProperties(props); emit maximumFlickVelocityChanged(); } @@ -1395,27 +995,31 @@ void QDeclarativeFlickable::setMaximumFlickVelocity(qreal v) \qmlproperty real Flickable::flickDeceleration This property holds the rate at which a flick will decelerate. - The default is 500. + The default is platform dependant. */ qreal QDeclarativeFlickable::flickDeceleration() const { - Q_D(const QDeclarativeFlickable); - return d->deceleration; + // 4000 ~ the conversion factor from [m/s] to [pix/s] on a 100dpi screen + return qreal(4000) * QScroller::scroller(const_cast(this))->scrollerProperties().scrollMetric(QScrollerProperties::DecelerationFactor).toDouble(); } void QDeclarativeFlickable::setFlickDeceleration(qreal deceleration) { - Q_D(QDeclarativeFlickable); - if (deceleration == d->deceleration) + // 4000 ~ the conversion factor from [m/s] to [pix/s] on a 100dpi screen + deceleration /= qreal(4000); + QScrollerProperties props = QScroller::scroller(this)->scrollerProperties(); + qreal oldDeceleration = props.scrollMetric(QScrollerProperties::DecelerationFactor).toReal(); + if (deceleration == oldDeceleration) return; - d->deceleration = deceleration; + props.setScrollMetric(QScrollerProperties::DecelerationFactor, deceleration); + QScroller::scroller(this)->setScrollerProperties(props); emit flickDecelerationChanged(); } bool QDeclarativeFlickable::isFlicking() const { Q_D(const QDeclarativeFlickable); - return d->flickingHorizontally || d->flickingVertically; + return d->isFlicking; } /*! @@ -1429,13 +1033,13 @@ bool QDeclarativeFlickable::isFlicking() const bool QDeclarativeFlickable::isFlickingHorizontally() const { Q_D(const QDeclarativeFlickable); - return d->flickingHorizontally; + return d->movingHorizontally && d->isFlicking; } bool QDeclarativeFlickable::isFlickingVertically() const { Q_D(const QDeclarativeFlickable); - return d->flickingVertically; + return d->movingVertically && d->isFlicking; } /*! @@ -1451,16 +1055,18 @@ bool QDeclarativeFlickable::isFlickingVertically() const */ int QDeclarativeFlickable::pressDelay() const { - Q_D(const QDeclarativeFlickable); - return d->pressDelay; + return int(qreal(1000) * QScroller::scroller(const_cast(this))->scrollerProperties().scrollMetric(QScrollerProperties::MousePressEventDelay).toReal()); } void QDeclarativeFlickable::setPressDelay(int delay) { - Q_D(QDeclarativeFlickable); - if (d->pressDelay == delay) + qreal pressDelay = qreal(delay) / qreal(1000); // [ms] -> [s] + QScrollerProperties props = QScroller::scroller(this)->scrollerProperties(); + qreal oldPressDelay = props.scrollMetric(QScrollerProperties::MousePressEventDelay).toReal(); + if (pressDelay == oldPressDelay) return; - d->pressDelay = delay; + props.setScrollMetric(QScrollerProperties::MousePressEventDelay, pressDelay); + QScroller::scroller(this)->setScrollerProperties(props); emit pressDelayChanged(); } @@ -1468,7 +1074,7 @@ void QDeclarativeFlickable::setPressDelay(int delay) bool QDeclarativeFlickable::isMoving() const { Q_D(const QDeclarativeFlickable); - return d->movingHorizontally || d->movingVertically; + return d->isMoving; } /*! @@ -1492,83 +1098,4 @@ bool QDeclarativeFlickable::isMovingVertically() const return d->movingVertically; } -void QDeclarativeFlickable::movementStarting() -{ - Q_D(QDeclarativeFlickable); - if (d->hMoved && !d->movingHorizontally) { - d->movingHorizontally = true; - emit movingChanged(); - emit movingHorizontallyChanged(); - if (!d->movingVertically) - emit movementStarted(); - } - else if (d->vMoved && !d->movingVertically) { - d->movingVertically = true; - emit movingChanged(); - emit movingVerticallyChanged(); - if (!d->movingHorizontally) - emit movementStarted(); - } -} - -void QDeclarativeFlickable::movementEnding() -{ - Q_D(QDeclarativeFlickable); - movementXEnding(); - movementYEnding(); - d->hData.smoothVelocity.setValue(0); - d->vData.smoothVelocity.setValue(0); -} - -void QDeclarativeFlickable::movementXEnding() -{ - Q_D(QDeclarativeFlickable); - if (d->flickingHorizontally) { - d->flickingHorizontally = false; - emit flickingChanged(); - emit flickingHorizontallyChanged(); - if (!d->flickingVertically) - emit flickEnded(); - } - if (!d->pressed && !d->stealMouse) { - if (d->movingHorizontally) { - d->movingHorizontally = false; - d->hMoved = false; - emit movingChanged(); - emit movingHorizontallyChanged(); - if (!d->movingVertically) - emit movementEnded(); - } - } -} - -void QDeclarativeFlickable::movementYEnding() -{ - Q_D(QDeclarativeFlickable); - if (d->flickingVertically) { - d->flickingVertically = false; - emit flickingChanged(); - emit flickingVerticallyChanged(); - if (!d->flickingHorizontally) - emit flickEnded(); - } - if (!d->pressed && !d->stealMouse) { - if (d->movingVertically) { - d->movingVertically = false; - d->vMoved = false; - emit movingChanged(); - emit movingVerticallyChanged(); - if (!d->movingHorizontally) - emit movementEnded(); - } - } -} - -void QDeclarativeFlickablePrivate::updateVelocity() -{ - Q_Q(QDeclarativeFlickable); - emit q->horizontalVelocityChanged(); - emit q->verticalVelocityChanged(); -} - QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p.h index 6e4d8ed..b79b08c 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable_p.h +++ b/src/declarative/graphicsitems/qdeclarativeflickable_p.h @@ -43,6 +43,7 @@ #define QDECLARATIVEFLICKABLE_H #include "qdeclarativeitem.h" +#include QT_BEGIN_HEADER @@ -175,19 +176,12 @@ Q_SIGNALS: void flickEnded(); protected: - virtual bool sceneEventFilter(QGraphicsItem *, QEvent *); - void mousePressEvent(QGraphicsSceneMouseEvent *event); - void mouseMoveEvent(QGraphicsSceneMouseEvent *event); - void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); - void wheelEvent(QGraphicsSceneWheelEvent *event); - void timerEvent(QTimerEvent *event); + virtual bool event(QEvent *e); QDeclarativeFlickableVisibleArea *visibleArea(); protected Q_SLOTS: - virtual void ticked(); - void movementStarting(); - void movementEnding(); + virtual void scrollerStateChanged(QScroller::State); protected: void movementXEnding(); @@ -196,16 +190,10 @@ protected: virtual qreal minYExtent() const; virtual qreal maxXExtent() const; virtual qreal maxYExtent() const; - qreal vWidth() const; - qreal vHeight() const; + virtual void viewportAboutToMove(QPointF newPos); virtual void viewportMoved(); virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); - bool sendMouseEvent(QGraphicsSceneMouseEvent *event); - - bool xflick() const; - bool yflick() const; - void cancelFlick(); protected: QDeclarativeFlickable(QDeclarativeFlickablePrivate &dd, QDeclarativeItem *parent); @@ -213,6 +201,8 @@ protected: private: Q_DISABLE_COPY(QDeclarativeFlickable) Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeFlickable) + + friend class QDeclarativeFlickableVisibleArea; }; diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h index 92cf748..1f348ab 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h @@ -78,94 +78,35 @@ public: QDeclarativeFlickablePrivate(); void init(); - struct Velocity : public QDeclarativeTimeLineValue - { - Velocity(QDeclarativeFlickablePrivate *p) - : parent(p) {} - virtual void setValue(qreal v) { - if (v != value()) { - QDeclarativeTimeLineValue::setValue(v); - parent->updateVelocity(); - } - } - QDeclarativeFlickablePrivate *parent; - }; - - struct AxisData { - AxisData(QDeclarativeFlickablePrivate *fp, void (QDeclarativeFlickablePrivate::*func)(qreal)) - : move(fp, func), viewSize(-1), smoothVelocity(fp), atEnd(false), atBeginning(true) - {} - - QDeclarativeTimeLineValueProxy move; - qreal viewSize; - qreal pressPos; - qreal dragStartOffset; - qreal velocity; - qreal flickTarget; - QDeclarativeFlickablePrivate::Velocity smoothVelocity; - bool atEnd : 1; - bool atBeginning : 1; - }; - - void flickX(qreal velocity); - void flickY(qreal velocity); - virtual void flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, - QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity); - - void fixupX(); - void fixupY(); - virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent); - void updateBeginningEnd(); - void captureDelayedPress(QGraphicsSceneMouseEvent *event); - void clearDelayedPress(); - - void setRoundedViewportX(qreal x); - void setRoundedViewportY(qreal y); - - qreal overShootDistance(qreal velocity, qreal size); - + void updateScrollerValues(); + void updateOvershootPolicy(); void itemGeometryChanged(QDeclarativeItem *, const QRectF &, const QRectF &); + // private slot + void _q_scrollerStateChanged(QScroller::State state); + qreal dragStartOffset; + public: QDeclarativeItem *contentItem; - AxisData hData; - AxisData vData; - - QDeclarativeTimeLine timeline; - bool flickingHorizontally : 1; - bool flickingVertically : 1; - bool hMoved : 1; - bool vMoved : 1; - bool movingHorizontally : 1; - bool movingVertically : 1; - bool stealMouse : 1; - bool pressed : 1; - bool interactive : 1; - bool calcVelocity : 1; - QElapsedTimer lastPosTime; - QPointF lastPos; - QPointF pressPos; - QElapsedTimer pressTime; - qreal deceleration; - qreal maxVelocity; - QElapsedTimer velocityTime; - QPointF lastFlickablePosition; - qreal reportedVelocitySmoothing; - QGraphicsSceneMouseEvent *delayedPressEvent; - QGraphicsItem *delayedPressTarget; - QBasicTimer delayedPressTimer; - int pressDelay; - int fixupDuration; - - static void fixupY_callback(void *); - static void fixupX_callback(void *); - - void updateVelocity(); - int vTime; - QDeclarativeTimeLine velocityTimeline; + bool updateScrollerValuesRequested; + bool duringScrollEvent; + + bool isUserGenerated; + bool isFlicking; + bool isMoving; + bool movingHorizontally; + bool movingVertically; + + bool atBeginningX; + bool atBeginningY; + bool atEndX; + bool atEndY; + + bool interactive; + QDeclarativeFlickableVisibleArea *visibleArea; QDeclarativeFlickable::FlickableDirection flickableDirection; QDeclarativeFlickable::BoundsBehavior boundsBehavior; diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 6f38f63..b6af7dc 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -95,24 +95,42 @@ public: //---------------------------------------------------------------------------- +/* + Some explanations: + The grid view is not creating graphics items for every entry + in the model. + + Instead it's creating only number of items that are currently + visible in visibleItems. The first model index of those items is + visibleIndex +*/ + class QDeclarativeGridViewPrivate : public QDeclarativeFlickablePrivate { Q_DECLARE_PUBLIC(QDeclarativeGridView) public: QDeclarativeGridViewPrivate() - : currentItem(0), flow(QDeclarativeGridView::LeftToRight) - , visibleIndex(0) , currentIndex(-1) - , cellWidth(100), cellHeight(100), columns(1), requestedIndex(-1), itemCount(0) - , highlightRangeStart(0), highlightRangeEnd(0), highlightRange(QDeclarativeGridView::NoHighlightRange) - , highlightComponent(0), highlight(0), trackedItem(0) - , moveReason(Other), buffer(0), highlightXAnimator(0), highlightYAnimator(0) - , highlightMoveDuration(150) - , footerComponent(0), footer(0), headerComponent(0), header(0) - , bufferMode(BufferBefore | BufferAfter), snapMode(QDeclarativeGridView::NoSnap) - , ownModel(false), wrap(false), autoHighlight(true) - , fixCurrentVisibility(false), lazyRelease(false), layoutScheduled(false) - , deferredRelease(false), haveHighlightRange(false), currentIndexCleared(false) {} + : currentItem(0), flow(QDeclarativeGridView::LeftToRight) + , visibleIndex(0) , currentIndex(-1) + , cellWidth(100), cellHeight(100), columns(1), requestedIndex(-1), modelCount(0) + , highlightRangeStart(0), highlightRangeEnd(0), highlightRange(QDeclarativeGridView::NoHighlightRange) + , highlightComponent(0), highlight(0) + , moveReason(Other) + , buffer(0) + , bufferMode(BufferBefore | BufferAfter) + , highlightXAnimator(0), highlightYAnimator(0) + , highlightMoveDuration(150) + , footerComponent(0) + , footer(0) + , headerComponent(0) + , header(0) + , snapMode(QDeclarativeGridView::NoSnap) + , ownModel(false), wrap(false), autoHighlight(true) + , fixCurrentVisibility(false), lazyRelease(false), layoutScheduled(false) + , deferredRelease(false), haveHighlightRange(false) + , currentIndexCleared(false) + {} void init(); void clear(); @@ -120,18 +138,15 @@ public: void releaseItem(FxGridItem *item); void refill(qreal from, qreal to, bool doBuffer=false); - void updateGrid(); void scheduleLayout(); void layout(); void updateUnrequestedIndexes(); void updateUnrequestedPositions(); - void updateTrackedItem(); - void createHighlight(); - void updateHighlight(); - void updateCurrent(int modelIndex); + void recreateHighlight(); + void updateHighlight(bool smooth = true); + void setCurrentIndex(int modelIndex); void updateHeader(); void updateFooter(); - void fixupPosition(); FxGridItem *visibleItem(int modelIndex) const { if (modelIndex >= visibleIndex && modelIndex < visibleIndex + visibleItems.count()) { @@ -144,10 +159,28 @@ public: return 0; } + /* The following methods are using flow independent coordinates. + row and column also change the direction depending on the flow. + */ + + /*! \internal + Returns the position of the view. + Depending on the flow this can be either the x or the y content coordinate + */ qreal position() const { Q_Q(const QDeclarativeGridView); return flow == QDeclarativeGridView::LeftToRight ? q->contentY() : q->contentX(); } + + void scrollTo(qreal pos) { + Q_Q(QDeclarativeGridView); + QScroller *scroller = QScroller::scroller(q); + if (flow == QDeclarativeGridView::LeftToRight) + scroller->scrollTo(QPoint(q->contentX(), pos)); + else + scroller->scrollTo(QPoint(pos, q->contentY())); + } + void setPosition(qreal pos) { Q_Q(QDeclarativeGridView); if (flow == QDeclarativeGridView::LeftToRight) @@ -159,22 +192,39 @@ public: Q_Q(const QDeclarativeGridView); return flow == QDeclarativeGridView::LeftToRight ? q->height() : q->width(); } - qreal startPosition() const { - qreal pos = 0; - if (!visibleItems.isEmpty()) - pos = visibleItems.first()->rowPos() - visibleIndex / columns * rowSize(); - return pos; + + /*! \internal + Returns the row size of the header to be added to the total item size. + */ + qreal headerSize() const { + if (!header) + return 0; + if (flow == QDeclarativeGridView::LeftToRight) + return header->item->height(); + else + return header->item->width(); + } + + /*! \internal + Returns the row size of the footer to be added to the total item size. + */ + qreal footerSize() const { + if (!footer) + return 0; + if (flow == QDeclarativeGridView::LeftToRight) + return footer->item->height(); + else + return footer->item->width(); } - qreal endPosition() const { - qreal pos = 0; - if (model && model->count()) - pos = rowPosAt(model->count() - 1) + rowSize(); - return pos; + qreal contentSize() const { + if (!model || !model->isValid()) + return 0.0; + return ((modelCount + columns - 1 /*round up*/) / columns) * rowSize(); } bool isValid() const { - return model && model->count() && model->isValid(); + return model && modelCount && model->isValid(); } int rowSize() const { @@ -185,51 +235,13 @@ public: } qreal colPosAt(int modelIndex) const { - if (FxGridItem *item = visibleItem(modelIndex)) - return item->colPos(); - if (!visibleItems.isEmpty()) { - if (modelIndex < visibleIndex) { - int count = (visibleIndex - modelIndex) % columns; - int col = visibleItems.first()->colPos() / colSize(); - col = (columns - count + col) % columns; - return col * colSize(); - } else { - int count = columns - 1 - (modelIndex - visibleItems.last()->index - 1) % columns; - return visibleItems.last()->colPos() - count * colSize(); - } - } else { - return (modelIndex % columns) * colSize(); - } - return 0; + return (modelIndex % columns) * colSize(); } qreal rowPosAt(int modelIndex) const { - if (FxGridItem *item = visibleItem(modelIndex)) - return item->rowPos(); - if (!visibleItems.isEmpty()) { - if (modelIndex < visibleIndex) { - int firstCol = visibleItems.first()->colPos() / colSize(); - int col = visibleIndex - modelIndex + (columns - firstCol - 1); - int rows = col / columns; - return visibleItems.first()->rowPos() - rows * rowSize(); - } else { - int count = modelIndex - visibleItems.last()->index; - int col = visibleItems.last()->colPos() + count * colSize(); - int rows = col / (columns * colSize()); - return visibleItems.last()->rowPos() + rows * rowSize(); - } - } else { - qreal pos = (modelIndex / columns) * rowSize(); - if (header) { - qreal headerSize = flow == QDeclarativeGridView::LeftToRight - ? header->item->height() - : header->item->width(); - pos += headerSize; - } - return pos; - } - return 0; + return (modelIndex / columns) * rowSize() + headerSize(); } + /*! Returns the first of the visibleItems that is visible */ FxGridItem *firstVisibleItem() const { const qreal pos = position(); for (int i = 0; i < visibleItems.count(); ++i) { @@ -240,16 +252,17 @@ public: return visibleItems.count() ? visibleItems.first() : 0; } + /*! \internal + Returns the last visible model index. delayRemove items are not counted (as they don't have an index) + */ int lastVisibleIndex() const { - int lastIndex = -1; - for (int i = visibleItems.count()-1; i >= 0; --i) { - FxGridItem *gridItem = visibleItems.at(i); - if (gridItem->index != -1) { - lastIndex = gridItem->index; - break; - } + // find the last valid model index + for (int i = visibleItems.count() - 1; i >= 0; --i) { + FxGridItem *item = visibleItems.at(i); + if (item->index != -1) + return item->index; } - return lastIndex; + return visibleIndex; } // Map a model index to visibleItems list index. @@ -268,51 +281,22 @@ public: return -1; // Not in visibleList } - qreal snapPosAt(qreal pos) const { - Q_Q(const QDeclarativeGridView); - qreal snapPos = 0; - if (!visibleItems.isEmpty()) { - pos += rowSize()/2; - snapPos = visibleItems.first()->rowPos() - visibleIndex / columns * rowSize(); - snapPos = pos - fmodf(pos - snapPos, qreal(rowSize())); - qreal maxExtent = flow == QDeclarativeGridView::LeftToRight ? -q->maxYExtent() : -q->maxXExtent(); - qreal minExtent = flow == QDeclarativeGridView::LeftToRight ? -q->minYExtent() : -q->minXExtent(); - if (snapPos > maxExtent) - snapPos = maxExtent; - if (snapPos < minExtent) - snapPos = minExtent; - } - return snapPos; - } - - FxGridItem *snapItemAt(qreal pos) { - for (int i = 0; i < visibleItems.count(); ++i) { - FxGridItem *item = visibleItems[i]; - if (item->index == -1) - continue; - qreal itemTop = item->rowPos(); - if (item->index == model->count()-1 || (itemTop+rowSize()/2 >= pos)) - return item; - } - if (visibleItems.count() && visibleItems.first()->rowPos() <= pos) - return visibleItems.first(); - return 0; - } - - int snapIndex() { - int index = currentIndex; - for (int i = 0; i < visibleItems.count(); ++i) { - FxGridItem *item = visibleItems[i]; - if (item->index == -1) - continue; - qreal itemTop = item->rowPos(); - if (itemTop >= highlight->rowPos()-rowSize()/2 && itemTop < highlight->rowPos()+rowSize()/2) { - index = item->index; - if (item->colPos() >= highlight->colPos()-colSize()/2 && item->colPos() < highlight->colPos()+colSize()/2) - return item->index; - } - } - return index; + /*! \internal + Return the model index of the visible item which is + next to the highlight. + */ + int snapIndex() + { + // which is the next row and column around the hightlight + int nextRow = qRound(highlight->rowPos() / rowSize()); + int nextCol = qRound(highlight->colPos() / colSize()); + + // calculate and verify index + int index = nextRow * columns + nextCol; + if (index < 0 || index >= modelCount) + return currentIndex; + else + return index; } virtual void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) { @@ -322,7 +306,6 @@ public: if (newGeometry.height() != oldGeometry.height() || newGeometry.width() != oldGeometry.width()) { if (q->isComponentComplete()) { - updateGrid(); scheduleLayout(); } } @@ -330,12 +313,10 @@ public: updateHeader(); updateFooter(); } + if (currentItem && currentItem->item == item) + updateHighlight(); } - virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent); - virtual void flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, - QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity); - // for debugging only void checkVisible() const { int skip = 0; @@ -354,34 +335,71 @@ public: QDeclarativeGuard model; QVariant modelVariant; QList visibleItems; + + /* + These are items that were not requested but send by createdItem from the model. + Usually these items were created because another view showing the same model + needed them. + */ QHash unrequestedItems; + FxGridItem *currentItem; QDeclarativeGridView::Flow flow; + + /* + The visibleIndex is the modelIndex of the first item in visibleItems + visible row. + */ int visibleIndex; + + /* + The currentIndex is the model index of the currently highlighted item. + */ int currentIndex; + int cellWidth; int cellHeight; + + /* + The number of columns this layout currently has. + */ int columns; + + /* + The model index of the item that is currently created via createItem + */ int requestedIndex; - int itemCount; + + /* + This is the number of items in the model. + */ + int modelCount; + qreal highlightRangeStart; qreal highlightRangeEnd; QDeclarativeGridView::HighlightRangeMode highlightRange; QDeclarativeComponent *highlightComponent; FxGridItem *highlight; - FxGridItem *trackedItem; enum MovementReason { Other, SetIndex, Mouse }; MovementReason moveReason; + + /* + The maximum number of pixels that should be covered by buffered + delegates in front and behind the visible area. + */ int buffer; + enum BufferMode { NoBuffer = 0x00, BufferBefore = 0x01, BufferAfter = 0x02 }; + int bufferMode; + QSmoothedAnimation *highlightXAnimator; QSmoothedAnimation *highlightYAnimator; int highlightMoveDuration; + QDeclarativeComponent *footerComponent; FxGridItem *footer; QDeclarativeComponent *headerComponent; FxGridItem *header; - enum BufferMode { NoBuffer = 0x00, BufferBefore = 0x01, BufferAfter = 0x02 }; - int bufferMode; + QDeclarativeGridView::SnapMode snapMode; bool ownModel : 1; @@ -398,7 +416,6 @@ public: void QDeclarativeGridViewPrivate::init() { Q_Q(QDeclarativeGridView); - QObject::connect(q, SIGNAL(movementEnded()), q, SLOT(animStopped())); q->setFlag(QGraphicsItem::ItemIsFocusScope); q->setFlickableDirection(QDeclarativeFlickable::VerticalFlick); addItemChangeListener(this, Geometry); @@ -412,9 +429,8 @@ void QDeclarativeGridViewPrivate::clear() visibleIndex = 0; releaseItem(currentItem); currentItem = 0; - createHighlight(); - trackedItem = 0; - itemCount = 0; + recreateHighlight(); + modelCount = 0; } FxGridItem *QDeclarativeGridViewPrivate::createItem(int modelIndex) @@ -446,11 +462,6 @@ void QDeclarativeGridViewPrivate::releaseItem(FxGridItem *item) Q_Q(QDeclarativeGridView); if (!item || !model) return; - if (trackedItem == item) { - QObject::disconnect(trackedItem->item, SIGNAL(yChanged()), q, SLOT(trackedPositionChanged())); - QObject::disconnect(trackedItem->item, SIGNAL(xChanged()), q, SLOT(trackedPositionChanged())); - trackedItem = 0; - } if (model->release(item->item) == 0) { // item was not destroyed, and we no longer reference it. unrequestedItems.insert(item->item, model->indexOf(item->item, q)); @@ -461,9 +472,12 @@ void QDeclarativeGridViewPrivate::releaseItem(FxGridItem *item) void QDeclarativeGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) { Q_Q(QDeclarativeGridView); - if (!isValid() || !q->isComponentComplete()) + if (!q->isComponentComplete()) return; - itemCount = model->count(); + + if (!doBuffer && buffer && bufferMode != NoBuffer) + doBuffer = true; + qreal bufferFrom = from - buffer; qreal bufferTo = to + buffer; qreal fillFrom = from; @@ -475,29 +489,32 @@ void QDeclarativeGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) bool changed = false; - int colPos = colPosAt(visibleIndex); - int rowPos = rowPosAt(visibleIndex); - int modelIndex = visibleIndex; - if (visibleItems.count()) { - rowPos = visibleItems.last()->rowPos(); - colPos = visibleItems.last()->colPos() + colSize(); - if (colPos > colSize() * (columns-1)) { - colPos = 0; - rowPos += rowSize(); - } - int i = visibleItems.count() - 1; - while (i > 0 && visibleItems.at(i)->index == -1) - --i; - modelIndex = visibleItems.at(i)->index + 1; + updateHeader(); + + columns = (int)qMax((flow == QDeclarativeGridView::LeftToRight ? q->width() : q->height()) / colSize(), qreal(1.)); + + // -- update the positions of all visible items + for (int i = 0; i < visibleItems.count(); ++i) { + qreal colPos = colPosAt(i + visibleIndex); + qreal rowPos = rowPosAt(i + visibleIndex); + FxGridItem *item = visibleItems.at(i); + item->setPosition(colPos, rowPos); } - int colNum = colPos / colSize(); + // determine the next position + int modelIndex = lastVisibleIndex(); + if (!visibleItems.isEmpty()) + modelIndex++; + qreal colPos = colPosAt(modelIndex); + qreal rowPos = rowPosAt(modelIndex); + + int colNum = colPos / colSize(); FxGridItem *item = 0; // Item creation and release is staggered in order to avoid // creating/releasing multiple items in one frame // while flicking (as much as possible). - while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) { + while (modelIndex < modelCount && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) { // qDebug() << "refill: append item" << modelIndex; if (!(item = createItem(modelIndex))) break; @@ -571,31 +588,17 @@ void QDeclarativeGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) } else { deferredRelease = true; } - if (changed) { - if (header) - updateHeader(); - if (footer) - updateFooter(); - if (flow == QDeclarativeGridView::LeftToRight) - q->setContentHeight(endPosition() - startPosition()); - else - q->setContentWidth(endPosition() - startPosition()); - } else if (!doBuffer && buffer && bufferMode != NoBuffer) { - refill(from, to, true); - } - lazyRelease = false; -} -void QDeclarativeGridViewPrivate::updateGrid() -{ - Q_Q(QDeclarativeGridView); - columns = (int)qMax((flow == QDeclarativeGridView::LeftToRight ? q->width() : q->height()) / colSize(), qreal(1.)); - if (isValid()) { - if (flow == QDeclarativeGridView::LeftToRight) - q->setContentHeight(endPosition() - startPosition()); - else - q->setContentWidth(endPosition() - startPosition()); - } + if (flow == QDeclarativeGridView::LeftToRight) + q->setContentHeight(contentSize()); + else + q->setContentWidth(contentSize()); + + updateFooter(); + + updateUnrequestedPositions(); + + lazyRelease = false; } void QDeclarativeGridViewPrivate::scheduleLayout() @@ -609,53 +612,9 @@ void QDeclarativeGridViewPrivate::scheduleLayout() void QDeclarativeGridViewPrivate::layout() { - Q_Q(QDeclarativeGridView); layoutScheduled = false; - if (!isValid() && !visibleItems.count()) { - clear(); - return; - } - if (visibleItems.count()) { - qreal rowPos = visibleItems.first()->rowPos(); - qreal colPos = visibleItems.first()->colPos(); - int col = visibleIndex % columns; - if (colPos != col * colSize()) { - colPos = col * colSize(); - visibleItems.first()->setPosition(colPos, rowPos); - } - for (int i = 1; i < visibleItems.count(); ++i) { - FxGridItem *item = visibleItems.at(i); - colPos += colSize(); - if (colPos > colSize() * (columns-1)) { - colPos = 0; - rowPos += rowSize(); - } - item->setPosition(colPos, rowPos); - } - } - if (header) - updateHeader(); - if (footer) - updateFooter(); - q->refill(); - updateHighlight(); - moveReason = Other; - if (flow == QDeclarativeGridView::LeftToRight) { - q->setContentHeight(endPosition() - startPosition()); - fixupY(); - } else { - q->setContentWidth(endPosition() - startPosition()); - fixupX(); - } - updateUnrequestedPositions(); -} -void QDeclarativeGridViewPrivate::updateUnrequestedIndexes() -{ - Q_Q(QDeclarativeGridView); - QHash::iterator it; - for (it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it) - *it = model->indexOf(it.key(), q); + refill(position(), position() + size() - 1); } void QDeclarativeGridViewPrivate::updateUnrequestedPositions() @@ -670,35 +629,11 @@ void QDeclarativeGridViewPrivate::updateUnrequestedPositions() } } -void QDeclarativeGridViewPrivate::updateTrackedItem() -{ - Q_Q(QDeclarativeGridView); - FxGridItem *item = currentItem; - if (highlight) - item = highlight; - - if (trackedItem && item != trackedItem) { - QObject::disconnect(trackedItem->item, SIGNAL(yChanged()), q, SLOT(trackedPositionChanged())); - QObject::disconnect(trackedItem->item, SIGNAL(xChanged()), q, SLOT(trackedPositionChanged())); - trackedItem = 0; - } - - if (!trackedItem && item) { - trackedItem = item; - QObject::connect(trackedItem->item, SIGNAL(yChanged()), q, SLOT(trackedPositionChanged())); - QObject::connect(trackedItem->item, SIGNAL(xChanged()), q, SLOT(trackedPositionChanged())); - } - if (trackedItem) - q->trackedPositionChanged(); -} - -void QDeclarativeGridViewPrivate::createHighlight() +void QDeclarativeGridViewPrivate::recreateHighlight() { Q_Q(QDeclarativeGridView); bool changed = false; if (highlight) { - if (trackedItem == highlight) - trackedItem = 0; delete highlight->item; delete highlight; highlight = 0; @@ -724,8 +659,6 @@ void QDeclarativeGridViewPrivate::createHighlight() } } else { item = new QDeclarativeItem; - QDeclarative_setParent_noEvent(item, q->contentItem()); - item->setParentItem(q->contentItem()); } if (item) { QDeclarative_setParent_noEvent(item, q->contentItem()); @@ -750,59 +683,88 @@ void QDeclarativeGridViewPrivate::createHighlight() emit q->highlightItemChanged(); } -void QDeclarativeGridViewPrivate::updateHighlight() +void QDeclarativeGridViewPrivate::updateHighlight(bool smooth) { if ((!currentItem && highlight) || (currentItem && !highlight)) - createHighlight(); - if (currentItem && autoHighlight && highlight && !movingHorizontally && !movingVertically) { - // auto-update highlight - highlightXAnimator->to = currentItem->item->x(); - highlightYAnimator->to = currentItem->item->y(); - highlight->item->setWidth(currentItem->item->width()); - highlight->item->setHeight(currentItem->item->height()); - highlightXAnimator->restart(); - highlightYAnimator->restart(); + recreateHighlight(); + + // --- move the current item between the highlight range + if (moveReason == QDeclarativeGridViewPrivate::SetIndex) { + // ensure that the tracked item is inside the highlight range + + // reposition view + if (currentItem) { + qreal pos = currentItem->rowPos(); + qreal viewPos = position(); + + if (autoHighlight && haveHighlightRange) { + if (pos > viewPos + highlightRangeEnd - rowSize()) + viewPos = pos - highlightRangeEnd + rowSize(); + if (pos < viewPos + highlightRangeStart) + viewPos = pos - highlightRangeStart; + + } else { + if (pos > viewPos + size() - rowSize()) + viewPos = pos - size() + rowSize(); + if (pos < viewPos + 0) + viewPos = pos - 0; + } + if (smooth) + scrollTo(viewPos); + else + setPosition(viewPos); + } + + // move the highlight + if (currentItem && autoHighlight && highlight) { + highlight->item->setWidth(currentItem->item->width()); + highlight->item->setHeight(currentItem->item->height()); + highlightXAnimator->to = currentItem->item->x(); + highlightYAnimator->to = currentItem->item->y(); + if (smooth) { + highlightXAnimator->restart(); + highlightYAnimator->restart(); + } else { + highlightXAnimator->stop(); + highlightYAnimator->stop(); + highlight->item->setPos(QPointF(highlightXAnimator->to, + highlightYAnimator->to)); + } + } } - updateTrackedItem(); } -void QDeclarativeGridViewPrivate::updateCurrent(int modelIndex) +void QDeclarativeGridViewPrivate::setCurrentIndex(int newIndex) { Q_Q(QDeclarativeGridView); - if (!q->isComponentComplete() || !isValid() || modelIndex < 0 || modelIndex >= model->count()) { - if (currentItem) { + + // --- release the old item + if (currentItem && currentIndex != newIndex ) { currentItem->attached->setIsCurrentItem(false); releaseItem(currentItem); currentItem = 0; - currentIndex = modelIndex; - emit q->currentIndexChanged(); - updateHighlight(); - } else if (currentIndex != modelIndex) { - currentIndex = modelIndex; - emit q->currentIndexChanged(); - } - return; } - if (currentItem && currentIndex == modelIndex) { - updateHighlight(); - return; - } + int oldIndex = currentIndex; + currentIndex = newIndex; - FxGridItem *oldCurrentItem = currentItem; - currentIndex = modelIndex; - currentItem = createItem(modelIndex); - fixCurrentVisibility = true; - if (oldCurrentItem && (!currentItem || oldCurrentItem->item != currentItem->item)) - oldCurrentItem->attached->setIsCurrentItem(false); - if (currentItem) { - currentItem->setPosition(colPosAt(modelIndex), rowPosAt(modelIndex)); - currentItem->item->setFocus(true); - currentItem->attached->setIsCurrentItem(true); + bool visible = (q->isComponentComplete() && isValid() && !currentItem && + newIndex >= 0 && newIndex < modelCount); + + // --- set the new item + if (visible) { + currentItem = createItem(newIndex); + if (currentItem) { + currentItem->setPosition(colPosAt(newIndex), rowPosAt(newIndex)); + currentItem->item->setFocus(true); + currentItem->attached->setIsCurrentItem(true); + } } + updateHighlight(); - emit q->currentIndexChanged(); - releaseItem(oldCurrentItem); + + if (currentIndex != oldIndex) + emit q->currentIndexChanged(); } void QDeclarativeGridViewPrivate::updateFooter() @@ -830,24 +792,7 @@ void QDeclarativeGridViewPrivate::updateFooter() } } if (footer) { - if (visibleItems.count()) { - qreal endPos = endPosition(); - if (lastVisibleIndex() == model->count()-1) { - footer->setPosition(0, endPos); - } else { - qreal visiblePos = position() + q->height(); - if (endPos <= visiblePos || footer->endRowPos() < endPos) - footer->setPosition(0, endPos); - } - } else { - qreal endPos = 0; - if (header) { - endPos += flow == QDeclarativeGridView::LeftToRight - ? header->item->height() - : header->item->width(); - } - footer->setPosition(0, endPos); - } + footer->setPosition(0, contentSize() + headerSize()); } } @@ -876,194 +821,10 @@ void QDeclarativeGridViewPrivate::updateHeader() } } if (header) { - if (visibleItems.count()) { - qreal startPos = startPosition(); - qreal headerSize = flow == QDeclarativeGridView::LeftToRight - ? header->item->height() - : header->item->width(); - if (visibleIndex == 0) { - header->setPosition(0, startPos - headerSize); - } else { - if (position() <= startPos || header->rowPos() > startPos - headerSize) - header->setPosition(0, startPos - headerSize); - } - } else { - header->setPosition(0, 0); - } + header->setPosition(0, 0); } } -void QDeclarativeGridViewPrivate::fixupPosition() -{ - moveReason = Other; - if (flow == QDeclarativeGridView::LeftToRight) - fixupY(); - else - fixupX(); -} - -void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent) -{ - if ((flow == QDeclarativeGridView::TopToBottom && &data == &vData) - || (flow == QDeclarativeGridView::LeftToRight && &data == &hData)) - return; - - int oldDuration = fixupDuration; - fixupDuration = moveReason == Mouse ? fixupDuration : 0; - - if (snapMode != QDeclarativeGridView::NoSnap) { - FxGridItem *topItem = snapItemAt(position()+highlightRangeStart); - FxGridItem *bottomItem = snapItemAt(position()+highlightRangeEnd); - qreal pos; - if (topItem && bottomItem && haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) { - qreal topPos = qMin(topItem->rowPos() - highlightRangeStart, -maxExtent); - qreal bottomPos = qMax(bottomItem->rowPos() - highlightRangeEnd, -minExtent); - pos = qAbs(data.move + topPos) < qAbs(data.move + bottomPos) ? topPos : bottomPos; - } else if (topItem) { - pos = qMax(qMin(topItem->rowPos() - highlightRangeStart, -maxExtent), -minExtent); - } else if (bottomItem) { - pos = qMax(qMin(bottomItem->rowPos() - highlightRangeStart, -maxExtent), -minExtent); - } else { - fixupDuration = oldDuration; - return; - } - if (currentItem && haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) { - updateHighlight(); - qreal currPos = currentItem->rowPos(); - if (pos < currPos + rowSize() - highlightRangeEnd) - pos = currPos + rowSize() - highlightRangeEnd; - if (pos > currPos - highlightRangeStart) - pos = currPos - highlightRangeStart; - } - - qreal dist = qAbs(data.move + pos); - if (dist > 0) { - timeline.reset(data.move); - if (fixupDuration) - timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - else - timeline.set(data.move, -pos); - vTime = timeline.time(); - } - } else if (haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) { - if (currentItem) { - updateHighlight(); - qreal pos = currentItem->rowPos(); - qreal viewPos = position(); - if (viewPos < pos + rowSize() - highlightRangeEnd) - viewPos = pos + rowSize() - highlightRangeEnd; - if (viewPos > pos - highlightRangeStart) - viewPos = pos - highlightRangeStart; - - timeline.reset(data.move); - if (viewPos != position()) { - if (fixupDuration) - timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - else - timeline.set(data.move, -viewPos); - } - vTime = timeline.time(); - } - } else { - QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent); - } - fixupDuration = oldDuration; -} - -void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, - QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity) -{ - Q_Q(QDeclarativeGridView); - moveReason = Mouse; - if ((!haveHighlightRange || highlightRange != QDeclarativeGridView::StrictlyEnforceRange) - && snapMode == QDeclarativeGridView::NoSnap) { - QDeclarativeFlickablePrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity); - return; - } - qreal maxDistance = 0; - // -ve velocity means list is moving up - if (velocity > 0) { - if (data.move.value() < minExtent) { - if (snapMode == QDeclarativeGridView::SnapOneRow) { - if (FxGridItem *item = firstVisibleItem()) - maxDistance = qAbs(item->rowPos() + data.move.value()); - } else { - maxDistance = qAbs(minExtent - data.move.value()); - } - } - if (snapMode == QDeclarativeGridView::NoSnap && highlightRange != QDeclarativeGridView::StrictlyEnforceRange) - data.flickTarget = minExtent; - } else { - if (data.move.value() > maxExtent) { - if (snapMode == QDeclarativeGridView::SnapOneRow) { - qreal pos = snapPosAt(-data.move.value()) + rowSize(); - maxDistance = qAbs(pos + data.move.value()); - } else { - maxDistance = qAbs(maxExtent - data.move.value()); - } - } - if (snapMode == QDeclarativeGridView::NoSnap && highlightRange != QDeclarativeGridView::StrictlyEnforceRange) - data.flickTarget = maxExtent; - } - bool overShoot = boundsBehavior == QDeclarativeFlickable::DragAndOvershootBounds; - if (maxDistance > 0 || overShoot) { - // This mode requires the grid to stop exactly on a row boundary. - qreal v = velocity; - if (maxVelocity != -1 && maxVelocity < qAbs(v)) { - if (v < 0) - v = -maxVelocity; - else - v = maxVelocity; - } - qreal accel = deceleration; - qreal v2 = v * v; - qreal overshootDist = 0.0; - if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarativeGridView::SnapOneRow) { - // + rowSize()/4 to encourage moving at least one item in the flick direction - qreal dist = v2 / (accel * 2.0) + rowSize()/4; - dist = qMin(dist, maxDistance); - if (v > 0) - dist = -dist; - data.flickTarget = -snapPosAt(-(data.move.value() - highlightRangeStart) + dist) + highlightRangeStart; - qreal adjDist = -data.flickTarget + data.move.value(); - if (qAbs(adjDist) > qAbs(dist)) { - // Prevent painfully slow flicking - adjust velocity to suit flickDeceleration - qreal adjv2 = accel * 2.0f * qAbs(adjDist); - if (adjv2 > v2) { - v2 = adjv2; - v = qSqrt(v2); - if (dist > 0) - v = -v; - } - } - dist = adjDist; - accel = v2 / (2.0f * qAbs(dist)); - } else { - data.flickTarget = velocity > 0 ? minExtent : maxExtent; - overshootDist = overShoot ? overShootDistance(v, vSize) : 0; - } - timeline.reset(data.move); - timeline.accel(data.move, v, accel, maxDistance + overshootDist); - timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this)); - if (!flickingHorizontally && q->xflick()) { - flickingHorizontally = true; - emit q->flickingChanged(); - emit q->flickingHorizontallyChanged(); - emit q->flickStarted(); - } - if (!flickingVertically && q->yflick()) { - flickingVertically = true; - emit q->flickingChanged(); - emit q->flickingVerticallyChanged(); - emit q->flickStarted(); - } - } else { - timeline.reset(data.move); - fixup(data, minExtent, maxExtent); - } -} - - //---------------------------------------------------------------------------- /*! @@ -1207,10 +968,10 @@ QVariant QDeclarativeGridView::model() const return d->modelVariant; } -void QDeclarativeGridView::setModel(const QVariant &model) +void QDeclarativeGridView::setModel(const QVariant &newModel) { Q_D(QDeclarativeGridView); - if (d->modelVariant == model) + if (d->modelVariant == newModel) return; if (d->model) { disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); @@ -1220,13 +981,18 @@ void QDeclarativeGridView::setModel(const QVariant &model) disconnect(d->model, SIGNAL(createdItem(int,QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*))); disconnect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*))); } + d->clear(); - d->modelVariant = model; - QObject *object = qvariant_cast(model); + QDeclarativeVisualModel *oldModel = d->model; + d->model = 0; + d->modelCount = 0; + + d->modelVariant = newModel; + QObject *object = qvariant_cast(newModel); QDeclarativeVisualModel *vim = 0; if (object && (vim = qobject_cast(object))) { if (d->ownModel) { - delete d->model; + delete oldModel; d->ownModel = false; } d->model = vim; @@ -1234,24 +1000,22 @@ void QDeclarativeGridView::setModel(const QVariant &model) if (!d->ownModel) { d->model = new QDeclarativeVisualDataModel(qmlContext(this), this); d->ownModel = true; + } else { + d->model = oldModel; } if (QDeclarativeVisualDataModel *dataModel = qobject_cast(d->model)) - dataModel->setModel(model); + dataModel->setModel(newModel); } + if (d->model) { + d->modelCount = d->model->count(); d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore | QDeclarativeGridViewPrivate::BufferAfter; if (isComponentComplete()) { refill(); - if ((d->currentIndex >= d->model->count() || d->currentIndex < 0) && !d->currentIndexCleared) { + if ((d->currentIndex >= d->modelCount || d->currentIndex < 0) && !d->currentIndexCleared) { setCurrentIndex(0); } else { - d->moveReason = QDeclarativeGridViewPrivate::SetIndex; - d->updateCurrent(d->currentIndex); - if (d->highlight && d->currentItem) { - d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); - d->updateTrackedItem(); - } - d->moveReason = QDeclarativeGridViewPrivate::Other; + d->setCurrentIndex(d->currentIndex); } } connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); @@ -1314,12 +1078,7 @@ void QDeclarativeGridView::setDelegate(QDeclarativeComponent *delegate) d->currentItem = 0; refill(); d->moveReason = QDeclarativeGridViewPrivate::SetIndex; - d->updateCurrent(d->currentIndex); - if (d->highlight && d->currentItem) { - d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); - d->updateTrackedItem(); - } - d->moveReason = QDeclarativeGridViewPrivate::Other; + d->setCurrentIndex(d->currentIndex); } emit delegateChanged(); } @@ -1351,12 +1110,15 @@ void QDeclarativeGridView::setCurrentIndex(int index) Q_D(QDeclarativeGridView); if (d->requestedIndex >= 0) // currently creating item return; + d->currentIndexCleared = (index == -1); + if (index == d->currentIndex) return; + if (isComponentComplete() && d->isValid()) { d->moveReason = QDeclarativeGridViewPrivate::SetIndex; - d->updateCurrent(index); + d->setCurrentIndex(index); } else { d->currentIndex = index; emit currentIndexChanged(); @@ -1396,9 +1158,7 @@ QDeclarativeItem *QDeclarativeGridView::highlightItem() int QDeclarativeGridView::count() const { Q_D(const QDeclarativeGridView); - if (d->model) - return d->model->count(); - return 0; + return d->modelCount; } /*! @@ -1422,7 +1182,7 @@ void QDeclarativeGridView::setHighlight(QDeclarativeComponent *highlight) Q_D(QDeclarativeGridView); if (highlight != d->highlightComponent) { d->highlightComponent = highlight; - d->updateCurrent(d->currentIndex); + d->recreateHighlight(); emit highlightChanged(); } } @@ -1599,10 +1359,8 @@ void QDeclarativeGridView::setFlow(Flow flow) setContentHeight(-1); setFlickableDirection(QDeclarativeFlickable::HorizontalFlick); } - d->clear(); - d->updateGrid(); - refill(); - d->updateCurrent(d->currentIndex); + d->layout(); + d->setCurrentIndex(d->currentIndex); emit flowChanged(); } } @@ -1687,9 +1445,8 @@ void QDeclarativeGridView::setCellWidth(int cellWidth) Q_D(QDeclarativeGridView); if (cellWidth != d->cellWidth && cellWidth > 0) { d->cellWidth = qMax(1, cellWidth); - d->updateGrid(); - emit cellWidthChanged(); d->layout(); + emit cellWidthChanged(); } } @@ -1704,9 +1461,8 @@ void QDeclarativeGridView::setCellHeight(int cellHeight) Q_D(QDeclarativeGridView); if (cellHeight != d->cellHeight && cellHeight > 0) { d->cellHeight = qMax(1, cellHeight); - d->updateGrid(); - emit cellHeightChanged(); d->layout(); + emit cellHeightChanged(); } } /*! @@ -1764,8 +1520,7 @@ void QDeclarativeGridView::setFooter(QDeclarativeComponent *footer) d->footer = 0; } d->footerComponent = footer; - d->updateFooter(); - d->updateGrid(); + d->layout(); emit footerChanged(); } } @@ -1794,9 +1549,7 @@ void QDeclarativeGridView::setHeader(QDeclarativeComponent *header) d->header = 0; } d->headerComponent = header; - d->updateHeader(); - d->updateFooter(); - d->updateGrid(); + d->layout(); emit headerChanged(); } } @@ -1820,116 +1573,140 @@ void QDeclarativeGridView::setContentY(qreal pos) bool QDeclarativeGridView::event(QEvent *event) { Q_D(QDeclarativeGridView); - if (event->type() == QEvent::User) { + QScroller *scroller = QScroller::scroller(this); + + switch (event->type()) { + case QEvent::User: d->layout(); return true; + + case QEvent::ScrollPrepare: { + qreal snapOffset = 0; + bool forceSnapping = false; + // bool useEndPosition = false; + bool ignoreHeaders = false; + + // --- do the highlight range + if (d->haveHighlightRange) { + snapOffset = -d->highlightRangeStart; + ignoreHeaders = true; + } + + // just before scrolling set the snap points if needed + QList snapPoints; + // -- snap to every point (SnapToRow) + if (d->snapMode == QDeclarativeGridView::SnapToRow || forceSnapping) { + if (d->header && !ignoreHeaders) + snapPoints.append(0 + snapOffset); + foreach (FxGridItem *item, d->visibleItems) + snapPoints.append(item->rowPos() + snapOffset); + if (d->footer && !ignoreHeaders) + snapPoints.append(d->headerSize() + d->contentSize() + snapOffset); + + // -- snap to the next three point (SnapOneRow) + } else if (d->snapMode == QDeclarativeGridView::SnapOneRow) { + // here we just set three snap points around the current position. + + qreal rowPos = d->rowPosAt(d->currentIndex); + if (rowPos - d->rowSize() >= 0) + snapPoints.append( rowPos - d->rowSize()); + else if( d->header ) + snapPoints.append(0); // position of the header + + snapPoints.append(rowPos); + + if (rowPos + d->rowSize() < d->headerSize() + d->contentSize()) + snapPoints.append(rowPos + d->rowSize()); + else if( d->footer ) + snapPoints.append(d->headerSize() + d->contentSize() + snapOffset); // position of the footer + } + + if (d->flow == QDeclarativeGridView::LeftToRight) { + scroller->setSnapPositionsX(0.0, 0.0); + scroller->setSnapPositionsY(snapPoints); + } else { + scroller->setSnapPositionsX(snapPoints); + scroller->setSnapPositionsY(0.0, 0.0); + } + } + break; + + default: + break; } return QDeclarativeFlickable::event(event); } -void QDeclarativeGridView::viewportMoved() +void QDeclarativeGridView::scrollerStateChanged(QScroller::State state) { Q_D(QDeclarativeGridView); - QDeclarativeFlickable::viewportMoved(); - if (!d->itemCount) - return; - d->lazyRelease = true; - if (d->flickingHorizontally || d->flickingVertically) { - if (yflick()) { - if (d->vData.velocity > 0) - d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore; - else if (d->vData.velocity < 0) - d->bufferMode = QDeclarativeGridViewPrivate::BufferAfter; - } + QDeclarativeFlickable::scrollerStateChanged(state); - if (xflick()) { - if (d->hData.velocity > 0) - d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore; - else if (d->hData.velocity < 0) - d->bufferMode = QDeclarativeGridViewPrivate::BufferAfter; - } - } - refill(); - if (d->flickingHorizontally || d->flickingVertically || d->movingHorizontally || d->movingVertically) - d->moveReason = QDeclarativeGridViewPrivate::Mouse; - if (d->moveReason != QDeclarativeGridViewPrivate::SetIndex) { - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) { - // reposition highlight - qreal pos = d->highlight->rowPos(); - qreal viewPos = d->position(); - if (pos > viewPos + d->highlightRangeEnd - d->rowSize()) - pos = viewPos + d->highlightRangeEnd - d->rowSize(); - if (pos < viewPos + d->highlightRangeStart) - pos = viewPos + d->highlightRangeStart; - d->highlight->setPosition(d->highlight->colPos(), qRound(pos)); - - // update current index - int idx = d->snapIndex(); - if (idx >= 0 && idx != d->currentIndex) { - d->updateCurrent(idx); - if (d->currentItem && d->currentItem->colPos() != d->highlight->colPos() && d->autoHighlight) { - if (d->flow == LeftToRight) - d->highlightXAnimator->to = d->currentItem->item->x(); - else - d->highlightYAnimator->to = d->currentItem->item->y(); - } - } + if (state == QScroller::Inactive) { + d->bufferMode = QDeclarativeGridViewPrivate::NoBuffer; + if (d->highlightRange == QDeclarativeGridView::StrictlyEnforceRange) { + d->updateHighlight(); // nudge the highlight in the right position if needed. } } } -qreal QDeclarativeGridView::minYExtent() const +qreal QDeclarativeGridView::minExtent() const { Q_D(const QDeclarativeGridView); - if (d->flow == QDeclarativeGridView::TopToBottom) - return QDeclarativeFlickable::minYExtent(); - qreal extent = -d->startPosition(); - if (d->header && d->visibleItems.count()) - extent += d->header->item->height(); - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - extent += d->highlightRangeStart; - extent = qMax(extent, -(d->rowPosAt(0) + d->rowSize() - d->highlightRangeEnd)); + + qreal extent = 0.0; + if (d->modelCount && + d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + extent -= d->highlightRangeStart; + // extent = qMax(extent, -(d->rowPosAt(0) + d->rowSize() - d->highlightRangeEnd)); } return extent; } -qreal QDeclarativeGridView::maxYExtent() const +qreal QDeclarativeGridView::maxExtent() const { Q_D(const QDeclarativeGridView); - if (d->flow == QDeclarativeGridView::TopToBottom) - return QDeclarativeFlickable::maxYExtent(); - qreal extent; - if (!d->model || !d->model->count()) { - extent = 0; - } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - extent = -(d->rowPosAt(d->model->count()-1) - d->highlightRangeStart); - if (d->highlightRangeEnd != d->highlightRangeStart) - extent = qMin(extent, -(d->endPosition() - d->highlightRangeEnd + 1)); - } else { - extent = -(d->endPosition() - height()); + + qreal extent = d->contentSize(); + extent += d->headerSize(); + extent += d->footerSize(); + + if (d->visibleItems.count() && + d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + extent = qMin(extent + d->size() - d->highlightRangeEnd + 1, + // ensure that the last item fits fully behind hightlightRangeStart + d->rowPosAt(d->modelCount-1) + d->size() - d->highlightRangeStart); } - if (d->footer) - extent -= d->footer->item->height(); - const qreal minY = minYExtent(); - if (extent > minY) - extent = minY; + return extent; } +qreal QDeclarativeGridView::minYExtent() const +{ + Q_D(const QDeclarativeGridView); + if (d->flow != QDeclarativeGridView::LeftToRight) + return QDeclarativeFlickable::minXExtent(); + else + return minExtent(); +} + +qreal QDeclarativeGridView::maxYExtent() const +{ + Q_D(const QDeclarativeGridView); + if (d->flow != QDeclarativeGridView::LeftToRight) + return QDeclarativeFlickable::maxXExtent(); + else + return maxExtent(); +} + qreal QDeclarativeGridView::minXExtent() const { Q_D(const QDeclarativeGridView); if (d->flow == QDeclarativeGridView::LeftToRight) return QDeclarativeFlickable::minXExtent(); - qreal extent = -d->startPosition(); - if (d->header && d->visibleItems.count()) - extent += d->header->item->width(); - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - extent += d->highlightRangeStart; - extent = qMax(extent, -(d->rowPosAt(0) + d->rowSize() - d->highlightRangeEnd)); - } - return extent; + else + return minExtent(); } qreal QDeclarativeGridView::maxXExtent() const @@ -1937,32 +1714,70 @@ qreal QDeclarativeGridView::maxXExtent() const Q_D(const QDeclarativeGridView); if (d->flow == QDeclarativeGridView::LeftToRight) return QDeclarativeFlickable::maxXExtent(); - qreal extent; - if (!d->model || !d->model->count()) { - extent = 0; - } if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - extent = -(d->rowPosAt(d->model->count()-1) - d->highlightRangeStart); - if (d->highlightRangeEnd != d->highlightRangeStart) - extent = qMin(extent, -(d->endPosition() - d->highlightRangeEnd + 1)); - } else { - extent = -(d->endPosition() - width()); + else + return maxExtent(); +} + +void QDeclarativeGridView::viewportAboutToMove(QPointF newPos) +{ + Q_D(QDeclarativeGridView); + + // need to refill before moving + if (d->flow == LeftToRight) + d->refill(newPos.y(), newPos.y() + height() - 1); + else + d->refill(newPos.x(), newPos.x() + width() - 1); + + d->lazyRelease = true; + + if (isFlickingHorizontally()) { + if (horizontalVelocity() > 0) + d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore; + else if (horizontalVelocity() < 0) + d->bufferMode = QDeclarativeGridViewPrivate::BufferAfter; + + } else if (isFlickingVertically()) { + if (verticalVelocity() > 0) + d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore; + else if (verticalVelocity() < 0) + d->bufferMode = QDeclarativeGridViewPrivate::BufferAfter; + } + + if (d->isUserGenerated) + d->moveReason = QDeclarativeGridViewPrivate::Mouse; + + if (d->haveHighlightRange && d->highlight && d->highlightRange == StrictlyEnforceRange) { + + d->highlightXAnimator->stop(); + d->highlightYAnimator->stop(); + + // reposition highlight + qreal pos = d->highlight->rowPos(); + qreal viewPos = (d->flow == QDeclarativeGridView::LeftToRight) ? newPos.y() : newPos.x(); + if (pos > viewPos + d->highlightRangeEnd - d->rowSize()) + pos = viewPos + d->highlightRangeEnd - d->rowSize(); + if (pos < viewPos + d->highlightRangeStart) + pos = viewPos + d->highlightRangeStart; + d->highlight->setPosition(d->highlight->colPos(), pos); + + // update current index + if (d->moveReason != QDeclarativeGridViewPrivate::SetIndex) { + int idx = d->snapIndex(); + if (idx >= 0 && idx != d->currentIndex) { + d->setCurrentIndex(idx); + } + } } - if (d->footer) - extent -= d->footer->item->width(); - const qreal minX = minXExtent(); - if (extent > minX) - extent = minX; - return extent; } void QDeclarativeGridView::keyPressEvent(QKeyEvent *event) { Q_D(QDeclarativeGridView); keyPressPreHandler(event); + if (event->isAccepted()) return; - if (d->model && d->model->count() && d->interactive) { - d->moveReason = QDeclarativeGridViewPrivate::SetIndex; + if (d->model && d->modelCount && d->interactive) { int oldCurrent = currentIndex(); switch (event->key()) { case Qt::Key_Up: @@ -1985,7 +1800,6 @@ void QDeclarativeGridView::keyPressEvent(QKeyEvent *event) return; } } - d->moveReason = QDeclarativeGridViewPrivate::Other; event->ignore(); QDeclarativeFlickable::keyPressEvent(event); } @@ -2002,7 +1816,7 @@ void QDeclarativeGridView::keyPressEvent(QKeyEvent *event) void QDeclarativeGridView::moveCurrentIndexUp() { Q_D(QDeclarativeGridView); - const int count = d->model ? d->model->count() : 0; + const int count = d->modelCount; if (!count) return; if (d->flow == QDeclarativeGridView::LeftToRight) { @@ -2030,7 +1844,7 @@ void QDeclarativeGridView::moveCurrentIndexUp() void QDeclarativeGridView::moveCurrentIndexDown() { Q_D(QDeclarativeGridView); - const int count = d->model ? d->model->count() : 0; + const int count = d->modelCount; if (!count) return; if (d->flow == QDeclarativeGridView::LeftToRight) { @@ -2058,7 +1872,7 @@ void QDeclarativeGridView::moveCurrentIndexDown() void QDeclarativeGridView::moveCurrentIndexLeft() { Q_D(QDeclarativeGridView); - const int count = d->model ? d->model->count() : 0; + const int count = d->modelCount; if (!count) return; if (d->flow == QDeclarativeGridView::LeftToRight) { @@ -2086,7 +1900,7 @@ void QDeclarativeGridView::moveCurrentIndexLeft() void QDeclarativeGridView::moveCurrentIndexRight() { Q_D(QDeclarativeGridView); - const int count = d->model ? d->model->count() : 0; + const int count = d->modelCount; if (!count) return; if (d->flow == QDeclarativeGridView::LeftToRight) { @@ -2137,7 +1951,7 @@ void QDeclarativeGridView::moveCurrentIndexRight() void QDeclarativeGridView::positionViewAtIndex(int index, int mode) { Q_D(QDeclarativeGridView); - if (!d->isValid() || index < 0 || index >= d->model->count()) + if (!d->isValid() || index < 0 || index >= d->modelCount) return; if (mode < Beginning || mode > Contain) return; @@ -2182,15 +1996,12 @@ void QDeclarativeGridView::positionViewAtIndex(int index, int mode) if (itemPos < pos) pos = itemPos; } - qreal maxExtent = d->flow == QDeclarativeGridView::LeftToRight ? -maxYExtent() : -maxXExtent(); - pos = qMin(pos, maxExtent); - qreal minExtent = d->flow == QDeclarativeGridView::LeftToRight ? -minYExtent() : -minXExtent(); - pos = qMax(pos, minExtent); + pos += d->headerSize(); + pos = qMin(pos, maxExtent() - d->size()); + pos = qMax(pos, minExtent()); d->moveReason = QDeclarativeGridViewPrivate::Other; - cancelFlick(); d->setPosition(pos); } - d->fixupPosition(); } /*! @@ -2221,95 +2032,43 @@ void QDeclarativeGridView::componentComplete() { Q_D(QDeclarativeGridView); QDeclarativeFlickable::componentComplete(); - d->updateGrid(); + d->layout(); if (d->isValid()) { refill(); d->moveReason = QDeclarativeGridViewPrivate::SetIndex; if (d->currentIndex < 0 && !d->currentIndexCleared) - d->updateCurrent(0); + d->setCurrentIndex(0); else - d->updateCurrent(d->currentIndex); + d->setCurrentIndex(d->currentIndex); if (d->highlight && d->currentItem) { d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); - d->updateTrackedItem(); } - d->moveReason = QDeclarativeGridViewPrivate::Other; - d->fixupPosition(); + d->updateHighlight(false); } } -void QDeclarativeGridView::trackedPositionChanged() +void QDeclarativeGridView::itemsInserted(int modelIndex, int count) { Q_D(QDeclarativeGridView); - if (!d->trackedItem || !d->currentItem) + + if (!isComponentComplete()) { + d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count return; - if (d->moveReason == QDeclarativeGridViewPrivate::SetIndex) { - const qreal trackedPos = d->trackedItem->rowPos(); - const qreal viewPos = d->position(); - qreal pos = viewPos; - if (d->haveHighlightRange) { - if (d->highlightRange == StrictlyEnforceRange) { - if (trackedPos > pos + d->highlightRangeEnd - d->rowSize()) - pos = trackedPos - d->highlightRangeEnd + d->rowSize(); - if (trackedPos < pos + d->highlightRangeStart) - pos = trackedPos - d->highlightRangeStart; - } else { - if (trackedPos < d->startPosition() + d->highlightRangeStart) { - pos = d->startPosition(); - } else if (d->trackedItem->endRowPos() > d->endPosition() - d->size() + d->highlightRangeEnd) { - pos = d->endPosition() - d->size() + 1; - if (pos < d->startPosition()) - pos = d->startPosition(); - } else { - if (trackedPos < viewPos + d->highlightRangeStart) { - pos = trackedPos - d->highlightRangeStart; - } else if (trackedPos > viewPos + d->highlightRangeEnd - d->rowSize()) { - pos = trackedPos - d->highlightRangeEnd + d->rowSize(); - } - } - } - } else { - if (trackedPos < viewPos && d->currentItem->rowPos() < viewPos) { - pos = d->currentItem->rowPos() < trackedPos ? trackedPos : d->currentItem->rowPos(); - } else if (d->trackedItem->endRowPos() >= viewPos + d->size() - && d->currentItem->endRowPos() >= viewPos + d->size()) { - if (d->trackedItem->endRowPos() <= d->currentItem->endRowPos()) { - pos = d->trackedItem->endRowPos() - d->size() + 1; - if (d->rowSize() > d->size()) - pos = trackedPos; - } else { - pos = d->currentItem->endRowPos() - d->size() + 1; - if (d->rowSize() > d->size()) - pos = d->currentItem->rowPos(); - } - } - } - if (viewPos != pos) { - cancelFlick(); - d->calcVelocity = true; - d->setPosition(pos); - d->calcVelocity = false; - } } -} -void QDeclarativeGridView::itemsInserted(int modelIndex, int count) -{ - Q_D(QDeclarativeGridView); - if (!isComponentComplete()) - return; + d->moveReason = QDeclarativeGridViewPrivate::Other; if (!d->visibleItems.count() || d->model->count() <= 1) { d->scheduleLayout(); - if (d->itemCount && d->currentIndex >= modelIndex) { + if (d->modelCount && d->currentIndex >= modelIndex) { // adjust current item index d->currentIndex += count; if (d->currentItem) d->currentItem->index = d->currentIndex; emit currentIndexChanged(); } else if (!d->currentIndex || (d->currentIndex < 0 && !d->currentIndexCleared)) { - d->updateCurrent(0); + d->setCurrentIndex(0); } - d->itemCount += count; + d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count emit countChanged(); return; } @@ -2340,7 +2099,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) emit currentIndexChanged(); } d->scheduleLayout(); - d->itemCount += count; + d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count emit countChanged(); return; } @@ -2414,7 +2173,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) } } - if (d->itemCount && d->currentIndex >= modelIndex) { + if (d->modelCount && d->currentIndex >= modelIndex) { // adjust current item index d->currentIndex += count; if (d->currentItem) { @@ -2428,17 +2187,17 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) for (int j = 0; j < added.count(); ++j) added.at(j)->attached->emitAdd(); - d->itemCount += count; + d->modelCount += count; emit countChanged(); } void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) { Q_D(QDeclarativeGridView); + d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count if (!isComponentComplete()) return; - d->itemCount -= count; bool currentRemoved = d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count; bool removedVisible = false; @@ -2486,8 +2245,8 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) d->releaseItem(d->currentItem); d->currentItem = 0; d->currentIndex = -1; - if (d->itemCount) - d->updateCurrent(qMin(modelIndex, d->itemCount-1)); + if (d->modelCount) + d->setCurrentIndex(qMin(modelIndex, d->modelCount-1)); } // update visibleIndex @@ -2500,13 +2259,7 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) } if (removedVisible && d->visibleItems.isEmpty()) { - d->timeline.clear(); - if (d->itemCount == 0) { d->setPosition(0); - d->updateHeader(); - d->updateFooter(); - update(); - } } emit countChanged(); @@ -2634,14 +2387,13 @@ void QDeclarativeGridView::modelReset() { Q_D(QDeclarativeGridView); d->clear(); + d->modelCount = d->model->count(); refill(); d->moveReason = QDeclarativeGridViewPrivate::SetIndex; - d->updateCurrent(d->currentIndex); + d->setCurrentIndex(d->currentIndex); if (d->highlight && d->currentItem) { d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); - d->updateTrackedItem(); } - d->moveReason = QDeclarativeGridViewPrivate::Other; emit countChanged(); } @@ -2666,14 +2418,6 @@ void QDeclarativeGridView::destroyingItem(QDeclarativeItem *item) d->unrequestedItems.remove(item); } -void QDeclarativeGridView::animStopped() -{ - Q_D(QDeclarativeGridView); - d->bufferMode = QDeclarativeGridViewPrivate::NoBuffer; - if (d->haveHighlightRange && d->highlightRange == QDeclarativeGridView::StrictlyEnforceRange) - d->updateHighlight(); -} - void QDeclarativeGridView::refill() { Q_D(QDeclarativeGridView); diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h index ee632b1..22407f4 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview_p.h +++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h @@ -188,18 +188,22 @@ Q_SIGNALS: void headerChanged(); void footerChanged(); +protected Q_SLOTS: + void scrollerStateChanged(QScroller::State state); + protected: virtual bool event(QEvent *event); - virtual void viewportMoved(); + virtual qreal minExtent() const; + virtual qreal maxExtent() const; virtual qreal minYExtent() const; virtual qreal maxYExtent() const; virtual qreal minXExtent() const; virtual qreal maxXExtent() const; + virtual void viewportAboutToMove(QPointF newPos); virtual void keyPressEvent(QKeyEvent *); virtual void componentComplete(); private Q_SLOTS: - void trackedPositionChanged(); void itemsInserted(int index, int count); void itemsRemoved(int index, int count); void itemsMoved(int from, int to, int count); @@ -207,7 +211,6 @@ private Q_SLOTS: void destroyRemoved(); void createdItem(int index, QDeclarativeItem *item); void destroyingItem(QDeclarativeItem *item); - void animStopped(); private: void refill(); diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 450b6af..27f7b52 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -56,6 +56,11 @@ QT_BEGIN_NAMESPACE +template static const T &forceConst(const T &t) +{ + return t; +} + void QDeclarativeViewSection::setProperty(const QString &property) { if (property != m_property) { @@ -93,40 +98,62 @@ QString QDeclarativeViewSection::sectionString(const QString &value) class FxListItem { public: - FxListItem(QDeclarativeItem *i, QDeclarativeListView *v) : item(i), section(0), view(v) { + FxListItem(QDeclarativeItem *i, QDeclarativeListView *v) + : item(i), section(0), view(v) + { attached = static_cast(qmlAttachedPropertiesObject(item)); if (attached) attached->setView(view); } + ~FxListItem() {} + + /*! /internal + The position of the item plus section header. + */ qreal position() const { if (section) return (view->orientation() == QDeclarativeListView::Vertical ? section->y() : section->x()); else return (view->orientation() == QDeclarativeListView::Vertical ? item->y() : item->x()); } + + /*! /internal + The position of the item itself + */ qreal itemPosition() const { return (view->orientation() == QDeclarativeListView::Vertical ? item->y() : item->x()); } + + /*! /internal + The size of the item plus section header. + */ qreal size() const { if (section) return (view->orientation() == QDeclarativeListView::Vertical ? item->height()+section->height() : item->width()+section->width()); else return (view->orientation() == QDeclarativeListView::Vertical ? item->height() : item->width()); } + + /*! /internal + The size of the item itself + */ qreal itemSize() const { return (view->orientation() == QDeclarativeListView::Vertical ? item->height() : item->width()); } + qreal sectionSize() const { if (section) return (view->orientation() == QDeclarativeListView::Vertical ? section->height() : section->width()); return 0.0; } + qreal endPosition() const { return (view->orientation() == QDeclarativeListView::Vertical ? item->y() + (item->height() >= 1.0 ? item->height() : 1) : item->x() + (item->width() >= 1.0 ? item->width() : 1)) - 1; } + void setPosition(qreal pos) { if (view->orientation() == QDeclarativeListView::Vertical) { if (section) { @@ -142,12 +169,14 @@ public: item->setX(pos); } } + void setSize(qreal size) { if (view->orientation() == QDeclarativeListView::Vertical) item->setHeight(size); else item->setWidth(size); } + bool contains(int x, int y) const { return (x >= item->x() && x < item->x() + item->width() && y >= item->y() && y < item->y() + item->height()); @@ -171,19 +200,22 @@ public: : currentItem(0), orient(QDeclarativeListView::Vertical) , visiblePos(0), visibleIndex(0) , averageSize(100.0), currentIndex(-1), requestedIndex(-1) - , itemCount(0), highlightRangeStart(0), highlightRangeEnd(0) - , highlightComponent(0), highlight(0), trackedItem(0) + , modelCount(0) + , highlightRangeStart(0), highlightRangeEnd(0) + , highlightComponent(0), highlight(0) , moveReason(Other), buffer(0), highlightPosAnimator(0), highlightSizeAnimator(0) , sectionCriteria(0), spacing(0.0) , highlightMoveSpeed(400), highlightMoveDuration(-1) , highlightResizeSpeed(400), highlightResizeDuration(-1), highlightRange(QDeclarativeListView::NoHighlightRange) - , snapMode(QDeclarativeListView::NoSnap), overshootDist(0.0) - , footerComponent(0), footer(0), headerComponent(0), header(0) + , snapMode(QDeclarativeListView::NoSnap) + , footerComponent(0), footer(0) + , headerComponent(0), header(0) , bufferMode(BufferBefore | BufferAfter) , ownModel(false), wrap(false), autoHighlight(true), haveHighlightRange(false) - , correctFlick(false), inFlickCorrection(false), lazyRelease(false) - , deferredRelease(false), layoutScheduled(false), currentIndexCleared(false) - , inViewportMoved(false) + , lazyRelease(false) + , deferredRelease(false) + , layoutScheduled(false) + , currentIndexCleared(false) , minExtentDirty(true), maxExtentDirty(true) {} @@ -228,10 +260,25 @@ public: return 0; } + /*! \internal + Returns the last visible model index. delayRemove items are not counted (as they don't have an index) + */ + int lastVisibleIndex() const + { + // find the last valid model index + for (int i = visibleItems.count() - 1; i >= 0; --i) { + FxListItem *item = visibleItems.at(i); + if (item->index != -1) + return item->index; + } + return visibleIndex; + } + qreal position() const { Q_Q(const QDeclarativeListView); return orient == QDeclarativeListView::Vertical ? q->contentY() : q->contentX(); } + void setPosition(qreal pos) { Q_Q(QDeclarativeListView); if (orient == QDeclarativeListView::Vertical) @@ -239,33 +286,53 @@ public: else q->QDeclarativeFlickable::setContentX(pos); } + + void scrollToPosition(qreal pos) { + Q_Q(QDeclarativeListView); + if (orient == QDeclarativeListView::Vertical) + QScroller::scroller(q)->scrollTo(QPointF(q->contentX(), pos)); + else + QScroller::scroller(q)->scrollTo(QPointF(pos, q->contentY())); + } + qreal size() const { Q_Q(const QDeclarativeListView); return orient == QDeclarativeListView::Vertical ? q->height() : q->width(); } + /*! /internal + Estimates the current position of the first visible item counting the header (the first item starts at position header->size()). + */ qreal startPosition() const { qreal pos = 0; if (!visibleItems.isEmpty()) { - pos = (*visibleItems.constBegin())->position(); - if (visibleIndex > 0) - pos -= visibleIndex * (averageSize + spacing); + pos = visibleItems.first()->position(); + pos -= visibleIndex * (averageSize + spacing); } + if( header ) + pos -= header->size(); return pos; } + /*! /internal + Estimates the full length of the list including header and footer. + */ qreal endPosition() const { - qreal pos = 0; + qreal pos = -1; if (!visibleItems.isEmpty()) { int invisibleCount = visibleItems.count() - visibleIndex; + for (int i = visibleItems.count()-1; i >= 0; --i) { if (visibleItems.at(i)->index != -1) { - invisibleCount = model->count() - visibleItems.at(i)->index - 1; + invisibleCount = modelCount - visibleItems.at(i)->index - 1; + pos = visibleItems.at(i)->endPosition(); break; } } - pos = (*(--visibleItems.constEnd()))->endPosition() + invisibleCount * (averageSize + spacing); + pos = visibleItems.last()->endPosition() + invisibleCount * (averageSize + spacing); } + if (footer) + pos += footer->size(); return pos; } @@ -280,17 +347,10 @@ public: cs = currentItem->size() + spacing; --count; } - return (*visibleItems.constBegin())->position() - count * (averageSize + spacing) - cs; + return forceConst(visibleItems).first()->position() - count * (averageSize + spacing) - cs; } else { - int idx = visibleItems.count() - 1; - while (idx >= 0 && visibleItems.at(idx)->index == -1) - --idx; - if (idx < 0) - idx = visibleIndex; - else - idx = visibleItems.at(idx)->index; - int count = modelIndex - idx - 1; - return (*(--visibleItems.constEnd()))->endPosition() + spacing + count * (averageSize + spacing) + 1; + int count = modelIndex - lastVisibleIndex() - 1; + return forceConst(visibleItems).last()->endPosition() + spacing + count * (averageSize + spacing) + 1; } } return 0; @@ -302,17 +362,10 @@ public: if (!visibleItems.isEmpty()) { if (modelIndex < visibleIndex) { int count = visibleIndex - modelIndex; - return (*visibleItems.constBegin())->position() - (count - 1) * (averageSize + spacing) - spacing - 1; + return forceConst(visibleItems).first()->position() - (count - 1) * (averageSize + spacing) - spacing - 1; } else { - int idx = visibleItems.count() - 1; - while (idx >= 0 && visibleItems.at(idx)->index == -1) - --idx; - if (idx < 0) - idx = visibleIndex; - else - idx = visibleItems.at(idx)->index; - int count = modelIndex - idx - 1; - return (*(--visibleItems.constEnd()))->endPosition() + count * (averageSize + spacing); + int count = modelIndex - lastVisibleIndex() - 1; + return forceConst(visibleItems).last()->endPosition() + count * (averageSize + spacing); } } return 0; @@ -332,52 +385,32 @@ public: } bool isValid() const { - return model && model->count() && model->isValid(); + return model && modelCount && model->isValid(); } - qreal snapPosAt(qreal pos) { - if (FxListItem *snapItem = snapItemAt(pos)) - return snapItem->position(); - if (visibleItems.count()) { - qreal firstPos = visibleItems.first()->position(); - qreal endPos = visibleItems.last()->position(); - if (pos < firstPos) { - return firstPos - qRound((firstPos - pos) / averageSize) * averageSize; - } else if (pos > endPos) - return endPos + qRound((pos - endPos) / averageSize) * averageSize; - } - return qRound((pos - startPosition()) / averageSize) * averageSize + startPosition(); - } + /** \internal + Returns the index of the item which is at or around the highlight. + */ + int snapIndex() { + int index = currentIndex; - FxListItem *snapItemAt(qreal pos) { - FxListItem *snapItem = 0; + // qDebug() << "snapIndex" << index << "hp:" << highlight->position() << highlight->size() << "items:" << visibleItems.count(); for (int i = 0; i < visibleItems.count(); ++i) { FxListItem *item = visibleItems[i]; if (item->index == -1) continue; + index = item->index; qreal itemTop = item->position(); - if (highlight && itemTop >= pos && item->endPosition() <= pos + highlight->size() - 1) - return item; - if (itemTop+item->size()/2 >= pos && itemTop-item->size()/2 < pos) - snapItem = item; - } - return snapItem; - } - - int lastVisibleIndex() const { - int lastIndex = -1; - for (int i = visibleItems.count()-1; i >= 0; --i) { - FxListItem *listItem = visibleItems.at(i); - if (listItem->index != -1) { - lastIndex = listItem->index; - break; - } + // qDebug() << " "<size(); + if (itemTop + item->size() / 2 > highlight->position()) + return item->index; } - return lastIndex; + return index; } // map a model index to visibleItems index. - int mapFromModel(int modelIndex) const { + int mapFromModel(int modelIndex) const + { if (modelIndex < visibleIndex || modelIndex >= visibleIndex + visibleItems.count()) return -1; for (int i = 0; i < visibleItems.count(); ++i) { @@ -390,22 +423,28 @@ public: return -1; // Not in visibleList } - void updateViewport() { + void updateViewport() + { Q_Q(QDeclarativeListView); - if (orient == QDeclarativeListView::Vertical) { - q->setContentHeight(endPosition() - startPosition() + 1); - } else { - q->setContentWidth(endPosition() - startPosition() + 1); - } + if (orient == QDeclarativeListView::Vertical) + q->setContentHeight(q->maxExtent() - q->minExtent() + 1); + else + q->setContentWidth(q->maxExtent() - q->minExtent() + 1); } - void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) { - Q_Q(QDeclarativeListView); + void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) + { + + // qDebug() << "itemGeometryChanged" << newGeometry; + + // Q_Q(QDeclarativeListView); QDeclarativeFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry); if (item != contentItem && (!highlight || item != highlight->item)) { if ((orient == QDeclarativeListView::Vertical && newGeometry.height() != oldGeometry.height()) || (orient == QDeclarativeListView::Horizontal && newGeometry.width() != oldGeometry.width())) { scheduleLayout(); + minExtentDirty = true; + maxExtentDirty = true; } } if ((header && header->item == item) || (footer && footer->item == item)) { @@ -414,8 +453,6 @@ public: } if (currentItem && currentItem->item == item) updateHighlight(); - if (trackedItem && trackedItem->item == item) - q->trackedPositionChanged(); } // for debugging only @@ -436,40 +473,60 @@ public: void layout(); void updateUnrequestedIndexes(); void updateUnrequestedPositions(); - void updateTrackedItem(); - void createHighlight(); - void updateHighlight(); + void recreateHighlight(); + void updateHighlight(bool smooth = true); void createSection(FxListItem *); void updateSections(); void updateCurrentSection(); - void updateCurrent(int); + void setCurrentIndex(int); void updateAverage(); void updateHeader(); void updateFooter(); - void fixupPosition(); - virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent); - virtual void flick(QDeclarativeFlickablePrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, - QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity); QDeclarativeGuard model; QVariant modelVariant; QList visibleItems; + + /* + These are items that were not requested but send by createdItem from the model. + Usually these items were created because another view showing the same model + needed them. + */ QHash unrequestedItems; + FxListItem *currentItem; QDeclarativeListView::Orientation orient; + + /* + This is the position of the first visible item. + It is stored in case when all items are deleted and we need to create new + ones. + */ qreal visiblePos; + + /* + The visibleIndex is the modelIndex of the first item in visibleItems with an index != -1 + */ int visibleIndex; qreal averageSize; - int currentIndex; + int currentIndex; // the model index of the currentItem + + /* + The model index of the item that is currently created via createItem + */ int requestedIndex; - int itemCount; + + /* + This is the number of items in the model. + */ + int modelCount; + qreal highlightRangeStart; qreal highlightRangeEnd; QDeclarativeComponent *highlightComponent; FxListItem *highlight; - FxListItem *trackedItem; enum MovementReason { Other, SetIndex, Mouse }; - MovementReason moveReason; + MovementReason moveReason; // the moveReason determines if the highlight needs to be centered or if the currentItem needs to be changed. int buffer; QSmoothedAnimation *highlightPosAnimator; QSmoothedAnimation *highlightSizeAnimator; @@ -484,7 +541,6 @@ public: int highlightResizeDuration; QDeclarativeListView::HighlightRangeMode highlightRange; QDeclarativeListView::SnapMode snapMode; - qreal overshootDist; QDeclarativeComponent *footerComponent; FxListItem *footer; QDeclarativeComponent *headerComponent; @@ -498,13 +554,10 @@ public: bool wrap : 1; bool autoHighlight : 1; bool haveHighlightRange : 1; - bool correctFlick : 1; - bool inFlickCorrection : 1; bool lazyRelease : 1; bool deferredRelease : 1; bool layoutScheduled : 1; bool currentIndexCleared : 1; - bool inViewportMoved : 1; mutable bool minExtentDirty : 1; mutable bool maxExtentDirty : 1; }; @@ -514,14 +567,12 @@ void QDeclarativeListViewPrivate::init() Q_Q(QDeclarativeListView); q->setFlag(QGraphicsItem::ItemIsFocusScope); addItemChangeListener(this, Geometry); - QObject::connect(q, SIGNAL(movementEnded()), q, SLOT(animStopped())); q->setFlickableDirection(QDeclarativeFlickable::VerticalFlick); ::memset(sectionCache, 0, sizeof(QDeclarativeItem*) * sectionCacheSize); } void QDeclarativeListViewPrivate::clear() { - timeline.clear(); for (int i = 0; i < visibleItems.count(); ++i) releaseItem(visibleItems.at(i)); visibleItems.clear(); @@ -533,13 +584,20 @@ void QDeclarativeListViewPrivate::clear() visibleIndex = 0; releaseItem(currentItem); currentItem = 0; - createHighlight(); - trackedItem = 0; + recreateHighlight(); minExtentDirty = true; maxExtentDirty = true; - itemCount = 0; + modelCount = 0; + + setPosition(0); + updateHeader(); + updateFooter(); } +/** \internal + Tries to create the FxListItem for the given model index. + \returns the item or 0 if the item could not be created. +*/ FxListItem *QDeclarativeListViewPrivate::createItem(int modelIndex) { Q_Q(QDeclarativeListView); @@ -559,13 +617,16 @@ FxListItem *QDeclarativeListViewPrivate::createItem(int modelIndex) else listItem->attached->m_prevSection = sectionAt(modelIndex-1); } - if (modelIndex < model->count()-1) { + if (modelIndex < modelCount - 1) { if (FxListItem *item = visibleItem(modelIndex+1)) listItem->attached->m_nextSection = item->attached->section(); else listItem->attached->m_nextSection = sectionAt(modelIndex+1); } } + + // qDebug() << "createItem"<completePending()) { // complete listItem->item->setZValue(1); @@ -592,9 +653,10 @@ void QDeclarativeListViewPrivate::releaseItem(FxListItem *item) Q_Q(QDeclarativeListView); if (!item || !model) return; - if (trackedItem == item) - trackedItem = 0; QDeclarativeItemPrivate *itemPrivate = static_cast(QGraphicsItemPrivate::get(item->item)); + + // qDebug() << "releaseItem"<<(currentItem==item?"current":(highlight==item?"highlight":"normal"))<index<<"at"<< item->position(); + itemPrivate->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry); if (model->release(item->item) == 0) { // item was not destroyed, and we no longer reference it. @@ -616,12 +678,20 @@ void QDeclarativeListViewPrivate::releaseItem(FxListItem *item) delete item; } +/** \internal + Updates the visible items so that they cover the from and to range. + updateViewport should be called afterwards to handle cases where + the viewport size is changed by different sized items. +*/ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) { Q_Q(QDeclarativeListView); if (!isValid() || !q->isComponentComplete()) return; - itemCount = model->count(); + + if (!doBuffer && buffer && bufferMode != NoBuffer) + doBuffer = true; + qreal bufferFrom = from - buffer; qreal bufferTo = to + buffer; qreal fillFrom = from; @@ -631,34 +701,55 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) if (doBuffer && (bufferMode & BufferBefore)) fillFrom = bufferFrom; - int modelIndex = visibleIndex; - qreal itemEnd = visiblePos-1; + bool changed = false; + + // -- layout the items if (!visibleItems.isEmpty()) { - visiblePos = (*visibleItems.constBegin())->position(); - itemEnd = (*(--visibleItems.constEnd()))->endPosition() + spacing; - int i = visibleItems.count() - 1; - while (i > 0 && visibleItems.at(i)->index == -1) - --i; - modelIndex = visibleItems.at(i)->index + 1; + qreal oldEnd = forceConst(visibleItems).last()->endPosition(); + qreal pos = forceConst(visibleItems).first()->position() + forceConst(visibleItems).first()->size() + spacing; + for (int i=1; i < visibleItems.count(); ++i) { + FxListItem *item = visibleItems.at(i); + if (item->position() != pos) { + // qDebug() << "Moved item"<position()<<"to"<setPosition(pos); + // changed = true; + } + pos += item->size() + spacing; + } + // move current item if it is after the visible items. + if (currentItem && currentIndex > lastVisibleIndex()) + currentItem->setPosition(currentItem->position() + (forceConst(visibleItems).last()->endPosition() - oldEnd)); } - bool changed = false; + qreal endPos = visiblePos; + int modelIndex = lastVisibleIndex(); + if (!visibleItems.isEmpty()) { + endPos = forceConst(visibleItems).last()->endPosition() + spacing + 1; + modelIndex++; + } + + // qDebug() << "REFILL: from" << from << "to" << to << "doBuffer" << doBuffer << "visiblePos" << visiblePos << "endPos" << endPos << "lvindex" << lastVisibleIndex() << "mindex" << modelIndex; + + FxListItem *item = 0; - qreal pos = itemEnd + 1; - while (modelIndex < model->count() && pos <= fillTo) { -// qDebug() << "refill: append item" << modelIndex << "pos" << pos; + + // -- add items to the back + while (modelIndex < modelCount && endPos <= fillTo) { + // qDebug() << "refill: append item" << modelIndex << "endPos" << endPos; if (!(item = createItem(modelIndex))) break; - item->setPosition(pos); - pos += item->size() + spacing; + item->setPosition(endPos); + endPos += item->size() + spacing; visibleItems.append(item); ++modelIndex; changed = true; if (doBuffer) // never buffer more than one item per frame break; } - while (visibleIndex > 0 && visibleIndex <= model->count() && visiblePos-1 >= fillFrom) { -// qDebug() << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos; + + // -- add items to the front + while (visibleIndex > 0 && visibleIndex <= modelCount && visiblePos-1 >= fillFrom) { + // qDebug() << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos; if (!(item = createItem(visibleIndex-1))) break; --visibleIndex; @@ -670,35 +761,56 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) break; } + // TODO: why do we need deferredRelease? Only release every second frame? if (!lazyRelease || !changed || deferredRelease) { // avoid destroying items in the same frame that we create - while (visibleItems.count() > 1 && (item = visibleItems.first()) && item->endPosition() < bufferFrom) { - if (item->attached->delayRemove()) - break; -// qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endPosition(); - if (item->index != -1) - visibleIndex++; - visibleItems.removeFirst(); - releaseItem(item); - changed = true; - } - while (visibleItems.count() > 1 && (item = visibleItems.last()) && item->position() > bufferTo) { - if (item->attached->delayRemove()) - break; -// qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position(); - visibleItems.removeLast(); - releaseItem(item); - changed = true; + if (visibleItems.count() > 1) { + // only delete items if we have more than could be visible + if (forceConst(visibleItems).last()->endPosition() - forceConst(visibleItems).first()->position() > size() ) { + while (!visibleItems.isEmpty() && + (item = forceConst(visibleItems).first()) && item->endPosition() < bufferFrom) { + if (item->attached->delayRemove()) + break; + // qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endPosition(); + if (item->index != -1) + { + visibleIndex++; + // visiblePos += item->size() + spacing; + } + visibleItems.removeFirst(); + releaseItem(item); + changed = true; + } + while (!visibleItems.isEmpty() && + (item = forceConst(visibleItems).last()) && item->position() > bufferTo) { + if (item->attached->delayRemove()) + break; + // qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position(); + if (item->index != -1) + { + // endPos -= item->size() + spacing; + } + visibleItems.removeLast(); + releaseItem(item); + changed = true; + } + } } deferredRelease = false; } else { deferredRelease = true; } + + + if (changed) { + // qDebug()<<"REFILLED: from" << from << "to" << to << "fillFrom" << fillFrom << "fillTo" << fillTo << "endPos:" << endPos << "buffer" << buffer; minExtentDirty = true; maxExtentDirty = true; if (visibleItems.count()) - visiblePos = (*visibleItems.constBegin())->position(); + visiblePos = forceConst(visibleItems).first()->position(); updateAverage(); + + // update the highlight position in cases where we are estimating it if (currentIndex >= 0 && currentItem && !visibleItem(currentIndex)) { currentItem->setPosition(positionAt(currentIndex)); updateHighlight(); @@ -706,16 +818,15 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) if (sectionCriteria) updateCurrentSection(); - if (header) - updateHeader(); - if (footer) - updateFooter(); - updateViewport(); updateUnrequestedPositions(); - } else if (!doBuffer && buffer && bufferMode != NoBuffer) { - refill(from, to, true); + updateScrollerValues(); + updateViewport(); } lazyRelease = false; + if (header) + updateHeader(); + if (footer) + updateFooter(); } void QDeclarativeListViewPrivate::scheduleLayout() @@ -736,31 +847,11 @@ void QDeclarativeListViewPrivate::layout() setPosition(0); return; } - if (!visibleItems.isEmpty()) { - qreal oldEnd = visibleItems.last()->endPosition(); - qreal pos = visibleItems.first()->position() + visibleItems.first()->size() + spacing; - for (int i=1; i < visibleItems.count(); ++i) { - FxListItem *item = visibleItems.at(i); - item->setPosition(pos); - pos += item->size() + spacing; - } - // move current item if it is after the visible items. - if (currentItem && currentIndex > lastVisibleIndex()) - currentItem->setPosition(currentItem->position() + (visibleItems.last()->endPosition() - oldEnd)); - } q->refill(); - minExtentDirty = true; - maxExtentDirty = true; + // qDebug() << "highlight1" << currentItem << highlight; updateHighlight(); - if (!q->isMoving() && !q->isFlicking()) { - fixupPosition(); - q->refill(); - } - if (header) - updateHeader(); - if (footer) - updateFooter(); - updateViewport(); + // qDebug() << "highlight2" << currentItem << highlight; + q->refill(); } void QDeclarativeListViewPrivate::updateUnrequestedIndexes() @@ -790,24 +881,13 @@ void QDeclarativeListViewPrivate::updateUnrequestedPositions() } } -void QDeclarativeListViewPrivate::updateTrackedItem() +void QDeclarativeListViewPrivate::recreateHighlight() { Q_Q(QDeclarativeListView); - FxListItem *item = currentItem; - if (highlight) - item = highlight; - trackedItem = item; - if (trackedItem) - q->trackedPositionChanged(); -} -void QDeclarativeListViewPrivate::createHighlight() -{ - Q_Q(QDeclarativeListView); + // qDebug() << "recreate Highlight"; bool changed = false; if (highlight) { - if (trackedItem == highlight) - trackedItem = 0; delete highlight->item; delete highlight; highlight = 0; @@ -819,6 +899,7 @@ void QDeclarativeListViewPrivate::createHighlight() } if (currentItem) { + // qDebug()<<"new highlight"; QDeclarativeItem *item = 0; if (highlightComponent) { QDeclarativeContext *highlightContext = new QDeclarativeContext(qmlContext(q)); @@ -865,29 +946,76 @@ void QDeclarativeListViewPrivate::createHighlight() changed = true; } } - if (changed) + if (changed) { + updateHighlight(); emit q->highlightItemChanged(); + } } -void QDeclarativeListViewPrivate::updateHighlight() +/* + This function will recreate or delete the highlight (depening on the state) and + then try to move it to a correct position. + It will not update the current item (that is done in viewportMoved() + If \c smooth is set to true then all updates will be using an animation. +*/ +void QDeclarativeListViewPrivate::updateHighlight(bool smooth) { + if ((!currentItem && highlight) || (currentItem && !highlight)) - createHighlight(); - if (currentItem && autoHighlight && highlight && !movingHorizontally && !movingVertically) { - // auto-update highlight - highlightPosAnimator->to = currentItem->itemPosition(); - highlightSizeAnimator->to = currentItem->itemSize(); - if (orient == QDeclarativeListView::Vertical) { - if (highlight->item->width() == 0) - highlight->item->setWidth(currentItem->item->width()); - } else { - if (highlight->item->height() == 0) - highlight->item->setHeight(currentItem->item->height()); + recreateHighlight(); + + // --- move the current item between the highlight range + if (moveReason == QDeclarativeListViewPrivate::SetIndex) { + // ensure that the tracked item is inside the highlight range + + // reposition view + if (currentItem) { + qreal pos = currentItem->position(); + qreal viewPos = position(); + + if (autoHighlight && haveHighlightRange) { + if (pos > viewPos + highlightRangeEnd - currentItem->size()) + viewPos = pos - highlightRangeEnd + currentItem->size(); + if (pos < viewPos + highlightRangeStart) + viewPos = pos - highlightRangeStart; + + } else { + if (pos > viewPos + size() - currentItem->size()) + viewPos = pos - size() + currentItem->size(); + if (pos < viewPos + 0) + viewPos = pos - 0; + } + if (smooth) + scrollToPosition(viewPos); + else + { + setPosition(viewPos); + // qDebug() << "setPos to "<to = currentItem->itemPosition(); + highlightSizeAnimator->to = currentItem->itemSize(); + if (orient == QDeclarativeListView::Vertical) { + if (highlight->item->width() == 0) + highlight->item->setWidth(currentItem->item->width()); + } else { + if (highlight->item->height() == 0) + highlight->item->setHeight(currentItem->item->height()); + } + if (smooth) { + highlightPosAnimator->restart(); + highlightSizeAnimator->restart(); + } else { + highlightPosAnimator->stop(); + highlightSizeAnimator->stop(); + highlight->setPosition(highlightPosAnimator->to); + highlight->setSize(highlightSizeAnimator->to); + } } - highlightPosAnimator->restart(); - highlightSizeAnimator->restart(); } - updateTrackedItem(); } void QDeclarativeListViewPrivate::createSection(FxListItem *listItem) @@ -968,14 +1096,17 @@ void QDeclarativeListViewPrivate::updateSections() } } if (prevAtt) { - if (idx > 0 && idx < model->count()-1) - prevAtt->setNextSection(sectionAt(idx+1)); + if (idx > 0 && idx < modelCount - 1) + prevAtt->setNextSection(sectionAt(idx + 1)); else prevAtt->setNextSection(QString()); } } } +/** \internal + Updates the currentSection variable and emits the changed signals. +*/ void QDeclarativeListViewPrivate::updateCurrentSection() { Q_Q(QDeclarativeListView); @@ -986,6 +1117,7 @@ void QDeclarativeListViewPrivate::updateCurrentSection() } return; } + int index = 0; while (index < visibleItems.count() && visibleItems.at(index)->endPosition() < position()) ++index; @@ -994,61 +1126,56 @@ void QDeclarativeListViewPrivate::updateCurrentSection() if (index < visibleItems.count()) newSection = visibleItems.at(index)->attached->section(); else - newSection = visibleItems.first()->attached->section(); + newSection = forceConst(visibleItems).first()->attached->section(); if (newSection != currentSection) { currentSection = newSection; emit q->currentSectionChanged(); } } -void QDeclarativeListViewPrivate::updateCurrent(int modelIndex) +void QDeclarativeListViewPrivate::setCurrentIndex(int newIndex) { Q_Q(QDeclarativeListView); - if (!q->isComponentComplete() || !isValid() || modelIndex < 0 || modelIndex >= model->count()) { + + // --- release the old item + if (currentItem && currentIndex != newIndex) { + currentItem->attached->setIsCurrentItem(false); + releaseItem(currentItem); + currentItem = 0; + } + + int oldIndex = currentIndex; + currentIndex = newIndex; + + bool visible = (q->isComponentComplete() && isValid() && !currentItem && + newIndex >= 0 && newIndex < modelCount); + + // --- set the new item + if (visible) { + currentItem = createItem(currentIndex); if (currentItem) { - currentItem->attached->setIsCurrentItem(false); - releaseItem(currentItem); - currentItem = 0; - currentIndex = modelIndex; - emit q->currentIndexChanged(); - updateHighlight(); - } else if (currentIndex != modelIndex) { - currentIndex = modelIndex; - emit q->currentIndexChanged(); + if (currentIndex == visibleIndex - 1 && visibleItems.count()) { + // We can calculate exact postion in this case + currentItem->setPosition(forceConst(visibleItems).first()->position() - currentItem->size() - spacing); + } else { + // Create current item now and position as best we can. + // Its position will be corrected when it becomes visible. + currentItem->setPosition(positionAt(currentIndex)); + } + currentItem->item->setFocus(true); + currentItem->attached->setIsCurrentItem(true); + // Avoid showing section delegate twice. We still need the section heading so that + // currentItem positioning works correctly. + // This is slightly sub-optimal, but section heading caching minimizes the impact. + if (currentItem->section) + currentItem->section->setVisible(false); } - return; } - if (currentItem && currentIndex == modelIndex) { - updateHighlight(); - return; - } - FxListItem *oldCurrentItem = currentItem; - currentIndex = modelIndex; - currentItem = createItem(modelIndex); - if (oldCurrentItem && (!currentItem || oldCurrentItem->item != currentItem->item)) - oldCurrentItem->attached->setIsCurrentItem(false); - if (currentItem) { - if (modelIndex == visibleIndex - 1 && visibleItems.count()) { - // We can calculate exact postion in this case - currentItem->setPosition(visibleItems.first()->position() - currentItem->size() - spacing); - } else { - // Create current item now and position as best we can. - // Its position will be corrected when it becomes visible. - currentItem->setPosition(positionAt(modelIndex)); - } - currentItem->item->setFocus(true); - currentItem->attached->setIsCurrentItem(true); - // Avoid showing section delegate twice. We still need the section heading so that - // currentItem positioning works correctly. - // This is slightly sub-optimal, but section heading caching minimizes the impact. - if (currentItem->section) - currentItem->section->setVisible(false); - } - updateHighlight(); - emit q->currentIndexChanged(); - // Release the old current item - releaseItem(oldCurrentItem); + updateHighlight(visible); + + if (currentIndex != oldIndex) + emit q->currentIndexChanged(); } void QDeclarativeListViewPrivate::updateAverage() @@ -1061,13 +1188,13 @@ void QDeclarativeListViewPrivate::updateAverage() averageSize = qRound(sum / visibleItems.count()); } -void QDeclarativeListViewPrivate::updateFooter() +void QDeclarativeListViewPrivate::updateHeader() { Q_Q(QDeclarativeListView); - if (!footer && footerComponent) { + if (!header && headerComponent) { QDeclarativeItem *item = 0; QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q)); - QObject *nobj = footerComponent->create(context); + QObject *nobj = headerComponent->create(context); if (nobj) { QDeclarative_setParent_noEvent(context, nobj); item = qobject_cast(nobj); @@ -1079,35 +1206,26 @@ void QDeclarativeListViewPrivate::updateFooter() if (item) { QDeclarative_setParent_noEvent(item, q->contentItem()); item->setParentItem(q->contentItem()); - item->setZValue(1); + item->setZValue(100); QDeclarativeItemPrivate *itemPrivate = static_cast(QGraphicsItemPrivate::get(item)); itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); - footer = new FxListItem(item, q); + header = new FxListItem(item, q); + if (!visibleItems.isEmpty()) + visiblePos = header->size(); } } - if (footer) { - if (visibleItems.count()) { - qreal endPos = endPosition() + 1; - if (lastVisibleIndex() == model->count()-1) { - footer->setPosition(endPos); - } else { - qreal visiblePos = position() + q->height(); - if (endPos <= visiblePos || footer->position() < endPos) - footer->setPosition(endPos); - } - } else { - footer->setPosition(visiblePos); - } + if (header) { + header->setPosition(startPosition()); } } -void QDeclarativeListViewPrivate::updateHeader() +void QDeclarativeListViewPrivate::updateFooter() { Q_Q(QDeclarativeListView); - if (!header && headerComponent) { + if (!footer && footerComponent) { QDeclarativeItem *item = 0; QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q)); - QObject *nobj = headerComponent->create(context); + QObject *nobj = footerComponent->create(context); if (nobj) { QDeclarative_setParent_noEvent(context, nobj); item = qobject_cast(nobj); @@ -1122,233 +1240,11 @@ void QDeclarativeListViewPrivate::updateHeader() item->setZValue(1); QDeclarativeItemPrivate *itemPrivate = static_cast(QGraphicsItemPrivate::get(item)); itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); - header = new FxListItem(item, q); - if (visibleItems.isEmpty()) - visiblePos = header->size(); - } - } - if (header) { - if (visibleItems.count()) { - qreal startPos = startPosition(); - if (visibleIndex == 0) { - header->setPosition(startPos - header->size()); - } else { - if (position() <= startPos || header->position() > startPos - header->size()) - header->setPosition(startPos - header->size()); - } - } else { - header->setPosition(0); - } - } -} - -void QDeclarativeListViewPrivate::fixupPosition() -{ - if ((haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange) - || snapMode != QDeclarativeListView::NoSnap) - moveReason = Other; - if (orient == QDeclarativeListView::Vertical) - fixupY(); - else - fixupX(); -} - -void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent) -{ - if ((orient == QDeclarativeListView::Horizontal && &data == &vData) - || (orient == QDeclarativeListView::Vertical && &data == &hData)) - return; - - correctFlick = false; - int oldDuration = fixupDuration; - fixupDuration = moveReason == Mouse ? fixupDuration : 0; - - if (currentItem && haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange) { - updateHighlight(); - qreal pos = currentItem->itemPosition(); - qreal viewPos = position(); - if (viewPos < pos + currentItem->itemSize() - highlightRangeEnd) - viewPos = pos + currentItem->itemSize() - highlightRangeEnd; - if (viewPos > pos - highlightRangeStart) - viewPos = pos - highlightRangeStart; - - timeline.reset(data.move); - if (viewPos != position()) { - if (fixupDuration) - timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - else - timeline.set(data.move, -viewPos); - } - vTime = timeline.time(); - } else if (snapMode != QDeclarativeListView::NoSnap) { - FxListItem *topItem = snapItemAt(position()+highlightRangeStart); - FxListItem *bottomItem = snapItemAt(position()+highlightRangeEnd); - qreal pos; - if (topItem) { - pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent); - } else if (bottomItem) { - pos = qMax(qMin(bottomItem->position() - highlightRangeStart, -maxExtent), -minExtent); - } else { - fixupDuration = oldDuration; - return; - } - - qreal dist = qAbs(data.move + pos); - if (dist > 0) { - timeline.reset(data.move); - if (fixupDuration) - timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - else - timeline.set(data.move, -pos); - vTime = timeline.time(); - } - } else { - QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent); - } - fixupDuration = oldDuration; -} - -void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, - QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity) -{ - Q_Q(QDeclarativeListView); - - moveReason = Mouse; - if ((!haveHighlightRange || highlightRange != QDeclarativeListView::StrictlyEnforceRange) && snapMode == QDeclarativeListView::NoSnap) { - correctFlick = true; - QDeclarativeFlickablePrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity); - return; - } - qreal maxDistance = 0; - // -ve velocity means list is moving up/left - if (velocity > 0) { - if (data.move.value() < minExtent) { - if (snapMode == QDeclarativeListView::SnapOneItem) { - if (FxListItem *item = firstVisibleItem()) - maxDistance = qAbs(item->position() + data.move.value()); - } else { - maxDistance = qAbs(minExtent - data.move.value()); - } - } - if (snapMode == QDeclarativeListView::NoSnap && highlightRange != QDeclarativeListView::StrictlyEnforceRange) - data.flickTarget = minExtent; - } else { - if (data.move.value() > maxExtent) { - if (snapMode == QDeclarativeListView::SnapOneItem) { - if (FxListItem *item = nextVisibleItem()) - maxDistance = qAbs(item->position() + data.move.value()); - } else { - maxDistance = qAbs(maxExtent - data.move.value()); - } - } - if (snapMode == QDeclarativeListView::NoSnap && highlightRange != QDeclarativeListView::StrictlyEnforceRange) - data.flickTarget = maxExtent; - } - bool overShoot = boundsBehavior == QDeclarativeFlickable::DragAndOvershootBounds; - if (maxDistance > 0 || overShoot) { - // These modes require the list to stop exactly on an item boundary. - // The initial flick will estimate the boundary to stop on. - // Since list items can have variable sizes, the boundary will be - // reevaluated and adjusted as we approach the boundary. - qreal v = velocity; - if (maxVelocity != -1 && maxVelocity < qAbs(v)) { - if (v < 0) - v = -maxVelocity; - else - v = maxVelocity; - } - if (!flickingHorizontally && !flickingVertically) { - // the initial flick - estimate boundary - qreal accel = deceleration; - qreal v2 = v * v; - overshootDist = 0.0; - // + averageSize/4 to encourage moving at least one item in the flick direction - qreal dist = v2 / (accel * 2.0) + averageSize/4; - if (maxDistance > 0) - dist = qMin(dist, maxDistance); - if (v > 0) - dist = -dist; - if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarativeListView::SnapOneItem) { - data.flickTarget = -snapPosAt(-(data.move.value() - highlightRangeStart) + dist) + highlightRangeStart; - if (overShoot) { - if (data.flickTarget >= minExtent) { - overshootDist = overShootDistance(v, vSize); - data.flickTarget += overshootDist; - } else if (data.flickTarget <= maxExtent) { - overshootDist = overShootDistance(v, vSize); - data.flickTarget -= overshootDist; - } - } - qreal adjDist = -data.flickTarget + data.move.value(); - if (qAbs(adjDist) > qAbs(dist)) { - // Prevent painfully slow flicking - adjust velocity to suit flickDeceleration - qreal adjv2 = accel * 2.0f * qAbs(adjDist); - if (adjv2 > v2) { - v2 = adjv2; - v = qSqrt(v2); - if (dist > 0) - v = -v; - } - } - dist = adjDist; - accel = v2 / (2.0f * qAbs(dist)); - } else if (overShoot) { - data.flickTarget = data.move.value() - dist; - if (data.flickTarget >= minExtent) { - overshootDist = overShootDistance(v, vSize); - data.flickTarget += overshootDist; - } else if (data.flickTarget <= maxExtent) { - overshootDist = overShootDistance(v, vSize); - data.flickTarget -= overshootDist; - } - } - timeline.reset(data.move); - timeline.accel(data.move, v, accel, maxDistance + overshootDist); - timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this)); - if (!flickingHorizontally && q->xflick()) { - flickingHorizontally = true; - emit q->flickingChanged(); - emit q->flickingHorizontallyChanged(); - emit q->flickStarted(); - } - if (!flickingVertically && q->yflick()) { - flickingVertically = true; - emit q->flickingChanged(); - emit q->flickingVerticallyChanged(); - emit q->flickStarted(); - } - correctFlick = true; - } else { - // reevaluate the target boundary. - qreal newtarget = data.flickTarget; - if (snapMode != QDeclarativeListView::NoSnap || highlightRange == QDeclarativeListView::StrictlyEnforceRange) - newtarget = -snapPosAt(-(data.flickTarget - highlightRangeStart)) + highlightRangeStart; - if (velocity < 0 && newtarget <= maxExtent) - newtarget = maxExtent - overshootDist; - else if (velocity > 0 && newtarget >= minExtent) - newtarget = minExtent + overshootDist; - if (newtarget == data.flickTarget) { // boundary unchanged - nothing to do - if (qAbs(velocity) < MinimumFlickVelocity) - correctFlick = false; - return; - } - data.flickTarget = newtarget; - qreal dist = -newtarget + data.move.value(); - if ((v < 0 && dist < 0) || (v > 0 && dist > 0)) { - correctFlick = false; - timeline.reset(data.move); - fixup(data, minExtent, maxExtent); - return; - } - timeline.reset(data.move); - timeline.accelDistance(data.move, v, -dist); - timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this)); + footer = new FxListItem(item, q); } - } else { - correctFlick = false; - timeline.reset(data.move); - fixup(data, minExtent, maxExtent); } + if (footer) + footer->setPosition(endPosition() + 1 - footer->size()); } //---------------------------------------------------------------------------- @@ -1513,10 +1409,10 @@ QVariant QDeclarativeListView::model() const return d->modelVariant; } -void QDeclarativeListView::setModel(const QVariant &model) +void QDeclarativeListView::setModel(const QVariant &newModel) { Q_D(QDeclarativeListView); - if (d->modelVariant == model) + if (d->modelVariant == newModel) return; if (d->model) { disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); @@ -1527,12 +1423,15 @@ void QDeclarativeListView::setModel(const QVariant &model) disconnect(d->model, SIGNAL(createdItem(int,QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*))); disconnect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*))); } + d->clear(); QDeclarativeVisualModel *oldModel = d->model; d->model = 0; - d->setPosition(0); - d->modelVariant = model; - QObject *object = qvariant_cast(model); + d->modelCount = 0; + // d->setPosition(0); // we should do a re-layout and that should do a setViewportHeight and that should check the current position. + + d->modelVariant = newModel; + QObject *object = qvariant_cast(newModel); QDeclarativeVisualModel *vim = 0; if (object && (vim = qobject_cast(object))) { if (d->ownModel) { @@ -1548,24 +1447,14 @@ void QDeclarativeListView::setModel(const QVariant &model) d->model = oldModel; } if (QDeclarativeVisualDataModel *dataModel = qobject_cast(d->model)) - dataModel->setModel(model); + dataModel->setModel(newModel); } + if (d->model) { + d->modelCount = d->model->count(); d->bufferMode = QDeclarativeListViewPrivate::BufferBefore | QDeclarativeListViewPrivate::BufferAfter; - if (isComponentComplete()) { - updateSections(); - refill(); - if ((d->currentIndex >= d->model->count() || d->currentIndex < 0) && !d->currentIndexCleared) { - setCurrentIndex(0); - } else { - d->moveReason = QDeclarativeListViewPrivate::SetIndex; - d->updateCurrent(d->currentIndex); - if (d->highlight && d->currentItem) { - d->highlight->setPosition(d->currentItem->position()); - d->updateTrackedItem(); - } - } - } + + //qDebug() << "setModel: " << d->model<<"model:" << isComponentComplete(); connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int))); connect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int))); @@ -1575,6 +1464,17 @@ void QDeclarativeListView::setModel(const QVariant &model) connect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*))); emit countChanged(); } + + if (isComponentComplete()) { + updateSections(); + refill(); + if ((d->currentIndex < 0 || d->currentIndex >= d->modelCount) && !d->currentIndexCleared) { + setCurrentIndex(0); + } else { + d->setCurrentIndex(d->currentIndex); + } + d->updateViewport(); + } emit modelChanged(); } @@ -1619,9 +1519,11 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) d->model = new QDeclarativeVisualDataModel(qmlContext(this)); d->ownModel = true; } + //qDebug() << "setDelegate" << delegate; if (QDeclarativeVisualDataModel *dataModel = qobject_cast(d->model)) { dataModel->setDelegate(delegate); if (isComponentComplete()) { + // TODO: why not call clear() ? for (int i = 0; i < d->visibleItems.count(); ++i) d->releaseItem(d->visibleItems.at(i)); d->visibleItems.clear(); @@ -1630,13 +1532,15 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) updateSections(); refill(); d->moveReason = QDeclarativeListViewPrivate::SetIndex; - d->updateCurrent(d->currentIndex); + d->setCurrentIndex(d->currentIndex); if (d->highlight && d->currentItem) { d->highlight->setPosition(d->currentItem->position()); - d->updateTrackedItem(); } + d->updateHighlight(); + d->updateViewport(); } } + //qDebug() << "setDelegate current" << d->currentIndex << d->currentItem; emit delegateChanged(); } @@ -1648,10 +1552,10 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) \c currentItem holds the current item. Setting the currentIndex to -1 will clear the highlight and set currentItem to null. - If highlightFollowsCurrentItem is \c true, setting either of these - properties will smoothly scroll the ListView so that the current + If highlightFollowsCurrentItem is \c true, setting either of these + properties will smoothly scroll the ListView so that the current item becomes visible. - + Note that the position of the current item may only be approximate until it becomes visible in the view. */ @@ -1664,14 +1568,17 @@ int QDeclarativeListView::currentIndex() const void QDeclarativeListView::setCurrentIndex(int index) { Q_D(QDeclarativeListView); - if (d->requestedIndex >= 0) // currently creating item + if (d->requestedIndex >= 0) // currently creating an item return; + d->currentIndexCleared = (index == -1); + if (index == d->currentIndex) return; + if (isComponentComplete() && d->isValid()) { d->moveReason = QDeclarativeListViewPrivate::SetIndex; - d->updateCurrent(index); + d->setCurrentIndex(index); } else if (d->currentIndex != index) { d->currentIndex = index; emit currentIndexChanged(); @@ -1711,9 +1618,8 @@ QDeclarativeItem *QDeclarativeListView::highlightItem() int QDeclarativeListView::count() const { Q_D(const QDeclarativeListView); - if (d->model) - return d->model->count(); - return 0; + Q_ASSERT( d->model || d->modelCount == 0 ); + return d->modelCount; } /*! @@ -1738,9 +1644,7 @@ void QDeclarativeListView::setHighlight(QDeclarativeComponent *highlight) Q_D(QDeclarativeListView); if (highlight != d->highlightComponent) { d->highlightComponent = highlight; - d->createHighlight(); - if (d->currentItem) - d->updateHighlight(); + d->recreateHighlight(); emit highlightChanged(); } } @@ -1928,17 +1832,22 @@ void QDeclarativeListView::setOrientation(QDeclarativeListView::Orientation orie setContentHeight(-1); setFlickableDirection(HorizontalFlick); } - d->clear(); - d->setPosition(0); - refill(); + + // -- swap the coordinates and then let layout do the final positioning + for (int i = 0; i < d->visibleItems.count(); ++i) + d->visibleItems.at(i)->item->setPos(d->visibleItems.at(i)->item->pos().y(), + d->visibleItems.at(i)->item->pos().x()); + + d->layout(); + d->updateViewport(); emit orientationChanged(); - d->updateCurrent(d->currentIndex); + d->setCurrentIndex(d->currentIndex); } } /*! \qmlproperty bool ListView::keyNavigationWraps - This property holds whether the list wraps key navigation. + This property holds whether the list wraps key navigation. If this is true, key navigation that would move the current item selection past the end of the list instead wraps around and moves the selection to @@ -1994,6 +1903,7 @@ void QDeclarativeListView::setCacheBuffer(int b) if (isComponentComplete()) { d->bufferMode = QDeclarativeListViewPrivate::BufferBefore | QDeclarativeListViewPrivate::BufferAfter; refill(); + d->updateViewport(); } emit cacheBufferChanged(); } @@ -2182,6 +2092,7 @@ void QDeclarativeListView::setSnapMode(SnapMode mode) if (d->snapMode != mode) { d->snapMode = mode; emit snapModeChanged(); + QScroller::scroller(this)->resendPrepareEvent(); } } @@ -2269,153 +2180,165 @@ void QDeclarativeListView::setContentY(qreal pos) bool QDeclarativeListView::event(QEvent *event) { Q_D(QDeclarativeListView); - if (event->type() == QEvent::User) { + + switch (event->type()) { + case QEvent::User: d->layout(); return true; + + case QEvent::ScrollPrepare: { + QScroller *scroller = QScroller::scroller(this); + qreal snapOffset = 0; + bool forceSnapping = false; + bool useEndPosition = false; + bool ignoreHeaders = false; + + // --- do the highlight range + if (d->haveHighlightRange) { + snapOffset = -d->highlightRangeStart; + ignoreHeaders = true; + } + + // --- now finally do the snap points + QList snapPoints; + // -- snap to every point (SnapToItem) + if (d->snapMode == QDeclarativeListView::SnapToItem || forceSnapping) { + // - snap to begin of item + if (!useEndPosition) { + if (d->header && !ignoreHeaders) + snapPoints.append(d->header->itemPosition() + snapOffset); + foreach (FxListItem *item, d->visibleItems) + snapPoints.append(item->itemPosition() + snapOffset); + if (d->footer && !ignoreHeaders) + snapPoints.append(d->footer->itemPosition() + snapOffset); + + // - snap to end of item + } else { + if (d->header && !ignoreHeaders) + snapPoints.append(d->header->endPosition() + snapOffset); + foreach (FxListItem *item, d->visibleItems) + snapPoints.append(item->endPosition() + snapOffset); + if (d->footer && !ignoreHeaders) + snapPoints.append(d->footer->endPosition() + snapOffset); + } + + // -- snap to the next three point (SnapOneItem) + } else if (d->snapMode == QDeclarativeListView::SnapOneItem) { + // here we just set three snap points around the current position. + // TODO + + // - snap to begin of item + if (!useEndPosition) { + qreal currentSnapPos = (d->positionAt(d->currentIndex) + snapOffset); + if (d->currentIndex > 0) + snapPoints.append(d->positionAt(d->currentIndex - 1) + snapOffset); + snapPoints.append(d->positionAt(d->currentIndex) + snapOffset); + // TODO: don't use last point if we are between two points already + if (d->currentIndex < d->modelCount - 1 && currentSnapPos <= d->position()) + snapPoints.append(d->positionAt(d->currentIndex + 1) + snapOffset); + + // - snap to end of item + } else { + snapPoints.append(d->endPositionAt(d->currentIndex - 1) + 1 + snapOffset); + snapPoints.append(d->endPositionAt(d->currentIndex) + 1 + snapOffset); + // TODO: don't use last point if we are between two points already + snapPoints.append(d->endPositionAt(d->currentIndex + 1) + 1 + snapOffset); + } + } + + if (d->orient == QDeclarativeListView::Vertical) { + scroller->setSnapPositionsX(0.0, 0.0); + scroller->setSnapPositionsY(snapPoints); + } else { + scroller->setSnapPositionsX(snapPoints); + scroller->setSnapPositionsY(0.0, 0.0); + } + } + break; + + default: + break; } return QDeclarativeFlickable::event(event); } -void QDeclarativeListView::viewportMoved() +void QDeclarativeListView::scrollerStateChanged(QScroller::State state) { Q_D(QDeclarativeListView); - QDeclarativeFlickable::viewportMoved(); - if (!d->itemCount) - return; - // Recursion can occur due to refill changing the content size. - if (d->inViewportMoved) - return; - d->inViewportMoved = true; - d->lazyRelease = true; - refill(); - if (d->flickingHorizontally || d->flickingVertically || d->movingHorizontally || d->movingVertically) - d->moveReason = QDeclarativeListViewPrivate::Mouse; - if (d->moveReason != QDeclarativeListViewPrivate::SetIndex) { - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) { - // reposition highlight - qreal pos = d->highlight->position(); - qreal viewPos = d->position(); - if (pos > viewPos + d->highlightRangeEnd - d->highlight->size()) - pos = viewPos + d->highlightRangeEnd - d->highlight->size(); - if (pos < viewPos + d->highlightRangeStart) - pos = viewPos + d->highlightRangeStart; - d->highlightPosAnimator->stop(); - d->highlight->setPosition(qRound(pos)); - - // update current index - if (FxListItem *snapItem = d->snapItemAt(d->highlight->position())) { - if (snapItem->index >= 0 && snapItem->index != d->currentIndex) - d->updateCurrent(snapItem->index); - } - } - } + QDeclarativeFlickable::scrollerStateChanged(state); - if ((d->flickingHorizontally || d->flickingVertically) && d->correctFlick && !d->inFlickCorrection) { - d->inFlickCorrection = true; - // Near an end and it seems that the extent has changed? - // Recalculate the flick so that we don't end up in an odd position. - if (yflick()) { - if (d->vData.velocity > 0) { - const qreal minY = minYExtent(); - if ((minY - d->vData.move.value() < height()/2 || d->vData.flickTarget - d->vData.move.value() < height()/2) - && minY != d->vData.flickTarget) - d->flickY(-d->vData.smoothVelocity.value()); - d->bufferMode = QDeclarativeListViewPrivate::BufferBefore; - } else if (d->vData.velocity < 0) { - const qreal maxY = maxYExtent(); - if ((d->vData.move.value() - maxY < height()/2 || d->vData.move.value() - d->vData.flickTarget < height()/2) - && maxY != d->vData.flickTarget) - d->flickY(-d->vData.smoothVelocity.value()); - d->bufferMode = QDeclarativeListViewPrivate::BufferAfter; - } + if (state == QScroller::Inactive) { + d->bufferMode = QDeclarativeListViewPrivate::NoBuffer; + if (d->highlightRange == QDeclarativeListView::StrictlyEnforceRange) { + d->updateHighlight(); // nudge the highlight in the right position if needed. } - - if (xflick()) { - if (d->hData.velocity > 0) { - const qreal minX = minXExtent(); - if ((minX - d->hData.move.value() < width()/2 || d->hData.flickTarget - d->hData.move.value() < width()/2) - && minX != d->hData.flickTarget) - d->flickX(-d->hData.smoothVelocity.value()); - d->bufferMode = QDeclarativeListViewPrivate::BufferBefore; - } else if (d->hData.velocity < 0) { - const qreal maxX = maxXExtent(); - if ((d->hData.move.value() - maxX < width()/2 || d->hData.move.value() - d->hData.flickTarget < width()/2) - && maxX != d->hData.flickTarget) - d->flickX(-d->hData.smoothVelocity.value()); - d->bufferMode = QDeclarativeListViewPrivate::BufferAfter; - } - } - d->inFlickCorrection = false; } - d->inViewportMoved = false; } -qreal QDeclarativeListView::minYExtent() const +qreal QDeclarativeListView::minExtent() const { Q_D(const QDeclarativeListView); - if (d->orient == QDeclarativeListView::Horizontal) - return QDeclarativeFlickable::minYExtent(); + if (d->minExtentDirty) { - d->minExtent = -d->startPosition(); - if (d->header && d->visibleItems.count()) - d->minExtent += d->header->size(); - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - d->minExtent += d->highlightRangeStart; + d->minExtent = d->startPosition(); + if (d->modelCount && + d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + d->minExtent -= d->highlightRangeStart; if (d->sectionCriteria) { if (d->visibleItem(0)) d->minExtent -= d->visibleItem(0)->sectionSize(); } - d->minExtent = qMax(d->minExtent, -(d->endPositionAt(0) - d->highlightRangeEnd + 1)); } d->minExtentDirty = false; } - return d->minExtent; } -qreal QDeclarativeListView::maxYExtent() const +qreal QDeclarativeListView::maxExtent() const { Q_D(const QDeclarativeListView); - if (d->orient == QDeclarativeListView::Horizontal) - return height(); + if (d->maxExtentDirty) { - if (!d->model || !d->model->count()) { - d->maxExtent = 0; - } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - d->maxExtent = -(d->positionAt(d->model->count()-1) - d->highlightRangeStart); - if (d->highlightRangeEnd != d->highlightRangeStart) - d->maxExtent = qMin(d->maxExtent, -(d->endPosition() - d->highlightRangeEnd + 1)); - } else { - d->maxExtent = -(d->endPosition() - height() + 1); + d->maxExtent = d->endPosition() + 1; + + if (d->modelCount && + d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + d->maxExtent = qMin(d->maxExtent + d->size() - d->highlightRangeEnd + 1, + // ensure that the last item fits fully behind hightlightRangeStart + d->positionAt(d->modelCount-1) + d->size() - d->highlightRangeStart); } - if (d->footer) - d->maxExtent -= d->footer->size(); - qreal minY = minYExtent(); - if (d->maxExtent > minY) - d->maxExtent = minY; + d->maxExtent = qMax(d->maxExtent, minExtent()); d->maxExtentDirty = false; } return d->maxExtent; } +qreal QDeclarativeListView::minYExtent() const +{ + Q_D(const QDeclarativeListView); + if (d->orient == QDeclarativeListView::Horizontal) + return QDeclarativeFlickable::minYExtent(); + else + return minExtent(); +} + +qreal QDeclarativeListView::maxYExtent() const +{ + Q_D(const QDeclarativeListView); + if (d->orient == QDeclarativeListView::Horizontal) + return height(); + else + return maxExtent(); +} + qreal QDeclarativeListView::minXExtent() const { Q_D(const QDeclarativeListView); if (d->orient == QDeclarativeListView::Vertical) return QDeclarativeFlickable::minXExtent(); - if (d->minExtentDirty) { - d->minExtent = -d->startPosition(); - if (d->header) - d->minExtent += d->header->size(); - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - d->minExtent += d->highlightRangeStart; - d->minExtent = qMax(d->minExtent, -(d->endPositionAt(0) - d->highlightRangeEnd + 1)); - } - d->minExtentDirty = false; - } - - return d->minExtent; + else + return minExtent(); } qreal QDeclarativeListView::maxXExtent() const @@ -2423,25 +2346,50 @@ qreal QDeclarativeListView::maxXExtent() const Q_D(const QDeclarativeListView); if (d->orient == QDeclarativeListView::Vertical) return width(); - if (d->maxExtentDirty) { - if (!d->model || !d->model->count()) { - d->maxExtent = 0; - } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - d->maxExtent = -(d->positionAt(d->model->count()-1) - d->highlightRangeStart); - if (d->highlightRangeEnd != d->highlightRangeStart) - d->maxExtent = qMin(d->maxExtent, -(d->endPosition() - d->highlightRangeEnd + 1)); - } else { - d->maxExtent = -(d->endPosition() - width() + 1); + else + return maxExtent(); +} + +void QDeclarativeListView::viewportAboutToMove(QPointF newPos) +{ + Q_D(QDeclarativeListView); + + // qDebug() << "viewport about to move"; + // need to refill before moving + if( d->orient == Horizontal ) + d->refill(newPos.x(), newPos.x() + width() - 1); + else + d->refill(newPos.y(), newPos.y() + height() - 1); + + d->lazyRelease = true; + + if (d->isUserGenerated) + d->moveReason = QDeclarativeListViewPrivate::Mouse; + + if (d->haveHighlightRange && d->highlight && d->highlightRange == StrictlyEnforceRange) { + + d->highlightPosAnimator->stop(); + + // reposition highlight + qreal pos = d->highlight->position(); + qreal viewPos = d->orient == Horizontal ? newPos.x() : newPos.y(); + if (pos > viewPos + d->highlightRangeEnd - d->highlight->size()) + pos = viewPos + d->highlightRangeEnd - d->highlight->size(); + if (pos < viewPos + d->highlightRangeStart) + pos = viewPos + d->highlightRangeStart; + d->highlight->setPosition(pos); + + // update current index + if (d->moveReason != QDeclarativeListViewPrivate::SetIndex) { + int idx = d->snapIndex(); + if (idx >= 0 && idx != d->currentIndex) + d->setCurrentIndex(idx); } - if (d->footer) - d->maxExtent -= d->footer->size(); - qreal minX = minXExtent(); - if (d->maxExtent > minX) - d->maxExtent = minX; - d->maxExtentDirty = false; } - return d->maxExtent; + if (d->sectionCriteria) + d->updateCurrentSection(); + d->updateViewport(); } void QDeclarativeListView::keyPressEvent(QKeyEvent *event) @@ -2451,7 +2399,7 @@ void QDeclarativeListView::keyPressEvent(QKeyEvent *event) if (event->isAccepted()) return; - if (d->model && d->model->count() && d->interactive) { + if (d->model && d->modelCount && d->interactive) { if ((d->orient == QDeclarativeListView::Horizontal && event->key() == Qt::Key_Left) || (d->orient == QDeclarativeListView::Vertical && event->key() == Qt::Key_Up)) { if (currentIndex() > 0 || (d->wrap && !event->isAutoRepeat())) { @@ -2464,7 +2412,7 @@ void QDeclarativeListView::keyPressEvent(QKeyEvent *event) } } else if ((d->orient == QDeclarativeListView::Horizontal && event->key() == Qt::Key_Right) || (d->orient == QDeclarativeListView::Vertical && event->key() == Qt::Key_Down)) { - if (currentIndex() < d->model->count() - 1 || (d->wrap && !event->isAutoRepeat())) { + if (currentIndex() < d->modelCount - 1 || (d->wrap && !event->isAutoRepeat())) { incrementCurrentIndex(); event->accept(); return; @@ -2478,8 +2426,7 @@ void QDeclarativeListView::keyPressEvent(QKeyEvent *event) QDeclarativeFlickable::keyPressEvent(event); } -void QDeclarativeListView::geometryChanged(const QRectF &newGeometry, - const QRectF &oldGeometry) +void QDeclarativeListView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QDeclarativeListView); d->maxExtentDirty = true; @@ -2500,11 +2447,11 @@ void QDeclarativeListView::geometryChanged(const QRectF &newGeometry, void QDeclarativeListView::incrementCurrentIndex() { Q_D(QDeclarativeListView); - int count = d->model ? d->model->count() : 0; - if (count && (currentIndex() < count - 1 || d->wrap)) { + //qDebug() << "incrementCurrentIndex" << currentIndex() << "c:" << count; + if (d->modelCount && (currentIndex() < d->modelCount - 1 || d->wrap)) { d->moveReason = QDeclarativeListViewPrivate::SetIndex; int index = currentIndex()+1; - setCurrentIndex((index >= 0 && index < count) ? index : 0); + setCurrentIndex((index >= 0 && index < d->modelCount) ? index : 0); } } @@ -2520,11 +2467,11 @@ void QDeclarativeListView::incrementCurrentIndex() void QDeclarativeListView::decrementCurrentIndex() { Q_D(QDeclarativeListView); - int count = d->model ? d->model->count() : 0; - if (count && (currentIndex() > 0 || d->wrap)) { + //qDebug() << "decrementCurrentIndex" << currentIndex() << "c:" << count; + if (d->modelCount && (currentIndex() > 0 || d->wrap)) { d->moveReason = QDeclarativeListViewPrivate::SetIndex; int index = currentIndex()-1; - setCurrentIndex((index >= 0 && index < count) ? index : count-1); + setCurrentIndex((index >= 0 && index < d->modelCount) ? index : d->modelCount - 1); } } @@ -2563,8 +2510,9 @@ void QDeclarativeListView::decrementCurrentIndex() */ void QDeclarativeListView::positionViewAtIndex(int index, int mode) { + //qDebug() << "positionViewAtIndex index:" << index << "mode:" << mode; Q_D(QDeclarativeListView); - if (!d->isValid() || index < 0 || index >= d->model->count()) + if (!d->isValid() || index < 0 || index >= d->modelCount) return; if (mode < Beginning || mode > Contain) return; @@ -2610,12 +2558,9 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode) if (itemPos < pos) pos = itemPos; } - qreal maxExtent = d->orient == QDeclarativeListView::Vertical ? -maxYExtent() : -maxXExtent(); - pos = qMin(pos, maxExtent); - qreal minExtent = d->orient == QDeclarativeListView::Vertical ? -minYExtent() : -minXExtent(); - pos = qMax(pos, minExtent); + pos = qMin(pos, maxExtent() - d->size()); // shouldn't that be + 1 ? + pos = qMax(pos, minExtent()); d->moveReason = QDeclarativeListViewPrivate::Other; - cancelFlick(); d->setPosition(pos); if (d->highlight) { d->highlight->setPosition(d->currentItem->itemPosition()); @@ -2623,7 +2568,6 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode) d->updateHighlight(); } } - d->fixupPosition(); } /*! @@ -2659,15 +2603,13 @@ void QDeclarativeListView::componentComplete() refill(); d->moveReason = QDeclarativeListViewPrivate::SetIndex; if (d->currentIndex < 0 && !d->currentIndexCleared) - d->updateCurrent(0); + d->setCurrentIndex(0); else - d->updateCurrent(d->currentIndex); + d->setCurrentIndex(d->currentIndex); if (d->highlight && d->currentItem) { d->highlight->setPosition(d->currentItem->position()); - d->updateTrackedItem(); } - d->moveReason = QDeclarativeListViewPrivate::Other; - d->fixupPosition(); + d->updateHighlight(false); } } @@ -2686,88 +2628,35 @@ void QDeclarativeListView::updateSections() void QDeclarativeListView::refill() { Q_D(QDeclarativeListView); - d->refill(d->position(), d->position()+d->size()-1); + d->refill(d->position(), d->position() + d->size() - 1); } -void QDeclarativeListView::trackedPositionChanged() +void QDeclarativeListView::itemsInserted(int modelIndex, int count) { Q_D(QDeclarativeListView); - if (!d->trackedItem || !d->currentItem) + d->minExtentDirty = true; + d->maxExtentDirty = true; + + if (!isComponentComplete()) { + d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count return; - if (d->moveReason == QDeclarativeListViewPrivate::SetIndex) { - qreal trackedPos = qCeil(d->trackedItem->position()); - qreal trackedSize = d->trackedItem->size(); - if (d->trackedItem != d->currentItem) { - trackedPos -= d->currentItem->sectionSize(); - trackedSize += d->currentItem->sectionSize(); - } - const qreal viewPos = d->position(); - qreal pos = viewPos; - if (d->haveHighlightRange) { - if (d->highlightRange == StrictlyEnforceRange) { - if (trackedPos > pos + d->highlightRangeEnd - d->trackedItem->size()) - pos = trackedPos - d->highlightRangeEnd + d->trackedItem->size(); - if (trackedPos < pos + d->highlightRangeStart) - pos = trackedPos - d->highlightRangeStart; - } else { - if (trackedPos < d->startPosition() + d->highlightRangeStart) { - pos = d->startPosition(); - } else if (d->trackedItem->endPosition() > d->endPosition() - d->size() + d->highlightRangeEnd) { - pos = d->endPosition() - d->size() + 1; - if (pos < d->startPosition()) - pos = d->startPosition(); - } else { - if (trackedPos < viewPos + d->highlightRangeStart) { - pos = trackedPos - d->highlightRangeStart; - } else if (trackedPos > viewPos + d->highlightRangeEnd - trackedSize) { - pos = trackedPos - d->highlightRangeEnd + trackedSize; - } - } - } - } else { - if (trackedPos < viewPos && d->currentItem->position() < viewPos) { - pos = d->currentItem->position() < trackedPos ? trackedPos : d->currentItem->position(); - } else if (d->trackedItem->endPosition() >= viewPos + d->size() - && d->currentItem->endPosition() >= viewPos + d->size()) { - if (d->trackedItem->endPosition() <= d->currentItem->endPosition()) { - pos = d->trackedItem->endPosition() - d->size() + 1; - if (trackedSize > d->size()) - pos = trackedPos; - } else { - pos = d->currentItem->endPosition() - d->size() + 1; - if (d->currentItem->size() > d->size()) - pos = d->currentItem->position(); - } - } - } - if (viewPos != pos) { - cancelFlick(); - d->calcVelocity = true; - d->setPosition(pos); - d->calcVelocity = false; - } } -} -void QDeclarativeListView::itemsInserted(int modelIndex, int count) -{ - Q_D(QDeclarativeListView); - if (!isComponentComplete()) - return; d->updateUnrequestedIndexes(); d->moveReason = QDeclarativeListViewPrivate::Other; if (!d->visibleItems.count() || d->model->count() <= 1) { d->scheduleLayout(); - if (d->itemCount && d->currentIndex >= modelIndex) { + if (d->modelCount && d->currentIndex >= modelIndex) { // adjust current item index d->currentIndex += count; if (d->currentItem) d->currentItem->index = d->currentIndex; emit currentIndexChanged(); } else if (!d->currentIndex || (d->currentIndex < 0 && !d->currentIndexCleared)) { - d->updateCurrent(0); + d->setCurrentIndex(0); } - d->itemCount += count; + d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count + d->updateScrollerValues(); emit countChanged(); return; } @@ -2799,13 +2688,16 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) emit currentIndexChanged(); } d->scheduleLayout(); - d->itemCount += count; + d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count + d->updateScrollerValues(); emit countChanged(); return; } } // At least some of the added items will be visible + if (d->layoutScheduled) + d->layout(); // index can be the next item past the end of the visible items list (i.e. appended) int pos = index < d->visibleItems.count() ? d->visibleItems.at(index)->position() @@ -2870,14 +2762,9 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) } diff = pos - initialPos; } - if (d->itemCount && d->currentIndex >= modelIndex) { + if (d->modelCount && d->currentIndex >= modelIndex) { // adjust current item index - d->currentIndex += count; - if (d->currentItem) { - d->currentItem->index = d->currentIndex; - d->currentItem->setPosition(d->currentItem->position() + diff); - } - emit currentIndexChanged(); + d->setCurrentIndex(d->currentIndex + count); } // Update the indexes of the following visible items. for (; index < d->visibleItems.count(); ++index) { @@ -2892,35 +2779,42 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) added.at(j)->attached->emitAdd(); d->updateSections(); - d->itemCount += count; + d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count + d->updateScrollerValues(); emit countChanged(); } void QDeclarativeListView::itemsRemoved(int modelIndex, int count) { Q_D(QDeclarativeListView); + d->minExtentDirty = true; + d->maxExtentDirty = true; + d->modelCount = d->model->count(); // don't rely on newCount = oldCount - count if (!isComponentComplete()) return; d->moveReason = QDeclarativeListViewPrivate::Other; d->updateUnrequestedIndexes(); - d->itemCount -= count; FxListItem *firstVisible = d->firstVisibleItem(); int preRemovedSize = 0; - bool removedVisible = false; + bool removedVisible = false; // true if we removed an visible item. // Remove the items from the visible list, skipping anything already marked for removal QList::Iterator it = d->visibleItems.begin(); while (it != d->visibleItems.end()) { FxListItem *item = *it; + + // qDebug() << "Remove visible?: "<index<<"at"<position()<<"mi"<index == -1 || item->index < modelIndex) { // already removed, or before removed items ++it; } else if (item->index >= modelIndex + count) { // after removed items + // qDebug() << "Remove item not" << item->index <<"at" << item->position() << "newINdex:"<<(item->index-count); item->index -= count; ++it; } else { // removed item + // qDebug() << "Remove item really" << item->index <<"at" << item->position(); if (!removedVisible) { d->scheduleLayout(); removedVisible = true; @@ -2931,18 +2825,22 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) connect(item->attached, SIGNAL(delayRemoveChanged()), this, SLOT(destroyRemoved()), Qt::QueuedConnection); ++it; } else { + // move the list down if we remove an item between the start of the list and the first visible item. if (item == firstVisible) - firstVisible = 0; + firstVisible = 0; if (firstVisible && item->position() < firstVisible->position()) preRemovedSize += item->size(); + it = d->visibleItems.erase(it); d->releaseItem(item); } } } - if (firstVisible && d->visibleItems.first() != firstVisible) - d->visibleItems.first()->setPosition(d->visibleItems.first()->position() + preRemovedSize); + + // restore the start position of the visible items + if (firstVisible && forceConst(d->visibleItems).first() != firstVisible) + forceConst(d->visibleItems).first()->setPosition(forceConst(d->visibleItems).first()->position() + preRemovedSize); // fix current if (d->currentIndex >= modelIndex + count) { @@ -2956,8 +2854,8 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) d->releaseItem(d->currentItem); d->currentItem = 0; d->currentIndex = -1; - if (d->itemCount) - d->updateCurrent(qMin(modelIndex, d->itemCount-1)); + if (d->modelCount) + d->setCurrentIndex(qMin(modelIndex, d->modelCount-1)); } // update visibleIndex @@ -2967,24 +2865,21 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) break; } } - if (removedVisible && d->visibleItems.isEmpty()) { - d->timeline.clear(); - if (d->itemCount == 0) { - d->visibleIndex = 0; - d->visiblePos = d->header ? d->header->size() : 0; - d->setPosition(0); - d->updateHeader(); - d->updateFooter(); - update(); + QScroller::scroller(this)->stop(); + // the complete visible area was removed + if (!d->modelCount) { + d->clear(); } else { if (modelIndex < d->visibleIndex) d->visibleIndex = modelIndex+1; - d->visibleIndex = qMax(qMin(d->visibleIndex, d->itemCount-1), 0); + d->visibleIndex = qBound(0, d->visibleIndex, d->modelCount - 1); } } d->updateSections(); + d->updateScrollerValues(); + emit countChanged(); } @@ -3104,7 +2999,7 @@ void QDeclarativeListView::itemsMoved(int from, int to, int count) } // Ensure we don't cause an ugly list scroll. - d->visibleItems.first()->setPosition(d->visibleItems.first()->position() + moveBy); + forceConst(d->visibleItems).first()->setPosition(forceConst(d->visibleItems).first()->position() + moveBy); d->updateSections(); d->layout(); @@ -3121,14 +3016,15 @@ void QDeclarativeListView::modelReset() { Q_D(QDeclarativeListView); d->clear(); + d->modelCount = d->model->count(); d->setPosition(0); refill(); d->moveReason = QDeclarativeListViewPrivate::SetIndex; - d->updateCurrent(d->currentIndex); + d->setCurrentIndex(d->currentIndex); if (d->highlight && d->currentItem) { d->highlight->setPosition(d->currentItem->position()); - d->updateTrackedItem(); } + d->updateHighlight(); d->moveReason = QDeclarativeListViewPrivate::Other; emit countChanged(); } @@ -3152,14 +3048,6 @@ void QDeclarativeListView::destroyingItem(QDeclarativeItem *item) d->unrequestedItems.remove(item); } -void QDeclarativeListView::animStopped() -{ - Q_D(QDeclarativeListView); - d->bufferMode = QDeclarativeListViewPrivate::NoBuffer; - if (d->haveHighlightRange && d->highlightRange == QDeclarativeListView::StrictlyEnforceRange) - d->updateHighlight(); -} - QDeclarativeListViewAttached *QDeclarativeListView::qmlAttachedProperties(QObject *obj) { return new QDeclarativeListViewAttached(obj); diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h index 2678b90..5593574 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview_p.h +++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h @@ -238,13 +238,18 @@ Q_SIGNALS: void headerChanged(); void footerChanged(); +protected Q_SLOTS: + virtual void scrollerStateChanged(QScroller::State); + protected: virtual bool event(QEvent *event); - virtual void viewportMoved(); + virtual qreal minExtent() const; + virtual qreal maxExtent() const; virtual qreal minYExtent() const; virtual qreal maxYExtent() const; virtual qreal minXExtent() const; virtual qreal maxXExtent() const; + virtual void viewportAboutToMove(QPointF newPos); virtual void keyPressEvent(QKeyEvent *); virtual void geometryChanged(const QRectF &newGeometry,const QRectF &oldGeometry); virtual void componentComplete(); @@ -252,7 +257,6 @@ protected: private Q_SLOTS: void updateSections(); void refill(); - void trackedPositionChanged(); void itemsInserted(int index, int count); void itemsRemoved(int index, int count); void itemsMoved(int from, int to, int count); @@ -261,7 +265,6 @@ private Q_SLOTS: void destroyRemoved(); void createdItem(int index, QDeclarativeItem *item); void destroyingItem(QDeclarativeItem *item); - void animStopped(); }; class QDeclarativeListViewAttached : public QObject diff --git a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp index 25edb36..3442596 100644 --- a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp +++ b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp @@ -99,9 +99,11 @@ void tst_qdeclarativeflickable::create() QCOMPARE(obj->verticalVelocity(), 0.); QCOMPARE(obj->isInteractive(), true); - QCOMPARE(obj->boundsBehavior(), QDeclarativeFlickable::DragAndOvershootBounds); QCOMPARE(obj->pressDelay(), 0); + QCOMPARE(obj->boundsBehavior(), QDeclarativeFlickable::DragAndOvershootBounds); + /* Those values are platform dependant QCOMPARE(obj->maximumFlickVelocity(), 2000.); + */ delete obj; } diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index 327bba2..ef5c976 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -649,6 +649,7 @@ void tst_QDeclarativeGridView::currentIndex() #endif QTRY_VERIFY(canvas->hasFocus()); QTRY_VERIFY(canvas->scene()->hasFocus()); + gridview->forceActiveFocus(); qApp->processEvents(); QTest::keyClick(canvas, Qt::Key_Down); @@ -666,6 +667,7 @@ void tst_QDeclarativeGridView::currentIndex() #endif QTRY_VERIFY(canvas->hasFocus()); QTRY_VERIFY(canvas->scene()->hasFocus()); + gridview->forceActiveFocus(); qApp->processEvents(); QTest::keyClick(canvas, Qt::Key_Right); diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 37d836d..70f417f 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -613,10 +613,11 @@ void tst_QDeclarativeListView::removed(bool animated) listview->setCurrentIndex(10); model.removeItem(1); // post: top item will be at 40 + // let transitions settle. qApp->processEvents(); - // Confirm items positioned correctly - for (int i = 2; i < 18; ++i) { + // Confirm items positioned correctly (we were at the fourth item and deleted one) + for (int i = 2; i < 2 + 16; ++i) { QDeclarativeItem *item = findItem(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QTRY_VERIFY(item); @@ -663,10 +664,12 @@ void tst_QDeclarativeListView::removed(bool animated) listview->setContentY(80); QTest::qWait(300); + // remove all visible items model.removeItems(1, 17); QTest::qWait(300); // Confirm items positioned correctly + // we were at the fourth item, but deleted 1 through 17. So we should be at 1 now. itemCount = findItems(contentItem, "wrapper").count(); for (int i = 0; i < model.count() && i < itemCount-1; ++i) { QDeclarativeItem *item = findItem(contentItem, "wrapper", i+2); @@ -1076,6 +1079,7 @@ void tst_QDeclarativeListView::currentIndex() #endif QTRY_VERIFY(canvas->hasFocus()); QTRY_VERIFY(canvas->scene()->hasFocus()); + listview->forceActiveFocus(); qApp->processEvents(); QTest::keyClick(canvas, Qt::Key_Down); -- cgit v0.12 From b9a029d7abaf46353b7b428eba29c3612661743e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Sat, 4 Dec 2010 08:55:10 +0100 Subject: Add missing include --- src/corelib/io/qfilesystemengine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index 1e5914b..d9d802e 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -42,6 +42,7 @@ #include "qfilesystemengine_p.h" #include #include +#include #include #ifdef QT_BUILD_CORE_LIB #include -- cgit v0.12 From 684a61aa3da00b04f44eea0e92dbcb6183f505bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Sat, 4 Dec 2010 17:04:33 +0100 Subject: More missing includes --- src/corelib/io/qfilesystemiterator_win.cpp | 2 ++ src/corelib/io/qfilesystemmetadata_p.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 9181789..095a46a 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -43,6 +43,8 @@ #include "qfilesystemengine_p.h" #include "qplatformdefs.h" +#include + QT_BEGIN_NAMESPACE bool done = true; diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 860b887..50c1b61 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -60,6 +60,7 @@ // Platform-specific includes #if defined(Q_OS_WIN) +#include #elif defined(Q_OS_SYMBIAN) #include #include -- cgit v0.12 From 72db8d3075f91cac831de590dd6748c6bbc9a52f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Sat, 4 Dec 2010 20:31:06 +0100 Subject: Set minimum target Windows version to 2000 Required for FindFirstFileEx. --- src/corelib/io/qfilesystemiterator_win.cpp | 4 ++++ src/corelib/io/qfilesystemmetadata_p.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 095a46a..96c7fdb 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -43,6 +43,10 @@ #include "qfilesystemengine_p.h" #include "qplatformdefs.h" +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0500 +#endif + #include QT_BEGIN_NAMESPACE diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 50c1b61..03bb7f6 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -60,6 +60,10 @@ // Platform-specific includes #if defined(Q_OS_WIN) +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0500 +#endif + #include #elif defined(Q_OS_SYMBIAN) #include -- cgit v0.12 From 07de3abf3785248160fbd42c449b0832ea97c320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Sat, 4 Dec 2010 20:55:13 +0100 Subject: No symbolic links in Windows CE --- src/corelib/io/qfilesystemmetadata_p.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 03bb7f6..5b5587b 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -370,11 +370,13 @@ inline void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, boo if (setLinkType) { knownFlagsMask |= LinkType; entryFlags &= ~LinkType; +#if !defined(Q_OS_WINCE) if ((fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT) && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK || findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) { entryFlags |= LinkType; } +#endif } } -- cgit v0.12 From e2498cf6e6c193df849f6dbbaab3a827ca3e3a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Sun, 5 Dec 2010 01:25:02 +0100 Subject: Removing unused duplicate definitions These functions have been forked in qfilesystemengine_win.cpp and are no longer used in this file. Cleaning up. --- src/corelib/io/qfsfileengine_win.cpp | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 715fe39..3b6e80c 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -75,15 +75,6 @@ QT_BEGIN_NAMESPACE - - -#if defined(Q_OS_WINCE) -static QString qfsPrivateCurrentDir = QLatin1String(""); -// As none of the functions we try to resolve do exist on Windows CE -// we use QT_NO_LIBRARY to shorten everything up a little bit. -#define QT_NO_LIBRARY 1 -#endif - #if !defined(Q_OS_WINCE) static inline bool isUncPath(const QString &path) { @@ -114,24 +105,6 @@ QString QFSFileEnginePrivate::longFileName(const QString &path) #endif } -static inline bool getFindData(QString path, WIN32_FIND_DATA &findData) -{ - // path should not end with a trailing slash - while (path.endsWith(QLatin1Char('\\'))) - path.chop(1); - - // can't handle drives - if (!path.endsWith(QLatin1Char(':'))) { - HANDLE hFind = ::FindFirstFile((wchar_t*)path.utf16(), &findData); - if (hFind != INVALID_HANDLE_VALUE) { - ::FindClose(hFind); - return true; - } - } - - return false; -} - /* \internal */ -- cgit v0.12 From e37ca76dc70269017eaa7a32c4fae97c9e153ca0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Sun, 5 Dec 2010 01:28:48 +0100 Subject: New attempt at fixing compilation failure Including windows.h and defining _WIN32_WINNT didn't cut it. Instead, fall back to explicitly #defining IO_REPARSE_TAG_SYMLINK in metadata header, since it's all that's needed there. In windows-specific iterator implementation ensure _WIN32_WINNT >= 0x0500. --- src/corelib/io/qfilesystemiterator_win.cpp | 3 ++- src/corelib/io/qfilesystemmetadata_p.h | 7 ++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 96c7fdb..6608a9e 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -43,7 +43,8 @@ #include "qfilesystemengine_p.h" #include "qplatformdefs.h" -#ifndef _WIN32_WINNT +#if _WIN32_WINNT < 0x0500 +#undef _WIN32_WINNT #define _WIN32_WINNT 0x0500 #endif diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 5b5587b..c4e11d9 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -60,15 +60,12 @@ // Platform-specific includes #if defined(Q_OS_WIN) -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0500 +#ifndef IO_REPARSE_TAG_SYMLINK +#define IO_REPARSE_TAG_SYMLINK (0xA000000CL) #endif - -#include #elif defined(Q_OS_SYMBIAN) #include #include -#else #endif QT_BEGIN_NAMESPACE -- cgit v0.12 From 364e9d4ff5056f36fbff436ba9539a69ae45c5d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Sun, 5 Dec 2010 03:05:40 +0100 Subject: Define _WIN32_WINNT before any includes ... to ensure it's properly defined before is ever included. --- src/corelib/io/qfilesystemiterator_win.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 6608a9e..b5fce12 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -39,15 +39,15 @@ ** ****************************************************************************/ -#include "qfilesystemiterator_p.h" -#include "qfilesystemengine_p.h" -#include "qplatformdefs.h" - #if _WIN32_WINNT < 0x0500 #undef _WIN32_WINNT #define _WIN32_WINNT 0x0500 #endif +#include "qfilesystemiterator_p.h" +#include "qfilesystemengine_p.h" +#include "qplatformdefs.h" + #include QT_BEGIN_NAMESPACE -- cgit v0.12 From dcc7df8ed32d900a616d415c0eb2565e559f6435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Sun, 5 Dec 2010 11:12:37 +0100 Subject: Add missing license header to test case --- .../tst_qabstractfileengine.cpp | 41 ++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp b/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp index f98adca..5952252 100644 --- a/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp +++ b/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** 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 FOO module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the 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 #include -- cgit v0.12 From 9371ba70ac747484b1300d96c2a80dcdbc872fe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Sun, 5 Dec 2010 11:28:28 +0100 Subject: Fix spelling in comments --- src/corelib/io/qfilesystemengine_symbian.cpp | 2 +- src/corelib/io/qfilesystemengine_win.cpp | 2 +- tests/auto/qdir/tst_qdir.cpp | 2 +- tests/auto/qfile/tst_qfile.cpp | 4 ++-- tests/auto/qfiledialog/tst_qfiledialog.cpp | 8 ++++---- tests/auto/qfileinfo/tst_qfileinfo.cpp | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 3659a39..84c3aa1 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -378,7 +378,7 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry) if(!abspath.endsWith(QLatin1Char('\\'))) abspath.append(QLatin1Char('\\')); TInt r = fs.SetSessionPath(qt_QString2TPtrC(abspath)); - //SetSessionPath succeeds for non existant directory, which is why it's checked above + //SetSessionPath succeeds for non existent directory, which is why it's checked above if (r == KErrNone) { __ASSERT_COMPILE(sizeof(wchar_t) == sizeof(unsigned short)); //attempt to set open C to the same path diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 621b631..39fce97 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -378,7 +378,7 @@ static QString readLink(const QFileSystemEntry &link) static bool uncShareExists(const QString &server) { - // This code asumes the UNC path is always like \\?\UNC\server... + // This code assumes the UNC path is always like \\?\UNC\server... QStringList parts = server.split(QLatin1Char('\\'), QString::SkipEmptyParts); if (parts.count() >= 3) { QStringList shares; diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 6a81da6..dc46f52 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -928,7 +928,7 @@ void tst_QDir::current() if (!path.isEmpty()) { bool b = QDir::setCurrent(path); - // If path is non existant, then setCurrent should be false (currentDir is empty in testData) + // If path is non existent, then setCurrent should be false (currentDir is empty in testData) QVERIFY(b == !currentDir.isEmpty()); } if (!currentDir.isEmpty()) { diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index a8715e2..c19079f 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -414,7 +414,7 @@ void tst_QFile::cleanupTestCase() // attributes and the contents itself // will be changed as far as we have a // proper way to handle files in the -// testing enviroment. +// testing environment. //------------------------------------------ void tst_QFile::exists() @@ -1702,7 +1702,7 @@ void tst_QFile::seekAfterEndOfFile() void tst_QFile::FILEReadWrite() { - // Tests modifing a file. First creates it then reads in 4 bytes and then overwrites these + // Tests modifying a file. First creates it then reads in 4 bytes and then overwrites these // 4 bytes with new values. At the end check to see the file contains the new values. QFile::remove("FILEReadWrite.txt"); diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp index ec244c5..668a3e0 100644 --- a/tests/auto/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp @@ -187,7 +187,7 @@ public: QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const { return QSize(); } }; -// emited any time the selection model emits current changed +// emitted any time the selection model emits current changed void tst_QFiledialog::currentChangedSignal() { QNonNativeFileDialog fd; @@ -212,7 +212,7 @@ void tst_QFiledialog::currentChangedSignal() QCOMPARE(spyCurrentChanged.count(), 1); } -// only emited from the views, sidebar, or lookin combo +// only emitted from the views, sidebar, or lookin combo void tst_QFiledialog::directoryEnteredSignal() { #if defined QT_BUILD_INTERNAL @@ -273,7 +273,7 @@ void tst_QFiledialog::filesSelectedSignal_data() QTest::newRow("existingFiles") << QFileDialog::ExistingFiles; } -// emited when the dialog closes with the selected files +// emitted when the dialog closes with the selected files void tst_QFiledialog::filesSelectedSignal() { QNonNativeFileDialog fd; @@ -317,7 +317,7 @@ void tst_QFiledialog::filesSelectedSignal() QCOMPARE(spyFilesSelected.count(), 1); } -// only emited when the combo box is activated +// only emitted when the combo box is activated void tst_QFiledialog::filterSelectedSignal() { QNonNativeFileDialog fd; diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 79c5184..3bbe2ca 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -1653,8 +1653,8 @@ void tst_QFileInfo::owner() DWORD bufSize = 1024; if (GetUserNameW(usernameBuf, &bufSize)) { userName = QString::fromWCharArray(usernameBuf, bufSize); - // Special case : If the user is a member of Adminstrators group, all files - // created by the current user are owned by the Admistrators group. + // Special case : If the user is a member of Administrators group, all files + // created by the current user are owned by the Administrators group. LPLOCALGROUP_USERS_INFO_0 pBuf = NULL; DWORD dwLevel = 0; DWORD dwFlags = LG_INCLUDE_INDIRECT ; @@ -1664,7 +1664,7 @@ void tst_QFileInfo::owner() NET_API_STATUS nStatus; nStatus = NetUserGetLocalGroups(0, usernameBuf, dwLevel, dwFlags, (LPBYTE *) &pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries); - // Check if the current user is a member of Adminstrators group + // Check if the current user is a member of Administrators group if (nStatus == NERR_Success && pBuf){ for (int i = 0; i < dwEntriesRead; i++) { QString groupName = QString::fromWCharArray(pBuf[i].lgrui0_name); -- cgit v0.12 From 01276467bc7cf9b7cf8f83dc924a47b90e5bf053 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Sun, 5 Dec 2010 19:53:12 +0100 Subject: Fix code style issues in QScroller based Flickable replacement. --- src/declarative/graphicsitems/qdeclarativegridview.cpp | 4 ++-- src/declarative/graphicsitems/qdeclarativelistview.cpp | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index b6af7dc..8f6c34f 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1610,14 +1610,14 @@ bool QDeclarativeGridView::event(QEvent *event) qreal rowPos = d->rowPosAt(d->currentIndex); if (rowPos - d->rowSize() >= 0) snapPoints.append( rowPos - d->rowSize()); - else if( d->header ) + else if (d->header) snapPoints.append(0); // position of the header snapPoints.append(rowPos); if (rowPos + d->rowSize() < d->headerSize() + d->contentSize()) snapPoints.append(rowPos + d->rowSize()); - else if( d->footer ) + else if (d->footer) snapPoints.append(d->headerSize() + d->contentSize() + snapOffset); // position of the footer } diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 27f7b52..d6a75ba 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -309,7 +309,7 @@ public: pos = visibleItems.first()->position(); pos -= visibleIndex * (averageSize + spacing); } - if( header ) + if (header) pos -= header->size(); return pos; } @@ -960,7 +960,6 @@ void QDeclarativeListViewPrivate::recreateHighlight() */ void QDeclarativeListViewPrivate::updateHighlight(bool smooth) { - if ((!currentItem && highlight) || (currentItem && !highlight)) recreateHighlight(); @@ -2356,7 +2355,7 @@ void QDeclarativeListView::viewportAboutToMove(QPointF newPos) // qDebug() << "viewport about to move"; // need to refill before moving - if( d->orient == Horizontal ) + if (d->orient == Horizontal) d->refill(newPos.x(), newPos.x() + width() - 1); else d->refill(newPos.y(), newPos.y() + height() - 1); @@ -2837,7 +2836,6 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) } } - // restore the start position of the visible items if (firstVisible && forceConst(d->visibleItems).first() != firstVisible) forceConst(d->visibleItems).first()->setPosition(forceConst(d->visibleItems).first()->position() + preRemovedSize); -- cgit v0.12 From db506f31cf98d050aef10534fb5dad7058f64caf Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 6 Dec 2010 08:57:21 +1000 Subject: Doc: make it clear that "z" affects sibling stacking order. Task-number: QTBUG-15802 --- src/declarative/graphicsitems/qdeclarativeitem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 9d6fe12..932e68f 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -1809,9 +1809,9 @@ void QDeclarativeItem::setClip(bool c) /*! \qmlproperty real Item::z - Sets the stacking order of the item. By default the stacking order is 0. + Sets the stacking order of sibling items. By default the stacking order is 0. - Items with a higher stacking value are drawn on top of items with a + Items with a higher stacking value are drawn on top of siblings with a lower stacking order. Items with the same stacking value are drawn bottom up in the order they appear. Items with a negative stacking value are drawn under their parent's content. -- cgit v0.12 From ac977c4d57eba8fe2b71e51fc3d0b5eddd416e17 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Mon, 6 Dec 2010 12:46:35 +1000 Subject: Qt.include() docs weren't being picked up by qdoc This moves the Qt.include() docs to qdeclarativeengine.cpp and also documents it in the "Integrating JavaScript" page. Task-number: QTBUG-15855 --- doc/src/declarative/javascriptblocks.qdoc | 25 ++++++++++ .../integrating-javascript/includejs/app.qml | 56 ++++++++++++++++++++++ .../integrating-javascript/includejs/factorial.js | 49 +++++++++++++++++++ .../integrating-javascript/includejs/script.js | 48 +++++++++++++++++++ src/declarative/qml/qdeclarativeengine.cpp | 27 +++++++++++ src/declarative/qml/qdeclarativeinclude.cpp | 24 +--------- 6 files changed, 207 insertions(+), 22 deletions(-) create mode 100644 doc/src/snippets/declarative/integrating-javascript/includejs/app.qml create mode 100644 doc/src/snippets/declarative/integrating-javascript/includejs/factorial.js create mode 100644 doc/src/snippets/declarative/integrating-javascript/includejs/script.js diff --git a/doc/src/declarative/javascriptblocks.qdoc b/doc/src/declarative/javascriptblocks.qdoc index 16d0633..41b64da 100644 --- a/doc/src/declarative/javascriptblocks.qdoc +++ b/doc/src/declarative/javascriptblocks.qdoc @@ -143,6 +143,31 @@ As they are shared, stateless library files cannot access QML component instance objects or properties directly, although QML values can be passed as function parameters. + +\section2 Importing One JavaScript File From Another + +If a JavaScript file needs to use functions defined inside another JavaScript file, +the other file can be imported using the \l {QML:Qt::include()}{Qt.include()} +function. This imports all functions from the other file into the current file's +namespace. + +For example, the QML code below left calls \c showCalculations() in \c script.js, +which in turn can call \c factorial() in \c factorial.js, as it has included +\c factorial.js using \l {QML:Qt::include()}{Qt.include()}. + +\table +\row +\o {1,2} \snippet doc/src/snippets/declarative/integrating-javascript/includejs/app.qml 0 +\o \snippet doc/src/snippets/declarative/integrating-javascript/includejs/script.js 0 +\row +\o \snippet doc/src/snippets/declarative/integrating-javascript/includejs/factorial.js 0 +\endtable + +Notice that calling \l {QML:Qt::include()}{Qt.include()} imports all functions from +\c factorial.js into the \c MyScript namespace, which means the QML component can also +access \c factorial() directly as \c MyScript.factorial(). + + \section1 Running JavaScript at Startup It is occasionally necessary to run some imperative code at application (or diff --git a/doc/src/snippets/declarative/integrating-javascript/includejs/app.qml b/doc/src/snippets/declarative/integrating-javascript/includejs/app.qml new file mode 100644 index 0000000..2ecc475 --- /dev/null +++ b/doc/src/snippets/declarative/integrating-javascript/includejs/app.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick 1.0 +import "script.js" as MyScript + +Item { + width: 100; height: 100 + + MouseArea { + anchors.fill: parent + onClicked: { + MyScript.showCalculations(10) + console.log("Call factorial() from QML:", + MyScript.factorial(10)) + } + } +} +//![0] diff --git a/doc/src/snippets/declarative/integrating-javascript/includejs/factorial.js b/doc/src/snippets/declarative/integrating-javascript/includejs/factorial.js new file mode 100644 index 0000000..0a01e9e --- /dev/null +++ b/doc/src/snippets/declarative/integrating-javascript/includejs/factorial.js @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +// factorial.js +function factorial(a) { + a = parseInt(a); + if (a <= 0) + return 1; + else + return a * factorial(a - 1); +} +//![0] diff --git a/doc/src/snippets/declarative/integrating-javascript/includejs/script.js b/doc/src/snippets/declarative/integrating-javascript/includejs/script.js new file mode 100644 index 0000000..7380412 --- /dev/null +++ b/doc/src/snippets/declarative/integrating-javascript/includejs/script.js @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +// script.js +Qt.include("factorial.js") + +function showCalculations(value) { + console.log("Call factorial() from script.js:", + factorial(value)); +} +//![0] diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index a8404f0..201e675 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -261,6 +261,33 @@ of their use. \endlist */ +/*! +\qmlmethod object Qt::include(string url, jsobject callback) + +Includes another JavaScript file. This method can only be used from within JavaScript files, +and not regular QML files. + +This imports all functions from \a url into the current script's namespace. + +Qt.include() returns an object that describes the status of the operation. The object has +a single property, \c {status}, that is set to one of the following values: + +\table +\header \o Symbol \o Value \o Description +\row \o result.OK \o 0 \o The include completed successfully. +\row \o result.LOADING \o 1 \o Data is being loaded from the network. +\row \o result.NETWORK_ERROR \o 2 \o A network error occurred while fetching the url. +\row \o result.EXCEPTION \o 3 \o A JavaScript exception occurred while executing the included code. +An additional \c exception property will be set in this case. +\endtable + +The \c status property will be updated as the operation progresses. + +If provided, \a callback is invoked when the operation completes. The callback is passed +the same object as is returned from the Qt.include() call. +*/ +// Qt.include() is implemented in qdeclarativeinclude.cpp + QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e) : captureProperties(false), rootContext(0), isDebugging(false), diff --git a/src/declarative/qml/qdeclarativeinclude.cpp b/src/declarative/qml/qdeclarativeinclude.cpp index 1e240d7..a9ecdda 100644 --- a/src/declarative/qml/qdeclarativeinclude.cpp +++ b/src/declarative/qml/qdeclarativeinclude.cpp @@ -172,28 +172,8 @@ void QDeclarativeInclude::callback(QScriptEngine *engine, QScriptValue &callback } } -/*! -\qmlmethod object Qt::include(string url, jsobject callback) - -Include another JavaScript file. This method can only be used from within JavaScript files, -and not regular QML files. - -Qt.include() returns an object that describes the status of the operation. The object has -a single property, \c {status} that is set to one of the following values: - -\table -\header \o Symbol \o Value \o Description -\row \o result.OK \o 0 \o The include completed successfully. -\row \o result.LOADING \o 1 \o Data is being loaded from the network. -\row \o result.NETWORK_ERROR \o 2 \o A network error occurred while fetching the url. -\row \o result.EXCEPTION \o 3 \o A JavaScript exception occurred while executing the included code. -An additional \c exception property will be set in this case. -\endtable - -The return object's properties will be updated as the operation progresses. - -If provided, \a callback is invoked when the operation completes. The callback is passed -the same object as is returned from the Qt.include() call. +/* + Documented in qdeclarativeengine.cpp */ QScriptValue QDeclarativeInclude::include(QScriptContext *ctxt, QScriptEngine *engine) { -- cgit v0.12 From d3dc2ab3e0ee6bca8eca374e3cb3b3f4c7d0c34e Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Mon, 6 Dec 2010 15:12:52 +1000 Subject: Fix license header. Reviewed-by: Trust Me --- doc/src/examples/wheel.qdoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/src/examples/wheel.qdoc b/doc/src/examples/wheel.qdoc index 1ea85fc..992aba6 100644 --- a/doc/src/examples/wheel.qdoc +++ b/doc/src/examples/wheel.qdoc @@ -7,11 +7,11 @@ ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:FDL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in a -** written agreement between you and Nokia. +** 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 Free Documentation License ** Alternatively, this file may be used under the terms of the GNU Free -- cgit v0.12 From b74ec2156b2a1f1acd38443047da5bb26cb082b1 Mon Sep 17 00:00:00 2001 From: Christopher Ham Date: Mon, 6 Dec 2010 15:46:47 +1000 Subject: Cursor shouldn't blink while dragging cursor position A function resetCursorBlinkerTimer was introduced to QLineControl. Each time the cursor position in a textInput is updated, the blinker timer is reset. Task-number: QTBUG-15815 Reviewed-by: Martin Jones --- src/declarative/graphicsitems/qdeclarativetextinput.cpp | 1 + src/gui/widgets/qlinecontrol.cpp | 9 +++++++++ src/gui/widgets/qlinecontrol_p.h | 1 + 3 files changed, 11 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index f8421a3..df103de 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -1479,6 +1479,7 @@ void QDeclarativeTextInput::cursorPosChanged() updateRect();//TODO: Only update rect between pos's updateMicroFocus(); emit cursorPositionChanged(); + d->control->resetCursorBlinkTimer(); if(!d->control->hasSelectedText()){ if(d->lastSelectionStart != d->control->cursor()){ diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index f338f40..5ea9dc4 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -1308,6 +1308,15 @@ void QLineControl::setCursorBlinkPeriod(int msec) m_blinkPeriod = msec; } +void QLineControl::resetCursorBlinkTimer() +{ + if (m_blinkPeriod == 0 || m_blinkTimer == 0) + return; + killTimer(m_blinkTimer); + m_blinkTimer = startTimer(m_blinkPeriod / 2); + m_blinkStatus = 1; +} + void QLineControl::timerEvent(QTimerEvent *event) { if (event->timerId() == m_blinkTimer) { diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index 7068f62..d881acf 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -296,6 +296,7 @@ public: int cursorBlinkPeriod() const { return m_blinkPeriod; } void setCursorBlinkPeriod(int msec); + void resetCursorBlinkTimer(); QString cancelText() const { return m_cancelText; } void setCancelText(const QString &text) { m_cancelText = text; } -- cgit v0.12 From 4fb210b9e225fffafdaac26e0acb3c0b71087137 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 25 Nov 2010 12:33:14 +0200 Subject: Fix proxy reading from gconf so that it is only done once / session. Fixes: NB#194509 - Network access from a Qt app makes dbus daemon consume tons of cpu Task-number: QT-4220 --- src/plugins/bearer/icd/proxyconf.cpp | 18 ++++++++++++++---- src/plugins/bearer/icd/proxyconf.h | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/plugins/bearer/icd/proxyconf.cpp b/src/plugins/bearer/icd/proxyconf.cpp index e5c8f4e..37501fb 100644 --- a/src/plugins/bearer/icd/proxyconf.cpp +++ b/src/plugins/bearer/icd/proxyconf.cpp @@ -142,16 +142,23 @@ QHash GConfItemFast::getEntries() const -class NetworkProxyFactory : QNetworkProxyFactory { +class NetworkProxyFactory : QNetworkProxyFactory +{ + ProxyConf proxy_conf; + bool proxy_data_read; + public: - NetworkProxyFactory() { } + NetworkProxyFactory() : proxy_data_read(false) { } QList queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery()); }; QList NetworkProxyFactory::queryProxy(const QNetworkProxyQuery &query) { - ProxyConf proxy_conf; + if (proxy_data_read == false) { + proxy_data_read = true; + proxy_conf.readProxyData(); + } QList result = proxy_conf.flush(query); if (result.isEmpty()) @@ -377,10 +384,13 @@ ProxyConf::~ProxyConf() delete d_ptr; } +void ProxyConf::readProxyData() +{ + d_ptr->readProxyData(); +} QList ProxyConf::flush(const QNetworkProxyQuery &query) { - d_ptr->readProxyData(); return d_ptr->flush(query); } diff --git a/src/plugins/bearer/icd/proxyconf.h b/src/plugins/bearer/icd/proxyconf.h index 884cc5c..eedbbf2 100644 --- a/src/plugins/bearer/icd/proxyconf.h +++ b/src/plugins/bearer/icd/proxyconf.h @@ -58,6 +58,7 @@ public: virtual ~ProxyConf(); QList flush(const QNetworkProxyQuery &query = QNetworkProxyQuery()); // read the proxies from db + void readProxyData(); /* Note that for each update() call there should be corresponding * clear() call because the ProxyConf class implements a reference -- cgit v0.12 From 2051459dd9a257c6492c755a583ff331e7009012 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Mon, 6 Dec 2010 17:49:04 +1000 Subject: Some doc clarification for components and javascript integration --- doc/src/declarative/javascriptblocks.qdoc | 5 ++--- src/declarative/qml/qdeclarativecomponent.cpp | 28 +++++++++++++++------------ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/doc/src/declarative/javascriptblocks.qdoc b/doc/src/declarative/javascriptblocks.qdoc index 41b64da..155bd6e 100644 --- a/doc/src/declarative/javascriptblocks.qdoc +++ b/doc/src/declarative/javascriptblocks.qdoc @@ -94,9 +94,8 @@ Both relative and absolute JavaScript URLs can be imported. In the case of a relative URL, the location is resolved relative to the location of the \l {QML Document} that contains the import. If the script file is not accessible, an error will occur. If the JavaScript needs to be fetched from a network -resource, the QML document has a "Loading" -\l {QDeclarativeComponent::status()}{status} until the script has been -downloaded. +resource, the component's \l {QDeclarativeComponent::status()}{status} is set to +"Loading" until the script has been downloaded. Imported JavaScript files are always qualified using the "as" keyword. The qualifier for JavaScript files must be unique, so there is always a one-to-one diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index 63bde0f..77fc925 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -147,32 +147,36 @@ class QByteArray; Components are reusable, encapsulated QML elements with well-defined interfaces. Components are often defined by \l {qdeclarativedocuments.html}{component files} - - that is, \c .qml files. The \e Component element allows components to be defined - within QML items rather than in a separate file. This may be useful for reusing - a small component within a QML file, or for defining a component that logically - belongs with other QML components within a file. + that is, \c .qml files. The \e Component element essentially allows QML components + to be defined inline, within a \l {QML Document}{QML document}, rather than as a separate QML file. + This may be useful for reusing a small component within a QML file, or for defining + a component that logically belongs with other QML components within a file. For example, here is a component that is used by multiple \l Loader objects. - It contains a top level \l Rectangle item: + It contains a single item, a \l Rectangle: \snippet doc/src/snippets/declarative/component.qml 0 Notice that while a \l Rectangle by itself would be automatically rendered and displayed, this is not the case for the above rectangle because it is defined inside a \c Component. The component encapsulates the - QML elements within, as if they were defined in a separate \c .qml + QML elements within, as if they were defined in a separate QML file, and is not loaded until requested (in this case, by the two \l Loader objects). - A Component cannot contain anything other - than an \c id and a single top level item. While the \c id is optional, - the top level item is not; you cannot define an empty component. + Defining a \c Component is similar to defining a \l {QML Document}{QML document}. + A QML document has a single top-level item that defines the behaviors and + properties of that component, and cannot define properties or behaviors outside + of that top-level item. In the same way, a \c Component definition contains a single + top level item (which in the above example is a \l Rectangle) and cannot define any + data outside of this item, with the exception of an \e id (which in the above example + is \e redSquare). - The Component element is commonly used to provide graphical components - for views. For example, the ListView::delegate property requires a Component + The \c Component element is commonly used to provide graphical components + for views. For example, the ListView::delegate property requires a \c Component to specify how each list item is to be displayed. - Component objects can also be dynamically created using + \c Component objects can also be created dynamically using \l{QML:Qt::createComponent()}{Qt.createComponent()}. */ -- cgit v0.12 From 2e7cfca6089a0923698b9cd208f79a660e058caa Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Mon, 6 Dec 2010 17:49:17 +1000 Subject: Document support for QVariantList and QVariantMap type conversion --- doc/src/declarative/qtbinding.qdoc | 34 ++++++++++- .../qtbinding/variantlistmap/MyItem.qml | 54 +++++++++++++++++ .../declarative/qtbinding/variantlistmap/main.cpp | 67 ++++++++++++++++++++++ .../qtbinding/variantlistmap/variantlistmap.pro | 2 + 4 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 doc/src/snippets/declarative/qtbinding/variantlistmap/MyItem.qml create mode 100644 doc/src/snippets/declarative/qtbinding/variantlistmap/main.cpp create mode 100644 doc/src/snippets/declarative/qtbinding/variantlistmap/variantlistmap.pro diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc index 71f41bc..04b8ca6 100644 --- a/doc/src/declarative/qtbinding.qdoc +++ b/doc/src/declarative/qtbinding.qdoc @@ -426,6 +426,7 @@ By default, QML recognizes the following data types: \o QSize, QSizeF \o QRect, QRectF \o QVariant +\o QVariantList, QVariantMap \o QObject* \o Enumerations declared with Q_ENUMS() \endlist @@ -434,6 +435,37 @@ To allow a custom C++ type to be created or used in QML, the C++ class must be r type using qmlRegisterType(), as shown in the \l {Defining new QML elements} section above. +\section2 JavaScript arrays and objects + +There is built-in support for automatic type conversion between QVariantList and JavaScript +arrays, and QVariantMap and JavaScript objects. + +For example, the function defined in QML below left expects two arguments, an array and an object, and prints +their contents using the standard JavaScript syntax for array and object item access. The C++ code +below right calls this function, passing a QVariantList and a QVariantMap, which are automatically +converted to JavaScript array and object values, repectively: + +\table +\row +\o \snippet doc/src/snippets/declarative/qtbinding/variantlistmap/MyItem.qml 0 +\o \snippet doc/src/snippets/declarative/qtbinding/variantlistmap/main.cpp 0 +\endtable + +This produces output like: + +\code +Array item: 10 +Array item: #00ff00 +Array item: bottles +Object item: language = QML +Object item: released = Tue Sep 21 2010 00:00:00 GMT+1000 (EST) +\endcode + +Similarly, if a C++ type uses a QVariantList or QVariantMap type for a property or method +parameter, the value can be created as a JavaScript array or object in the QML +side, and is automatically converted to a QVariantList or QVariantMap when it is passed to C++. + + \section2 Using enumerations of a custom type To use an enumeration from a custom C++ component, the enumeration must be declared with Q_ENUMS() to @@ -455,7 +487,7 @@ See the \l {Tutorial: Writing QML extensions with C++}{Writing QML extensions wi the \l {Extending QML in C++} reference documentation for more information. -\section2 Automatic type conversion +\section2 Automatic type conversion from strings As a convenience, some basic types can be specified in QML using format strings to make it easier to pass simple values from QML to C++. diff --git a/doc/src/snippets/declarative/qtbinding/variantlistmap/MyItem.qml b/doc/src/snippets/declarative/qtbinding/variantlistmap/MyItem.qml new file mode 100644 index 0000000..dd59fed --- /dev/null +++ b/doc/src/snippets/declarative/qtbinding/variantlistmap/MyItem.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** 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 documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 1.0 + +//![0] +// MyItem.qml +Item { + function readValues(anArray, anObject) { + for (var i=0; i +#include + +int main(int argc, char *argv[]) { + QApplication app(argc, argv); + +//![0] +// C++ +QDeclarativeView view(QUrl::fromLocalFile("MyItem.qml")); + +QVariantList list; +list << 10 << Qt::green << "bottles"; + +QVariantMap map; +map.insert("language", "QML"); +map.insert("released", QDate(2010, 9, 21)); + +QMetaObject::invokeMethod(view.rootObject(), "readValues", + Q_ARG(QVariant, QVariant::fromValue(list)), + Q_ARG(QVariant, QVariant::fromValue(map))); +//![0] + + view.setSource(QUrl::fromLocalFile("MyItem.qml")); + view.show(); + + return app.exec(); +} + diff --git a/doc/src/snippets/declarative/qtbinding/variantlistmap/variantlistmap.pro b/doc/src/snippets/declarative/qtbinding/variantlistmap/variantlistmap.pro new file mode 100644 index 0000000..68eeaf2 --- /dev/null +++ b/doc/src/snippets/declarative/qtbinding/variantlistmap/variantlistmap.pro @@ -0,0 +1,2 @@ +QT += declarative +SOURCES += main.cpp -- cgit v0.12 From 1ba320366e1b010ecf32c263574e183e4b1f452d Mon Sep 17 00:00:00 2001 From: Jedrzej Nowacki Date: Tue, 23 Nov 2010 10:58:46 +0200 Subject: Move test data to a qrc file. Using qrc file simplify deployment on a device. Reviewed-by: Kent Hansen --- tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro | 8 +------- tests/auto/qscriptv8testsuite/qscriptv8testsuite.qrc | 5 +++++ tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp | 12 +++--------- tests/benchmarks/script/sunspider/sunspider.pro | 10 +--------- tests/benchmarks/script/sunspider/sunspider.qrc | 5 +++++ tests/benchmarks/script/sunspider/tst_sunspider.cpp | 9 ++------- tests/benchmarks/script/v8/tst_v8.cpp | 9 ++------- tests/benchmarks/script/v8/v8.pro | 10 +--------- tests/benchmarks/script/v8/v8.qrc | 5 +++++ 9 files changed, 25 insertions(+), 48 deletions(-) create mode 100644 tests/auto/qscriptv8testsuite/qscriptv8testsuite.qrc create mode 100644 tests/benchmarks/script/sunspider/sunspider.qrc create mode 100644 tests/benchmarks/script/v8/v8.qrc diff --git a/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro index 5d8e5af4..00e2e01 100644 --- a/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro +++ b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro @@ -1,10 +1,4 @@ load(qttest_p4) QT = core script SOURCES += tst_qscriptv8testsuite.cpp -!symbian:DEFINES += SRCDIR=\\\"$$PWD\\\" - -wince*|symbian: { -testFiles.files = tests -testFiles.path = . -DEPLOYMENT += testFiles -} +RESOURCES += qscriptv8testsuite.qrc diff --git a/tests/auto/qscriptv8testsuite/qscriptv8testsuite.qrc b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.qrc new file mode 100644 index 0000000..a894ee5 --- /dev/null +++ b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.qrc @@ -0,0 +1,5 @@ + + + tests + + diff --git a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp index 5f9a578..912027e 100644 --- a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp +++ b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp @@ -45,10 +45,6 @@ #include -#if defined(Q_OS_SYMBIAN) -# define SRCDIR "" -#endif - //TESTED_CLASS= //TESTED_FILES= @@ -217,9 +213,8 @@ int tst_Suite::qt_metacall(QMetaObject::Call _c, int _id, void **_a) tst_Suite::tst_Suite() { - testsDir = QDir(SRCDIR); - bool testsFound = testsDir.cd("tests"); - if (!testsFound) { + testsDir = QDir(":/tests"); + if (!testsDir.exists()) { qWarning("*** no tests/ dir!"); } else { if (!testsDir.exists("mjsunit.js")) @@ -297,8 +292,7 @@ tst_Suite::tst_Suite() appendCString(stringdata, ""); QFileInfoList testFileInfos; - if (testsFound) - testFileInfos = testsDir.entryInfoList(QStringList() << "*.js", QDir::Files); + testFileInfos = testsDir.entryInfoList(QStringList() << "*.js", QDir::Files); foreach (QFileInfo tfi, testFileInfos) { QString name = tfi.baseName(); // slot: signature, parameters, type, tag, flags diff --git a/tests/benchmarks/script/sunspider/sunspider.pro b/tests/benchmarks/script/sunspider/sunspider.pro index aab4cdb..dce3855 100644 --- a/tests/benchmarks/script/sunspider/sunspider.pro +++ b/tests/benchmarks/script/sunspider/sunspider.pro @@ -1,19 +1,11 @@ load(qttest_p4) TEMPLATE = app TARGET = tst_bench_sunspider - +RESOURCES += sunspider.qrc SOURCES += tst_sunspider.cpp QT = core script -!symbian:DEFINES += SRCDIR=\\\"$$PWD\\\" - -wince*|symbian: { -testFiles.files = tests -testFiles.path = . -DEPLOYMENT += testFiles -} - symbian* { TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 // Min 128kB, Max 32MB TARGET.EPOCSTACKSIZE = 0x14000 diff --git a/tests/benchmarks/script/sunspider/sunspider.qrc b/tests/benchmarks/script/sunspider/sunspider.qrc new file mode 100644 index 0000000..a894ee5 --- /dev/null +++ b/tests/benchmarks/script/sunspider/sunspider.qrc @@ -0,0 +1,5 @@ + + + tests + + diff --git a/tests/benchmarks/script/sunspider/tst_sunspider.cpp b/tests/benchmarks/script/sunspider/tst_sunspider.cpp index 7a8617a..0df19b6 100644 --- a/tests/benchmarks/script/sunspider/tst_sunspider.cpp +++ b/tests/benchmarks/script/sunspider/tst_sunspider.cpp @@ -46,10 +46,6 @@ #include #include -#if defined(Q_OS_SYMBIAN) -# define SRCDIR "" -#endif - //TESTED_FILES= static QString readFile(const QString &filename) @@ -84,9 +80,8 @@ private: tst_SunSpider::tst_SunSpider() { - testsDir = QDir(SRCDIR); - bool testsFound = testsDir.cd("tests"); - if (!testsFound) + testsDir = QDir(":/tests"); + if (!testsDir.exists()) qWarning("*** no tests/ dir!"); } diff --git a/tests/benchmarks/script/v8/tst_v8.cpp b/tests/benchmarks/script/v8/tst_v8.cpp index f8297e2..841e2f3 100644 --- a/tests/benchmarks/script/v8/tst_v8.cpp +++ b/tests/benchmarks/script/v8/tst_v8.cpp @@ -46,10 +46,6 @@ #include #include -#if defined(Q_OS_SYMBIAN) -# define SRCDIR "" -#endif - //TESTED_FILES= static QString readFile(const QString &filename) @@ -84,9 +80,8 @@ private: tst_V8::tst_V8() { - testsDir = QDir(SRCDIR); - bool testsFound = testsDir.cd("tests"); - if (!testsFound) + testsDir = QDir(":/tests"); + if (!testsDir.exists()) qWarning("*** no tests/ dir!"); } diff --git a/tests/benchmarks/script/v8/v8.pro b/tests/benchmarks/script/v8/v8.pro index f36bda5..547eecc 100644 --- a/tests/benchmarks/script/v8/v8.pro +++ b/tests/benchmarks/script/v8/v8.pro @@ -1,19 +1,11 @@ load(qttest_p4) TEMPLATE = app TARGET = tst_bench_v8 - +RESOURCES += v8.qrc SOURCES += tst_v8.cpp QT = core script -!symbian:DEFINES += SRCDIR=\\\"$$PWD\\\" - -wince*|symbian: { -testFiles.files = tests -testFiles.path = . -DEPLOYMENT += testFiles -} - symbian* { TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 // Min 128kB, Max 32MB TARGET.EPOCSTACKSIZE = 0x14000 diff --git a/tests/benchmarks/script/v8/v8.qrc b/tests/benchmarks/script/v8/v8.qrc new file mode 100644 index 0000000..a894ee5 --- /dev/null +++ b/tests/benchmarks/script/v8/v8.qrc @@ -0,0 +1,5 @@ + + + tests + + -- cgit v0.12 From 236d4e3c5d58e69a85a362c702d830227309404d Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Mon, 6 Dec 2010 13:34:13 +0100 Subject: Fix qreal vs. double issue and a copy/paste error. Reviewed-by: Ralf Engels --- .../graphicsitems/qdeclarativeflickable.cpp | 27 +++++++++++----------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 96f54a8..3d47a8d 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -600,7 +600,7 @@ void QDeclarativeFlickable::setFlickableDirection(FlickableDirection direction) */ qreal QDeclarativeFlickable::minXExtent() const { - return 0.0; + return 0; } /*! \internal @@ -609,7 +609,7 @@ qreal QDeclarativeFlickable::minXExtent() const */ qreal QDeclarativeFlickable::minYExtent() const { - return 0.0; + return 0; } /*! \internal Returns the maximum horizontal content position. @@ -617,7 +617,7 @@ qreal QDeclarativeFlickable::minYExtent() const qreal QDeclarativeFlickable::maxXExtent() const { Q_D(const QDeclarativeFlickable); - return qMax(0.0, d->contentItem->width()); + return qMax(qreal(0), d->contentItem->width()); } /*! \internal @@ -626,7 +626,7 @@ qreal QDeclarativeFlickable::maxXExtent() const qreal QDeclarativeFlickable::maxYExtent() const { Q_D(const QDeclarativeFlickable); - return qMax(0.0, d->contentItem->height()); + return qMax(qreal(0), d->contentItem->height()); } /*! \internal @@ -673,10 +673,10 @@ void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry, //qDebug() << "xxx geometryChanged: "<state() == QScroller::Inactive) - scroller->ensureVisible( QRectF(0.0, 0.0, - d->contentItem->width(), d->contentItem->height() ), 0, 0, 0 ); - else + if (scroller->state() == QScroller::Inactive) { + scroller->ensureVisible(QRectF(minXExtent(), minYExtent(), + d->contentItem->width(), d->contentItem->height()), 0, 0, 0); + } else d->updateScrollerValues(); d->updateBeginningEnd(); } @@ -840,9 +840,10 @@ void QDeclarativeFlickable::setContentWidth(qreal w) // Make sure that we're entirely in view. QScroller *scroller = QScroller::scroller(this); - if (scroller->state() == QScroller::Inactive) - scroller->ensureVisible( QRectF(0.0, 0.0, d->contentItem->width(), d->contentItem->height() ), 0, 0, 0 ); - else + if (scroller->state() == QScroller::Inactive) { + scroller->ensureVisible(QRectF(minXExtent(), minYExtent(), + d->contentItem->width(), d->contentItem->height()), 0, 0, 0); + } else d->updateScrollerValues(); emit contentWidthChanged(); @@ -869,8 +870,8 @@ void QDeclarativeFlickable::setContentHeight(qreal h) // Make sure that we're entirely in view. QScroller *scroller = QScroller::scroller(this); if (scroller->state() == QScroller::Inactive) { - scroller->ensureVisible( QRectF(minXExtent(), minYExtent(), - d->contentItem->width(), d->contentItem->height() ), 0, 0, 0 ); + scroller->ensureVisible(QRectF(minXExtent(), minYExtent(), + d->contentItem->width(), d->contentItem->height()), 0, 0, 0); } else d->updateScrollerValues(); -- cgit v0.12 From fb43ea28e2712073de06644d78ed5a97a40f016b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 6 Dec 2010 13:46:35 +0100 Subject: Fix QDir::relativeFilePath We used to call cleanPath on the result of absolutePath, before returning it to the user, but stopped doing that. relativeFilePath actually depended on that and broke. Fixed now. Reviewed-by: Prasanth Ullattil --- src/corelib/io/qdir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index e1fed0d..2f97c3a 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -711,7 +711,7 @@ QString QDir::absoluteFilePath(const QString &fileName) const */ QString QDir::relativeFilePath(const QString &fileName) const { - QString dir = absolutePath(); + QString dir = cleanPath(absolutePath()); QString file = cleanPath(fileName); if (isRelativePath(file) || isRelativePath(dir)) -- cgit v0.12 From 3f3ef052663371b81652f77892f7a217db9969a8 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Mon, 6 Dec 2010 14:17:56 +0100 Subject: Revert "QSystemTrayIcon::messageTimeout() signal implemented" This reverts commit 7a5b81532d482b611d5ea8b3a93e6ee9f9098db0. Reverted because the autotest fails. Reviewed-by: Gunnar --- src/gui/util/qsystemtrayicon.cpp | 14 +----- src/gui/util/qsystemtrayicon.h | 1 - src/gui/util/qsystemtrayicon_win.cpp | 4 -- tests/auto/qsystemtrayicon/qsystemtrayicon.pro | 1 - tests/auto/qsystemtrayicon/tst_qsystemtrayicon.cpp | 56 ---------------------- 5 files changed, 1 insertion(+), 75 deletions(-) diff --git a/src/gui/util/qsystemtrayicon.cpp b/src/gui/util/qsystemtrayicon.cpp index 1c95558..941961b 100644 --- a/src/gui/util/qsystemtrayicon.cpp +++ b/src/gui/util/qsystemtrayicon.cpp @@ -335,16 +335,6 @@ bool QSystemTrayIcon::event(QEvent *e) \sa activated() */ -/*! - \fn void QSystemTrayIcon::messageTimeout() - - This signal is emitted when the message displayed using showMessage() - hides automatically after being shown for the timeout value. - - Currently this signal is not sent on Mac OS X. - - \since 4.8 -*/ /*! Returns true if the system tray is available; otherwise returns false. @@ -667,10 +657,8 @@ void QBalloonTip::timerEvent(QTimerEvent *e) { if (e->timerId() == timerId) { killTimer(timerId); - if (!underMouse()) { + if (!underMouse()) close(); - emit trayIcon->messageTimeout(); - } return; } QWidget::timerEvent(e); diff --git a/src/gui/util/qsystemtrayicon.h b/src/gui/util/qsystemtrayicon.h index 5812d07..0a57e35 100644 --- a/src/gui/util/qsystemtrayicon.h +++ b/src/gui/util/qsystemtrayicon.h @@ -111,7 +111,6 @@ public Q_SLOTS: Q_SIGNALS: void activated(QSystemTrayIcon::ActivationReason reason); void messageClicked(); - void messageTimeout(); protected: bool event(QEvent *event); diff --git a/src/gui/util/qsystemtrayicon_win.cpp b/src/gui/util/qsystemtrayicon_win.cpp index 91b11ef..fc5de44 100644 --- a/src/gui/util/qsystemtrayicon_win.cpp +++ b/src/gui/util/qsystemtrayicon_win.cpp @@ -313,10 +313,6 @@ bool QSystemTrayIconSys::winEvent( MSG *m, long *result ) emit q->messageClicked(); break; - case NIN_BALLOONTIMEOUT: - emit q->messageTimeout(); - break; - case WM_MBUTTONUP: emit q->activated(QSystemTrayIcon::MiddleClick); break; diff --git a/tests/auto/qsystemtrayicon/qsystemtrayicon.pro b/tests/auto/qsystemtrayicon/qsystemtrayicon.pro index a33d072..a77b478 100644 --- a/tests/auto/qsystemtrayicon/qsystemtrayicon.pro +++ b/tests/auto/qsystemtrayicon/qsystemtrayicon.pro @@ -5,6 +5,5 @@ load(qttest_p4) SOURCES += tst_qsystemtrayicon.cpp -win32:LIBS += user32.lib diff --git a/tests/auto/qsystemtrayicon/tst_qsystemtrayicon.cpp b/tests/auto/qsystemtrayicon/tst_qsystemtrayicon.cpp index f4120ca..b1ec0ff 100644 --- a/tests/auto/qsystemtrayicon/tst_qsystemtrayicon.cpp +++ b/tests/auto/qsystemtrayicon/tst_qsystemtrayicon.cpp @@ -47,10 +47,6 @@ #include #include -#ifdef Q_OS_WIN32 -#include -#endif - //TESTED_CLASS= //TESTED_FILES= @@ -68,7 +64,6 @@ private slots: void showMessage(); void supportsMessages(); void lastWindowClosed(); - void messageTimeout(); }; tst_QSystemTrayIcon::tst_QSystemTrayIcon() @@ -149,56 +144,5 @@ void tst_QSystemTrayIcon::lastWindowClosed() QVERIFY(spy.count() == 1); } -#ifndef Q_WS_MAC - -static void triggerMessageTimeout() -{ -#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) - // the application has to loose focus on Windows for the message to timeout - INPUT input[2] = {}; - - input[0].type = INPUT_KEYBOARD; - input[0].ki.wVk = VK_LWIN; - input[0].ki.dwFlags = 0; - - input[1].type = INPUT_KEYBOARD; - input[1].ki.wVk = VK_LWIN; - input[1].ki.dwFlags = KEYEVENTF_KEYUP; - - for (int i = 0; i < 2; i++) { - QTest::qWait(100); - ::SendInput(2, input, sizeof(INPUT)); - } -#endif /* defined(Q_WS_WIN) && !defined(Q_WS_WINCE) */ -} - -void tst_QSystemTrayIcon::messageTimeout() -{ - QSystemTrayIcon icon; - if (icon.supportsMessages()) { - icon.setIcon(QIcon("whatever.png")); - icon.show(); - - QObject::connect(&icon, SIGNAL(messageTimeout()), qApp, SLOT(quit())); - QSignalSpy spy(&icon, SIGNAL(messageTimeout())); - icon.showMessage("Title", "Hello World!", QSystemTrayIcon::Information, 1000); - - triggerMessageTimeout(); - - QTimer::singleShot(30000, qApp, SLOT(quit())); // in case the test fails - qApp->exec(); - QVERIFY(spy.count() == 1); - } -} - -#else - -void tst_QSystemTrayIcon::messageTimeout() -{ - // skip the test on Mac OS X -} - -#endif /* Q_WS_MAC */ - QTEST_MAIN(tst_QSystemTrayIcon) #include "tst_qsystemtrayicon.moc" -- cgit v0.12 From 5bdc4ec60655aba2972f0e6cb2b09ee5f012690b Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Mon, 6 Dec 2010 14:24:58 +0100 Subject: Fix tst_QFileInfo::canonicalFilePath failure on Windows When the test application is running without administrative privilages, the CreateSymbolicLink() can incorrectly return success. To handle this we need to check whether GetLastError() returns ERROR_PRIVILEGE_NOT_HELD or not. Reviewed-by: Joao --- tests/auto/qfileinfo/tst_qfileinfo.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 3bbe2ca..96a0d77 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -621,18 +621,27 @@ void tst_QFileInfo::canonicalFilePath() PtrCreateSymbolicLink ptrCreateSymbolicLink = (PtrCreateSymbolicLink)QLibrary::resolve(QLatin1String("kernel32"), "CreateSymbolicLinkW"); - if (!ptrCreateSymbolicLink || - ptrCreateSymbolicLink((wchar_t*)QString("res").utf16(), (wchar_t*)QString("resources").utf16(), 1) == 0) { + if (!ptrCreateSymbolicLink) { QSKIP("Symbolic links aren't supported by FS", SkipAll); + } else { + // CreateSymbolicLink can return TRUE & still fail to create the link, + // the error code in that case is ERROR_PRIVILEGE_NOT_HELD (1314) + SetLastError(0); + BOOL ret = ptrCreateSymbolicLink((wchar_t*)QString("res").utf16(), (wchar_t*)QString("resources").utf16(), 1); + DWORD dwErr = GetLastError(); + if (!ret) + QSKIP("Symbolic links aren't supported by FS", SkipAll); + QString currentPath = QDir::currentPath(); + bool is_res_Current = QDir::setCurrent("res"); + if (!is_res_Current && dwErr == 1314) + QSKIP("Not enough privilages to create Symbolic links", SkipAll); + QCOMPARE(is_res_Current, true); + + QCOMPARE(QFileInfo("file1").canonicalFilePath(), currentPath + "/resources/file1"); + + QCOMPARE(QDir::setCurrent(currentPath), true); + QDir::current().rmdir("res"); } - - QString currentPath = QDir::currentPath(); - QCOMPARE(QDir::setCurrent("res"), true); - - QCOMPARE(QFileInfo("file1").canonicalFilePath(), currentPath + "/resources/file1"); - - QCOMPARE(QDir::setCurrent(currentPath), true); - QDir::current().rmdir("res"); #endif } -- cgit v0.12 From 37fdb437084a7a4acefefbe1d55adee4e7723b7a Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Mon, 6 Dec 2010 14:46:22 +0100 Subject: Fix tst_QFileInfo owner() & group() failure on Windows. The ownership of newly created files are transferred to the Administrator group only if the application is running with Admin privilages. This will happen only on Windows 7 & Vista, on XP user has the ownership. Reviewed-by: Joao --- tests/auto/qfileinfo/tst_qfileinfo.cpp | 63 +++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 96a0d77..70ed842 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -1648,6 +1648,27 @@ void tst_QFileInfo::detachingOperations() } #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) +BOOL IsUserAdmin() +{ + BOOL b; + SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; + PSID AdministratorsGroup; + b = AllocateAndInitializeSid( + &NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &AdministratorsGroup); + if (b) { + if (!CheckTokenMembership( NULL, AdministratorsGroup, &b)) + b = FALSE; + FreeSid(AdministratorsGroup); + } + + return(b); +} + void tst_QFileInfo::owner() { QString userName; @@ -1661,28 +1682,30 @@ void tst_QFileInfo::owner() wchar_t usernameBuf[1024]; DWORD bufSize = 1024; if (GetUserNameW(usernameBuf, &bufSize)) { - userName = QString::fromWCharArray(usernameBuf, bufSize); - // Special case : If the user is a member of Administrators group, all files - // created by the current user are owned by the Administrators group. - LPLOCALGROUP_USERS_INFO_0 pBuf = NULL; - DWORD dwLevel = 0; - DWORD dwFlags = LG_INCLUDE_INDIRECT ; - DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH; - DWORD dwEntriesRead = 0; - DWORD dwTotalEntries = 0; - NET_API_STATUS nStatus; - nStatus = NetUserGetLocalGroups(0, usernameBuf, dwLevel, dwFlags, (LPBYTE *) &pBuf, - dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries); - // Check if the current user is a member of Administrators group - if (nStatus == NERR_Success && pBuf){ - for (int i = 0; i < dwEntriesRead; i++) { - QString groupName = QString::fromWCharArray(pBuf[i].lgrui0_name); - if (!groupName.compare(QLatin1String("Administrators"))) - userName = groupName; + userName = QString::fromWCharArray(usernameBuf); + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && IsUserAdmin()) { + // Special case : If the user is a member of Administrators group, all files + // created by the current user are owned by the Administrators group. + LPLOCALGROUP_USERS_INFO_0 pBuf = NULL; + DWORD dwLevel = 0; + DWORD dwFlags = LG_INCLUDE_INDIRECT ; + DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH; + DWORD dwEntriesRead = 0; + DWORD dwTotalEntries = 0; + NET_API_STATUS nStatus; + nStatus = NetUserGetLocalGroups(0, usernameBuf, dwLevel, dwFlags, (LPBYTE *) &pBuf, + dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries); + // Check if the current user is a member of Administrators group + if (nStatus == NERR_Success && pBuf){ + for (int i = 0; i < dwEntriesRead; i++) { + QString groupName = QString::fromWCharArray(pBuf[i].lgrui0_name); + if (!groupName.compare(QLatin1String("Administrators"))) + userName = groupName; + } } + if (pBuf != NULL) + NetApiBufferFree(pBuf); } - if (pBuf != NULL) - NetApiBufferFree(pBuf); } extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; qt_ntfs_permission_lookup = 1; -- cgit v0.12 From 6ae84f1183e91c910ca92a55e37f8254ace805c0 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Mon, 6 Dec 2010 13:07:36 +0100 Subject: Fix QTextEdit::selectAll crash from textChanged() Doing selectAll() after the entire block of text has been removed will cause this crash, because we didn't check if the block we found is valid or not. Task-number: QTBUG-15857 Reviewed-by: Eskil --- src/gui/text/qtextcursor.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 769ab2f..f73cc4b 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -363,6 +363,9 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor bool adjustX = true; QTextBlock blockIt = block(); + if (!blockIt.isValid()) + return false; + if (op >= QTextCursor::Left && op <= QTextCursor::WordRight && blockIt.textDirection() == Qt::RightToLeft) { if (op == QTextCursor::Left) -- cgit v0.12 From 9a63863d6f0c614c041c3d4b375bf88d93148ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 6 Dec 2010 14:06:56 +0100 Subject: Make sure to do a deep copy of a QImage when it's being painted on. Not doing so can produce some hard-to-track-down bugs in the app. Task-number: QTBUG-15749 Reviewed-by: Gunnar Sletta --- src/gui/image/qimage.cpp | 25 +++++++++++++++++-------- src/gui/image/qpixmap_raster.cpp | 8 ++++++++ tests/auto/qimage/tst_qimage.cpp | 16 ++++++++++++++++ tests/auto/qpixmap/tst_qpixmap.cpp | 17 +++++++++++++++++ 4 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 1157b93..6ba3858 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -1121,9 +1121,14 @@ QImage::QImage(const char * const xpm[]) QImage::QImage(const QImage &image) : QPaintDevice() { - d = image.d; - if (d) - d->ref.ref(); + if (image.paintingActive()) { + d = 0; + operator=(image.copy()); + } else { + d = image.d; + if (d) + d->ref.ref(); + } } #ifdef QT3_SUPPORT @@ -1320,11 +1325,15 @@ QImage::~QImage() QImage &QImage::operator=(const QImage &image) { - if (image.d) - image.d->ref.ref(); - if (d && !d->ref.deref()) - delete d; - d = image.d; + if (image.paintingActive()) { + operator=(image.copy()); + } else { + if (image.d) + image.d->ref.ref(); + if (d && !d->ref.deref()) + delete d; + d = image.d; + } return *this; } diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index 53f3559..f080687 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -44,6 +44,7 @@ #include "qpixmap_raster_p.h" #include "qnativeimage_p.h" #include "qimage_p.h" +#include "qpaintengine.h" #include "qbitmap.h" #include "qimage.h" @@ -302,6 +303,13 @@ bool QRasterPixmapData::hasAlphaChannel() const QImage QRasterPixmapData::toImage() const { + if (image.paintEngine() + && image.paintEngine()->isActive() + && image.paintEngine()->paintDevice() == &image) + { + return image.copy(); + } + return image; } diff --git a/tests/auto/qimage/tst_qimage.cpp b/tests/auto/qimage/tst_qimage.cpp index b446941..b2c59fc 100644 --- a/tests/auto/qimage/tst_qimage.cpp +++ b/tests/auto/qimage/tst_qimage.cpp @@ -142,6 +142,8 @@ private slots: void rgbSwapped_data(); void rgbSwapped(); + + void deepCopyWhenPaintingActive(); }; tst_QImage::tst_QImage() @@ -1886,5 +1888,19 @@ void tst_QImage::rgbSwapped() QCOMPARE(memcmp(image.constBits(), imageSwappedTwice.constBits(), image.numBytes()), 0); } +void tst_QImage::deepCopyWhenPaintingActive() +{ + QImage image(64, 64, QImage::Format_ARGB32_Premultiplied); + image.fill(0); + + QPainter painter(&image); + QImage copy = image; + + painter.setBrush(Qt::black); + painter.drawEllipse(image.rect()); + + QVERIFY(copy != image); +} + QTEST_MAIN(tst_QImage) #include "tst_qimage.moc" diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 51e6cf5..d5267b5 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -185,6 +185,8 @@ private slots: void preserveDepth(); void splash_crash(); + void toImageDeepCopy(); + void loadAsBitmapOrPixmap(); }; @@ -1751,6 +1753,21 @@ void tst_QPixmap::loadAsBitmapOrPixmap() QVERIFY(bitmap.isQBitmap()); } +void tst_QPixmap::toImageDeepCopy() +{ + QPixmap pixmap(64, 64); + pixmap.fill(Qt::white); + + QPainter painter(&pixmap); + QImage first = pixmap.toImage(); + + painter.setBrush(Qt::black); + painter.drawEllipse(pixmap.rect()); + + QImage second = pixmap.toImage(); + + QVERIFY(first != second); +} QTEST_MAIN(tst_QPixmap) -- cgit v0.12 From fd3fc0b34a891751e6a0849421e8cecd19481324 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Mon, 6 Dec 2010 15:55:22 +0100 Subject: Fix crash in QTextDocument::markContentsDirty 6f6c25b6 introduced this regression because it didn't check d->lout before calling d->lout->documentChange(). Task-number: QTBUG-15777 Reviewed-by: Eskil --- src/gui/text/qtextdocument.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index c35069f..77e6aa1 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -596,8 +596,10 @@ void QTextDocument::markContentsDirty(int from, int length) Q_D(QTextDocument); d->documentChange(from, length); if (!d->inContentsChange) { - d->lout->documentChanged(d->docChangeFrom, d->docChangeOldLength, d->docChangeLength); - d->docChangeFrom = -1; + if (d->lout) { + d->lout->documentChanged(d->docChangeFrom, d->docChangeOldLength, d->docChangeLength); + d->docChangeFrom = -1; + } } } -- cgit v0.12 From c5a9bf1553dc1960ef5d1531a0acf405ace6a05c Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 6 Dec 2010 17:25:40 +0100 Subject: QGtkStyle: Use gtk_progress_configure() instead of adjustment API There is no corresponding getter for gtk_progress_set_adjustment() anyway, so the old code was actually crashing. Reviewed-by: Jens Bache-Wiig --- src/gui/styles/qgtkstyle.cpp | 8 +------- src/gui/styles/qgtkstyle_p.cpp | 6 ++---- src/gui/styles/qgtkstyle_p.h | 6 ++---- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index f3ec746..323639a 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -3017,13 +3017,7 @@ void QGtkStyle::drawControl(ControlElement element, else if (bar->progress > bar->minimum) fakePos = maximum - 1; - GtkAdjustment *adjustment = d->gtk_progress_get_adjustment((GtkProgress*)gtkProgressBar); - if (adjustment) { - d->gtk_adjustment_configure(adjustment, fakePos, 0, maximum, 0, 0, 0); - } else { - adjustment = (GtkAdjustment*)d->gtk_adjustment_new(fakePos, 0, maximum, 0, 0, 0); - d->gtk_progress_set_adjustment((GtkProgress*)(gtkProgressBar), adjustment); - } + d->gtk_progress_configure((GtkProgress*)gtkProgressBar, fakePos, 0, maximum); QRect progressBar; diff --git a/src/gui/styles/qgtkstyle_p.cpp b/src/gui/styles/qgtkstyle_p.cpp index dd20253..aa56baa 100644 --- a/src/gui/styles/qgtkstyle_p.cpp +++ b/src/gui/styles/qgtkstyle_p.cpp @@ -121,8 +121,7 @@ Ptr_gtk_combo_box_entry_new QGtkStylePrivate::gtk_combo_box_entry_new = 0; Ptr_gtk_progress_bar_new QGtkStylePrivate::gtk_progress_bar_new = 0; Ptr_gtk_container_add QGtkStylePrivate::gtk_container_add = 0; Ptr_gtk_menu_shell_append QGtkStylePrivate::gtk_menu_shell_append = 0; -Ptr_gtk_progress_get_adjustment QGtkStylePrivate::gtk_progress_get_adjustment = 0; -Ptr_gtk_progress_set_adjustment QGtkStylePrivate::gtk_progress_set_adjustment = 0; +Ptr_gtk_progress_configure QGtkStylePrivate::gtk_progress_configure = 0; Ptr_gtk_range_get_adjustment QGtkStylePrivate::gtk_range_get_adjustment = 0; Ptr_gtk_range_set_adjustment QGtkStylePrivate::gtk_range_set_adjustment = 0; Ptr_gtk_range_set_inverted QGtkStylePrivate::gtk_range_set_inverted = 0; @@ -379,8 +378,7 @@ void QGtkStylePrivate::resolveGtk() const gtk_entry_new = (Ptr_gtk_entry_new)libgtk.resolve("gtk_entry_new"); gtk_tree_view_new = (Ptr_gtk_tree_view_new)libgtk.resolve("gtk_tree_view_new"); gtk_combo_box_new = (Ptr_gtk_combo_box_new)libgtk.resolve("gtk_combo_box_new"); - gtk_progress_get_adjustment = (Ptr_gtk_progress_get_adjustment)libgtk.resolve("gtk_progress_get_adjustment"); - gtk_progress_set_adjustment = (Ptr_gtk_progress_set_adjustment)libgtk.resolve("gtk_progress_set_adjustment"); + gtk_progress_configure = (Ptr_gtk_progress_configure)libgtk.resolve("gtk_progress_configure"); gtk_range_get_adjustment = (Ptr_gtk_range_get_adjustment)libgtk.resolve("gtk_range_get_adjustment"); gtk_range_set_adjustment = (Ptr_gtk_range_set_adjustment)libgtk.resolve("gtk_range_set_adjustment"); gtk_range_set_inverted = (Ptr_gtk_range_set_inverted)libgtk.resolve("gtk_range_set_inverted"); diff --git a/src/gui/styles/qgtkstyle_p.h b/src/gui/styles/qgtkstyle_p.h index 57fa2fc..16ceb3a 100644 --- a/src/gui/styles/qgtkstyle_p.h +++ b/src/gui/styles/qgtkstyle_p.h @@ -176,8 +176,7 @@ typedef GtkWidget* (*Ptr_gtk_statusbar_new)(void); typedef GtkSettings* (*Ptr_gtk_settings_get_default)(void); typedef GtkAdjustment* (*Ptr_gtk_range_get_adjustment)(GtkRange *); typedef void (*Ptr_gtk_range_set_adjustment)(GtkRange *, GtkAdjustment *); -typedef GtkAdjustment* (*Ptr_gtk_progress_get_adjustment)(GtkProgress *); -typedef void (*Ptr_gtk_progress_set_adjustment)(GtkProgress *, GtkAdjustment *); +typedef void (*Ptr_gtk_progress_configure)(GtkProgress *, double, double, double); typedef void (*Ptr_gtk_range_set_inverted)(GtkRange*, bool); typedef void (*Ptr_gtk_container_add)(GtkContainer *container, GtkWidget *widget); typedef GtkIconSet* (*Ptr_gtk_icon_factory_lookup_default) (const gchar*); @@ -396,8 +395,7 @@ public: static Ptr_gtk_progress_bar_new gtk_progress_bar_new; static Ptr_gtk_container_add gtk_container_add; static Ptr_gtk_menu_shell_append gtk_menu_shell_append; - static Ptr_gtk_progress_get_adjustment gtk_progress_get_adjustment; - static Ptr_gtk_progress_set_adjustment gtk_progress_set_adjustment; + static Ptr_gtk_progress_configure gtk_progress_configure; static Ptr_gtk_range_get_adjustment gtk_range_get_adjustment; static Ptr_gtk_range_set_adjustment gtk_range_set_adjustment; static Ptr_gtk_range_set_inverted gtk_range_set_inverted; -- cgit v0.12 From 16447b1193fedf5fdcf1f3d270fa73c5036a1ba0 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Tue, 7 Dec 2010 10:41:10 +1000 Subject: Fix openDatabaseSync() to not create unused directory Task-number: QTBUG-15909 Reviewed-by: Warwick Allison --- src/declarative/qml/qdeclarativesqldatabase.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativesqldatabase.cpp b/src/declarative/qml/qdeclarativesqldatabase.cpp index 45f277e..3f53111 100644 --- a/src/declarative/qml/qdeclarativesqldatabase.cpp +++ b/src/declarative/qml/qdeclarativesqldatabase.cpp @@ -375,7 +375,6 @@ static QScriptValue qmlsqldatabase_open_sync(QScriptContext *context, QScriptEng } else { created = !QFile::exists(basename+QLatin1String(".sqlite")); database = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), dbid); - QDir().mkpath(basename); if (created) { ini.setValue(QLatin1String("Name"), dbname); if (dbcreationCallback.isFunction()) -- cgit v0.12 From f3a7c4e458edb40957186e52012f15767eb8c1f4 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Tue, 7 Dec 2010 12:49:54 +1000 Subject: Update QtGui def files Task-number: QTBUG-15815 --- src/s60installs/bwins/QtGuiu.def | 1 + src/s60installs/eabi/QtGuiu.def | 1 + 2 files changed, 2 insertions(+) diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 6a33fc3..355b46a 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -12905,4 +12905,5 @@ EXPORTS ?reactivateDeferredActiveObjects@QEventDispatcherS60@@UAEXXZ @ 12904 NONAME ; void QEventDispatcherS60::reactivateDeferredActiveObjects(void) ?userData@QStaticTextItem@@QBEPAVQStaticTextUserData@@XZ @ 12905 NONAME ; class QStaticTextUserData * QStaticTextItem::userData(void) const ?populate@QTextureGlyphCache@@QAE_NPAVQFontEngine@@HPBIPBUQFixedPoint@@@Z @ 12906 NONAME ; bool QTextureGlyphCache::populate(class QFontEngine *, int, unsigned int const *, struct QFixedPoint const *) + ?resetCursorBlinkTimer@QLineControl@@QAEXXZ @ 12907 NONAME ; void QLineControl::resetCursorBlinkTimer(void) diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 54768a1..6b8dd7c 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -12105,4 +12105,5 @@ EXPORTS _ZN15QStaticTextItemD1Ev @ 12104 NONAME _ZN15QStaticTextItemD2Ev @ 12105 NONAME _ZN19QEventDispatcherS6031reactivateDeferredActiveObjectsEv @ 12106 NONAME + _ZN12QLineControl21resetCursorBlinkTimerEv @ 12107 NONAME -- cgit v0.12 From f48a99165e0f3a63b3b144e1a7c7ce586bfc96c4 Mon Sep 17 00:00:00 2001 From: axis Date: Mon, 6 Dec 2010 15:26:08 +0100 Subject: Fixed a BC break between S60 SDK 3.2 and 5.0. Task: QT-4077 RevBy: Shane Kearns --- src/gui/kernel/qeventdispatcher_s60_p.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/kernel/qeventdispatcher_s60_p.h b/src/gui/kernel/qeventdispatcher_s60_p.h index c14fef0..539a21c 100644 --- a/src/gui/kernel/qeventdispatcher_s60_p.h +++ b/src/gui/kernel/qeventdispatcher_s60_p.h @@ -75,6 +75,13 @@ public: void complete(); private: + // Workaround for a BC break from S60 3.2 -> 5.0, where the CEikonEnv override was removed. + // To avoid linking to that when we build against 3.2, define an empty body here. + // Reserved_*() have been verified to be empty in the S60 code. + void Reserved_1() {} + void Reserved_2() {} + +private: int m_lastIterationCount; TInt m_savedStatusCode; bool m_hasAlreadyRun; -- cgit v0.12 From 457d1e176a8f298f8d753d40f177b771113329dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0smail=20D=C3=B6nmez?= Date: Tue, 7 Dec 2010 02:30:24 -0600 Subject: Add library prefixes for Cygwin Merge-request: 2520 Reviewed-by: Marius Storm-Olsen --- mkspecs/cygwin-g++/qmake.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mkspecs/cygwin-g++/qmake.conf b/mkspecs/cygwin-g++/qmake.conf index ddfceb0..c46384f 100644 --- a/mkspecs/cygwin-g++/qmake.conf +++ b/mkspecs/cygwin-g++/qmake.conf @@ -68,6 +68,9 @@ QMAKE_LIBS_X11SM = -lSM -lICE QMAKE_LIBS_OPENGL = -lGL QMAKE_LIBS_OPENGL_QT = -lGL QMAKE_LIBS_THREAD = -lpthread +QMAKE_PREFIX_SHLIB = lib +QMAKE_PREFIX_STATICLIB = lib +QMAKE_EXTENSION_STATICLIB = a QMAKE_MOC = $$[QT_INSTALL_BINS]/moc QMAKE_UIC = $$[QT_INSTALL_BINS]/uic -- cgit v0.12 From 700ce118e1f294148fbbd9b92672f9ff7ec21f8e Mon Sep 17 00:00:00 2001 From: Karim Pinter Date: Tue, 7 Dec 2010 11:46:55 +0200 Subject: Updating merge request 2512 Removing unnecessary comments and changing define to Q_OS_SYMBIAN. Task-number: QTBUG_9505 --- src/gui/widgets/qmenu.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index d9233f5..538df35 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1795,9 +1795,7 @@ QSize QMenu::sizeHint() const void QMenu::popup(const QPoint &p, QAction *atAction) { Q_D(QMenu); -#ifndef Q_WS_S60 - //on S60 opens the menu at the same position it was activated last time - //there is no need to reset the offset fix for QTBUG-9505 +#ifndef Q_OS_SYMBIAN if (d->scroll) { // reset scroll state from last popup d->scroll->scrollOffset = 0; d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone; -- cgit v0.12 From 84fa2a82ea90ad2c554b54bd08db1f41d85484ea Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 7 Dec 2010 11:07:39 +0100 Subject: Fix compile error in tst_qfileinfo on Mac/Linux Reviewed-by: Shane Kearns --- tests/auto/qfileinfo/tst_qfileinfo.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 70ed842..2e1ab39 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -1648,6 +1648,7 @@ void tst_QFileInfo::detachingOperations() } #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) +#if defined (Q_OS_WIN) BOOL IsUserAdmin() { BOOL b; @@ -1668,6 +1669,7 @@ BOOL IsUserAdmin() return(b); } +#endif void tst_QFileInfo::owner() { -- cgit v0.12 From 4103f03579515c1d1993afd6b619315754be330b Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Tue, 7 Dec 2010 12:11:13 +0100 Subject: Revert "Fix qreal vs. double issue and a copy/paste error." This reverts commit 236d4e3c5d58e69a85a362c702d830227309404d. (Some weird autotest regressions have shown up - need to fix those first) --- .../graphicsitems/qdeclarativeflickable.cpp | 27 +++++++++++----------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 3d47a8d..96f54a8 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -600,7 +600,7 @@ void QDeclarativeFlickable::setFlickableDirection(FlickableDirection direction) */ qreal QDeclarativeFlickable::minXExtent() const { - return 0; + return 0.0; } /*! \internal @@ -609,7 +609,7 @@ qreal QDeclarativeFlickable::minXExtent() const */ qreal QDeclarativeFlickable::minYExtent() const { - return 0; + return 0.0; } /*! \internal Returns the maximum horizontal content position. @@ -617,7 +617,7 @@ qreal QDeclarativeFlickable::minYExtent() const qreal QDeclarativeFlickable::maxXExtent() const { Q_D(const QDeclarativeFlickable); - return qMax(qreal(0), d->contentItem->width()); + return qMax(0.0, d->contentItem->width()); } /*! \internal @@ -626,7 +626,7 @@ qreal QDeclarativeFlickable::maxXExtent() const qreal QDeclarativeFlickable::maxYExtent() const { Q_D(const QDeclarativeFlickable); - return qMax(qreal(0), d->contentItem->height()); + return qMax(0.0, d->contentItem->height()); } /*! \internal @@ -673,10 +673,10 @@ void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry, //qDebug() << "xxx geometryChanged: "<state() == QScroller::Inactive) { - scroller->ensureVisible(QRectF(minXExtent(), minYExtent(), - d->contentItem->width(), d->contentItem->height()), 0, 0, 0); - } else + if (scroller->state() == QScroller::Inactive) + scroller->ensureVisible( QRectF(0.0, 0.0, + d->contentItem->width(), d->contentItem->height() ), 0, 0, 0 ); + else d->updateScrollerValues(); d->updateBeginningEnd(); } @@ -840,10 +840,9 @@ void QDeclarativeFlickable::setContentWidth(qreal w) // Make sure that we're entirely in view. QScroller *scroller = QScroller::scroller(this); - if (scroller->state() == QScroller::Inactive) { - scroller->ensureVisible(QRectF(minXExtent(), minYExtent(), - d->contentItem->width(), d->contentItem->height()), 0, 0, 0); - } else + if (scroller->state() == QScroller::Inactive) + scroller->ensureVisible( QRectF(0.0, 0.0, d->contentItem->width(), d->contentItem->height() ), 0, 0, 0 ); + else d->updateScrollerValues(); emit contentWidthChanged(); @@ -870,8 +869,8 @@ void QDeclarativeFlickable::setContentHeight(qreal h) // Make sure that we're entirely in view. QScroller *scroller = QScroller::scroller(this); if (scroller->state() == QScroller::Inactive) { - scroller->ensureVisible(QRectF(minXExtent(), minYExtent(), - d->contentItem->width(), d->contentItem->height()), 0, 0, 0); + scroller->ensureVisible( QRectF(minXExtent(), minYExtent(), + d->contentItem->width(), d->contentItem->height() ), 0, 0, 0 ); } else d->updateScrollerValues(); -- cgit v0.12 From 3dfab643ccbf9fea78b1889418ccb89b25ba986b Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Tue, 7 Dec 2010 12:11:47 +0100 Subject: Revert "Fix code style issues in QScroller based Flickable replacement." This reverts commit 01276467bc7cf9b7cf8f83dc924a47b90e5bf053. (Some weird autotest regressions have shown up - need to fix those first) --- src/declarative/graphicsitems/qdeclarativegridview.cpp | 4 ++-- src/declarative/graphicsitems/qdeclarativelistview.cpp | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 8f6c34f..b6af7dc 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1610,14 +1610,14 @@ bool QDeclarativeGridView::event(QEvent *event) qreal rowPos = d->rowPosAt(d->currentIndex); if (rowPos - d->rowSize() >= 0) snapPoints.append( rowPos - d->rowSize()); - else if (d->header) + else if( d->header ) snapPoints.append(0); // position of the header snapPoints.append(rowPos); if (rowPos + d->rowSize() < d->headerSize() + d->contentSize()) snapPoints.append(rowPos + d->rowSize()); - else if (d->footer) + else if( d->footer ) snapPoints.append(d->headerSize() + d->contentSize() + snapOffset); // position of the footer } diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index d6a75ba..27f7b52 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -309,7 +309,7 @@ public: pos = visibleItems.first()->position(); pos -= visibleIndex * (averageSize + spacing); } - if (header) + if( header ) pos -= header->size(); return pos; } @@ -960,6 +960,7 @@ void QDeclarativeListViewPrivate::recreateHighlight() */ void QDeclarativeListViewPrivate::updateHighlight(bool smooth) { + if ((!currentItem && highlight) || (currentItem && !highlight)) recreateHighlight(); @@ -2355,7 +2356,7 @@ void QDeclarativeListView::viewportAboutToMove(QPointF newPos) // qDebug() << "viewport about to move"; // need to refill before moving - if (d->orient == Horizontal) + if( d->orient == Horizontal ) d->refill(newPos.x(), newPos.x() + width() - 1); else d->refill(newPos.y(), newPos.y() + height() - 1); @@ -2836,6 +2837,7 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) } } + // restore the start position of the visible items if (firstVisible && forceConst(d->visibleItems).first() != firstVisible) forceConst(d->visibleItems).first()->setPosition(forceConst(d->visibleItems).first()->position() + preRemovedSize); -- cgit v0.12 From 38389903bedbb45b640231c8a53e824ff3f99253 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Tue, 7 Dec 2010 12:11:53 +0100 Subject: Revert "QScroller merge, part 2" This reverts commit 53dd7206a7a2ba4393d558bf76fa23f4a4e05183. (Some weird autotest regressions have shown up - need to fix those first) --- .../graphicsitems/qdeclarativeflickable.cpp | 1169 +++++++++++----- .../graphicsitems/qdeclarativeflickable_p.h | 22 +- .../graphicsitems/qdeclarativeflickable_p_p.h | 103 +- .../graphicsitems/qdeclarativegridview.cpp | 1202 +++++++++------- .../graphicsitems/qdeclarativegridview_p.h | 9 +- .../graphicsitems/qdeclarativelistview.cpp | 1428 +++++++++++--------- .../graphicsitems/qdeclarativelistview_p.h | 9 +- .../tst_qdeclarativeflickable.cpp | 4 +- .../tst_qdeclarativegridview.cpp | 2 - .../tst_qdeclarativelistview.cpp | 8 +- 10 files changed, 2426 insertions(+), 1530 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 96f54a8..98c213c 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -44,12 +44,14 @@ #include #include #include +#include -#include -#include +QT_BEGIN_NAMESPACE -QT_BEGIN_NAMESPACE +// FlickThreshold determines how far the "mouse" must have moved +// before we perform a flick. +static const int FlickThreshold = 20; QDeclarativeFlickableVisibleArea::QDeclarativeFlickableVisibleArea(QDeclarativeFlickable *parent) : QObject(parent), flickable(parent), m_xPosition(0.), m_widthRatio(0.) @@ -77,11 +79,6 @@ qreal QDeclarativeFlickableVisibleArea::yPosition() const return m_yPosition; } -/*! \internal - Updates the page position and ratio values and sends out the appropriate position - and ratio changed signals. - Will be called by updateBeginningEnd. -*/ void QDeclarativeFlickableVisibleArea::updateVisible() { QDeclarativeFlickablePrivate *p = static_cast(QGraphicsItemPrivate::get(flickable)); @@ -93,11 +90,9 @@ void QDeclarativeFlickableVisibleArea::updateVisible() // Vertical const qreal viewheight = flickable->height(); - const qreal maxyextent = flickable->maxYExtent(); - qreal pagePos = (p->contentItem->pos().y() + flickable->minYExtent()) / maxyextent; - qreal pageSize = viewheight / maxyextent; - - // qDebug() << "updateVisible" << viewheight << "ext:" << flickable->minYExtent() <<"-"<maxYExtent() << "pagesize:"<maxYExtent() + flickable->minYExtent(); + qreal pagePos = (-p->vData.move.value() + flickable->minYExtent()) / (maxyextent + viewheight); + qreal pageSize = viewheight / (maxyextent + viewheight); if (pageSize != m_heightRatio) { m_heightRatio = pageSize; @@ -110,9 +105,9 @@ void QDeclarativeFlickableVisibleArea::updateVisible() // Horizontal const qreal viewwidth = flickable->width(); - const qreal maxxextent = flickable->maxXExtent(); - pagePos = (p->contentItem->pos().x() + flickable->minXExtent()) / maxxextent; - pageSize = viewwidth / maxxextent; + const qreal maxxextent = -flickable->maxXExtent() + flickable->minXExtent(); + pagePos = (-p->hData.move.value() + flickable->minXExtent()) / (maxxextent + viewwidth); + pageSize = viewwidth / (maxxextent + viewwidth); if (pageSize != m_widthRatio) { m_widthRatio = pageSize; @@ -136,19 +131,15 @@ void QDeclarativeFlickableVisibleArea::updateVisible() QDeclarativeFlickablePrivate::QDeclarativeFlickablePrivate() : contentItem(new QDeclarativeItem) - , updateScrollerValuesRequested(false) - , duringScrollEvent(false) - , isUserGenerated(false) - , isFlicking(false) - , isMoving(false) - , movingHorizontally(false) - , movingVertically(false) - , atBeginningX(true) - , atBeginningY(true) - , atEndX(false) - , atEndY(false) - , interactive(true) - , visibleArea(0) + , hData(this, &QDeclarativeFlickablePrivate::setRoundedViewportX) + , vData(this, &QDeclarativeFlickablePrivate::setRoundedViewportY) + , flickingHorizontally(false), flickingVertically(false) + , hMoved(false), vMoved(false) + , movingHorizontally(false), movingVertically(false) + , stealMouse(false), pressed(false), interactive(true), calcVelocity(false) + , deceleration(500), maxVelocity(2000), reportedVelocitySmoothing(100) + , delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(600) + , vTime(0), visibleArea(0) , flickableDirection(QDeclarativeFlickable::AutoFlickDirection) , boundsBehavior(QDeclarativeFlickable::DragAndOvershootBounds) { @@ -159,39 +150,45 @@ void QDeclarativeFlickablePrivate::init() Q_Q(QDeclarativeFlickable); QDeclarative_setParent_noEvent(contentItem, q); contentItem->setParentItem(q); - + static int timelineUpdatedIdx = -1; + static int timelineCompletedIdx = -1; + static int flickableTickedIdx = -1; + static int flickableMovementEndingIdx = -1; + if (timelineUpdatedIdx == -1) { + timelineUpdatedIdx = QDeclarativeTimeLine::staticMetaObject.indexOfSignal("updated()"); + timelineCompletedIdx = QDeclarativeTimeLine::staticMetaObject.indexOfSignal("completed()"); + flickableTickedIdx = QDeclarativeFlickable::staticMetaObject.indexOfSlot("ticked()"); + flickableMovementEndingIdx = QDeclarativeFlickable::staticMetaObject.indexOfSlot("movementEnding()"); + } + QMetaObject::connect(&timeline, timelineUpdatedIdx, + q, flickableTickedIdx, Qt::DirectConnection); + QMetaObject::connect(&timeline, timelineCompletedIdx, + q, flickableMovementEndingIdx, Qt::DirectConnection); q->setAcceptedMouseButtons(Qt::LeftButton); - q->setAcceptTouchEvents(true); - - QScroller::grabGesture(q, QScroller::LeftMouseButtonGesture); - QScroller *scroller = QScroller::scroller(q); - - QScrollerProperties sp = scroller->scrollerProperties(); - sp.setScrollMetric(QScrollerProperties::MousePressEventDelay, 0); - sp.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 1.0); - sp.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 1.0); - scroller->setScrollerProperties(sp); - - QObject::connect(scroller, SIGNAL(stateChanged(QScroller::State)), q, SLOT(scrollerStateChanged(QScroller::State))); + q->setFiltersChildEvents(true); + QDeclarativeItemPrivate *viewportPrivate = static_cast(QGraphicsItemPrivate::get(contentItem)); + viewportPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); + lastPosTime.invalidate(); } -/*! /internal - Requests a prepare event to be send to the scroller informing it about changed - positions or scroll area bounds. +/* + Returns the amount to overshoot by given a velocity. + Will be roughly in range 0 - size/4 */ -void QDeclarativeFlickablePrivate::updateScrollerValues() +qreal QDeclarativeFlickablePrivate::overShootDistance(qreal velocity, qreal size) { - Q_Q(QDeclarativeFlickable); - //qDebug() << "DeclarativeFlickablePrivate::updateScrollerValues" << duringScrollEvent; - if (!duringScrollEvent) - QScroller::scroller(q)->resendPrepareEvent(); - else - updateScrollerValuesRequested = true; + if (maxVelocity <= 0) + return 0.0; + + velocity = qAbs(velocity); + if (velocity > maxVelocity) + velocity = maxVelocity; + qreal dist = size / 4 * velocity / maxVelocity; + return dist; } void QDeclarativeFlickablePrivate::itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeom, const QRectF &oldGeom) { - // TODO Q_Q(QDeclarativeFlickable); if (item == contentItem) { if (newGeom.x() != oldGeom.x()) @@ -201,41 +198,149 @@ void QDeclarativeFlickablePrivate::itemGeometryChanged(QDeclarativeItem *item, c } } -/*! \internal - Updates the atBeginning and atEnd flags and sends out the changed signals -*/ -void QDeclarativeFlickablePrivate::updateBeginningEnd() +void QDeclarativeFlickablePrivate::flickX(qreal velocity) { Q_Q(QDeclarativeFlickable); + flick(hData, q->minXExtent(), q->maxXExtent(), q->width(), fixupX_callback, velocity); +} - bool boundaryChanged = false; - - bool newAtBeginningX = -contentItem->pos().x() <= q->minXExtent(); - bool newAtEndX = -contentItem->pos().x() >= (q->maxXExtent() - width()); - bool newAtBeginningY = -contentItem->pos().y() <= q->minYExtent(); - bool newAtEndY = -contentItem->pos().y() >= (q->maxYExtent() - height()); +void QDeclarativeFlickablePrivate::flickY(qreal velocity) +{ + Q_Q(QDeclarativeFlickable); + flick(vData, q->minYExtent(), q->maxYExtent(), q->height(), fixupY_callback, velocity); +} - // Horizontal - if (newAtBeginningX != atBeginningX) { - atBeginningX = newAtBeginningX; - boundaryChanged = true; +void QDeclarativeFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, + QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity) +{ + Q_Q(QDeclarativeFlickable); + qreal maxDistance = -1; + bool overShoot = boundsBehavior == QDeclarativeFlickable::DragAndOvershootBounds; + // -ve velocity means list is moving up + if (velocity > 0) { + if (data.move.value() < minExtent) + maxDistance = qAbs(minExtent - data.move.value() + (overShoot?overShootDistance(velocity,vSize):0)); + data.flickTarget = minExtent; + } else { + if (data.move.value() > maxExtent) + maxDistance = qAbs(maxExtent - data.move.value()) + (overShoot?overShootDistance(velocity,vSize):0); + data.flickTarget = maxExtent; + } + if (maxDistance > 0) { + qreal v = velocity; + if (maxVelocity != -1 && maxVelocity < qAbs(v)) { + if (v < 0) + v = -maxVelocity; + else + v = maxVelocity; + } + timeline.reset(data.move); + timeline.accel(data.move, v, deceleration, maxDistance); + timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this)); + if (!flickingHorizontally && q->xflick()) { + flickingHorizontally = true; + emit q->flickingChanged(); + emit q->flickingHorizontallyChanged(); + if (!flickingVertically) + emit q->flickStarted(); + } + if (!flickingVertically && q->yflick()) { + flickingVertically = true; + emit q->flickingChanged(); + emit q->flickingVerticallyChanged(); + if (!flickingHorizontally) + emit q->flickStarted(); + } + } else { + timeline.reset(data.move); + fixup(data, minExtent, maxExtent); } - if (newAtEndX != atEndX) { - atEndX = newAtEndX; - boundaryChanged = true; +} + +void QDeclarativeFlickablePrivate::fixupY_callback(void *data) +{ + ((QDeclarativeFlickablePrivate *)data)->fixupY(); +} + +void QDeclarativeFlickablePrivate::fixupX_callback(void *data) +{ + ((QDeclarativeFlickablePrivate *)data)->fixupX(); +} + +void QDeclarativeFlickablePrivate::fixupX() +{ + Q_Q(QDeclarativeFlickable); + fixup(hData, q->minXExtent(), q->maxXExtent()); +} + +void QDeclarativeFlickablePrivate::fixupY() +{ + Q_Q(QDeclarativeFlickable); + fixup(vData, q->minYExtent(), q->maxYExtent()); +} + +void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent) +{ + if (data.move.value() > minExtent || maxExtent > minExtent) { + timeline.reset(data.move); + if (data.move.value() != minExtent) { + if (fixupDuration) { + qreal dist = minExtent - data.move; + timeline.move(data.move, minExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4); + timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4); + } else { + timeline.set(data.move, minExtent); + } + } + } else if (data.move.value() < maxExtent) { + timeline.reset(data.move); + if (fixupDuration) { + qreal dist = maxExtent - data.move; + timeline.move(data.move, maxExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4); + timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4); + } else { + timeline.set(data.move, minExtent); + } } + vTime = timeline.time(); +} + +void QDeclarativeFlickablePrivate::updateBeginningEnd() +{ + Q_Q(QDeclarativeFlickable); + bool atBoundaryChange = false; // Vertical - if (newAtBeginningY != atBeginningY) { - atBeginningY = newAtBeginningY; - boundaryChanged = true; + const int maxyextent = int(-q->maxYExtent()); + const qreal ypos = -vData.move.value(); + bool atBeginning = (ypos <= -q->minYExtent()); + bool atEnd = (maxyextent <= ypos); + + if (atBeginning != vData.atBeginning) { + vData.atBeginning = atBeginning; + atBoundaryChange = true; + } + if (atEnd != vData.atEnd) { + vData.atEnd = atEnd; + atBoundaryChange = true; + } + + // Horizontal + const int maxxextent = int(-q->maxXExtent()); + const qreal xpos = -hData.move.value(); + atBeginning = (xpos <= -q->minXExtent()); + atEnd = (maxxextent <= xpos); + + if (atBeginning != hData.atBeginning) { + hData.atBeginning = atBeginning; + atBoundaryChange = true; } - if (newAtEndY != atEndY) { - atEndY = newAtEndY; - boundaryChanged = true; + if (atEnd != hData.atEnd) { + hData.atEnd = atEnd; + atBoundaryChange = true; } - if (boundaryChanged) + if (atBoundaryChange) emit q->isAtBoundaryChanged(); if (visibleArea) @@ -379,14 +484,13 @@ qreal QDeclarativeFlickable::contentX() const void QDeclarativeFlickable::setContentX(qreal pos) { Q_D(QDeclarativeFlickable); - QScroller::scroller(this)->stop(); - - if (pos == -d->contentItem->x()) - return; - viewportAboutToMove(QPointF(pos, contentY())); - d->contentItem->setX(-pos); - viewportMoved(); - emit contentXChanged(); + d->timeline.reset(d->hData.move); + d->vTime = d->timeline.time(); + movementXEnding(); + if (-pos != d->hData.move.value()) { + d->hData.move.setValue(-pos); + viewportMoved(); + } } qreal QDeclarativeFlickable::contentY() const @@ -398,14 +502,13 @@ qreal QDeclarativeFlickable::contentY() const void QDeclarativeFlickable::setContentY(qreal pos) { Q_D(QDeclarativeFlickable); - QScroller::scroller(this)->stop(); - - if (pos == -d->contentItem->y()) - return; - viewportAboutToMove(QPointF(contentX(), pos)); - d->contentItem->setY(-pos); - viewportMoved(); - emit contentYChanged(); + d->timeline.reset(d->vData.move); + d->vTime = d->timeline.time(); + movementYEnding(); + if (-pos != d->vData.move.value()) { + d->vData.move.setValue(-pos); + viewportMoved(); + } } /*! @@ -432,7 +535,16 @@ void QDeclarativeFlickable::setInteractive(bool interactive) Q_D(QDeclarativeFlickable); if (interactive != d->interactive) { d->interactive = interactive; - QScroller::scroller(this)->stop(); + if (!interactive && (d->flickingHorizontally || d->flickingVertically)) { + d->timeline.clear(); + d->vTime = d->timeline.time(); + d->flickingHorizontally = false; + d->flickingVertically = false; + emit flickingChanged(); + emit flickingHorizontallyChanged(); + emit flickingVerticallyChanged(); + emit flickEnded(); + } emit interactiveChanged(); } } @@ -442,15 +554,19 @@ void QDeclarativeFlickable::setInteractive(bool interactive) \qmlproperty real Flickable::verticalVelocity The instantaneous velocity of movement along the x and y axes, in pixels/sec. + + The reported velocity is smoothed to avoid erratic output. */ qreal QDeclarativeFlickable::horizontalVelocity() const { - return QScroller::scroller(this)->velocity().x(); + Q_D(const QDeclarativeFlickable); + return d->hData.smoothVelocity.value(); } qreal QDeclarativeFlickable::verticalVelocity() const { - return QScroller::scroller(this)->velocity().y(); + Q_D(const QDeclarativeFlickable); + return d->vData.smoothVelocity.value(); } /*! @@ -465,25 +581,30 @@ qreal QDeclarativeFlickable::verticalVelocity() const bool QDeclarativeFlickable::isAtXEnd() const { Q_D(const QDeclarativeFlickable); - return d->atEndX; + return d->hData.atEnd; } bool QDeclarativeFlickable::isAtXBeginning() const { Q_D(const QDeclarativeFlickable); - return d->atBeginningX; + return d->hData.atBeginning; } bool QDeclarativeFlickable::isAtYEnd() const { Q_D(const QDeclarativeFlickable); - return d->atEndY; + return d->vData.atEnd; } bool QDeclarativeFlickable::isAtYBeginning() const { Q_D(const QDeclarativeFlickable); - return d->atBeginningY; + return d->vData.atBeginning; +} + +void QDeclarativeFlickable::ticked() +{ + viewportMoved(); } /*! @@ -518,52 +639,6 @@ QDeclarativeFlickableVisibleArea *QDeclarativeFlickable::visibleArea() return d->visibleArea; } -void QDeclarativeFlickable::scrollerStateChanged(QScroller::State state) -{ - Q_D(QDeclarativeFlickable); - - //qDebug() << "scrollerStateChanged" << int(state); - - switch (state) { - case QScroller::Inactive: - d->isUserGenerated = false; - // fall through - case QScroller::Pressed: - if (d->isMoving) { - d->isMoving = false; - emit movingChanged(); - emit movementEnded(); - } - if (d->isFlicking) { - d->isFlicking = false; - emit flickingChanged(); - emit flickEnded(); - } - break; - - case QScroller::Dragging: - d->isUserGenerated = true; - if (!d->isMoving) { - d->isMoving = true; - emit movingChanged(); - emit movementStarted(); - } - break; - - case QScroller::Scrolling: - QScroller::scroller(this)->resendPrepareEvent(); // sometimes snappoints depend on the scrolling direction. - if (d->isUserGenerated) { - if (!d->isFlicking) { - emit flickStarted(); - emit flickingChanged(); - } - d->isFlicking = true; - } - break; - } -} - - /*! \qmlproperty enumeration Flickable::flickableDirection @@ -594,92 +669,409 @@ void QDeclarativeFlickable::setFlickableDirection(FlickableDirection direction) } } -/*! \internal - Returns the minimum horizontal content position. - Note: this function will be overloaded. - */ -qreal QDeclarativeFlickable::minXExtent() const +void QDeclarativeFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event) { - return 0.0; + if (interactive && timeline.isActive() && (qAbs(hData.velocity) > 10 || qAbs(vData.velocity) > 10)) + stealMouse = true; // If we've been flicked then steal the click. + else + stealMouse = false; + pressed = true; + timeline.clear(); + hData.velocity = 0; + vData.velocity = 0; + hData.dragStartOffset = 0; + vData.dragStartOffset = 0; + lastPos = QPoint(); + QDeclarativeItemPrivate::start(lastPosTime); + pressPos = event->pos(); + hData.pressPos = hData.move.value(); + vData.pressPos = vData.move.value(); + flickingHorizontally = false; + flickingVertically = false; + QDeclarativeItemPrivate::start(pressTime); + QDeclarativeItemPrivate::start(velocityTime); +} + +void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + Q_Q(QDeclarativeFlickable); + if (!interactive || !lastPosTime.isValid()) + return; + bool rejectY = false; + bool rejectX = false; + + bool stealY = false; + bool stealX = false; + + if (q->yflick()) { + int dy = int(event->pos().y() - pressPos.y()); + if (qAbs(dy) > QApplication::startDragDistance() || QDeclarativeItemPrivate::elapsed(pressTime) > 200) { + if (!vMoved) + vData.dragStartOffset = dy; + qreal newY = dy + vData.pressPos - vData.dragStartOffset; + const qreal minY = q->minYExtent(); + const qreal maxY = q->maxYExtent(); + if (newY > minY) + newY = minY + (newY - minY) / 2; + if (newY < maxY && maxY - minY <= 0) + newY = maxY + (newY - maxY) / 2; + if (boundsBehavior == QDeclarativeFlickable::StopAtBounds && (newY > minY || newY < maxY)) { + rejectY = true; + if (newY < maxY) { + newY = maxY; + rejectY = false; + } + if (newY > minY) { + newY = minY; + rejectY = false; + } + } + if (!rejectY && stealMouse) { + vData.move.setValue(qRound(newY)); + vMoved = true; + } + if (qAbs(dy) > QApplication::startDragDistance()) + stealY = true; + } + } + + if (q->xflick()) { + int dx = int(event->pos().x() - pressPos.x()); + if (qAbs(dx) > QApplication::startDragDistance() || QDeclarativeItemPrivate::elapsed(pressTime) > 200) { + if (!hMoved) + hData.dragStartOffset = dx; + qreal newX = dx + hData.pressPos - hData.dragStartOffset; + const qreal minX = q->minXExtent(); + const qreal maxX = q->maxXExtent(); + if (newX > minX) + newX = minX + (newX - minX) / 2; + if (newX < maxX && maxX - minX <= 0) + newX = maxX + (newX - maxX) / 2; + if (boundsBehavior == QDeclarativeFlickable::StopAtBounds && (newX > minX || newX < maxX)) { + rejectX = true; + if (newX < maxX) { + newX = maxX; + rejectX = false; + } + if (newX > minX) { + newX = minX; + rejectX = false; + } + } + if (!rejectX && stealMouse) { + hData.move.setValue(qRound(newX)); + hMoved = true; + } + + if (qAbs(dx) > QApplication::startDragDistance()) + stealX = true; + } + } + + stealMouse = stealX || stealY; + + if (!lastPos.isNull()) { + qreal elapsed = qreal(QDeclarativeItemPrivate::restart(lastPosTime)) / 1000.; + if (elapsed <= 0) + elapsed = 1; + if (q->yflick()) { + qreal diff = event->pos().y() - lastPos.y(); + // average to reduce the effect of spurious moves + vData.velocity += diff / elapsed; + vData.velocity /= 2; + } + + if (q->xflick()) { + qreal diff = event->pos().x() - lastPos.x(); + // average to reduce the effect of spurious moves + hData.velocity += diff / elapsed; + hData.velocity /= 2; + } + } + + if (rejectY) vData.velocity = 0; + if (rejectX) hData.velocity = 0; + + if (hMoved || vMoved) { + q->movementStarting(); + q->viewportMoved(); + } + + lastPos = event->pos(); +} + +void QDeclarativeFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_Q(QDeclarativeFlickable); + stealMouse = false; + q->setKeepMouseGrab(false); + pressed = false; + if (!lastPosTime.isValid()) + return; + + if (QDeclarativeItemPrivate::elapsed(lastPosTime) > 100) { + // if we drag then pause before release we should not cause a flick. + hData.velocity = 0.0; + vData.velocity = 0.0; + } + + vTime = timeline.time(); + if (qAbs(vData.velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) + flickY(vData.velocity); + else + fixupY(); + + if (qAbs(hData.velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) + flickX(hData.velocity); + else + fixupX(); + + lastPosTime.invalidate(); + + if (!timeline.isActive()) + q->movementEnding(); +} + +void QDeclarativeFlickable::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(QDeclarativeFlickable); + if (d->interactive) { + d->handleMousePressEvent(event); + event->accept(); + } else { + QDeclarativeItem::mousePressEvent(event); + } +} + +void QDeclarativeFlickable::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(QDeclarativeFlickable); + if (d->interactive) { + d->handleMouseMoveEvent(event); + if (d->stealMouse) + setKeepMouseGrab(true); + event->accept(); + } else { + QDeclarativeItem::mouseMoveEvent(event); + } +} + +void QDeclarativeFlickable::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(QDeclarativeFlickable); + if (d->interactive) { + d->clearDelayedPress(); + d->handleMouseReleaseEvent(event); + event->accept(); + ungrabMouse(); + } else { + QDeclarativeItem::mouseReleaseEvent(event); + } +} + +void QDeclarativeFlickable::wheelEvent(QGraphicsSceneWheelEvent *event) +{ + Q_D(QDeclarativeFlickable); + if (!d->interactive) { + QDeclarativeItem::wheelEvent(event); + } else if (yflick()) { + if (event->delta() > 0) + d->vData.velocity = qMax(event->delta() - d->vData.smoothVelocity.value(), qreal(250.0)); + else + d->vData.velocity = qMin(event->delta() - d->vData.smoothVelocity.value(), qreal(-250.0)); + d->flickingVertically = false; + d->flickY(d->vData.velocity); + if (d->flickingVertically) { + d->vMoved = true; + movementStarting(); + } + event->accept(); + } else if (xflick()) { + if (event->delta() > 0) + d->hData.velocity = qMax(event->delta() - d->hData.smoothVelocity.value(), qreal(250.0)); + else + d->hData.velocity = qMin(event->delta() - d->hData.smoothVelocity.value(), qreal(-250.0)); + d->flickingHorizontally = false; + d->flickX(d->hData.velocity); + if (d->flickingHorizontally) { + d->hMoved = true; + movementStarting(); + } + event->accept(); + } else { + QDeclarativeItem::wheelEvent(event); + } +} + +void QDeclarativeFlickablePrivate::captureDelayedPress(QGraphicsSceneMouseEvent *event) +{ + Q_Q(QDeclarativeFlickable); + if (!q->scene() || pressDelay <= 0) + return; + delayedPressTarget = q->scene()->mouseGrabberItem(); + delayedPressEvent = new QGraphicsSceneMouseEvent(event->type()); + delayedPressEvent->setAccepted(false); + for (int i = 0x1; i <= 0x10; i <<= 1) { + if (event->buttons() & i) { + Qt::MouseButton button = Qt::MouseButton(i); + delayedPressEvent->setButtonDownPos(button, event->buttonDownPos(button)); + delayedPressEvent->setButtonDownScenePos(button, event->buttonDownScenePos(button)); + delayedPressEvent->setButtonDownScreenPos(button, event->buttonDownScreenPos(button)); + } + } + delayedPressEvent->setButtons(event->buttons()); + delayedPressEvent->setButton(event->button()); + delayedPressEvent->setPos(event->pos()); + delayedPressEvent->setScenePos(event->scenePos()); + delayedPressEvent->setScreenPos(event->screenPos()); + delayedPressEvent->setLastPos(event->lastPos()); + delayedPressEvent->setLastScenePos(event->lastScenePos()); + delayedPressEvent->setLastScreenPos(event->lastScreenPos()); + delayedPressEvent->setModifiers(event->modifiers()); + delayedPressTimer.start(pressDelay, q); +} + +void QDeclarativeFlickablePrivate::clearDelayedPress() +{ + if (delayedPressEvent) { + delayedPressTimer.stop(); + delete delayedPressEvent; + delayedPressEvent = 0; + } +} + +void QDeclarativeFlickablePrivate::setRoundedViewportX(qreal x) +{ + contentItem->setX(qRound(x)); +} + +void QDeclarativeFlickablePrivate::setRoundedViewportY(qreal y) +{ + contentItem->setY(qRound(y)); +} + +void QDeclarativeFlickable::timerEvent(QTimerEvent *event) +{ + Q_D(QDeclarativeFlickable); + if (event->timerId() == d->delayedPressTimer.timerId()) { + d->delayedPressTimer.stop(); + if (d->delayedPressEvent) { + QDeclarativeItem *grabber = scene() ? qobject_cast(scene()->mouseGrabberItem()) : 0; + if (!grabber || grabber != this) { + // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay) + // so we reset the grabber + if (scene()->mouseGrabberItem() == d->delayedPressTarget) + d->delayedPressTarget->ungrabMouse(); + //Use the event handler that will take care of finding the proper item to propagate the event + QApplication::sendEvent(scene(), d->delayedPressEvent); + } + delete d->delayedPressEvent; + d->delayedPressEvent = 0; + } + } } -/*! \internal - Returns the minimum vertical content position. - Note: this function will be overloaded. - */ qreal QDeclarativeFlickable::minYExtent() const { return 0.0; } -/*! \internal - Returns the maximum horizontal content position. - */ -qreal QDeclarativeFlickable::maxXExtent() const + +qreal QDeclarativeFlickable::minXExtent() const { - Q_D(const QDeclarativeFlickable); - return qMax(0.0, d->contentItem->width()); + return 0.0; } -/*! \internal - Returns the maximum vertical content position. - */ -qreal QDeclarativeFlickable::maxYExtent() const +/* returns -ve */ +qreal QDeclarativeFlickable::maxXExtent() const { - Q_D(const QDeclarativeFlickable); - return qMax(0.0, d->contentItem->height()); + return width() - vWidth(); } - -/*! \internal - This function is called before the viewport starts to move. - This is a good chance to fill up some buffers. - */ -void QDeclarativeFlickable::viewportAboutToMove(QPointF newPos) +/* returns -ve */ +qreal QDeclarativeFlickable::maxYExtent() const { - Q_UNUSED(newPos); + return height() - vHeight(); } -/*! \internal - This function is called after the viewport was moved (and the - move finished) - */ void QDeclarativeFlickable::viewportMoved() { Q_D(QDeclarativeFlickable); + + qreal prevX = d->lastFlickablePosition.x(); + qreal prevY = d->lastFlickablePosition.y(); + d->velocityTimeline.clear(); + if (d->pressed || d->calcVelocity) { + int elapsed = QDeclarativeItemPrivate::restart(d->velocityTime); + if (elapsed > 0) { + qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / elapsed; + qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / elapsed; + d->velocityTimeline.move(d->hData.smoothVelocity, horizontalVelocity, d->reportedVelocitySmoothing); + d->velocityTimeline.move(d->hData.smoothVelocity, 0, d->reportedVelocitySmoothing); + d->velocityTimeline.move(d->vData.smoothVelocity, verticalVelocity, d->reportedVelocitySmoothing); + d->velocityTimeline.move(d->vData.smoothVelocity, 0, d->reportedVelocitySmoothing); + } + } else { + if (d->timeline.time() > d->vTime) { + qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / (d->timeline.time() - d->vTime); + qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / (d->timeline.time() - d->vTime); + d->hData.smoothVelocity.setValue(horizontalVelocity); + d->vData.smoothVelocity.setValue(verticalVelocity); + } + } + + d->lastFlickablePosition = QPointF(d->hData.move.value(), d->vData.move.value()); + + d->vTime = d->timeline.time(); d->updateBeginningEnd(); } void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry, - const QRectF &oldGeometry) + const QRectF &oldGeometry) { Q_D(QDeclarativeFlickable); QDeclarativeItem::geometryChanged(newGeometry, oldGeometry); bool changed = false; if (newGeometry.width() != oldGeometry.width()) { - changed = true; - // strangely this causes problems - // d->contentItem->setWidth(newGeometry.width()); - emit contentWidthChanged(); + if (xflick()) + changed = true; + if (d->hData.viewSize < 0) { + d->contentItem->setWidth(width()); + emit contentWidthChanged(); + } + // Make sure that we're entirely in view. + if (!d->pressed && !d->movingHorizontally && !d->movingVertically) { + int oldDuration = d->fixupDuration; + d->fixupDuration = 0; + d->fixupX(); + d->fixupDuration = oldDuration; + } } if (newGeometry.height() != oldGeometry.height()) { - changed = true; - // strangely this causes problems - // d->contentItem->setHeight(newGeometry.height()); - emit contentHeightChanged(); + if (yflick()) + changed = true; + if (d->vData.viewSize < 0) { + d->contentItem->setHeight(height()); + emit contentHeightChanged(); + } + // Make sure that we're entirely in view. + if (!d->pressed && !d->movingHorizontally && !d->movingVertically) { + int oldDuration = d->fixupDuration; + d->fixupDuration = 0; + d->fixupY(); + d->fixupDuration = oldDuration; + } } - if (changed) { - QScroller *scroller = QScroller::scroller(this); - - //qDebug() << "xxx geometryChanged: "<state() == QScroller::Inactive) - scroller->ensureVisible( QRectF(0.0, 0.0, - d->contentItem->width(), d->contentItem->height() ), 0, 0, 0 ); - else - d->updateScrollerValues(); + if (changed) d->updateBeginningEnd(); - } +} + +void QDeclarativeFlickable::cancelFlick() +{ + Q_D(QDeclarativeFlickable); + d->timeline.reset(d->hData.move); + d->timeline.reset(d->vData.move); + movementEnding(); } void QDeclarativeFlickablePrivate::data_append(QDeclarativeListProperty *prop, QObject *o) @@ -765,12 +1157,10 @@ QDeclarativeListProperty QDeclarativeFlickable::flickableChildr of the flickable, and flicks will not overshoot. \o Flickable.DragOverBounds - the contents can be dragged beyond the boundary of the Flickable, but flicks will not overshoot. - \o Flickable.DragAndOvershootBounds - the contents can be dragged + \o Flickable.DragAndOvershootBounds (default) - the contents can be dragged beyond the boundary of the Flickable, and can overshoot the boundary when flicked. \endlist - - The default is platform dependant. */ QDeclarativeFlickable::BoundsBehavior QDeclarativeFlickable::boundsBehavior() const { @@ -784,23 +1174,6 @@ void QDeclarativeFlickable::setBoundsBehavior(BoundsBehavior b) if (b == d->boundsBehavior) return; d->boundsBehavior = b; - - QScroller *scroller = QScroller::scroller(this); - QScrollerProperties props = scroller->scrollerProperties(); - if (b == StopAtBounds) { - props.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.0); - props.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.0); - - } else if (b == DragOverBounds) { - props.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 1.0); - props.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.0); - - } else { - props.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 1.0); - props.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 1.0); - } - scroller->setScrollerProperties(props); - emit boundsBehaviorChanged(); } @@ -824,27 +1197,26 @@ void QDeclarativeFlickable::setBoundsBehavior(BoundsBehavior b) qreal QDeclarativeFlickable::contentWidth() const { Q_D(const QDeclarativeFlickable); - return d->contentItem->width(); + return d->hData.viewSize; } void QDeclarativeFlickable::setContentWidth(qreal w) { Q_D(QDeclarativeFlickable); - if (d->contentItem->width() == w) + if (d->hData.viewSize == w) return; - + d->hData.viewSize = w; if (w < 0) d->contentItem->setWidth(width()); else d->contentItem->setWidth(w); - // Make sure that we're entirely in view. - QScroller *scroller = QScroller::scroller(this); - if (scroller->state() == QScroller::Inactive) - scroller->ensureVisible( QRectF(0.0, 0.0, d->contentItem->width(), d->contentItem->height() ), 0, 0, 0 ); - else - d->updateScrollerValues(); - + if (!d->pressed && !d->movingHorizontally && !d->movingVertically) { + int oldDuration = d->fixupDuration; + d->fixupDuration = 0; + d->fixupX(); + d->fixupDuration = oldDuration; + } emit contentWidthChanged(); d->updateBeginningEnd(); } @@ -852,142 +1224,170 @@ void QDeclarativeFlickable::setContentWidth(qreal w) qreal QDeclarativeFlickable::contentHeight() const { Q_D(const QDeclarativeFlickable); - return d->contentItem->height(); + return d->vData.viewSize; } void QDeclarativeFlickable::setContentHeight(qreal h) { Q_D(QDeclarativeFlickable); - if (d->contentItem->height() == h) + if (d->vData.viewSize == h) return; - + d->vData.viewSize = h; if (h < 0) d->contentItem->setHeight(height()); else d->contentItem->setHeight(h); - // Make sure that we're entirely in view. - QScroller *scroller = QScroller::scroller(this); - if (scroller->state() == QScroller::Inactive) { - scroller->ensureVisible( QRectF(minXExtent(), minYExtent(), - d->contentItem->width(), d->contentItem->height() ), 0, 0, 0 ); - } else - d->updateScrollerValues(); - + if (!d->pressed && !d->movingHorizontally && !d->movingVertically) { + int oldDuration = d->fixupDuration; + d->fixupDuration = 0; + d->fixupY(); + d->fixupDuration = oldDuration; + } emit contentHeightChanged(); d->updateBeginningEnd(); } -bool QDeclarativeFlickable::event(QEvent *event) +qreal QDeclarativeFlickable::vWidth() const { - Q_D(QDeclarativeFlickable); + Q_D(const QDeclarativeFlickable); + if (d->hData.viewSize < 0) + return width(); + else + return d->hData.viewSize; +} - switch (event->type()) { - case QEvent::ScrollPrepare: { - if (!d->interactive) - return false; - - QScrollPrepareEvent *se = static_cast(event); - se->setViewportSize(QSizeF(d->width(), d->height())); - - QRectF contentPosRange(QPointF(minXExtent(), minYExtent()), - QPointF(maxXExtent() - d->width(), maxYExtent() - d->height())); - if (d->flickableDirection == HorizontalFlick) - contentPosRange.setHeight(0); - if (d->flickableDirection == VerticalFlick) - contentPosRange.setWidth(0); - se->setContentPosRange(contentPosRange); - se->setContentPos(-d->contentItem->pos()); - - //qDebug() << "QDeclarativeFlickable::event: ScPrEv " << this - // << " pos:" << se->contentPos() - // << " range:" << se->contentPosRange(); - - se->accept(); - d->updateScrollerValuesRequested = false; - return true; - } - case QEvent::Scroll: { - d->duringScrollEvent = true; +qreal QDeclarativeFlickable::vHeight() const +{ + Q_D(const QDeclarativeFlickable); + if (d->vData.viewSize < 0) + return height(); + else + return d->vData.viewSize; +} - QScrollEvent *se = static_cast(event); +bool QDeclarativeFlickable::xflick() const +{ + Q_D(const QDeclarativeFlickable); + if (d->flickableDirection == QDeclarativeFlickable::AutoFlickDirection) + return vWidth() != width(); + return d->flickableDirection & QDeclarativeFlickable::HorizontalFlick; +} - /* - qDebug() << "QDeclarativeFlickable::event: Scroll " - << " scrollerPos:" << se->contentPos() - << " pos:" << -d->contentItem->pos() - << " overshoot:" << se->overshootDistance() - << " newPos: " << (se->contentPos() + se->overshootDistance()); - */ +bool QDeclarativeFlickable::yflick() const +{ + Q_D(const QDeclarativeFlickable); + if (d->flickableDirection == QDeclarativeFlickable::AutoFlickDirection) + return vHeight() != height(); + return d->flickableDirection & QDeclarativeFlickable::VerticalFlick; +} - QPointF oldPos = -d->contentItem->pos(); - QPointF newPos = se->contentPos() + se->overshootDistance(); - QPointF delta = newPos - oldPos; +bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(QDeclarativeFlickable); + QGraphicsSceneMouseEvent mouseEvent(event->type()); + QRectF myRect = mapToScene(QRectF(0, 0, width(), height())).boundingRect(); + + QGraphicsScene *s = scene(); + QDeclarativeItem *grabber = s ? qobject_cast(s->mouseGrabberItem()) : 0; + bool stealThisEvent = d->stealMouse; + if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) { + mouseEvent.setAccepted(false); + for (int i = 0x1; i <= 0x10; i <<= 1) { + if (event->buttons() & i) { + Qt::MouseButton button = Qt::MouseButton(i); + mouseEvent.setButtonDownPos(button, mapFromScene(event->buttonDownPos(button))); + } + } + mouseEvent.setScenePos(event->scenePos()); + mouseEvent.setLastScenePos(event->lastScenePos()); + mouseEvent.setPos(mapFromScene(event->scenePos())); + mouseEvent.setLastPos(mapFromScene(event->lastScenePos())); + + switch(mouseEvent.type()) { + case QEvent::GraphicsSceneMouseMove: + d->handleMouseMoveEvent(&mouseEvent); + break; + case QEvent::GraphicsSceneMousePress: + if (d->delayedPressEvent) + return false; + + d->handleMousePressEvent(&mouseEvent); + d->captureDelayedPress(event); + stealThisEvent = d->stealMouse; // Update stealThisEvent in case changed by function call above + break; + case QEvent::GraphicsSceneMouseRelease: + if (d->delayedPressEvent) { + // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay) + // so we reset the grabber + if (s->mouseGrabberItem() == d->delayedPressTarget) + d->delayedPressTarget->ungrabMouse(); + //Use the event handler that will take care of finding the proper item to propagate the event + QApplication::sendEvent(scene(), d->delayedPressEvent); + d->clearDelayedPress(); + // We send the release + scene()->sendEvent(s->mouseGrabberItem(), event); + // And the event has been consumed + return true; + } + d->handleMouseReleaseEvent(&mouseEvent); + break; + default: + break; + } + grabber = qobject_cast(s->mouseGrabberItem()); + if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) { + d->clearDelayedPress(); + grabMouse(); + } - viewportAboutToMove(newPos); - d->contentItem->setPos(-newPos); - viewportMoved(); - if (delta.x()) - emit contentXChanged(); - if (delta.y()) - emit contentYChanged(); - - d->duringScrollEvent = false; - if (d->updateScrollerValuesRequested) - QScroller::scroller(this)->resendPrepareEvent(); - - bool newMovingHorizontally = delta.x() != 0; - bool newMovingVertically = delta.y() != 0; - if (se->scrollState() == QScrollEvent::ScrollFinished) { - newMovingHorizontally = false; - newMovingVertically = false; - } - - if (newMovingHorizontally != d->movingHorizontally) { - d->movingHorizontally = newMovingHorizontally; - emit movingHorizontallyChanged(); - } - if (newMovingVertically != d->movingVertically) { - d->movingVertically = newMovingVertically; - emit movingVerticallyChanged(); - } - - if (newMovingHorizontally) - emit horizontalVelocityChanged(); - if (newMovingVertically) - emit verticalVelocityChanged(); - - se->accept(); - return true; + return stealThisEvent || d->delayedPressEvent; + } else if (d->lastPosTime.isValid()) { + d->lastPosTime.invalidate(); } + if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) { + d->clearDelayedPress(); + d->stealMouse = false; + d->pressed = false; + } + return false; +} + +bool QDeclarativeFlickable::sceneEventFilter(QGraphicsItem *i, QEvent *e) +{ + Q_D(QDeclarativeFlickable); + if (!isVisible() || !d->interactive) + return QDeclarativeItem::sceneEventFilter(i, e); + switch (e->type()) { + case QEvent::GraphicsSceneMousePress: + case QEvent::GraphicsSceneMouseMove: + case QEvent::GraphicsSceneMouseRelease: + return sendMouseEvent(static_cast(e)); default: break; } - return QDeclarativeItem::event(event); + + return QDeclarativeItem::sceneEventFilter(i, e); } /*! \qmlproperty real Flickable::maximumFlickVelocity - This property holds the maximum velocity that the user can flick the view in pixel per second + This property holds the maximum velocity that the user can flick the view in pixels/second. - The default is platform dependant. + The default is 2000 pixels/s */ qreal QDeclarativeFlickable::maximumFlickVelocity() const { - // 4000 ~ the conversion factor from [m/s] to [pix/s] on a 100dpi screen - return 4000 * QScroller::scroller(const_cast(this))->scrollerProperties().scrollMetric(QScrollerProperties::MaximumVelocity).toDouble(); + Q_D(const QDeclarativeFlickable); + return d->maxVelocity; } void QDeclarativeFlickable::setMaximumFlickVelocity(qreal v) { - // 4000 ~ the conversion factor from [m/s] to [pix/s] on a 100dpi screen - v /= qreal(4000); - QScrollerProperties props = QScroller::scroller(this)->scrollerProperties(); - qreal oldV = props.scrollMetric(QScrollerProperties::MaximumVelocity).toReal(); - if (v == oldV) + Q_D(QDeclarativeFlickable); + if (v == d->maxVelocity) return; - props.setScrollMetric(QScrollerProperties::MaximumVelocity, v); - QScroller::scroller(this)->setScrollerProperties(props); + d->maxVelocity = v; emit maximumFlickVelocityChanged(); } @@ -995,31 +1395,27 @@ void QDeclarativeFlickable::setMaximumFlickVelocity(qreal v) \qmlproperty real Flickable::flickDeceleration This property holds the rate at which a flick will decelerate. - The default is platform dependant. + The default is 500. */ qreal QDeclarativeFlickable::flickDeceleration() const { - // 4000 ~ the conversion factor from [m/s] to [pix/s] on a 100dpi screen - return qreal(4000) * QScroller::scroller(const_cast(this))->scrollerProperties().scrollMetric(QScrollerProperties::DecelerationFactor).toDouble(); + Q_D(const QDeclarativeFlickable); + return d->deceleration; } void QDeclarativeFlickable::setFlickDeceleration(qreal deceleration) { - // 4000 ~ the conversion factor from [m/s] to [pix/s] on a 100dpi screen - deceleration /= qreal(4000); - QScrollerProperties props = QScroller::scroller(this)->scrollerProperties(); - qreal oldDeceleration = props.scrollMetric(QScrollerProperties::DecelerationFactor).toReal(); - if (deceleration == oldDeceleration) + Q_D(QDeclarativeFlickable); + if (deceleration == d->deceleration) return; - props.setScrollMetric(QScrollerProperties::DecelerationFactor, deceleration); - QScroller::scroller(this)->setScrollerProperties(props); + d->deceleration = deceleration; emit flickDecelerationChanged(); } bool QDeclarativeFlickable::isFlicking() const { Q_D(const QDeclarativeFlickable); - return d->isFlicking; + return d->flickingHorizontally || d->flickingVertically; } /*! @@ -1033,13 +1429,13 @@ bool QDeclarativeFlickable::isFlicking() const bool QDeclarativeFlickable::isFlickingHorizontally() const { Q_D(const QDeclarativeFlickable); - return d->movingHorizontally && d->isFlicking; + return d->flickingHorizontally; } bool QDeclarativeFlickable::isFlickingVertically() const { Q_D(const QDeclarativeFlickable); - return d->movingVertically && d->isFlicking; + return d->flickingVertically; } /*! @@ -1055,18 +1451,16 @@ bool QDeclarativeFlickable::isFlickingVertically() const */ int QDeclarativeFlickable::pressDelay() const { - return int(qreal(1000) * QScroller::scroller(const_cast(this))->scrollerProperties().scrollMetric(QScrollerProperties::MousePressEventDelay).toReal()); + Q_D(const QDeclarativeFlickable); + return d->pressDelay; } void QDeclarativeFlickable::setPressDelay(int delay) { - qreal pressDelay = qreal(delay) / qreal(1000); // [ms] -> [s] - QScrollerProperties props = QScroller::scroller(this)->scrollerProperties(); - qreal oldPressDelay = props.scrollMetric(QScrollerProperties::MousePressEventDelay).toReal(); - if (pressDelay == oldPressDelay) + Q_D(QDeclarativeFlickable); + if (d->pressDelay == delay) return; - props.setScrollMetric(QScrollerProperties::MousePressEventDelay, pressDelay); - QScroller::scroller(this)->setScrollerProperties(props); + d->pressDelay = delay; emit pressDelayChanged(); } @@ -1074,7 +1468,7 @@ void QDeclarativeFlickable::setPressDelay(int delay) bool QDeclarativeFlickable::isMoving() const { Q_D(const QDeclarativeFlickable); - return d->isMoving; + return d->movingHorizontally || d->movingVertically; } /*! @@ -1098,4 +1492,83 @@ bool QDeclarativeFlickable::isMovingVertically() const return d->movingVertically; } +void QDeclarativeFlickable::movementStarting() +{ + Q_D(QDeclarativeFlickable); + if (d->hMoved && !d->movingHorizontally) { + d->movingHorizontally = true; + emit movingChanged(); + emit movingHorizontallyChanged(); + if (!d->movingVertically) + emit movementStarted(); + } + else if (d->vMoved && !d->movingVertically) { + d->movingVertically = true; + emit movingChanged(); + emit movingVerticallyChanged(); + if (!d->movingHorizontally) + emit movementStarted(); + } +} + +void QDeclarativeFlickable::movementEnding() +{ + Q_D(QDeclarativeFlickable); + movementXEnding(); + movementYEnding(); + d->hData.smoothVelocity.setValue(0); + d->vData.smoothVelocity.setValue(0); +} + +void QDeclarativeFlickable::movementXEnding() +{ + Q_D(QDeclarativeFlickable); + if (d->flickingHorizontally) { + d->flickingHorizontally = false; + emit flickingChanged(); + emit flickingHorizontallyChanged(); + if (!d->flickingVertically) + emit flickEnded(); + } + if (!d->pressed && !d->stealMouse) { + if (d->movingHorizontally) { + d->movingHorizontally = false; + d->hMoved = false; + emit movingChanged(); + emit movingHorizontallyChanged(); + if (!d->movingVertically) + emit movementEnded(); + } + } +} + +void QDeclarativeFlickable::movementYEnding() +{ + Q_D(QDeclarativeFlickable); + if (d->flickingVertically) { + d->flickingVertically = false; + emit flickingChanged(); + emit flickingVerticallyChanged(); + if (!d->flickingHorizontally) + emit flickEnded(); + } + if (!d->pressed && !d->stealMouse) { + if (d->movingVertically) { + d->movingVertically = false; + d->vMoved = false; + emit movingChanged(); + emit movingVerticallyChanged(); + if (!d->movingHorizontally) + emit movementEnded(); + } + } +} + +void QDeclarativeFlickablePrivate::updateVelocity() +{ + Q_Q(QDeclarativeFlickable); + emit q->horizontalVelocityChanged(); + emit q->verticalVelocityChanged(); +} + QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p.h index b79b08c..6e4d8ed 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable_p.h +++ b/src/declarative/graphicsitems/qdeclarativeflickable_p.h @@ -43,7 +43,6 @@ #define QDECLARATIVEFLICKABLE_H #include "qdeclarativeitem.h" -#include QT_BEGIN_HEADER @@ -176,12 +175,19 @@ Q_SIGNALS: void flickEnded(); protected: - virtual bool event(QEvent *e); + virtual bool sceneEventFilter(QGraphicsItem *, QEvent *); + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + void wheelEvent(QGraphicsSceneWheelEvent *event); + void timerEvent(QTimerEvent *event); QDeclarativeFlickableVisibleArea *visibleArea(); protected Q_SLOTS: - virtual void scrollerStateChanged(QScroller::State); + virtual void ticked(); + void movementStarting(); + void movementEnding(); protected: void movementXEnding(); @@ -190,10 +196,16 @@ protected: virtual qreal minYExtent() const; virtual qreal maxXExtent() const; virtual qreal maxYExtent() const; - virtual void viewportAboutToMove(QPointF newPos); + qreal vWidth() const; + qreal vHeight() const; virtual void viewportMoved(); virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); + bool sendMouseEvent(QGraphicsSceneMouseEvent *event); + + bool xflick() const; + bool yflick() const; + void cancelFlick(); protected: QDeclarativeFlickable(QDeclarativeFlickablePrivate &dd, QDeclarativeItem *parent); @@ -201,8 +213,6 @@ protected: private: Q_DISABLE_COPY(QDeclarativeFlickable) Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeFlickable) - - friend class QDeclarativeFlickableVisibleArea; }; diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h index 1f348ab..92cf748 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h @@ -78,35 +78,94 @@ public: QDeclarativeFlickablePrivate(); void init(); - void updateBeginningEnd(); - - void updateScrollerValues(); - void updateOvershootPolicy(); - void itemGeometryChanged(QDeclarativeItem *, const QRectF &, const QRectF &); - - // private slot - void _q_scrollerStateChanged(QScroller::State state); + struct Velocity : public QDeclarativeTimeLineValue + { + Velocity(QDeclarativeFlickablePrivate *p) + : parent(p) {} + virtual void setValue(qreal v) { + if (v != value()) { + QDeclarativeTimeLineValue::setValue(v); + parent->updateVelocity(); + } + } + QDeclarativeFlickablePrivate *parent; + }; + + struct AxisData { + AxisData(QDeclarativeFlickablePrivate *fp, void (QDeclarativeFlickablePrivate::*func)(qreal)) + : move(fp, func), viewSize(-1), smoothVelocity(fp), atEnd(false), atBeginning(true) + {} + + QDeclarativeTimeLineValueProxy move; + qreal viewSize; + qreal pressPos; qreal dragStartOffset; + qreal velocity; + qreal flickTarget; + QDeclarativeFlickablePrivate::Velocity smoothVelocity; + bool atEnd : 1; + bool atBeginning : 1; + }; + + void flickX(qreal velocity); + void flickY(qreal velocity); + virtual void flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, + QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity); + + void fixupX(); + void fixupY(); + virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent); -public: - QDeclarativeItem *contentItem; + void updateBeginningEnd(); + + void captureDelayedPress(QGraphicsSceneMouseEvent *event); + void clearDelayedPress(); - bool updateScrollerValuesRequested; - bool duringScrollEvent; + void setRoundedViewportX(qreal x); + void setRoundedViewportY(qreal y); - bool isUserGenerated; - bool isFlicking; - bool isMoving; - bool movingHorizontally; - bool movingVertically; + qreal overShootDistance(qreal velocity, qreal size); - bool atBeginningX; - bool atBeginningY; - bool atEndX; - bool atEndY; + void itemGeometryChanged(QDeclarativeItem *, const QRectF &, const QRectF &); - bool interactive; +public: + QDeclarativeItem *contentItem; + AxisData hData; + AxisData vData; + + QDeclarativeTimeLine timeline; + bool flickingHorizontally : 1; + bool flickingVertically : 1; + bool hMoved : 1; + bool vMoved : 1; + bool movingHorizontally : 1; + bool movingVertically : 1; + bool stealMouse : 1; + bool pressed : 1; + bool interactive : 1; + bool calcVelocity : 1; + QElapsedTimer lastPosTime; + QPointF lastPos; + QPointF pressPos; + QElapsedTimer pressTime; + qreal deceleration; + qreal maxVelocity; + QElapsedTimer velocityTime; + QPointF lastFlickablePosition; + qreal reportedVelocitySmoothing; + QGraphicsSceneMouseEvent *delayedPressEvent; + QGraphicsItem *delayedPressTarget; + QBasicTimer delayedPressTimer; + int pressDelay; + int fixupDuration; + + static void fixupY_callback(void *); + static void fixupX_callback(void *); + + void updateVelocity(); + int vTime; + QDeclarativeTimeLine velocityTimeline; QDeclarativeFlickableVisibleArea *visibleArea; QDeclarativeFlickable::FlickableDirection flickableDirection; QDeclarativeFlickable::BoundsBehavior boundsBehavior; diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index b6af7dc..6f38f63 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -95,42 +95,24 @@ public: //---------------------------------------------------------------------------- -/* - Some explanations: - The grid view is not creating graphics items for every entry - in the model. - - Instead it's creating only number of items that are currently - visible in visibleItems. The first model index of those items is - visibleIndex -*/ - class QDeclarativeGridViewPrivate : public QDeclarativeFlickablePrivate { Q_DECLARE_PUBLIC(QDeclarativeGridView) public: QDeclarativeGridViewPrivate() - : currentItem(0), flow(QDeclarativeGridView::LeftToRight) - , visibleIndex(0) , currentIndex(-1) - , cellWidth(100), cellHeight(100), columns(1), requestedIndex(-1), modelCount(0) - , highlightRangeStart(0), highlightRangeEnd(0), highlightRange(QDeclarativeGridView::NoHighlightRange) - , highlightComponent(0), highlight(0) - , moveReason(Other) - , buffer(0) - , bufferMode(BufferBefore | BufferAfter) - , highlightXAnimator(0), highlightYAnimator(0) - , highlightMoveDuration(150) - , footerComponent(0) - , footer(0) - , headerComponent(0) - , header(0) - , snapMode(QDeclarativeGridView::NoSnap) - , ownModel(false), wrap(false), autoHighlight(true) - , fixCurrentVisibility(false), lazyRelease(false), layoutScheduled(false) - , deferredRelease(false), haveHighlightRange(false) - , currentIndexCleared(false) - {} + : currentItem(0), flow(QDeclarativeGridView::LeftToRight) + , visibleIndex(0) , currentIndex(-1) + , cellWidth(100), cellHeight(100), columns(1), requestedIndex(-1), itemCount(0) + , highlightRangeStart(0), highlightRangeEnd(0), highlightRange(QDeclarativeGridView::NoHighlightRange) + , highlightComponent(0), highlight(0), trackedItem(0) + , moveReason(Other), buffer(0), highlightXAnimator(0), highlightYAnimator(0) + , highlightMoveDuration(150) + , footerComponent(0), footer(0), headerComponent(0), header(0) + , bufferMode(BufferBefore | BufferAfter), snapMode(QDeclarativeGridView::NoSnap) + , ownModel(false), wrap(false), autoHighlight(true) + , fixCurrentVisibility(false), lazyRelease(false), layoutScheduled(false) + , deferredRelease(false), haveHighlightRange(false), currentIndexCleared(false) {} void init(); void clear(); @@ -138,15 +120,18 @@ public: void releaseItem(FxGridItem *item); void refill(qreal from, qreal to, bool doBuffer=false); + void updateGrid(); void scheduleLayout(); void layout(); void updateUnrequestedIndexes(); void updateUnrequestedPositions(); - void recreateHighlight(); - void updateHighlight(bool smooth = true); - void setCurrentIndex(int modelIndex); + void updateTrackedItem(); + void createHighlight(); + void updateHighlight(); + void updateCurrent(int modelIndex); void updateHeader(); void updateFooter(); + void fixupPosition(); FxGridItem *visibleItem(int modelIndex) const { if (modelIndex >= visibleIndex && modelIndex < visibleIndex + visibleItems.count()) { @@ -159,28 +144,10 @@ public: return 0; } - /* The following methods are using flow independent coordinates. - row and column also change the direction depending on the flow. - */ - - /*! \internal - Returns the position of the view. - Depending on the flow this can be either the x or the y content coordinate - */ qreal position() const { Q_Q(const QDeclarativeGridView); return flow == QDeclarativeGridView::LeftToRight ? q->contentY() : q->contentX(); } - - void scrollTo(qreal pos) { - Q_Q(QDeclarativeGridView); - QScroller *scroller = QScroller::scroller(q); - if (flow == QDeclarativeGridView::LeftToRight) - scroller->scrollTo(QPoint(q->contentX(), pos)); - else - scroller->scrollTo(QPoint(pos, q->contentY())); - } - void setPosition(qreal pos) { Q_Q(QDeclarativeGridView); if (flow == QDeclarativeGridView::LeftToRight) @@ -192,39 +159,22 @@ public: Q_Q(const QDeclarativeGridView); return flow == QDeclarativeGridView::LeftToRight ? q->height() : q->width(); } - - /*! \internal - Returns the row size of the header to be added to the total item size. - */ - qreal headerSize() const { - if (!header) - return 0; - if (flow == QDeclarativeGridView::LeftToRight) - return header->item->height(); - else - return header->item->width(); - } - - /*! \internal - Returns the row size of the footer to be added to the total item size. - */ - qreal footerSize() const { - if (!footer) - return 0; - if (flow == QDeclarativeGridView::LeftToRight) - return footer->item->height(); - else - return footer->item->width(); + qreal startPosition() const { + qreal pos = 0; + if (!visibleItems.isEmpty()) + pos = visibleItems.first()->rowPos() - visibleIndex / columns * rowSize(); + return pos; } - qreal contentSize() const { - if (!model || !model->isValid()) - return 0.0; - return ((modelCount + columns - 1 /*round up*/) / columns) * rowSize(); + qreal endPosition() const { + qreal pos = 0; + if (model && model->count()) + pos = rowPosAt(model->count() - 1) + rowSize(); + return pos; } bool isValid() const { - return model && modelCount && model->isValid(); + return model && model->count() && model->isValid(); } int rowSize() const { @@ -235,13 +185,51 @@ public: } qreal colPosAt(int modelIndex) const { - return (modelIndex % columns) * colSize(); + if (FxGridItem *item = visibleItem(modelIndex)) + return item->colPos(); + if (!visibleItems.isEmpty()) { + if (modelIndex < visibleIndex) { + int count = (visibleIndex - modelIndex) % columns; + int col = visibleItems.first()->colPos() / colSize(); + col = (columns - count + col) % columns; + return col * colSize(); + } else { + int count = columns - 1 - (modelIndex - visibleItems.last()->index - 1) % columns; + return visibleItems.last()->colPos() - count * colSize(); + } + } else { + return (modelIndex % columns) * colSize(); + } + return 0; } qreal rowPosAt(int modelIndex) const { - return (modelIndex / columns) * rowSize() + headerSize(); + if (FxGridItem *item = visibleItem(modelIndex)) + return item->rowPos(); + if (!visibleItems.isEmpty()) { + if (modelIndex < visibleIndex) { + int firstCol = visibleItems.first()->colPos() / colSize(); + int col = visibleIndex - modelIndex + (columns - firstCol - 1); + int rows = col / columns; + return visibleItems.first()->rowPos() - rows * rowSize(); + } else { + int count = modelIndex - visibleItems.last()->index; + int col = visibleItems.last()->colPos() + count * colSize(); + int rows = col / (columns * colSize()); + return visibleItems.last()->rowPos() + rows * rowSize(); + } + } else { + qreal pos = (modelIndex / columns) * rowSize(); + if (header) { + qreal headerSize = flow == QDeclarativeGridView::LeftToRight + ? header->item->height() + : header->item->width(); + pos += headerSize; + } + return pos; + } + return 0; } - /*! Returns the first of the visibleItems that is visible */ FxGridItem *firstVisibleItem() const { const qreal pos = position(); for (int i = 0; i < visibleItems.count(); ++i) { @@ -252,17 +240,16 @@ public: return visibleItems.count() ? visibleItems.first() : 0; } - /*! \internal - Returns the last visible model index. delayRemove items are not counted (as they don't have an index) - */ int lastVisibleIndex() const { - // find the last valid model index - for (int i = visibleItems.count() - 1; i >= 0; --i) { - FxGridItem *item = visibleItems.at(i); - if (item->index != -1) - return item->index; + int lastIndex = -1; + for (int i = visibleItems.count()-1; i >= 0; --i) { + FxGridItem *gridItem = visibleItems.at(i); + if (gridItem->index != -1) { + lastIndex = gridItem->index; + break; + } } - return visibleIndex; + return lastIndex; } // Map a model index to visibleItems list index. @@ -281,22 +268,51 @@ public: return -1; // Not in visibleList } - /*! \internal - Return the model index of the visible item which is - next to the highlight. - */ - int snapIndex() - { - // which is the next row and column around the hightlight - int nextRow = qRound(highlight->rowPos() / rowSize()); - int nextCol = qRound(highlight->colPos() / colSize()); - - // calculate and verify index - int index = nextRow * columns + nextCol; - if (index < 0 || index >= modelCount) - return currentIndex; - else - return index; + qreal snapPosAt(qreal pos) const { + Q_Q(const QDeclarativeGridView); + qreal snapPos = 0; + if (!visibleItems.isEmpty()) { + pos += rowSize()/2; + snapPos = visibleItems.first()->rowPos() - visibleIndex / columns * rowSize(); + snapPos = pos - fmodf(pos - snapPos, qreal(rowSize())); + qreal maxExtent = flow == QDeclarativeGridView::LeftToRight ? -q->maxYExtent() : -q->maxXExtent(); + qreal minExtent = flow == QDeclarativeGridView::LeftToRight ? -q->minYExtent() : -q->minXExtent(); + if (snapPos > maxExtent) + snapPos = maxExtent; + if (snapPos < minExtent) + snapPos = minExtent; + } + return snapPos; + } + + FxGridItem *snapItemAt(qreal pos) { + for (int i = 0; i < visibleItems.count(); ++i) { + FxGridItem *item = visibleItems[i]; + if (item->index == -1) + continue; + qreal itemTop = item->rowPos(); + if (item->index == model->count()-1 || (itemTop+rowSize()/2 >= pos)) + return item; + } + if (visibleItems.count() && visibleItems.first()->rowPos() <= pos) + return visibleItems.first(); + return 0; + } + + int snapIndex() { + int index = currentIndex; + for (int i = 0; i < visibleItems.count(); ++i) { + FxGridItem *item = visibleItems[i]; + if (item->index == -1) + continue; + qreal itemTop = item->rowPos(); + if (itemTop >= highlight->rowPos()-rowSize()/2 && itemTop < highlight->rowPos()+rowSize()/2) { + index = item->index; + if (item->colPos() >= highlight->colPos()-colSize()/2 && item->colPos() < highlight->colPos()+colSize()/2) + return item->index; + } + } + return index; } virtual void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) { @@ -306,6 +322,7 @@ public: if (newGeometry.height() != oldGeometry.height() || newGeometry.width() != oldGeometry.width()) { if (q->isComponentComplete()) { + updateGrid(); scheduleLayout(); } } @@ -313,10 +330,12 @@ public: updateHeader(); updateFooter(); } - if (currentItem && currentItem->item == item) - updateHighlight(); } + virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent); + virtual void flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, + QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity); + // for debugging only void checkVisible() const { int skip = 0; @@ -335,71 +354,34 @@ public: QDeclarativeGuard model; QVariant modelVariant; QList visibleItems; - - /* - These are items that were not requested but send by createdItem from the model. - Usually these items were created because another view showing the same model - needed them. - */ QHash unrequestedItems; - FxGridItem *currentItem; QDeclarativeGridView::Flow flow; - - /* - The visibleIndex is the modelIndex of the first item in visibleItems - visible row. - */ int visibleIndex; - - /* - The currentIndex is the model index of the currently highlighted item. - */ int currentIndex; - int cellWidth; int cellHeight; - - /* - The number of columns this layout currently has. - */ int columns; - - /* - The model index of the item that is currently created via createItem - */ int requestedIndex; - - /* - This is the number of items in the model. - */ - int modelCount; - + int itemCount; qreal highlightRangeStart; qreal highlightRangeEnd; QDeclarativeGridView::HighlightRangeMode highlightRange; QDeclarativeComponent *highlightComponent; FxGridItem *highlight; + FxGridItem *trackedItem; enum MovementReason { Other, SetIndex, Mouse }; MovementReason moveReason; - - /* - The maximum number of pixels that should be covered by buffered - delegates in front and behind the visible area. - */ int buffer; - enum BufferMode { NoBuffer = 0x00, BufferBefore = 0x01, BufferAfter = 0x02 }; - int bufferMode; - QSmoothedAnimation *highlightXAnimator; QSmoothedAnimation *highlightYAnimator; int highlightMoveDuration; - QDeclarativeComponent *footerComponent; FxGridItem *footer; QDeclarativeComponent *headerComponent; FxGridItem *header; - + enum BufferMode { NoBuffer = 0x00, BufferBefore = 0x01, BufferAfter = 0x02 }; + int bufferMode; QDeclarativeGridView::SnapMode snapMode; bool ownModel : 1; @@ -416,6 +398,7 @@ public: void QDeclarativeGridViewPrivate::init() { Q_Q(QDeclarativeGridView); + QObject::connect(q, SIGNAL(movementEnded()), q, SLOT(animStopped())); q->setFlag(QGraphicsItem::ItemIsFocusScope); q->setFlickableDirection(QDeclarativeFlickable::VerticalFlick); addItemChangeListener(this, Geometry); @@ -429,8 +412,9 @@ void QDeclarativeGridViewPrivate::clear() visibleIndex = 0; releaseItem(currentItem); currentItem = 0; - recreateHighlight(); - modelCount = 0; + createHighlight(); + trackedItem = 0; + itemCount = 0; } FxGridItem *QDeclarativeGridViewPrivate::createItem(int modelIndex) @@ -462,6 +446,11 @@ void QDeclarativeGridViewPrivate::releaseItem(FxGridItem *item) Q_Q(QDeclarativeGridView); if (!item || !model) return; + if (trackedItem == item) { + QObject::disconnect(trackedItem->item, SIGNAL(yChanged()), q, SLOT(trackedPositionChanged())); + QObject::disconnect(trackedItem->item, SIGNAL(xChanged()), q, SLOT(trackedPositionChanged())); + trackedItem = 0; + } if (model->release(item->item) == 0) { // item was not destroyed, and we no longer reference it. unrequestedItems.insert(item->item, model->indexOf(item->item, q)); @@ -472,12 +461,9 @@ void QDeclarativeGridViewPrivate::releaseItem(FxGridItem *item) void QDeclarativeGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) { Q_Q(QDeclarativeGridView); - if (!q->isComponentComplete()) + if (!isValid() || !q->isComponentComplete()) return; - - if (!doBuffer && buffer && bufferMode != NoBuffer) - doBuffer = true; - + itemCount = model->count(); qreal bufferFrom = from - buffer; qreal bufferTo = to + buffer; qreal fillFrom = from; @@ -489,32 +475,29 @@ void QDeclarativeGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) bool changed = false; - updateHeader(); - - columns = (int)qMax((flow == QDeclarativeGridView::LeftToRight ? q->width() : q->height()) / colSize(), qreal(1.)); - - // -- update the positions of all visible items - for (int i = 0; i < visibleItems.count(); ++i) { - qreal colPos = colPosAt(i + visibleIndex); - qreal rowPos = rowPosAt(i + visibleIndex); - FxGridItem *item = visibleItems.at(i); - item->setPosition(colPos, rowPos); + int colPos = colPosAt(visibleIndex); + int rowPos = rowPosAt(visibleIndex); + int modelIndex = visibleIndex; + if (visibleItems.count()) { + rowPos = visibleItems.last()->rowPos(); + colPos = visibleItems.last()->colPos() + colSize(); + if (colPos > colSize() * (columns-1)) { + colPos = 0; + rowPos += rowSize(); + } + int i = visibleItems.count() - 1; + while (i > 0 && visibleItems.at(i)->index == -1) + --i; + modelIndex = visibleItems.at(i)->index + 1; } - - // determine the next position - int modelIndex = lastVisibleIndex(); - if (!visibleItems.isEmpty()) - modelIndex++; - qreal colPos = colPosAt(modelIndex); - qreal rowPos = rowPosAt(modelIndex); - int colNum = colPos / colSize(); + FxGridItem *item = 0; // Item creation and release is staggered in order to avoid // creating/releasing multiple items in one frame // while flicking (as much as possible). - while (modelIndex < modelCount && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) { + while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) { // qDebug() << "refill: append item" << modelIndex; if (!(item = createItem(modelIndex))) break; @@ -588,19 +571,33 @@ void QDeclarativeGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) } else { deferredRelease = true; } - - if (flow == QDeclarativeGridView::LeftToRight) - q->setContentHeight(contentSize()); - else - q->setContentWidth(contentSize()); - - updateFooter(); - - updateUnrequestedPositions(); - + if (changed) { + if (header) + updateHeader(); + if (footer) + updateFooter(); + if (flow == QDeclarativeGridView::LeftToRight) + q->setContentHeight(endPosition() - startPosition()); + else + q->setContentWidth(endPosition() - startPosition()); + } else if (!doBuffer && buffer && bufferMode != NoBuffer) { + refill(from, to, true); + } lazyRelease = false; } +void QDeclarativeGridViewPrivate::updateGrid() +{ + Q_Q(QDeclarativeGridView); + columns = (int)qMax((flow == QDeclarativeGridView::LeftToRight ? q->width() : q->height()) / colSize(), qreal(1.)); + if (isValid()) { + if (flow == QDeclarativeGridView::LeftToRight) + q->setContentHeight(endPosition() - startPosition()); + else + q->setContentWidth(endPosition() - startPosition()); + } +} + void QDeclarativeGridViewPrivate::scheduleLayout() { Q_Q(QDeclarativeGridView); @@ -612,9 +609,53 @@ void QDeclarativeGridViewPrivate::scheduleLayout() void QDeclarativeGridViewPrivate::layout() { + Q_Q(QDeclarativeGridView); layoutScheduled = false; + if (!isValid() && !visibleItems.count()) { + clear(); + return; + } + if (visibleItems.count()) { + qreal rowPos = visibleItems.first()->rowPos(); + qreal colPos = visibleItems.first()->colPos(); + int col = visibleIndex % columns; + if (colPos != col * colSize()) { + colPos = col * colSize(); + visibleItems.first()->setPosition(colPos, rowPos); + } + for (int i = 1; i < visibleItems.count(); ++i) { + FxGridItem *item = visibleItems.at(i); + colPos += colSize(); + if (colPos > colSize() * (columns-1)) { + colPos = 0; + rowPos += rowSize(); + } + item->setPosition(colPos, rowPos); + } + } + if (header) + updateHeader(); + if (footer) + updateFooter(); + q->refill(); + updateHighlight(); + moveReason = Other; + if (flow == QDeclarativeGridView::LeftToRight) { + q->setContentHeight(endPosition() - startPosition()); + fixupY(); + } else { + q->setContentWidth(endPosition() - startPosition()); + fixupX(); + } + updateUnrequestedPositions(); +} - refill(position(), position() + size() - 1); +void QDeclarativeGridViewPrivate::updateUnrequestedIndexes() +{ + Q_Q(QDeclarativeGridView); + QHash::iterator it; + for (it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it) + *it = model->indexOf(it.key(), q); } void QDeclarativeGridViewPrivate::updateUnrequestedPositions() @@ -629,11 +670,35 @@ void QDeclarativeGridViewPrivate::updateUnrequestedPositions() } } -void QDeclarativeGridViewPrivate::recreateHighlight() +void QDeclarativeGridViewPrivate::updateTrackedItem() +{ + Q_Q(QDeclarativeGridView); + FxGridItem *item = currentItem; + if (highlight) + item = highlight; + + if (trackedItem && item != trackedItem) { + QObject::disconnect(trackedItem->item, SIGNAL(yChanged()), q, SLOT(trackedPositionChanged())); + QObject::disconnect(trackedItem->item, SIGNAL(xChanged()), q, SLOT(trackedPositionChanged())); + trackedItem = 0; + } + + if (!trackedItem && item) { + trackedItem = item; + QObject::connect(trackedItem->item, SIGNAL(yChanged()), q, SLOT(trackedPositionChanged())); + QObject::connect(trackedItem->item, SIGNAL(xChanged()), q, SLOT(trackedPositionChanged())); + } + if (trackedItem) + q->trackedPositionChanged(); +} + +void QDeclarativeGridViewPrivate::createHighlight() { Q_Q(QDeclarativeGridView); bool changed = false; if (highlight) { + if (trackedItem == highlight) + trackedItem = 0; delete highlight->item; delete highlight; highlight = 0; @@ -659,6 +724,8 @@ void QDeclarativeGridViewPrivate::recreateHighlight() } } else { item = new QDeclarativeItem; + QDeclarative_setParent_noEvent(item, q->contentItem()); + item->setParentItem(q->contentItem()); } if (item) { QDeclarative_setParent_noEvent(item, q->contentItem()); @@ -683,88 +750,59 @@ void QDeclarativeGridViewPrivate::recreateHighlight() emit q->highlightItemChanged(); } -void QDeclarativeGridViewPrivate::updateHighlight(bool smooth) +void QDeclarativeGridViewPrivate::updateHighlight() { if ((!currentItem && highlight) || (currentItem && !highlight)) - recreateHighlight(); - - // --- move the current item between the highlight range - if (moveReason == QDeclarativeGridViewPrivate::SetIndex) { - // ensure that the tracked item is inside the highlight range - - // reposition view - if (currentItem) { - qreal pos = currentItem->rowPos(); - qreal viewPos = position(); - - if (autoHighlight && haveHighlightRange) { - if (pos > viewPos + highlightRangeEnd - rowSize()) - viewPos = pos - highlightRangeEnd + rowSize(); - if (pos < viewPos + highlightRangeStart) - viewPos = pos - highlightRangeStart; - - } else { - if (pos > viewPos + size() - rowSize()) - viewPos = pos - size() + rowSize(); - if (pos < viewPos + 0) - viewPos = pos - 0; - } - if (smooth) - scrollTo(viewPos); - else - setPosition(viewPos); - } - - // move the highlight - if (currentItem && autoHighlight && highlight) { - highlight->item->setWidth(currentItem->item->width()); - highlight->item->setHeight(currentItem->item->height()); - highlightXAnimator->to = currentItem->item->x(); - highlightYAnimator->to = currentItem->item->y(); - if (smooth) { - highlightXAnimator->restart(); - highlightYAnimator->restart(); - } else { - highlightXAnimator->stop(); - highlightYAnimator->stop(); - highlight->item->setPos(QPointF(highlightXAnimator->to, - highlightYAnimator->to)); - } - } + createHighlight(); + if (currentItem && autoHighlight && highlight && !movingHorizontally && !movingVertically) { + // auto-update highlight + highlightXAnimator->to = currentItem->item->x(); + highlightYAnimator->to = currentItem->item->y(); + highlight->item->setWidth(currentItem->item->width()); + highlight->item->setHeight(currentItem->item->height()); + highlightXAnimator->restart(); + highlightYAnimator->restart(); } + updateTrackedItem(); } -void QDeclarativeGridViewPrivate::setCurrentIndex(int newIndex) +void QDeclarativeGridViewPrivate::updateCurrent(int modelIndex) { Q_Q(QDeclarativeGridView); - - // --- release the old item - if (currentItem && currentIndex != newIndex ) { + if (!q->isComponentComplete() || !isValid() || modelIndex < 0 || modelIndex >= model->count()) { + if (currentItem) { currentItem->attached->setIsCurrentItem(false); releaseItem(currentItem); currentItem = 0; + currentIndex = modelIndex; + emit q->currentIndexChanged(); + updateHighlight(); + } else if (currentIndex != modelIndex) { + currentIndex = modelIndex; + emit q->currentIndexChanged(); + } + return; } - int oldIndex = currentIndex; - currentIndex = newIndex; - - bool visible = (q->isComponentComplete() && isValid() && !currentItem && - newIndex >= 0 && newIndex < modelCount); - - // --- set the new item - if (visible) { - currentItem = createItem(newIndex); - if (currentItem) { - currentItem->setPosition(colPosAt(newIndex), rowPosAt(newIndex)); - currentItem->item->setFocus(true); - currentItem->attached->setIsCurrentItem(true); - } + if (currentItem && currentIndex == modelIndex) { + updateHighlight(); + return; } + FxGridItem *oldCurrentItem = currentItem; + currentIndex = modelIndex; + currentItem = createItem(modelIndex); + fixCurrentVisibility = true; + if (oldCurrentItem && (!currentItem || oldCurrentItem->item != currentItem->item)) + oldCurrentItem->attached->setIsCurrentItem(false); + if (currentItem) { + currentItem->setPosition(colPosAt(modelIndex), rowPosAt(modelIndex)); + currentItem->item->setFocus(true); + currentItem->attached->setIsCurrentItem(true); + } updateHighlight(); - - if (currentIndex != oldIndex) - emit q->currentIndexChanged(); + emit q->currentIndexChanged(); + releaseItem(oldCurrentItem); } void QDeclarativeGridViewPrivate::updateFooter() @@ -792,7 +830,24 @@ void QDeclarativeGridViewPrivate::updateFooter() } } if (footer) { - footer->setPosition(0, contentSize() + headerSize()); + if (visibleItems.count()) { + qreal endPos = endPosition(); + if (lastVisibleIndex() == model->count()-1) { + footer->setPosition(0, endPos); + } else { + qreal visiblePos = position() + q->height(); + if (endPos <= visiblePos || footer->endRowPos() < endPos) + footer->setPosition(0, endPos); + } + } else { + qreal endPos = 0; + if (header) { + endPos += flow == QDeclarativeGridView::LeftToRight + ? header->item->height() + : header->item->width(); + } + footer->setPosition(0, endPos); + } } } @@ -821,10 +876,194 @@ void QDeclarativeGridViewPrivate::updateHeader() } } if (header) { - header->setPosition(0, 0); + if (visibleItems.count()) { + qreal startPos = startPosition(); + qreal headerSize = flow == QDeclarativeGridView::LeftToRight + ? header->item->height() + : header->item->width(); + if (visibleIndex == 0) { + header->setPosition(0, startPos - headerSize); + } else { + if (position() <= startPos || header->rowPos() > startPos - headerSize) + header->setPosition(0, startPos - headerSize); + } + } else { + header->setPosition(0, 0); + } } } +void QDeclarativeGridViewPrivate::fixupPosition() +{ + moveReason = Other; + if (flow == QDeclarativeGridView::LeftToRight) + fixupY(); + else + fixupX(); +} + +void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent) +{ + if ((flow == QDeclarativeGridView::TopToBottom && &data == &vData) + || (flow == QDeclarativeGridView::LeftToRight && &data == &hData)) + return; + + int oldDuration = fixupDuration; + fixupDuration = moveReason == Mouse ? fixupDuration : 0; + + if (snapMode != QDeclarativeGridView::NoSnap) { + FxGridItem *topItem = snapItemAt(position()+highlightRangeStart); + FxGridItem *bottomItem = snapItemAt(position()+highlightRangeEnd); + qreal pos; + if (topItem && bottomItem && haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) { + qreal topPos = qMin(topItem->rowPos() - highlightRangeStart, -maxExtent); + qreal bottomPos = qMax(bottomItem->rowPos() - highlightRangeEnd, -minExtent); + pos = qAbs(data.move + topPos) < qAbs(data.move + bottomPos) ? topPos : bottomPos; + } else if (topItem) { + pos = qMax(qMin(topItem->rowPos() - highlightRangeStart, -maxExtent), -minExtent); + } else if (bottomItem) { + pos = qMax(qMin(bottomItem->rowPos() - highlightRangeStart, -maxExtent), -minExtent); + } else { + fixupDuration = oldDuration; + return; + } + if (currentItem && haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) { + updateHighlight(); + qreal currPos = currentItem->rowPos(); + if (pos < currPos + rowSize() - highlightRangeEnd) + pos = currPos + rowSize() - highlightRangeEnd; + if (pos > currPos - highlightRangeStart) + pos = currPos - highlightRangeStart; + } + + qreal dist = qAbs(data.move + pos); + if (dist > 0) { + timeline.reset(data.move); + if (fixupDuration) + timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); + else + timeline.set(data.move, -pos); + vTime = timeline.time(); + } + } else if (haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) { + if (currentItem) { + updateHighlight(); + qreal pos = currentItem->rowPos(); + qreal viewPos = position(); + if (viewPos < pos + rowSize() - highlightRangeEnd) + viewPos = pos + rowSize() - highlightRangeEnd; + if (viewPos > pos - highlightRangeStart) + viewPos = pos - highlightRangeStart; + + timeline.reset(data.move); + if (viewPos != position()) { + if (fixupDuration) + timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); + else + timeline.set(data.move, -viewPos); + } + vTime = timeline.time(); + } + } else { + QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent); + } + fixupDuration = oldDuration; +} + +void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, + QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity) +{ + Q_Q(QDeclarativeGridView); + moveReason = Mouse; + if ((!haveHighlightRange || highlightRange != QDeclarativeGridView::StrictlyEnforceRange) + && snapMode == QDeclarativeGridView::NoSnap) { + QDeclarativeFlickablePrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity); + return; + } + qreal maxDistance = 0; + // -ve velocity means list is moving up + if (velocity > 0) { + if (data.move.value() < minExtent) { + if (snapMode == QDeclarativeGridView::SnapOneRow) { + if (FxGridItem *item = firstVisibleItem()) + maxDistance = qAbs(item->rowPos() + data.move.value()); + } else { + maxDistance = qAbs(minExtent - data.move.value()); + } + } + if (snapMode == QDeclarativeGridView::NoSnap && highlightRange != QDeclarativeGridView::StrictlyEnforceRange) + data.flickTarget = minExtent; + } else { + if (data.move.value() > maxExtent) { + if (snapMode == QDeclarativeGridView::SnapOneRow) { + qreal pos = snapPosAt(-data.move.value()) + rowSize(); + maxDistance = qAbs(pos + data.move.value()); + } else { + maxDistance = qAbs(maxExtent - data.move.value()); + } + } + if (snapMode == QDeclarativeGridView::NoSnap && highlightRange != QDeclarativeGridView::StrictlyEnforceRange) + data.flickTarget = maxExtent; + } + bool overShoot = boundsBehavior == QDeclarativeFlickable::DragAndOvershootBounds; + if (maxDistance > 0 || overShoot) { + // This mode requires the grid to stop exactly on a row boundary. + qreal v = velocity; + if (maxVelocity != -1 && maxVelocity < qAbs(v)) { + if (v < 0) + v = -maxVelocity; + else + v = maxVelocity; + } + qreal accel = deceleration; + qreal v2 = v * v; + qreal overshootDist = 0.0; + if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarativeGridView::SnapOneRow) { + // + rowSize()/4 to encourage moving at least one item in the flick direction + qreal dist = v2 / (accel * 2.0) + rowSize()/4; + dist = qMin(dist, maxDistance); + if (v > 0) + dist = -dist; + data.flickTarget = -snapPosAt(-(data.move.value() - highlightRangeStart) + dist) + highlightRangeStart; + qreal adjDist = -data.flickTarget + data.move.value(); + if (qAbs(adjDist) > qAbs(dist)) { + // Prevent painfully slow flicking - adjust velocity to suit flickDeceleration + qreal adjv2 = accel * 2.0f * qAbs(adjDist); + if (adjv2 > v2) { + v2 = adjv2; + v = qSqrt(v2); + if (dist > 0) + v = -v; + } + } + dist = adjDist; + accel = v2 / (2.0f * qAbs(dist)); + } else { + data.flickTarget = velocity > 0 ? minExtent : maxExtent; + overshootDist = overShoot ? overShootDistance(v, vSize) : 0; + } + timeline.reset(data.move); + timeline.accel(data.move, v, accel, maxDistance + overshootDist); + timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this)); + if (!flickingHorizontally && q->xflick()) { + flickingHorizontally = true; + emit q->flickingChanged(); + emit q->flickingHorizontallyChanged(); + emit q->flickStarted(); + } + if (!flickingVertically && q->yflick()) { + flickingVertically = true; + emit q->flickingChanged(); + emit q->flickingVerticallyChanged(); + emit q->flickStarted(); + } + } else { + timeline.reset(data.move); + fixup(data, minExtent, maxExtent); + } +} + + //---------------------------------------------------------------------------- /*! @@ -968,10 +1207,10 @@ QVariant QDeclarativeGridView::model() const return d->modelVariant; } -void QDeclarativeGridView::setModel(const QVariant &newModel) +void QDeclarativeGridView::setModel(const QVariant &model) { Q_D(QDeclarativeGridView); - if (d->modelVariant == newModel) + if (d->modelVariant == model) return; if (d->model) { disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); @@ -981,18 +1220,13 @@ void QDeclarativeGridView::setModel(const QVariant &newModel) disconnect(d->model, SIGNAL(createdItem(int,QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*))); disconnect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*))); } - d->clear(); - QDeclarativeVisualModel *oldModel = d->model; - d->model = 0; - d->modelCount = 0; - - d->modelVariant = newModel; - QObject *object = qvariant_cast(newModel); + d->modelVariant = model; + QObject *object = qvariant_cast(model); QDeclarativeVisualModel *vim = 0; if (object && (vim = qobject_cast(object))) { if (d->ownModel) { - delete oldModel; + delete d->model; d->ownModel = false; } d->model = vim; @@ -1000,22 +1234,24 @@ void QDeclarativeGridView::setModel(const QVariant &newModel) if (!d->ownModel) { d->model = new QDeclarativeVisualDataModel(qmlContext(this), this); d->ownModel = true; - } else { - d->model = oldModel; } if (QDeclarativeVisualDataModel *dataModel = qobject_cast(d->model)) - dataModel->setModel(newModel); + dataModel->setModel(model); } - if (d->model) { - d->modelCount = d->model->count(); d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore | QDeclarativeGridViewPrivate::BufferAfter; if (isComponentComplete()) { refill(); - if ((d->currentIndex >= d->modelCount || d->currentIndex < 0) && !d->currentIndexCleared) { + if ((d->currentIndex >= d->model->count() || d->currentIndex < 0) && !d->currentIndexCleared) { setCurrentIndex(0); } else { - d->setCurrentIndex(d->currentIndex); + d->moveReason = QDeclarativeGridViewPrivate::SetIndex; + d->updateCurrent(d->currentIndex); + if (d->highlight && d->currentItem) { + d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); + d->updateTrackedItem(); + } + d->moveReason = QDeclarativeGridViewPrivate::Other; } } connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); @@ -1078,7 +1314,12 @@ void QDeclarativeGridView::setDelegate(QDeclarativeComponent *delegate) d->currentItem = 0; refill(); d->moveReason = QDeclarativeGridViewPrivate::SetIndex; - d->setCurrentIndex(d->currentIndex); + d->updateCurrent(d->currentIndex); + if (d->highlight && d->currentItem) { + d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); + d->updateTrackedItem(); + } + d->moveReason = QDeclarativeGridViewPrivate::Other; } emit delegateChanged(); } @@ -1110,15 +1351,12 @@ void QDeclarativeGridView::setCurrentIndex(int index) Q_D(QDeclarativeGridView); if (d->requestedIndex >= 0) // currently creating item return; - d->currentIndexCleared = (index == -1); - if (index == d->currentIndex) return; - if (isComponentComplete() && d->isValid()) { d->moveReason = QDeclarativeGridViewPrivate::SetIndex; - d->setCurrentIndex(index); + d->updateCurrent(index); } else { d->currentIndex = index; emit currentIndexChanged(); @@ -1158,7 +1396,9 @@ QDeclarativeItem *QDeclarativeGridView::highlightItem() int QDeclarativeGridView::count() const { Q_D(const QDeclarativeGridView); - return d->modelCount; + if (d->model) + return d->model->count(); + return 0; } /*! @@ -1182,7 +1422,7 @@ void QDeclarativeGridView::setHighlight(QDeclarativeComponent *highlight) Q_D(QDeclarativeGridView); if (highlight != d->highlightComponent) { d->highlightComponent = highlight; - d->recreateHighlight(); + d->updateCurrent(d->currentIndex); emit highlightChanged(); } } @@ -1359,8 +1599,10 @@ void QDeclarativeGridView::setFlow(Flow flow) setContentHeight(-1); setFlickableDirection(QDeclarativeFlickable::HorizontalFlick); } - d->layout(); - d->setCurrentIndex(d->currentIndex); + d->clear(); + d->updateGrid(); + refill(); + d->updateCurrent(d->currentIndex); emit flowChanged(); } } @@ -1445,8 +1687,9 @@ void QDeclarativeGridView::setCellWidth(int cellWidth) Q_D(QDeclarativeGridView); if (cellWidth != d->cellWidth && cellWidth > 0) { d->cellWidth = qMax(1, cellWidth); - d->layout(); + d->updateGrid(); emit cellWidthChanged(); + d->layout(); } } @@ -1461,8 +1704,9 @@ void QDeclarativeGridView::setCellHeight(int cellHeight) Q_D(QDeclarativeGridView); if (cellHeight != d->cellHeight && cellHeight > 0) { d->cellHeight = qMax(1, cellHeight); - d->layout(); + d->updateGrid(); emit cellHeightChanged(); + d->layout(); } } /*! @@ -1520,7 +1764,8 @@ void QDeclarativeGridView::setFooter(QDeclarativeComponent *footer) d->footer = 0; } d->footerComponent = footer; - d->layout(); + d->updateFooter(); + d->updateGrid(); emit footerChanged(); } } @@ -1549,7 +1794,9 @@ void QDeclarativeGridView::setHeader(QDeclarativeComponent *header) d->header = 0; } d->headerComponent = header; - d->layout(); + d->updateHeader(); + d->updateFooter(); + d->updateGrid(); emit headerChanged(); } } @@ -1573,131 +1820,101 @@ void QDeclarativeGridView::setContentY(qreal pos) bool QDeclarativeGridView::event(QEvent *event) { Q_D(QDeclarativeGridView); - QScroller *scroller = QScroller::scroller(this); - - switch (event->type()) { - case QEvent::User: + if (event->type() == QEvent::User) { d->layout(); return true; - - case QEvent::ScrollPrepare: { - qreal snapOffset = 0; - bool forceSnapping = false; - // bool useEndPosition = false; - bool ignoreHeaders = false; - - // --- do the highlight range - if (d->haveHighlightRange) { - snapOffset = -d->highlightRangeStart; - ignoreHeaders = true; - } - - // just before scrolling set the snap points if needed - QList snapPoints; - // -- snap to every point (SnapToRow) - if (d->snapMode == QDeclarativeGridView::SnapToRow || forceSnapping) { - if (d->header && !ignoreHeaders) - snapPoints.append(0 + snapOffset); - foreach (FxGridItem *item, d->visibleItems) - snapPoints.append(item->rowPos() + snapOffset); - if (d->footer && !ignoreHeaders) - snapPoints.append(d->headerSize() + d->contentSize() + snapOffset); - - // -- snap to the next three point (SnapOneRow) - } else if (d->snapMode == QDeclarativeGridView::SnapOneRow) { - // here we just set three snap points around the current position. - - qreal rowPos = d->rowPosAt(d->currentIndex); - if (rowPos - d->rowSize() >= 0) - snapPoints.append( rowPos - d->rowSize()); - else if( d->header ) - snapPoints.append(0); // position of the header - - snapPoints.append(rowPos); - - if (rowPos + d->rowSize() < d->headerSize() + d->contentSize()) - snapPoints.append(rowPos + d->rowSize()); - else if( d->footer ) - snapPoints.append(d->headerSize() + d->contentSize() + snapOffset); // position of the footer - } - - if (d->flow == QDeclarativeGridView::LeftToRight) { - scroller->setSnapPositionsX(0.0, 0.0); - scroller->setSnapPositionsY(snapPoints); - } else { - scroller->setSnapPositionsX(snapPoints); - scroller->setSnapPositionsY(0.0, 0.0); - } - } - break; - - default: - break; } return QDeclarativeFlickable::event(event); } -void QDeclarativeGridView::scrollerStateChanged(QScroller::State state) +void QDeclarativeGridView::viewportMoved() { Q_D(QDeclarativeGridView); - QDeclarativeFlickable::scrollerStateChanged(state); + QDeclarativeFlickable::viewportMoved(); + if (!d->itemCount) + return; + d->lazyRelease = true; + if (d->flickingHorizontally || d->flickingVertically) { + if (yflick()) { + if (d->vData.velocity > 0) + d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore; + else if (d->vData.velocity < 0) + d->bufferMode = QDeclarativeGridViewPrivate::BufferAfter; + } - if (state == QScroller::Inactive) { - d->bufferMode = QDeclarativeGridViewPrivate::NoBuffer; - if (d->highlightRange == QDeclarativeGridView::StrictlyEnforceRange) { - d->updateHighlight(); // nudge the highlight in the right position if needed. + if (xflick()) { + if (d->hData.velocity > 0) + d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore; + else if (d->hData.velocity < 0) + d->bufferMode = QDeclarativeGridViewPrivate::BufferAfter; } } -} - -qreal QDeclarativeGridView::minExtent() const -{ - Q_D(const QDeclarativeGridView); - - qreal extent = 0.0; - if (d->modelCount && - d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - extent -= d->highlightRangeStart; - // extent = qMax(extent, -(d->rowPosAt(0) + d->rowSize() - d->highlightRangeEnd)); + refill(); + if (d->flickingHorizontally || d->flickingVertically || d->movingHorizontally || d->movingVertically) + d->moveReason = QDeclarativeGridViewPrivate::Mouse; + if (d->moveReason != QDeclarativeGridViewPrivate::SetIndex) { + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) { + // reposition highlight + qreal pos = d->highlight->rowPos(); + qreal viewPos = d->position(); + if (pos > viewPos + d->highlightRangeEnd - d->rowSize()) + pos = viewPos + d->highlightRangeEnd - d->rowSize(); + if (pos < viewPos + d->highlightRangeStart) + pos = viewPos + d->highlightRangeStart; + d->highlight->setPosition(d->highlight->colPos(), qRound(pos)); + + // update current index + int idx = d->snapIndex(); + if (idx >= 0 && idx != d->currentIndex) { + d->updateCurrent(idx); + if (d->currentItem && d->currentItem->colPos() != d->highlight->colPos() && d->autoHighlight) { + if (d->flow == LeftToRight) + d->highlightXAnimator->to = d->currentItem->item->x(); + else + d->highlightYAnimator->to = d->currentItem->item->y(); + } + } + } } - return extent; } -qreal QDeclarativeGridView::maxExtent() const +qreal QDeclarativeGridView::minYExtent() const { Q_D(const QDeclarativeGridView); - - qreal extent = d->contentSize(); - extent += d->headerSize(); - extent += d->footerSize(); - - if (d->visibleItems.count() && - d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - extent = qMin(extent + d->size() - d->highlightRangeEnd + 1, - // ensure that the last item fits fully behind hightlightRangeStart - d->rowPosAt(d->modelCount-1) + d->size() - d->highlightRangeStart); + if (d->flow == QDeclarativeGridView::TopToBottom) + return QDeclarativeFlickable::minYExtent(); + qreal extent = -d->startPosition(); + if (d->header && d->visibleItems.count()) + extent += d->header->item->height(); + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + extent += d->highlightRangeStart; + extent = qMax(extent, -(d->rowPosAt(0) + d->rowSize() - d->highlightRangeEnd)); } - return extent; } -qreal QDeclarativeGridView::minYExtent() const -{ - Q_D(const QDeclarativeGridView); - if (d->flow != QDeclarativeGridView::LeftToRight) - return QDeclarativeFlickable::minXExtent(); - else - return minExtent(); -} - qreal QDeclarativeGridView::maxYExtent() const { Q_D(const QDeclarativeGridView); - if (d->flow != QDeclarativeGridView::LeftToRight) - return QDeclarativeFlickable::maxXExtent(); - else - return maxExtent(); + if (d->flow == QDeclarativeGridView::TopToBottom) + return QDeclarativeFlickable::maxYExtent(); + qreal extent; + if (!d->model || !d->model->count()) { + extent = 0; + } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + extent = -(d->rowPosAt(d->model->count()-1) - d->highlightRangeStart); + if (d->highlightRangeEnd != d->highlightRangeStart) + extent = qMin(extent, -(d->endPosition() - d->highlightRangeEnd + 1)); + } else { + extent = -(d->endPosition() - height()); + } + if (d->footer) + extent -= d->footer->item->height(); + const qreal minY = minYExtent(); + if (extent > minY) + extent = minY; + return extent; } qreal QDeclarativeGridView::minXExtent() const @@ -1705,8 +1922,14 @@ qreal QDeclarativeGridView::minXExtent() const Q_D(const QDeclarativeGridView); if (d->flow == QDeclarativeGridView::LeftToRight) return QDeclarativeFlickable::minXExtent(); - else - return minExtent(); + qreal extent = -d->startPosition(); + if (d->header && d->visibleItems.count()) + extent += d->header->item->width(); + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + extent += d->highlightRangeStart; + extent = qMax(extent, -(d->rowPosAt(0) + d->rowSize() - d->highlightRangeEnd)); + } + return extent; } qreal QDeclarativeGridView::maxXExtent() const @@ -1714,70 +1937,32 @@ qreal QDeclarativeGridView::maxXExtent() const Q_D(const QDeclarativeGridView); if (d->flow == QDeclarativeGridView::LeftToRight) return QDeclarativeFlickable::maxXExtent(); - else - return maxExtent(); -} - -void QDeclarativeGridView::viewportAboutToMove(QPointF newPos) -{ - Q_D(QDeclarativeGridView); - - // need to refill before moving - if (d->flow == LeftToRight) - d->refill(newPos.y(), newPos.y() + height() - 1); - else - d->refill(newPos.x(), newPos.x() + width() - 1); - - d->lazyRelease = true; - - if (isFlickingHorizontally()) { - if (horizontalVelocity() > 0) - d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore; - else if (horizontalVelocity() < 0) - d->bufferMode = QDeclarativeGridViewPrivate::BufferAfter; - - } else if (isFlickingVertically()) { - if (verticalVelocity() > 0) - d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore; - else if (verticalVelocity() < 0) - d->bufferMode = QDeclarativeGridViewPrivate::BufferAfter; - } - - if (d->isUserGenerated) - d->moveReason = QDeclarativeGridViewPrivate::Mouse; - - if (d->haveHighlightRange && d->highlight && d->highlightRange == StrictlyEnforceRange) { - - d->highlightXAnimator->stop(); - d->highlightYAnimator->stop(); - - // reposition highlight - qreal pos = d->highlight->rowPos(); - qreal viewPos = (d->flow == QDeclarativeGridView::LeftToRight) ? newPos.y() : newPos.x(); - if (pos > viewPos + d->highlightRangeEnd - d->rowSize()) - pos = viewPos + d->highlightRangeEnd - d->rowSize(); - if (pos < viewPos + d->highlightRangeStart) - pos = viewPos + d->highlightRangeStart; - d->highlight->setPosition(d->highlight->colPos(), pos); - - // update current index - if (d->moveReason != QDeclarativeGridViewPrivate::SetIndex) { - int idx = d->snapIndex(); - if (idx >= 0 && idx != d->currentIndex) { - d->setCurrentIndex(idx); - } - } + qreal extent; + if (!d->model || !d->model->count()) { + extent = 0; + } if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + extent = -(d->rowPosAt(d->model->count()-1) - d->highlightRangeStart); + if (d->highlightRangeEnd != d->highlightRangeStart) + extent = qMin(extent, -(d->endPosition() - d->highlightRangeEnd + 1)); + } else { + extent = -(d->endPosition() - width()); } + if (d->footer) + extent -= d->footer->item->width(); + const qreal minX = minXExtent(); + if (extent > minX) + extent = minX; + return extent; } void QDeclarativeGridView::keyPressEvent(QKeyEvent *event) { Q_D(QDeclarativeGridView); keyPressPreHandler(event); - if (event->isAccepted()) return; - if (d->model && d->modelCount && d->interactive) { + if (d->model && d->model->count() && d->interactive) { + d->moveReason = QDeclarativeGridViewPrivate::SetIndex; int oldCurrent = currentIndex(); switch (event->key()) { case Qt::Key_Up: @@ -1800,6 +1985,7 @@ void QDeclarativeGridView::keyPressEvent(QKeyEvent *event) return; } } + d->moveReason = QDeclarativeGridViewPrivate::Other; event->ignore(); QDeclarativeFlickable::keyPressEvent(event); } @@ -1816,7 +2002,7 @@ void QDeclarativeGridView::keyPressEvent(QKeyEvent *event) void QDeclarativeGridView::moveCurrentIndexUp() { Q_D(QDeclarativeGridView); - const int count = d->modelCount; + const int count = d->model ? d->model->count() : 0; if (!count) return; if (d->flow == QDeclarativeGridView::LeftToRight) { @@ -1844,7 +2030,7 @@ void QDeclarativeGridView::moveCurrentIndexUp() void QDeclarativeGridView::moveCurrentIndexDown() { Q_D(QDeclarativeGridView); - const int count = d->modelCount; + const int count = d->model ? d->model->count() : 0; if (!count) return; if (d->flow == QDeclarativeGridView::LeftToRight) { @@ -1872,7 +2058,7 @@ void QDeclarativeGridView::moveCurrentIndexDown() void QDeclarativeGridView::moveCurrentIndexLeft() { Q_D(QDeclarativeGridView); - const int count = d->modelCount; + const int count = d->model ? d->model->count() : 0; if (!count) return; if (d->flow == QDeclarativeGridView::LeftToRight) { @@ -1900,7 +2086,7 @@ void QDeclarativeGridView::moveCurrentIndexLeft() void QDeclarativeGridView::moveCurrentIndexRight() { Q_D(QDeclarativeGridView); - const int count = d->modelCount; + const int count = d->model ? d->model->count() : 0; if (!count) return; if (d->flow == QDeclarativeGridView::LeftToRight) { @@ -1951,7 +2137,7 @@ void QDeclarativeGridView::moveCurrentIndexRight() void QDeclarativeGridView::positionViewAtIndex(int index, int mode) { Q_D(QDeclarativeGridView); - if (!d->isValid() || index < 0 || index >= d->modelCount) + if (!d->isValid() || index < 0 || index >= d->model->count()) return; if (mode < Beginning || mode > Contain) return; @@ -1996,12 +2182,15 @@ void QDeclarativeGridView::positionViewAtIndex(int index, int mode) if (itemPos < pos) pos = itemPos; } - pos += d->headerSize(); - pos = qMin(pos, maxExtent() - d->size()); - pos = qMax(pos, minExtent()); + qreal maxExtent = d->flow == QDeclarativeGridView::LeftToRight ? -maxYExtent() : -maxXExtent(); + pos = qMin(pos, maxExtent); + qreal minExtent = d->flow == QDeclarativeGridView::LeftToRight ? -minYExtent() : -minXExtent(); + pos = qMax(pos, minExtent); d->moveReason = QDeclarativeGridViewPrivate::Other; + cancelFlick(); d->setPosition(pos); } + d->fixupPosition(); } /*! @@ -2032,43 +2221,95 @@ void QDeclarativeGridView::componentComplete() { Q_D(QDeclarativeGridView); QDeclarativeFlickable::componentComplete(); - d->layout(); + d->updateGrid(); if (d->isValid()) { refill(); d->moveReason = QDeclarativeGridViewPrivate::SetIndex; if (d->currentIndex < 0 && !d->currentIndexCleared) - d->setCurrentIndex(0); + d->updateCurrent(0); else - d->setCurrentIndex(d->currentIndex); + d->updateCurrent(d->currentIndex); if (d->highlight && d->currentItem) { d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); + d->updateTrackedItem(); } - d->updateHighlight(false); + d->moveReason = QDeclarativeGridViewPrivate::Other; + d->fixupPosition(); } } -void QDeclarativeGridView::itemsInserted(int modelIndex, int count) +void QDeclarativeGridView::trackedPositionChanged() { Q_D(QDeclarativeGridView); - - if (!isComponentComplete()) { - d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count + if (!d->trackedItem || !d->currentItem) return; + if (d->moveReason == QDeclarativeGridViewPrivate::SetIndex) { + const qreal trackedPos = d->trackedItem->rowPos(); + const qreal viewPos = d->position(); + qreal pos = viewPos; + if (d->haveHighlightRange) { + if (d->highlightRange == StrictlyEnforceRange) { + if (trackedPos > pos + d->highlightRangeEnd - d->rowSize()) + pos = trackedPos - d->highlightRangeEnd + d->rowSize(); + if (trackedPos < pos + d->highlightRangeStart) + pos = trackedPos - d->highlightRangeStart; + } else { + if (trackedPos < d->startPosition() + d->highlightRangeStart) { + pos = d->startPosition(); + } else if (d->trackedItem->endRowPos() > d->endPosition() - d->size() + d->highlightRangeEnd) { + pos = d->endPosition() - d->size() + 1; + if (pos < d->startPosition()) + pos = d->startPosition(); + } else { + if (trackedPos < viewPos + d->highlightRangeStart) { + pos = trackedPos - d->highlightRangeStart; + } else if (trackedPos > viewPos + d->highlightRangeEnd - d->rowSize()) { + pos = trackedPos - d->highlightRangeEnd + d->rowSize(); + } + } + } + } else { + if (trackedPos < viewPos && d->currentItem->rowPos() < viewPos) { + pos = d->currentItem->rowPos() < trackedPos ? trackedPos : d->currentItem->rowPos(); + } else if (d->trackedItem->endRowPos() >= viewPos + d->size() + && d->currentItem->endRowPos() >= viewPos + d->size()) { + if (d->trackedItem->endRowPos() <= d->currentItem->endRowPos()) { + pos = d->trackedItem->endRowPos() - d->size() + 1; + if (d->rowSize() > d->size()) + pos = trackedPos; + } else { + pos = d->currentItem->endRowPos() - d->size() + 1; + if (d->rowSize() > d->size()) + pos = d->currentItem->rowPos(); + } + } + } + if (viewPos != pos) { + cancelFlick(); + d->calcVelocity = true; + d->setPosition(pos); + d->calcVelocity = false; + } } +} - d->moveReason = QDeclarativeGridViewPrivate::Other; +void QDeclarativeGridView::itemsInserted(int modelIndex, int count) +{ + Q_D(QDeclarativeGridView); + if (!isComponentComplete()) + return; if (!d->visibleItems.count() || d->model->count() <= 1) { d->scheduleLayout(); - if (d->modelCount && d->currentIndex >= modelIndex) { + if (d->itemCount && d->currentIndex >= modelIndex) { // adjust current item index d->currentIndex += count; if (d->currentItem) d->currentItem->index = d->currentIndex; emit currentIndexChanged(); } else if (!d->currentIndex || (d->currentIndex < 0 && !d->currentIndexCleared)) { - d->setCurrentIndex(0); + d->updateCurrent(0); } - d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count + d->itemCount += count; emit countChanged(); return; } @@ -2099,7 +2340,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) emit currentIndexChanged(); } d->scheduleLayout(); - d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count + d->itemCount += count; emit countChanged(); return; } @@ -2173,7 +2414,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) } } - if (d->modelCount && d->currentIndex >= modelIndex) { + if (d->itemCount && d->currentIndex >= modelIndex) { // adjust current item index d->currentIndex += count; if (d->currentItem) { @@ -2187,17 +2428,17 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count) for (int j = 0; j < added.count(); ++j) added.at(j)->attached->emitAdd(); - d->modelCount += count; + d->itemCount += count; emit countChanged(); } void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) { Q_D(QDeclarativeGridView); - d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count if (!isComponentComplete()) return; + d->itemCount -= count; bool currentRemoved = d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count; bool removedVisible = false; @@ -2245,8 +2486,8 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) d->releaseItem(d->currentItem); d->currentItem = 0; d->currentIndex = -1; - if (d->modelCount) - d->setCurrentIndex(qMin(modelIndex, d->modelCount-1)); + if (d->itemCount) + d->updateCurrent(qMin(modelIndex, d->itemCount-1)); } // update visibleIndex @@ -2259,7 +2500,13 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) } if (removedVisible && d->visibleItems.isEmpty()) { + d->timeline.clear(); + if (d->itemCount == 0) { d->setPosition(0); + d->updateHeader(); + d->updateFooter(); + update(); + } } emit countChanged(); @@ -2387,13 +2634,14 @@ void QDeclarativeGridView::modelReset() { Q_D(QDeclarativeGridView); d->clear(); - d->modelCount = d->model->count(); refill(); d->moveReason = QDeclarativeGridViewPrivate::SetIndex; - d->setCurrentIndex(d->currentIndex); + d->updateCurrent(d->currentIndex); if (d->highlight && d->currentItem) { d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); + d->updateTrackedItem(); } + d->moveReason = QDeclarativeGridViewPrivate::Other; emit countChanged(); } @@ -2418,6 +2666,14 @@ void QDeclarativeGridView::destroyingItem(QDeclarativeItem *item) d->unrequestedItems.remove(item); } +void QDeclarativeGridView::animStopped() +{ + Q_D(QDeclarativeGridView); + d->bufferMode = QDeclarativeGridViewPrivate::NoBuffer; + if (d->haveHighlightRange && d->highlightRange == QDeclarativeGridView::StrictlyEnforceRange) + d->updateHighlight(); +} + void QDeclarativeGridView::refill() { Q_D(QDeclarativeGridView); diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h index 22407f4..ee632b1 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview_p.h +++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h @@ -188,22 +188,18 @@ Q_SIGNALS: void headerChanged(); void footerChanged(); -protected Q_SLOTS: - void scrollerStateChanged(QScroller::State state); - protected: virtual bool event(QEvent *event); - virtual qreal minExtent() const; - virtual qreal maxExtent() const; + virtual void viewportMoved(); virtual qreal minYExtent() const; virtual qreal maxYExtent() const; virtual qreal minXExtent() const; virtual qreal maxXExtent() const; - virtual void viewportAboutToMove(QPointF newPos); virtual void keyPressEvent(QKeyEvent *); virtual void componentComplete(); private Q_SLOTS: + void trackedPositionChanged(); void itemsInserted(int index, int count); void itemsRemoved(int index, int count); void itemsMoved(int from, int to, int count); @@ -211,6 +207,7 @@ private Q_SLOTS: void destroyRemoved(); void createdItem(int index, QDeclarativeItem *item); void destroyingItem(QDeclarativeItem *item); + void animStopped(); private: void refill(); diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 27f7b52..450b6af 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -56,11 +56,6 @@ QT_BEGIN_NAMESPACE -template static const T &forceConst(const T &t) -{ - return t; -} - void QDeclarativeViewSection::setProperty(const QString &property) { if (property != m_property) { @@ -98,62 +93,40 @@ QString QDeclarativeViewSection::sectionString(const QString &value) class FxListItem { public: - FxListItem(QDeclarativeItem *i, QDeclarativeListView *v) - : item(i), section(0), view(v) - { + FxListItem(QDeclarativeItem *i, QDeclarativeListView *v) : item(i), section(0), view(v) { attached = static_cast(qmlAttachedPropertiesObject(item)); if (attached) attached->setView(view); } - ~FxListItem() {} - - /*! /internal - The position of the item plus section header. - */ qreal position() const { if (section) return (view->orientation() == QDeclarativeListView::Vertical ? section->y() : section->x()); else return (view->orientation() == QDeclarativeListView::Vertical ? item->y() : item->x()); } - - /*! /internal - The position of the item itself - */ qreal itemPosition() const { return (view->orientation() == QDeclarativeListView::Vertical ? item->y() : item->x()); } - - /*! /internal - The size of the item plus section header. - */ qreal size() const { if (section) return (view->orientation() == QDeclarativeListView::Vertical ? item->height()+section->height() : item->width()+section->width()); else return (view->orientation() == QDeclarativeListView::Vertical ? item->height() : item->width()); } - - /*! /internal - The size of the item itself - */ qreal itemSize() const { return (view->orientation() == QDeclarativeListView::Vertical ? item->height() : item->width()); } - qreal sectionSize() const { if (section) return (view->orientation() == QDeclarativeListView::Vertical ? section->height() : section->width()); return 0.0; } - qreal endPosition() const { return (view->orientation() == QDeclarativeListView::Vertical ? item->y() + (item->height() >= 1.0 ? item->height() : 1) : item->x() + (item->width() >= 1.0 ? item->width() : 1)) - 1; } - void setPosition(qreal pos) { if (view->orientation() == QDeclarativeListView::Vertical) { if (section) { @@ -169,14 +142,12 @@ public: item->setX(pos); } } - void setSize(qreal size) { if (view->orientation() == QDeclarativeListView::Vertical) item->setHeight(size); else item->setWidth(size); } - bool contains(int x, int y) const { return (x >= item->x() && x < item->x() + item->width() && y >= item->y() && y < item->y() + item->height()); @@ -200,22 +171,19 @@ public: : currentItem(0), orient(QDeclarativeListView::Vertical) , visiblePos(0), visibleIndex(0) , averageSize(100.0), currentIndex(-1), requestedIndex(-1) - , modelCount(0) - , highlightRangeStart(0), highlightRangeEnd(0) - , highlightComponent(0), highlight(0) + , itemCount(0), highlightRangeStart(0), highlightRangeEnd(0) + , highlightComponent(0), highlight(0), trackedItem(0) , moveReason(Other), buffer(0), highlightPosAnimator(0), highlightSizeAnimator(0) , sectionCriteria(0), spacing(0.0) , highlightMoveSpeed(400), highlightMoveDuration(-1) , highlightResizeSpeed(400), highlightResizeDuration(-1), highlightRange(QDeclarativeListView::NoHighlightRange) - , snapMode(QDeclarativeListView::NoSnap) - , footerComponent(0), footer(0) - , headerComponent(0), header(0) + , snapMode(QDeclarativeListView::NoSnap), overshootDist(0.0) + , footerComponent(0), footer(0), headerComponent(0), header(0) , bufferMode(BufferBefore | BufferAfter) , ownModel(false), wrap(false), autoHighlight(true), haveHighlightRange(false) - , lazyRelease(false) - , deferredRelease(false) - , layoutScheduled(false) - , currentIndexCleared(false) + , correctFlick(false), inFlickCorrection(false), lazyRelease(false) + , deferredRelease(false), layoutScheduled(false), currentIndexCleared(false) + , inViewportMoved(false) , minExtentDirty(true), maxExtentDirty(true) {} @@ -260,25 +228,10 @@ public: return 0; } - /*! \internal - Returns the last visible model index. delayRemove items are not counted (as they don't have an index) - */ - int lastVisibleIndex() const - { - // find the last valid model index - for (int i = visibleItems.count() - 1; i >= 0; --i) { - FxListItem *item = visibleItems.at(i); - if (item->index != -1) - return item->index; - } - return visibleIndex; - } - qreal position() const { Q_Q(const QDeclarativeListView); return orient == QDeclarativeListView::Vertical ? q->contentY() : q->contentX(); } - void setPosition(qreal pos) { Q_Q(QDeclarativeListView); if (orient == QDeclarativeListView::Vertical) @@ -286,53 +239,33 @@ public: else q->QDeclarativeFlickable::setContentX(pos); } - - void scrollToPosition(qreal pos) { - Q_Q(QDeclarativeListView); - if (orient == QDeclarativeListView::Vertical) - QScroller::scroller(q)->scrollTo(QPointF(q->contentX(), pos)); - else - QScroller::scroller(q)->scrollTo(QPointF(pos, q->contentY())); - } - qreal size() const { Q_Q(const QDeclarativeListView); return orient == QDeclarativeListView::Vertical ? q->height() : q->width(); } - /*! /internal - Estimates the current position of the first visible item counting the header (the first item starts at position header->size()). - */ qreal startPosition() const { qreal pos = 0; if (!visibleItems.isEmpty()) { - pos = visibleItems.first()->position(); - pos -= visibleIndex * (averageSize + spacing); + pos = (*visibleItems.constBegin())->position(); + if (visibleIndex > 0) + pos -= visibleIndex * (averageSize + spacing); } - if( header ) - pos -= header->size(); return pos; } - /*! /internal - Estimates the full length of the list including header and footer. - */ qreal endPosition() const { - qreal pos = -1; + qreal pos = 0; if (!visibleItems.isEmpty()) { int invisibleCount = visibleItems.count() - visibleIndex; - for (int i = visibleItems.count()-1; i >= 0; --i) { if (visibleItems.at(i)->index != -1) { - invisibleCount = modelCount - visibleItems.at(i)->index - 1; - pos = visibleItems.at(i)->endPosition(); + invisibleCount = model->count() - visibleItems.at(i)->index - 1; break; } } - pos = visibleItems.last()->endPosition() + invisibleCount * (averageSize + spacing); + pos = (*(--visibleItems.constEnd()))->endPosition() + invisibleCount * (averageSize + spacing); } - if (footer) - pos += footer->size(); return pos; } @@ -347,10 +280,17 @@ public: cs = currentItem->size() + spacing; --count; } - return forceConst(visibleItems).first()->position() - count * (averageSize + spacing) - cs; + return (*visibleItems.constBegin())->position() - count * (averageSize + spacing) - cs; } else { - int count = modelIndex - lastVisibleIndex() - 1; - return forceConst(visibleItems).last()->endPosition() + spacing + count * (averageSize + spacing) + 1; + int idx = visibleItems.count() - 1; + while (idx >= 0 && visibleItems.at(idx)->index == -1) + --idx; + if (idx < 0) + idx = visibleIndex; + else + idx = visibleItems.at(idx)->index; + int count = modelIndex - idx - 1; + return (*(--visibleItems.constEnd()))->endPosition() + spacing + count * (averageSize + spacing) + 1; } } return 0; @@ -362,10 +302,17 @@ public: if (!visibleItems.isEmpty()) { if (modelIndex < visibleIndex) { int count = visibleIndex - modelIndex; - return forceConst(visibleItems).first()->position() - (count - 1) * (averageSize + spacing) - spacing - 1; + return (*visibleItems.constBegin())->position() - (count - 1) * (averageSize + spacing) - spacing - 1; } else { - int count = modelIndex - lastVisibleIndex() - 1; - return forceConst(visibleItems).last()->endPosition() + count * (averageSize + spacing); + int idx = visibleItems.count() - 1; + while (idx >= 0 && visibleItems.at(idx)->index == -1) + --idx; + if (idx < 0) + idx = visibleIndex; + else + idx = visibleItems.at(idx)->index; + int count = modelIndex - idx - 1; + return (*(--visibleItems.constEnd()))->endPosition() + count * (averageSize + spacing); } } return 0; @@ -385,32 +332,52 @@ public: } bool isValid() const { - return model && modelCount && model->isValid(); + return model && model->count() && model->isValid(); } - /** \internal - Returns the index of the item which is at or around the highlight. - */ - int snapIndex() { - int index = currentIndex; + qreal snapPosAt(qreal pos) { + if (FxListItem *snapItem = snapItemAt(pos)) + return snapItem->position(); + if (visibleItems.count()) { + qreal firstPos = visibleItems.first()->position(); + qreal endPos = visibleItems.last()->position(); + if (pos < firstPos) { + return firstPos - qRound((firstPos - pos) / averageSize) * averageSize; + } else if (pos > endPos) + return endPos + qRound((pos - endPos) / averageSize) * averageSize; + } + return qRound((pos - startPosition()) / averageSize) * averageSize + startPosition(); + } - // qDebug() << "snapIndex" << index << "hp:" << highlight->position() << highlight->size() << "items:" << visibleItems.count(); + FxListItem *snapItemAt(qreal pos) { + FxListItem *snapItem = 0; for (int i = 0; i < visibleItems.count(); ++i) { FxListItem *item = visibleItems[i]; if (item->index == -1) continue; - index = item->index; qreal itemTop = item->position(); - // qDebug() << " "<size(); - if (itemTop + item->size() / 2 > highlight->position()) - return item->index; + if (highlight && itemTop >= pos && item->endPosition() <= pos + highlight->size() - 1) + return item; + if (itemTop+item->size()/2 >= pos && itemTop-item->size()/2 < pos) + snapItem = item; + } + return snapItem; + } + + int lastVisibleIndex() const { + int lastIndex = -1; + for (int i = visibleItems.count()-1; i >= 0; --i) { + FxListItem *listItem = visibleItems.at(i); + if (listItem->index != -1) { + lastIndex = listItem->index; + break; + } } - return index; + return lastIndex; } // map a model index to visibleItems index. - int mapFromModel(int modelIndex) const - { + int mapFromModel(int modelIndex) const { if (modelIndex < visibleIndex || modelIndex >= visibleIndex + visibleItems.count()) return -1; for (int i = 0; i < visibleItems.count(); ++i) { @@ -423,28 +390,22 @@ public: return -1; // Not in visibleList } - void updateViewport() - { + void updateViewport() { Q_Q(QDeclarativeListView); - if (orient == QDeclarativeListView::Vertical) - q->setContentHeight(q->maxExtent() - q->minExtent() + 1); - else - q->setContentWidth(q->maxExtent() - q->minExtent() + 1); + if (orient == QDeclarativeListView::Vertical) { + q->setContentHeight(endPosition() - startPosition() + 1); + } else { + q->setContentWidth(endPosition() - startPosition() + 1); + } } - void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) - { - - // qDebug() << "itemGeometryChanged" << newGeometry; - - // Q_Q(QDeclarativeListView); + void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) { + Q_Q(QDeclarativeListView); QDeclarativeFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry); if (item != contentItem && (!highlight || item != highlight->item)) { if ((orient == QDeclarativeListView::Vertical && newGeometry.height() != oldGeometry.height()) || (orient == QDeclarativeListView::Horizontal && newGeometry.width() != oldGeometry.width())) { scheduleLayout(); - minExtentDirty = true; - maxExtentDirty = true; } } if ((header && header->item == item) || (footer && footer->item == item)) { @@ -453,6 +414,8 @@ public: } if (currentItem && currentItem->item == item) updateHighlight(); + if (trackedItem && trackedItem->item == item) + q->trackedPositionChanged(); } // for debugging only @@ -473,60 +436,40 @@ public: void layout(); void updateUnrequestedIndexes(); void updateUnrequestedPositions(); - void recreateHighlight(); - void updateHighlight(bool smooth = true); + void updateTrackedItem(); + void createHighlight(); + void updateHighlight(); void createSection(FxListItem *); void updateSections(); void updateCurrentSection(); - void setCurrentIndex(int); + void updateCurrent(int); void updateAverage(); void updateHeader(); void updateFooter(); + void fixupPosition(); + virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent); + virtual void flick(QDeclarativeFlickablePrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, + QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity); QDeclarativeGuard model; QVariant modelVariant; QList visibleItems; - - /* - These are items that were not requested but send by createdItem from the model. - Usually these items were created because another view showing the same model - needed them. - */ QHash unrequestedItems; - FxListItem *currentItem; QDeclarativeListView::Orientation orient; - - /* - This is the position of the first visible item. - It is stored in case when all items are deleted and we need to create new - ones. - */ qreal visiblePos; - - /* - The visibleIndex is the modelIndex of the first item in visibleItems with an index != -1 - */ int visibleIndex; qreal averageSize; - int currentIndex; // the model index of the currentItem - - /* - The model index of the item that is currently created via createItem - */ + int currentIndex; int requestedIndex; - - /* - This is the number of items in the model. - */ - int modelCount; - + int itemCount; qreal highlightRangeStart; qreal highlightRangeEnd; QDeclarativeComponent *highlightComponent; FxListItem *highlight; + FxListItem *trackedItem; enum MovementReason { Other, SetIndex, Mouse }; - MovementReason moveReason; // the moveReason determines if the highlight needs to be centered or if the currentItem needs to be changed. + MovementReason moveReason; int buffer; QSmoothedAnimation *highlightPosAnimator; QSmoothedAnimation *highlightSizeAnimator; @@ -541,6 +484,7 @@ public: int highlightResizeDuration; QDeclarativeListView::HighlightRangeMode highlightRange; QDeclarativeListView::SnapMode snapMode; + qreal overshootDist; QDeclarativeComponent *footerComponent; FxListItem *footer; QDeclarativeComponent *headerComponent; @@ -554,10 +498,13 @@ public: bool wrap : 1; bool autoHighlight : 1; bool haveHighlightRange : 1; + bool correctFlick : 1; + bool inFlickCorrection : 1; bool lazyRelease : 1; bool deferredRelease : 1; bool layoutScheduled : 1; bool currentIndexCleared : 1; + bool inViewportMoved : 1; mutable bool minExtentDirty : 1; mutable bool maxExtentDirty : 1; }; @@ -567,12 +514,14 @@ void QDeclarativeListViewPrivate::init() Q_Q(QDeclarativeListView); q->setFlag(QGraphicsItem::ItemIsFocusScope); addItemChangeListener(this, Geometry); + QObject::connect(q, SIGNAL(movementEnded()), q, SLOT(animStopped())); q->setFlickableDirection(QDeclarativeFlickable::VerticalFlick); ::memset(sectionCache, 0, sizeof(QDeclarativeItem*) * sectionCacheSize); } void QDeclarativeListViewPrivate::clear() { + timeline.clear(); for (int i = 0; i < visibleItems.count(); ++i) releaseItem(visibleItems.at(i)); visibleItems.clear(); @@ -584,20 +533,13 @@ void QDeclarativeListViewPrivate::clear() visibleIndex = 0; releaseItem(currentItem); currentItem = 0; - recreateHighlight(); + createHighlight(); + trackedItem = 0; minExtentDirty = true; maxExtentDirty = true; - modelCount = 0; - - setPosition(0); - updateHeader(); - updateFooter(); + itemCount = 0; } -/** \internal - Tries to create the FxListItem for the given model index. - \returns the item or 0 if the item could not be created. -*/ FxListItem *QDeclarativeListViewPrivate::createItem(int modelIndex) { Q_Q(QDeclarativeListView); @@ -617,16 +559,13 @@ FxListItem *QDeclarativeListViewPrivate::createItem(int modelIndex) else listItem->attached->m_prevSection = sectionAt(modelIndex-1); } - if (modelIndex < modelCount - 1) { + if (modelIndex < model->count()-1) { if (FxListItem *item = visibleItem(modelIndex+1)) listItem->attached->m_nextSection = item->attached->section(); else listItem->attached->m_nextSection = sectionAt(modelIndex+1); } } - - // qDebug() << "createItem"<completePending()) { // complete listItem->item->setZValue(1); @@ -653,10 +592,9 @@ void QDeclarativeListViewPrivate::releaseItem(FxListItem *item) Q_Q(QDeclarativeListView); if (!item || !model) return; + if (trackedItem == item) + trackedItem = 0; QDeclarativeItemPrivate *itemPrivate = static_cast(QGraphicsItemPrivate::get(item->item)); - - // qDebug() << "releaseItem"<<(currentItem==item?"current":(highlight==item?"highlight":"normal"))<index<<"at"<< item->position(); - itemPrivate->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry); if (model->release(item->item) == 0) { // item was not destroyed, and we no longer reference it. @@ -678,20 +616,12 @@ void QDeclarativeListViewPrivate::releaseItem(FxListItem *item) delete item; } -/** \internal - Updates the visible items so that they cover the from and to range. - updateViewport should be called afterwards to handle cases where - the viewport size is changed by different sized items. -*/ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) { Q_Q(QDeclarativeListView); if (!isValid() || !q->isComponentComplete()) return; - - if (!doBuffer && buffer && bufferMode != NoBuffer) - doBuffer = true; - + itemCount = model->count(); qreal bufferFrom = from - buffer; qreal bufferTo = to + buffer; qreal fillFrom = from; @@ -701,55 +631,34 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) if (doBuffer && (bufferMode & BufferBefore)) fillFrom = bufferFrom; - bool changed = false; - - // -- layout the items + int modelIndex = visibleIndex; + qreal itemEnd = visiblePos-1; if (!visibleItems.isEmpty()) { - qreal oldEnd = forceConst(visibleItems).last()->endPosition(); - qreal pos = forceConst(visibleItems).first()->position() + forceConst(visibleItems).first()->size() + spacing; - for (int i=1; i < visibleItems.count(); ++i) { - FxListItem *item = visibleItems.at(i); - if (item->position() != pos) { - // qDebug() << "Moved item"<position()<<"to"<setPosition(pos); - // changed = true; - } - pos += item->size() + spacing; - } - // move current item if it is after the visible items. - if (currentItem && currentIndex > lastVisibleIndex()) - currentItem->setPosition(currentItem->position() + (forceConst(visibleItems).last()->endPosition() - oldEnd)); - } - - qreal endPos = visiblePos; - int modelIndex = lastVisibleIndex(); - if (!visibleItems.isEmpty()) { - endPos = forceConst(visibleItems).last()->endPosition() + spacing + 1; - modelIndex++; + visiblePos = (*visibleItems.constBegin())->position(); + itemEnd = (*(--visibleItems.constEnd()))->endPosition() + spacing; + int i = visibleItems.count() - 1; + while (i > 0 && visibleItems.at(i)->index == -1) + --i; + modelIndex = visibleItems.at(i)->index + 1; } - // qDebug() << "REFILL: from" << from << "to" << to << "doBuffer" << doBuffer << "visiblePos" << visiblePos << "endPos" << endPos << "lvindex" << lastVisibleIndex() << "mindex" << modelIndex; - - + bool changed = false; FxListItem *item = 0; - - // -- add items to the back - while (modelIndex < modelCount && endPos <= fillTo) { - // qDebug() << "refill: append item" << modelIndex << "endPos" << endPos; + qreal pos = itemEnd + 1; + while (modelIndex < model->count() && pos <= fillTo) { +// qDebug() << "refill: append item" << modelIndex << "pos" << pos; if (!(item = createItem(modelIndex))) break; - item->setPosition(endPos); - endPos += item->size() + spacing; + item->setPosition(pos); + pos += item->size() + spacing; visibleItems.append(item); ++modelIndex; changed = true; if (doBuffer) // never buffer more than one item per frame break; } - - // -- add items to the front - while (visibleIndex > 0 && visibleIndex <= modelCount && visiblePos-1 >= fillFrom) { - // qDebug() << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos; + while (visibleIndex > 0 && visibleIndex <= model->count() && visiblePos-1 >= fillFrom) { +// qDebug() << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos; if (!(item = createItem(visibleIndex-1))) break; --visibleIndex; @@ -761,56 +670,35 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) break; } - // TODO: why do we need deferredRelease? Only release every second frame? if (!lazyRelease || !changed || deferredRelease) { // avoid destroying items in the same frame that we create - if (visibleItems.count() > 1) { - // only delete items if we have more than could be visible - if (forceConst(visibleItems).last()->endPosition() - forceConst(visibleItems).first()->position() > size() ) { - while (!visibleItems.isEmpty() && - (item = forceConst(visibleItems).first()) && item->endPosition() < bufferFrom) { - if (item->attached->delayRemove()) - break; - // qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endPosition(); - if (item->index != -1) - { - visibleIndex++; - // visiblePos += item->size() + spacing; - } - visibleItems.removeFirst(); - releaseItem(item); - changed = true; - } - while (!visibleItems.isEmpty() && - (item = forceConst(visibleItems).last()) && item->position() > bufferTo) { - if (item->attached->delayRemove()) - break; - // qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position(); - if (item->index != -1) - { - // endPos -= item->size() + spacing; - } - visibleItems.removeLast(); - releaseItem(item); - changed = true; - } - } + while (visibleItems.count() > 1 && (item = visibleItems.first()) && item->endPosition() < bufferFrom) { + if (item->attached->delayRemove()) + break; +// qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endPosition(); + if (item->index != -1) + visibleIndex++; + visibleItems.removeFirst(); + releaseItem(item); + changed = true; + } + while (visibleItems.count() > 1 && (item = visibleItems.last()) && item->position() > bufferTo) { + if (item->attached->delayRemove()) + break; +// qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position(); + visibleItems.removeLast(); + releaseItem(item); + changed = true; } deferredRelease = false; } else { deferredRelease = true; } - - - if (changed) { - // qDebug()<<"REFILLED: from" << from << "to" << to << "fillFrom" << fillFrom << "fillTo" << fillTo << "endPos:" << endPos << "buffer" << buffer; minExtentDirty = true; maxExtentDirty = true; if (visibleItems.count()) - visiblePos = forceConst(visibleItems).first()->position(); + visiblePos = (*visibleItems.constBegin())->position(); updateAverage(); - - // update the highlight position in cases where we are estimating it if (currentIndex >= 0 && currentItem && !visibleItem(currentIndex)) { currentItem->setPosition(positionAt(currentIndex)); updateHighlight(); @@ -818,15 +706,16 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) if (sectionCriteria) updateCurrentSection(); - updateUnrequestedPositions(); - updateScrollerValues(); + if (header) + updateHeader(); + if (footer) + updateFooter(); updateViewport(); + updateUnrequestedPositions(); + } else if (!doBuffer && buffer && bufferMode != NoBuffer) { + refill(from, to, true); } lazyRelease = false; - if (header) - updateHeader(); - if (footer) - updateFooter(); } void QDeclarativeListViewPrivate::scheduleLayout() @@ -847,11 +736,31 @@ void QDeclarativeListViewPrivate::layout() setPosition(0); return; } + if (!visibleItems.isEmpty()) { + qreal oldEnd = visibleItems.last()->endPosition(); + qreal pos = visibleItems.first()->position() + visibleItems.first()->size() + spacing; + for (int i=1; i < visibleItems.count(); ++i) { + FxListItem *item = visibleItems.at(i); + item->setPosition(pos); + pos += item->size() + spacing; + } + // move current item if it is after the visible items. + if (currentItem && currentIndex > lastVisibleIndex()) + currentItem->setPosition(currentItem->position() + (visibleItems.last()->endPosition() - oldEnd)); + } q->refill(); - // qDebug() << "highlight1" << currentItem << highlight; + minExtentDirty = true; + maxExtentDirty = true; updateHighlight(); - // qDebug() << "highlight2" << currentItem << highlight; - q->refill(); + if (!q->isMoving() && !q->isFlicking()) { + fixupPosition(); + q->refill(); + } + if (header) + updateHeader(); + if (footer) + updateFooter(); + updateViewport(); } void QDeclarativeListViewPrivate::updateUnrequestedIndexes() @@ -881,13 +790,24 @@ void QDeclarativeListViewPrivate::updateUnrequestedPositions() } } -void QDeclarativeListViewPrivate::recreateHighlight() +void QDeclarativeListViewPrivate::updateTrackedItem() { Q_Q(QDeclarativeListView); + FxListItem *item = currentItem; + if (highlight) + item = highlight; + trackedItem = item; + if (trackedItem) + q->trackedPositionChanged(); +} - // qDebug() << "recreate Highlight"; +void QDeclarativeListViewPrivate::createHighlight() +{ + Q_Q(QDeclarativeListView); bool changed = false; if (highlight) { + if (trackedItem == highlight) + trackedItem = 0; delete highlight->item; delete highlight; highlight = 0; @@ -899,7 +819,6 @@ void QDeclarativeListViewPrivate::recreateHighlight() } if (currentItem) { - // qDebug()<<"new highlight"; QDeclarativeItem *item = 0; if (highlightComponent) { QDeclarativeContext *highlightContext = new QDeclarativeContext(qmlContext(q)); @@ -946,76 +865,29 @@ void QDeclarativeListViewPrivate::recreateHighlight() changed = true; } } - if (changed) { - updateHighlight(); + if (changed) emit q->highlightItemChanged(); - } } -/* - This function will recreate or delete the highlight (depening on the state) and - then try to move it to a correct position. - It will not update the current item (that is done in viewportMoved() - If \c smooth is set to true then all updates will be using an animation. -*/ -void QDeclarativeListViewPrivate::updateHighlight(bool smooth) +void QDeclarativeListViewPrivate::updateHighlight() { - if ((!currentItem && highlight) || (currentItem && !highlight)) - recreateHighlight(); - - // --- move the current item between the highlight range - if (moveReason == QDeclarativeListViewPrivate::SetIndex) { - // ensure that the tracked item is inside the highlight range - - // reposition view - if (currentItem) { - qreal pos = currentItem->position(); - qreal viewPos = position(); - - if (autoHighlight && haveHighlightRange) { - if (pos > viewPos + highlightRangeEnd - currentItem->size()) - viewPos = pos - highlightRangeEnd + currentItem->size(); - if (pos < viewPos + highlightRangeStart) - viewPos = pos - highlightRangeStart; - - } else { - if (pos > viewPos + size() - currentItem->size()) - viewPos = pos - size() + currentItem->size(); - if (pos < viewPos + 0) - viewPos = pos - 0; - } - if (smooth) - scrollToPosition(viewPos); - else - { - setPosition(viewPos); - // qDebug() << "setPos to "<to = currentItem->itemPosition(); - highlightSizeAnimator->to = currentItem->itemSize(); - if (orient == QDeclarativeListView::Vertical) { - if (highlight->item->width() == 0) - highlight->item->setWidth(currentItem->item->width()); - } else { - if (highlight->item->height() == 0) - highlight->item->setHeight(currentItem->item->height()); - } - if (smooth) { - highlightPosAnimator->restart(); - highlightSizeAnimator->restart(); - } else { - highlightPosAnimator->stop(); - highlightSizeAnimator->stop(); - highlight->setPosition(highlightPosAnimator->to); - highlight->setSize(highlightSizeAnimator->to); - } + createHighlight(); + if (currentItem && autoHighlight && highlight && !movingHorizontally && !movingVertically) { + // auto-update highlight + highlightPosAnimator->to = currentItem->itemPosition(); + highlightSizeAnimator->to = currentItem->itemSize(); + if (orient == QDeclarativeListView::Vertical) { + if (highlight->item->width() == 0) + highlight->item->setWidth(currentItem->item->width()); + } else { + if (highlight->item->height() == 0) + highlight->item->setHeight(currentItem->item->height()); } + highlightPosAnimator->restart(); + highlightSizeAnimator->restart(); } + updateTrackedItem(); } void QDeclarativeListViewPrivate::createSection(FxListItem *listItem) @@ -1096,17 +968,14 @@ void QDeclarativeListViewPrivate::updateSections() } } if (prevAtt) { - if (idx > 0 && idx < modelCount - 1) - prevAtt->setNextSection(sectionAt(idx + 1)); + if (idx > 0 && idx < model->count()-1) + prevAtt->setNextSection(sectionAt(idx+1)); else prevAtt->setNextSection(QString()); } } } -/** \internal - Updates the currentSection variable and emits the changed signals. -*/ void QDeclarativeListViewPrivate::updateCurrentSection() { Q_Q(QDeclarativeListView); @@ -1117,7 +986,6 @@ void QDeclarativeListViewPrivate::updateCurrentSection() } return; } - int index = 0; while (index < visibleItems.count() && visibleItems.at(index)->endPosition() < position()) ++index; @@ -1126,56 +994,61 @@ void QDeclarativeListViewPrivate::updateCurrentSection() if (index < visibleItems.count()) newSection = visibleItems.at(index)->attached->section(); else - newSection = forceConst(visibleItems).first()->attached->section(); + newSection = visibleItems.first()->attached->section(); if (newSection != currentSection) { currentSection = newSection; emit q->currentSectionChanged(); } } -void QDeclarativeListViewPrivate::setCurrentIndex(int newIndex) +void QDeclarativeListViewPrivate::updateCurrent(int modelIndex) { Q_Q(QDeclarativeListView); - - // --- release the old item - if (currentItem && currentIndex != newIndex) { - currentItem->attached->setIsCurrentItem(false); - releaseItem(currentItem); - currentItem = 0; - } - - int oldIndex = currentIndex; - currentIndex = newIndex; - - bool visible = (q->isComponentComplete() && isValid() && !currentItem && - newIndex >= 0 && newIndex < modelCount); - - // --- set the new item - if (visible) { - currentItem = createItem(currentIndex); + if (!q->isComponentComplete() || !isValid() || modelIndex < 0 || modelIndex >= model->count()) { if (currentItem) { - if (currentIndex == visibleIndex - 1 && visibleItems.count()) { - // We can calculate exact postion in this case - currentItem->setPosition(forceConst(visibleItems).first()->position() - currentItem->size() - spacing); - } else { - // Create current item now and position as best we can. - // Its position will be corrected when it becomes visible. - currentItem->setPosition(positionAt(currentIndex)); - } - currentItem->item->setFocus(true); - currentItem->attached->setIsCurrentItem(true); - // Avoid showing section delegate twice. We still need the section heading so that - // currentItem positioning works correctly. - // This is slightly sub-optimal, but section heading caching minimizes the impact. - if (currentItem->section) - currentItem->section->setVisible(false); + currentItem->attached->setIsCurrentItem(false); + releaseItem(currentItem); + currentItem = 0; + currentIndex = modelIndex; + emit q->currentIndexChanged(); + updateHighlight(); + } else if (currentIndex != modelIndex) { + currentIndex = modelIndex; + emit q->currentIndexChanged(); } + return; } - updateHighlight(visible); - - if (currentIndex != oldIndex) - emit q->currentIndexChanged(); + if (currentItem && currentIndex == modelIndex) { + updateHighlight(); + return; + } + FxListItem *oldCurrentItem = currentItem; + currentIndex = modelIndex; + currentItem = createItem(modelIndex); + if (oldCurrentItem && (!currentItem || oldCurrentItem->item != currentItem->item)) + oldCurrentItem->attached->setIsCurrentItem(false); + if (currentItem) { + if (modelIndex == visibleIndex - 1 && visibleItems.count()) { + // We can calculate exact postion in this case + currentItem->setPosition(visibleItems.first()->position() - currentItem->size() - spacing); + } else { + // Create current item now and position as best we can. + // Its position will be corrected when it becomes visible. + currentItem->setPosition(positionAt(modelIndex)); + } + currentItem->item->setFocus(true); + currentItem->attached->setIsCurrentItem(true); + // Avoid showing section delegate twice. We still need the section heading so that + // currentItem positioning works correctly. + // This is slightly sub-optimal, but section heading caching minimizes the impact. + if (currentItem->section) + currentItem->section->setVisible(false); + } + updateHighlight(); + emit q->currentIndexChanged(); + // Release the old current item + releaseItem(oldCurrentItem); } void QDeclarativeListViewPrivate::updateAverage() @@ -1188,13 +1061,13 @@ void QDeclarativeListViewPrivate::updateAverage() averageSize = qRound(sum / visibleItems.count()); } -void QDeclarativeListViewPrivate::updateHeader() +void QDeclarativeListViewPrivate::updateFooter() { Q_Q(QDeclarativeListView); - if (!header && headerComponent) { + if (!footer && footerComponent) { QDeclarativeItem *item = 0; QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q)); - QObject *nobj = headerComponent->create(context); + QObject *nobj = footerComponent->create(context); if (nobj) { QDeclarative_setParent_noEvent(context, nobj); item = qobject_cast(nobj); @@ -1206,26 +1079,35 @@ void QDeclarativeListViewPrivate::updateHeader() if (item) { QDeclarative_setParent_noEvent(item, q->contentItem()); item->setParentItem(q->contentItem()); - item->setZValue(100); + item->setZValue(1); QDeclarativeItemPrivate *itemPrivate = static_cast(QGraphicsItemPrivate::get(item)); itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); - header = new FxListItem(item, q); - if (!visibleItems.isEmpty()) - visiblePos = header->size(); + footer = new FxListItem(item, q); } } - if (header) { - header->setPosition(startPosition()); + if (footer) { + if (visibleItems.count()) { + qreal endPos = endPosition() + 1; + if (lastVisibleIndex() == model->count()-1) { + footer->setPosition(endPos); + } else { + qreal visiblePos = position() + q->height(); + if (endPos <= visiblePos || footer->position() < endPos) + footer->setPosition(endPos); + } + } else { + footer->setPosition(visiblePos); + } } } -void QDeclarativeListViewPrivate::updateFooter() +void QDeclarativeListViewPrivate::updateHeader() { Q_Q(QDeclarativeListView); - if (!footer && footerComponent) { + if (!header && headerComponent) { QDeclarativeItem *item = 0; QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q)); - QObject *nobj = footerComponent->create(context); + QObject *nobj = headerComponent->create(context); if (nobj) { QDeclarative_setParent_noEvent(context, nobj); item = qobject_cast(nobj); @@ -1240,11 +1122,233 @@ void QDeclarativeListViewPrivate::updateFooter() item->setZValue(1); QDeclarativeItemPrivate *itemPrivate = static_cast(QGraphicsItemPrivate::get(item)); itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); - footer = new FxListItem(item, q); + header = new FxListItem(item, q); + if (visibleItems.isEmpty()) + visiblePos = header->size(); + } + } + if (header) { + if (visibleItems.count()) { + qreal startPos = startPosition(); + if (visibleIndex == 0) { + header->setPosition(startPos - header->size()); + } else { + if (position() <= startPos || header->position() > startPos - header->size()) + header->setPosition(startPos - header->size()); + } + } else { + header->setPosition(0); } } - if (footer) - footer->setPosition(endPosition() + 1 - footer->size()); +} + +void QDeclarativeListViewPrivate::fixupPosition() +{ + if ((haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange) + || snapMode != QDeclarativeListView::NoSnap) + moveReason = Other; + if (orient == QDeclarativeListView::Vertical) + fixupY(); + else + fixupX(); +} + +void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent) +{ + if ((orient == QDeclarativeListView::Horizontal && &data == &vData) + || (orient == QDeclarativeListView::Vertical && &data == &hData)) + return; + + correctFlick = false; + int oldDuration = fixupDuration; + fixupDuration = moveReason == Mouse ? fixupDuration : 0; + + if (currentItem && haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange) { + updateHighlight(); + qreal pos = currentItem->itemPosition(); + qreal viewPos = position(); + if (viewPos < pos + currentItem->itemSize() - highlightRangeEnd) + viewPos = pos + currentItem->itemSize() - highlightRangeEnd; + if (viewPos > pos - highlightRangeStart) + viewPos = pos - highlightRangeStart; + + timeline.reset(data.move); + if (viewPos != position()) { + if (fixupDuration) + timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); + else + timeline.set(data.move, -viewPos); + } + vTime = timeline.time(); + } else if (snapMode != QDeclarativeListView::NoSnap) { + FxListItem *topItem = snapItemAt(position()+highlightRangeStart); + FxListItem *bottomItem = snapItemAt(position()+highlightRangeEnd); + qreal pos; + if (topItem) { + pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent); + } else if (bottomItem) { + pos = qMax(qMin(bottomItem->position() - highlightRangeStart, -maxExtent), -minExtent); + } else { + fixupDuration = oldDuration; + return; + } + + qreal dist = qAbs(data.move + pos); + if (dist > 0) { + timeline.reset(data.move); + if (fixupDuration) + timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); + else + timeline.set(data.move, -pos); + vTime = timeline.time(); + } + } else { + QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent); + } + fixupDuration = oldDuration; +} + +void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, + QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity) +{ + Q_Q(QDeclarativeListView); + + moveReason = Mouse; + if ((!haveHighlightRange || highlightRange != QDeclarativeListView::StrictlyEnforceRange) && snapMode == QDeclarativeListView::NoSnap) { + correctFlick = true; + QDeclarativeFlickablePrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity); + return; + } + qreal maxDistance = 0; + // -ve velocity means list is moving up/left + if (velocity > 0) { + if (data.move.value() < minExtent) { + if (snapMode == QDeclarativeListView::SnapOneItem) { + if (FxListItem *item = firstVisibleItem()) + maxDistance = qAbs(item->position() + data.move.value()); + } else { + maxDistance = qAbs(minExtent - data.move.value()); + } + } + if (snapMode == QDeclarativeListView::NoSnap && highlightRange != QDeclarativeListView::StrictlyEnforceRange) + data.flickTarget = minExtent; + } else { + if (data.move.value() > maxExtent) { + if (snapMode == QDeclarativeListView::SnapOneItem) { + if (FxListItem *item = nextVisibleItem()) + maxDistance = qAbs(item->position() + data.move.value()); + } else { + maxDistance = qAbs(maxExtent - data.move.value()); + } + } + if (snapMode == QDeclarativeListView::NoSnap && highlightRange != QDeclarativeListView::StrictlyEnforceRange) + data.flickTarget = maxExtent; + } + bool overShoot = boundsBehavior == QDeclarativeFlickable::DragAndOvershootBounds; + if (maxDistance > 0 || overShoot) { + // These modes require the list to stop exactly on an item boundary. + // The initial flick will estimate the boundary to stop on. + // Since list items can have variable sizes, the boundary will be + // reevaluated and adjusted as we approach the boundary. + qreal v = velocity; + if (maxVelocity != -1 && maxVelocity < qAbs(v)) { + if (v < 0) + v = -maxVelocity; + else + v = maxVelocity; + } + if (!flickingHorizontally && !flickingVertically) { + // the initial flick - estimate boundary + qreal accel = deceleration; + qreal v2 = v * v; + overshootDist = 0.0; + // + averageSize/4 to encourage moving at least one item in the flick direction + qreal dist = v2 / (accel * 2.0) + averageSize/4; + if (maxDistance > 0) + dist = qMin(dist, maxDistance); + if (v > 0) + dist = -dist; + if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarativeListView::SnapOneItem) { + data.flickTarget = -snapPosAt(-(data.move.value() - highlightRangeStart) + dist) + highlightRangeStart; + if (overShoot) { + if (data.flickTarget >= minExtent) { + overshootDist = overShootDistance(v, vSize); + data.flickTarget += overshootDist; + } else if (data.flickTarget <= maxExtent) { + overshootDist = overShootDistance(v, vSize); + data.flickTarget -= overshootDist; + } + } + qreal adjDist = -data.flickTarget + data.move.value(); + if (qAbs(adjDist) > qAbs(dist)) { + // Prevent painfully slow flicking - adjust velocity to suit flickDeceleration + qreal adjv2 = accel * 2.0f * qAbs(adjDist); + if (adjv2 > v2) { + v2 = adjv2; + v = qSqrt(v2); + if (dist > 0) + v = -v; + } + } + dist = adjDist; + accel = v2 / (2.0f * qAbs(dist)); + } else if (overShoot) { + data.flickTarget = data.move.value() - dist; + if (data.flickTarget >= minExtent) { + overshootDist = overShootDistance(v, vSize); + data.flickTarget += overshootDist; + } else if (data.flickTarget <= maxExtent) { + overshootDist = overShootDistance(v, vSize); + data.flickTarget -= overshootDist; + } + } + timeline.reset(data.move); + timeline.accel(data.move, v, accel, maxDistance + overshootDist); + timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this)); + if (!flickingHorizontally && q->xflick()) { + flickingHorizontally = true; + emit q->flickingChanged(); + emit q->flickingHorizontallyChanged(); + emit q->flickStarted(); + } + if (!flickingVertically && q->yflick()) { + flickingVertically = true; + emit q->flickingChanged(); + emit q->flickingVerticallyChanged(); + emit q->flickStarted(); + } + correctFlick = true; + } else { + // reevaluate the target boundary. + qreal newtarget = data.flickTarget; + if (snapMode != QDeclarativeListView::NoSnap || highlightRange == QDeclarativeListView::StrictlyEnforceRange) + newtarget = -snapPosAt(-(data.flickTarget - highlightRangeStart)) + highlightRangeStart; + if (velocity < 0 && newtarget <= maxExtent) + newtarget = maxExtent - overshootDist; + else if (velocity > 0 && newtarget >= minExtent) + newtarget = minExtent + overshootDist; + if (newtarget == data.flickTarget) { // boundary unchanged - nothing to do + if (qAbs(velocity) < MinimumFlickVelocity) + correctFlick = false; + return; + } + data.flickTarget = newtarget; + qreal dist = -newtarget + data.move.value(); + if ((v < 0 && dist < 0) || (v > 0 && dist > 0)) { + correctFlick = false; + timeline.reset(data.move); + fixup(data, minExtent, maxExtent); + return; + } + timeline.reset(data.move); + timeline.accelDistance(data.move, v, -dist); + timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this)); + } + } else { + correctFlick = false; + timeline.reset(data.move); + fixup(data, minExtent, maxExtent); + } } //---------------------------------------------------------------------------- @@ -1409,10 +1513,10 @@ QVariant QDeclarativeListView::model() const return d->modelVariant; } -void QDeclarativeListView::setModel(const QVariant &newModel) +void QDeclarativeListView::setModel(const QVariant &model) { Q_D(QDeclarativeListView); - if (d->modelVariant == newModel) + if (d->modelVariant == model) return; if (d->model) { disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); @@ -1423,15 +1527,12 @@ void QDeclarativeListView::setModel(const QVariant &newModel) disconnect(d->model, SIGNAL(createdItem(int,QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*))); disconnect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*))); } - d->clear(); QDeclarativeVisualModel *oldModel = d->model; d->model = 0; - d->modelCount = 0; - // d->setPosition(0); // we should do a re-layout and that should do a setViewportHeight and that should check the current position. - - d->modelVariant = newModel; - QObject *object = qvariant_cast(newModel); + d->setPosition(0); + d->modelVariant = model; + QObject *object = qvariant_cast(model); QDeclarativeVisualModel *vim = 0; if (object && (vim = qobject_cast(object))) { if (d->ownModel) { @@ -1447,14 +1548,24 @@ void QDeclarativeListView::setModel(const QVariant &newModel) d->model = oldModel; } if (QDeclarativeVisualDataModel *dataModel = qobject_cast(d->model)) - dataModel->setModel(newModel); + dataModel->setModel(model); } - if (d->model) { - d->modelCount = d->model->count(); d->bufferMode = QDeclarativeListViewPrivate::BufferBefore | QDeclarativeListViewPrivate::BufferAfter; - - //qDebug() << "setModel: " << d->model<<"model:" << isComponentComplete(); + if (isComponentComplete()) { + updateSections(); + refill(); + if ((d->currentIndex >= d->model->count() || d->currentIndex < 0) && !d->currentIndexCleared) { + setCurrentIndex(0); + } else { + d->moveReason = QDeclarativeListViewPrivate::SetIndex; + d->updateCurrent(d->currentIndex); + if (d->highlight && d->currentItem) { + d->highlight->setPosition(d->currentItem->position()); + d->updateTrackedItem(); + } + } + } connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int))); connect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int))); @@ -1464,17 +1575,6 @@ void QDeclarativeListView::setModel(const QVariant &newModel) connect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*))); emit countChanged(); } - - if (isComponentComplete()) { - updateSections(); - refill(); - if ((d->currentIndex < 0 || d->currentIndex >= d->modelCount) && !d->currentIndexCleared) { - setCurrentIndex(0); - } else { - d->setCurrentIndex(d->currentIndex); - } - d->updateViewport(); - } emit modelChanged(); } @@ -1519,11 +1619,9 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) d->model = new QDeclarativeVisualDataModel(qmlContext(this)); d->ownModel = true; } - //qDebug() << "setDelegate" << delegate; if (QDeclarativeVisualDataModel *dataModel = qobject_cast(d->model)) { dataModel->setDelegate(delegate); if (isComponentComplete()) { - // TODO: why not call clear() ? for (int i = 0; i < d->visibleItems.count(); ++i) d->releaseItem(d->visibleItems.at(i)); d->visibleItems.clear(); @@ -1532,15 +1630,13 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) updateSections(); refill(); d->moveReason = QDeclarativeListViewPrivate::SetIndex; - d->setCurrentIndex(d->currentIndex); + d->updateCurrent(d->currentIndex); if (d->highlight && d->currentItem) { d->highlight->setPosition(d->currentItem->position()); + d->updateTrackedItem(); } - d->updateHighlight(); - d->updateViewport(); } } - //qDebug() << "setDelegate current" << d->currentIndex << d->currentItem; emit delegateChanged(); } @@ -1552,10 +1648,10 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) \c currentItem holds the current item. Setting the currentIndex to -1 will clear the highlight and set currentItem to null. - If highlightFollowsCurrentItem is \c true, setting either of these - properties will smoothly scroll the ListView so that the current + If highlightFollowsCurrentItem is \c true, setting either of these + properties will smoothly scroll the ListView so that the current item becomes visible. - + Note that the position of the current item may only be approximate until it becomes visible in the view. */ @@ -1568,17 +1664,14 @@ int QDeclarativeListView::currentIndex() const void QDeclarativeListView::setCurrentIndex(int index) { Q_D(QDeclarativeListView); - if (d->requestedIndex >= 0) // currently creating an item + if (d->requestedIndex >= 0) // currently creating item return; - d->currentIndexCleared = (index == -1); - if (index == d->currentIndex) return; - if (isComponentComplete() && d->isValid()) { d->moveReason = QDeclarativeListViewPrivate::SetIndex; - d->setCurrentIndex(index); + d->updateCurrent(index); } else if (d->currentIndex != index) { d->currentIndex = index; emit currentIndexChanged(); @@ -1618,8 +1711,9 @@ QDeclarativeItem *QDeclarativeListView::highlightItem() int QDeclarativeListView::count() const { Q_D(const QDeclarativeListView); - Q_ASSERT( d->model || d->modelCount == 0 ); - return d->modelCount; + if (d->model) + return d->model->count(); + return 0; } /*! @@ -1644,7 +1738,9 @@ void QDeclarativeListView::setHighlight(QDeclarativeComponent *highlight) Q_D(QDeclarativeListView); if (highlight != d->highlightComponent) { d->highlightComponent = highlight; - d->recreateHighlight(); + d->createHighlight(); + if (d->currentItem) + d->updateHighlight(); emit highlightChanged(); } } @@ -1832,22 +1928,17 @@ void QDeclarativeListView::setOrientation(QDeclarativeListView::Orientation orie setContentHeight(-1); setFlickableDirection(HorizontalFlick); } - - // -- swap the coordinates and then let layout do the final positioning - for (int i = 0; i < d->visibleItems.count(); ++i) - d->visibleItems.at(i)->item->setPos(d->visibleItems.at(i)->item->pos().y(), - d->visibleItems.at(i)->item->pos().x()); - - d->layout(); - d->updateViewport(); + d->clear(); + d->setPosition(0); + refill(); emit orientationChanged(); - d->setCurrentIndex(d->currentIndex); + d->updateCurrent(d->currentIndex); } } /*! \qmlproperty bool ListView::keyNavigationWraps - This property holds whether the list wraps key navigation. + This property holds whether the list wraps key navigation. If this is true, key navigation that would move the current item selection past the end of the list instead wraps around and moves the selection to @@ -1903,7 +1994,6 @@ void QDeclarativeListView::setCacheBuffer(int b) if (isComponentComplete()) { d->bufferMode = QDeclarativeListViewPrivate::BufferBefore | QDeclarativeListViewPrivate::BufferAfter; refill(); - d->updateViewport(); } emit cacheBufferChanged(); } @@ -2092,7 +2182,6 @@ void QDeclarativeListView::setSnapMode(SnapMode mode) if (d->snapMode != mode) { d->snapMode = mode; emit snapModeChanged(); - QScroller::scroller(this)->resendPrepareEvent(); } } @@ -2180,165 +2269,153 @@ void QDeclarativeListView::setContentY(qreal pos) bool QDeclarativeListView::event(QEvent *event) { Q_D(QDeclarativeListView); - - switch (event->type()) { - case QEvent::User: + if (event->type() == QEvent::User) { d->layout(); return true; - - case QEvent::ScrollPrepare: { - QScroller *scroller = QScroller::scroller(this); - qreal snapOffset = 0; - bool forceSnapping = false; - bool useEndPosition = false; - bool ignoreHeaders = false; - - // --- do the highlight range - if (d->haveHighlightRange) { - snapOffset = -d->highlightRangeStart; - ignoreHeaders = true; - } - - // --- now finally do the snap points - QList snapPoints; - // -- snap to every point (SnapToItem) - if (d->snapMode == QDeclarativeListView::SnapToItem || forceSnapping) { - // - snap to begin of item - if (!useEndPosition) { - if (d->header && !ignoreHeaders) - snapPoints.append(d->header->itemPosition() + snapOffset); - foreach (FxListItem *item, d->visibleItems) - snapPoints.append(item->itemPosition() + snapOffset); - if (d->footer && !ignoreHeaders) - snapPoints.append(d->footer->itemPosition() + snapOffset); - - // - snap to end of item - } else { - if (d->header && !ignoreHeaders) - snapPoints.append(d->header->endPosition() + snapOffset); - foreach (FxListItem *item, d->visibleItems) - snapPoints.append(item->endPosition() + snapOffset); - if (d->footer && !ignoreHeaders) - snapPoints.append(d->footer->endPosition() + snapOffset); - } - - // -- snap to the next three point (SnapOneItem) - } else if (d->snapMode == QDeclarativeListView::SnapOneItem) { - // here we just set three snap points around the current position. - // TODO - - // - snap to begin of item - if (!useEndPosition) { - qreal currentSnapPos = (d->positionAt(d->currentIndex) + snapOffset); - if (d->currentIndex > 0) - snapPoints.append(d->positionAt(d->currentIndex - 1) + snapOffset); - snapPoints.append(d->positionAt(d->currentIndex) + snapOffset); - // TODO: don't use last point if we are between two points already - if (d->currentIndex < d->modelCount - 1 && currentSnapPos <= d->position()) - snapPoints.append(d->positionAt(d->currentIndex + 1) + snapOffset); - - // - snap to end of item - } else { - snapPoints.append(d->endPositionAt(d->currentIndex - 1) + 1 + snapOffset); - snapPoints.append(d->endPositionAt(d->currentIndex) + 1 + snapOffset); - // TODO: don't use last point if we are between two points already - snapPoints.append(d->endPositionAt(d->currentIndex + 1) + 1 + snapOffset); - } - } - - if (d->orient == QDeclarativeListView::Vertical) { - scroller->setSnapPositionsX(0.0, 0.0); - scroller->setSnapPositionsY(snapPoints); - } else { - scroller->setSnapPositionsX(snapPoints); - scroller->setSnapPositionsY(0.0, 0.0); - } - } - break; - - default: - break; } return QDeclarativeFlickable::event(event); } -void QDeclarativeListView::scrollerStateChanged(QScroller::State state) +void QDeclarativeListView::viewportMoved() { Q_D(QDeclarativeListView); - QDeclarativeFlickable::scrollerStateChanged(state); + QDeclarativeFlickable::viewportMoved(); + if (!d->itemCount) + return; + // Recursion can occur due to refill changing the content size. + if (d->inViewportMoved) + return; + d->inViewportMoved = true; + d->lazyRelease = true; + refill(); + if (d->flickingHorizontally || d->flickingVertically || d->movingHorizontally || d->movingVertically) + d->moveReason = QDeclarativeListViewPrivate::Mouse; + if (d->moveReason != QDeclarativeListViewPrivate::SetIndex) { + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) { + // reposition highlight + qreal pos = d->highlight->position(); + qreal viewPos = d->position(); + if (pos > viewPos + d->highlightRangeEnd - d->highlight->size()) + pos = viewPos + d->highlightRangeEnd - d->highlight->size(); + if (pos < viewPos + d->highlightRangeStart) + pos = viewPos + d->highlightRangeStart; + d->highlightPosAnimator->stop(); + d->highlight->setPosition(qRound(pos)); + + // update current index + if (FxListItem *snapItem = d->snapItemAt(d->highlight->position())) { + if (snapItem->index >= 0 && snapItem->index != d->currentIndex) + d->updateCurrent(snapItem->index); + } + } + } - if (state == QScroller::Inactive) { - d->bufferMode = QDeclarativeListViewPrivate::NoBuffer; - if (d->highlightRange == QDeclarativeListView::StrictlyEnforceRange) { - d->updateHighlight(); // nudge the highlight in the right position if needed. + if ((d->flickingHorizontally || d->flickingVertically) && d->correctFlick && !d->inFlickCorrection) { + d->inFlickCorrection = true; + // Near an end and it seems that the extent has changed? + // Recalculate the flick so that we don't end up in an odd position. + if (yflick()) { + if (d->vData.velocity > 0) { + const qreal minY = minYExtent(); + if ((minY - d->vData.move.value() < height()/2 || d->vData.flickTarget - d->vData.move.value() < height()/2) + && minY != d->vData.flickTarget) + d->flickY(-d->vData.smoothVelocity.value()); + d->bufferMode = QDeclarativeListViewPrivate::BufferBefore; + } else if (d->vData.velocity < 0) { + const qreal maxY = maxYExtent(); + if ((d->vData.move.value() - maxY < height()/2 || d->vData.move.value() - d->vData.flickTarget < height()/2) + && maxY != d->vData.flickTarget) + d->flickY(-d->vData.smoothVelocity.value()); + d->bufferMode = QDeclarativeListViewPrivate::BufferAfter; + } } + + if (xflick()) { + if (d->hData.velocity > 0) { + const qreal minX = minXExtent(); + if ((minX - d->hData.move.value() < width()/2 || d->hData.flickTarget - d->hData.move.value() < width()/2) + && minX != d->hData.flickTarget) + d->flickX(-d->hData.smoothVelocity.value()); + d->bufferMode = QDeclarativeListViewPrivate::BufferBefore; + } else if (d->hData.velocity < 0) { + const qreal maxX = maxXExtent(); + if ((d->hData.move.value() - maxX < width()/2 || d->hData.move.value() - d->hData.flickTarget < width()/2) + && maxX != d->hData.flickTarget) + d->flickX(-d->hData.smoothVelocity.value()); + d->bufferMode = QDeclarativeListViewPrivate::BufferAfter; + } + } + d->inFlickCorrection = false; } + d->inViewportMoved = false; } -qreal QDeclarativeListView::minExtent() const +qreal QDeclarativeListView::minYExtent() const { Q_D(const QDeclarativeListView); - + if (d->orient == QDeclarativeListView::Horizontal) + return QDeclarativeFlickable::minYExtent(); if (d->minExtentDirty) { - d->minExtent = d->startPosition(); - if (d->modelCount && - d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - d->minExtent -= d->highlightRangeStart; + d->minExtent = -d->startPosition(); + if (d->header && d->visibleItems.count()) + d->minExtent += d->header->size(); + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + d->minExtent += d->highlightRangeStart; if (d->sectionCriteria) { if (d->visibleItem(0)) d->minExtent -= d->visibleItem(0)->sectionSize(); } + d->minExtent = qMax(d->minExtent, -(d->endPositionAt(0) - d->highlightRangeEnd + 1)); } d->minExtentDirty = false; } + return d->minExtent; } -qreal QDeclarativeListView::maxExtent() const +qreal QDeclarativeListView::maxYExtent() const { Q_D(const QDeclarativeListView); - + if (d->orient == QDeclarativeListView::Horizontal) + return height(); if (d->maxExtentDirty) { - d->maxExtent = d->endPosition() + 1; - - if (d->modelCount && - d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { - d->maxExtent = qMin(d->maxExtent + d->size() - d->highlightRangeEnd + 1, - // ensure that the last item fits fully behind hightlightRangeStart - d->positionAt(d->modelCount-1) + d->size() - d->highlightRangeStart); + if (!d->model || !d->model->count()) { + d->maxExtent = 0; + } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + d->maxExtent = -(d->positionAt(d->model->count()-1) - d->highlightRangeStart); + if (d->highlightRangeEnd != d->highlightRangeStart) + d->maxExtent = qMin(d->maxExtent, -(d->endPosition() - d->highlightRangeEnd + 1)); + } else { + d->maxExtent = -(d->endPosition() - height() + 1); } - d->maxExtent = qMax(d->maxExtent, minExtent()); + if (d->footer) + d->maxExtent -= d->footer->size(); + qreal minY = minYExtent(); + if (d->maxExtent > minY) + d->maxExtent = minY; d->maxExtentDirty = false; } return d->maxExtent; } -qreal QDeclarativeListView::minYExtent() const -{ - Q_D(const QDeclarativeListView); - if (d->orient == QDeclarativeListView::Horizontal) - return QDeclarativeFlickable::minYExtent(); - else - return minExtent(); -} - -qreal QDeclarativeListView::maxYExtent() const -{ - Q_D(const QDeclarativeListView); - if (d->orient == QDeclarativeListView::Horizontal) - return height(); - else - return maxExtent(); -} - qreal QDeclarativeListView::minXExtent() const { Q_D(const QDeclarativeListView); if (d->orient == QDeclarativeListView::Vertical) return QDeclarativeFlickable::minXExtent(); - else - return minExtent(); + if (d->minExtentDirty) { + d->minExtent = -d->startPosition(); + if (d->header) + d->minExtent += d->header->size(); + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + d->minExtent += d->highlightRangeStart; + d->minExtent = qMax(d->minExtent, -(d->endPositionAt(0) - d->highlightRangeEnd + 1)); + } + d->minExtentDirty = false; + } + + return d->minExtent; } qreal QDeclarativeListView::maxXExtent() const @@ -2346,50 +2423,25 @@ qreal QDeclarativeListView::maxXExtent() const Q_D(const QDeclarativeListView); if (d->orient == QDeclarativeListView::Vertical) return width(); - else - return maxExtent(); -} - -void QDeclarativeListView::viewportAboutToMove(QPointF newPos) -{ - Q_D(QDeclarativeListView); - - // qDebug() << "viewport about to move"; - // need to refill before moving - if( d->orient == Horizontal ) - d->refill(newPos.x(), newPos.x() + width() - 1); - else - d->refill(newPos.y(), newPos.y() + height() - 1); - - d->lazyRelease = true; - - if (d->isUserGenerated) - d->moveReason = QDeclarativeListViewPrivate::Mouse; - - if (d->haveHighlightRange && d->highlight && d->highlightRange == StrictlyEnforceRange) { - - d->highlightPosAnimator->stop(); - - // reposition highlight - qreal pos = d->highlight->position(); - qreal viewPos = d->orient == Horizontal ? newPos.x() : newPos.y(); - if (pos > viewPos + d->highlightRangeEnd - d->highlight->size()) - pos = viewPos + d->highlightRangeEnd - d->highlight->size(); - if (pos < viewPos + d->highlightRangeStart) - pos = viewPos + d->highlightRangeStart; - d->highlight->setPosition(pos); - - // update current index - if (d->moveReason != QDeclarativeListViewPrivate::SetIndex) { - int idx = d->snapIndex(); - if (idx >= 0 && idx != d->currentIndex) - d->setCurrentIndex(idx); + if (d->maxExtentDirty) { + if (!d->model || !d->model->count()) { + d->maxExtent = 0; + } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + d->maxExtent = -(d->positionAt(d->model->count()-1) - d->highlightRangeStart); + if (d->highlightRangeEnd != d->highlightRangeStart) + d->maxExtent = qMin(d->maxExtent, -(d->endPosition() - d->highlightRangeEnd + 1)); + } else { + d->maxExtent = -(d->endPosition() - width() + 1); } + if (d->footer) + d->maxExtent -= d->footer->size(); + qreal minX = minXExtent(); + if (d->maxExtent > minX) + d->maxExtent = minX; + d->maxExtentDirty = false; } - if (d->sectionCriteria) - d->updateCurrentSection(); - d->updateViewport(); + return d->maxExtent; } void QDeclarativeListView::keyPressEvent(QKeyEvent *event) @@ -2399,7 +2451,7 @@ void QDeclarativeListView::keyPressEvent(QKeyEvent *event) if (event->isAccepted()) return; - if (d->model && d->modelCount && d->interactive) { + if (d->model && d->model->count() && d->interactive) { if ((d->orient == QDeclarativeListView::Horizontal && event->key() == Qt::Key_Left) || (d->orient == QDeclarativeListView::Vertical && event->key() == Qt::Key_Up)) { if (currentIndex() > 0 || (d->wrap && !event->isAutoRepeat())) { @@ -2412,7 +2464,7 @@ void QDeclarativeListView::keyPressEvent(QKeyEvent *event) } } else if ((d->orient == QDeclarativeListView::Horizontal && event->key() == Qt::Key_Right) || (d->orient == QDeclarativeListView::Vertical && event->key() == Qt::Key_Down)) { - if (currentIndex() < d->modelCount - 1 || (d->wrap && !event->isAutoRepeat())) { + if (currentIndex() < d->model->count() - 1 || (d->wrap && !event->isAutoRepeat())) { incrementCurrentIndex(); event->accept(); return; @@ -2426,7 +2478,8 @@ void QDeclarativeListView::keyPressEvent(QKeyEvent *event) QDeclarativeFlickable::keyPressEvent(event); } -void QDeclarativeListView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +void QDeclarativeListView::geometryChanged(const QRectF &newGeometry, + const QRectF &oldGeometry) { Q_D(QDeclarativeListView); d->maxExtentDirty = true; @@ -2447,11 +2500,11 @@ void QDeclarativeListView::geometryChanged(const QRectF &newGeometry, const QRec void QDeclarativeListView::incrementCurrentIndex() { Q_D(QDeclarativeListView); - //qDebug() << "incrementCurrentIndex" << currentIndex() << "c:" << count; - if (d->modelCount && (currentIndex() < d->modelCount - 1 || d->wrap)) { + int count = d->model ? d->model->count() : 0; + if (count && (currentIndex() < count - 1 || d->wrap)) { d->moveReason = QDeclarativeListViewPrivate::SetIndex; int index = currentIndex()+1; - setCurrentIndex((index >= 0 && index < d->modelCount) ? index : 0); + setCurrentIndex((index >= 0 && index < count) ? index : 0); } } @@ -2467,11 +2520,11 @@ void QDeclarativeListView::incrementCurrentIndex() void QDeclarativeListView::decrementCurrentIndex() { Q_D(QDeclarativeListView); - //qDebug() << "decrementCurrentIndex" << currentIndex() << "c:" << count; - if (d->modelCount && (currentIndex() > 0 || d->wrap)) { + int count = d->model ? d->model->count() : 0; + if (count && (currentIndex() > 0 || d->wrap)) { d->moveReason = QDeclarativeListViewPrivate::SetIndex; int index = currentIndex()-1; - setCurrentIndex((index >= 0 && index < d->modelCount) ? index : d->modelCount - 1); + setCurrentIndex((index >= 0 && index < count) ? index : count-1); } } @@ -2510,9 +2563,8 @@ void QDeclarativeListView::decrementCurrentIndex() */ void QDeclarativeListView::positionViewAtIndex(int index, int mode) { - //qDebug() << "positionViewAtIndex index:" << index << "mode:" << mode; Q_D(QDeclarativeListView); - if (!d->isValid() || index < 0 || index >= d->modelCount) + if (!d->isValid() || index < 0 || index >= d->model->count()) return; if (mode < Beginning || mode > Contain) return; @@ -2558,9 +2610,12 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode) if (itemPos < pos) pos = itemPos; } - pos = qMin(pos, maxExtent() - d->size()); // shouldn't that be + 1 ? - pos = qMax(pos, minExtent()); + qreal maxExtent = d->orient == QDeclarativeListView::Vertical ? -maxYExtent() : -maxXExtent(); + pos = qMin(pos, maxExtent); + qreal minExtent = d->orient == QDeclarativeListView::Vertical ? -minYExtent() : -minXExtent(); + pos = qMax(pos, minExtent); d->moveReason = QDeclarativeListViewPrivate::Other; + cancelFlick(); d->setPosition(pos); if (d->highlight) { d->highlight->setPosition(d->currentItem->itemPosition()); @@ -2568,6 +2623,7 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode) d->updateHighlight(); } } + d->fixupPosition(); } /*! @@ -2603,13 +2659,15 @@ void QDeclarativeListView::componentComplete() refill(); d->moveReason = QDeclarativeListViewPrivate::SetIndex; if (d->currentIndex < 0 && !d->currentIndexCleared) - d->setCurrentIndex(0); + d->updateCurrent(0); else - d->setCurrentIndex(d->currentIndex); + d->updateCurrent(d->currentIndex); if (d->highlight && d->currentItem) { d->highlight->setPosition(d->currentItem->position()); + d->updateTrackedItem(); } - d->updateHighlight(false); + d->moveReason = QDeclarativeListViewPrivate::Other; + d->fixupPosition(); } } @@ -2628,35 +2686,88 @@ void QDeclarativeListView::updateSections() void QDeclarativeListView::refill() { Q_D(QDeclarativeListView); - d->refill(d->position(), d->position() + d->size() - 1); + d->refill(d->position(), d->position()+d->size()-1); } -void QDeclarativeListView::itemsInserted(int modelIndex, int count) +void QDeclarativeListView::trackedPositionChanged() { Q_D(QDeclarativeListView); - d->minExtentDirty = true; - d->maxExtentDirty = true; - - if (!isComponentComplete()) { - d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count + if (!d->trackedItem || !d->currentItem) return; + if (d->moveReason == QDeclarativeListViewPrivate::SetIndex) { + qreal trackedPos = qCeil(d->trackedItem->position()); + qreal trackedSize = d->trackedItem->size(); + if (d->trackedItem != d->currentItem) { + trackedPos -= d->currentItem->sectionSize(); + trackedSize += d->currentItem->sectionSize(); + } + const qreal viewPos = d->position(); + qreal pos = viewPos; + if (d->haveHighlightRange) { + if (d->highlightRange == StrictlyEnforceRange) { + if (trackedPos > pos + d->highlightRangeEnd - d->trackedItem->size()) + pos = trackedPos - d->highlightRangeEnd + d->trackedItem->size(); + if (trackedPos < pos + d->highlightRangeStart) + pos = trackedPos - d->highlightRangeStart; + } else { + if (trackedPos < d->startPosition() + d->highlightRangeStart) { + pos = d->startPosition(); + } else if (d->trackedItem->endPosition() > d->endPosition() - d->size() + d->highlightRangeEnd) { + pos = d->endPosition() - d->size() + 1; + if (pos < d->startPosition()) + pos = d->startPosition(); + } else { + if (trackedPos < viewPos + d->highlightRangeStart) { + pos = trackedPos - d->highlightRangeStart; + } else if (trackedPos > viewPos + d->highlightRangeEnd - trackedSize) { + pos = trackedPos - d->highlightRangeEnd + trackedSize; + } + } + } + } else { + if (trackedPos < viewPos && d->currentItem->position() < viewPos) { + pos = d->currentItem->position() < trackedPos ? trackedPos : d->currentItem->position(); + } else if (d->trackedItem->endPosition() >= viewPos + d->size() + && d->currentItem->endPosition() >= viewPos + d->size()) { + if (d->trackedItem->endPosition() <= d->currentItem->endPosition()) { + pos = d->trackedItem->endPosition() - d->size() + 1; + if (trackedSize > d->size()) + pos = trackedPos; + } else { + pos = d->currentItem->endPosition() - d->size() + 1; + if (d->currentItem->size() > d->size()) + pos = d->currentItem->position(); + } + } + } + if (viewPos != pos) { + cancelFlick(); + d->calcVelocity = true; + d->setPosition(pos); + d->calcVelocity = false; + } } +} +void QDeclarativeListView::itemsInserted(int modelIndex, int count) +{ + Q_D(QDeclarativeListView); + if (!isComponentComplete()) + return; d->updateUnrequestedIndexes(); d->moveReason = QDeclarativeListViewPrivate::Other; if (!d->visibleItems.count() || d->model->count() <= 1) { d->scheduleLayout(); - if (d->modelCount && d->currentIndex >= modelIndex) { + if (d->itemCount && d->currentIndex >= modelIndex) { // adjust current item index d->currentIndex += count; if (d->currentItem) d->currentItem->index = d->currentIndex; emit currentIndexChanged(); } else if (!d->currentIndex || (d->currentIndex < 0 && !d->currentIndexCleared)) { - d->setCurrentIndex(0); + d->updateCurrent(0); } - d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count - d->updateScrollerValues(); + d->itemCount += count; emit countChanged(); return; } @@ -2688,16 +2799,13 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) emit currentIndexChanged(); } d->scheduleLayout(); - d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count - d->updateScrollerValues(); + d->itemCount += count; emit countChanged(); return; } } // At least some of the added items will be visible - if (d->layoutScheduled) - d->layout(); // index can be the next item past the end of the visible items list (i.e. appended) int pos = index < d->visibleItems.count() ? d->visibleItems.at(index)->position() @@ -2762,9 +2870,14 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) } diff = pos - initialPos; } - if (d->modelCount && d->currentIndex >= modelIndex) { + if (d->itemCount && d->currentIndex >= modelIndex) { // adjust current item index - d->setCurrentIndex(d->currentIndex + count); + d->currentIndex += count; + if (d->currentItem) { + d->currentItem->index = d->currentIndex; + d->currentItem->setPosition(d->currentItem->position() + diff); + } + emit currentIndexChanged(); } // Update the indexes of the following visible items. for (; index < d->visibleItems.count(); ++index) { @@ -2779,42 +2892,35 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) added.at(j)->attached->emitAdd(); d->updateSections(); - d->modelCount = d->model->count(); // don't rely on newCount = oldCount + count - d->updateScrollerValues(); + d->itemCount += count; emit countChanged(); } void QDeclarativeListView::itemsRemoved(int modelIndex, int count) { Q_D(QDeclarativeListView); - d->minExtentDirty = true; - d->maxExtentDirty = true; - d->modelCount = d->model->count(); // don't rely on newCount = oldCount - count if (!isComponentComplete()) return; d->moveReason = QDeclarativeListViewPrivate::Other; d->updateUnrequestedIndexes(); + d->itemCount -= count; FxListItem *firstVisible = d->firstVisibleItem(); int preRemovedSize = 0; - bool removedVisible = false; // true if we removed an visible item. + bool removedVisible = false; // Remove the items from the visible list, skipping anything already marked for removal QList::Iterator it = d->visibleItems.begin(); while (it != d->visibleItems.end()) { FxListItem *item = *it; - - // qDebug() << "Remove visible?: "<index<<"at"<position()<<"mi"<index == -1 || item->index < modelIndex) { // already removed, or before removed items ++it; } else if (item->index >= modelIndex + count) { // after removed items - // qDebug() << "Remove item not" << item->index <<"at" << item->position() << "newINdex:"<<(item->index-count); item->index -= count; ++it; } else { // removed item - // qDebug() << "Remove item really" << item->index <<"at" << item->position(); if (!removedVisible) { d->scheduleLayout(); removedVisible = true; @@ -2825,22 +2931,18 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) connect(item->attached, SIGNAL(delayRemoveChanged()), this, SLOT(destroyRemoved()), Qt::QueuedConnection); ++it; } else { - // move the list down if we remove an item between the start of the list and the first visible item. if (item == firstVisible) - firstVisible = 0; + firstVisible = 0; if (firstVisible && item->position() < firstVisible->position()) preRemovedSize += item->size(); - it = d->visibleItems.erase(it); d->releaseItem(item); } } } - - // restore the start position of the visible items - if (firstVisible && forceConst(d->visibleItems).first() != firstVisible) - forceConst(d->visibleItems).first()->setPosition(forceConst(d->visibleItems).first()->position() + preRemovedSize); + if (firstVisible && d->visibleItems.first() != firstVisible) + d->visibleItems.first()->setPosition(d->visibleItems.first()->position() + preRemovedSize); // fix current if (d->currentIndex >= modelIndex + count) { @@ -2854,8 +2956,8 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) d->releaseItem(d->currentItem); d->currentItem = 0; d->currentIndex = -1; - if (d->modelCount) - d->setCurrentIndex(qMin(modelIndex, d->modelCount-1)); + if (d->itemCount) + d->updateCurrent(qMin(modelIndex, d->itemCount-1)); } // update visibleIndex @@ -2865,21 +2967,24 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) break; } } + if (removedVisible && d->visibleItems.isEmpty()) { - QScroller::scroller(this)->stop(); - // the complete visible area was removed - if (!d->modelCount) { - d->clear(); + d->timeline.clear(); + if (d->itemCount == 0) { + d->visibleIndex = 0; + d->visiblePos = d->header ? d->header->size() : 0; + d->setPosition(0); + d->updateHeader(); + d->updateFooter(); + update(); } else { if (modelIndex < d->visibleIndex) d->visibleIndex = modelIndex+1; - d->visibleIndex = qBound(0, d->visibleIndex, d->modelCount - 1); + d->visibleIndex = qMax(qMin(d->visibleIndex, d->itemCount-1), 0); } } d->updateSections(); - d->updateScrollerValues(); - emit countChanged(); } @@ -2999,7 +3104,7 @@ void QDeclarativeListView::itemsMoved(int from, int to, int count) } // Ensure we don't cause an ugly list scroll. - forceConst(d->visibleItems).first()->setPosition(forceConst(d->visibleItems).first()->position() + moveBy); + d->visibleItems.first()->setPosition(d->visibleItems.first()->position() + moveBy); d->updateSections(); d->layout(); @@ -3016,15 +3121,14 @@ void QDeclarativeListView::modelReset() { Q_D(QDeclarativeListView); d->clear(); - d->modelCount = d->model->count(); d->setPosition(0); refill(); d->moveReason = QDeclarativeListViewPrivate::SetIndex; - d->setCurrentIndex(d->currentIndex); + d->updateCurrent(d->currentIndex); if (d->highlight && d->currentItem) { d->highlight->setPosition(d->currentItem->position()); + d->updateTrackedItem(); } - d->updateHighlight(); d->moveReason = QDeclarativeListViewPrivate::Other; emit countChanged(); } @@ -3048,6 +3152,14 @@ void QDeclarativeListView::destroyingItem(QDeclarativeItem *item) d->unrequestedItems.remove(item); } +void QDeclarativeListView::animStopped() +{ + Q_D(QDeclarativeListView); + d->bufferMode = QDeclarativeListViewPrivate::NoBuffer; + if (d->haveHighlightRange && d->highlightRange == QDeclarativeListView::StrictlyEnforceRange) + d->updateHighlight(); +} + QDeclarativeListViewAttached *QDeclarativeListView::qmlAttachedProperties(QObject *obj) { return new QDeclarativeListViewAttached(obj); diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h index 5593574..2678b90 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview_p.h +++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h @@ -238,18 +238,13 @@ Q_SIGNALS: void headerChanged(); void footerChanged(); -protected Q_SLOTS: - virtual void scrollerStateChanged(QScroller::State); - protected: virtual bool event(QEvent *event); - virtual qreal minExtent() const; - virtual qreal maxExtent() const; + virtual void viewportMoved(); virtual qreal minYExtent() const; virtual qreal maxYExtent() const; virtual qreal minXExtent() const; virtual qreal maxXExtent() const; - virtual void viewportAboutToMove(QPointF newPos); virtual void keyPressEvent(QKeyEvent *); virtual void geometryChanged(const QRectF &newGeometry,const QRectF &oldGeometry); virtual void componentComplete(); @@ -257,6 +252,7 @@ protected: private Q_SLOTS: void updateSections(); void refill(); + void trackedPositionChanged(); void itemsInserted(int index, int count); void itemsRemoved(int index, int count); void itemsMoved(int from, int to, int count); @@ -265,6 +261,7 @@ private Q_SLOTS: void destroyRemoved(); void createdItem(int index, QDeclarativeItem *item); void destroyingItem(QDeclarativeItem *item); + void animStopped(); }; class QDeclarativeListViewAttached : public QObject diff --git a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp index 3442596..25edb36 100644 --- a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp +++ b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp @@ -99,11 +99,9 @@ void tst_qdeclarativeflickable::create() QCOMPARE(obj->verticalVelocity(), 0.); QCOMPARE(obj->isInteractive(), true); - QCOMPARE(obj->pressDelay(), 0); QCOMPARE(obj->boundsBehavior(), QDeclarativeFlickable::DragAndOvershootBounds); - /* Those values are platform dependant + QCOMPARE(obj->pressDelay(), 0); QCOMPARE(obj->maximumFlickVelocity(), 2000.); - */ delete obj; } diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index ef5c976..327bba2 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -649,7 +649,6 @@ void tst_QDeclarativeGridView::currentIndex() #endif QTRY_VERIFY(canvas->hasFocus()); QTRY_VERIFY(canvas->scene()->hasFocus()); - gridview->forceActiveFocus(); qApp->processEvents(); QTest::keyClick(canvas, Qt::Key_Down); @@ -667,7 +666,6 @@ void tst_QDeclarativeGridView::currentIndex() #endif QTRY_VERIFY(canvas->hasFocus()); QTRY_VERIFY(canvas->scene()->hasFocus()); - gridview->forceActiveFocus(); qApp->processEvents(); QTest::keyClick(canvas, Qt::Key_Right); diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 70f417f..37d836d 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -613,11 +613,10 @@ void tst_QDeclarativeListView::removed(bool animated) listview->setCurrentIndex(10); model.removeItem(1); // post: top item will be at 40 - // let transitions settle. qApp->processEvents(); - // Confirm items positioned correctly (we were at the fourth item and deleted one) - for (int i = 2; i < 2 + 16; ++i) { + // Confirm items positioned correctly + for (int i = 2; i < 18; ++i) { QDeclarativeItem *item = findItem(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QTRY_VERIFY(item); @@ -664,12 +663,10 @@ void tst_QDeclarativeListView::removed(bool animated) listview->setContentY(80); QTest::qWait(300); - // remove all visible items model.removeItems(1, 17); QTest::qWait(300); // Confirm items positioned correctly - // we were at the fourth item, but deleted 1 through 17. So we should be at 1 now. itemCount = findItems(contentItem, "wrapper").count(); for (int i = 0; i < model.count() && i < itemCount-1; ++i) { QDeclarativeItem *item = findItem(contentItem, "wrapper", i+2); @@ -1079,7 +1076,6 @@ void tst_QDeclarativeListView::currentIndex() #endif QTRY_VERIFY(canvas->hasFocus()); QTRY_VERIFY(canvas->scene()->hasFocus()); - listview->forceActiveFocus(); qApp->processEvents(); QTest::keyClick(canvas, Qt::Key_Down); -- cgit v0.12 From 8f7de974b34b6fc6c0c15dbf4cdc35e5722e2196 Mon Sep 17 00:00:00 2001 From: Ruben Van Boxem Date: Tue, 7 Dec 2010 12:29:36 +0100 Subject: Fix for GCC on Windows x64. Merge-request: 939 Reviewed-by: Olivier Goffart --- src/corelib/tools/qsimd.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index 63ebafb..bc5e9e4 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -285,7 +285,13 @@ static inline uint detectProcessorFeatures() uint features = MMX|SSE|SSE2|CMOV; uint feature_result = 0; -#if defined(Q_CC_GNU) +#if defined (Q_OS_WIN64) + { + int info[4]; + __cpuid(info, 1); + feature_result = info[2]; + } +#elif defined(Q_CC_GNU) quint64 tmp; asm ("xchg %%rbx, %1\n" "cpuid\n" @@ -294,12 +300,6 @@ static inline uint detectProcessorFeatures() : "a" (1) : "%edx" ); -#elif defined (Q_OS_WIN64) - { - int info[4]; - __cpuid(info, 1); - feature_result = info[2]; - } #endif if (feature_result & (1u)) -- cgit v0.12 From 532115bcaa370af827a5cbad017b272842c5aacf Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 7 Dec 2010 13:02:48 +0100 Subject: Fix text disappearing on GL when RGB-path is taken (no transformation) When there is no transformation on a glyph in the GL texture glyph cache, it will take the RGB code path to support subpixel antialiasing. In this code path we would ask glTextImage2D() to convert from a GL_ALPHA buffer to an internal format of GL_RGBA. This is not supported on OpenGL ES 2, and would cause missing text for some drivers. The change also fixes a typo in an #ifdef. Task-number: QTBUG-15789 Reviewed-by: Kim --- src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 705ad09..66445cd 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -128,14 +128,17 @@ void QGLTextureGlyphCache::createTextureData(int width, int height) m_width = width; m_height = height; - QVarLengthArray data(width * height); - for (int i = 0; i < data.size(); ++i) - data[i] = 0; - - if (m_type == QFontEngineGlyphCache::Raster_RGBMask) - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]); - else + if (m_type == QFontEngineGlyphCache::Raster_RGBMask) { + QVarLengthArray data(width * height * 4); + for (int i = 0; i < data.size(); ++i) + data[i] = 0; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); + } else { + QVarLengthArray data(width * height); + for (int i = 0; i < data.size(); ++i) + data[i] = 0; glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]); + } glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -287,7 +290,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) if (mask.format() == QImage::Format_RGB32) { glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits()); } else { -#ifdef QT_OPENGL_ES2 +#ifdef QT_OPENGL_ES_2 glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_ALPHA, GL_UNSIGNED_BYTE, mask.bits()); #else // glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is -- cgit v0.12 From eac9e6a11e7727d8a749242f317362337ce89a1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 7 Dec 2010 12:53:37 +0100 Subject: Prevent always deep-copying in QPixmap::toImage() for raster pixmaps. Calling paintEngine() can cause a deep copy since it will indirectly call the bits() function. Since we don't want to create a paint engine if it doesn't exist we should access the QImageData paintEngine variable directly instead. Reviewed-by: Olivier Goffart --- src/gui/image/qpixmap_raster.cpp | 13 ++++++++----- tests/auto/qpixmap/tst_qpixmap.cpp | 10 ++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index f080687..29bf5f5 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -50,6 +50,7 @@ #include "qimage.h" #include #include +#include #include #include #include @@ -303,11 +304,13 @@ bool QRasterPixmapData::hasAlphaChannel() const QImage QRasterPixmapData::toImage() const { - if (image.paintEngine() - && image.paintEngine()->isActive() - && image.paintEngine()->paintDevice() == &image) - { - return image.copy(); + if (!image.isNull()) { + QImageData *data = const_cast(image).data_ptr(); + if (data->paintEngine && data->paintEngine->isActive() + && data->paintEngine->paintDevice() == &image) + { + return image.copy(); + } } return image; diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index d5267b5..419518a1 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -129,10 +129,7 @@ private slots: void isNull(); void task_246446(); -#ifdef Q_WS_QWS void convertFromImageNoDetach(); -#endif - void convertFromImageDetach(); #if defined(Q_WS_WIN) @@ -913,11 +910,13 @@ void tst_QPixmap::isNull() } } -#ifdef Q_WS_QWS void tst_QPixmap::convertFromImageNoDetach() { + QPixmap randomPixmap(10, 10); + if (randomPixmap.pixmapData()->classId() != QPixmapData::RasterClass) + QSKIP("Test only valid for raster pixmaps", SkipAll); + //first get the screen format - QPixmap randomPixmap(10,10); QImage::Format screenFormat = randomPixmap.toImage().format(); QVERIFY(screenFormat != QImage::Format_Invalid); @@ -932,7 +931,6 @@ void tst_QPixmap::convertFromImageNoDetach() const QImage constCopy = copy; QVERIFY(constOrig.bits() == constCopy.bits()); } -#endif //Q_WS_QWS void tst_QPixmap::convertFromImageDetach() { -- cgit v0.12 From 82ae06cf32514ae60ce5b9c04a48a4619c2252e0 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Tue, 7 Dec 2010 15:19:37 +0100 Subject: Optimize behavior of QGLTextureCache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we iterate over the cache to figure out which objects to remove, we would change the internal order of the cache, leading to a suboptimal caching behavior. Instead, let QCache decide which objects to remove when the cache overflows, based on its internal last-recently-used algorithm. Reviewed-by: Samuel Rødal --- src/opengl/qgl.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index dc7a333..63df8c3 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1853,18 +1853,6 @@ QGLTextureCache::~QGLTextureCache() void QGLTextureCache::insert(QGLContext* ctx, qint64 key, QGLTexture* texture, int cost) { QWriteLocker locker(&m_lock); - if (m_cache.totalCost() + cost > m_cache.maxCost()) { - // the cache is full - make an attempt to remove something - const QList keys = m_cache.keys(); - int i = 0; - while (i < m_cache.count() - && (m_cache.totalCost() + cost > m_cache.maxCost())) { - QGLTexture *tex = m_cache.object(keys.at(i)); - if (tex->context == ctx) - m_cache.remove(keys.at(i)); - ++i; - } - } const QGLTextureCacheKey cacheKey = {key, QGLContextPrivate::contextGroup(ctx)}; m_cache.insert(cacheKey, texture, cost); } -- cgit v0.12 From 783a278f243c6411f5f32d11f2165b9eed9b6f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 7 Dec 2010 14:27:14 +0100 Subject: Don't emit activeFocusChanged() unless the active focus actually changed We would previously call subFocusItemChanged(0) on the item as part of clearing the subfocus, even if the item in question would recieve a new subfocus item as part of setting the new subfocus. This resulted in the declarative item emitting activeFocusChanged(false) and then activeFocusChanged(true), which was affecting any animation or state bound to the activeFocus property of the item. We now stop clearing the subfocus when encountering an item that we know will get subfocus during the set-subfocus pass. We then set subfocus all the way to the root item, since the subfocus item itself might change. The effect of this is that the declarative item will only get one call to subFocusItemChanged(), passing the new subfocus item, instead of two. This means the declarative item can keep track of wherther ot not it had a subfocus item previously, and only emit activeFocusChanged() when the active focus goes from true to false or false to true. Task-number: QTBUG-15615 Reviewed-by: Yoann Lopes --- src/declarative/graphicsitems/qdeclarativeitem_p.h | 10 +- src/gui/graphicsview/qgraphicsitem.cpp | 18 ++-- src/gui/graphicsview/qgraphicsitem_p.h | 4 +- .../data/forceActiveFocus.qml | 26 +++++ .../tst_qdeclarativefocusscope.cpp | 109 +++++++++++++++++++++ 5 files changed, 155 insertions(+), 12 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativefocusscope/data/forceActiveFocus.qml diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h index d8635b9..a36ee34 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem_p.h +++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h @@ -126,7 +126,7 @@ public: widthValid(false), heightValid(false), componentComplete(true), keepMouse(false), smooth(false), transformOriginDirty(true), doneEventPreHandler(false), keyHandler(0), - mWidth(0), mHeight(0), implicitWidth(0), implicitHeight(0) + mWidth(0), mHeight(0), implicitWidth(0), implicitHeight(0), hadSubFocusItem(false) { QGraphicsItemPrivate::acceptedMouseButtons = 0; isDeclarativeItem = 1; @@ -275,6 +275,8 @@ public: qreal implicitWidth; qreal implicitHeight; + bool hadSubFocusItem; + QPointF computeTransformOrigin() const; virtual void setPosHelper(const QPointF &pos) @@ -288,9 +290,11 @@ public: // Reimplemented from QGraphicsItemPrivate virtual void subFocusItemChange() { - if (flags & QGraphicsItem::ItemIsFocusScope || !parent) - emit q_func()->activeFocusChanged(subFocusItem != 0); + bool hasSubFocusItem = subFocusItem != 0; + if (((flags & QGraphicsItem::ItemIsFocusScope) || !parent) && hasSubFocusItem != hadSubFocusItem) + emit q_func()->activeFocusChanged(hasSubFocusItem); //see also QDeclarativeItemPrivate::focusChanged + hadSubFocusItem = hasSubFocusItem; } // Reimplemented from QGraphicsItemPrivate diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 7ab49cb..94e1a72 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3295,9 +3295,13 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim } // Update the child focus chain. - if (scene && scene->focusItem()) - scene->focusItem()->d_ptr->clearSubFocus(); - f->d_ptr->setSubFocus(); + QGraphicsItem *commonAncestor = 0; + if (scene && scene->focusItem()) { + commonAncestor = scene->focusItem()->commonAncestorItem(f); + scene->focusItem()->d_ptr->clearSubFocus(scene->focusItem(), commonAncestor); + } + + f->d_ptr->setSubFocus(f, commonAncestor); // Update the scene's focus item. if (scene) { @@ -5554,7 +5558,7 @@ void QGraphicsItemPrivate::ensureSceneTransformRecursive(QGraphicsItem **topMost /*! \internal */ -void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem) +void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem) { // Update focus child chain. Stop at panels, or if this item // is hidden, stop at the first item with a visible parent. @@ -5567,7 +5571,7 @@ void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem) if (parent != q_ptr && parent->d_ptr->subFocusItem) { if (parent->d_ptr->subFocusItem == q_ptr) break; - parent->d_ptr->subFocusItem->d_ptr->clearSubFocus(); + parent->d_ptr->subFocusItem->d_ptr->clearSubFocus(0, stopItem); } parent->d_ptr->subFocusItem = q_ptr; parent->d_ptr->subFocusItemChange(); @@ -5580,12 +5584,12 @@ void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem) /*! \internal */ -void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem) +void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem) { // Reset sub focus chain. QGraphicsItem *parent = rootItem ? rootItem : q_ptr; do { - if (parent->d_ptr->subFocusItem != q_ptr) + if (parent->d_ptr->subFocusItem != q_ptr || parent == stopItem) break; parent->d_ptr->subFocusItem = 0; parent->d_ptr->subFocusItemChange(); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 1b7aa97..b938759 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -479,8 +479,8 @@ public: void setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide); void clearFocusHelper(bool giveFocusToParent); - void setSubFocus(QGraphicsItem *rootItem = 0); - void clearSubFocus(QGraphicsItem *rootItem = 0); + void setSubFocus(QGraphicsItem *rootItem = 0, QGraphicsItem *stopItem = 0); + void clearSubFocus(QGraphicsItem *rootItem = 0, QGraphicsItem *stopItem = 0); void resetFocusProxy(); virtual void subFocusItemChange(); virtual void focusScopeItemChange(bool isSubFocusItem); diff --git a/tests/auto/declarative/qdeclarativefocusscope/data/forceActiveFocus.qml b/tests/auto/declarative/qdeclarativefocusscope/data/forceActiveFocus.qml new file mode 100644 index 0000000..6c39d4a --- /dev/null +++ b/tests/auto/declarative/qdeclarativefocusscope/data/forceActiveFocus.qml @@ -0,0 +1,26 @@ +import QtQuick 1.0 + +Rectangle { + objectName: "root" + FocusScope { + objectName: "scope" + Item { + objectName: "item-a1" + FocusScope { + objectName: "scope-a" + Item { + objectName: "item-a2" + } + } + } + Item { + objectName: "item-b1" + FocusScope { + objectName: "scope-b" + Item { + objectName: "item-b2" + } + } + } + } +} diff --git a/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp b/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp index 1645dac..6a3627b 100644 --- a/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp +++ b/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp @@ -71,6 +71,7 @@ private slots: void noParentFocus(); void signalEmission(); void qtBug13380(); + void forceActiveFocus(); }; /* @@ -432,6 +433,114 @@ void tst_qdeclarativefocusscope::qtBug13380() delete view; } +void tst_qdeclarativefocusscope::forceActiveFocus() +{ + QDeclarativeView *view = new QDeclarativeView; + view->setSource(QUrl::fromLocalFile(SRCDIR "/data/forceActiveFocus.qml")); + + QGraphicsObject *rootObject = view->rootObject(); + QVERIFY(rootObject); + + QDeclarativeItem *scope = findItem(rootObject, QLatin1String("scope")); + QDeclarativeItem *itemA1 = findItem(rootObject, QLatin1String("item-a1")); + QDeclarativeItem *scopeA = findItem(rootObject, QLatin1String("scope-a")); + QDeclarativeItem *itemA2 = findItem(rootObject, QLatin1String("item-a2")); + QDeclarativeItem *itemB1 = findItem(rootObject, QLatin1String("item-b1")); + QDeclarativeItem *scopeB = findItem(rootObject, QLatin1String("scope-b")); + QDeclarativeItem *itemB2 = findItem(rootObject, QLatin1String("item-b2")); + + QVERIFY(scope); + QVERIFY(itemA1); + QVERIFY(scopeA); + QVERIFY(itemA2); + QVERIFY(itemB1); + QVERIFY(scopeB); + QVERIFY(itemB2); + + QSignalSpy rootSpy(rootObject, SIGNAL(activeFocusChanged(bool))); + QSignalSpy scopeSpy(scope, SIGNAL(activeFocusChanged(bool))); + QSignalSpy scopeASpy(scopeA, SIGNAL(activeFocusChanged(bool))); + QSignalSpy scopeBSpy(scopeB, SIGNAL(activeFocusChanged(bool))); + + // First, walk the focus from item-a1 down to item-a2 and back again + itemA1->forceActiveFocus(); + QVERIFY(itemA1->hasActiveFocus()); + QCOMPARE(rootSpy.count(), 1); + QCOMPARE(scopeSpy.count(), 1); + + scopeA->forceActiveFocus(); + QVERIFY(!itemA1->hasActiveFocus()); + QVERIFY(scopeA->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 1); + QCOMPARE(rootSpy.count(), 1); + QCOMPARE(scopeSpy.count(), 1); + + itemA2->forceActiveFocus(); + QVERIFY(!itemA1->hasActiveFocus()); + QVERIFY(itemA2->hasActiveFocus()); + QVERIFY(scopeA->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 1); + QCOMPARE(rootSpy.count(), 1); + QCOMPARE(scopeSpy.count(), 1); + + scopeA->forceActiveFocus(); + QVERIFY(!itemA1->hasActiveFocus()); + QVERIFY(itemA2->hasActiveFocus()); + QVERIFY(scopeA->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 1); + QCOMPARE(rootSpy.count(), 1); + QCOMPARE(scopeSpy.count(), 1); + + itemA1->forceActiveFocus(); + QVERIFY(itemA1->hasActiveFocus()); + QVERIFY(!scopeA->hasActiveFocus()); + QVERIFY(!itemA2->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 2); + QCOMPARE(rootSpy.count(), 1); + QCOMPARE(scopeSpy.count(), 1); + + // Then jump back and forth between branch 'a' and 'b' + itemB1->forceActiveFocus(); + QVERIFY(itemB1->hasActiveFocus()); + QCOMPARE(rootSpy.count(), 1); + QCOMPARE(scopeSpy.count(), 1); + + scopeA->forceActiveFocus(); + QVERIFY(!itemA1->hasActiveFocus()); + QVERIFY(!itemB1->hasActiveFocus()); + QVERIFY(scopeA->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 3); + QCOMPARE(rootSpy.count(), 1); + QCOMPARE(scopeSpy.count(), 1); + + scopeB->forceActiveFocus(); + QVERIFY(!scopeA->hasActiveFocus()); + QVERIFY(!itemB1->hasActiveFocus()); + QVERIFY(scopeB->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 4); + QCOMPARE(scopeBSpy.count(), 1); + QCOMPARE(rootSpy.count(), 1); + QCOMPARE(scopeSpy.count(), 1); + + itemA2->forceActiveFocus(); + QVERIFY(!scopeB->hasActiveFocus()); + QVERIFY(itemA2->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 5); + QCOMPARE(scopeBSpy.count(), 2); + QCOMPARE(rootSpy.count(), 1); + QCOMPARE(scopeSpy.count(), 1); + + itemB2->forceActiveFocus(); + QVERIFY(!itemA2->hasActiveFocus()); + QVERIFY(itemB2->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 6); + QCOMPARE(scopeBSpy.count(), 3); + QCOMPARE(rootSpy.count(), 1); + QCOMPARE(scopeSpy.count(), 1); + + delete view; +} + QTEST_MAIN(tst_qdeclarativefocusscope) #include "tst_qdeclarativefocusscope.moc" -- cgit v0.12 From 2eea05dee36f6ce263a91eae88f1029d2c333988 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 3 Dec 2010 13:39:24 +0200 Subject: Proxy mode was not correctly checked. Fixes: NB#208617 - QtProxyFactory does not return correct (any) proxy data --- src/plugins/bearer/icd/proxyconf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/bearer/icd/proxyconf.cpp b/src/plugins/bearer/icd/proxyconf.cpp index 37501fb..efe2da7 100644 --- a/src/plugins/bearer/icd/proxyconf.cpp +++ b/src/plugins/bearer/icd/proxyconf.cpp @@ -306,12 +306,12 @@ QList ProxyConfPrivate::flush(const QNetworkProxyQuery &query) if (isHostExcluded(query.peerHostName())) return result; // no proxy for this host - if (mode == "auto") { + if (mode == QLatin1String("AUTO")) { // TODO: pac currently not supported, fix me return result; } - if (mode == "manual") { + if (mode == QLatin1String("MANUAL")) { bool isHttps = false; QString protocol = query.protocolTag().toLower(); -- cgit v0.12 From ddeae91ab54bb92b813304778ab8dc4037937274 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 8 Dec 2010 16:22:04 +1000 Subject: ListView: Fix calculation of currentItem position when out of view. The calculation of position of currentItem when it is out of the visible area was bogus. Task-number: QTBUG-15525 Reviewed-by: Bea Lam --- .../graphicsitems/qdeclarativelistview.cpp | 12 ++- .../qdeclarativelistview/data/displaylist.qml | 9 ++- .../tst_qdeclarativelistview.cpp | 86 ++++++++++++++++++++++ 3 files changed, 102 insertions(+), 5 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 845da79..2dfee3b 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -739,16 +739,20 @@ void QDeclarativeListViewPrivate::layout() return; } if (!visibleItems.isEmpty()) { - qreal oldEnd = visibleItems.last()->endPosition(); + bool fixedCurrent = currentItem && visibleItems.first()->item == currentItem->item; + qreal sum = visibleItems.first()->size(); qreal pos = visibleItems.first()->position() + visibleItems.first()->size() + spacing; for (int i=1; i < visibleItems.count(); ++i) { FxListItem *item = visibleItems.at(i); item->setPosition(pos); pos += item->size() + spacing; + sum += item->size(); + fixedCurrent = fixedCurrent || (currentItem && item->item == currentItem->item); } - // move current item if it is after the visible items. - if (currentItem && currentIndex > lastVisibleIndex()) - currentItem->setPosition(currentItem->position() + (visibleItems.last()->endPosition() - oldEnd)); + averageSize = qRound(sum / visibleItems.count()); + // move current item if it is not a visible item. + if (currentIndex >= 0 && currentItem && !fixedCurrent) + currentItem->setPosition(positionAt(currentIndex)); } q->refill(); minExtentDirty = true; diff --git a/tests/auto/declarative/qdeclarativelistview/data/displaylist.qml b/tests/auto/declarative/qdeclarativelistview/data/displaylist.qml index 487b70e..9d58530 100644 --- a/tests/auto/declarative/qdeclarativelistview/data/displaylist.qml +++ b/tests/auto/declarative/qdeclarativelistview/data/displaylist.qml @@ -1,6 +1,8 @@ import QtQuick 1.0 Rectangle { + id: root + property real delegateHeight: 20 width: 240 height: 320 color: "#ffffff" @@ -10,7 +12,8 @@ Rectangle { Rectangle { id: wrapper objectName: "wrapper" - height: 20 + height: root.delegateHeight + Behavior on height { NumberAnimation {} } width: 240 Text { text: index @@ -20,6 +23,10 @@ Rectangle { objectName: "displayText" text: display } + Text { + x: 200 + text: wrapper.y + } color: ListView.isCurrentItem ? "lightsteelblue" : "white" } }, diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 759caf2..22ebb1a 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -103,6 +103,7 @@ private slots: void resizeView(); void sizeLessThan1(); void QTBUG_14821(); + void resizeDelegate(); private: template void items(); @@ -1406,6 +1407,8 @@ void tst_QDeclarativeListView::resetModel() QTRY_VERIFY(display != 0); QTRY_COMPARE(display->text(), strings.at(i)); } + + delete canvas; } void tst_QDeclarativeListView::propertyChanges() @@ -1613,6 +1616,8 @@ void tst_QDeclarativeListView::manualHighlight() QTRY_COMPARE(listview->currentIndex(), 2); QTRY_COMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 2)); QTRY_COMPARE(listview->highlightItem()->y(), listview->currentItem()->y()); + + delete canvas; } void tst_QDeclarativeListView::QTBUG_11105() @@ -1752,6 +1757,8 @@ void tst_QDeclarativeListView::footer() model.clear(); QTRY_COMPARE(footer->y(), 0.0); + + delete canvas; } void tst_QDeclarativeListView::resizeView() @@ -1794,6 +1801,8 @@ void tst_QDeclarativeListView::resizeView() QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio)); QCOMPARE(heightRatio.toReal(), 0.25); + + delete canvas; } void tst_QDeclarativeListView::sizeLessThan1() @@ -1849,6 +1858,83 @@ void tst_QDeclarativeListView::QTBUG_14821() listview->incrementCurrentIndex(); QCOMPARE(listview->currentIndex(), 0); + + delete canvas; +} + +void tst_QDeclarativeListView::resizeDelegate() +{ + QDeclarativeView *canvas = createView(); + + QStringList strings; + for (int i = 0; i < 30; ++i) + strings << QString::number(i); + QStringListModel model(strings); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaylist.qml")); + qApp->processEvents(); + + QDeclarativeListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QDeclarativeItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QTRY_COMPARE(listview->count(), model.rowCount()); + + listview->setCurrentIndex(25); + listview->setContentY(0); + + for (int i = 0; i < 16; ++i) { + QDeclarativeItem *item = findItem(contentItem, "wrapper", i); + QVERIFY(item != 0); + QCOMPARE(item->y(), i*20.0); + } + + QCOMPARE(listview->currentItem()->y(), 500.0); + QTRY_COMPARE(listview->highlightItem()->y(), 500.0); + + canvas->rootObject()->setProperty("delegateHeight", 30); + qApp->processEvents(); + + for (int i = 0; i < 11; ++i) { + QDeclarativeItem *item = findItem(contentItem, "wrapper", i); + QVERIFY(item != 0); + QTRY_COMPARE(item->y(), i*30.0); + } + + QTRY_COMPARE(listview->currentItem()->y(), 750.0); + QTRY_COMPARE(listview->highlightItem()->y(), 750.0); + + listview->setCurrentIndex(1); + listview->positionViewAtIndex(25, QDeclarativeListView::Beginning); + listview->positionViewAtIndex(5, QDeclarativeListView::Beginning); + + for (int i = 5; i < 16; ++i) { + QDeclarativeItem *item = findItem(contentItem, "wrapper", i); + QVERIFY(item != 0); + QCOMPARE(item->y(), i*30.0); + } + + QTRY_COMPARE(listview->currentItem()->y(), 30.0); + QTRY_COMPARE(listview->highlightItem()->y(), 30.0); + + canvas->rootObject()->setProperty("delegateHeight", 20); + qApp->processEvents(); + + for (int i = 5; i < 11; ++i) { + QDeclarativeItem *item = findItem(contentItem, "wrapper", i); + QVERIFY(item != 0); + QTRY_COMPARE(item->y(), 150 + (i-5)*20.0); + } + + QTRY_COMPARE(listview->currentItem()->y(), 70.0); + QTRY_COMPARE(listview->highlightItem()->y(), 70.0); + + delete canvas; } void tst_QDeclarativeListView::qListModelInterface_items() -- cgit v0.12 From bf3c5942840dc9dadcfa89b26ca46f61d8d79f93 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 8 Dec 2010 07:58:14 +0100 Subject: Fix QApplication::setGraphicsSystem() since lighthouse integration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The application set parameter was overridden by this piece of ligthhouse legacy. Reviewed-by: Jørgen Lind --- src/gui/kernel/qapplication.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 833e803..b5409df 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -807,7 +807,6 @@ void QApplicationPrivate::construct( ) { initResources(); - graphics_system_name = QLatin1String(qgetenv("QT_DEFAULT_GRAPHICS_SYSTEM")); qt_is_gui_used = (qt_appType != QApplication::Tty); process_cmdline(); -- cgit v0.12 From 8e01304939a19b65267887b220aa9814fc56b350 Mon Sep 17 00:00:00 2001 From: Michael Dominic K Date: Wed, 8 Dec 2010 10:52:36 +0100 Subject: Make sure QMeeGoGraphicsSystem::setTranslucent can't be called if surface already created. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge-request: 967 Reviewed-by: Samuel Rødal --- src/plugins/graphicssystems/meego/qmeegographicssystem.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp index 507f70b..4a86082 100644 --- a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp +++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp @@ -124,8 +124,10 @@ QPixmapData* QMeeGoGraphicsSystem::wrapPixmapData(QPixmapData *pmd) void QMeeGoGraphicsSystem::setSurfaceFixedSize(int /*width*/, int /*height*/) { - if (QMeeGoGraphicsSystem::surfaceWasCreated) + if (QMeeGoGraphicsSystem::surfaceWasCreated) { qWarning("Trying to set surface fixed size but surface already created!"); + return; + } #ifdef QT_WAS_PATCHED QEglProperties *properties = new QEglProperties(); @@ -143,6 +145,11 @@ void QMeeGoGraphicsSystem::setSurfaceScaling(int x, int y, int width, int height void QMeeGoGraphicsSystem::setTranslucent(bool translucent) { + if (QMeeGoGraphicsSystem::surfaceWasCreated) { + qWarning("Trying to set translucency but surface already created!"); + return; + } + QGLWindowSurface::surfaceFormat.setSampleBuffers(false); QGLWindowSurface::surfaceFormat.setSamples(0); QGLWindowSurface::surfaceFormat.setAlpha(translucent); -- cgit v0.12 From d5383440d1a3e0d96cfcfa754aaefe9d30f2e022 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 8 Dec 2010 10:46:16 +0100 Subject: Fix QWingedEdge memory usage issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QWingedEdge should reserve the amount of segments/edges/vertices in relative to the element count instead of length of the QPainterPath passed in. This problem is especially severe when QTextLayout using it to calculate the region for full line selection highlighting, because the region used QFIXED_MAX as right most coordinate, it will cost more than 2 GB of memory allocated just for it (recorded by valgrind on Mac OS X), and cause crash in systems short of memory. Task-number: QTBUG-15823 Reviewed-by: Samuel Rødal --- src/gui/painting/qpathclipper.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp index a17b7c1..5060ad6 100644 --- a/src/gui/painting/qpathclipper.cpp +++ b/src/gui/painting/qpathclipper.cpp @@ -868,9 +868,9 @@ QWingedEdge::QWingedEdge() : } QWingedEdge::QWingedEdge(const QPainterPath &subject, const QPainterPath &clip) : - m_edges(subject.length()), - m_vertices(subject.length()), - m_segments(subject.length()) + m_edges(subject.elementCount()), + m_vertices(subject.elementCount()), + m_segments(subject.elementCount()) { m_segments.setPath(subject); m_segments.addPath(clip); @@ -1405,9 +1405,9 @@ bool QPathClipper::intersect() else if (clipIsRect) return subjectPath.intersects(r2); - QPathSegments a(subjectPath.length()); + QPathSegments a(subjectPath.elementCount()); a.setPath(subjectPath); - QPathSegments b(clipPath.length()); + QPathSegments b(clipPath.elementCount()); b.setPath(clipPath); QIntersectionFinder finder; @@ -1450,9 +1450,9 @@ bool QPathClipper::contains() if (clipIsRect) return subjectPath.contains(r2); - QPathSegments a(subjectPath.length()); + QPathSegments a(subjectPath.elementCount()); a.setPath(subjectPath); - QPathSegments b(clipPath.length()); + QPathSegments b(clipPath.elementCount()); b.setPath(clipPath); QIntersectionFinder finder; -- cgit v0.12 From 36d38c3670aca638a99618291a467b0a4b36f919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 8 Dec 2010 11:52:14 +0100 Subject: Update .def files after 783a278f243c6411f5f32d11f2165b9eed9b6f8c Based on patch from CI system --- src/s60installs/eabi/QtGuiu.def | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 54768a1..632326d 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -4658,11 +4658,11 @@ EXPORTS _ZN20QGraphicsEllipseItemD1Ev @ 4657 NONAME _ZN20QGraphicsEllipseItemD2Ev @ 4658 NONAME _ZN20QGraphicsItemPrivate11removeChildEP13QGraphicsItem @ 4659 NONAME - _ZN20QGraphicsItemPrivate11setSubFocusEP13QGraphicsItem @ 4660 NONAME + _ZN20QGraphicsItemPrivate11setSubFocusEP13QGraphicsItem @ 4660 NONAME ABSENT _ZN20QGraphicsItemPrivate12remapItemPosEP6QEventP13QGraphicsItem @ 4661 NONAME _ZN20QGraphicsItemPrivate12resolveDepthEv @ 4662 NONAME _ZN20QGraphicsItemPrivate12setPosHelperERK7QPointF @ 4663 NONAME - _ZN20QGraphicsItemPrivate13clearSubFocusEP13QGraphicsItem @ 4664 NONAME + _ZN20QGraphicsItemPrivate13clearSubFocusEP13QGraphicsItem @ 4664 NONAME ABSENT _ZN20QGraphicsItemPrivate14setFocusHelperEN2Qt11FocusReasonEb @ 4665 NONAME ABSENT _ZN20QGraphicsItemPrivate15resetFocusProxyEv @ 4666 NONAME _ZN20QGraphicsItemPrivate16setEnabledHelperEbbb @ 4667 NONAME @@ -12105,4 +12105,6 @@ EXPORTS _ZN15QStaticTextItemD1Ev @ 12104 NONAME _ZN15QStaticTextItemD2Ev @ 12105 NONAME _ZN19QEventDispatcherS6031reactivateDeferredActiveObjectsEv @ 12106 NONAME + _ZN20QGraphicsItemPrivate11setSubFocusEP13QGraphicsItemS1_ @ 12107 NONAME + _ZN20QGraphicsItemPrivate13clearSubFocusEP13QGraphicsItemS1_ @ 12108 NONAME -- cgit v0.12 From eb2bd43078c1bb43481aab795f92e105fa130860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 8 Dec 2010 12:18:06 +0100 Subject: Revert "qgrayraster: Speed up rendering of small cubic splines." This reverts commit a9c0fbd5e946ae6e90b6db6dd4aea64c824a4066. The subdivision code in the above commit messed up subdivision of cubic beziers, so we have to revert it. Task-number: QTBUG-15660 Reviewed-by: Andreas Kling --- src/gui/painting/qgrayraster.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c index ec9ebeb..5d665cd 100644 --- a/src/gui/painting/qgrayraster.c +++ b/src/gui/painting/qgrayraster.c @@ -963,49 +963,53 @@ const QT_FT_Vector* control2, const QT_FT_Vector* to ) { + TPos dx, dy, da, db; int top, level; int* levels; QT_FT_Vector* arc; - int mid_x = ( DOWNSCALE( ras.x ) + to->x + - 3 * (control1->x + control2->x ) ) / 8; - int mid_y = ( DOWNSCALE( ras.y ) + to->y + - 3 * (control1->y + control2->y ) ) / 8; - TPos dx = DOWNSCALE( ras.x ) + to->x - ( mid_x << 1 ); - TPos dy = DOWNSCALE( ras.y ) + to->y - ( mid_y << 1 ); + dx = DOWNSCALE( ras.x ) + to->x - ( control1->x << 1 ); if ( dx < 0 ) dx = -dx; + dy = DOWNSCALE( ras.y ) + to->y - ( control1->y << 1 ); if ( dy < 0 ) dy = -dy; if ( dx < dy ) dx = dy; + da = dx; + + dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x ); + if ( dx < 0 ) + dx = -dx; + dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->x + control2->y ); + if ( dy < 0 ) + dy = -dy; + if ( dx < dy ) + dx = dy; + db = dx; level = 1; - dx /= ras.cubic_level; - while ( dx > 0 ) + da = da / ras.cubic_level; + db = db / ras.conic_level; + while ( da > 0 || db > 0 ) { - dx >>= 2; + da >>= 2; + db >>= 3; level++; } if ( level <= 1 ) { - TPos to_x, to_y; + TPos to_x, to_y, mid_x, mid_y; to_x = UPSCALE( to->x ); to_y = UPSCALE( to->y ); - - /* Recalculation of midpoint is needed only if */ - /* UPSCALE and DOWNSCALE have any effect. */ - -#if ( PIXEL_BITS != 6 ) mid_x = ( ras.x + to_x + 3 * UPSCALE( control1->x + control2->x ) ) / 8; mid_y = ( ras.y + to_y + 3 * UPSCALE( control1->y + control2->y ) ) / 8; -#endif gray_render_line( RAS_VAR_ mid_x, mid_y ); gray_render_line( RAS_VAR_ to_x, to_y ); -- cgit v0.12 From 07b3a1c3d38d5870009e76de6315a9025e8f7915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 8 Dec 2010 12:28:34 +0100 Subject: Fixed cubic bezier rendering bug in qgrayraster. Use the y coordinates to compute the y delta... This could cause too fine (or too coarse) subdivision of cubic bezier curves, so potentially both performance problems and visual artifacts. Task-number: QTBUG-15660 Reviewed-by: Andreas Kling --- src/gui/painting/qgrayraster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c index 5d665cd..001345f 100644 --- a/src/gui/painting/qgrayraster.c +++ b/src/gui/painting/qgrayraster.c @@ -982,7 +982,7 @@ dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x ); if ( dx < 0 ) dx = -dx; - dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->x + control2->y ); + dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->y + control2->y ); if ( dy < 0 ) dy = -dy; if ( dx < dy ) -- cgit v0.12 From 3ca55de912dc01e23fc01d4aab953c08619a51a9 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Wed, 8 Dec 2010 14:21:53 +0200 Subject: Remove whitespace and leading tab from documentation change Task-number: QTBUG-12119 Reviewed-by: TrustMe --- src/gui/widgets/qmenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 2e42cdb..74c2a9e 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1319,7 +1319,7 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) Conversely, actions can be added to widgets with the addAction(), addActions() and insertAction() functions. - + \warning To make QMenu visible on the screen, exec() or popup() should be used instead of show(). -- cgit v0.12 From 299e27838df58153e76e5b3d9bee46dc2a867dec Mon Sep 17 00:00:00 2001 From: Michael Dominic K Date: Wed, 8 Dec 2010 13:44:03 +0100 Subject: Use a different dither distribution matrix + a bit of rand. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also don't dither on edges. Improves dithering over tiles/scaled smooth gradients. Merge-request: 971 Reviewed-by: Samuel Rødal --- src/plugins/graphicssystems/meego/dithering.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/plugins/graphicssystems/meego/dithering.cpp b/src/plugins/graphicssystems/meego/dithering.cpp index 1a2e3fa..ca303a8 100644 --- a/src/plugins/graphicssystems/meego/dithering.cpp +++ b/src/plugins/graphicssystems/meego/dithering.cpp @@ -154,7 +154,10 @@ unsigned short* convertRGB32_to_RGB565(const unsigned char *in, int width, int h // Add the diffusion for this pixel we stored in the accumulator. // >> 7 because the values in accumulator are stored * 128 - component[c] += accumulator[c][x] >> 7; + if (x != 0 && x != (width - 1)) { + if (accumulator[c][x] >> 7 != 0) + component[c] += rand() % accumulator[c][x] >> 7; + } // Make sure we're not over the boundaries. CLAMP_256(component[c]); @@ -172,10 +175,10 @@ unsigned short* convertRGB32_to_RGB565(const unsigned char *in, int width, int h // Distribute the difference according to the matrix in the // accumulation bufffer. - ACCUMULATE(accumulator[c], x + 1, 0, width, diff * 7); - ACCUMULATE(accumulator[c], x - 1, 1, width, diff * 3); + ACCUMULATE(accumulator[c], x + 1, 0, width, diff * 3); + ACCUMULATE(accumulator[c], x - 1, 1, width, diff * 5); ACCUMULATE(accumulator[c], x, 1, width, diff * 5); - ACCUMULATE(accumulator[c], x + 1, 1, width, diff * 1); + ACCUMULATE(accumulator[c], x + 1, 1, width, diff * 3); } // Write the newly produced pixel -- cgit v0.12 From f317d94880554a114937554907d08807c0cf5047 Mon Sep 17 00:00:00 2001 From: Michael Dominic K Date: Wed, 8 Dec 2010 13:48:22 +0100 Subject: Support for 'qglTranslucent' in QGLWindowSurface. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge-request: 2523 Reviewed-by: Samuel Rødal --- src/opengl/qwindowsurface_gl.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index bbb98d0..cd9ae01 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -377,7 +377,25 @@ void QGLWindowSurface::hijackWindow(QWidget *widget) if (widgetPrivate->extraData()->glContext) return; - QGLContext *ctx = new QGLContext(surfaceFormat, widget); + QGLContext *ctx = NULL; + + // Inspect the 'qglTranslucent' property of the target widget. If set to true, + // we need to create the surface in a 32bit alpha-compatible format. This is + // currently used by MeeGo graphics system extra API's. Could be in future + // used by other platform-specific graphic system API's. + if (widget->property("qglTranslucent").isValid()) { + QGLFormat modFormat(surfaceFormat); + + if (widget->property("qglTranslucent").toBool() == true) { + modFormat.setSampleBuffers(false); + modFormat.setSamples(0); + modFormat.setAlpha(true); + } + + ctx = new QGLContext(modFormat, widget); + } else + ctx = new QGLContext(surfaceFormat, widget); + ctx->create(qt_gl_share_widget()->context()); #ifndef QT_NO_EGL -- cgit v0.12 From c4f4d801f5dd31ca4c65c70b2245c987ac8ff203 Mon Sep 17 00:00:00 2001 From: Michael Dominic K Date: Wed, 8 Dec 2010 13:48:23 +0100 Subject: New translucency API for the meego graphics system. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge-request: 2523 Reviewed-by: Samuel Rødal --- .../qmeegographicssystemhelper.cpp | 5 +++++ .../qmeegographicssystemhelper.h | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp index b660eb3..13e44b8 100644 --- a/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp +++ b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp @@ -153,3 +153,8 @@ void QMeeGoGraphicsSystemHelper::setTranslucent(bool translucent) ENSURE_RUNNING_MEEGO; QMeeGoRuntime::setTranslucent(translucent); } + +void QMeeGoGraphicsSystemHelper::setTranslucentWidget(QWidget w, bool translucent) +{ + w.setProperty("qglTranslucent", QVariant(translucent)); +} diff --git a/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.h b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.h index d47c829..3e1333d 100644 --- a/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.h +++ b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.h @@ -181,8 +181,25 @@ public: This function needs to be called *before* any widget/content is created. When called with true, the base window surface will be translucent and initialized with QGLFormat.alpha == true. + + This function is *deprecated*. Use ::setTranslucentWidget instead. */ static void setTranslucent(bool translucent); + + //! Sets translucency (alpha) on the given top-level widget. + /*! + This is a new API for enabling GL translucency on top-level widgets. + The specified widget needs to be top-level. When the time comes to create + a window surface for the widget, it'll be created with translucency enabled + (if translucent is true). + + This function has no effect if the widget is already visible or if it's + not a top-level widget. + + This function can be called even if not running MeeGo graphics system. It'll + have no effect though. + */ + static void setTranslucentWidget(QWidget w, bool translucent); }; #endif -- cgit v0.12 From b850c43896d60b4dda21b01fdbdb15013cca48fa Mon Sep 17 00:00:00 2001 From: Michael Dominic K Date: Wed, 8 Dec 2010 15:45:00 +0100 Subject: Check Qt::WA_TranslucentBackground instead of custom widget property. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge-request: 2523 Reviewed-by: Samuel Rødal --- src/opengl/qwindowsurface_gl.cpp | 17 +++++------------ .../qmeegographicssystemhelper.cpp | 5 ----- .../qmeegographicssystemhelper.h | 18 ++---------------- 3 files changed, 7 insertions(+), 33 deletions(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index cd9ae01..f64b93c 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -379,19 +379,12 @@ void QGLWindowSurface::hijackWindow(QWidget *widget) QGLContext *ctx = NULL; - // Inspect the 'qglTranslucent' property of the target widget. If set to true, - // we need to create the surface in a 32bit alpha-compatible format. This is - // currently used by MeeGo graphics system extra API's. Could be in future - // used by other platform-specific graphic system API's. - if (widget->property("qglTranslucent").isValid()) { + // For translucent top-level widgets we need alpha in the format. + if (widget->testAttribute(Qt::WA_TranslucentBackground)) { QGLFormat modFormat(surfaceFormat); - - if (widget->property("qglTranslucent").toBool() == true) { - modFormat.setSampleBuffers(false); - modFormat.setSamples(0); - modFormat.setAlpha(true); - } - + modFormat.setSampleBuffers(false); + modFormat.setSamples(0); + modFormat.setAlpha(true); ctx = new QGLContext(modFormat, widget); } else ctx = new QGLContext(surfaceFormat, widget); diff --git a/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp index 13e44b8..b660eb3 100644 --- a/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp +++ b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp @@ -153,8 +153,3 @@ void QMeeGoGraphicsSystemHelper::setTranslucent(bool translucent) ENSURE_RUNNING_MEEGO; QMeeGoRuntime::setTranslucent(translucent); } - -void QMeeGoGraphicsSystemHelper::setTranslucentWidget(QWidget w, bool translucent) -{ - w.setProperty("qglTranslucent", QVariant(translucent)); -} diff --git a/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.h b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.h index 3e1333d..6df3c22 100644 --- a/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.h +++ b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.h @@ -182,24 +182,10 @@ public: When called with true, the base window surface will be translucent and initialized with QGLFormat.alpha == true. - This function is *deprecated*. Use ::setTranslucentWidget instead. + This function is *deprecated*. Set Qt::WA_TranslucentBackground attribute + on the top-level widget *before* you show it instead. */ static void setTranslucent(bool translucent); - - //! Sets translucency (alpha) on the given top-level widget. - /*! - This is a new API for enabling GL translucency on top-level widgets. - The specified widget needs to be top-level. When the time comes to create - a window surface for the widget, it'll be created with translucency enabled - (if translucent is true). - - This function has no effect if the widget is already visible or if it's - not a top-level widget. - - This function can be called even if not running MeeGo graphics system. It'll - have no effect though. - */ - static void setTranslucentWidget(QWidget w, bool translucent); }; #endif -- cgit v0.12 From d7294806fc43e8611c4441881e511af5f18c60db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 8 Dec 2010 16:46:09 +0100 Subject: Prevent out-of-bounds memory access in drawhelper. The coordinates should be modulo the image width and height like for all the other tiled blend functions. Covered by perspectives.qps Task-number: QTBUG-15837 Reviewed-by: Olivier Goffart --- src/gui/painting/qdrawhelper.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index a4ab278..024a69d 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6432,6 +6432,8 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp int px = int(tx) - (tx < 0); int py = int(ty) - (ty < 0); + px %= image_width; + py %= image_height; if (px < 0) px += image_width; if (py < 0) -- cgit v0.12 From 98b709fec4e0e9d6f1740309936dcb95475d6ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 8 Dec 2010 16:18:58 +0100 Subject: Use effective user id instead of getlogin And check if this gives us more reliable results. Reviewed-by: Prasanth Ullattil --- tests/auto/qfileinfo/tst_qfileinfo.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 2e1ab39..0a61d55 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -54,6 +54,8 @@ #include #include #include +#include +#include #endif #ifdef Q_OS_WIN #define _WIN32_WINNT 0x500 @@ -1675,8 +1677,10 @@ void tst_QFileInfo::owner() { QString userName; #if defined(Q_OS_UNIX) - char *usernameBuf = getlogin(); - if (usernameBuf) { + { + passwd *user = getpwuid(geteuid()); + QVERIFY(user); + char *usernameBuf = user->pw_name; userName = QString::fromLocal8Bit(usernameBuf); } #endif @@ -1715,18 +1719,18 @@ void tst_QFileInfo::owner() if (userName.isEmpty()) QSKIP("Can't retrieve the user name", SkipAll); QString fileName("ownertest.txt"); - if (QFile::exists(fileName)) - QFile::remove(fileName); - QFile testFile(fileName); - QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Text)); - QByteArray testData("testfile"); - QVERIFY(testFile.write(testData) != -1); - testFile.close(); + QVERIFY(!QFile::exists(fileName) || QFile::remove(fileName)); + { + QFile testFile(fileName); + QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Text)); + QByteArray testData("testfile"); + QVERIFY(testFile.write(testData) != -1); + } QFileInfo fi(fileName); QVERIFY(fi.exists()); - QCOMPARE(userName, fi.owner()); - if (QFile::exists(fileName)) - QFile::remove(fileName); + QCOMPARE(fi.owner(), userName); + + QFile::remove(fileName); #if defined(Q_OS_WIN) qt_ntfs_permission_lookup = 0; #endif -- cgit v0.12 From 58ae252e5555dc379b4ed500532bc51ff7bebc25 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 9 Dec 2010 10:12:35 +1000 Subject: highlightFollowsCurrentItem: false was not always honored In some cases ListView and GridView would position the highlight despite highlightFollowsCurrentItem: false being specified. Task-number: QTBUG-15972 Reviewed-by: Michael Brasser --- src/declarative/graphicsitems/qdeclarativegridview.cpp | 14 +++++++++----- src/declarative/graphicsitems/qdeclarativelistview.cpp | 18 ++++++++++++------ .../qdeclarativegridview/data/manual-highlight.qml | 4 ++-- .../qdeclarativegridview/tst_qdeclarativegridview.cpp | 15 +++++++++++---- .../qdeclarativelistview/data/manual-highlight.qml | 2 +- .../qdeclarativelistview/tst_qdeclarativelistview.cpp | 11 +++++++++-- 6 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 1615b0f..4a6a9dc 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -735,7 +735,7 @@ void QDeclarativeGridViewPrivate::createHighlight() QDeclarative_setParent_noEvent(item, q->contentItem()); item->setParentItem(q->contentItem()); highlight = new FxGridItem(item, q); - if (currentItem) + if (currentItem && autoHighlight) highlight->setPosition(currentItem->colPos(), currentItem->rowPos()); highlightXAnimator = new QSmoothedAnimation(q); highlightXAnimator->target = QDeclarativeProperty(highlight->item, QLatin1String("x")); @@ -1253,7 +1253,8 @@ void QDeclarativeGridView::setModel(const QVariant &model) d->moveReason = QDeclarativeGridViewPrivate::SetIndex; d->updateCurrent(d->currentIndex); if (d->highlight && d->currentItem) { - d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); + if (d->autoHighlight) + d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); d->updateTrackedItem(); } d->moveReason = QDeclarativeGridViewPrivate::Other; @@ -1321,7 +1322,8 @@ void QDeclarativeGridView::setDelegate(QDeclarativeComponent *delegate) d->moveReason = QDeclarativeGridViewPrivate::SetIndex; d->updateCurrent(d->currentIndex); if (d->highlight && d->currentItem) { - d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); + if (d->autoHighlight) + d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); d->updateTrackedItem(); } d->moveReason = QDeclarativeGridViewPrivate::Other; @@ -2241,7 +2243,8 @@ void QDeclarativeGridView::componentComplete() else d->updateCurrent(d->currentIndex); if (d->highlight && d->currentItem) { - d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); + if (d->autoHighlight) + d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); d->updateTrackedItem(); } d->moveReason = QDeclarativeGridViewPrivate::Other; @@ -2649,7 +2652,8 @@ void QDeclarativeGridView::modelReset() d->moveReason = QDeclarativeGridViewPrivate::SetIndex; d->updateCurrent(d->currentIndex); if (d->highlight && d->currentItem) { - d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); + if (d->autoHighlight) + d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); d->updateTrackedItem(); } d->moveReason = QDeclarativeGridViewPrivate::Other; diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 2dfee3b..d008f91 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -1571,7 +1571,8 @@ void QDeclarativeListView::setModel(const QVariant &model) d->moveReason = QDeclarativeListViewPrivate::SetIndex; d->updateCurrent(d->currentIndex); if (d->highlight && d->currentItem) { - d->highlight->setPosition(d->currentItem->position()); + if (d->autoHighlight) + d->highlight->setPosition(d->currentItem->position()); d->updateTrackedItem(); } } @@ -1642,7 +1643,8 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) d->moveReason = QDeclarativeListViewPrivate::SetIndex; d->updateCurrent(d->currentIndex); if (d->highlight && d->currentItem) { - d->highlight->setPosition(d->currentItem->position()); + if (d->autoHighlight) + d->highlight->setPosition(d->currentItem->position()); d->updateTrackedItem(); } } @@ -2632,8 +2634,10 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode) cancelFlick(); d->setPosition(pos); if (d->highlight) { - d->highlight->setPosition(d->currentItem->itemPosition()); - d->highlight->setSize(d->currentItem->itemSize()); + if (d->autoHighlight) { + d->highlight->setPosition(d->currentItem->itemPosition()); + d->highlight->setSize(d->currentItem->itemSize()); + } d->updateHighlight(); } } @@ -2679,7 +2683,8 @@ void QDeclarativeListView::componentComplete() else d->updateCurrent(d->currentIndex); if (d->highlight && d->currentItem) { - d->highlight->setPosition(d->currentItem->position()); + if (d->autoHighlight) + d->highlight->setPosition(d->currentItem->position()); d->updateTrackedItem(); } d->moveReason = QDeclarativeListViewPrivate::Other; @@ -3142,7 +3147,8 @@ void QDeclarativeListView::modelReset() d->moveReason = QDeclarativeListViewPrivate::SetIndex; d->updateCurrent(d->currentIndex); if (d->highlight && d->currentItem) { - d->highlight->setPosition(d->currentItem->position()); + if (d->autoHighlight) + d->highlight->setPosition(d->currentItem->position()); d->updateTrackedItem(); } d->moveReason = QDeclarativeListViewPrivate::Other; diff --git a/tests/auto/declarative/qdeclarativegridview/data/manual-highlight.qml b/tests/auto/declarative/qdeclarativegridview/data/manual-highlight.qml index 7bb2c95..d082847 100644 --- a/tests/auto/declarative/qdeclarativegridview/data/manual-highlight.qml +++ b/tests/auto/declarative/qdeclarativegridview/data/manual-highlight.qml @@ -28,8 +28,8 @@ Item { objectName: "highlight" width: 80; height: 80 color: "lightsteelblue"; radius: 5 - y: grid.currentItem.y - x: grid.currentItem.x + y: grid.currentItem.y+5 + x: grid.currentItem.x+5 } } diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index 7998e30..fd5d140 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -1215,15 +1215,22 @@ void tst_QDeclarativeGridView::manualHighlight() QTRY_COMPARE(gridview->currentIndex(), 0); QTRY_COMPARE(gridview->currentItem(), findItem(contentItem, "wrapper", 0)); - QTRY_COMPARE(gridview->highlightItem()->y(), gridview->currentItem()->y()); - QTRY_COMPARE(gridview->highlightItem()->x(), gridview->currentItem()->x()); + QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y()); + QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x()); gridview->setCurrentIndex(2); QTRY_COMPARE(gridview->currentIndex(), 2); QTRY_COMPARE(gridview->currentItem(), findItem(contentItem, "wrapper", 2)); - QTRY_COMPARE(gridview->highlightItem()->y(), gridview->currentItem()->y()); - QTRY_COMPARE(gridview->highlightItem()->x(), gridview->currentItem()->x()); + QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y()); + QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x()); + + gridview->positionViewAtIndex(8, QDeclarativeGridView::Contain); + + QTRY_COMPARE(gridview->currentIndex(), 2); + QTRY_COMPARE(gridview->currentItem(), findItem(contentItem, "wrapper", 2)); + QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y()); + QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x()); } void tst_QDeclarativeGridView::footer() diff --git a/tests/auto/declarative/qdeclarativelistview/data/manual-highlight.qml b/tests/auto/declarative/qdeclarativelistview/data/manual-highlight.qml index d8cfd9a..a32a194 100644 --- a/tests/auto/declarative/qdeclarativelistview/data/manual-highlight.qml +++ b/tests/auto/declarative/qdeclarativelistview/data/manual-highlight.qml @@ -28,7 +28,7 @@ Item { objectName: "highlight" width: 180; height: 20 color: "lightsteelblue"; radius: 5 - y: list.currentItem.y + y: list.currentItem.y+5 } } diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 22ebb1a..ff90d32 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -1609,13 +1609,20 @@ void tst_QDeclarativeListView::manualHighlight() QTRY_COMPARE(listview->currentIndex(), 0); QTRY_COMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 0)); - QTRY_COMPARE(listview->highlightItem()->y(), listview->currentItem()->y()); + QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y()); listview->setCurrentIndex(2); QTRY_COMPARE(listview->currentIndex(), 2); QTRY_COMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 2)); - QTRY_COMPARE(listview->highlightItem()->y(), listview->currentItem()->y()); + QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y()); + + // QTBUG-15972 + listview->positionViewAtIndex(3, QDeclarativeListView::Contain); + + QTRY_COMPARE(listview->currentIndex(), 2); + QTRY_COMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 2)); + QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y()); delete canvas; } -- cgit v0.12 From 1e33b4ea1374b499bf938bc2f370f12404b76a58 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Thu, 9 Dec 2010 16:40:11 +1000 Subject: Update QtGui bwins def file for QTBUG-15615 --- src/s60installs/bwins/QtGuiu.def | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 355b46a..bf4d99f 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -2725,7 +2725,7 @@ EXPORTS ?clearSelection@QTextCursor@@QAEXXZ @ 2724 NONAME ; void QTextCursor::clearSelection(void) ?clearSpans@QTableView@@QAEXXZ @ 2725 NONAME ; void QTableView::clearSpans(void) ?clearString@QLineControl@@ABE?AVQString@@II@Z @ 2726 NONAME ; class QString QLineControl::clearString(unsigned int, unsigned int) const - ?clearSubFocus@QGraphicsItemPrivate@@QAEXPAVQGraphicsItem@@@Z @ 2727 NONAME ; void QGraphicsItemPrivate::clearSubFocus(class QGraphicsItem *) + ?clearSubFocus@QGraphicsItemPrivate@@QAEXPAVQGraphicsItem@@@Z @ 2727 NONAME ABSENT ; void QGraphicsItemPrivate::clearSubFocus(class QGraphicsItem *) ?clearUndo@QLineControl@@QAEXXZ @ 2728 NONAME ; void QLineControl::clearUndo(void) ?click@QAbstractButton@@QAEXXZ @ 2729 NONAME ; void QAbstractButton::click(void) ?clicked@QAbstractButton@@IAEX_N@Z @ 2730 NONAME ; void QAbstractButton::clicked(bool) @@ -9914,7 +9914,7 @@ EXPORTS ?setStyleSheet@QWidget@@QAEXABVQString@@@Z @ 9913 NONAME ; void QWidget::setStyleSheet(class QString const &) ?setStyleStrategy@QFont@@QAEXW4StyleStrategy@1@@Z @ 9914 NONAME ; void QFont::setStyleStrategy(enum QFont::StyleStrategy) ?setStyle_helper@QWidgetPrivate@@QAEXPAVQStyle@@_N1@Z @ 9915 NONAME ; void QWidgetPrivate::setStyle_helper(class QStyle *, bool, bool) - ?setSubFocus@QGraphicsItemPrivate@@QAEXPAVQGraphicsItem@@@Z @ 9916 NONAME ; void QGraphicsItemPrivate::setSubFocus(class QGraphicsItem *) + ?setSubFocus@QGraphicsItemPrivate@@QAEXPAVQGraphicsItem@@@Z @ 9916 NONAME ABSENT ; void QGraphicsItemPrivate::setSubFocus(class QGraphicsItem *) ?setSubTitle@QWizardPage@@QAEXABVQString@@@Z @ 9917 NONAME ; void QWizardPage::setSubTitle(class QString const &) ?setSubTitleFormat@QWizard@@QAEXW4TextFormat@Qt@@@Z @ 9918 NONAME ; void QWizard::setSubTitleFormat(enum Qt::TextFormat) ?setSubmitPolicy@QDataWidgetMapper@@QAEXW4SubmitPolicy@1@@Z @ 9919 NONAME ; void QDataWidgetMapper::setSubmitPolicy(enum QDataWidgetMapper::SubmitPolicy) @@ -12906,4 +12906,6 @@ EXPORTS ?userData@QStaticTextItem@@QBEPAVQStaticTextUserData@@XZ @ 12905 NONAME ; class QStaticTextUserData * QStaticTextItem::userData(void) const ?populate@QTextureGlyphCache@@QAE_NPAVQFontEngine@@HPBIPBUQFixedPoint@@@Z @ 12906 NONAME ; bool QTextureGlyphCache::populate(class QFontEngine *, int, unsigned int const *, struct QFixedPoint const *) ?resetCursorBlinkTimer@QLineControl@@QAEXXZ @ 12907 NONAME ; void QLineControl::resetCursorBlinkTimer(void) + ?setSubFocus@QGraphicsItemPrivate@@QAEXPAVQGraphicsItem@@0@Z @ 12908 NONAME ; void QGraphicsItemPrivate::setSubFocus(class QGraphicsItem *, class QGraphicsItem *) + ?clearSubFocus@QGraphicsItemPrivate@@QAEXPAVQGraphicsItem@@0@Z @ 12909 NONAME ; void QGraphicsItemPrivate::clearSubFocus(class QGraphicsItem *, class QGraphicsItem *) -- cgit v0.12 From 8f5a46deb3604d1d07a7f291695f0da2b04f1b73 Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Wed, 8 Dec 2010 21:31:14 +0200 Subject: QT::Window palette brush fails to render correctly. QWidget uses QPainter::drawTiledPixmap to draw textured background brush but OpenVG paint engine fails to render pixmaps correctly because of incorrect offset calculation. Task-number: QTBUG-15737 Reviewed-by: Gunnar Sletta --- src/openvg/qpaintengine_vg.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index b8e8bad..13156d7 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -3210,8 +3210,7 @@ void QVGPaintEngine::drawTiledPixmap (const QRectF &r, const QPixmap &pixmap, const QPointF &s) { QBrush brush(state()->pen.color(), pixmap); - QTransform xform; - xform.translate(-s.x(), -s.y()); + QTransform xform = QTransform::fromTranslate(r.x() - s.x(), r.y() - s.y()); brush.setTransform(xform); fillRect(r, brush); } -- cgit v0.12 From f9057f290bc89884d32ec88bddc8de6e0a3b3f7f Mon Sep 17 00:00:00 2001 From: Janne Koskinen Date: Wed, 8 Dec 2010 12:25:29 +0200 Subject: QLabel wordwrap to respect maximumSize 80 characters width can be longer than maximum size of QLabel. Restrict to max size. Task-number: QT-4354 Reviewed-by: Sami Merila --- src/gui/widgets/qlabel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp index 42be03b..011b07a 100644 --- a/src/gui/widgets/qlabel.cpp +++ b/src/gui/widgets/qlabel.cpp @@ -682,7 +682,7 @@ QSize QLabelPrivate::sizeForWidth(int w) const bool tryWidth = (w < 0) && (align & Qt::TextWordWrap); if (tryWidth) - w = fm.averageCharWidth() * 80; + w = qMin(fm.averageCharWidth() * 80, q->maximumSize().width()); else if (w < 0) w = 2000; w -= (hextra + contentsMargin.width()); -- cgit v0.12 From 4ecc45086102807901a3bd2b9e02a169ca212716 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Thu, 9 Dec 2010 10:51:01 +0100 Subject: Fix a rare race condition when showing windows When setting a window to translucent shortly before showing it with the OpenGL graphics system, the hijacking would call XDestroyWindow without resetting the internal state. This might lead to the window waiting for a map notify message forever. The patch now properly resets the internal state when destroying the old window, so it'll get mapped correctly when show() is called. Reviewed-by: Denis Dzyubenko --- src/gui/kernel/qwidget_x11.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 9085e98..ff6f215 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -905,8 +905,17 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO inputContext->setFocusWidget(q); } - if (destroyw) + if (destroyw) { qt_XDestroyWindow(q, dpy, destroyw); + if (QTLWExtra *topData = maybeTopData()) { +#ifndef QT_NO_XSYNC + if (topData->syncUpdateCounter) + XSyncDestroyCounter(dpy, topData->syncUpdateCounter); +#endif + // we destroyed our old window - reset the top-level state + createTLSysExtra(); + } + } // newly created windows are positioned at the window system's // (0,0) position. If the parent uses wrect mapping to expand the -- cgit v0.12 From e195adf461ae81f1fedd75cc8907f823edd1f8f7 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 9 Dec 2010 11:21:12 +0100 Subject: Fix compilation of qnetworkreply test with namespaces. --- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 9cf61f9..cff0ae9 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -336,10 +336,10 @@ private Q_SLOTS: void parentingRepliesToTheApp(); }; -QT_BEGIN_NAMESPACE - bool tst_QNetworkReply::seedCreated = false; +QT_BEGIN_NAMESPACE + namespace QTest { template<> char *toString(const QNetworkReply::NetworkError& code) -- cgit v0.12 From 1b41444e13d3e9e2f0733129675d0c2996e7df57 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 8 Dec 2010 16:06:18 +0200 Subject: Add libinfix support for QML plugins in Symbian. Task-number: QTBUG-14736 Reviewed-by: Alessandro Portale --- mkspecs/common/symbian/symbian.conf | 2 +- src/declarative/qml/qdeclarativeimport.cpp | 8 +++++++- tools/configure/configureapp.cpp | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 11907cf..707335c 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -147,7 +147,7 @@ SYMBIAN_SUPPORTED_LANGUAGES = \ # These directories must match what configure uses for QT_INSTALL_PLUGINS and QT_INSTALL_IMPORTS QT_PLUGINS_BASE_DIR = /resource/qt$${QT_LIBINFIX}/plugins -QT_IMPORTS_BASE_DIR = /resource/qt/imports +QT_IMPORTS_BASE_DIR = /resource/qt$${QT_LIBINFIX}/imports load(symbian/platform_paths) diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp index acc13de..94765f2 100644 --- a/src/declarative/qml/qdeclarativeimport.cpp +++ b/src/declarative/qml/qdeclarativeimport.cpp @@ -382,7 +382,13 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { QString resolvedFilePath = database->resolvePlugin(dir, plugin.path, plugin.name); - +#if defined(QT_LIBINFIX) && defined(Q_OS_SYMBIAN) + if (resolvedFilePath.isEmpty()) { + // In case of libinfixed build, attempt to load libinfixed version, too. + QString infixedPluginName = plugin.name + QLatin1String(QT_LIBINFIX); + resolvedFilePath = database->resolvePlugin(dir, plugin.path, infixedPluginName); + } +#endif if (!resolvedFilePath.isEmpty()) { if (!database->importPlugin(resolvedFilePath, uri, errorString)) { if (errorString) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 050ad62..c967dad 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1029,6 +1029,8 @@ void Configure::parseCmdLine() if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith("symbian")) { dictionary[ "QT_INSTALL_PLUGINS" ] = QString("\\resource\\qt%1\\plugins").arg(dictionary[ "QT_LIBINFIX" ]); + dictionary[ "QT_INSTALL_IMPORTS" ] = + QString("\\resource\\qt%1\\imports").arg(dictionary[ "QT_LIBINFIX" ]); } } else if (configCmdLine.at(i) == "-D") { ++i; -- cgit v0.12 From 99938908456a422ebced06744deec6333546bf6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 9 Dec 2010 12:44:58 +0100 Subject: Fixed missing text in GL 2 engine after recreating a context. If we recreate the texture glyph cache, we also need to repopulate. Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 3ddc15a..ac41c04 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1477,16 +1477,18 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp QOpenGL2PaintEngineState *s = q->state(); + bool recreateVertexArrays = false; + QGLTextureGlyphCache *cache = (QGLTextureGlyphCache *) staticTextItem->fontEngine()->glyphCache(ctx, glyphType, QTransform()); if (!cache || cache->cacheType() != glyphType) { cache = new QGLTextureGlyphCache(ctx, glyphType, QTransform()); staticTextItem->fontEngine()->setGlyphCache(ctx, cache); + recreateVertexArrays = true; } else if (cache->context() == 0) { // Old context has been destroyed, new context has same ptr value cache->setContext(ctx); } - bool recreateVertexArrays = false; if (staticTextItem->userDataNeedsUpdate) recreateVertexArrays = true; else if (staticTextItem->userData() == 0) -- cgit v0.12 From 43d5a0757d857c2a6694ae81d6b70c04ef876aff Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Tue, 7 Dec 2010 12:53:51 +0100 Subject: Fix boundingBox for raster engine with synthesized italic fonts We need to account for the extra right side bearing caused by text transform for synthesized italic. Task-number: QTBUG-14803 Reviewed-by: Eskil --- src/gui/text/qfontengine_coretext.mm | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index dcc8329..2ae60b1 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -50,6 +50,8 @@ QT_BEGIN_NAMESPACE +static float SYNTHETIC_ITALIC_SKEW = tanf(14 * acosf(0) / 90); + QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning) : QFontEngineMulti(0) { @@ -396,6 +398,9 @@ glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph) glyph_metrics_t ret; CGGlyph g = glyph; CGRect rect = CTFontGetBoundingRectsForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, 0, 1); + if (synthesisFlags & QFontEngine::SynthesizedItalic) { + rect.size.width += rect.size.height * SYNTHETIC_ITALIC_SKEW; + } ret.width = QFixed::fromReal(rect.size.width); ret.height = QFixed::fromReal(rect.size.height); ret.x = QFixed::fromReal(rect.origin.x); @@ -487,7 +492,7 @@ void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextIt CGAffineTransformConcat(cgMatrix, oldTextMatrix); if (synthesisFlags & QFontEngine::SynthesizedItalic) - cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); + cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -SYNTHETIC_ITALIC_SKEW, 1, 0, 0)); cgMatrix = CGAffineTransformConcat(cgMatrix, transform); @@ -570,13 +575,11 @@ static void convertCGPathToQPainterPath(void *info, const CGPathElement *element void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nGlyphs, QPainterPath *path, QTextItem::RenderFlags) { - CGAffineTransform cgMatrix = CGAffineTransformIdentity; cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1); if (synthesisFlags & QFontEngine::SynthesizedItalic) - cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); - + cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -SYNTHETIC_ITALIC_SKEW, 1, 0, 0)); for (int i = 0; i < nGlyphs; ++i) { QCFType cgpath = CTFontCreatePathForGlyph(ctfont, glyphs[i], &cgMatrix); @@ -616,7 +619,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition CGAffineTransformConcat(cgMatrix, oldTextMatrix); if (synthesisFlags & QFontEngine::SynthesizedItalic) - cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0)); + cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, SYNTHETIC_ITALIC_SKEW, 1, 0, 0)); cgMatrix = CGAffineTransformConcat(cgMatrix, transform); -- cgit v0.12 From a23cab16dd4dd3505578d2747debaa28a21190ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 9 Dec 2010 14:21:26 +0100 Subject: Fixed DeviceCoordinateCache items when using QGraphicsScene::render(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since viewRect is null, we shouldn't try to use the partialCacheExposure path which intersects the viewRect with the device rect of the item. Task-number: QTBUG-15977 Reviewed-by: Bjørn Erik Nilsen --- src/gui/graphicsview/qgraphicsscene.cpp | 4 ++-- tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index a0015dc..726e6d7 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4583,13 +4583,13 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte itemCache->exposed.clear(); deviceData->cacheIndent = QPoint(); pix = QPixmap(); - } else { + } else if (!viewRect.isNull()) { allowPartialCacheExposure = deviceData->cacheIndent != QPoint(); } // Allow partial cache exposure if the device rect isn't fully contained and // deviceRect is 20% taller or wider than the viewRect. - if (!allowPartialCacheExposure && !viewRect.contains(deviceRect)) { + if (!allowPartialCacheExposure && !viewRect.isNull() && !viewRect.contains(deviceRect)) { allowPartialCacheExposure = (viewRect.width() * 1.2 < deviceRect.width()) || (viewRect.height() * 1.2 < deviceRect.height()); } diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 6a2f849..588c476 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -288,6 +288,7 @@ private slots: void taskQT657_paintIntoCacheWithTransparentParts(); void taskQTBUG_7863_paintIntoCacheWithTransparentParts(); void taskQT_3674_doNotCrash(); + void taskQTBUG_15977_renderWithDeviceCoordinateCache(); }; void tst_QGraphicsScene::initTestCase() @@ -4629,5 +4630,27 @@ void tst_QGraphicsScene::zeroScale() QTRY_COMPARE(cl.changes.count(), 2); } +void tst_QGraphicsScene::taskQTBUG_15977_renderWithDeviceCoordinateCache() +{ + QGraphicsScene scene; + scene.setSceneRect(0, 0, 100, 100); + QGraphicsRectItem *rect = scene.addRect(0, 0, 100, 100); + rect->setPen(Qt::NoPen); + rect->setBrush(Qt::red); + rect->setCacheMode(QGraphicsItem::DeviceCoordinateCache); + + QImage image(100, 100, QImage::Format_RGB32); + QPainter p(&image); + scene.render(&p); + p.end(); + + QImage expected(100, 100, QImage::Format_RGB32); + p.begin(&expected); + p.fillRect(expected.rect(), Qt::red); + p.end(); + + QCOMPARE(image, expected); +} + QTEST_MAIN(tst_QGraphicsScene) #include "tst_qgraphicsscene.moc" -- cgit v0.12 From fcd578e713a5a1c165ff78bab98487185a9f4d15 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 9 Dec 2010 15:20:36 +0100 Subject: Watch qrc files also when they are empty Reviewed-by: Friedemann Kleint Task-number: QTCREATORBUG-825 --- tools/designer/src/lib/shared/qtresourcemodel.cpp | 50 ++++++++++++----------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/tools/designer/src/lib/shared/qtresourcemodel.cpp b/tools/designer/src/lib/shared/qtresourcemodel.cpp index e3fc805..d04a5fc 100644 --- a/tools/designer/src/lib/shared/qtresourcemodel.cpp +++ b/tools/designer/src/lib/shared/qtresourcemodel.cpp @@ -184,15 +184,15 @@ const QByteArray *QtResourceModelPrivate::createResource(const QString &path, QS break; // return code cannot be fully trusted, might still be empty const ResourceDataFileMap resMap = library.resourceDataFileMap(); - if (resMap.empty()) - break; - if (!library.output(buffer, errorDevice)) break; *errorCount = library.failedResources().size(); *contents = resMap.keys(); + if (resMap.empty()) + break; + buffer.close(); rc = new QByteArray(buffer.data()); } while (false); @@ -225,15 +225,18 @@ void QtResourceModelPrivate::registerResourceSet(QtResourceSet *resourceSet) qDebug() << "registerResourceSet " << path; const PathDataMap::const_iterator itRcc = m_pathToData.constFind(path); if (itRcc != m_pathToData.constEnd()) { // otherwise data was not created yet - if (!QResource::registerResource(reinterpret_cast(itRcc.value()->constData()))) { - qDebug() << "** WARNING: Failed to register " << path << " (QResource failure)."; - } else { - QStringList contents = m_pathToContents.value(path); - QStringListIterator itContents(contents); - while (itContents.hasNext()) { - const QString filePath = itContents.next(); - if (!m_fileToQrc.contains(filePath)) // the first loaded resource has higher priority in qt resource system - m_fileToQrc.insert(filePath, path); + const QByteArray *data = itRcc.value(); + if (data) { + if (!QResource::registerResource(reinterpret_cast(data->constData()))) { + qWarning() << "** WARNING: Failed to register " << path << " (QResource failure)."; + } else { + QStringList contents = m_pathToContents.value(path); + QStringListIterator itContents(contents); + while (itContents.hasNext()) { + const QString filePath = itContents.next(); + if (!m_fileToQrc.contains(filePath)) // the first loaded resource has higher priority in qt resource system + m_fileToQrc.insert(filePath, path); + } } } } @@ -254,8 +257,11 @@ void QtResourceModelPrivate::unregisterResourceSet(QtResourceSet *resourceSet) qDebug() << "unregisterResourceSet " << path; const PathDataMap::const_iterator itRcc = m_pathToData.constFind(path); if (itRcc != m_pathToData.constEnd()) { // otherwise data was not created yet - if (!QResource::unregisterResource(reinterpret_cast(itRcc.value()->constData()))) - qDebug() << "** WARNING: Failed to unregister " << path << " (QResource failure)."; + const QByteArray *data = itRcc.value(); + if (data) { + if (!QResource::unregisterResource(reinterpret_cast(itRcc.value()->constData()))) + qWarning() << "** WARNING: Failed to unregister " << path << " (QResource failure)."; + } } } m_fileToQrc.clear(); @@ -292,15 +298,13 @@ void QtResourceModelPrivate::activate(QtResourceSet *resourceSet, const QStringL QStringList contents; int qrcErrorCount; generatedCount++; - if (const QByteArray *data = createResource(path, &contents, &qrcErrorCount, errorStream)) { - newPathToData.insert(path, data); - if (qrcErrorCount) // Count single failed files as sort of 1/2 error - errorCount++; - addWatcher(path); - } else { - newPathToData.remove(path); + const QByteArray *data = createResource(path, &contents, &qrcErrorCount, errorStream); + + newPathToData.insert(path, data); + if (qrcErrorCount) // Count single failed files as sort of 1/2 error errorCount++; - } + addWatcher(path); + m_pathToModified.insert(path, false); m_pathToContents.insert(path, contents); newResourceSetChanged = true; @@ -326,7 +330,7 @@ void QtResourceModelPrivate::activate(QtResourceSet *resourceSet, const QStringL QListIterator itOld(oldData); if (itOld.hasNext()) { const QByteArray *array = itOld.next(); - if (!newData.contains(array)) + if (array && !newData.contains(array)) toDelete.append(array); } -- cgit v0.12 From 0c7687458c524252dae26deb32f7a3b8a38491f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 9 Dec 2010 17:17:22 +0100 Subject: Try using pure scissor clip in GL 2 engine for rotations. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As long as the final clip area is rectangular and axis aligned we can use a scissor clip. This prevents performance problems when doing 90-degree rotated rectangle clips. Reviewed-by: Bjørn Erik Nilsen --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index ac41c04..7045fe9 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -2141,7 +2141,11 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op) const QPointF* const points = reinterpret_cast(path.points()); QRectF rect(points[0], points[2]); - if (state()->matrix.type() <= QTransform::TxScale) { + if (state()->matrix.type() <= QTransform::TxScale + || (state()->matrix.type() == QTransform::TxRotate + && qFuzzyIsNull(state()->matrix.m11()) + && qFuzzyIsNull(state()->matrix.m22()))) + { state()->rectangleClip = state()->rectangleClip.intersected(state()->matrix.mapRect(rect).toRect()); d->updateClipScissorTest(); return; -- cgit v0.12 From 4c870f3fe88d14e2efa19b924d9f89dea0a6931c Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Thu, 9 Dec 2010 19:23:04 +0100 Subject: Runtime dependency on Symbians Font Table API The Symbian Font Table API is a feature from (the former) Symbian^4 which will be backported into Symbian^3 in a random minor OS version. In order to keep Qt source and binary compatible between these minor versions, we cannot decide at compile time whether or not to use the new Font Table API. This patch changes many "#ifdef Q_SYMBIAN_HAS_FONTTABLE_API" into "if (symbianFontTableApiAvailable())". The Font Table feature is detected at runtime. Currently, CFeatureDiscovery is not used, because at the time of writing, that feature flag test would give false positives or false negatives. Instead, CFont::ExtendedFunction() is called with KFontGetFontTable to see if the return value is KErrNone, which indicates that the feature is available. The avalibility information gets cached, so the hack happens only once per application run. The font table Api feature comes with helper classes such as "RFontTable" and "TGetFontTableParam". But we cannot use those, because we want to stay source and binary compatible across the Symbian(^3) versions without the Font table API and those with. So, in Qt, RFontTable is simply not used and TGetFontTableParam is replicated as "QSymbianTGetFontTableParam". Same for KFontGetFontTable, KFontReleaseFontTable and later also FfFontTable. This patch has been looked at by colleagues, who verified the overall #ifdef to if() conversion, but did not feel entitled to give their official Reviewed-By for an obscure topic like Qt font support on Symbian. (It sucks to be the only creature in this universe who -kind of- knows how Qt text handling and Symbian text handling interact) Task-Number: QTBUG-15515 --- src/gui/text/qfontdatabase_s60.cpp | 130 +++++++++++++------------- src/gui/text/qfontengine_s60.cpp | 182 ++++++++++++++++++++++--------------- src/gui/text/qfontengine_s60_p.h | 16 ++-- 3 files changed, 181 insertions(+), 147 deletions(-) diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 5e168c6..9a77a7a 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -116,7 +116,6 @@ public: const QSymbianTypeFaceExtras *extras(const QString &typeface, bool bold, bool italic) const; void addFontFileToFontStore(const QFileInfo &fontFileInfo); -#ifndef Q_SYMBIAN_HAS_FONTTABLE_API struct CFontFromFontStoreReleaser { static inline void cleanup(CFont *font) { @@ -127,7 +126,6 @@ public: dbExtras->m_store->ReleaseFont(font); } }; -#endif // !Q_SYMBIAN_HAS_FONTTABLE_API struct CFontFromScreenDeviceReleaser { static inline void cleanup(CFont *font) @@ -138,37 +136,38 @@ public: } }; -#ifndef Q_SYMBIAN_HAS_FONTTABLE_API +// m_heap, m_store, m_rasterizer and m_extras are used if Symbian +// does not provide the Font Table API RHeap* m_heap; CFontStore *m_store; COpenFontRasterizer *m_rasterizer; mutable QList m_extras; -#endif // !Q_SYMBIAN_HAS_FONTTABLE_API + mutable QHash m_extrasHash; }; QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementation() { -#ifndef Q_SYMBIAN_HAS_FONTTABLE_API - QStringList filters; - filters.append(QLatin1String("*.ttf")); - filters.append(QLatin1String("*.ccc")); - filters.append(QLatin1String("*.ltt")); - const QFileInfoList fontFiles = alternativeFilePaths(QLatin1String("resource\\Fonts"), filters); - - const TInt heapMinLength = 0x1000; - const TInt heapMaxLength = qMax(0x20000 * fontFiles.count(), heapMinLength); - m_heap = User::ChunkHeap(NULL, heapMinLength, heapMaxLength); - QT_TRAP_THROWING( - m_store = CFontStore::NewL(m_heap); - m_rasterizer = COpenFontRasterizer::NewL(TUid::Uid(0x101F7F5E)); - CleanupStack::PushL(m_rasterizer); - m_store->InstallRasterizerL(m_rasterizer); - CleanupStack::Pop(m_rasterizer);); - - foreach (const QFileInfo &fontFileInfo, fontFiles) - addFontFileToFontStore(fontFileInfo); -#endif // !Q_SYMBIAN_HAS_FONTTABLE_API + if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) { + QStringList filters; + filters.append(QLatin1String("*.ttf")); + filters.append(QLatin1String("*.ccc")); + filters.append(QLatin1String("*.ltt")); + const QFileInfoList fontFiles = alternativeFilePaths(QLatin1String("resource\\Fonts"), filters); + + const TInt heapMinLength = 0x1000; + const TInt heapMaxLength = qMax(0x20000 * fontFiles.count(), heapMinLength); + m_heap = User::ChunkHeap(NULL, heapMinLength, heapMaxLength); + QT_TRAP_THROWING( + m_store = CFontStore::NewL(m_heap); + m_rasterizer = COpenFontRasterizer::NewL(TUid::Uid(0x101F7F5E)); + CleanupStack::PushL(m_rasterizer); + m_store->InstallRasterizerL(m_rasterizer); + CleanupStack::Pop(m_rasterizer);); + + foreach (const QFileInfo &fontFileInfo, fontFiles) + addFontFileToFontStore(fontFileInfo); + } } void qt_cleanup_symbianFontDatabaseExtras() @@ -177,26 +176,26 @@ void qt_cleanup_symbianFontDatabaseExtras() static_cast(privateDb()->symbianExtras); if (!dbExtras) return; // initializeDb() has never been called -#ifdef Q_SYMBIAN_HAS_FONTTABLE_API - qDeleteAll(dbExtras->m_extrasHash); -#else // Q_SYMBIAN_HAS_FONTTABLE_API - typedef QList::iterator iterator; - for (iterator p = dbExtras->m_extras.begin(); p != dbExtras->m_extras.end(); ++p) { - dbExtras->m_store->ReleaseFont((*p)->fontOwner()); - delete *p; + if (QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) { + qDeleteAll(dbExtras->m_extrasHash); + } else { + typedef QList::iterator iterator; + for (iterator p = dbExtras->m_extras.begin(); p != dbExtras->m_extras.end(); ++p) { + dbExtras->m_store->ReleaseFont((*p)->fontOwner()); + delete *p; + } + dbExtras->m_extras.clear(); } - dbExtras->m_extras.clear(); -#endif // Q_SYMBIAN_HAS_FONTTABLE_API dbExtras->m_extrasHash.clear(); } QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementation() { qt_cleanup_symbianFontDatabaseExtras(); -#ifndef Q_SYMBIAN_HAS_FONTTABLE_API - delete m_store; - m_heap->Close(); -#endif // !Q_SYMBIAN_HAS_FONTTABLE_API + if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) { + delete m_store; + m_heap->Close(); + } } #ifndef FNTSTORE_H_INLINES_SUPPORT_FMM @@ -228,44 +227,45 @@ const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(c searchSpec.iFontStyle.SetPosture(EPostureItalic); CFont* font = NULL; -#ifdef Q_SYMBIAN_HAS_FONTTABLE_API - const TInt err = S60->screenDevice()->GetNearestFontToDesignHeightInPixels(font, searchSpec); - Q_ASSERT(err == KErrNone && font); - QScopedPointer sFont(font); - QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font); - sFont.take(); - m_extrasHash.insert(searchKey, extras); -#else // Q_SYMBIAN_HAS_FONTTABLE_API - const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec); - Q_ASSERT(err == KErrNone && font); - const CBitmapFont *bitmapFont = static_cast(font); - COpenFont *openFont = -#ifdef FNTSTORE_H_INLINES_SUPPORT_FMM - bitmapFont->OpenFont(); -#else // FNTSTORE_H_INLINES_SUPPORT_FMM - OpenFontFromBitmapFont(bitmapFont); -#endif // FNTSTORE_H_INLINES_SUPPORT_FMM - const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib(); - const QString foundKey = - QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length()); - if (!m_extrasHash.contains(foundKey)) { - QScopedPointer sFont(font); - QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont); + if (QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) { + const TInt err = S60->screenDevice()->GetNearestFontToDesignHeightInPixels(font, searchSpec); + Q_ASSERT(err == KErrNone && font); + QScopedPointer sFont(font); + QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font); sFont.take(); - m_extras.append(extras); m_extrasHash.insert(searchKey, extras); - m_extrasHash.insert(foundKey, extras); } else { - m_store->ReleaseFont(font); - m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey)); + const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec); + Q_ASSERT(err == KErrNone && font); + const CBitmapFont *bitmapFont = static_cast(font); + COpenFont *openFont = +#ifdef FNTSTORE_H_INLINES_SUPPORT_FMM + bitmapFont->OpenFont(); +#else // FNTSTORE_H_INLINES_SUPPORT_FMM + OpenFontFromBitmapFont(bitmapFont); +#endif // FNTSTORE_H_INLINES_SUPPORT_FMM + const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib(); + const QString foundKey = + QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length()); + if (!m_extrasHash.contains(foundKey)) { + QScopedPointer sFont(font); + QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont); + sFont.take(); + m_extras.append(extras); + m_extrasHash.insert(searchKey, extras); + m_extrasHash.insert(foundKey, extras); + } else { + m_store->ReleaseFont(font); + m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey)); + } } -#endif // Q_SYMBIAN_HAS_FONTTABLE_API } return m_extrasHash.value(searchKey); } void QSymbianFontDatabaseExtrasImplementation::addFontFileToFontStore(const QFileInfo &fontFileInfo) { + Q_ASSERT(!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()); const QString fontFile = QDir::toNativeSeparators(fontFileInfo.absoluteFilePath()); TPtrC fontFilePtr(qt_QString2TPtrC(fontFile)); QT_TRAP_THROWING(m_store->AddFileL(fontFilePtr)); diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp index bf30e1c..f8e5b4a 100644 --- a/src/gui/text/qfontengine_s60.cpp +++ b/src/gui/text/qfontengine_s60.cpp @@ -46,114 +46,115 @@ #include #include "qimage.h" #include +#include #include #include #include #include -#if defined(Q_SYMBIAN_HAS_FONTTABLE_API) || defined(Q_SYMBIAN_HAS_GLYPHOUTLINE_API) +#if defined(Q_SYMBIAN_HAS_GLYPHOUTLINE_API) #include -#endif // Q_SYMBIAN_HAS_FONTTABLE_API || Q_SYMBIAN_HAS_GLYPHOUTLINE_API +#endif // Q_SYMBIAN_HAS_GLYPHOUTLINE_API + +// Replication of TGetFontTableParam & friends. +// There is unfortunately no compile time flag like SYMBIAN_FONT_TABLE_API +// that would help us to only replicate these things for Symbian versions +// that do not yet have the font table Api. Symbian's public SDK does +// generally not define any usable macros. +class QSymbianTGetFontTableParam +{ +public: + TUint32 iTag; + TAny *iContent; + TInt iLength; +}; +const TUid QSymbianKFontGetFontTable = {0x102872C1}; +const TUid QSymbianKFontReleaseFontTable = {0x2002AC24}; QT_BEGIN_NAMESPACE -#ifdef Q_SYMBIAN_HAS_FONTTABLE_API QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* cFont, COpenFont *openFont) : m_cFont(cFont) , m_symbolCMap(false) + , m_openFont(openFont) { - Q_UNUSED(openFont) + if (!symbianFontTableApiAvailable()) { + TAny *trueTypeExtension = NULL; + m_openFont->ExtendedInterface(KUidOpenFontTrueTypeExtension, trueTypeExtension); + m_trueTypeExtension = static_cast(trueTypeExtension); + Q_ASSERT(m_trueTypeExtension); + } } QSymbianTypeFaceExtras::~QSymbianTypeFaceExtras() { - S60->screenDevice()->ReleaseFont(m_cFont); + if (symbianFontTableApiAvailable()) + S60->screenDevice()->ReleaseFont(m_cFont); } QByteArray QSymbianTypeFaceExtras::getSfntTable(uint tag) const { - RFontTable fontTable; - if (fontTable.Open(*m_cFont, tag) != KErrNone) + if (symbianFontTableApiAvailable()) { + QSymbianTGetFontTableParam fontTableParams = { tag, 0, 0 }; + if (m_cFont->ExtendedFunction(QSymbianKFontGetFontTable, &fontTableParams) == KErrNone) { + const char* const fontTableContent = + static_cast(fontTableParams.iContent); + const QByteArray fontTable(fontTableContent, fontTableParams.iLength); + m_cFont->ExtendedFunction(QSymbianKFontReleaseFontTable, &fontTableParams); + return fontTable; + } return QByteArray(); - const QByteArray byteArray(reinterpret_cast - (fontTable.TableContent()),fontTable.TableLength()); - fontTable.Close(); - return byteArray; + } else { + Q_ASSERT(m_trueTypeExtension->HasTrueTypeTable(tag)); + TInt error = KErrNone; + TInt tableByteLength = 0; + TAny *table = q_check_ptr(m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength)); + const QByteArray result(static_cast(table), tableByteLength); + m_trueTypeExtension->ReleaseTrueTypeTable(table); + return result; + } } bool QSymbianTypeFaceExtras::getSfntTableData(uint tag, uchar *buffer, uint *length) const { - RFontTable fontTable; - if (fontTable.Open(*m_cFont, tag) != KErrNone) - return false; - bool result = true; - const TInt tableByteLength = fontTable.TableLength(); - - if (*length > 0 && *length < tableByteLength) { - result = false; // Caller did not allocate enough memory + if (symbianFontTableApiAvailable()) { + QSymbianTGetFontTableParam fontTableParams = { tag, 0, 0 }; + if (m_cFont->ExtendedFunction(QSymbianKFontGetFontTable, &fontTableParams) == KErrNone) { + if (*length > 0 && *length < fontTableParams.iLength) { + result = false; // Caller did not allocate enough memory + } else { + *length = fontTableParams.iLength; + if (buffer) + memcpy(buffer, fontTableParams.iContent, fontTableParams.iLength); + } + m_cFont->ExtendedFunction(QSymbianKFontReleaseFontTable, &fontTableParams); + } else { + result = false; + } } else { - *length = tableByteLength; - if (buffer) - memcpy(buffer, fontTable.TableContent(), tableByteLength); - } - - fontTable.Close(); - return result; -} - -#else // Q_SYMBIAN_HAS_FONTTABLE_API -QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* cFont, COpenFont *openFont) - : m_cFont(cFont) - , m_symbolCMap(false) - , m_openFont(openFont) -{ - TAny *trueTypeExtension = NULL; - m_openFont->ExtendedInterface(KUidOpenFontTrueTypeExtension, trueTypeExtension); - m_trueTypeExtension = static_cast(trueTypeExtension); - Q_ASSERT(m_trueTypeExtension); -} - -QSymbianTypeFaceExtras::~QSymbianTypeFaceExtras() -{ -} - -QByteArray QSymbianTypeFaceExtras::getSfntTable(uint tag) const -{ - Q_ASSERT(m_trueTypeExtension->HasTrueTypeTable(tag)); - TInt error = KErrNone; - TInt tableByteLength = 0; - TAny *table = q_check_ptr(m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength)); - QByteArray result(static_cast(table), tableByteLength); - m_trueTypeExtension->ReleaseTrueTypeTable(table); - return result; -} + if (!m_trueTypeExtension->HasTrueTypeTable(tag)) + return false; -bool QSymbianTypeFaceExtras::getSfntTableData(uint tag, uchar *buffer, uint *length) const -{ - if (!m_trueTypeExtension->HasTrueTypeTable(tag)) - return false; + TInt error = KErrNone; + TInt tableByteLength; + TAny *table = + q_check_ptr(m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength)); - bool result = true; - TInt error = KErrNone; - TInt tableByteLength; - TAny *table = - q_check_ptr(m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength)); + if (error != KErrNone) { + return false; + } else if (*length > 0 && *length < tableByteLength) { + result = false; // Caller did not allocate enough memory + } else { + *length = tableByteLength; + if (buffer) + memcpy(buffer, table, tableByteLength); + } - if (error != KErrNone) { - return false; - } else if (*length > 0 && *length < tableByteLength) { - result = false; // Caller did not allocate enough memory - } else { - *length = tableByteLength; - if (buffer) - memcpy(buffer, table, tableByteLength); + m_trueTypeExtension->ReleaseTrueTypeTable(table); } - - m_trueTypeExtension->ReleaseTrueTypeTable(table); return result; } -#endif // Q_SYMBIAN_HAS_FONTTABLE_API const uchar *QSymbianTypeFaceExtras::cmap() const { @@ -195,6 +196,39 @@ QFixed QSymbianTypeFaceExtras::unitsPerEm() const return m_unitsPerEm; } +bool QSymbianTypeFaceExtras::symbianFontTableApiAvailable() +{ + enum FontTableApiAvailability { + Unknown, + Available, + Unavailable + }; + static FontTableApiAvailability availability = + QSysInfo::symbianVersion() < QSysInfo::SV_SF_3 ? + Unavailable : Unknown; + if (availability == Unknown) { + // Actually, we should ask CFeatureDiscovery::IsFeatureSupportedL() + // with FfFontTable here. But since at the time of writing, the + // FfFontTable flag check either gave false positives or false + // negatives. Here comes an implicit check via CFont::ExtendedFunction. + QSymbianTGetFontTableParam fontTableParams = { + MAKE_TAG('O', 'S', '/', '2'), 0, 0 }; + QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); + CFont *font; + const TInt getFontErr = S60->screenDevice()->GetNearestFontInTwips(font, TFontSpec()); + Q_ASSERT(getFontErr == KErrNone); + if (font->ExtendedFunction(QSymbianKFontGetFontTable, &fontTableParams) == KErrNone) { + font->ExtendedFunction(QSymbianKFontReleaseFontTable, &fontTableParams); + availability = Available; + } else { + availability = Unavailable; + } + S60->screenDevice()->ReleaseFont(font); + lock.relock(); + } + return availability == Available; +} + // duplicated from qfontengine_xyz.cpp static inline unsigned int getChar(const QChar *str, int &i, const int len) { diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h index c65ce55..cdf2185 100644 --- a/src/gui/text/qfontengine_s60_p.h +++ b/src/gui/text/qfontengine_s60_p.h @@ -58,13 +58,11 @@ #include "qsize.h" #include -#ifdef SYMBIAN_GDI_GLYPHDATA -#define Q_SYMBIAN_HAS_FONTTABLE_API -#endif - -#ifdef Q_SYMBIAN_HAS_FONTTABLE_API +// The glyph outline code is intentionally disabled. It will be reactivated as +// soon as the glyph outline API is backported from Symbian(^4) to Symbian(^3). +#if 0 #define Q_SYMBIAN_HAS_GLYPHOUTLINE_API -#endif // Q_SYMBIAN_HAS_FONTTABLE_API +#endif class CFont; @@ -83,16 +81,18 @@ public: CFont *fontOwner() const; bool isSymbolCMap() const; QFixed unitsPerEm() const; + static bool symbianFontTableApiAvailable(); private: CFont* m_cFont; mutable bool m_symbolCMap; mutable QByteArray m_cmapTable; mutable QFixed m_unitsPerEm; -#ifndef Q_SYMBIAN_HAS_FONTTABLE_API + + // m_openFont and m_openFont are used if Symbian does not provide + // the Font Table API COpenFont *m_openFont; mutable MOpenFontTrueTypeExtension *m_trueTypeExtension; -#endif // Q_SYMBIAN_HAS_FONTTABLE_API }; class QFontEngineS60 : public QFontEngine -- cgit v0.12 From bb07641213dfc4c949707500c3d665fae5f4b9f0 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Tue, 7 Dec 2010 14:19:43 +1000 Subject: QDeclarativeProperty doc improvements --- src/declarative/qml/qdeclarativeproperty.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index df0917f..60edd64 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -77,15 +77,28 @@ a property on a specific object instance. To read a property's value, programme QDeclarativeProperty instance and call the read() method. Likewise to write a property value the write() method is used. +For example, for the following QML code: + +\qml +// MyItem.qml +import QtQuick 1.0 + +Text { text: "A bit of text" } +\endqml + +The \l Text object's properties could be accessed using QDeclarativeProperty, like this: + \code +#include +#include -QObject *object = declarativeComponent.create(); +... -QDeclarativeProperty property(object, "font.pixelSize"); +QDeclarativeView view(QUrl::fromLocalFile("MyItem.qml")); +QDeclarativeProperty property(view.rootObject(), "font.pixelSize"); qWarning() << "Current pixel size:" << property.read().toInt(); property.write(24); qWarning() << "Pixel size should now be 24:" << property.read().toInt(); - \endcode */ -- cgit v0.12 From b8da3a08945091d077d3096efae23d613b24210b Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Thu, 9 Dec 2010 14:23:42 +1000 Subject: Improvements to anchoring docs Make it clear that anchor margins only apply to anchors. Also document that anchor and absolute positioning cannot be mixed. --- doc/src/declarative/anchor-layout.qdoc | 66 ++++++++++++++++------ src/declarative/graphicsitems/qdeclarativeitem.cpp | 2 + 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/doc/src/declarative/anchor-layout.qdoc b/doc/src/declarative/anchor-layout.qdoc index b77ce36..f5d5697 100644 --- a/doc/src/declarative/anchor-layout.qdoc +++ b/doc/src/declarative/anchor-layout.qdoc @@ -30,6 +30,8 @@ \target anchor-layout \title Anchor-based Layout in QML +\section1 Overview + In addition to the more traditional \l Grid, \l Row, and \l Column, QML also provides a way to layout items using the concept of \e anchors. Each item can be thought of as having a set of 7 invisible "anchor lines": @@ -54,20 +56,6 @@ In this case, the left edge of \e rect2 is bound to the right edge of \e rect1, \image edge1.png -The anchoring system also allows you to specify margins and offsets. Margins specify the amount of empty space to leave to the outside of an item, while offsets allow you to manipulate positioning using the center anchor lines. Note that margins specified using the anchor layout system only have meaning for anchors; they won't have any effect when using other layouts or absolute positioning. - -\image margins_qml.png - -The following example specifies a left margin: - -\code -Rectangle { id: rect1; ... } -Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... } -\endcode - -In this case, a margin of 5 pixels is reserved to the left of \e rect2, producing the following: - -\image edge2.png You can specify multiple anchors. For example: @@ -78,7 +66,9 @@ Rectangle { id: rect2; anchors.left: rect1.right; anchors.top: rect1.bottom; ... \image edge3.png -By specifying multiple horizontal or vertical anchors you can control the size of an item. For example: +By specifying multiple horizontal or vertical anchors you can control the size of an item. Below, +\e rect2 is anchored to the right of \e rect1 and the left of \e rect3. If either of the blue +rectangles are moved, \e rect2 will stretch and shrink as necessary: \code Rectangle { id: rect1; x: 0; ... } @@ -88,9 +78,42 @@ Rectangle { id: rect3; x: 150; ... } \image edge4.png -\section1 Limitations -For performance reasons, you can only anchor an item to its siblings and direct parent. For example, the following anchor would be considered invalid and would produce a warning: +\section1 Anchor Margins and Offsets + +The anchoring system also allows \e margins and \e offsets to be specified for an item's anchors. +Margins specify the amount of empty space to leave to the outside of an item's anchor, while +offsets allow positioning to be manipulated using the center anchor lines. An item can +specify its anchor margins individually through \l {Item::anchors.leftMargin}{leftMargin}, +\l {Item::anchors.rightMargin}{rightMargin}, \l {Item::anchors.topMargin}{topMargin} and +\l {Item::anchors.bottomMargin}{bottomMargin}, or use \l {Item::}{anchors.margins} to +specify the same margin value for all four edges. Anchor offsets are specified using +\l {Item::anchors.horizontalCenterOffset}{horizontalCenterOffset}, +\l {Item::anchors.verticalCenterOffset}{verticalCenterOffset} and +\l {Item::anchors.baselineOffset}{baselineOffset}. + +\image margins_qml.png + +The following example specifies a left margin: + +\code +Rectangle { id: rect1; ... } +Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... } +\endcode + +In this case, a margin of 5 pixels is reserved to the left of \e rect2, producing the following: + +\image edge2.png + +\note Anchor margins only apply to anchors; they are \e not a generic means of applying margins to an \l Item. +If an anchor margin is specified for an edge but the item is not anchored to any item on that +edge, the margin is not applied. + + +\section1 Restrictions + +For performance reasons, you can only anchor an item to its siblings and direct parent. For example, +the following anchor is invalid and would produce a warning: \badcode Item { @@ -103,4 +126,13 @@ Item { } \endcode +Also, anchor-based layouts cannot be mixed with absolute positioning. If an item specifies its +\l {Item::}{x} position and also sets \l {Item::}{anchors.left}, +or anchors its left and right edges but additionally sets a \l {Item::}{width}, the +result is undefined, as it would not be clear whether the item should use anchoring or absolute +positioning. The same can be said for setting an item's \l {Item::}{y} and \l {Item::}{height} +with \l {Item::}{anchors.top} and \l {Item::}{anchors.bottom}, or setting \l {Item::}{anchors.fill} +as well as \l {Item::}{width} or \l {Item::}{height}. If you wish to change from using +anchor-based to absolute positioning, you can clear an anchor value by setting it to \c undefined. + */ diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 932e68f..75e4a0b 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -2112,6 +2112,8 @@ QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const Margins apply to top, bottom, left, right, and fill anchors. The \c anchors.margins property can be used to set all of the various margins at once, to the same value. + Note that margins are anchor-specific and are not applied if an item does not + use anchors. Offsets apply for horizontal center, vertical center, and baseline anchors. -- cgit v0.12 From 36f88ca5bdace12bb713085a11351d06318534d7 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 10 Dec 2010 13:47:27 +1000 Subject: minor clean-ups and styling fixes Merge-request: 899 Reviewed-by: Aaron McCarthy --- src/network/bearer/bearer.pri | 1 - src/network/bearer/qbearerengine.cpp | 14 ++-- src/network/bearer/qbearerengine_p.h | 5 +- src/network/bearer/qbearerplugin.cpp | 4 +- src/network/bearer/qbearerplugin_p.h | 2 +- src/network/bearer/qnetworkconfigmanager.cpp | 16 ++--- src/network/bearer/qnetworkconfigmanager.h | 18 ++--- src/network/bearer/qnetworkconfigmanager_p.cpp | 57 ++++++---------- src/network/bearer/qnetworkconfigmanager_p.h | 28 ++++---- src/network/bearer/qnetworkconfiguration.cpp | 30 ++++----- src/network/bearer/qnetworkconfiguration.h | 11 ++-- src/network/bearer/qnetworkconfiguration_p.h | 17 ++--- src/network/bearer/qnetworksession.cpp | 91 ++++++++++++-------------- src/network/bearer/qnetworksession.h | 17 ++--- src/network/bearer/qnetworksession_p.h | 20 +++--- src/plugins/bearer/platformdefs_win.h | 2 +- src/plugins/bearer/qbearerengine_impl.h | 7 +- src/plugins/bearer/qnetworksession_impl.cpp | 67 ++++++------------- src/plugins/bearer/qnetworksession_impl.h | 23 +++---- 19 files changed, 180 insertions(+), 250 deletions(-) diff --git a/src/network/bearer/bearer.pri b/src/network/bearer/bearer.pri index 44e97fd..bc5b0b5 100644 --- a/src/network/bearer/bearer.pri +++ b/src/network/bearer/bearer.pri @@ -15,4 +15,3 @@ SOURCES += bearer/qnetworksession.cpp \ bearer/qnetworkconfigmanager_p.cpp \ bearer/qbearerengine.cpp \ bearer/qbearerplugin.cpp - diff --git a/src/network/bearer/qbearerengine.cpp b/src/network/bearer/qbearerengine.cpp index b074924..ee7c66e 100644 --- a/src/network/bearer/qbearerengine.cpp +++ b/src/network/bearer/qbearerengine.cpp @@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE QBearerEngine::QBearerEngine(QObject *parent) -: QObject(parent), mutex(QMutex::Recursive) + : QObject(parent), mutex(QMutex::Recursive) { } @@ -54,6 +54,7 @@ QBearerEngine::~QBearerEngine() { QHash::Iterator it; QHash::Iterator end; + for (it = snapConfigurations.begin(), end = snapConfigurations.end(); it != end; ++it) { it.value()->isValid = false; it.value()->id.clear(); @@ -93,19 +94,20 @@ bool QBearerEngine::configurationsInUse() const QMutexLocker locker(&mutex); - for (it = accessPointConfigurations.begin(), - end = accessPointConfigurations.end(); it != end; ++it) { + for (it = accessPointConfigurations.constBegin(), + end = accessPointConfigurations.constEnd(); it != end; ++it) { if (it.value()->ref > 1) return true; } - for (it = snapConfigurations.begin(), end = snapConfigurations.end(); it != end; ++it) { + for (it = snapConfigurations.constBegin(), + end = snapConfigurations.constEnd(); it != end; ++it) { if (it.value()->ref > 1) return true; } - for (it = userChoiceConfigurations.begin(), - end = userChoiceConfigurations.end(); it != end; ++it) { + for (it = userChoiceConfigurations.constBegin(), + end = userChoiceConfigurations.constEnd(); it != end; ++it) { if (it.value()->ref > 1) return true; } diff --git a/src/network/bearer/qbearerengine_p.h b/src/network/bearer/qbearerengine_p.h index 70aa5fa..bac6b14 100644 --- a/src/network/bearer/qbearerengine_p.h +++ b/src/network/bearer/qbearerengine_p.h @@ -78,7 +78,7 @@ class Q_NETWORK_EXPORT QBearerEngine : public QObject friend class QNetworkConfigurationManagerPrivate; public: - QBearerEngine(QObject *parent = 0); + explicit QBearerEngine(QObject *parent = 0); virtual ~QBearerEngine(); virtual bool hasIdentifier(const QString &id) = 0; @@ -96,7 +96,6 @@ Q_SIGNALS: void configurationAdded(QNetworkConfigurationPrivatePointer config); void configurationRemoved(QNetworkConfigurationPrivatePointer config); void configurationChanged(QNetworkConfigurationPrivatePointer config); - void updateCompleted(); protected: @@ -114,4 +113,4 @@ QT_END_NAMESPACE #endif // QT_NO_BEARERMANAGEMENT -#endif +#endif // QBEARERENGINE_P_H diff --git a/src/network/bearer/qbearerplugin.cpp b/src/network/bearer/qbearerplugin.cpp index a5e8918..b92982f 100644 --- a/src/network/bearer/qbearerplugin.cpp +++ b/src/network/bearer/qbearerplugin.cpp @@ -41,14 +41,12 @@ #include "qbearerplugin_p.h" -#include - #ifndef QT_NO_BEARERMANAGEMENT QT_BEGIN_NAMESPACE QBearerEnginePlugin::QBearerEnginePlugin(QObject *parent) -: QObject(parent) + : QObject(parent) { } diff --git a/src/network/bearer/qbearerplugin_p.h b/src/network/bearer/qbearerplugin_p.h index 9652f14..3dbea9d 100644 --- a/src/network/bearer/qbearerplugin_p.h +++ b/src/network/bearer/qbearerplugin_p.h @@ -93,4 +93,4 @@ QT_END_HEADER #endif // QT_NO_BEARERMANAGEMENT -#endif +#endif // QBEARERPLUGIN_P_H diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp index 4c149a2..8b6d45f 100644 --- a/src/network/bearer/qnetworkconfigmanager.cpp +++ b/src/network/bearer/qnetworkconfigmanager.cpp @@ -124,14 +124,14 @@ QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate() */ /*! - \fn void QNetworkConfigurationManager::configurationAdded(const QNetworkConfiguration& config) + \fn void QNetworkConfigurationManager::configurationAdded(const QNetworkConfiguration &config) This signal is emitted whenever a new network configuration is added to the system. The new configuration is specified by \a config. */ /*! - \fn void QNetworkConfigurationManager::configurationRemoved(const QNetworkConfiguration& configuration) + \fn void QNetworkConfigurationManager::configurationRemoved(const QNetworkConfiguration &config) This signal is emitted when a configuration is about to be removed from the system. The removed \a configuration is invalid but retains name and identifier. @@ -144,7 +144,7 @@ QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate() be initiated via \l updateConfigurations(). */ -/*! \fn void QNetworkConfigurationManager::configurationChanged(const QNetworkConfiguration& config) +/*! \fn void QNetworkConfigurationManager::configurationChanged(const QNetworkConfiguration &config) This signal is emitted when the \l {QNetworkConfiguration::state()}{state} of \a config changes. */ @@ -204,7 +204,7 @@ QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate() /*! Constructs a QNetworkConfigurationManager with the given \a parent. */ -QNetworkConfigurationManager::QNetworkConfigurationManager( QObject* parent ) +QNetworkConfigurationManager::QNetworkConfigurationManager(QObject *parent) : QObject(parent) { QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate(); @@ -213,12 +213,12 @@ QNetworkConfigurationManager::QNetworkConfigurationManager( QObject* parent ) this, SIGNAL(configurationAdded(QNetworkConfiguration))); connect(priv, SIGNAL(configurationRemoved(QNetworkConfiguration)), this, SIGNAL(configurationRemoved(QNetworkConfiguration))); - connect(priv, SIGNAL(configurationUpdateComplete()), - this, SIGNAL(updateCompleted())); - connect(priv, SIGNAL(onlineStateChanged(bool)), - this, SIGNAL(onlineStateChanged(bool))); connect(priv, SIGNAL(configurationChanged(QNetworkConfiguration)), this, SIGNAL(configurationChanged(QNetworkConfiguration))); + connect(priv, SIGNAL(onlineStateChanged(bool)), + this, SIGNAL(onlineStateChanged(bool))); + connect(priv, SIGNAL(configurationUpdateComplete()), + this, SIGNAL(updateCompleted())); priv->enablePolling(); } diff --git a/src/network/bearer/qnetworkconfigmanager.h b/src/network/bearer/qnetworkconfigmanager.h index 3e44be1..a2c5504 100644 --- a/src/network/bearer/qnetworkconfigmanager.h +++ b/src/network/bearer/qnetworkconfigmanager.h @@ -68,7 +68,6 @@ class QNetworkConfigurationManagerExport QNetworkConfigurationManager : public Q Q_OBJECT public: - enum Capability { CanStartAndStopInterfaces = 0x00000001, DirectConnectionRouting = 0x00000002, @@ -81,26 +80,24 @@ public: Q_DECLARE_FLAGS(Capabilities, Capability) - QNetworkConfigurationManager( QObject* parent = 0 ); + explicit QNetworkConfigurationManager(QObject *parent = 0); virtual ~QNetworkConfigurationManager(); - QNetworkConfigurationManager::Capabilities capabilities() const; - QNetworkConfiguration defaultConfiguration() const; + QNetworkConfiguration defaultConfiguration() const; QList allConfigurations(QNetworkConfiguration::StateFlags flags = 0) const; - QNetworkConfiguration configurationFromIdentifier(const QString& identifier) const; + QNetworkConfiguration configurationFromIdentifier(const QString &identifier) const; void updateConfigurations(); bool isOnline() const; Q_SIGNALS: - void configurationAdded(const QNetworkConfiguration& config); - void configurationRemoved(const QNetworkConfiguration& config); - void configurationChanged(const QNetworkConfiguration& config); + void configurationAdded(const QNetworkConfiguration &config); + void configurationRemoved(const QNetworkConfiguration &config); + void configurationChanged(const QNetworkConfiguration &config); void onlineStateChanged(bool isOnline); void updateCompleted(); - }; Q_DECLARE_OPERATORS_FOR_FLAGS(QNetworkConfigurationManager::Capabilities) @@ -115,5 +112,4 @@ QT_END_HEADER #endif // QT_NO_BEARERMANAGEMENT -#endif //QNETWORKCONFIGURATIONMANAGER_H - +#endif // QNETWORKCONFIGURATIONMANAGER_H diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index d388920..d33cda1 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -60,7 +60,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, #endif QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate() -: pollTimer(0), mutex(QMutex::Recursive), forcedPolling(0), firstUpdate(true) + : QObject(), pollTimer(0), mutex(QMutex::Recursive), forcedPolling(0), firstUpdate(true) { qRegisterMetaType("QNetworkConfiguration"); qRegisterMetaType("QNetworkConfigurationPrivatePointer"); @@ -79,7 +79,6 @@ QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration( foreach (QBearerEngine *engine, sessionEngines) { QNetworkConfigurationPrivatePointer ptr = engine->defaultConfiguration(); - if (ptr) { QNetworkConfiguration config; config.d = ptr; @@ -98,8 +97,8 @@ QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration( QMutexLocker locker(&engine->mutex); - for (it = engine->snapConfigurations.begin(), end = engine->snapConfigurations.end(); - it != end; ++it) { + for (it = engine->snapConfigurations.begin(), + end = engine->snapConfigurations.end(); it != end; ++it) { QNetworkConfigurationPrivatePointer ptr = it.value(); QMutexLocker configLocker(&ptr->mutex); @@ -109,10 +108,8 @@ QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration( config.d = ptr; return config; } else if (!defaultConfiguration) { - if ((ptr->state & QNetworkConfiguration::Discovered) == - QNetworkConfiguration::Discovered) { + if ((ptr->state & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) defaultConfiguration = ptr; - } } } } @@ -136,8 +133,6 @@ QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration( 6. Discovered Other */ - defaultConfiguration.reset(); - foreach (QBearerEngine *engine, sessionEngines) { QHash::Iterator it; QHash::Iterator end; @@ -151,8 +146,7 @@ QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration( QMutexLocker configLocker(&ptr->mutex); QNetworkConfiguration::BearerType bearerType = ptr->bearerType; - if ((ptr->state & QNetworkConfiguration::Discovered) == - QNetworkConfiguration::Discovered) { + if ((ptr->state & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) { if (!defaultConfiguration) { defaultConfiguration = ptr; } else { @@ -250,11 +244,11 @@ QNetworkConfiguration QNetworkConfigurationManagerPrivate::configurationFromIden QMutexLocker locker(&engine->mutex); if (engine->accessPointConfigurations.contains(identifier)) - item.d = engine->accessPointConfigurations.value(identifier); + item.d = engine->accessPointConfigurations[identifier]; else if (engine->snapConfigurations.contains(identifier)) - item.d = engine->snapConfigurations.value(identifier); + item.d = engine->snapConfigurations[identifier]; else if (engine->userChoiceConfigurations.contains(identifier)) - item.d = engine->userChoiceConfigurations.value(identifier); + item.d = engine->userChoiceConfigurations[identifier]; else continue; @@ -353,7 +347,7 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() QMutexLocker locker(&mutex); if (firstUpdate) { - if (sender()) + if (qobject_cast(sender())) return; if (thread() != QCoreApplicationPrivate::mainThread()) { @@ -366,10 +360,9 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() updating = false; #ifndef QT_NO_LIBRARY - QFactoryLoader *l = loader(); - QBearerEngine *generic = 0; + QFactoryLoader *l = loader(); foreach (const QString &key, l->keys()) { QBearerEnginePlugin *plugin = qobject_cast(l->instance(key)); if (plugin) { @@ -403,11 +396,8 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() } QBearerEngine *engine = qobject_cast(sender()); - if (!updatingEngines.isEmpty() && engine) { - int index = sessionEngines.indexOf(engine); - if (index >= 0) - updatingEngines.remove(index); - } + if (engine && !updatingEngines.isEmpty()) + updatingEngines.remove(engine); if (updating && updatingEngines.isEmpty()) { updating = false; @@ -415,10 +405,7 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() } if (engine && !pollingEngines.isEmpty()) { - int index = sessionEngines.indexOf(engine); - if (index >= 0) - pollingEngines.remove(index); - + pollingEngines.remove(engine); if (pollingEngines.isEmpty()) startPolling(); } @@ -438,9 +425,9 @@ void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate() updating = true; - for (int i = 0; i < sessionEngines.count(); ++i) { - updatingEngines.insert(i); - QMetaObject::invokeMethod(sessionEngines.at(i), "requestUpdate"); + foreach (QBearerEngine *engine, sessionEngines) { + updatingEngines.insert(engine); + QMetaObject::invokeMethod(engine, "requestUpdate"); } } @@ -482,7 +469,6 @@ void QNetworkConfigurationManagerPrivate::startPolling() pollTimer->setSingleShot(true); connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollEngines())); } - pollTimer->start(); } } @@ -491,13 +477,10 @@ void QNetworkConfigurationManagerPrivate::pollEngines() { QMutexLocker locker(&mutex); - for (int i = 0; i < sessionEngines.count(); ++i) { - if (!sessionEngines.at(i)->requiresPolling()) - continue; - - if (forcedPolling || sessionEngines.at(i)->configurationsInUse()) { - pollingEngines.insert(i); - QMetaObject::invokeMethod(sessionEngines.at(i), "requestUpdate"); + foreach (QBearerEngine *engine, sessionEngines) { + if (engine->requiresPolling() && (forcedPolling || engine->configurationsInUse())) { + pollingEngines.insert(engine); + QMetaObject::invokeMethod(engine, "requestUpdate"); } } } diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h index 0649031..45c1fb4 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.h +++ b/src/network/bearer/qnetworkconfigmanager_p.h @@ -91,17 +91,22 @@ public: void enablePolling(); void disablePolling(); -public slots: +public Q_SLOTS: void updateConfigurations(); Q_SIGNALS: - void configurationAdded(const QNetworkConfiguration& config); - void configurationRemoved(const QNetworkConfiguration& config); + void configurationAdded(const QNetworkConfiguration &config); + void configurationRemoved(const QNetworkConfiguration &config); + void configurationChanged(const QNetworkConfiguration &config); void configurationUpdateComplete(); - void configurationChanged(const QNetworkConfiguration& config); void onlineStateChanged(bool isOnline); - void abort(); +private Q_SLOTS: + void configurationAdded(QNetworkConfigurationPrivatePointer ptr); + void configurationRemoved(QNetworkConfigurationPrivatePointer ptr); + void configurationChanged(QNetworkConfigurationPrivatePointer ptr); + + void pollEngines(); private: QTimer *pollTimer; @@ -112,19 +117,12 @@ private: QSet onlineConfigurations; - QSet pollingEngines; - QSet updatingEngines; + QSet pollingEngines; + QSet updatingEngines; int forcedPolling; bool updating; bool firstUpdate; - -private Q_SLOTS: - void configurationAdded(QNetworkConfigurationPrivatePointer ptr); - void configurationRemoved(QNetworkConfigurationPrivatePointer ptr); - void configurationChanged(QNetworkConfigurationPrivatePointer ptr); - - void pollEngines(); }; Q_NETWORK_EXPORT QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate(); @@ -133,4 +131,4 @@ QT_END_NAMESPACE #endif // QT_NO_BEARERMANAGEMENT -#endif //QNETWORKCONFIGURATIONMANAGERPRIVATE_H +#endif // QNETWORKCONFIGURATIONMANAGERPRIVATE_H diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp index 3190a30..96d8bff 100644 --- a/src/network/bearer/qnetworkconfiguration.cpp +++ b/src/network/bearer/qnetworkconfiguration.cpp @@ -212,44 +212,38 @@ QNetworkConfiguration::QNetworkConfiguration() /*! Creates a copy of the QNetworkConfiguration object contained in \a other. */ -QNetworkConfiguration::QNetworkConfiguration(const QNetworkConfiguration& other) +QNetworkConfiguration::QNetworkConfiguration(const QNetworkConfiguration &other) : d(other.d) { } /*! - Copies the content of the QNetworkConfiguration object contained in \a other into this one. + Frees the resources associated with the QNetworkConfiguration object. */ -QNetworkConfiguration& QNetworkConfiguration::operator=(const QNetworkConfiguration& other) +QNetworkConfiguration::~QNetworkConfiguration() { - d = other.d; - return *this; } /*! - Frees the resources associated with the QNetworkConfiguration object. + Copies the content of the QNetworkConfiguration object contained in \a other into this one. */ -QNetworkConfiguration::~QNetworkConfiguration() +QNetworkConfiguration &QNetworkConfiguration::operator=(const QNetworkConfiguration &other) { + d = other.d; + return *this; } /*! Returns true, if this configuration is the same as the \a other configuration given; otherwise returns false. */ -bool QNetworkConfiguration::operator==(const QNetworkConfiguration& other) const +bool QNetworkConfiguration::operator==(const QNetworkConfiguration &other) const { - if (!d) - return !other.d; - - if (!other.d) - return false; - return (d == other.d); } /*! - \fn bool QNetworkConfiguration::operator!=(const QNetworkConfiguration& other) const + \fn bool QNetworkConfiguration::operator!=(const QNetworkConfiguration &other) const Returns true if this configuration is not the same as the \a other configuration given; otherwise returns false. @@ -370,11 +364,14 @@ QList QNetworkConfiguration::children() const { QList results; - if (type() != QNetworkConfiguration::ServiceNetwork || !isValid()) + if (!d) return results; QMutexLocker locker(&d->mutex); + if (d->type != QNetworkConfiguration::ServiceNetwork || !d->isValid) + return results; + QMutableMapIterator i(d->serviceNetworkMembers); while (i.hasNext()) { i.next(); @@ -510,4 +507,3 @@ QString QNetworkConfiguration::bearerTypeName() const } QT_END_NAMESPACE - diff --git a/src/network/bearer/qnetworkconfiguration.h b/src/network/bearer/qnetworkconfiguration.h index 593dbbe..475df9e 100644 --- a/src/network/bearer/qnetworkconfiguration.h +++ b/src/network/bearer/qnetworkconfiguration.h @@ -73,12 +73,12 @@ class QNetworkConfigurationExport QNetworkConfiguration public: QNetworkConfiguration(); QNetworkConfiguration(const QNetworkConfiguration& other); - QNetworkConfiguration &operator=(const QNetworkConfiguration& other); + QNetworkConfiguration &operator=(const QNetworkConfiguration &other); ~QNetworkConfiguration(); - bool operator==(const QNetworkConfiguration& cp) const; - inline bool operator!=(const QNetworkConfiguration& cp) const - { return !operator==(cp); } + bool operator==(const QNetworkConfiguration &other) const; + inline bool operator!=(const QNetworkConfiguration &other) const + { return !operator==(other); } enum Type { InternetAccessPoint = 0, @@ -100,7 +100,6 @@ public: Discovered = 0x0000006, Active = 0x000000e }; - Q_DECLARE_FLAGS(StateFlags, StateFlag) #ifndef QT_MOBILITY_BEARER @@ -155,4 +154,4 @@ QTM_END_NAMESPACE QT_END_HEADER -#endif //QNETWORKCONFIGURATION_H +#endif // QNETWORKCONFIGURATION_H diff --git a/src/network/bearer/qnetworkconfiguration_p.h b/src/network/bearer/qnetworkconfiguration_p.h index 2b0bbf6..4d41acb 100644 --- a/src/network/bearer/qnetworkconfiguration_p.h +++ b/src/network/bearer/qnetworkconfiguration_p.h @@ -65,18 +65,17 @@ typedef QExplicitlySharedDataPointer QNetworkConfi class QNetworkConfigurationPrivate : public QSharedData { public: - QNetworkConfigurationPrivate () - : mutex(QMutex::Recursive), type(QNetworkConfiguration::Invalid), + QNetworkConfigurationPrivate() : + mutex(QMutex::Recursive), + type(QNetworkConfiguration::Invalid), purpose(QNetworkConfiguration::UnknownPurpose), bearerType(QNetworkConfiguration::BearerUnknown), isValid(false), roamingSupported(false) - { - } - + {} virtual ~QNetworkConfigurationPrivate() { //release pointers to member configurations - serviceNetworkMembers.clear(); + serviceNetworkMembers.clear(); } virtual QString bearerTypeName() const @@ -100,11 +99,9 @@ public: bool roamingSupported; private: - // disallow detaching - QNetworkConfigurationPrivate &operator=(const QNetworkConfigurationPrivate &other); - QNetworkConfigurationPrivate(const QNetworkConfigurationPrivate &other); + Q_DISABLE_COPY(QNetworkConfigurationPrivate) }; QT_END_NAMESPACE -#endif //QNETWORKCONFIGURATIONPRIVATE_H +#endif // QNETWORKCONFIGURATIONPRIVATE_H diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp index 226c3c5..dedbbf9 100644 --- a/src/network/bearer/qnetworksession.cpp +++ b/src/network/bearer/qnetworksession.cpp @@ -39,11 +39,12 @@ ** ****************************************************************************/ +#include "qnetworksession.h" +#include "qbearerengine_p.h" + #include #include -#include "qnetworksession.h" -#include "qbearerengine_p.h" #include "qnetworkconfigmanager_p.h" #include "qnetworksession_p.h" @@ -165,7 +166,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn void QNetworkSession::preferredConfigurationChanged(const QNetworkConfiguration& config, bool isSeamless) + \fn void QNetworkSession::preferredConfigurationChanged(const QNetworkConfiguration &config, bool isSeamless) This signal is emitted when the preferred configuration/access point for the session changes. Only sessions which are based on service network configurations @@ -224,30 +225,29 @@ QT_BEGIN_NAMESPACE \sa QNetworkConfiguration */ -QNetworkSession::QNetworkSession(const QNetworkConfiguration& connectionConfig, QObject* parent) -: QObject(parent), d(0) +QNetworkSession::QNetworkSession(const QNetworkConfiguration &connectionConfig, QObject *parent) + : QObject(parent), d(0) { // invalid configuration - if (connectionConfig.identifier().isNull()) - return; - - foreach (QBearerEngine *engine, qNetworkConfigurationManagerPrivate()->engines()) { - if (engine->hasIdentifier(connectionConfig.identifier())) { - d = engine->createSessionBackend(); - d->q = this; - d->publicConfig = connectionConfig; - d->syncStateWithInterface(); - connect(d, SIGNAL(quitPendingWaitsForOpened()), this, SIGNAL(opened())); - connect(d, SIGNAL(error(QNetworkSession::SessionError)), - this, SIGNAL(error(QNetworkSession::SessionError))); - connect(d, SIGNAL(stateChanged(QNetworkSession::State)), - this, SIGNAL(stateChanged(QNetworkSession::State))); - connect(d, SIGNAL(closed()), this, SIGNAL(closed())); - connect(d, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)), - this, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))); - connect(d, SIGNAL(newConfigurationActivated()), - this, SIGNAL(newConfigurationActivated())); - break; + if (!connectionConfig.identifier().isEmpty()) { + foreach (QBearerEngine *engine, qNetworkConfigurationManagerPrivate()->engines()) { + if (engine->hasIdentifier(connectionConfig.identifier())) { + d = engine->createSessionBackend(); + d->q = this; + d->publicConfig = connectionConfig; + d->syncStateWithInterface(); + connect(d, SIGNAL(quitPendingWaitsForOpened()), this, SIGNAL(opened())); + connect(d, SIGNAL(error(QNetworkSession::SessionError)), + this, SIGNAL(error(QNetworkSession::SessionError))); + connect(d, SIGNAL(stateChanged(QNetworkSession::State)), + this, SIGNAL(stateChanged(QNetworkSession::State))); + connect(d, SIGNAL(closed()), this, SIGNAL(closed())); + connect(d, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)), + this, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))); + connect(d, SIGNAL(newConfigurationActivated()), + this, SIGNAL(newConfigurationActivated())); + break; + } } } } @@ -320,7 +320,7 @@ bool QNetworkSession::waitForOpened(int msecs) loop, SLOT(quit())); //final call - if (msecs>=0) + if (msecs >= 0) QTimer::singleShot(msecs, loop, SLOT(quit())); loop->exec(); @@ -471,7 +471,7 @@ QString QNetworkSession::errorString() const \code QNetworkConfigurationManager mgr; QNetworkConfiguration ap = mgr.defaultConfiguration(); - QNetworkSession* session = new QNetworkSession(ap); + QNetworkSession *session = new QNetworkSession(ap); ... //code activates session QString ident = session->sessionProperty("ActiveConfiguration").toString(); @@ -516,20 +516,13 @@ QString QNetworkSession::errorString() const has no effect for sessions that do not require polling. \endtable */ -QVariant QNetworkSession::sessionProperty(const QString& key) const +QVariant QNetworkSession::sessionProperty(const QString &key) const { - if (!d) - return QVariant(); - - if (!d->publicConfig.isValid()) + if (!d || !d->publicConfig.isValid()) return QVariant(); - if (key == QLatin1String("ActiveConfiguration")) { - if (!d->isOpen) - return QString(); - else - return d->activeConfig.identifier(); - } + if (key == QLatin1String("ActiveConfiguration")) + return d->isOpen ? d->activeConfig.identifier() : QString(); if (key == QLatin1String("UserChoiceConfiguration")) { if (!d->isOpen || d->publicConfig.type() != QNetworkConfiguration::UserChoice) @@ -552,7 +545,7 @@ QVariant QNetworkSession::sessionProperty(const QString& key) const Note that the \e UserChoiceConfiguration and \e ActiveConfiguration properties are read only and cannot be changed using this method. */ -void QNetworkSession::setSessionProperty(const QString& key, const QVariant& value) +void QNetworkSession::setSessionProperty(const QString &key, const QVariant &value) { if (!d) return; @@ -586,7 +579,7 @@ void QNetworkSession::migrate() */ void QNetworkSession::ignore() { - // Needed on at least Symbian platform: the roaming must be explicitly + // Needed on at least Symbian platform: the roaming must be explicitly // ignore()'d or migrate()'d if (d) d->ignore(); @@ -680,32 +673,34 @@ quint64 QNetworkSession::activeTime() const void QNetworkSession::connectNotify(const char *signal) { QObject::connectNotify(signal); - //check for preferredConfigurationChanged() signal connect notification - //This is not required on all platforms + if (!d) return; - if (qstrcmp(signal, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))) == 0) + //check for preferredConfigurationChanged() signal connect notification + //This is not required on all platforms + if (QLatin1String(signal) == SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))) d->setALREnabled(true); } /*! \internal - This function is called when the client disconnects from the preferredConfigurationChanged() - signal. + This function is called when the client disconnects from the + preferredConfigurationChanged() signal. \sa connectNotify() */ void QNetworkSession::disconnectNotify(const char *signal) { QObject::disconnectNotify(signal); - //check for preferredConfigurationChanged() signal disconnect notification - //This is not required on all platforms + if (!d) return; - if (qstrcmp(signal, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))) == 0) + //check for preferredConfigurationChanged() signal disconnect notification + //This is not required on all platforms + if (QLatin1String(signal) == SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))) d->setALREnabled(false); } diff --git a/src/network/bearer/qnetworksession.h b/src/network/bearer/qnetworksession.h index 0b40147..717e085 100644 --- a/src/network/bearer/qnetworksession.h +++ b/src/network/bearer/qnetworksession.h @@ -71,6 +71,7 @@ class QNetworkSessionPrivate; class QNetworkSessionExport QNetworkSession : public QObject { Q_OBJECT + public: enum State { Invalid = 0, @@ -89,7 +90,8 @@ public: OperationNotSupportedError, InvalidConfigurationError }; - explicit QNetworkSession(const QNetworkConfiguration& connConfig, QObject* parent =0); + + explicit QNetworkSession(const QNetworkConfiguration &connConfig, QObject *parent = 0); virtual ~QNetworkSession(); bool isOpen() const; @@ -101,8 +103,8 @@ public: State state() const; SessionError error() const; QString errorString() const; - QVariant sessionProperty(const QString& key) const; - void setSessionProperty(const QString& key, const QVariant& value); + QVariant sessionProperty(const QString &key) const; + void setSessionProperty(const QString &key, const QVariant &value); quint64 bytesWritten() const; quint64 bytesReceived() const; @@ -121,13 +123,12 @@ public Q_SLOTS: void accept(); void reject(); - Q_SIGNALS: void stateChanged(QNetworkSession::State); void opened(); void closed(); void error(QNetworkSession::SessionError); - void preferredConfigurationChanged(const QNetworkConfiguration& config, bool isSeamless); + void preferredConfigurationChanged(const QNetworkConfiguration &config, bool isSeamless); void newConfigurationActivated(); protected: @@ -135,9 +136,9 @@ protected: virtual void disconnectNotify(const char *signal); private: - QNetworkSessionPrivate* d; friend class QNetworkSessionPrivate; - }; + QNetworkSessionPrivate *d; +}; #ifndef QT_MOBILITY_BEARER QT_END_NAMESPACE @@ -149,4 +150,4 @@ QT_END_HEADER #endif // QT_NO_BEARERMANAGEMENT -#endif //QNETWORKSESSION_H +#endif // QNETWORKSESSION_H diff --git a/src/network/bearer/qnetworksession_p.h b/src/network/bearer/qnetworksession_p.h index c7b5718..943841f 100644 --- a/src/network/bearer/qnetworksession_p.h +++ b/src/network/bearer/qnetworksession_p.h @@ -67,14 +67,11 @@ class Q_NETWORK_EXPORT QNetworkSessionPrivate : public QObject friend class QNetworkSession; public: - QNetworkSessionPrivate() - : state(QNetworkSession::Invalid), isOpen(false) - { - } - + QNetworkSessionPrivate() : QObject(), + state(QNetworkSession::Invalid), isOpen(false) + {} virtual ~QNetworkSessionPrivate() - { - } + {} //called by QNetworkSession constructor and ensures //that the state is immediately updated (w/o actually opening @@ -85,14 +82,14 @@ public: #ifndef QT_NO_NETWORKINTERFACE virtual QNetworkInterface currentInterface() const = 0; #endif - virtual QVariant sessionProperty(const QString& key) const = 0; - virtual void setSessionProperty(const QString& key, const QVariant& value) = 0; + virtual QVariant sessionProperty(const QString &key) const = 0; + virtual void setSessionProperty(const QString &key, const QVariant &value) = 0; virtual void open() = 0; virtual void close() = 0; virtual void stop() = 0; - virtual void setALREnabled(bool /*enabled*/) { } + virtual void setALREnabled(bool /*enabled*/) {} virtual void migrate() = 0; virtual void accept() = 0; virtual void ignore() = 0; @@ -150,5 +147,4 @@ QT_END_NAMESPACE #endif // QT_NO_BEARERMANAGEMENT -#endif //QNETWORKSESSIONPRIVATE_H - +#endif // QNETWORKSESSIONPRIVATE_H diff --git a/src/plugins/bearer/platformdefs_win.h b/src/plugins/bearer/platformdefs_win.h index 68343cf..0968e71 100644 --- a/src/plugins/bearer/platformdefs_win.h +++ b/src/plugins/bearer/platformdefs_win.h @@ -138,4 +138,4 @@ enum NDIS_PHYSICAL_MEDIUM { QT_END_NAMESPACE -#endif +#endif // QPLATFORMDEFS_WIN_H diff --git a/src/plugins/bearer/qbearerengine_impl.h b/src/plugins/bearer/qbearerengine_impl.h index 6c30d0f..2325bd0 100644 --- a/src/plugins/bearer/qbearerengine_impl.h +++ b/src/plugins/bearer/qbearerengine_impl.h @@ -60,8 +60,8 @@ public: DisconnectionError, }; - QBearerEngineImpl(QObject *parent = 0) : QBearerEngine(parent) { } - ~QBearerEngineImpl() { } + QBearerEngineImpl(QObject *parent = 0) : QBearerEngine(parent) {} + ~QBearerEngineImpl() {} virtual void connectToId(const QString &id) = 0; virtual void disconnectFromId(const QString &id) = 0; @@ -81,4 +81,5 @@ Q_SIGNALS: QT_END_NAMESPACE #endif // QT_NO_BEARERMANAGEMENT -#endif + +#endif // QBEARERENGINE_IMPL_H diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp index ef5f347..27e14b1 100644 --- a/src/plugins/bearer/qnetworksession_impl.cpp +++ b/src/plugins/bearer/qnetworksession_impl.cpp @@ -45,9 +45,10 @@ #include #include -#include +#include #include #include +#include #ifndef QT_NO_BEARERMANAGEMENT @@ -71,10 +72,11 @@ class QNetworkSessionManagerPrivate : public QObject Q_OBJECT public: - QNetworkSessionManagerPrivate(QObject *parent = 0); - ~QNetworkSessionManagerPrivate(); + QNetworkSessionManagerPrivate(QObject *parent = 0) : QObject(parent) {} + ~QNetworkSessionManagerPrivate() {} - void forceSessionClose(const QNetworkConfiguration &config); + inline void forceSessionClose(const QNetworkConfiguration &config) + { emit forcedSessionClose(config); } Q_SIGNALS: void forcedSessionClose(const QNetworkConfiguration &config); @@ -84,20 +86,6 @@ Q_SIGNALS: Q_GLOBAL_STATIC(QNetworkSessionManagerPrivate, sessionManager); -QNetworkSessionManagerPrivate::QNetworkSessionManagerPrivate(QObject *parent) -: QObject(parent) -{ -} - -QNetworkSessionManagerPrivate::~QNetworkSessionManagerPrivate() -{ -} - -void QNetworkSessionManagerPrivate::forceSessionClose(const QNetworkConfiguration &config) -{ - emit forcedSessionClose(config); -} - void QNetworkSessionPrivateImpl::syncStateWithInterface() { connect(sessionManager(), SIGNAL(forcedSessionClose(QNetworkConfiguration)), @@ -108,8 +96,7 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface() state = QNetworkSession::Invalid; lastError = QNetworkSession::UnknownSessionError; - qRegisterMetaType - ("QBearerEngineImpl::ConnectionError"); + qRegisterMetaType("QBearerEngineImpl::ConnectionError"); switch (publicConfig.type()) { case QNetworkConfiguration::InternetAccessPoint: @@ -145,9 +132,8 @@ void QNetworkSessionPrivateImpl::open() lastError = QNetworkSession::OperationNotSupportedError; emit QNetworkSessionPrivate::error(lastError); } else if (!isOpen) { - if ((activeConfig.state() & QNetworkConfiguration::Discovered) != - QNetworkConfiguration::Discovered) { - lastError =QNetworkSession::InvalidConfigurationError; + if ((activeConfig.state() & QNetworkConfiguration::Discovered) != QNetworkConfiguration::Discovered) { + lastError = QNetworkSession::InvalidConfigurationError; state = QNetworkSession::Invalid; emit stateChanged(state); emit QNetworkSessionPrivate::error(lastError); @@ -221,11 +207,10 @@ void QNetworkSessionPrivateImpl::reject() #ifndef QT_NO_NETWORKINTERFACE QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const { - if (!publicConfig.isValid() || !engine || state != QNetworkSession::Connected) + if (!engine || state != QNetworkSession::Connected || !publicConfig.isValid()) return QNetworkInterface(); QString interface = engine->getInterfaceFromId(activeConfig.identifier()); - if (interface.isEmpty()) return QNetworkInterface(); return QNetworkInterface::interfaceFromName(interface); @@ -237,10 +222,7 @@ QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString &key) const if (key == QLatin1String("AutoCloseSessionTimeout")) { if (engine && engine->requiresPolling() && !(engine->capabilities() & QNetworkConfigurationManager::CanStartAndStopInterfaces)) { - if (sessionTimeout >= 0) - return sessionTimeout * 10000; - else - return -1; + return sessionTimeout >= 0 ? sessionTimeout * 10000 : -1; } } @@ -278,7 +260,8 @@ QString QNetworkSessionPrivateImpl::errorString() const return tr("The specified configuration cannot be used."); case QNetworkSession::RoamingError: return tr("Roaming was aborted or is not possible."); - + default: + break; } return QString(); @@ -293,24 +276,21 @@ quint64 QNetworkSessionPrivateImpl::bytesWritten() const { if (engine && state == QNetworkSession::Connected) return engine->bytesWritten(activeConfig.identifier()); - else - return Q_UINT64_C(0); + return Q_UINT64_C(0); } quint64 QNetworkSessionPrivateImpl::bytesReceived() const { if (engine && state == QNetworkSession::Connected) return engine->bytesReceived(activeConfig.identifier()); - else - return Q_UINT64_C(0); + return Q_UINT64_C(0); } quint64 QNetworkSessionPrivateImpl::activeTime() const { if (state == QNetworkSession::Connected && startTime != Q_UINT64_C(0)) return QDateTime::currentDateTime().toTime_t() - startTime; - else - return Q_UINT64_C(0); + return Q_UINT64_C(0); } void QNetworkSessionPrivateImpl::updateStateFromServiceNetwork() @@ -323,17 +303,15 @@ void QNetworkSessionPrivateImpl::updateStateFromServiceNetwork() if (activeConfig != config) { if (engine) { - disconnect(engine, - SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)), - this, - SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError))); + disconnect(engine, SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)), + this, SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError))); } activeConfig = config; engine = getEngineFromId(activeConfig.identifier()); + if (engine) { - connect(engine, - SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)), + connect(engine, SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)), this, SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError)), Qt::QueuedConnection); } @@ -362,7 +340,6 @@ void QNetworkSessionPrivateImpl::updateStateFromActiveConfig() return; QNetworkSession::State oldState = state; - state = engine->sessionStateForId(activeConfig.identifier()); bool oldActive = isOpen; @@ -410,8 +387,7 @@ void QNetworkSessionPrivateImpl::forcedSessionClose(const QNetworkConfiguration } } -void QNetworkSessionPrivateImpl::connectionError(const QString &id, - QBearerEngineImpl::ConnectionError error) +void QNetworkSessionPrivateImpl::connectionError(const QString &id, QBearerEngineImpl::ConnectionError error) { if (activeConfig.identifier() == id) { networkConfigurationsChanged(); @@ -443,4 +419,3 @@ void QNetworkSessionPrivateImpl::decrementTimeout() QT_END_NAMESPACE #endif // QT_NO_BEARERMANAGEMENT - diff --git a/src/plugins/bearer/qnetworksession_impl.h b/src/plugins/bearer/qnetworksession_impl.h index a4902eb..d8f4803 100644 --- a/src/plugins/bearer/qnetworksession_impl.h +++ b/src/plugins/bearer/qnetworksession_impl.h @@ -58,8 +58,6 @@ #include #include -#include - #ifndef QT_NO_BEARERMANAGEMENT QT_BEGIN_NAMESPACE @@ -69,15 +67,13 @@ class QBearerEngineImpl; class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate { Q_OBJECT + public: QNetworkSessionPrivateImpl() - : startTime(0), sessionTimeout(-1) - { - } - + : startTime(0), sessionTimeout(-1) + {} ~QNetworkSessionPrivateImpl() - { - } + {} //called by QNetworkSession constructor and ensures //that the state is immediately updated (w/o actually opening @@ -106,10 +102,6 @@ public: quint64 bytesReceived() const; quint64 activeTime() const; -private: - void updateStateFromServiceNetwork(); - void updateStateFromActiveConfig(); - private Q_SLOTS: void networkConfigurationsChanged(); void configurationChanged(QNetworkConfigurationPrivatePointer config); @@ -118,6 +110,10 @@ private Q_SLOTS: void decrementTimeout(); private: + void updateStateFromServiceNetwork(); + void updateStateFromActiveConfig(); + +private: QBearerEngineImpl *engine; quint64 startTime; @@ -133,5 +129,4 @@ QT_END_NAMESPACE #endif // QT_NO_BEARERMANAGEMENT -#endif //QNETWORKSESSION_IMPL_H - +#endif // QNETWORKSESSION_IMPL_H -- cgit v0.12 From 8c79236781cc2dea904f36d6e8c751e6635b9bb9 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 10 Dec 2010 13:47:29 +1000 Subject: fix CV-qualifiers for some members this change is BC-safe since QNetworkConfigurationManagerPrivate is not a part of a public API Merge-request: 899 Reviewed-by: Aaron McCarthy --- src/network/bearer/qnetworkconfigmanager_p.cpp | 12 ++++++------ src/network/bearer/qnetworkconfigmanager_p.h | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index d33cda1..022365e 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -73,7 +73,7 @@ QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate() qDeleteAll(sessionEngines); } -QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration() +QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration() const { QMutexLocker locker(&mutex); @@ -190,7 +190,7 @@ QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration( return QNetworkConfiguration(); } -QList QNetworkConfigurationManagerPrivate::allConfigurations(QNetworkConfiguration::StateFlags filter) +QList QNetworkConfigurationManagerPrivate::allConfigurations(QNetworkConfiguration::StateFlags filter) const { QList result; @@ -234,7 +234,7 @@ QList QNetworkConfigurationManagerPrivate::allConfigurati return result; } -QNetworkConfiguration QNetworkConfigurationManagerPrivate::configurationFromIdentifier(const QString &identifier) +QNetworkConfiguration QNetworkConfigurationManagerPrivate::configurationFromIdentifier(const QString &identifier) const { QNetworkConfiguration item; @@ -258,14 +258,14 @@ QNetworkConfiguration QNetworkConfigurationManagerPrivate::configurationFromIden return item; } -bool QNetworkConfigurationManagerPrivate::isOnline() +bool QNetworkConfigurationManagerPrivate::isOnline() const { QMutexLocker locker(&mutex); return !onlineConfigurations.isEmpty(); } -QNetworkConfigurationManager::Capabilities QNetworkConfigurationManagerPrivate::capabilities() +QNetworkConfigurationManager::Capabilities QNetworkConfigurationManagerPrivate::capabilities() const { QMutexLocker locker(&mutex); @@ -431,7 +431,7 @@ void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate() } } -QList QNetworkConfigurationManagerPrivate::engines() +QList QNetworkConfigurationManagerPrivate::engines() const { QMutexLocker locker(&mutex); diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h index 45c1fb4..9b946d8 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.h +++ b/src/network/bearer/qnetworkconfigmanager_p.h @@ -74,17 +74,17 @@ public: QNetworkConfigurationManagerPrivate(); virtual ~QNetworkConfigurationManagerPrivate(); - QNetworkConfiguration defaultConfiguration(); - QList allConfigurations(QNetworkConfiguration::StateFlags filter); - QNetworkConfiguration configurationFromIdentifier(const QString &identifier); + QNetworkConfiguration defaultConfiguration() const; + QList allConfigurations(QNetworkConfiguration::StateFlags filter) const; + QNetworkConfiguration configurationFromIdentifier(const QString &identifier) const; - bool isOnline(); + bool isOnline() const; - QNetworkConfigurationManager::Capabilities capabilities(); + QNetworkConfigurationManager::Capabilities capabilities() const; void performAsyncConfigurationUpdate(); - QList engines(); + QList engines() const; Q_INVOKABLE void startPolling(); @@ -111,7 +111,7 @@ private Q_SLOTS: private: QTimer *pollTimer; - QMutex mutex; + mutable QMutex mutex; QList sessionEngines; -- cgit v0.12 From d509ec9707b3c4ce7efd7af27a18d171913c5682 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 10 Dec 2010 13:47:31 +1000 Subject: simplify waitForOpened() and don't exclude socket events so they might be used pings and so on... Merge-request: 899 Reviewed-by: Aaron McCarthy --- src/network/bearer/qnetworksession.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp index dedbbf9..eac0456 100644 --- a/src/network/bearer/qnetworksession.cpp +++ b/src/network/bearer/qnetworksession.cpp @@ -313,19 +313,16 @@ bool QNetworkSession::waitForOpened(int msecs) if (d->state != Connecting) return false; - QEventLoop* loop = new QEventLoop(this); - QObject::connect(d, SIGNAL(quitPendingWaitsForOpened()), - loop, SLOT(quit())); - QObject::connect(this, SIGNAL(error(QNetworkSession::SessionError)), - loop, SLOT(quit())); + QEventLoop loop; + QObject::connect(d, SIGNAL(quitPendingWaitsForOpened()), &loop, SLOT(quit())); + QObject::connect(this, SIGNAL(error(QNetworkSession::SessionError)), &loop, SLOT(quit())); //final call if (msecs >= 0) - QTimer::singleShot(msecs, loop, SLOT(quit())); + QTimer::singleShot(msecs, &loop, SLOT(quit())); - loop->exec(); - loop->disconnect(); - loop->deleteLater(); + // enter the event loop and wait for opened/error/timeout + loop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents); return d->isOpen; } -- cgit v0.12 From 32bb6d3ac2c5214a5294123d281cd4d21eaeaf2c Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 10 Dec 2010 13:47:33 +1000 Subject: promote QNetworkConfigurationManager::updateConfigurations() to a slot Merge-request: 899 Reviewed-by: Aaron McCarthy --- src/network/bearer/qnetworkconfigmanager.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/network/bearer/qnetworkconfigmanager.h b/src/network/bearer/qnetworkconfigmanager.h index a2c5504..9ddebe5 100644 --- a/src/network/bearer/qnetworkconfigmanager.h +++ b/src/network/bearer/qnetworkconfigmanager.h @@ -88,10 +88,12 @@ public: QNetworkConfiguration defaultConfiguration() const; QList allConfigurations(QNetworkConfiguration::StateFlags flags = 0) const; QNetworkConfiguration configurationFromIdentifier(const QString &identifier) const; - void updateConfigurations(); bool isOnline() const; +public Q_SLOTS: + void updateConfigurations(); + Q_SIGNALS: void configurationAdded(const QNetworkConfiguration &config); void configurationRemoved(const QNetworkConfiguration &config); -- cgit v0.12 From fab1d32dcb32235a34ed735251a27de2a1aaf8ce Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 10 Dec 2010 13:47:34 +1000 Subject: simplify polling code a bit Merge-request: 899 Reviewed-by: Aaron McCarthy --- src/network/bearer/qnetworkconfigmanager_p.cpp | 35 +++++--------------------- src/network/bearer/qnetworkconfigmanager_p.h | 6 ++--- 2 files changed, 8 insertions(+), 33 deletions(-) diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index 022365e..fd1052c 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -60,7 +60,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, #endif QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate() - : QObject(), pollTimer(0), mutex(QMutex::Recursive), forcedPolling(0), firstUpdate(true) + : QObject(), mutex(QMutex::Recursive), forcedPolling(0), firstUpdate(true) { qRegisterMetaType("QNetworkConfiguration"); qRegisterMetaType("QNetworkConfigurationPrivatePointer"); @@ -442,34 +442,11 @@ void QNetworkConfigurationManagerPrivate::startPolling() { QMutexLocker locker(&mutex); - bool pollingRequired = false; - - if (forcedPolling > 0) { - foreach (QBearerEngine *engine, sessionEngines) { - if (engine->requiresPolling()) { - pollingRequired = true; - break; - } - } - } - - if (!pollingRequired) { - foreach (QBearerEngine *engine, sessionEngines) { - if (engine->configurationsInUse()) { - pollingRequired = true; - break; - } - } - } - - if (pollingRequired) { - if (!pollTimer) { - pollTimer = new QTimer(this); - pollTimer->setInterval(10000); - pollTimer->setSingleShot(true); - connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollEngines())); + foreach (QBearerEngine *engine, sessionEngines) { + if (engine->requiresPolling() && (forcedPolling || engine->configurationsInUse())) { + QTimer::singleShot(10000, this, SLOT(pollEngines())); + break; } - pollTimer->start(); } } @@ -492,7 +469,7 @@ void QNetworkConfigurationManagerPrivate::enablePolling() ++forcedPolling; if (forcedPolling == 1) - QMetaObject::invokeMethod(this, "startPolling"); + startPolling(); } void QNetworkConfigurationManagerPrivate::disablePolling() diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h index 9b946d8..16c2c4b 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.h +++ b/src/network/bearer/qnetworkconfigmanager_p.h @@ -64,7 +64,6 @@ QT_BEGIN_NAMESPACE class QBearerEngine; -class QTimer; class Q_NETWORK_EXPORT QNetworkConfigurationManagerPrivate : public QObject { @@ -86,8 +85,6 @@ public: QList engines() const; - Q_INVOKABLE void startPolling(); - void enablePolling(); void disablePolling(); @@ -109,8 +106,9 @@ private Q_SLOTS: void pollEngines(); private: - QTimer *pollTimer; + void startPolling(); +private: mutable QMutex mutex; QList sessionEngines; -- cgit v0.12 From 35a6b31320104e90f584dc7ba528bd9ed05b8676 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 10 Dec 2010 13:47:36 +1000 Subject: remove useless overload sinse create(QString()) always returns 0 Merge-request: 899 Reviewed-by: Aaron McCarthy --- src/network/bearer/qbearerplugin_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/bearer/qbearerplugin_p.h b/src/network/bearer/qbearerplugin_p.h index 3dbea9d..aee189b 100644 --- a/src/network/bearer/qbearerplugin_p.h +++ b/src/network/bearer/qbearerplugin_p.h @@ -68,7 +68,7 @@ QT_MODULE(Network) struct Q_NETWORK_EXPORT QBearerEngineFactoryInterface : public QFactoryInterface { - virtual QBearerEngine *create(const QString &key = QString()) const = 0; + virtual QBearerEngine *create(const QString &key) const = 0; }; #define QBearerEngineFactoryInterface_iid "com.trolltech.Qt.QBearerEngineFactoryInterface" @@ -84,7 +84,7 @@ public: virtual ~QBearerEnginePlugin(); virtual QStringList keys() const = 0; - virtual QBearerEngine *create(const QString &key = QString()) const = 0; + virtual QBearerEngine *create(const QString &key) const = 0; }; QT_END_NAMESPACE -- cgit v0.12 From a0fabfac2ddd0b4e52a1d06623a0864f836cba71 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Fri, 10 Dec 2010 14:22:45 +1000 Subject: Fix broken database creation caused by previous fix 16447b1193fedf5fdcf1f3d270fa73c5036a1ba0 removed unused directory but the fix meant that the base Databases directory was no longer automatically created. Task-number: QTBUG-15909 --- src/declarative/qml/qdeclarativesqldatabase.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/declarative/qml/qdeclarativesqldatabase.cpp b/src/declarative/qml/qdeclarativesqldatabase.cpp index 3f53111..bda02a5 100644 --- a/src/declarative/qml/qdeclarativesqldatabase.cpp +++ b/src/declarative/qml/qdeclarativesqldatabase.cpp @@ -172,16 +172,23 @@ static const char* sqlerror[] = { return errorValue; \ } - -static QString databaseFile(const QString& connectionName, QScriptEngine *engine) +static QString qmlsqldatabase_databasesPath(QScriptEngine *engine) { QDeclarativeScriptEngine *qmlengine = static_cast(engine); - QString basename = qmlengine->offlineStoragePath - + QDir::separator() + QLatin1String("Databases") + QDir::separator(); - basename += connectionName; - return basename; + return qmlengine->offlineStoragePath + + QDir::separator() + QLatin1String("Databases"); } +static void qmlsqldatabase_initDatabasesPath(QScriptEngine *engine) +{ + QDir().mkpath(qmlsqldatabase_databasesPath(engine)); +} + +static QString qmlsqldatabase_databaseFile(const QString& connectionName, QScriptEngine *engine) +{ + return qmlsqldatabase_databasesPath(engine) + QDir::separator() + + connectionName; +} static QScriptValue qmlsqldatabase_item(QScriptContext *context, QScriptEngine *engine) @@ -302,7 +309,7 @@ static QScriptValue qmlsqldatabase_change_version(QScriptContext *context, QScri if (ok) { context->thisObject().setProperty(QLatin1String("version"), to_version, QScriptValue::ReadOnly); - QSettings ini(databaseFile(db.connectionName(),engine)+QLatin1String(".ini"),QSettings::IniFormat); + QSettings ini(qmlsqldatabase_databaseFile(db.connectionName(),engine) + QLatin1String(".ini"), QSettings::IniFormat); ini.setValue(QLatin1String("Version"), to_version); } @@ -348,6 +355,8 @@ static QScriptValue qmlsqldatabase_read_transaction(QScriptContext *context, QSc */ static QScriptValue qmlsqldatabase_open_sync(QScriptContext *context, QScriptEngine *engine) { + qmlsqldatabase_initDatabasesPath(engine); + QSqlDatabase database; QString dbname = context->argument(0).toString(); @@ -360,7 +369,7 @@ static QScriptValue qmlsqldatabase_open_sync(QScriptContext *context, QScriptEng md5.addData(dbname.toUtf8()); QString dbid(QLatin1String(md5.result().toHex())); - QString basename = databaseFile(dbid,engine); + QString basename = qmlsqldatabase_databaseFile(dbid, engine); bool created = false; QString version = dbversion; -- cgit v0.12 From 1de4983c86a73913bd2d719ad765726530009979 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Fri, 10 Dec 2010 15:34:52 +1000 Subject: PathView: removing the currentIndex could make it invalid. Removing the currentIndex could result in currentIndex being > than the number of items in the model. Task-number: QTBUG-15926 Reviewed-by: Michael Brasser --- src/declarative/graphicsitems/qdeclarativepathview.cpp | 2 +- .../declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index 7c79afe..87ea214 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -1478,7 +1478,7 @@ void QDeclarativePathView::itemsRemoved(int modelIndex, int count) currentChanged = true; } else if (d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count) { // current item has been removed. - d->currentIndex = qMin(modelIndex, d->modelCount-1); + d->currentIndex = qMin(modelIndex, d->modelCount-count-1); if (d->currentItem) { if (QDeclarativePathViewAttached *att = d->attached(d->currentItem)) att->setIsCurrentItem(true); diff --git a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp index a2a5363..9193707 100644 --- a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp +++ b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp @@ -429,6 +429,10 @@ void tst_QDeclarativePathView::dataModel() pathview->setOffset(0); QCOMPARE(findItems(pathview, "wrapper").count(), 5); + pathview->setCurrentIndex(model.count()-1); + model.removeItem(model.count()-1); + QCOMPARE(pathview->currentIndex(), model.count()-1); + delete canvas; } -- cgit v0.12 From cedb5e0a5bb381ecfe5acc463d96a0c15abe474d Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 10 Dec 2010 08:23:16 +0100 Subject: Missing glyphs in GL when scaling QStaticText and QML text items Since scaled text is backed by an A8 glyph cache, it needs to repopulate even if it has previously populated the cache for the unscaled text. This means that we need to record in the userData that the type of the cache is not the same as the last time. Otherwise the A8 version of the cache will only be updated when it's created and when the text actually changes, leading to glyphs missing on screen when zooming text using a scale. Task-number: QTBUG-16012 Reviewed-by: Gunnar --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 7045fe9..4a64f39 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1464,6 +1464,7 @@ namespace { QSize cacheSize; QGL2PEXVertexArray vertexCoordinateArray; QGL2PEXVertexArray textureCoordinateArray; + QFontEngineGlyphCache::Type glyphType; }; } @@ -1489,12 +1490,17 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp cache->setContext(ctx); } - if (staticTextItem->userDataNeedsUpdate) + if (staticTextItem->userDataNeedsUpdate) { recreateVertexArrays = true; - else if (staticTextItem->userData() == 0) + } else if (staticTextItem->userData() == 0) { recreateVertexArrays = true; - else if (staticTextItem->userData()->type != QStaticTextUserData::OpenGLUserData) + } else if (staticTextItem->userData()->type != QStaticTextUserData::OpenGLUserData) { recreateVertexArrays = true; + } else { + QOpenGLStaticTextUserData *userData = static_cast(staticTextItem->userData()); + if (userData->glyphType != glyphType) + recreateVertexArrays = true; + } // We only need to update the cache with new glyphs if we are actually going to recreate the vertex arrays. // If the cache size has changed, we do need to regenerate the vertices, but we don't need to repopulate the @@ -1506,8 +1512,8 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp // No space in cache. We need to clear the cache and try again cache->clear(); cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs, - staticTextItem->glyphs, staticTextItem->glyphPositions); - } + staticTextItem->glyphs, staticTextItem->glyphPositions); + } } if (cache->width() == 0 || cache->height() == 0) @@ -1537,6 +1543,8 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp userData = static_cast(staticTextItem->userData()); } + userData->glyphType = glyphType; + // Use cache if backend optimizations is turned on vertexCoordinates = &userData->vertexCoordinateArray; textureCoordinates = &userData->textureCoordinateArray; -- cgit v0.12 From cde178fdc12262ecbbd99edb73477c6d6143e30e Mon Sep 17 00:00:00 2001 From: axis Date: Fri, 26 Nov 2010 10:44:00 +0100 Subject: Corrected case on Symbian library. RevBy: Trust me --- src/gui/dialogs/dialogs.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/dialogs/dialogs.pri b/src/gui/dialogs/dialogs.pri index c25b6d5..12e3a71 100644 --- a/src/gui/dialogs/dialogs.pri +++ b/src/gui/dialogs/dialogs.pri @@ -109,7 +109,7 @@ SOURCES += \ dialogs/qprintpreviewdialog.cpp symbian:contains(QT_CONFIG, s60) { - LIBS += -lcommondialogs + LIBS += -lCommonDialogs SOURCES += dialogs/qfiledialog_symbian.cpp \ dialogs/qcolordialog_symbian.cpp } -- cgit v0.12 From d2a52072c7f0220d7abf0f73102cc5db616527b2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 10 Dec 2010 09:51:49 +0100 Subject: Remove superfluous OpenGL linking for QtDeclarative --- src/declarative/declarative.pro | 1 - 1 file changed, 1 deletion(-) diff --git a/src/declarative/declarative.pro b/src/declarative/declarative.pro index 93ad861..1ad888b 100644 --- a/src/declarative/declarative.pro +++ b/src/declarative/declarative.pro @@ -2,7 +2,6 @@ TARGET = QtDeclarative QPRO_PWD = $$PWD QT = core gui script network contains(QT_CONFIG, svg): QT += svg -contains(QT_CONFIG, opengl): QT += opengl DEFINES += QT_BUILD_DECLARATIVE_LIB QT_NO_URL_CAST_FROM_STRING win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x66000000 solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2 -- cgit v0.12 From 0e04bd14bb422d7098f859a3b904fcf4d05aa458 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 10 Dec 2010 09:56:18 +0100 Subject: Don't include directly: non-standard header. It's completely wrong to assume that any Linux has features.h. Instead, include something that comes from the libc (like stdlib.h, which is specified by ISO C 89) and hope that __GLIBC__ gets defined. Specifically don't do this to stddef.h as that one comes from the compiler. Reviewed-by: Andreas Kling --- src/corelib/global/qendian.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h index d53504a..08415bf 100644 --- a/src/corelib/global/qendian.h +++ b/src/corelib/global/qendian.h @@ -44,9 +44,8 @@ #include -#ifdef Q_OS_LINUX -# include -#endif +// include stdlib.h and hope that it defines __GLIBC__ for glibc-based systems +#include #ifdef __GLIBC__ #include -- cgit v0.12 From 38856b7ca5ec18b0292dd3dd11d8ea42fea361e6 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 10 Dec 2010 10:43:57 +0100 Subject: QmlViewer: Fix crash on exit We can't use atexit() handler to show a warning, since whether the QApplication object then still exists or not is undefined. Instead, call the method directly where it makes sense (warnings about command line arguments etc). Task-number: QTBUG-15740 Reviewed-by: Thomas Hartmann --- tools/qml/main.cpp | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index 209c72f..104f7b7 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -86,14 +86,16 @@ void myMessageOutput(QtMsgType type, const char *msg) QWeakPointer logger; QString warnings; -void showWarnings() +void exitApp(int i) { +#ifdef Q_OS_WIN + // Debugging output is not visible by default on Windows - + // therefore show modal dialog with errors instead. if (!warnings.isEmpty()) { - int argc = 0; char **argv = 0; - QApplication application(argc, argv); // QApplication() in main has been destroyed already. - Q_UNUSED(application) QMessageBox::warning(0, QApplication::tr("Qt QML Viewer"), warnings); } +#endif + exit(i); } static QAtomicInt recursiveLock(0); @@ -102,14 +104,16 @@ void myMessageOutput(QtMsgType type, const char *msg) { QString strMsg = QString::fromLatin1(msg); - if (!logger.isNull() && !QCoreApplication::closingDown()) { - if (recursiveLock.testAndSetOrdered(0, 1)) { - QMetaObject::invokeMethod(logger.data(), "append", Q_ARG(QString, strMsg)); - recursiveLock = 0; + if (!QCoreApplication::closingDown()) { + if (!logger.isNull()) { + if (recursiveLock.testAndSetOrdered(0, 1)) { + QMetaObject::invokeMethod(logger.data(), "append", Q_ARG(QString, strMsg)); + recursiveLock = 0; + } + } else { + warnings += strMsg; + warnings += QLatin1Char('\n'); } - } else { - warnings += strMsg; - warnings += QLatin1Char('\n'); } if (systemMsgOutput) { // Windows systemMsgOutput(type, msg); @@ -165,7 +169,8 @@ void usage() qWarning(" "); qWarning(" Press F1 for interactive help"); - exit(1); + + exitApp(1); } void scriptOptsUsage() @@ -184,7 +189,8 @@ void scriptOptsUsage() qWarning(" saveonexit ............................... save recording on viewer exit"); qWarning(" "); qWarning(" One of record, play or both must be specified."); - exit(1); + + exitApp(1); } enum WarningsConfig { ShowWarnings, HideWarnings, DefaultWarnings }; @@ -370,7 +376,7 @@ static void parseCommandLineOptions(const QStringList &arguments) qApp->setStartDragDistance(arguments.at(++i).toInt()); } else if (arg == QLatin1String("-v") || arg == QLatin1String("-version")) { qWarning("Qt QML Viewer version %s", QT_VERSION_STR); - exit(0); + exitApp(0); } else if (arg == "-translation") { if (lastArg) usage(); opts.translationFile = arguments.at(++i); @@ -400,7 +406,7 @@ static void parseCommandLineOptions(const QStringList &arguments) QDeclarativeEngine tmpEngine; QString paths = tmpEngine.importPathList().join(QLatin1String(":")); qWarning("Current search path: %s", paths.toLocal8Bit().constData()); - exit(0); + exitApp(0); } opts.imports << arguments.at(++i); } else if (arg == "-P") { @@ -529,12 +535,6 @@ int main(int argc, char ** argv) systemMsgOutput = qInstallMsgHandler(myMessageOutput); #endif -#if defined (Q_OS_WIN) - // Debugging output is not visible by default on Windows - - // therefore show modal dialog with errors instead. - atexit(showWarnings); -#endif - #if defined (Q_WS_X11) || defined (Q_WS_MAC) //### default to using raster graphics backend for now bool gsSpecified = false; -- cgit v0.12 From 0aaa9b79d9fb5c7ae4f293a272beab43e5851c83 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Thu, 9 Dec 2010 18:42:31 +0100 Subject: QNetworkReply: set to finished for synchronous requests Since 4.8, QNetworkReply has a setFinished() method, which we need to set to true for synchronous calls. Reviewed-by: Markus Goetz --- src/network/access/qnetworkreplyimpl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index feb869b..70c318c 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -117,6 +117,7 @@ void QNetworkReplyImplPrivate::_q_startOperation() if (backend->isSynchronous()) { state = Finished; + q_func()->setFinished(true); } else { if (state != Finished) { if (operation == QNetworkAccessManager::GetOperation) -- cgit v0.12 From 240c33480ea300a78416205602af293d5c223ee2 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 10 Dec 2010 11:17:33 +0100 Subject: QmlViewer: Remove trailing whitespace --- tools/qml/browser/Browser.qml | 2 +- tools/qml/deviceorientation.h | 4 ++-- tools/qml/qdeclarativetester.cpp | 16 ++++++++-------- tools/qml/qdeclarativetester.h | 4 ++-- tools/qml/qmlruntime.cpp | 4 ++-- tools/qml/startup/startup.qml | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tools/qml/browser/Browser.qml b/tools/qml/browser/Browser.qml index b9573da..968d077 100644 --- a/tools/qml/browser/Browser.qml +++ b/tools/qml/browser/Browser.qml @@ -173,7 +173,7 @@ Rectangle { width: parent.width model: folders1 delegate: folderDelegate - highlight: Rectangle { + highlight: Rectangle { color: palette.highlight visible: root.showFocusHighlight && view1.count != 0 gradient: Gradient { diff --git a/tools/qml/deviceorientation.h b/tools/qml/deviceorientation.h index 487ebd4..88ceb1b 100644 --- a/tools/qml/deviceorientation.h +++ b/tools/qml/deviceorientation.h @@ -52,8 +52,8 @@ class DeviceOrientation : public QObject Q_OBJECT Q_ENUMS(Orientation) public: - enum Orientation { - UnknownOrientation, + enum Orientation { + UnknownOrientation, Portrait, Landscape, PortraitInverted, diff --git a/tools/qml/qdeclarativetester.cpp b/tools/qml/qdeclarativetester.cpp index e3a1f59..1bcdb04 100644 --- a/tools/qml/qdeclarativetester.cpp +++ b/tools/qml/qdeclarativetester.cpp @@ -54,9 +54,9 @@ QT_BEGIN_NAMESPACE extern Q_GUI_EXPORT bool qt_applefontsmoothing_enabled; -QDeclarativeTester::QDeclarativeTester(const QString &script, QDeclarativeViewer::ScriptOptions opts, +QDeclarativeTester::QDeclarativeTester(const QString &script, QDeclarativeViewer::ScriptOptions opts, QDeclarativeView *parent) -: QAbstractAnimation(parent), m_script(script), m_view(parent), filterEvents(true), options(opts), +: QAbstractAnimation(parent), m_script(script), m_view(parent), filterEvents(true), options(opts), testscript(0), hasCompleted(false), hasFailed(false) { parent->viewport()->installEventFilter(this); @@ -75,8 +75,8 @@ QDeclarativeTester::QDeclarativeTester(const QString &script, QDeclarativeViewer QDeclarativeTester::~QDeclarativeTester() { - if (!hasFailed && - options & QDeclarativeViewer::Record && + if (!hasFailed && + options & QDeclarativeViewer::Record && options & QDeclarativeViewer::SaveOnExit) save(); } @@ -228,7 +228,7 @@ void QDeclarativeTester::save() } ts << " }\n"; - while (!mouseevents.isEmpty() && + while (!mouseevents.isEmpty() && mouseevents.first().msec == fe.msec) { MouseEvent me = mouseevents.takeFirst(); @@ -345,7 +345,7 @@ void QDeclarativeTester::updateCurrentTime(int msec) if (QDeclarativeVisualTestFrame *frame = qobject_cast(event)) { if (frame->msec() < msec) { if (options & QDeclarativeViewer::TestImages && !(options & QDeclarativeViewer::Record)) { - qWarning() << "QDeclarativeTester(" << m_script << "): Extra frame. Seen:" + qWarning() << "QDeclarativeTester(" << m_script << "): Extra frame. Seen:" << msec << "Expected:" << frame->msec(); imagefailure(); } @@ -371,7 +371,7 @@ void QDeclarativeTester::updateCurrentTime(int msec) } if (goodImage != img) { QString reject(frame->image().toLocalFile() + ".reject.png"); - qWarning() << "QDeclarativeTester(" << m_script << "): Image mismatch. Reject saved to:" + qWarning() << "QDeclarativeTester(" << m_script << "): Image mismatch. Reject saved to:" << reject; img.save(reject); bool doDiff = (goodImage.size() == img.size()); @@ -424,7 +424,7 @@ void QDeclarativeTester::updateCurrentTime(int msec) ke.destination = ViewPort; } m_savedKeyEvents.append(ke); - } + } testscriptidx++; } diff --git a/tools/qml/qdeclarativetester.h b/tools/qml/qdeclarativetester.h index 0cf508a..5a2a8c6 100644 --- a/tools/qml/qdeclarativetester.h +++ b/tools/qml/qdeclarativetester.h @@ -122,7 +122,7 @@ public: int type() const { return m_type; } void setType(int t) { m_type = t; } - + int button() const { return m_button; } void setButton(int b) { m_button = b; } @@ -237,7 +237,7 @@ private: struct MouseEvent { MouseEvent(QMouseEvent *e) - : type(e->type()), button(e->button()), buttons(e->buttons()), + : type(e->type()), button(e->button()), buttons(e->buttons()), pos(e->pos()), modifiers(e->modifiers()), destination(View) {} QEvent::Type type; diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index a368bc1..3803691 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -820,7 +820,7 @@ void QDeclarativeViewer::createMenu() fileMenu->addAction(reloadAction); fileMenu->addSeparator(); fileMenu->addAction(closeAction); -#if !defined(Q_OS_SYMBIAN) +#if !defined(Q_OS_SYMBIAN) fileMenu->addAction(quitAction); QMenu *recordMenu = menu->addMenu(tr("&Recording")); @@ -836,7 +836,7 @@ void QDeclarativeViewer::createMenu() settingsMenu->addAction(proxyAction); #if defined(Q_OS_SYMBIAN) settingsMenu->addAction(fullscreenAction); -#else +#else settingsMenu->addAction(recordOptions); settingsMenu->addMenu(loggerWindow->preferencesMenu()); #endif // !Q_OS_SYMBIAN diff --git a/tools/qml/startup/startup.qml b/tools/qml/startup/startup.qml index 9ca50a3..d3bc932 100644 --- a/tools/qml/startup/startup.qml +++ b/tools/qml/startup/startup.qml @@ -92,8 +92,8 @@ Rectangle { to: 360 loops: NumberAnimation.Infinite running: true - duration: 2000 - } + duration: 2000 + } } } } @@ -168,6 +168,6 @@ Rectangle { } } } - ] + ] } // treatsApp -- cgit v0.12 From 376e636eccedb8d8bbb280c3e2655722a5902461 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 10 Dec 2010 11:21:04 +0100 Subject: QmlViewer: Remove trailing whitespace --- tools/qml/qdeclarativetester.h | 2 +- tools/qml/qml.pro | 4 ++-- tools/qml/qmlruntime.cpp | 2 +- tools/qml/startup/startup.qml | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/qml/qdeclarativetester.h b/tools/qml/qdeclarativetester.h index 5a2a8c6..6fdf495 100644 --- a/tools/qml/qdeclarativetester.h +++ b/tools/qml/qdeclarativetester.h @@ -122,7 +122,7 @@ public: int type() const { return m_type; } void setType(int t) { m_type = t; } - + int button() const { return m_button; } void setButton(int b) { m_button = b; } diff --git a/tools/qml/qml.pro b/tools/qml/qml.pro index 3927dd6..bdac6e3 100644 --- a/tools/qml/qml.pro +++ b/tools/qml/qml.pro @@ -4,7 +4,7 @@ DESTDIR = ../../bin include(qml.pri) -SOURCES += main.cpp +SOURCES += main.cpp INCLUDEPATH += ../../include/QtDeclarative INCLUDEPATH += ../../src/declarative/util @@ -26,7 +26,7 @@ wince* { QT += xmlpatterns } contains(QT_CONFIG, webkit) { - QT += webkit + QT += webkit } } maemo5 { diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index 3803691..142e4c5 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -820,7 +820,7 @@ void QDeclarativeViewer::createMenu() fileMenu->addAction(reloadAction); fileMenu->addSeparator(); fileMenu->addAction(closeAction); -#if !defined(Q_OS_SYMBIAN) +#if !defined(Q_OS_SYMBIAN) fileMenu->addAction(quitAction); QMenu *recordMenu = menu->addMenu(tr("&Recording")); diff --git a/tools/qml/startup/startup.qml b/tools/qml/startup/startup.qml index d3bc932..35c44c2 100644 --- a/tools/qml/startup/startup.qml +++ b/tools/qml/startup/startup.qml @@ -92,8 +92,8 @@ Rectangle { to: 360 loops: NumberAnimation.Infinite running: true - duration: 2000 - } + duration: 2000 + } } } } @@ -168,6 +168,6 @@ Rectangle { } } } - ] + ] } // treatsApp -- cgit v0.12 From 7ea96f0d7b720eb38f3a974aa6cce2738f6ed808 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 9 Dec 2010 11:21:12 +0100 Subject: Fix compilation of qnetworkreply test with namespaces. (cherry picked from commit e195adf461ae81f1fedd75cc8907f823edd1f8f7) --- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index ebdc3e2..c796272 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -345,10 +345,10 @@ private Q_SLOTS: void parentingRepliesToTheApp(); }; -QT_BEGIN_NAMESPACE - bool tst_QNetworkReply::seedCreated = false; +QT_BEGIN_NAMESPACE + namespace QTest { template<> char *toString(const QNetworkReply::NetworkError& code) -- cgit v0.12 From c2b13ddde2f4998b03ff9036cc5ab81fd4132e61 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 10 Dec 2010 13:04:37 +0200 Subject: Fix qwidget test crash CEikonEnv::Static()->AppUiFactory()->Cba() call always returns NULL unless cba was defined via resources, which we are no longer doing. Due to the buggy implementation of MEikAppUiFactory interface in Symbian, the only way to get non-resources created cba is to use the return value of CEikonEnv::Static()->AppUiFactory()->SwapButtonGroup() method, so changed the test cases to do a dummy swap. Since the swap just changes the value of a member variable and doesn't trigger anything, it should not cause any interference for the tests. Task-number: QTBUG-15915 Reviewed-by: Janne Koskinen Reviewed-by: Sami Merila --- tests/auto/qwidget/tst_qwidget.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 5521873..6069383 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -10029,6 +10029,28 @@ void tst_QWidget::openModal_taskQTBUG_5804() } #ifdef Q_OS_SYMBIAN + +static CEikButtonGroupContainer* cba() +{ + CEikButtonGroupContainer *oldCba = NULL; + + // Due to convoluted/buggy implementation of MEikAppUiFactory interface in Symbian, + // the only way to get the correct cba is to use SwapButtonGroup function. + // Calling SwapButtonGroup doesn't trigger anything, it only changes the value of iToolbar + // member variable, so this double switching should not cause any interference for test. + QT_TRAP_THROWING( + CEikButtonGroupContainer *dummyCba = CEikButtonGroupContainer::NewL( + CEikButtonGroupContainer::ECba, CEikButtonGroupContainer::EHorizontal, NULL, 0); + + oldCba = CEikonEnv::Static()->AppUiFactory()->SwapButtonGroup(dummyCba); + CEikonEnv::Static()->AppUiFactory()->SwapButtonGroup(oldCba); + + delete dummyCba; + ) + + return oldCba; +} + void tst_QWidget::cbaVisibility() { // Test case for task 261048 @@ -10061,7 +10083,7 @@ void tst_QWidget::cbaVisibility() // Verify window decorations i.e. status pane and CBA are visible. CEikStatusPane* statusPane = CEikonEnv::Static()->AppUiFactory()->StatusPane(); QVERIFY(statusPane->IsVisible()); - CEikButtonGroupContainer* buttonGroup = CEikonEnv::Static()->AppUiFactory()->Cba(); + CEikButtonGroupContainer* buttonGroup = cba(); QVERIFY(buttonGroup->IsVisible()); } @@ -10078,7 +10100,7 @@ void tst_QWidget::fullScreenWindowModeTransitions() const QRect fullScreenGeometry = qApp->desktop()->screenGeometry(&widget); const QRect maximumScreenGeometry = qApp->desktop()->availableGeometry(&widget); CEikStatusPane *statusPane = CEikonEnv::Static()->AppUiFactory()->StatusPane(); - CEikButtonGroupContainer *buttonGroup = CEikonEnv::Static()->AppUiFactory()->Cba(); + CEikButtonGroupContainer *buttonGroup = cba(); //Enter widget.showNormal(); @@ -10132,7 +10154,7 @@ void tst_QWidget::maximizedWindowModeTransitions() const QRect fullScreenGeometry = qApp->desktop()->screenGeometry(&widget); const QRect maximumScreenGeometry = qApp->desktop()->availableGeometry(&widget); CEikStatusPane *statusPane = CEikonEnv::Static()->AppUiFactory()->StatusPane(); - CEikButtonGroupContainer *buttonGroup = CEikonEnv::Static()->AppUiFactory()->Cba(); + CEikButtonGroupContainer *buttonGroup = cba(); //Enter widget.showNormal(); @@ -10188,7 +10210,7 @@ void tst_QWidget::minimizedWindowModeTransitions() const QRect fullScreenGeometry = qApp->desktop()->screenGeometry(&widget); const QRect maximumScreenGeometry = qApp->desktop()->availableGeometry(&widget); CEikStatusPane *statusPane = CEikonEnv::Static()->AppUiFactory()->StatusPane(); - CEikButtonGroupContainer *buttonGroup = CEikonEnv::Static()->AppUiFactory()->Cba(); + CEikButtonGroupContainer *buttonGroup = cba(); //Enter widget.showNormal(); @@ -10244,7 +10266,7 @@ void tst_QWidget::normalWindowModeTransitions() const QRect fullScreenGeometry = qApp->desktop()->screenGeometry(&widget); const QRect maximumScreenGeometry = qApp->desktop()->availableGeometry(&widget); CEikStatusPane *statusPane = CEikonEnv::Static()->AppUiFactory()->StatusPane(); - CEikButtonGroupContainer *buttonGroup = CEikonEnv::Static()->AppUiFactory()->Cba(); + CEikButtonGroupContainer *buttonGroup = cba(); //Enter widget.showMaximized(); -- cgit v0.12 From 7b631a55c44520ca114f7e20a87a66c69e57a39e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 6 Dec 2010 16:41:40 +0100 Subject: fix nonsense condition checking the stdout of a grep redirected to /dev/null is rather pointless. also, this code had a syntax error ... --- configure | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 86c14dd..99d460b 100755 --- a/configure +++ b/configure @@ -8597,7 +8597,8 @@ for file in .projects .projects.3; do *winmain/winmain.pro) [ "$XPLATFORM_MINGW" = "yes" ] || continue SPEC=$XQMAKESPEC ;; - *s60main/s60main.pro) if [ "$CFG_NOPROCESS" = "yes" ] || [ -z "`echo "$XPLATFORM" | grep "symbian" >/dev/null`"]; then + *s60main/s60main.pro) + if [ "$CFG_NOPROCESS" = "yes" ] || ! echo "$XPLATFORM" | grep "symbian" >/dev/null; then continue fi;; *examples/activeqt/*) continue ;; -- cgit v0.12 From 6cf07024bfbf795b8c7ddf807668a2255c7b2985 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 6 Dec 2010 16:46:58 +0100 Subject: fix -dont-process for mingw cross-build --- configure | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 99d460b..7141880 100755 --- a/configure +++ b/configure @@ -8595,7 +8595,9 @@ for file in .projects .projects.3; do case $a in *winmain/winmain.pro) - [ "$XPLATFORM_MINGW" = "yes" ] || continue + if [ "$CFG_NOPROCESS" = "yes" ] || [ "$XPLATFORM_MINGW" != "yes" ]; then + continue + fi SPEC=$XQMAKESPEC ;; *s60main/s60main.pro) if [ "$CFG_NOPROCESS" = "yes" ] || ! echo "$XPLATFORM" | grep "symbian" >/dev/null; then -- cgit v0.12 From f602d82b542fb41099f6a1eb5a73a0e341e68fa0 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Fri, 10 Dec 2010 13:22:18 +0100 Subject: We should not cache ICO files. Otherwise first .ico file will be cached for this extension and all the other icons will have the same appearance. Reviewed-by: prasanth --- src/gui/itemviews/qfileiconprovider.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/gui/itemviews/qfileiconprovider.cpp index 4748f89..570c0ab 100644 --- a/src/gui/itemviews/qfileiconprovider.cpp +++ b/src/gui/itemviews/qfileiconprovider.cpp @@ -234,7 +234,7 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const const QString fileExtension = QLatin1Char('.') + fileInfo.suffix().toUpper(); QString key; - if (fileInfo.isFile() && !fileInfo.isExecutable() && !fileInfo.isSymLink()) + if (fileInfo.isFile() && !fileInfo.isExecutable() && !fileInfo.isSymLink() && fileExtension != QLatin1String(".ICO")) key = QLatin1String("qt_") + fileExtension; QPixmap pixmap; -- cgit v0.12 From 92f2ec30b86b7bf33fd632c8eb71318c9008a7ba Mon Sep 17 00:00:00 2001 From: mread Date: Fri, 10 Dec 2010 08:13:13 +0000 Subject: Improving memory leak analysis for argv, envp QtMainWrapper() gets the argv and envp arrays from __crt0(). There have been memory leaks reported from QtMainWrapper() because the contents of argv and envp are not deleted when the function returns. There has been some attempt to delete the memory with "delete []" on the top level arrays, but this will not delete any memory allocated for the strings themselves. The big problem is that there is no function which will free argv and envp properly. QtMainWrapper() can only guess at what is the best way to free the arrays. If QtMainWrapper() reverses the implementation of __crt0(), it is then tied to the current implementation of that function in an unrelated component. Instead we want these arrays to not be viewed as memory leaks when the app exits. QrMainWrapper() is only ever called as a top level function before main(), and the memory will be released automatically when the app exists shortly after the funciton returns. So in practice there is no meaningful leak from not freeing these arrays. The memory leak analysis tools should be able to spot heap ownership rooted in static data, and not treat that as a leak. In this case it is valid to put the argv and envp pointers in static data. Doing this should stop leaks being reported from these arrays. Task-number: QTBUG-15687 Reviewed-by: axis --- src/s60main/qts60main_mcrt0.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/s60main/qts60main_mcrt0.cpp b/src/s60main/qts60main_mcrt0.cpp index 0f0723e..ddab771 100644 --- a/src/s60main/qts60main_mcrt0.cpp +++ b/src/s60main/qts60main_mcrt0.cpp @@ -78,14 +78,14 @@ extern "C" IMPORT_C void exit(int ret); GLDEF_C TInt QtMainWrapper() { int argc = 0; - char **argv = 0; - char **envp = 0; + // these variables are declared static in the expectation that this function is not reentrant + // and so that memory analysis tools can trace any memory allocated in __crt0() to global memory ownership. + static char **argv = 0; + static char **envp = 0; // get args & environment __crt0(argc, argv, envp); //Call user(application)'s main TRAPD(ret, QT_TRYCATCH_LEAVING(ret = CALLMAIN(argc, argv, envp);)); - delete[] argv; - delete[] envp; return ret; } -- cgit v0.12 From 58334dcd3bf7c65ff910f4b00f356aa5944f2c82 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 10 Dec 2010 14:12:44 +0100 Subject: fix path separator matching use QDir::separator() instead of Option::dir_sep in localOS context. --- qmake/project.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/project.cpp b/qmake/project.cpp index d967a63..bd81b17 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -2173,7 +2173,7 @@ QMakeProject::doProjectExpand(QString func, QList args_list, const QRegExp regex(r, Qt::CaseSensitive, QRegExp::Wildcard); for(int d = 0; d < dirs.count(); d++) { QString dir = dirs[d]; - if(!dir.isEmpty() && !dir.endsWith(Option::dir_sep)) + if(!dir.isEmpty() && !dir.endsWith(QDir::separator())) dir += "/"; QDir qdir(dir); @@ -2389,7 +2389,7 @@ QMakeProject::doProjectTest(QString func, QList args_list, QMap Date: Fri, 10 Dec 2010 15:33:42 +0100 Subject: refuse to open empty translation files they cause a crash. fixing it properly would be in no reasonable relation to the gain (none whatsoever), so just forbid it. yes, this breaks the message freeze ... big deal in a translation application. ;) Task-number: QTBUG-14574 --- tools/linguist/linguist/messagemodel.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/linguist/linguist/messagemodel.cpp b/tools/linguist/linguist/messagemodel.cpp index 39ba9fd..c2edc75 100644 --- a/tools/linguist/linguist/messagemodel.cpp +++ b/tools/linguist/linguist/messagemodel.cpp @@ -209,6 +209,13 @@ bool DataModel::load(const QString &fileName, bool *langGuessed, QWidget *parent return false; } + if (!tor.messageCount()) { + QMessageBox::warning(parent, QObject::tr("Qt Linguist"), + tr("The translation file '%1' will not be loaded because it is empty.") + .arg(Qt::escape(fileName))); + return false; + } + Translator::Duplicates dupes = tor.resolveDuplicates(); if (!dupes.byId.isEmpty() || !dupes.byContents.isEmpty()) { QString err = tr("Duplicate messages found in '%1':").arg(Qt::escape(fileName)); -- cgit v0.12 From 275cf4baf5fb4c0fe28c192a1f5c295cb6032549 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 10 Dec 2010 17:01:19 +0100 Subject: QScript tests, sync the tests with the v8 branch --- tests/auto/qscriptvalue/tst_qscriptvalue.cpp | 60 +++++++++++++++++++++++++++- tests/auto/qscriptvalue/tst_qscriptvalue.h | 5 ++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp index 5a50e49..ec33e81 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp +++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp @@ -1970,7 +1970,7 @@ void tst_QScriptValue::getSetProperty_gettersAndSetters() QCOMPARE(object.property("foo").isUndefined(), true); } -void tst_QScriptValue::getSetProperty_gettersAndSettersThrowError() +void tst_QScriptValue::getSetProperty_gettersAndSettersThrowErrorNative() { // getter/setter that throws an error QScriptEngine eng; @@ -1984,6 +1984,32 @@ void tst_QScriptValue::getSetProperty_gettersAndSettersThrowError() QVERIFY(ret.isError()); QVERIFY(eng.hasUncaughtException()); QVERIFY(ret.strictlyEquals(eng.uncaughtException())); + QCOMPARE(ret.toString(), QLatin1String("Error: get foo")); + eng.evaluate("Object"); // clear exception state... + QVERIFY(!eng.hasUncaughtException()); + object.setProperty("foo", str); + QVERIFY(eng.hasUncaughtException()); + QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo")); +} + +void tst_QScriptValue::getSetProperty_gettersAndSettersThrowErrorJS() +{ + // getter/setter that throws an error (from js function) + QScriptEngine eng; + QScriptValue str = QScriptValue(&eng, "bar"); + + eng.evaluate("o = new Object; " + "o.__defineGetter__('foo', function() { throw new Error('get foo') }); " + "o.__defineSetter__('foo', function() { throw new Error('set foo') }); "); + QScriptValue object = eng.evaluate("o"); + QVERIFY(!eng.hasUncaughtException()); + QScriptValue ret = object.property("foo"); + QEXPECT_FAIL("", "Exception thrown from js function are not returned by the JSC port", Continue); + QVERIFY(ret.isError()); + QVERIFY(eng.hasUncaughtException()); + QEXPECT_FAIL("", "Exception thrown from js function are not returned by the JSC port", Continue); + QVERIFY(ret.strictlyEquals(eng.uncaughtException())); + QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: get foo")); eng.evaluate("Object"); // clear exception state... QVERIFY(!eng.hasUncaughtException()); object.setProperty("foo", str); @@ -2051,6 +2077,12 @@ void tst_QScriptValue::getSetProperty_gettersAndSettersChange() QVERIFY(!object.property("x").isValid()); object.setProperty("foo", num); QVERIFY(object.property("x").equals(num)); + + eng.globalObject().setProperty("object", object); + QScriptValue res = eng.evaluate("object.x = 89; var a = object.foo; object.foo = 65; a"); + QCOMPARE(res.toInt32(), 89); + QCOMPARE(object.property("x").toInt32(), 65); + QCOMPARE(object.property("foo").toInt32(), 65); } void tst_QScriptValue::getSetProperty_array() @@ -3931,4 +3963,30 @@ void tst_QScriptValue::nestedObjectToVariant() QCOMPARE(o.toVariant(), expected); } +void tst_QScriptValue::propertyFlags_data() +{ + QTest::addColumn("program"); + QTest::addColumn("expected"); + + QTest::newRow("nothing") << "" << 0u; + QTest::newRow("getter") << "o.__defineGetter__('prop', function() { return 'blah' } );\n" << uint(QScriptValue::PropertyGetter); + QTest::newRow("setter") << "o.__defineSetter__('prop', function(a) { this.setted_prop2 = a; } );\n" << uint(QScriptValue::PropertySetter); + QTest::newRow("getterSetter") << "o.__defineGetter__('prop', function() { return 'ploup' } );\n" + "o.__defineSetter__('prop', function(a) { this.setted_prop3 = a; } );\n" << uint(QScriptValue::PropertySetter|QScriptValue::PropertyGetter); + QTest::newRow("nothing2") << "o.prop = 'nothing'" << 0u; +} + +void tst_QScriptValue::propertyFlags() +{ + QFETCH(QString, program); + QFETCH(uint, expected); + QScriptEngine eng; + eng.evaluate("o = new Object;"); + eng.evaluate(program); + QScriptValue o = eng.evaluate("o"); + + QCOMPARE(uint(o.propertyFlags("prop")), expected); +} + + QTEST_MAIN(tst_QScriptValue) diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.h b/tests/auto/qscriptvalue/tst_qscriptvalue.h index 46f5526..6f55bc3 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue.h +++ b/tests/auto/qscriptvalue/tst_qscriptvalue.h @@ -127,7 +127,8 @@ private slots: void getSetProperty_resolveMode(); void getSetProperty_twoEngines(); void getSetProperty_gettersAndSetters(); - void getSetProperty_gettersAndSettersThrowError(); + void getSetProperty_gettersAndSettersThrowErrorNative(); + void getSetProperty_gettersAndSettersThrowErrorJS(); void getSetProperty_gettersAndSettersOnNative(); void getSetProperty_gettersAndSettersOnGlobalObject(); void getSetProperty_gettersAndSettersChange(); @@ -178,6 +179,8 @@ private slots: void objectId(); void nestedObjectToVariant_data(); void nestedObjectToVariant(); + void propertyFlags_data(); + void propertyFlags(); private: -- cgit v0.12 From 9fe927a54f0c465c0dcbcc5790ad0ddb17d4cc18 Mon Sep 17 00:00:00 2001 From: "Christian.Ehrlicher" Date: Fri, 10 Dec 2010 17:41:42 +0100 Subject: Proposed fix for QTBUG-10499 Merge-request: 866 Reviewed-by: Denis Dzyubenko --- src/gui/kernel/qx11embed_x11.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qx11embed_x11.cpp b/src/gui/kernel/qx11embed_x11.cpp index e6e3bfb..f2f95d3 100644 --- a/src/gui/kernel/qx11embed_x11.cpp +++ b/src/gui/kernel/qx11embed_x11.cpp @@ -512,7 +512,7 @@ QX11EmbedWidget::~QX11EmbedWidget() << "from container with winId" << d->container; #endif XUnmapWindow(x11Info().display(), internalWinId()); - XReparentWindow(x11Info().display(), internalWinId(), x11Info().appRootWindow(), 0, 0); + XReparentWindow(x11Info().display(), internalWinId(), x11Info().appRootWindow(x11Info().screen()), 0, 0); } #ifdef QX11EMBED_DEBUG @@ -791,13 +791,13 @@ bool QX11EmbedWidget::x11Event(XEvent *event) qDebug() << "QX11EmbedWidget::x11Event: client" << (void *)this << "with winId" << winId() << "received a ReparentNotify to" - << ((event->xreparent.parent == x11Info().appRootWindow()) + << ((event->xreparent.parent == x11Info().appRootWindow(x11Info().screen())) ? QString::fromLatin1("root") : QString::number(event->xreparent.parent)); #endif // If the container shuts down, we will be reparented to the // root window. We must also consider the case that we may be // reparented from one container to another. - if (event->xreparent.parent == x11Info().appRootWindow()) { + if (event->xreparent.parent == x11Info().appRootWindow(x11Info().screen())) { if (((QHackWidget *)this)->topData()->embedded) { d->container = 0; emit containerClosed(); @@ -1115,7 +1115,7 @@ QX11EmbedContainer::~QX11EmbedContainer() Q_D(QX11EmbedContainer); if (d->client) { XUnmapWindow(x11Info().display(), d->client); - XReparentWindow(x11Info().display(), d->client, x11Info().appRootWindow(), 0, 0); + XReparentWindow(x11Info().display(), d->client, x11Info().appRootWindow(x11Info().screen()), 0, 0); } if (d->xgrab) @@ -1379,7 +1379,7 @@ bool QX11EmbedContainer::eventFilter(QObject *o, QEvent *event) // Wait until the messages have been processed. Then ask // the window manager to delete the window. XUnmapWindow(x11Info().display(), d->client); - XReparentWindow(x11Info().display(), d->client, x11Info().appRootWindow(), 0, 0); + XReparentWindow(x11Info().display(), d->client, x11Info().appRootWindow(x11Info().screen()), 0, 0); XSync(x11Info().display(), false); XEvent ev; @@ -1627,7 +1627,7 @@ void QX11EmbedContainerPrivate::rejectClient(WId window) Q_Q(QX11EmbedContainer); q->setEnabled(false); XRemoveFromSaveSet(q->x11Info().display(), client); - XReparentWindow(q->x11Info().display(), window, q->x11Info().appRootWindow(), 0, 0); + XReparentWindow(q->x11Info().display(), window, q->x11Info().appRootWindow(q->x11Info().screen()), 0, 0); } /*! \internal -- cgit v0.12 From 13d3d484e4eadcec66e70c5a259a5a1ecc582300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 10 Dec 2010 18:38:00 +0100 Subject: Skip failing tests For Mac OS X 10.5 and earlier, QDir::canonicalPath depends on QDir::cleanPath which is fundamentally broken and specifically fails for the case of "/./", returning "" instead of "/". Fixing cleanPath to a sane and correct behaviour seems to break more code than it is worth so we're skipping these individual tests for the time being. --- tests/auto/qdir/tst_qdir.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index dc46f52..44d1fb6 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -852,7 +852,15 @@ void tst_QDir::canonicalPath_data() QTest::newRow("nonexistant") << "testd" << QString(); QTest::newRow("rootPath") << QDir::rootPath() << QDir::rootPath(); - QTest::newRow("rootPath + ./") << QDir::rootPath().append("./") << QDir::rootPath(); + +#ifdef Q_OS_MAC + // On Mac OS X 10.5 and earlier, canonicalPath depends on cleanPath which + // is itself very broken and fundamentally wrong on "/./" which, this would + // exercise + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) +#endif + QTest::newRow("rootPath + ./") << QDir::rootPath().append("./") << QDir::rootPath(); + QTest::newRow("rootPath + ../.. ") << QDir::rootPath().append("../..") << QDir::rootPath(); #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) QTest::newRow("drive:\\") << QDir::toNativeSeparators(QDir::rootPath()) << QDir::rootPath(); @@ -1753,8 +1761,16 @@ void tst_QDir::isRoot_data() QTest::newRow(QString("rootPath " + test).toLatin1()) << test << true; test = QDir::rootPath().append("./"); QTest::newRow(QString("./ appended " + test).toLatin1()) << test << false; + test = QDir(QDir::rootPath().append("./")).canonicalPath(); - QTest::newRow(QString("canonicalPath " + test).toLatin1()) << test << true; +#ifdef Q_OS_MAC + // On Mac OS X 10.5 and earlier, canonicalPath depends on cleanPath which + // is itself very broken and fundamentally wrong on "/./", which this would + // exercise + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) +#endif + QTest::newRow(QString("canonicalPath " + test).toLatin1()) << test << true; + #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) test = QDir::rootPath().left(2); QTest::newRow(QString("drive relative " + test).toLatin1()) << test << false; -- cgit v0.12 From 53c8baffd0bf9aa959f77a52dbce77b377d11e3b Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Fri, 10 Dec 2010 21:43:06 +0100 Subject: Doc: Fixing typo --- tests/auto/guiapplauncher/tst_guiapplauncher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/guiapplauncher/tst_guiapplauncher.cpp b/tests/auto/guiapplauncher/tst_guiapplauncher.cpp index 4b3ce18..c223992 100644 --- a/tests/auto/guiapplauncher/tst_guiapplauncher.cpp +++ b/tests/auto/guiapplauncher/tst_guiapplauncher.cpp @@ -270,7 +270,7 @@ private: const QSharedPointer m_wm; }; -// Test mask from enviroment as test lib does not allow options. +// Test mask from environment as test lib does not allow options. static inline unsigned testMask() { unsigned testMask = tst_GuiAppLauncher::TestAll; -- cgit v0.12 From 14f4ebce80ec7d39287b445192b25111a49fff6b Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Fri, 10 Dec 2010 22:56:52 +0100 Subject: Doc: Fixing typo --- tests/auto/macnativeevents/tst_macnativeevents.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/macnativeevents/tst_macnativeevents.cpp b/tests/auto/macnativeevents/tst_macnativeevents.cpp index 742267f..dce768e 100644 --- a/tests/auto/macnativeevents/tst_macnativeevents.cpp +++ b/tests/auto/macnativeevents/tst_macnativeevents.cpp @@ -488,7 +488,7 @@ void tst_MacNativeEvents::testModifierCtrlWithDontSwapCtrlAndMeta() { // On Mac, we switch the Command and Control modifier by default, so that Command // means Meta, and Control means Command. Lets check that the flag to swith off - // this behaviour works. While working on this test I realised that we actually + // this behaviour works. While working on this test I realized that we actually // don't (and never have) respected this flag for raw key events. Only for // menus, through QKeySequence. I don't want to change this behaviour now, at // least not until someone complains. So I choose to let the test just stop -- cgit v0.12 From 2249a44e57764e88ed2967aee7f845fdf4cf2358 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 13 Dec 2010 09:31:37 +1000 Subject: Build on Symbian Reviewed-by: Michael Brasser --- tools/qml/main.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index 104f7b7..b9513b9 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -59,6 +59,19 @@ QtMsgHandler systemMsgOutput = 0; static QDeclarativeViewer *openFile(const QString &fileName); static void showViewer(QDeclarativeViewer *viewer); +QString warnings; +void exitApp(int i) +{ +#ifdef Q_OS_WIN + // Debugging output is not visible by default on Windows - + // therefore show modal dialog with errors instead. + if (!warnings.isEmpty()) { + QMessageBox::warning(0, QApplication::tr("Qt QML Viewer"), warnings); + } +#endif + exit(i); +} + #if defined (Q_OS_SYMBIAN) #include #include @@ -85,19 +98,6 @@ void myMessageOutput(QtMsgType type, const char *msg) QWeakPointer logger; -QString warnings; -void exitApp(int i) -{ -#ifdef Q_OS_WIN - // Debugging output is not visible by default on Windows - - // therefore show modal dialog with errors instead. - if (!warnings.isEmpty()) { - QMessageBox::warning(0, QApplication::tr("Qt QML Viewer"), warnings); - } -#endif - exit(i); -} - static QAtomicInt recursiveLock(0); void myMessageOutput(QtMsgType type, const char *msg) -- cgit v0.12 From 35f964ac3d88831c857a850bbdc58fcbfdbaf13c Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 13 Dec 2010 13:49:52 +1000 Subject: A QAIM model resulted in items moving to incorrect locations QAbstractItemModel moves items to the gaps between items. QML views assume items are moved to the destination index. This means we need to adjust the destination when moving forward to a gap. Task-number: QTBUG-15841 Reviewed-by: Michael Brasser --- src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index 4fe6c4c..4f5213a 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -1367,7 +1367,7 @@ void QDeclarativeVisualDataModel::_q_rowsMoved(const QModelIndex &sourceParent, Q_D(QDeclarativeVisualDataModel); const int count = sourceEnd - sourceStart + 1; if (destinationParent == d->m_root && sourceParent == d->m_root) { - _q_itemsMoved(sourceStart, destinationRow, count); + _q_itemsMoved(sourceStart, sourceStart > destinationRow ? destinationRow : destinationRow-1, count); } else if (sourceParent == d->m_root) { _q_itemsRemoved(sourceStart, count); } else if (destinationParent == d->m_root) { -- cgit v0.12 From 18b940539d0633f30ae055feedb48aeb15969814 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Wed, 8 Dec 2010 13:38:48 +1000 Subject: Add mirroring-positioners.qml example --- .../positioners/mirroring-positioners.qml | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 examples/declarative/positioners/mirroring-positioners.qml diff --git a/examples/declarative/positioners/mirroring-positioners.qml b/examples/declarative/positioners/mirroring-positioners.qml new file mode 100644 index 0000000..0db95dd --- /dev/null +++ b/examples/declarative/positioners/mirroring-positioners.qml @@ -0,0 +1,70 @@ +import QtQuick 1.0 + +Rectangle { + width: column.width+10 + height: column.height+10 + property bool arabic: false + Column { + id: column + spacing: 10 + anchors.centerIn: parent + Text { + text: "Row" + anchors.horizontalCenter: parent.horizontalCenter + } + Row { + flow: arabic ? Row.RightToLeft : Row.LeftToRight + spacing: 10 + Repeater { + model: 4 + Loader { + property int value: index + sourceComponent: delegate + } + } + } + Text { + text: "Grid" + anchors.horizontalCenter: parent.horizontalCenter + } + Grid { + flow: arabic ? Grid.RightToLeft : Grid.LeftToRight + spacing: 10; columns: 4 + Repeater { + model: 11 + Loader { + property int value: index + sourceComponent: delegate + } + } + } + Rectangle { + height: 50; width: parent.width + color: mouseArea.pressed ? "black" : "gray" + Text { + text: arabic ? "RTL" : "LTR" + color: "white" + font.pixelSize: 20 + anchors.centerIn: parent + } + MouseArea { + id: mouseArea + onClicked: arabic = !arabic + anchors.fill: parent + } + } + } + Component { + id: delegate + Rectangle { + width: 50; height: 50 + color: Qt.rgba(0.8/(parent.value+1),0.8/(parent.value+1),0.8/(parent.value+1),1.0) + Text { + text: parent.parent.value+1 + color: "white" + font.pixelSize: 20 + anchors.centerIn: parent + } + } + } +} -- cgit v0.12 From ad653d169aaecf6273787a01797c7647a13eec04 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 13 Dec 2010 16:09:52 +1000 Subject: Fix dragging Flickable back over start point. Change 810e21d9e404aa2fcb602cb68bfd892387b234e7 caused regression. Once stealMouse is set to true is must stay that way until release. Task-number: QTBUG-15998 Reviewed-by: Michael Brasser --- src/declarative/graphicsitems/qdeclarativeflickable.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 377f3b5..f1d92c5 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -700,8 +700,8 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent bool rejectY = false; bool rejectX = false; - bool stealY = false; - bool stealX = false; + bool stealY = stealMouse; + bool stealX = stealMouse; if (q->yflick()) { int dy = int(event->pos().y() - pressPos.y()); -- cgit v0.12 From 2e2f26072647b08292955ebad631c34d58c828f9 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Mon, 13 Dec 2010 17:08:09 +1000 Subject: Revert "Add mirroring-positioners.qml example" that was accidentally pushed This reverts commit 18b940539d0633f30ae055feedb48aeb15969814. --- .../positioners/mirroring-positioners.qml | 70 ---------------------- 1 file changed, 70 deletions(-) delete mode 100644 examples/declarative/positioners/mirroring-positioners.qml diff --git a/examples/declarative/positioners/mirroring-positioners.qml b/examples/declarative/positioners/mirroring-positioners.qml deleted file mode 100644 index 0db95dd..0000000 --- a/examples/declarative/positioners/mirroring-positioners.qml +++ /dev/null @@ -1,70 +0,0 @@ -import QtQuick 1.0 - -Rectangle { - width: column.width+10 - height: column.height+10 - property bool arabic: false - Column { - id: column - spacing: 10 - anchors.centerIn: parent - Text { - text: "Row" - anchors.horizontalCenter: parent.horizontalCenter - } - Row { - flow: arabic ? Row.RightToLeft : Row.LeftToRight - spacing: 10 - Repeater { - model: 4 - Loader { - property int value: index - sourceComponent: delegate - } - } - } - Text { - text: "Grid" - anchors.horizontalCenter: parent.horizontalCenter - } - Grid { - flow: arabic ? Grid.RightToLeft : Grid.LeftToRight - spacing: 10; columns: 4 - Repeater { - model: 11 - Loader { - property int value: index - sourceComponent: delegate - } - } - } - Rectangle { - height: 50; width: parent.width - color: mouseArea.pressed ? "black" : "gray" - Text { - text: arabic ? "RTL" : "LTR" - color: "white" - font.pixelSize: 20 - anchors.centerIn: parent - } - MouseArea { - id: mouseArea - onClicked: arabic = !arabic - anchors.fill: parent - } - } - } - Component { - id: delegate - Rectangle { - width: 50; height: 50 - color: Qt.rgba(0.8/(parent.value+1),0.8/(parent.value+1),0.8/(parent.value+1),1.0) - Text { - text: parent.parent.value+1 - color: "white" - font.pixelSize: 20 - anchors.centerIn: parent - } - } - } -} -- cgit v0.12 From 95ddfa13737164c93c58ce3694ce59ec68a016d9 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 13 Dec 2010 17:33:13 +1000 Subject: Ensure ListView contentHeight is set to a valid size. If the view height is 0 no items will be created so the contentHeight can not be estimated. The currentItem is usually created, so it is possible to use that to estimate. Task-number: QTBUG-16037 Reviewed-by: Bea Lam --- .../graphicsitems/qdeclarativelistview.cpp | 6 ++++ .../qdeclarativelistview/data/qtbug16037.qml | 37 ++++++++++++++++++++++ .../tst_qdeclarativelistview.cpp | 20 ++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 tests/auto/declarative/qdeclarativelistview/data/qtbug16037.qml diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index d008f91..2a7f508 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -265,6 +265,8 @@ public: } } pos = (*(--visibleItems.constEnd()))->endPosition() + invisibleCount * (averageSize + spacing); + } else if (model && model->count()) { + pos = model->count() * averageSize + (model->count()-1) * spacing; } return pos; } @@ -1050,6 +1052,8 @@ void QDeclarativeListViewPrivate::updateCurrent(int modelIndex) // This is slightly sub-optimal, but section heading caching minimizes the impact. if (currentItem->section) currentItem->section->setVisible(false); + if (visibleItems.isEmpty()) + averageSize = currentItem->size(); } updateHighlight(); emit q->currentIndexChanged(); @@ -1576,6 +1580,7 @@ void QDeclarativeListView::setModel(const QVariant &model) d->updateTrackedItem(); } } + d->updateViewport(); } connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int))); @@ -1647,6 +1652,7 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) d->highlight->setPosition(d->currentItem->position()); d->updateTrackedItem(); } + d->updateViewport(); } } emit delegateChanged(); diff --git a/tests/auto/declarative/qdeclarativelistview/data/qtbug16037.qml b/tests/auto/declarative/qdeclarativelistview/data/qtbug16037.qml new file mode 100644 index 0000000..0756618 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelistview/data/qtbug16037.qml @@ -0,0 +1,37 @@ +import QtQuick 1.0 + +Item { + width: 640 + height: 480 + + function setModel() { + listView.model = listModel1 + } + + ListModel { + id: listModel1 + ListElement { text: "Apple" } + ListElement { text: "Banana" } + ListElement { text: "Orange" } + ListElement { text: "Coconut" } + } + + Rectangle { + width: 200 + height: listView.contentHeight + color: "yellow" + anchors.centerIn: parent + + ListView { + id: listView + objectName: "listview" + anchors.fill: parent + + delegate: Item { + width: 200 + height: 20 + Text { text: model.text; anchors.centerIn: parent } + } + } + } +} diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index ff90d32..b834d46 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -104,6 +104,7 @@ private slots: void sizeLessThan1(); void QTBUG_14821(); void resizeDelegate(); + void QTBUG_16037(); private: template void items(); @@ -1944,6 +1945,25 @@ void tst_QDeclarativeListView::resizeDelegate() delete canvas; } +void tst_QDeclarativeListView::QTBUG_16037() +{ + QDeclarativeView *canvas = createView(); + + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/qtbug16037.qml")); + qApp->processEvents(); + + QDeclarativeListView *listview = findItem(canvas->rootObject(), "listview"); + QTRY_VERIFY(listview != 0); + + QVERIFY(listview->contentHeight() <= 0.0); + + QMetaObject::invokeMethod(canvas->rootObject(), "setModel"); + + QTRY_COMPARE(listview->contentHeight(), 80.0); + + delete canvas; +} + void tst_QDeclarativeListView::qListModelInterface_items() { items(); -- cgit v0.12 From de1632cc7be17df234cd86d49df9787e6aa68107 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 10 Dec 2010 13:05:40 +0100 Subject: Add expected failures for JS test suite on Symbian These are bugs in the back-end (JavaScriptCore), not in the QtScript layer. Flag them as such. Task-number: QTBUG-15435 Reviewed-by: Jedrzej Nowacki --- tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp b/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp index a280256..4b14cc9 100644 --- a/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp +++ b/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp @@ -745,6 +745,16 @@ tst_Suite::tst_Suite() addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "1/-1e-2000", willFixInNextReleaseMessage); #endif +#ifdef Q_OS_SYMBIAN + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(-1, 0.5)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(-1, -0.5)", willFixInNextReleaseMessage); + addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.5.1 *", willFixInNextReleaseMessage); + addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.5.2 /", willFixInNextReleaseMessage); + addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.6.2 -", willFixInNextReleaseMessage); + addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.13.2 *=", willFixInNextReleaseMessage); + addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.13.2 /=", willFixInNextReleaseMessage); +#endif + static const char klass[] = "tst_QScriptJsTestSuite"; QVector *data = qt_meta_data_tst_Suite(); -- cgit v0.12 From 18dfe6da07eb9ea7beb3cf2b0ea8291d62832efb Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 13 Dec 2010 07:16:28 +0100 Subject: Fix transformed QPainter::drawGlyphs() for certain paint engines Support pretransforming glyph coordinates for paint engines that don't expect untransformed coordinates. Task-number: QTBUG-15605 Reviewed-by: Samuel --- src/gui/painting/qpainter.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 546861a..e8db049 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -151,6 +151,13 @@ static inline uint line_emulation(uint emulation) | QPaintEngine_OpaqueBackground); } +static bool qt_paintengine_supports_transformations(QPaintEngine::Type type) +{ + return type == QPaintEngine::OpenGL2 + || type == QPaintEngine::OpenVG + || type == QPaintEngine::OpenGL; +} + #ifndef QT_NO_DEBUG static bool qt_painter_thread_test(int devType, const char *what, bool extraCondition = false) { @@ -5795,8 +5802,17 @@ void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs) int count = qMin(glyphIndexes.size(), glyphPositions.size()); QVarLengthArray fixedPointPositions(count); - for (int i=0; iextended != 0 + ? qt_paintengine_supports_transformations(d->extended->type()) + : false; + for (int i=0; istate->transform().map(processedPosition); + fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition); + } d->drawGlyphs(glyphIndexes.data(), fixedPointPositions.data(), count); @@ -5988,10 +6004,7 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText return; } - bool paintEngineSupportsTransformations = d->extended->type() == QPaintEngine::OpenGL2 - || d->extended->type() == QPaintEngine::OpenVG - || d->extended->type() == QPaintEngine::OpenGL; - + bool paintEngineSupportsTransformations = qt_paintengine_supports_transformations(d->extended->type()); if (paintEngineSupportsTransformations && !staticText_d->untransformedCoordinates) { staticText_d->untransformedCoordinates = true; staticText_d->needsRelayout = true; -- cgit v0.12 From d5efbf00631022bc81f1a630aa386272937aa34c Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Mon, 13 Dec 2010 11:40:07 +0100 Subject: --warnings --- src/gui/kernel/qplatformwindow_qpa.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qplatformwindow_qpa.h b/src/gui/kernel/qplatformwindow_qpa.h index 90bc1cb..4f6fedc 100644 --- a/src/gui/kernel/qplatformwindow_qpa.h +++ b/src/gui/kernel/qplatformwindow_qpa.h @@ -60,7 +60,7 @@ class QPlatformGLContext; class Q_GUI_EXPORT QPlatformWindow { - Q_DECLARE_PRIVATE(QPlatformWindow); + Q_DECLARE_PRIVATE(QPlatformWindow) public: QPlatformWindow(QWidget *tlw); virtual ~QPlatformWindow(); @@ -85,7 +85,7 @@ public: protected: QScopedPointer d_ptr; private: - Q_DISABLE_COPY(QPlatformWindow); + Q_DISABLE_COPY(QPlatformWindow) }; QT_END_NAMESPACE -- cgit v0.12 From 6902cd0d68c63e3a0d0dd1593a77f54c002ae363 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 13 Dec 2010 12:56:36 +0100 Subject: Corrected documentation for QImage::fill(). Reviewed-by: Samuel --- src/gui/image/qimage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index bb94788c..897cb64 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -2018,11 +2018,11 @@ void QImage::fill(Qt::GlobalColor color) Fills the entire image with the given \a color. If the depth of the image is 1, the image will be filled with 1 if - \a color equals Qt::color0; it will otherwise be filled with 0. + \a color equals Qt::color1; it will otherwise be filled with 0. If the depth of the image is 8, the image will be filled with the index corresponding the \a color in the color table if present; it - will otherwise be filled with 0.| + will otherwise be filled with 0. \since 4.8 */ -- cgit v0.12 From 8e6078401562d40d2e63c4a2c769843088ec3350 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Fri, 10 Dec 2010 16:07:25 +0100 Subject: Make sure num_glyphs pass to HarfBuzz is large enough Currently we only pass the num_glyphs for the run to HB_ShapeItem, but it can be less then the string length for this run because of Unicode surrogates. Thus, we need to pass at least the length of that run as num_glyphs to HB (given that we have enough space allocated because for the entire string), if that's still not enough, we will do ensureSpace again according to the num_glyphs returned by HB and move remaining glyphs backwards. Task-number: QTBUG-15679 Reviewed-by: Lars Knoll --- src/gui/text/qtextengine.cpp | 5 ++++- tests/auto/qtextlayout/tst_qtextlayout.cpp | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 06eed55..96379e6 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1233,6 +1233,8 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const shaper_item.num_glyphs -= itemBoundaries[k + 1]; } shaper_item.initialGlyphCount = shaper_item.num_glyphs; + if (shaper_item.num_glyphs < shaper_item.item.length) + shaper_item.num_glyphs = shaper_item.item.length; QFontEngine *actualFontEngine = font; uint engineIdx = 0; @@ -1257,7 +1259,8 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const } const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos); - moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); + if (shaper_item.num_glyphs > shaper_item.item.length) + moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); shaper_item.glyphs = g.glyphs; shaper_item.attributes = g.attributes; diff --git a/tests/auto/qtextlayout/tst_qtextlayout.cpp b/tests/auto/qtextlayout/tst_qtextlayout.cpp index dcc43d0..4f4413f 100644 --- a/tests/auto/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/qtextlayout/tst_qtextlayout.cpp @@ -125,6 +125,7 @@ private slots: void lineWidthFromBOM(); void textWidthVsWIdth(); + void textWithSurrogates_qtbug15679(); private: QFont testFont; @@ -1412,6 +1413,24 @@ void tst_QTextLayout::textWidthVsWIdth() } } +void tst_QTextLayout::textWithSurrogates_qtbug15679() +{ + QString str = QString::fromUtf8("🀀a🀀"); + QTextLayout layout(str); + layout.beginLayout(); + QTextLine line = layout.createLine(); + layout.endLayout(); + + qreal x[6]; + for (int i = 0; i < 6; i++) + x[i] = line.cursorToX(i); + + // If the first and third character are using the same + // font, they must have the same advance (since they + // are surrogate pairs, we need to add two for each + // character) + QCOMPARE(x[2] - x[0], x[5] - x[3]); +} QTEST_MAIN(tst_QTextLayout) #include "tst_qtextlayout.moc" -- cgit v0.12 From 2362debe4e0b9e7d6ba39960a0b039370783cab4 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 13 Dec 2010 16:38:00 +0100 Subject: support app-bundles with whitespace in name based on merge-request 960 by Robin Helgelin --- tools/macdeployqt/shared/shared.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/macdeployqt/shared/shared.cpp b/tools/macdeployqt/shared/shared.cpp index c7d23c0..d974f5d 100644 --- a/tools/macdeployqt/shared/shared.cpp +++ b/tools/macdeployqt/shared/shared.cpp @@ -574,9 +574,13 @@ void createDiskImage(const QString &appBundlePath) } // More dmg options can be found in the hdiutil man page. - QString options = QString("create %1.dmg -srcfolder %1.app -format UDZO -volname %1").arg(appBaseName); + QStringList options = QStringList() + << "create" << dmgName + << "-srcfolder" << appBundlePath + << "-format" << "UDZO" + << "-volname" << appBaseName; QProcess hdutil; - hdutil.start("hdiutil", options.split(' ')); + hdutil.start("hdiutil", options); hdutil.waitForFinished(-1); } -- cgit v0.12 From 7d2cdbd606c70f6fb7c41742b028d1fb227122b0 Mon Sep 17 00:00:00 2001 From: miniak Date: Mon, 13 Dec 2010 16:47:05 +0100 Subject: Fix comctl32 v6 dependency generation in Visual Studio 2005 and higher Merge-request: 2526 Reviewed-by: Joerg Bornemann --- mkspecs/win32-msvc2005/qmake.conf | 6 +++--- mkspecs/win32-msvc2008/qmake.conf | 6 +++--- mkspecs/win32-msvc2010/qmake.conf | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mkspecs/win32-msvc2005/qmake.conf b/mkspecs/win32-msvc2005/qmake.conf index aa58e30..0c79561 100644 --- a/mkspecs/win32-msvc2005/qmake.conf +++ b/mkspecs/win32-msvc2005/qmake.conf @@ -1,7 +1,7 @@ # # qmake configuration for win32-msvc2005 # -# Written for Microsoft VC2005.NET +# Written for Microsoft Visual C++ 2005 # MAKEFILE_GENERATOR = MSVC.NET @@ -53,12 +53,12 @@ QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ $< QMAKE_RUN_CXX_IMP_BATCH = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ @<< QMAKE_LINK = link -QMAKE_LFLAGS = /NOLOGO +QMAKE_LFLAGS = /NOLOGO \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\" QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF QMAKE_LFLAGS_DEBUG = /DEBUG QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE -QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\" +QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS QMAKE_LFLAGS_DLL = /DLL QMAKE_LFLAGS_LTCG = /LTCG diff --git a/mkspecs/win32-msvc2008/qmake.conf b/mkspecs/win32-msvc2008/qmake.conf index ee7b99a..24a0486 100644 --- a/mkspecs/win32-msvc2008/qmake.conf +++ b/mkspecs/win32-msvc2008/qmake.conf @@ -1,7 +1,7 @@ # # qmake configuration for win32-msvc2008 # -# Written for Microsoft VC2005.NET +# Written for Microsoft Visual C++ 2008 # MAKEFILE_GENERATOR = MSVC.NET @@ -55,12 +55,12 @@ QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ $< QMAKE_RUN_CXX_IMP_BATCH = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ @<< QMAKE_LINK = link -QMAKE_LFLAGS = /NOLOGO +QMAKE_LFLAGS = /NOLOGO \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\" QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF QMAKE_LFLAGS_DEBUG = /DEBUG QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE -QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\" +QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS QMAKE_LFLAGS_DLL = /DLL QMAKE_LFLAGS_LTCG = /LTCG diff --git a/mkspecs/win32-msvc2010/qmake.conf b/mkspecs/win32-msvc2010/qmake.conf index 44e460e..c08a74d 100644 --- a/mkspecs/win32-msvc2010/qmake.conf +++ b/mkspecs/win32-msvc2010/qmake.conf @@ -1,7 +1,7 @@ # # qmake configuration for win32-msvc2010 # -# Written for Microsoft VC2005.NET +# Written for Microsoft Visual C++ 2010 # MAKEFILE_GENERATOR = MSBUILD @@ -55,12 +55,12 @@ QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ $< QMAKE_RUN_CXX_IMP_BATCH = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ @<< QMAKE_LINK = link -QMAKE_LFLAGS = /NOLOGO +QMAKE_LFLAGS = /NOLOGO \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\" QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF QMAKE_LFLAGS_DEBUG = /DEBUG QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE -QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\" +QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS QMAKE_LFLAGS_DLL = /DLL QMAKE_LFLAGS_LTCG = /LTCG -- cgit v0.12 From 496a3f83138e807150f2ff06f5462f7f9ab519fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 13 Dec 2010 18:06:19 +0100 Subject: Don't rely on uninitialized data When we fail to get file attributes, the file times are left in an uninitialized state, which may lead to a crash. In particular, this was showing up in QMessageBox's autotest, where the lastModified time is being queried on a non-existing file. Before the refactoring, we were returning a default constructed QDateTime to queries about different file times, with this change we will return the time corresponding to a default constructed FILETIME object. Reviewed-by: Shane Kearns --- src/corelib/io/qfilesystemengine_win.cpp | 3 +++ tests/auto/qfileinfo/tst_qfileinfo.cpp | 45 ++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 39fce97..b7bded9 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -433,6 +433,9 @@ void QFileSystemEngine::clearWinStatData(QFileSystemMetaData &data) { data.size_ = 0; data.fileAttribute_ = 0; + data.creationTime_ = FILETIME(); + data.lastAccessTime_ = FILETIME(); + data.lastWriteTime_ = FILETIME(); } bool QFileSystemEngine::isCaseSensitive() diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 0a61d55..4d9e80b 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -196,6 +196,8 @@ private slots: void owner(); #endif void group(); + + void invalidState(); }; tst_QFileInfo::tst_QFileInfo() @@ -1761,5 +1763,48 @@ void tst_QFileInfo::group() QCOMPARE(fi.group(), expected); } +void tst_QFileInfo::invalidState() +{ + // Shouldn't crash; + + { + QFileInfo info; + QCOMPARE(info.size(), qint64(0)); + QVERIFY(!info.exists()); + + info.setCaching(false); + + info.created(); + info.lastRead(); + info.lastModified(); + } + + { + QFileInfo info(""); + QCOMPARE(info.size(), qint64(0)); + QVERIFY(!info.exists()); + + info.setCaching(false); + + info.created(); + info.lastRead(); + info.lastModified(); + } + + { + QFileInfo info("file-doesn't-really-exist.txt"); + QCOMPARE(info.size(), qint64(0)); + QVERIFY(!info.exists()); + + info.setCaching(false); + + info.created(); + info.lastRead(); + info.lastModified(); + } + + QVERIFY(true); +} + QTEST_MAIN(tst_QFileInfo) #include "tst_qfileinfo.moc" -- cgit v0.12 From 18e3cd65980e1bc01e6af4807cae0bceca25288c Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 10 Dec 2010 13:20:48 +0100 Subject: QPointer: thread safety Fix a race condition between the destructor of QPointer and the destruction of the object living in a different thread. Task-number: QTBUG-16005 Reviewed-by: Joao --- src/corelib/kernel/qobject.cpp | 2 ++ tests/auto/qpointer/tst_qpointer.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 7fe9c52..c3102ea 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -408,6 +408,8 @@ void QMetaObject::removeGuard(QObject **ptr) if (!hash || hash->isEmpty()) return; QMutexLocker locker(guardHashLock()); + if (!*ptr) //check again, under the lock + return; GuardHash::iterator it = hash->find(*ptr); const GuardHash::iterator end = hash->end(); bool more = false; //if the QObject has more pointer attached to it. diff --git a/tests/auto/qpointer/tst_qpointer.cpp b/tests/auto/qpointer/tst_qpointer.cpp index 5a07e41..ce23764 100644 --- a/tests/auto/qpointer/tst_qpointer.cpp +++ b/tests/auto/qpointer/tst_qpointer.cpp @@ -73,6 +73,7 @@ private slots: void castDuringDestruction(); void data() const; void dataSignature() const; + void threadSafety(); }; tst_QPointer::tst_QPointer() @@ -345,5 +346,36 @@ void tst_QPointer::dataSignature() const } } +class TestRunnable : public QObject, public QRunnable { + void run() { + QPointer obj1 = new QObject; + QPointer obj2 = new QObject; + obj1->moveToThread(thread()); // this is the owner thread + obj1->deleteLater(); // the delete will happen in the owner thread + obj2->moveToThread(thread()); // this is the owner thread + obj2->deleteLater(); // the delete will happen in the owner thread + } +}; + +void tst_QPointer::threadSafety() +{ + + QThread owner; + owner.start(); + + QThreadPool pool; + for (int i = 0; i < 300; i++) { + QPointer task = new TestRunnable; + task->setAutoDelete(true); + task->moveToThread(&owner); + pool.start(task); + } + pool.waitForDone(); + + owner.quit(); + owner.wait(); +} + + QTEST_MAIN(tst_QPointer) #include "tst_qpointer.moc" -- cgit v0.12 From aa10afea34995c262156d26957455b698e630953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 14 Dec 2010 10:05:23 +0100 Subject: Fix warnings, whitespace cleanup ... and trigger CI :-/ --- src/corelib/io/qfilesystemengine_win.cpp | 4 ++++ src/corelib/io/qfilesystemmetadata_p.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index b7bded9..19c94e5 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1110,6 +1110,10 @@ QFileSystemEntry QFileSystemEngine::currentPath() bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { Q_ASSERT(false); + Q_UNUSED(source) + Q_UNUSED(target) + Q_UNUSED(error) + return false; // TODO implement; - code needs to be moved from qfsfileengine_win.cpp } diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index c4e11d9..7f75b05 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -94,7 +94,7 @@ public: ReadPermissions = OtherReadPermission | GroupReadPermission | UserReadPermission | OwnerReadPermission, WritePermissions = OtherWritePermission | GroupWritePermission | UserWritePermission | OwnerWritePermission, - ExecutePermissions = OtherExecutePermission | GroupExecutePermission | UserExecutePermission | OwnerExecutePermission, + ExecutePermissions = OtherExecutePermission | GroupExecutePermission | UserExecutePermission | OwnerExecutePermission, Permissions = OtherPermissions | GroupPermissions | UserPermissions | OwnerPermissions, -- cgit v0.12 From 67b24ac50637ecda00990b239fc5ed0b73e54d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 14 Dec 2010 12:03:23 +0100 Subject: Fixed stroke / fill inconsistencies in GL 2 paint engine. Get rid of the aliased coordinate delta, like we already did in the raster paint engine. Task-number: QTBUG-16043 Reviewed-by: Gunnar Sletta --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 40 ---------------------- .../gl2paintengineex/qpaintengineex_opengl2_p.h | 2 -- 2 files changed, 42 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index bb7c804..cdd785a 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -381,12 +381,6 @@ void QGL2PaintEngineExPrivate::updateMatrix() dx = ceilf(dx - 0.5f); dy = ceilf(dy - 0.5f); } -#ifndef Q_OS_SYMBIAN - if (addOffset) { - dx += 0.49f; - dy += 0.49f; - } -#endif pmvMatrix[0][0] = (wfactor * transform.m11()) - transform.m13(); pmvMatrix[1][0] = (wfactor * transform.m21()) - transform.m23(); pmvMatrix[2][0] = (wfactor * dx) - transform.m33(); @@ -488,11 +482,6 @@ void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& s currentBrush = noBrush; shaderManager->setSrcPixelType(pattern ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc); - if (addOffset) { - addOffset = false; - matrixDirty = true; - } - if (snapToPixelGrid) { snapToPixelGrid = false; matrixDirty = true; @@ -675,16 +664,6 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) { transferMode(BrushDrawingMode); - const QOpenGL2PaintEngineState *s = q->state(); - const bool newAddOffset = !(s->renderHints & QPainter::Antialiasing) && - (qbrush_style(currentBrush) == Qt::SolidPattern) && - !multisamplingAlwaysEnabled; - - if (addOffset != newAddOffset) { - addOffset = newAddOffset; - matrixDirty = true; - } - if (snapToPixelGrid) { snapToPixelGrid = false; matrixDirty = true; @@ -1203,12 +1182,6 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) void QGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &pen) { const QOpenGL2PaintEngineState *s = q->state(); - const bool newAddOffset = !(s->renderHints & QPainter::Antialiasing) && !multisamplingAlwaysEnabled; - if (addOffset != newAddOffset) { - addOffset = newAddOffset; - matrixDirty = true; - } - if (snapToPixelGrid) { snapToPixelGrid = false; matrixDirty = true; @@ -1638,10 +1611,6 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinates->data()); setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinates->data()); - if (addOffset) { - addOffset = false; - matrixDirty = true; - } if (!snapToPixelGrid) { snapToPixelGrid = true; matrixDirty = true; @@ -1786,11 +1755,6 @@ void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragmen textureCoordinateArray.clear(); opacityArray.reset(); - if (addOffset) { - addOffset = false; - matrixDirty = true; - } - if (snapToPixelGrid) { snapToPixelGrid = false; matrixDirty = true; @@ -2087,10 +2051,6 @@ void QGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, uint value) { transferMode(BrushDrawingMode); - if (addOffset) { - addOffset = false; - matrixDirty = true; - } if (snapToPixelGrid) { snapToPixelGrid = false; matrixDirty = true; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index b255e75..88172fb 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -181,7 +181,6 @@ public: elementIndicesVBOId(0), opacityArray(0), snapToPixelGrid(false), - addOffset(false), nativePaintingActive(false), inverseScale(1), lastMaskTextureUsed(0) @@ -283,7 +282,6 @@ public: GLfloat staticTextureCoordinateArray[8]; bool snapToPixelGrid; - bool addOffset; // When enabled, adds a 0.49,0.49 offset to matrix in updateMatrix bool nativePaintingActive; GLfloat pmvMatrix[3][3]; GLfloat inverseScale; -- cgit v0.12