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 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 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 d99d8953d2c45ca3ad05fea35ac71407237ab59d Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 22 Nov 2010 16:51:41 +0100 Subject: Doc: Fixed broken link by referring to the errors() method instead. Task-number: QTBUG-15506 --- src/declarative/util/qdeclarativeview.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index 0e31a20..c22f200 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -192,7 +192,7 @@ void QDeclarativeViewPrivate::itemGeometryChanged(QDeclarativeItem *resizeItem, /*! \class QDeclarativeView - \since 4.7 + \since 4.7 \brief The QDeclarativeView class provides a widget for displaying a Qt Declarative user interface. QDeclarativeItem objects can be placed on a standard QGraphicsScene and @@ -360,13 +360,14 @@ QDeclarativeContext* QDeclarativeView::rootContext() const } /*! - \enum QDeclarativeView::Status + \enum QDeclarativeView::Status Specifies the loading status of the QDeclarativeView. \value Null This QDeclarativeView has no source set. \value Ready This QDeclarativeView has loaded and created the QML component. \value Loading This QDeclarativeView is loading network data. - \value Error An error has occurred. Call errorDescription() to retrieve a description. + \value Error One or more errors has occurred. Call errors() to retrieve a list + of errors. */ /*! \enum QDeclarativeView::ResizeMode -- 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 be99e778d361068e81936773def14c731553991f Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 22 Nov 2010 19:42:25 +0100 Subject: Doc: Removed incorrect statement about the C locale. Task-number: QTBUG-15488 --- src/corelib/tools/qlocale.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index d152682..be1dc08 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1576,8 +1576,6 @@ QDataStream &operator>>(QDataStream &ds, QLocale &l) defaults to the default locale (see setDefault()). \endlist - The "C" locale is identical in behavior to \l{English}/\l{UnitedStates}. - Use language() and country() to determine the actual language and country values used. -- 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 3dc88a6229afc72125fa5565eb565a6fbc92620f Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 23 Nov 2010 15:21:20 +0100 Subject: Doc: Added general statements about reentrancy and thread safety. Task-number: QTBUG-14273 --- doc/src/frameworks-technologies/threads.qdoc | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/doc/src/frameworks-technologies/threads.qdoc b/doc/src/frameworks-technologies/threads.qdoc index 3ef617c..3e0204f 100644 --- a/doc/src/frameworks-technologies/threads.qdoc +++ b/doc/src/frameworks-technologies/threads.qdoc @@ -213,10 +213,10 @@ /*! \page threads-reentrancy.html \title Reentrancy and Thread-Safety - + \keyword reentrant \keyword thread-safe - + \previouspage Synchronizing Threads \contentspage Thread Support in Qt \nextpage Threads and QObjects @@ -243,6 +243,15 @@ from multiple threads, even if all the threads use the \e{same} instance of the class. + \note Qt classes are only documented as \e{thread-safe} if they + are intended to be used by multiple threads. If a function is not + marked as thread-safe or reentrant, it should not be used from + different threads. If a class is not marked as thread-safe or + reentrant then a specific instance of that class should not be + accessed from different threads. + + \section1 Reentrancy + C++ classes are often reentrant, simply because they only access their own member data. Any thread can call a member function on an instance of a reentrant class, as long as no other thread can call @@ -268,6 +277,8 @@ end up overwriting each other, and the variable is incremented only once! + \section1 Thread-Safety + Clearly, the access must be serialized: Thread A must perform steps 1, 2, 3 without interruption (atomically) before thread B can perform the same steps; or vice versa. An easy way to make @@ -284,6 +295,8 @@ declared with the \c mutable qualifier because we need to lock and unlock the mutex in \c value(), which is a const function. + \section1 Notes on Qt Classes + Many Qt classes are \e{reentrant}, but they are not made \e{thread-safe}, because making them thread-safe would incur the extra overhead of repeatedly locking and unlocking a QMutex. For @@ -297,9 +310,6 @@ the thread-related classes (e.g. QMutex) and fundamental functions (e.g. QCoreApplication::postEvent()). - \note Qt Classes are only documented as \e{thread-safe} if they - are intended to be used by multiple threads. - \note Terminology in the multithreading domain isn't entirely standardized. POSIX uses definitions of reentrant and thread-safe that are somewhat different for its C APIs. When using other -- 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 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 57d1545e4afc97517f1472e626c27b8009e904cc Mon Sep 17 00:00:00 2001 From: David Boddie Date: Wed, 24 Nov 2010 13:48:14 +0100 Subject: Doc: Added documentation about Tab and Backtab key handling. Task-number: QTBUG-15569 --- src/declarative/graphicsitems/qdeclarativeitem.cpp | 24 +++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index e0df751..93572a0 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -484,10 +484,18 @@ void QDeclarativeItemKeyFilter::componentComplete() \qmlproperty Item KeyNavigation::down These properties hold the item to assign focus to - when Key_Left, Key_Right, Key_Up or Key_Down are + when the left, right, up or down cursor keys are pressed. */ +/*! + \qmlproperty Item KeyNavigation::tab + \qmlproperty Item KeyNavigation::backtab + + These properties hold the item to assign focus to + when the Tab key or Shift+Tab key combination (Backtab) are pressed. +*/ + QDeclarativeKeyNavigationAttached::QDeclarativeKeyNavigationAttached(QObject *parent) : QObject(*(new QDeclarativeKeyNavigationAttachedPrivate), parent), QDeclarativeItemKeyFilter(qobject_cast(parent)) @@ -941,6 +949,20 @@ void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post) */ /*! + \qmlsignal Keys::onTabPressed(KeyEvent event) + + This handler is called when the Tab key has been pressed. The \a event + parameter provides information about the event. +*/ + +/*! + \qmlsignal Keys::onBacktabPressed(KeyEvent event) + + This handler is called when the Shift+Tab key combination (Backtab) has + been pressed. The \a event parameter provides information about the event. +*/ + +/*! \qmlsignal Keys::onAsteriskPressed(KeyEvent event) This handler is called when the Asterisk '*' has been pressed. The \a event -- 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 73fb20bc600546e5c7d7e0ad41b28a9b7856665a Mon Sep 17 00:00:00 2001 From: aavit Date: Thu, 25 Nov 2010 12:14:51 +0100 Subject: Avoid race condition: don't quit until new executable is ready --- tests/arthur/baselineserver/src/baselineserver.cpp | 2 ++ tests/arthur/common/baselineprotocol.pri | 1 + 2 files changed, 3 insertions(+) diff --git a/tests/arthur/baselineserver/src/baselineserver.cpp b/tests/arthur/baselineserver/src/baselineserver.cpp index 0399224..fbf68f5 100644 --- a/tests/arthur/baselineserver/src/baselineserver.cpp +++ b/tests/arthur/baselineserver/src/baselineserver.cpp @@ -97,6 +97,8 @@ void BaselineServer::heartbeat() QFileInfo me(QCoreApplication::applicationFilePath()); if (me.lastModified() == meLastMod) return; + if (!me.exists() || !me.isExecutable()) + return; //# (could close() here to avoid accepting new connections, to avoid livelock) //# also, could check for a timeout to force exit, to avoid hung threads blocking diff --git a/tests/arthur/common/baselineprotocol.pri b/tests/arthur/common/baselineprotocol.pri index 996f9d5..62e38a6 100644 --- a/tests/arthur/common/baselineprotocol.pri +++ b/tests/arthur/common/baselineprotocol.pri @@ -1,4 +1,5 @@ INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD QT *= network -- 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 a0be2bb3f5a7f71f1e77ca7b8907e49b8e16bef3 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 25 Nov 2010 13:50:27 +0100 Subject: Doc: Fixed a snippet to show QML comments. Task-number: QTBUG-15584 --- doc/src/snippets/declarative/comments.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/src/snippets/declarative/comments.qml b/doc/src/snippets/declarative/comments.qml index a8e47ad..97659a5 100644 --- a/doc/src/snippets/declarative/comments.qml +++ b/doc/src/snippets/declarative/comments.qml @@ -38,7 +38,6 @@ ** ****************************************************************************/ -//![0] import QtQuick 1.0 //![0] -- cgit v0.12 From dcce5c796e5cd5cb090f1c395e483269bab01566 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 25 Nov 2010 13:56:29 +0100 Subject: Doc: Fixed whitespace. --- .../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 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 3fe96820ea6830cb76793602f9f51fb961e70976 Mon Sep 17 00:00:00 2001 From: Geir Vattekar Date: Fri, 26 Nov 2010 08:41:37 +0100 Subject: Doc: Removed two warnings from QDirIterator docs Task-number: QTBUG-15492 --- src/corelib/io/qdiriterator.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index fd4b9c1..dbb333f 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -389,9 +389,6 @@ QDirIterator::QDirIterator(const QDir &dir, IteratorFlags flags) \note To list symlinks that point to non existing files, QDir::System must be passed to the flags. - \warning This constructor expects \a flags to be left at its default value. Use - the constructors that do not take the \a filters argument instead. - \sa hasNext(), next(), IteratorFlags */ QDirIterator::QDirIterator(const QString &path, QDir::Filters filters, IteratorFlags flags) @@ -429,9 +426,6 @@ QDirIterator::QDirIterator(const QString &path, IteratorFlags flags) \note To list symlinks that point to non existing files, QDir::System must be passed to the flags. - \warning This constructor expects \c flags to be left at its default value. Use the - constructors that do not take the \a filters argument instead. - \sa hasNext(), next(), IteratorFlags */ QDirIterator::QDirIterator(const QString &path, const QStringList &nameFilters, -- cgit v0.12 From 5f70c3d9004765f8f86e3472cf59cfa7677f9163 Mon Sep 17 00:00:00 2001 From: Geir Vattekar Date: Fri, 26 Nov 2010 09:29:26 +0100 Subject: Doc:Fix paths in styleplugin/echoplugin .pro files Task-number: QTBUG-14169 --- examples/tools/echoplugin/echowindow/echowindow.pro | 4 ++-- examples/tools/styleplugin/plugin/plugin.pro | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/tools/echoplugin/echowindow/echowindow.pro b/examples/tools/echoplugin/echowindow/echowindow.pro index bdf8c41..d56961c 100644 --- a/examples/tools/echoplugin/echowindow/echowindow.pro +++ b/examples/tools/echoplugin/echowindow/echowindow.pro @@ -5,8 +5,8 @@ SOURCES = echowindow.cpp \ TARGET = echoplugin win32 { - debug:DESTDIR = ../debug/ - release:DESTDIR = ../release/ + CONFIG(debug, release|debug):DESTDIR = ../debug/ + CONFIG(release, release|debug):DESTDIR = ../release/ } else { DESTDIR = ../ } diff --git a/examples/tools/styleplugin/plugin/plugin.pro b/examples/tools/styleplugin/plugin/plugin.pro index 7cb0c97..54e266c 100644 --- a/examples/tools/styleplugin/plugin/plugin.pro +++ b/examples/tools/styleplugin/plugin/plugin.pro @@ -8,8 +8,8 @@ SOURCES = simplestyle.cpp \ TARGET = simplestyleplugin #! [0] win32 { - debug:DESTDIR = ../debug/styles/ - release:DESTDIR = ../release/styles/ + CONFIG(debug, release|debug):DESTDIR = ../debug/styles/ + CONFIG(release, release|debug):DESTDIR = ../release/styles/ } else { DESTDIR = ../styles/ } -- 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 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 16c3df54960b776f35f59288b888e829e7e81002 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 30 Nov 2010 12:09:48 +0100 Subject: Fixed incorrect angle values in the RotationAnimation description. Task-number: QTBUG-15696 --- src/declarative/util/qdeclarativeanimation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index f2e6217..dd7e5fd 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -1324,7 +1324,7 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t) /*! \qmlclass RotationAnimation QDeclarativeRotationAnimation - \ingroup qml-animation-transition + \ingroup qml-animation-transition \since 4.7 \inherits PropertyAnimation \brief The RotationAnimation element animates changes in rotation values. @@ -1333,8 +1333,8 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t) over the direction of rotation during an animation. By default, it rotates in the direction - of the numerical change; a rotation from 0 to 240 will rotate 220 degrees - clockwise, while a rotation from 240 to 0 will rotate 220 degrees + of the numerical change; a rotation from 0 to 240 will rotate 240 degrees + clockwise, while a rotation from 240 to 0 will rotate 240 degrees counterclockwise. The \l direction property can be set to specify the direction in which the rotation should occur. @@ -1342,7 +1342,7 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t) between states via the shortest path: \snippet doc/src/snippets/declarative/rotationanimation.qml 0 - + Notice the RotationAnimation did not need to set a \l target value. As a convenience, when used in a transition, RotationAnimation will rotate all properties named "rotation" or "angle". You can override this by providing -- 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 0211631bb8af96dfe2f6edc2d6c419f496ba89da Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 30 Nov 2010 13:39:44 +0100 Subject: QRasterPixmapData: Reuse underlying QImage in fill() if possible. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When switching from a format without alpha channel to one that has it, reuse the underlying QImage memory if the old & new color depths match. This avoids one allocation when using the rather common pattern: QPixmap pixmap(w, h); pixmap.fill(Qt::transparent); Reviewed-by: Samuel Rødal --- src/gui/image/qimage.cpp | 42 +++------------------------------------- src/gui/image/qimage_p.h | 36 ++++++++++++++++++++++++++++++++++ src/gui/image/qpixmap_raster.cpp | 8 +++++++- 3 files changed, 46 insertions(+), 40 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index d86021cb9..747dd2f 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -139,42 +139,6 @@ QImageData::QImageData() { } -static int depthForFormat(QImage::Format format) -{ - int depth = 0; - switch(format) { - case QImage::Format_Invalid: - case QImage::NImageFormats: - Q_ASSERT(false); - case QImage::Format_Mono: - case QImage::Format_MonoLSB: - depth = 1; - break; - case QImage::Format_Indexed8: - depth = 8; - break; - case QImage::Format_RGB32: - case QImage::Format_ARGB32: - case QImage::Format_ARGB32_Premultiplied: - depth = 32; - break; - case QImage::Format_RGB555: - case QImage::Format_RGB16: - case QImage::Format_RGB444: - case QImage::Format_ARGB4444_Premultiplied: - depth = 16; - break; - case QImage::Format_RGB666: - case QImage::Format_ARGB6666_Premultiplied: - case QImage::Format_ARGB8565_Premultiplied: - case QImage::Format_ARGB8555_Premultiplied: - case QImage::Format_RGB888: - depth = 24; - break; - } - return depth; -} - /*! \fn QImageData * QImageData::create(const QSize &size, QImage::Format format, int numColors) \internal @@ -195,7 +159,7 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format, int nu uint width = size.width(); uint height = size.height(); - uint depth = depthForFormat(format); + uint depth = qt_depthForFormat(format); switch (format) { case QImage::Format_Mono: @@ -871,7 +835,7 @@ QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QIm return 0; } - const int depth = depthForFormat(format); + const int depth = qt_depthForFormat(format); const int calc_bytes_per_line = ((width * depth + 31)/32) * 4; const int min_bytes_per_line = (width * depth + 7)/8; @@ -6321,7 +6285,7 @@ int QImage::bitPlaneCount() const bpc = 12; break; default: - bpc = depthForFormat(d->format); + bpc = qt_depthForFormat(d->format); break; } return bpc; diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index c687448..e054814 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -112,6 +112,42 @@ struct Q_GUI_EXPORT QImageData { // internal image data void qInitImageConversions(); +inline int qt_depthForFormat(QImage::Format format) +{ + int depth = 0; + switch(format) { + case QImage::Format_Invalid: + case QImage::NImageFormats: + Q_ASSERT(false); + case QImage::Format_Mono: + case QImage::Format_MonoLSB: + depth = 1; + break; + case QImage::Format_Indexed8: + depth = 8; + break; + case QImage::Format_RGB32: + case QImage::Format_ARGB32: + case QImage::Format_ARGB32_Premultiplied: + depth = 32; + break; + case QImage::Format_RGB555: + case QImage::Format_RGB16: + case QImage::Format_RGB444: + case QImage::Format_ARGB4444_Premultiplied: + depth = 16; + break; + case QImage::Format_RGB666: + case QImage::Format_ARGB6666_Premultiplied: + case QImage::Format_ARGB8565_Premultiplied: + case QImage::Format_ARGB8555_Premultiplied: + case QImage::Format_RGB888: + depth = 24; + break; + } + return depth; +} + QT_END_NAMESPACE #endif diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index 53f3559..65c0344 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -206,7 +206,13 @@ void QRasterPixmapData::fill(const QColor &color) else #endif toFormat = QImage::Format_ARGB32_Premultiplied; - image = QImage(image.width(), image.height(), toFormat); + + if (!image.isNull() && qt_depthForFormat(image.format()) == qt_depthForFormat(toFormat)) { + image.detach(); + image.d->format = toFormat; + } else { + image = QImage(image.width(), image.height(), toFormat); + } } switch (image.format()) { -- 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 3e69b6b8f8e62bc7ca0944a957371e6d5de4640b Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Tue, 30 Nov 2010 17:15:19 +0100 Subject: avoid the warning about comparison between signed and unsigned integers Merge-request: 951 Reviewed-by: Thiago Macieira --- src/corelib/kernel/qeventdispatcher_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 91c20b5..a363874 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -492,7 +492,7 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA // we also use a Windows timer to send posted events when the message queue is full || (message == WM_TIMER && d->sendPostedEventsWindowsTimerId != 0 - && wp == d->sendPostedEventsWindowsTimerId)) { + && wp == (uint)d->sendPostedEventsWindowsTimerId)) { int localSerialNumber = d->serialNumber; if (localSerialNumber != d->lastSerialNumber) { d->lastSerialNumber = localSerialNumber; -- 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 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 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 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 993f9b23d72ec74453163413403d0cf06d9f08f4 Mon Sep 17 00:00:00 2001 From: aavit Date: Thu, 2 Dec 2010 15:23:13 +0100 Subject: Added new View command on reports --- tests/arthur/baselineserver/src/baselineserver.cpp | 8 +++ tests/arthur/baselineserver/src/baselineserver.h | 1 + tests/arthur/baselineserver/src/baselineserver.pro | 3 + tests/arthur/baselineserver/src/baselineserver.qrc | 5 ++ tests/arthur/baselineserver/src/htmlpage.cpp | 18 +++-- .../arthur/baselineserver/src/templates/view.html | 79 ++++++++++++++++++++++ 6 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 tests/arthur/baselineserver/src/baselineserver.qrc create mode 100644 tests/arthur/baselineserver/src/templates/view.html diff --git a/tests/arthur/baselineserver/src/baselineserver.cpp b/tests/arthur/baselineserver/src/baselineserver.cpp index fbf68f5..53e40b6 100644 --- a/tests/arthur/baselineserver/src/baselineserver.cpp +++ b/tests/arthur/baselineserver/src/baselineserver.cpp @@ -355,6 +355,14 @@ QString BaselineHandler::pathForItem(const ImageItem &item, bool isBaseline, boo } +QString BaselineHandler::view(const QString &baseline, const QString &rendered, const QString &compared) +{ + QFile f(":/templates/view.html"); + f.open(QIODevice::ReadOnly); + return QString::fromLatin1(f.readAll()).arg('/'+baseline, '/'+rendered, '/'+compared); +} + + QString BaselineHandler::clearAllBaselines(const QString &context) { int tot = 0; diff --git a/tests/arthur/baselineserver/src/baselineserver.h b/tests/arthur/baselineserver/src/baselineserver.h index c5cb45e..346ce1f 100644 --- a/tests/arthur/baselineserver/src/baselineserver.h +++ b/tests/arthur/baselineserver/src/baselineserver.h @@ -100,6 +100,7 @@ public: BaselineHandler(int socketDescriptor = -1); void testPathMapping(); + static QString view(const QString &baseline, const QString &rendered, const QString &compared); static QString clearAllBaselines(const QString &context); static QString updateSingleBaseline(const QString &oldBaseline, const QString &newBaseline); static QString blacklistTest(const QString &context, const QString &itemId, bool removeFromBlacklist = false); diff --git a/tests/arthur/baselineserver/src/baselineserver.pro b/tests/arthur/baselineserver/src/baselineserver.pro index a7be03d..defa05a 100644 --- a/tests/arthur/baselineserver/src/baselineserver.pro +++ b/tests/arthur/baselineserver/src/baselineserver.pro @@ -25,3 +25,6 @@ SOURCES += main.cpp \ HEADERS += \ baselineserver.h \ htmlpage.h + +RESOURCES += \ + baselineserver.qrc diff --git a/tests/arthur/baselineserver/src/baselineserver.qrc b/tests/arthur/baselineserver/src/baselineserver.qrc new file mode 100644 index 0000000..b5cd6af --- /dev/null +++ b/tests/arthur/baselineserver/src/baselineserver.qrc @@ -0,0 +1,5 @@ + + + templates/view.html + + diff --git a/tests/arthur/baselineserver/src/htmlpage.cpp b/tests/arthur/baselineserver/src/htmlpage.cpp index 9659505..11c2eac 100644 --- a/tests/arthur/baselineserver/src/htmlpage.cpp +++ b/tests/arthur/baselineserver/src/htmlpage.cpp @@ -131,10 +131,13 @@ void HTMLPage::addItem(const QString &baseline, const QString &rendered, const I foreach(const QString& img, images) out << "\n"; - out << "

Replace baseline with rendered

" + out << "\n" + << "

Replace baseline with rendered

\n" << "

Blacklist this item

" + << "&itemId=" << item.scriptName << "&url=" << pageUrl << "\">Blacklist this item

\n" + << "

View

\n" << "\n"; out << "\n\n"; @@ -213,12 +216,15 @@ void HTMLPage::handleCGIQuery(const QString &query) QTextStream s(stdout); s << "Content-Type: text/html\r\n\r\n" << ""; -// << "Contents of QUERY_STRING:
" -// << "Full string = " << query << "
"; QString command(cgiUrl.queryItemValue("cmd")); - if (command == QLS("updateSingleBaseline")) { + if (command == QLS("view")) { + s << BaselineHandler::view(cgiUrl.queryItemValue(QLS("baseline")), + cgiUrl.queryItemValue(QLS("rendered")), + cgiUrl.queryItemValue(QLS("compared"))); + } + else if (command == QLS("updateSingleBaseline")) { s << BaselineHandler::updateSingleBaseline(cgiUrl.queryItemValue(QLS("oldBaseline")), cgiUrl.queryItemValue(QLS("newBaseline"))); } else if (command == QLS("clearAllBaselines")) { diff --git a/tests/arthur/baselineserver/src/templates/view.html b/tests/arthur/baselineserver/src/templates/view.html new file mode 100644 index 0000000..c048f47 --- /dev/null +++ b/tests/arthur/baselineserver/src/templates/view.html @@ -0,0 +1,79 @@ +

Lancelot Viewer

+ +

+Zoom: +1x +2x +4x +

+ +

+ + + + + + + + + + + + +
Baseline%1
Rendered%2
Differences

+ + +

+ +

+ + -- 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 19b1ab1f2f4df72621b1bef43a4a24286ae12657 Mon Sep 17 00:00:00 2001 From: Jerome Pasion Date: Mon, 6 Dec 2010 16:07:06 +0100 Subject: Fixed a bug by changing the id name to lower case. --- doc/src/getting-started/gettingstartedqml.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/getting-started/gettingstartedqml.qdoc b/doc/src/getting-started/gettingstartedqml.qdoc index b767587..e3977bb 100644 --- a/doc/src/getting-started/gettingstartedqml.qdoc +++ b/doc/src/getting-started/gettingstartedqml.qdoc @@ -148,7 +148,7 @@ \code Rectangle { - id:Button + id: button ... property color buttonColor: "lightblue" -- cgit v0.12 From 9679add86ec1562d24d587c6c2343c47ca4b61d7 Mon Sep 17 00:00:00 2001 From: Jerome Pasion Date: Mon, 6 Dec 2010 16:09:26 +0100 Subject: Some whitespace fixes. --- doc/src/declarative/modules.qdoc | 64 ++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc index 011eb63..2a2e4ff 100644 --- a/doc/src/declarative/modules.qdoc +++ b/doc/src/declarative/modules.qdoc @@ -31,14 +31,14 @@ \section1 QML Modules -A module is a set of QML content files that can be imported as a unit into a QML +A module is a set of QML content files that can be imported as a unit into a QML application. Modules can be used to organize QML content into independent units, -and they can use a versioning mechanism that allows for independent +and they can use a versioning mechanism that allows for independent upgradability of the modules. While QML component files within the same directory are automatically accessible -within the global namespace, components defined elsewhere must be imported -explicitly using the \c import statement to import them as modules. For +within the global namespace, components defined elsewhere must be imported +explicitly using the \c import statement to import them as modules. For example, an \c import statement is required to use: \list @@ -54,13 +54,13 @@ This can be seen in the snippet commonly found at the top of QML files: \qml import QtQuick 1.0 \endqml - -This imports version 4.7 of the "Qt" module into the global namespace. (The QML + +This imports version 1.0 of the "QtQuick" module into the global namespace. (The QML library itself must be imported to use any of the \l {QML Elements}, as they are not included in the global namespace by default.) -The \c Qt module is an \e installed module; it is found in the -\l{The QML import path}{import path}. There are two types of QML modules: +The \c Qt module is an \e installed module; it is found in the +\l{The QML import path}{import path}. There are two types of QML modules: location modules (defined by a URL) and installed modules (defined by a URI). @@ -87,8 +87,8 @@ directory using a relative or absolute path, like this: MyQMLProject |- MyComponents |- Slider.qml - |- CheckBox.qml - |- Main + |- CheckBox.qml + |- Main |- application.qml \endcode @@ -112,7 +112,7 @@ be imported like this: Remote location modules must have a \l{Writing a qmldir file}{qmldir file} in the same directory to specify which QML files should be made available. See the -\l {#qmldirexample}{example} below. The qmldir file is optional for modules on +\l {#qmldirexample}{example} below. The qmldir file is optional for modules on the local filesystem. @@ -121,8 +121,8 @@ the local filesystem. Installed modules are modules that are installed on the -local filesystem within the QML import path, or modules defined in C++ -application code. When importing an installed module, an un-quoted URI is +local filesystem within the QML import path, or modules defined in C++ +application code. When importing an installed module, an un-quoted URI is used, with a mandatory version number: \code @@ -131,7 +131,7 @@ used, with a mandatory version number: \endcode Installed modules that are installed into the import path or created -as a \l{QDeclarativeExtensionPlugin}{QML C++ plugin} must define a +as a \l{QDeclarativeExtensionPlugin}{QML C++ plugin} must define a \l{Writing a qmldir file}{qmldir file}. @@ -142,7 +142,7 @@ The default import path includes: \list \o The directory of the current file -\o The location specified by QLibraryInfo::ImportsPath +\o The location specified by QLibraryInfo::ImportsPath \o Paths specified by the \c QML_IMPORT_PATH environment variable \endlist @@ -153,10 +153,10 @@ When running the \l {QML Viewer}, use the \c -I option to add paths to the impor \section2 Creating installed modules in C++ -C++ applications can dynamically define installed modules using -qmlRegisterType(). +C++ applications can dynamically define installed modules using +qmlRegisterType(). -For \l{QDeclarativeExtensionPlugin}{QML C++ plugins}, the +For \l{QDeclarativeExtensionPlugin}{QML C++ plugins}, the module URI is automatically passed to QDeclarativeExtensionPlugin::registerTypes(). The QDeclarativeExtensionPlugin documentation shows how to use this URI to call qmlRegisterType() to enable the plugin library to be built as @@ -167,7 +167,7 @@ in QML, like this: import com.nokia.TimeExample 1.0 \endcode -A \l{QDeclarativeExtensionPlugin}{QML C++ plugin} also requires a +A \l{QDeclarativeExtensionPlugin}{QML C++ plugin} also requires a \l{Writing a qmldir file}{qmldir file} to make it available to the QML engine. @@ -190,9 +190,9 @@ Types from these modules can then only be used when qualified by the namespace: \qml QtLibrary.Rectangle { ... } - + MyComponents.Slider { ... } - + MyModule.SomeComponent { ... } \endqml @@ -209,7 +209,7 @@ JavaScript files must always be imported with a named import: \qml import "somescript.js" as MyScript - + Item { //... Component.onCompleted: MyScript.doSomething() @@ -220,8 +220,8 @@ JavaScript files must always be imported with a named import: \section1 Writing a qmldir file -A \c qmldir file is a metadata file for a module that maps all type names in -the module to versioned QML files. It is required for installed modules, and +A \c qmldir file is a metadata file for a module that maps all type names in +the module to versioned QML files. It is required for installed modules, and location modules that are loaded from a network source. It is defined by a plain text file named "qmldir" that contains one or more lines of the form: @@ -237,7 +237,7 @@ plugin [] \bold { [] } lines are used to add QML files as types. is the type being made available, the optional is a version -number, and is the (relative) file name of the QML file defining the type. +number, and is the (relative) file name of the QML file defining the type. Installed files do not need to import the module of which they are a part, as they can refer to the other QML files in the module as relative (local) files, but @@ -264,10 +264,10 @@ provide those identifiers. \bold {plugin []} lines are used to add \l{QDeclarativeExtensionPlugin}{QML C++ plugins} to the module. is the name of the library. It is usually not the same as the file name of the plugin binary, which is platform dependent; e.g. the library \c MyAppTypes would produce -\c libMyAppTypes.so on Linux and \c MyAppTypes.dll on Windows. +\c libMyAppTypes.so on Linux and \c MyAppTypes.dll on Windows. is an optional argument specifying either an absolute path to the directory containing the -plugin file, or a relative path from the directory containing the \c qmldir file to the directory +plugin file, or a relative path from the directory containing the \c qmldir file to the directory containing the plugin file. By default the engine searches for the plugin library in the directory that contains the \c qmldir file. The plugin search path can be queried with QDeclarativeEngine::pluginPathList() and modified using QDeclarativeEngine::addPluginPath(). When running the \l {QML Viewer}, use the \c -P option to add paths to the plugin search path. @@ -275,7 +275,7 @@ file. The plugin search path can be queried with QDeclarativeEngine::pluginPathL \target qmldirexample \section2 Example -If the components in the \c MyComponents directory from the +If the components in the \c MyComponents directory from the \l{Location Modules}{earlier example} were to be made available as a network resource, the directory would need to contain a \c qmldir file similar to this: @@ -284,7 +284,7 @@ ComponentA 1.0 ComponentA.qml ComponentB 1.0 ComponentB.qml \endcode -The \c MyComponents directory could then be imported as a module using: +The \c MyComponents directory could then be imported as a module using: \code import "http://the-server-name.com/MyComponents" @@ -298,15 +298,15 @@ a later version is used, as the \c qmldir file specifies that these elements are only available in the 1.0 version. -For examples of \c qmldir files for plugins, see the -\l {declarative/cppextensions/plugins}{Plugins} example and +For examples of \c qmldir files for plugins, see the +\l {declarative/cppextensions/plugins}{Plugins} example and \l {Tutorial: Writing QML extensions with C++}. \section1 Debugging The \c QML_IMPORT_TRACE environment variable can be useful for debugging -when there are problems with finding and loading modules. See +when there are problems with finding and loading modules. See \l{Debugging module imports} for more information. -- 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 686dfda2146a84e6653faa56a1484e84571cc4fa Mon Sep 17 00:00:00 2001 From: Jerome Pasion Date: Mon, 6 Dec 2010 17:39:21 +0100 Subject: Fixed link to qtestlib-tools by adding link to qt-webpages.qdoc. Link is now linking to the gitorious project site. Task-number: QTBUG-15714 Reviewed-by: David Boddie --- doc/src/development/qtestlib.qdoc | 29 ++++++++++++++--------------- doc/src/qt-webpages.qdoc | 10 ++++++++++ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/doc/src/development/qtestlib.qdoc b/doc/src/development/qtestlib.qdoc index e53957f..08fdfc6 100644 --- a/doc/src/development/qtestlib.qdoc +++ b/doc/src/development/qtestlib.qdoc @@ -245,10 +245,10 @@ \endtable In short, walltime is always available but requires many repetitions to - get a useful result. - Tick counters are usually available and can provide - results with fewer repetitions, but can be susceptible to CPU frequency - scaling issues. + get a useful result. + Tick counters are usually available and can provide + results with fewer repetitions, but can be susceptible to CPU frequency + scaling issues. Valgrind provides exact results, but does not take I/O waits into account, and is only available on a limited number of platforms. @@ -264,7 +264,7 @@ See the chapter 5 in the \l{QTestLib Tutorial} for more benchmarking examples. \section1 Using QTestLib remotely on Windows CE - \c cetest is a convenience application which helps the user to launch an + \c cetest is a convenience application which helps the user to launch an application remotely on a Windows CE device or emulator. It needs to be executed after the unit test has been successfully compiled. @@ -717,15 +717,15 @@ \section1 Writing a Benchmark To create a benchmark we extend a test function with a QBENCHMARK macro. - A benchmark test function will then typically consist of setup code and + A benchmark test function will then typically consist of setup code and a QBENCHMARK macro that contains the code to be measured. This test function benchmarks QString::localeAwareCompare(). \snippet examples/qtestlib/tutorial5/benchmarking.cpp 0 - Setup can be done at the beginning of the function, the clock is not + Setup can be done at the beginning of the function, the clock is not running at this point. The code inside the QBENCHMARK macro will be - measured, and possibly repeated several times in order to get an + measured, and possibly repeated several times in order to get an accurate measurement. Several \l {testlib-benchmarking-measurement}{back-ends} are available @@ -733,7 +733,7 @@ \section1 Data Functions - Data functions are useful for creating benchmarks that compare + Data functions are useful for creating benchmarks that compare multiple data inputs, for example locale aware compare against standard compare. @@ -743,20 +743,19 @@ \snippet examples/qtestlib/tutorial5/benchmarking.cpp 2 - The "if(useLocaleCompare)" switch is placed outside the QBENCHMARK + The "if(useLocaleCompare)" switch is placed outside the QBENCHMARK macro to avoid measuring its overhead. Each benchmark test function - can have one active QBENCHMARK macro. + can have one active QBENCHMARK macro. \section1 External Tools Tools for handling and visualizing test data are available as part of - the qtestlib-tools project on the - \l{http://labs.qt.nokia.com/}{http://labs.qt.nokia.com/}Qt Labs Web site. + the \l {qtestlib-tools} project in the \l{Qt Labs} web site. These include a tool for comparing performance data obtained from test runs and a utility to generate Web-based graphs of performance data. - See the \l{qtestlib-tools Announcement} for more information on these - tools and a simple graphing example. + See the \l{qtestlib-tools Announcement}{qtestlib-tools announcement} + for more information on these tools and a simple graphing example. */ diff --git a/doc/src/qt-webpages.qdoc b/doc/src/qt-webpages.qdoc index 05817df..b7b9fba 100644 --- a/doc/src/qt-webpages.qdoc +++ b/doc/src/qt-webpages.qdoc @@ -239,3 +239,13 @@ \externalpage http://get.qt.nokia.com/nokiasmartinstaller/ \title Smart Installer */ + +/*! + \externalpage http://qt.gitorious.org/qt-labs/qtestlib-tools + \title qtestlib-tools +*/ + +/*! + \externalpage http://labs.qt.nokia.com + \title Qt Labs +*/ -- cgit v0.12 From 1eb7dca7fe6a81bada556c1310905be08e1b1d10 Mon Sep 17 00:00:00 2001 From: Jerome Pasion Date: Mon, 6 Dec 2010 17:43:31 +0100 Subject: Added QML coding convention for "private" properties. Private properties start with two underscores. __property Reviewed-by: David Boddie --- doc/src/declarative/codingconventions.qdoc | 18 ++++++-- .../declarative/codingconventions/private.qml | 49 ++++++++++++++++++++++ 2 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 doc/src/snippets/declarative/codingconventions/private.qml diff --git a/doc/src/declarative/codingconventions.qdoc b/doc/src/declarative/codingconventions.qdoc index ba789e0..3f92d46 100644 --- a/doc/src/declarative/codingconventions.qdoc +++ b/doc/src/declarative/codingconventions.qdoc @@ -35,7 +35,7 @@ This page assumes that you are already familiar with the QML language. If you need an introduction to the language, please read \l {Introduction to the QML language}{the QML introduction} first. -\section1 QML objects +\section1 QML Objects Through our documentation and examples, QML objects are always structured in the following order: @@ -58,7 +58,7 @@ For example, a hypothetical \e photo QML object would look like this: \snippet doc/src/snippets/declarative/codingconventions/photo.qml 0 -\section1 Grouped properties +\section1 Grouped Properties If using multiple properties from a group of properties, we use the \e {group notation} rather than the \e {dot notation} to improve readability. @@ -72,6 +72,18 @@ can be written like this: \snippet doc/src/snippets/declarative/codingconventions/dotproperties.qml 1 +\section1 Private Properties + +QML and JavaScript do not enforce private properties like C++. There is a need +to hide these private properties, for example, when the properties are part of +the implementation. As a convention, private properties begin with two +\e underscore characters. For example, \c __area, is a property that is +accessible but is not meant for public use. Note that QML and JavaScript will +grant the user access to these properties. + +\snippet doc/src/snippets/declarative/codingconventions/private.qml 0 + + \section1 Lists If a list contains only one element, we generally omit the square brackets. @@ -87,7 +99,7 @@ we will write this: \snippet doc/src/snippets/declarative/codingconventions/lists.qml 1 -\section1 JavaScript code +\section1 JavaScript Code If the script is a single expression, we recommend writing it inline: diff --git a/doc/src/snippets/declarative/codingconventions/private.qml b/doc/src/snippets/declarative/codingconventions/private.qml new file mode 100644 index 0000000..1d3dda8 --- /dev/null +++ b/doc/src/snippets/declarative/codingconventions/private.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 { + id: component + width: 40; height: 50 + property real __area: width * height * 0.5 //not meant for outside use +} +//! [0] -- cgit v0.12 From 608b66b5af75ae6982be428439eea735c00cc455 Mon Sep 17 00:00:00 2001 From: Jerome Pasion Date: Mon, 6 Dec 2010 17:46:28 +0100 Subject: Fixed the QML Focus document. Fixed snippets, images, and formatting. Reviewed-by: David Boddie --- doc/src/declarative/focus.qdoc | 339 ++++++++------------- doc/src/images/declarative-qmlfocus1.png | Bin 0 -> 1890 bytes doc/src/images/declarative-qmlfocus2.png | Bin 0 -> 2756 bytes doc/src/images/declarative-qmlfocus3.png | Bin 0 -> 2743 bytes doc/src/images/declarative-qmlfocus4.png | Bin 0 -> 4137 bytes doc/src/images/declarative-qmlfocus5.png | Bin 0 -> 1376 bytes .../snippets/declarative/focus/advancedFocus.qml | 67 ++++ doc/src/snippets/declarative/focus/basicwidget.qml | 59 ++++ .../snippets/declarative/focus/clickablewidget.qml | 61 ++++ doc/src/snippets/declarative/focus/focusColumn.qml | 25 ++ .../declarative/focus/focusscopewidget.qml | 61 ++++ .../declarative/focus/myclickablewidget.qml | 69 +++++ .../declarative/focus/myfocusscopewidget.qml | 66 ++++ doc/src/snippets/declarative/focus/mywidget.qml | 58 ++++ doc/src/snippets/declarative/focus/qmldir | 4 + doc/src/snippets/declarative/focus/rectangle.qml | 62 ++++ doc/src/snippets/declarative/focus/widget.qml | 61 ++++ 17 files changed, 713 insertions(+), 219 deletions(-) create mode 100644 doc/src/images/declarative-qmlfocus1.png create mode 100644 doc/src/images/declarative-qmlfocus2.png create mode 100644 doc/src/images/declarative-qmlfocus3.png create mode 100644 doc/src/images/declarative-qmlfocus4.png create mode 100644 doc/src/images/declarative-qmlfocus5.png create mode 100644 doc/src/snippets/declarative/focus/advancedFocus.qml create mode 100644 doc/src/snippets/declarative/focus/basicwidget.qml create mode 100644 doc/src/snippets/declarative/focus/clickablewidget.qml create mode 100644 doc/src/snippets/declarative/focus/focusColumn.qml create mode 100644 doc/src/snippets/declarative/focus/focusscopewidget.qml create mode 100644 doc/src/snippets/declarative/focus/myclickablewidget.qml create mode 100644 doc/src/snippets/declarative/focus/myfocusscopewidget.qml create mode 100644 doc/src/snippets/declarative/focus/mywidget.qml create mode 100644 doc/src/snippets/declarative/focus/qmldir create mode 100644 doc/src/snippets/declarative/focus/rectangle.qml create mode 100644 doc/src/snippets/declarative/focus/widget.qml diff --git a/doc/src/declarative/focus.qdoc b/doc/src/declarative/focus.qdoc index 2e74fe0..ae72c3c 100644 --- a/doc/src/declarative/focus.qdoc +++ b/doc/src/declarative/focus.qdoc @@ -31,7 +31,7 @@ \title Keyboard Focus in QML When a key is pressed or released, a key event is generated and delivered to the -focused QML \l Item. To facilitate the construction of reusable components +focused QML \l Item. To facilitate the construction of reusable components and to address some of the cases unique to fluid user interfaces, the QML items add a \e scope based extension to Qt's traditional keyboard focus model. @@ -42,27 +42,21 @@ and to address some of the cases unique to fluid user interfaces, the QML items When the user presses or releases a key, the following occurs: \list 1 \o Qt receives the key action and generates a key event. -\o If the Qt widget containing the \l QDeclarativeView has focus, the key event is delivered to it. Otherwise, regular Qt key handling continues. -\o The key event is delivered by the scene to the QML \l Item with \e {active focus}. If no \l Item has \e {active focus}, the key event is \l {QEvent::ignore()}{ignored} and regular Qt key handling continues. -\o If the QML \l Item with \e {active focus} accepts the key event, propagation stops. Otherwise the event is "bubbled up", by recursively passing it to each \l Item's parent until either the event is accepted, or the root \l Item is reached. - -If the \c {Rectangle} element in the following example has active focus and the \e A key is pressed, -it will bubble up to its parent. However, pressing the \e B key will bubble up to the root -item and thus subsequently be \l {QEvent::ignore()}{ignored}. - -\code -Item { - Item { - Keys.onPressed: { - if (event.key == Qt.Key_A) { - console.log('Key A was pressed'); - event.accepted = true; - } - } - Rectangle {} - } -} -\endcode +\o If the Qt widget containing the \l QDeclarativeView has focus, the key event +is delivered to it. Otherwise, regular Qt key handling continues. +\o The key event is delivered by the scene to the QML \l Item with +\e {active focus}. If no Item has active focus, the key event is +\l {QEvent::ignore()}{ignored} and regular Qt key handling continues. +\o If the QML Item with active focus accepts the key event, propagation +stops. Otherwise the event is "bubbled up", by recursively passing it to each +Item's parent until either the event is accepted, or the root Item is reached. + +If the \c {Rectangle} element in the following example has active focus and the \c A key is pressed, +it will bubble up to its parent. However, pressing the \c B key will bubble up to the root +item and thus subsequently be ignored. + +\snippet doc/src/snippets/declarative/focus/rectangle.qml simple key event +\snippet doc/src/snippets/declarative/focus/rectangle.qml simple key event end \o If the root \l Item is reached, the key event is \l {QEvent::ignore()}{ignored} and regular Qt key handling continues. @@ -72,232 +66,139 @@ See also the \l {Keys}{Keys attached property} and \l {KeyNavigation}{KeyNavigat \section1 Querying the Active Focus Item -Whether or not an \l Item has \e {active focus} can be queried through the -property \c {Item::activeFocus}. For example, here we have a \l Text -element whose text is determined by whether or not it has \e {active focus}. +Whether or not an \l Item has active focus can be queried through the +property \c {Item::activeFocus} property. For example, here we have a \l Text +element whose text is determined by whether or not it has active focus. -\code -Text { - text: activeFocus ? "I have active focus!" : "I do not have active focus" -} -\endcode +\snippet doc/src/snippets/declarative/focus/rectangle.qml active focus \section1 Acquiring Focus and Focus Scopes -An \l Item requests focus by setting the \c {Item::focus} property to true. - -For very simple cases simply setting the \c {Item::focus} property is sometimes -sufficient. If we run the following example with the \l {QML Viewer}, we see that -the \c {keyHandler} element has \e {active focus} and pressing the 'A', 'B' -or 'C' keys modifies the text appropriately. - -\table -\row -\o \code - Rectangle { - color: "lightsteelblue"; width: 240; height: 25 - Text { id: myText } - Item { - id: keyHandler - focus: true - Keys.onPressed: { - if (event.key == Qt.Key_A) - myText.text = 'Key A was pressed' - else if (event.key == Qt.Key_B) - myText.text = 'Key B was pressed' - else if (event.key == Qt.Key_C) - myText.text = 'Key C was pressed' - } - } - } -\endcode -\o \image declarative-qmlfocus1.png -\endtable - -However, were the above example to be used as a self-contained component, this -simple use of the \c {Item::focus} property is no longer sufficient. The left -hand side of the following table shows what we would like to be able to write. -Here we create two instances of our previously defined component, and set the -second one to have focus. The intention is that when the \e A, \e B, or \e C -keys are pressed, the second of the two components receives the event and +An \l Item requests focus by setting the \c focus property to \c true. + +For very simple cases simply setting the \c focus property is sometimes +sufficient. If we run the following example with the \l {QML Viewer}, we see that +the \c {keyHandler} element has active focus and pressing the \c A, \c B, +or \c C keys modifies the text appropriately. + +\snippet doc/src/snippets/declarative/focus/basicwidget.qml focus true + +\image declarative-qmlfocus1.png + +However, were the above example to be used as a reusable or imported component, +this simple use of the \c focus property is no longer sufficient. + +To demonstrate, we create two instances of our previously defined component and +set the first one to have focus. The intention is that when the \c A, \c B, or +\c C keys are pressed, the first of the two components receives the event and responds accordingly. -\table -\row -\o \code -Rectangle { - color: "red"; width: 240; height: 55 - MyWidget {} - MyWidget { y: 30; focus: true } -} -\endcode -\o \code -Rectangle { - color: "red"; width: 240; height: 55 - Rectangle { - color: "lightsteelblue"; width: 240; height: 25 - Text { id: myText } - Item { - id: keyHandler - focus: true - Keys.onPressed: { - if (event.key == Qt.Key_A) - myText.text = 'Key A was pressed' - else if (event.key == Qt.Key_B) - myText.text = 'Key B was pressed' - else if (event.key == Qt.Key_C) - myText.text = 'Key C was pressed' - } - } - } - Rectangle { - y: 30; focus: true - color: "lightsteelblue"; width: 240; height: 25 - Text { id: myText } - Item { - id: keyHandler - focus: true - Keys.onPressed: { - if (event.key == Qt.Key_A) - myText.text = 'Key A was pressed' - else if (event.key == Qt.Key_B) - myText.text = 'Key B was pressed' - else if (event.key == Qt.Key_C) - myText.text = 'Key C was pressed' - } - } - } -} -\endcode -\endtable - -The right hand side of the example shows the expanded code - the equivalent QML -without the use of the component \c {MyWidget}. From this, the problem is -evident - there are no less than three elements that have the \c {Item::focus} -property set to true. Ultimately only one element can have keyboard focus, and the -system has to decide which on. In this case the first appearance of the -\c {Item::focus} property being set to true on line 4 is selected, and the value -of \c {Item::focus} in the other two instances is reverted back to false. This -is exactly the opposite of what was wanted! - -This problem is fundamentally one of visibility. The \c {MyWidget} -components each set their \c {keyHandler} Items as focused as that is all they can -do - they don't know how they are going to be used, but they do know that when -they're in use their \c {keyHandler} element is what needs focus. Likewise -the code that uses the two \c {MyWidgets} sets the second \c {MyWidget} as -focused. While it doesn't know exactly how the \c {MyWidget} is -implemented, it knows that it wants the second one to be focused. This allows us -to achieve encapsulation, allowing each widget to focus on it's appropriate behaviour -itself. - -To solve this problem - allowing components to care about what they know about -and ignore everything else - the QML items introduce a concept known as a -\e {focus scope}. For existing Qt users, a \e {focus scope} is like an -automatic focus proxy. A \e {focus scope} is created using the \l FocusScope -element. - -In the next example, a \l FocusScope is added to the component, and the visual -result shown. - -\table -\row -\o \code -FocusScope { - width: 240; height: 25 - Rectangle { - color: "lightsteelblue"; width: 240; height: 25 - Text { id: myText } - Item { - id: keyHandler - focus: true - Keys.onPressed: { - if (event.key == Qt.Key_A) - myText.text = 'Key A was pressed' - else if (event.key == Qt.Key_B) - myText.text = 'Key B was pressed' - else if (event.key == Qt.Key_C) - myText.text = 'Key C was pressed' - } - } - } -} -\endcode -\o \image declarative-qmlfocus2.png -\endtable +The code that imports and creates two MyWidget instances: +\snippet doc/src/snippets/declarative/focus/widget.qml window + +The MyWidget code: +\snippet doc/src/snippets/declarative/focus/mywidget.qml mywidget + +We would like to have the first MyWidget object to have the focus by setting its +\c focus property to \c true. However, by running the code, we can confirm that +the second widget receives the focus. + +\image declarative-qmlfocus2.png + +Looking at both \c MyWidget and \c window code, the problem is evident - there +are three elements that set the \c focus property set to \c true. The two +MyWidget sets the \c focus to \c true and the \c window component also sets the +focus. Ultimately, only one element can have keyboard focus, and the system has +to decide which element receives the focus. When the second MyWidget is created, +it receives the focus because it is the last element to set its \c focus +property to \c true. + +This problem is due to visibility. The \c MyWidget component would like to have +the focus, but it cannot control the focus when it is imported or reused. +Likewise, the \c window component does not have the ability to know if its +imported components are requesting the focus. + +To solve this problem, the QML introduces a concept known as a \e {focus scope}. +For existing Qt users, a focus scope is like an automatic focus proxy. +A focus scope is created by declaring the \l FocusScope element. + +In the next example, a \l FocusScope element is added to the component, and the +visual result shown. + +\snippet doc/src/snippets/declarative/focus/myfocusscopewidget.qml widget in focusscope + +\image declarative-qmlfocus3.png + Conceptually \e {focus scopes} are quite simple. \list -\o Within each \e {focus scope} one element may have \c {Item::focus} set to true. -If more than one \l Item has the \c {Item::focus} property set, the first is selected -and the others are unset, just like when there are no \e {focus scopes}. -\o When a \e {focus scope} receives \e {active focus}, the contained element with -\c {Item::focus} set (if any) also gets \e {active focus}. If this element is -also a \l FocusScope, the proxying behaviour continues. Both the -\e {focus scope} and the sub-focused item will have \c {Item::activeFocus} set. +\o Within each focus scope one element may have \c {Item::focus} set to +\c true. If more than one \l Item has the \c focus property set, the +last element to set the \c focus will have the focus and the others are unset, +similar to when there are no focus scopes. +\o When a focus scope receives active focus, the contained element with +\c focus set (if any) also gets the active focus. If this element is +also a \l FocusScope, the proxying behavior continues. Both the +focus scope and the sub-focused item will have \c activeFocus property set. \endlist -So far the example has the second component statically selected. It is trivial +Note that, since the FocusScope element is not a visual element, the properties +of its children need to be exposed to the parent item of the FocusScope. Layouts +and positioning elements will use these visual and styling properties to create +the layout. In our example, the \c Column element cannot display the two widgets +properly because the FocusScope lacks visual properties of its own. The MyWidget +component directly binds to the \c rectangle properties to allow the \c Column +element to create the layout containing the children of the FocusScope. + +So far, the example has the second component statically selected. It is trivial now to extend this component to make it clickable, and add it to the original -application. We still set a one of the widgets as focused by default, but from -then on clicking the either one gives it focus. - -\table -\row -\o \code -Rectangle { - color: "red"; width: 240; height: 55 - MyClickableWidget {} - MyClickableWidget { y: 30; focus: true } -} -\endcode -\o \code -FocusScope { - id: page; width: 240; height: 25 - MyWidget { focus: true } - MouseArea { anchors.fill: parent; onClicked: { page.focus = true } } -} -\endcode -\endtable +application. We still set one of the widgets as focused by default. +Now, clicking either MyClickableWidget gives it focus and the other widget +loses the focus. -\image declarative-qmlfocus3.png +The code that imports and creates two MyClickableWidget instances: +\snippet doc/src/snippets/declarative/focus/clickablewidget.qml clickable window + +The MyClickableWidget code: +\snippet doc/src/snippets/declarative/focus/myclickablewidget.qml clickable in focusscope -When a QML item explicitly relinquishes focus (by setting its -\c {Item::focus} property to false while it has \e {active focus}), the system -does not automatically select another element to receive focus. That is, it -is possible for there to be no currently \e {active focus}. +\image declarative-qmlfocus4.png -See the \l{declarative/keyinteraction/focus}{Keyboard Focus example} for a +When a QML \l Item explicitly relinquishes focus (by setting its +\c focus property to \c false while it has active focus), the +system does not automatically select another element to receive focus. That is, +it is possible for there to be no currently active focus. + +See the \l{declarative/keyinteraction/focus}{Keyboard Focus example} for a demonstration of moving keyboard focus between multiple areas using FocusScope elements. \section1 Advanced uses of Focus Scopes -Focus scopes allow focus to allocation to be easily partitioned. Several +Focus scopes allow focus to allocation to be easily partitioned. Several QML items use it to this effect. -\l ListView, for example, is itself a focus scope. Generally this isn't +\l ListView, for example, is itself a focus scope. Generally this isn't noticeable as \l ListView doesn't usually have manually added visual children. By being a focus scope, \l ListView can focus the current list item without -worrying about how that will effect the rest of the application. This allows -the current item delegate to react to key presses. +worrying about how that will effect the rest of the application. This allows the +current item delegate to react to key presses. -This contrived example shows how this works. Pressing the \c Return key will +This contrived example shows how this works. Pressing the \c Return key will print the name of the current list item. -\table -\row -\o \snippet doc/src/snippets/declarative/focusscopes.qml 0 -\o \image declarative-qmlfocus4.png -\endtable +\snippet doc/src/snippets/declarative/focus/advancedFocus.qml FocusScope delegate + +\image declarative-qmlfocus5.png -While the example is simple, there's a lot going on behind the scenes. Whenever +While the example is simple, there are a lot going on behind the scenes. Whenever the current item changes, the \l ListView sets the delegate's \c {Item::focus} -property. As the \l ListView is a \e {focus scope}, this doesn't effect the -rest of the application. However, if the \l ListView itself has -\e {active focus} this causes the delegate itself to receive \e {active focus}. -In this example, the root element of the delegate is also a \e {focus scope}, -which in turn gives \e {active focus} to the \c {Text} element that -actually performs the work of handling the \e {Return} key. +property. As the \l ListView is a focus scope, this doesn't affect the +rest of the application. However, if the \l ListView itself has +active focus this causes the delegate itself to receive active focus. +In this example, the root element of the delegate is also a focus scope, +which in turn gives active focus to the \c {Text} element that actually performs +the work of handling the \c {Return} key. All of the QML view classes, such as \l PathView and \l GridView, behave in a similar manner to allow key handling in their respective delegates. diff --git a/doc/src/images/declarative-qmlfocus1.png b/doc/src/images/declarative-qmlfocus1.png new file mode 100644 index 0000000..317b34b Binary files /dev/null and b/doc/src/images/declarative-qmlfocus1.png differ diff --git a/doc/src/images/declarative-qmlfocus2.png b/doc/src/images/declarative-qmlfocus2.png new file mode 100644 index 0000000..e3f9643 Binary files /dev/null and b/doc/src/images/declarative-qmlfocus2.png differ diff --git a/doc/src/images/declarative-qmlfocus3.png b/doc/src/images/declarative-qmlfocus3.png new file mode 100644 index 0000000..a5897ce Binary files /dev/null and b/doc/src/images/declarative-qmlfocus3.png differ diff --git a/doc/src/images/declarative-qmlfocus4.png b/doc/src/images/declarative-qmlfocus4.png new file mode 100644 index 0000000..f2e64cd Binary files /dev/null and b/doc/src/images/declarative-qmlfocus4.png differ diff --git a/doc/src/images/declarative-qmlfocus5.png b/doc/src/images/declarative-qmlfocus5.png new file mode 100644 index 0000000..ec7307b Binary files /dev/null and b/doc/src/images/declarative-qmlfocus5.png differ diff --git a/doc/src/snippets/declarative/focus/advancedFocus.qml b/doc/src/snippets/declarative/focus/advancedFocus.qml new file mode 100644 index 0000000..274f54f --- /dev/null +++ b/doc/src/snippets/declarative/focus/advancedFocus.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** 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: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 + +//! [FocusScope delegate] +Rectangle { + color: "lightsteelblue"; width: 100; height: 50 + + ListView { + anchors.fill: parent + focus: true + + model: ListModel { + ListElement { name: "Bob" } + ListElement { name: "John" } + ListElement { name: "Michael" } + } + + delegate: FocusScope { + width: childrenRect.width; height: childrenRect.height + x:childrenRect.x; y: childrenRect.y + TextInput { + focus: true + text: name + Keys.onReturnPressed: console.log(name) + } + } + } +} +//! [FocusScope delegate] diff --git a/doc/src/snippets/declarative/focus/basicwidget.qml b/doc/src/snippets/declarative/focus/basicwidget.qml new file mode 100644 index 0000000..71e75ff --- /dev/null +++ b/doc/src/snippets/declarative/focus/basicwidget.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** 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: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 + +//! [focus true] +Rectangle { + color: "lightsteelblue"; width: 240; height: 25 + Text { id: myText } + Item { + id: keyHandler + focus: true + Keys.onPressed: { + if (event.key == Qt.Key_A) + myText.text = 'Key A was pressed' + else if (event.key == Qt.Key_B) + myText.text = 'Key B was pressed' + else if (event.key == Qt.Key_C) + myText.text = 'Key C was pressed' + } + } +} +//! [focus true] diff --git a/doc/src/snippets/declarative/focus/clickablewidget.qml b/doc/src/snippets/declarative/focus/clickablewidget.qml new file mode 100644 index 0000000..34b0d87 --- /dev/null +++ b/doc/src/snippets/declarative/focus/clickablewidget.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 FOO module 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 + +//! [clickable window] +Rectangle { + id: window + + color: "white"; width: 240; height: 150 + + Column { + anchors.centerIn: parent; spacing: 15 + + MyClickableWidget { + focus: true //set this MyWidget to receive the focus + color: "lightblue" + } + MyClickableWidget { + color: "palegreen" + } + } + +} +//! [clickable window] diff --git a/doc/src/snippets/declarative/focus/focusColumn.qml b/doc/src/snippets/declarative/focus/focusColumn.qml new file mode 100644 index 0000000..eb59309 --- /dev/null +++ b/doc/src/snippets/declarative/focus/focusColumn.qml @@ -0,0 +1,25 @@ +import QtQuick 1.0 + +Rectangle { + width: 200; height: 200 + + // Column { + FocusScope { + x: rect1.x; y:rect1.y; width: rect1.width; height: rect1.height + Rectangle {id: rect1; width: 50; height: 50; focus:true + color: focus ? "red":"blue" + } + Rectangle {id: rect2; width: 50; height: 50; focus:true + color: focus ? "red":"blue" + y: 75 + } +// } +/* + FocusScope { + x: rect2.x; y:rect2.y; width: rect2.width; height: rect2.height + Rectangle {id: rect2; width: 50; height: 50; color: "red"} + } +*/ + } + +} diff --git a/doc/src/snippets/declarative/focus/focusscopewidget.qml b/doc/src/snippets/declarative/focus/focusscopewidget.qml new file mode 100644 index 0000000..48e5750 --- /dev/null +++ b/doc/src/snippets/declarative/focus/focusscopewidget.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 FOO module 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 + +//! [focusscope window] +Rectangle { + id: window + + color: "white"; width: 240; height: 150 + + Column { + anchors.centerIn: parent; spacing: 15 + + MyFocusScopeWidget { + focus: true //set this MyWidget to receive the focus + color: "lightblue" + } + MyFocusScopeWidget { + color: "palegreen" + } + } + +} +//! [focusscope window] diff --git a/doc/src/snippets/declarative/focus/myclickablewidget.qml b/doc/src/snippets/declarative/focus/myclickablewidget.qml new file mode 100644 index 0000000..3294662 --- /dev/null +++ b/doc/src/snippets/declarative/focus/myclickablewidget.qml @@ -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 FOO module 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 + +//! [clickable in focusscope] +FocusScope { + + id: scope + + //FocusScope needs to bind to visual properties of the children + property alias color: rectangle.color + x: rectangle.x; y: rectangle.y + width: rectangle.width; height: rectangle.height + + Rectangle { + id: rectangle + anchors.centerIn: parent + color: "lightsteelblue"; width: 175; height: 25; radius: 10; smooth: true + Text { id: label; anchors.centerIn: parent } + focus: true + Keys.onPressed: { + if (event.key == Qt.Key_A) + label.text = 'Key A was pressed' + else if (event.key == Qt.Key_B) + label.text = 'Key B was pressed' + else if (event.key == Qt.Key_C) + label.text = 'Key C was pressed' + } + } + MouseArea { anchors.fill: parent; onClicked: { scope.focus = true } } +} +//! [clickable in focusscope] diff --git a/doc/src/snippets/declarative/focus/myfocusscopewidget.qml b/doc/src/snippets/declarative/focus/myfocusscopewidget.qml new file mode 100644 index 0000000..231ae3a --- /dev/null +++ b/doc/src/snippets/declarative/focus/myfocusscopewidget.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** 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: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 + +//! [widget in focusscope] +FocusScope { + + //FocusScope needs to bind to visual properties of the children + property alias color: rectangle.color + x: rectangle.x; y: rectangle.y + width: rectangle.width; height: rectangle.height + + Rectangle { + id: rectangle + anchors.centerIn: parent + color: "lightsteelblue"; width: 175; height: 25; radius: 10; smooth: true + Text { id: label; anchors.centerIn: parent } + focus: true + Keys.onPressed: { + if (event.key == Qt.Key_A) + label.text = 'Key A was pressed' + else if (event.key == Qt.Key_B) + label.text = 'Key B was pressed' + else if (event.key == Qt.Key_C) + label.text = 'Key C was pressed' + } + } +} +//! [widget in focusscope] diff --git a/doc/src/snippets/declarative/focus/mywidget.qml b/doc/src/snippets/declarative/focus/mywidget.qml new file mode 100644 index 0000000..bea723d --- /dev/null +++ b/doc/src/snippets/declarative/focus/mywidget.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** 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: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 + +//! [mywidget] +//MyWidget code +Rectangle { + id: widget + color: "lightsteelblue"; width: 175; height: 25; radius: 10; smooth: true + Text { id: label; anchors.centerIn: parent} + focus: true + Keys.onPressed: { + if (event.key == Qt.Key_A) + label.text = 'Key A was pressed' + else if (event.key == Qt.Key_B) + label.text = 'Key B was pressed' + else if (event.key == Qt.Key_C) + label.text = 'Key C was pressed' + } +} +//! [mywidget] diff --git a/doc/src/snippets/declarative/focus/qmldir b/doc/src/snippets/declarative/focus/qmldir new file mode 100644 index 0000000..d0683b2 --- /dev/null +++ b/doc/src/snippets/declarative/focus/qmldir @@ -0,0 +1,4 @@ +MyWidget 1.0 mywidget.qml +MyFocusScopeWidget 1.0 myfocusscopewidget.qml +MyClickableWidget 1.0 myclickablewidget.qml + diff --git a/doc/src/snippets/declarative/focus/rectangle.qml b/doc/src/snippets/declarative/focus/rectangle.qml new file mode 100644 index 0000000..01d1f0c --- /dev/null +++ b/doc/src/snippets/declarative/focus/rectangle.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** 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: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 + +//! [simple key event] +Rectangle { + width: 100; height: 100 + focus: true + Keys.onPressed: { + if (event.key == Qt.Key_A) { + console.log('Key A was pressed'); + event.accepted = true; + } + } +//! [simple key event] + +//! [active focus] + Text { + text: activeFocus ? "I have active focus!" : "I do not have active focus" + } +//! [active focus] + +//! [simple key event end] +} +//! [simple key event end] diff --git a/doc/src/snippets/declarative/focus/widget.qml b/doc/src/snippets/declarative/focus/widget.qml new file mode 100644 index 0000000..cef34c5 --- /dev/null +++ b/doc/src/snippets/declarative/focus/widget.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 FOO module 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 + +//! [window] + +//Window code that imports MyWidget +Rectangle { + id: window + color: "white"; width: 240; height: 150 + + Column { + anchors.centerIn: parent; spacing: 15 + + MyWidget { + focus: true //set this MyWidget to receive the focus + color: "lightblue" + } + MyWidget { + color: "palegreen" + } + } +} +//! [window] -- 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 146ea109f9980beda939088687b37549f4d7a125 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 7 Dec 2010 17:04:29 +0100 Subject: Doc: Added a missing external page reference. --- doc/src/external-resources.qdoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/src/external-resources.qdoc b/doc/src/external-resources.qdoc index 8eeaeb1..9bc3b1c 100644 --- a/doc/src/external-resources.qdoc +++ b/doc/src/external-resources.qdoc @@ -448,3 +448,8 @@ \externalpage https://developer.mozilla.org/en/JavaScript/About_JavaScript \title About JavaScript */ + +/*! + \externalpage http://www.libusb.org/ + \title libusb +*/ -- cgit v0.12 From 2c55c106839a4ba1a9d9c1d3f6f6cf7e835ccc1d Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 7 Dec 2010 17:29:04 +0100 Subject: Doc: Added documentation about the use of null custom title bar widgets. Task-number: QTBUG-15516 --- src/gui/widgets/qdockwidget.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp index df9b171..0a6269d 100644 --- a/src/gui/widgets/qdockwidget.cpp +++ b/src/gui/widgets/qdockwidget.cpp @@ -1531,8 +1531,11 @@ QAction * QDockWidget::toggleViewAction() const /*! \since 4.3 + Sets an arbitrary \a widget as the dock widget's title bar. If \a widget - is 0, the title bar widget is removed, but not deleted. + is 0, any custom title bar widget previously set on the dock widget is + removed, but not deleted, and the default title bar will be used + instead. If a title bar widget is set, QDockWidget will not use native window decorations when it is floated. @@ -1540,23 +1543,27 @@ QAction * QDockWidget::toggleViewAction() const Here are some tips for implementing custom title bars: \list - \i Mouse events that are not explicitly handled by the title bar widget + \o Mouse events that are not explicitly handled by the title bar widget must be ignored by calling QMouseEvent::ignore(). These events then propagate to the QDockWidget parent, which handles them in the usual manner, moving when the title bar is dragged, docking and undocking when it is double-clicked, etc. - \i When DockWidgetVerticalTitleBar is set on QDockWidget, the title + \o When DockWidgetVerticalTitleBar is set on QDockWidget, the title bar widget is repositioned accordingly. In resizeEvent(), the title bar should check what orientation it should assume: \snippet doc/src/snippets/code/src_gui_widgets_qdockwidget.cpp 0 - \i The title bar widget must have a valid QWidget::sizeHint() and + \o The title bar widget must have a valid QWidget::sizeHint() and QWidget::minimumSizeHint(). These functions should take into account the current orientation of the title bar. + + \o It is not possible to remove a title bar from a dock widget. However, + a similar effect can be achieved by setting a default constructed + QWidget as the title bar widget. \endlist - Using qobject_cast as shown above, the title bar widget has full access + Using qobject_cast() as shown above, the title bar widget has full access to its parent QDockWidget. Hence it can perform such operations as docking and hiding in response to user actions. -- cgit v0.12 From aa4b28cbe52eedfe898da04958339509b1d173bc Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 7 Dec 2010 17:36:01 +0100 Subject: Doc: Fixed a link to the correct searchPaths() function. --- src/corelib/io/qresource.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index ce9c57e..b45710c 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -187,7 +187,7 @@ Q_GLOBAL_STATIC(QStringList, resourceSearchPaths) A QResource can either be loaded with an absolute path, either treated as a file system rooted with a \c{/} character, or in resource notation rooted with a \c{:} character. A relative resource can also be opened - which will be found through the searchPaths(). + which will be found in the list of paths returned by QDir::searchPaths(). A QResource that is representing a file will have data backing it, this data can possibly be compressed, in which case qUncompress() must be -- cgit v0.12 From 4483325532f57157f9ce6953670f9ab175dbaf2a Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 7 Dec 2010 17:36:40 +0100 Subject: Doc: Removed duplicate external page reference. --- doc/src/qt-webpages.qdoc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/doc/src/qt-webpages.qdoc b/doc/src/qt-webpages.qdoc index b7b9fba..0a03157 100644 --- a/doc/src/qt-webpages.qdoc +++ b/doc/src/qt-webpages.qdoc @@ -201,11 +201,6 @@ */ /*! - \externalpage http://labs.qt.nokia.com/gitweb?p=qtestlib-tools;a=summary - \title qtestlib-tools -*/ - -/*! \externalpage http://qt.nokia.com/products/library/modular-class-library#info_scripting \title Qt Script for Applications (QSA) */ -- cgit v0.12 From 68a21753acd3e4159025bc73b0a31e652340e039 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 7 Dec 2010 17:37:12 +0100 Subject: Doc: Added a link to the QML Basic Types page. --- doc/src/declarative/declarativeui.qdoc | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index 5d9eaaf..3d963e2 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -136,6 +136,7 @@ Module. \list \o \l{QML Elements} +\o \l{QML Basic Types} \o \l{QML Global Object} \o \l{QML Internationalization} \o \l{QML Security} -- cgit v0.12 From 30272ee4f7b37a75bd9b56aa5eb763073a6c965a Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 7 Dec 2010 17:47:32 +0100 Subject: Doc: Fixed incorrect case in a page file name. --- doc/src/getting-started/installation.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/getting-started/installation.qdoc b/doc/src/getting-started/installation.qdoc index a68310c..aa10aaf 100644 --- a/doc/src/getting-started/installation.qdoc +++ b/doc/src/getting-started/installation.qdoc @@ -684,7 +684,7 @@ Binary Package} document. We hope you will enjoy using Qt. */ -/*! \page install-Symbian-linux.html +/*! \page install-symbian-linux.html \title Installing Qt for the Symbian platform using Linux (experimental) \ingroup installation \ingroup qtsymbian -- cgit v0.12 From 90928a986d8f37cf394d45cbcf12aaeeaa62d565 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 7 Dec 2010 17:48:11 +0100 Subject: Doc: Added missing What's New information for Qt 4.6 and 4.7. Task-number: QTBUG-15670 --- doc/src/network-programming/bearermanagement.qdoc | 8 +-- doc/src/qt4-intro.qdoc | 62 ++++++++++++++++++++--- 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/doc/src/network-programming/bearermanagement.qdoc b/doc/src/network-programming/bearermanagement.qdoc index 98de5bf..12da55b 100644 --- a/doc/src/network-programming/bearermanagement.qdoc +++ b/doc/src/network-programming/bearermanagement.qdoc @@ -26,11 +26,11 @@ ****************************************************************************/ /*! - \page bearer-management.html +\page bearer-management.html - \title Bearer Management - \ingroup qt-network - \brief An API to control the system's connectivity state. +\title Bearer Management +\ingroup qt-network +\brief An API to control the system's connectivity state. Bearer Management controls the connectivity state of the system so that the user can start or stop interfaces or roam transparently between diff --git a/doc/src/qt4-intro.qdoc b/doc/src/qt4-intro.qdoc index 62decbb..7325e27 100644 --- a/doc/src/qt4-intro.qdoc +++ b/doc/src/qt4-intro.qdoc @@ -60,7 +60,53 @@ \section1 Recent Additions to Qt 4 - The following features have been added to Qt since the first release of Qt 4: + The following features have been added to Qt since the first release of Qt 4. + + In Qt 4.7: + \list + \o Declarative UI Development with \l{Qt Quick}, technologies for creating + fluid, dynamic user interfaces. + \o Support for \l{Bearer Management}{network bearer management}, enabling + features such as control over network interfaces and support for roaming + between networks. + \o Feature and performance improvements in QtWebKit, including a new tiled + backing store, control over scroll bars used in frames and framesets, + accelerated compositing and \l{The QtWebKit Bridge}{support for hybrid + development}. + \o General performance improvements, including the use of "alien widgets" + on Mac OS X, the QStaticText class for optimized text rendering, a new + \l{QPainter::drawPixmapFragments()}{API for rendering pixmap fragments} + and an updated version of the JavaScriptCore engine for the QtScript + module with improved performance. + \endlist + + In Qt 4.6: + \list + \o Support for \l{The Symbian platform - Introduction to Qt}{the Symbian Platform} + as a mainstream Qt platform, with integration into the S60 framework. + \o The \l{The Animation Framework}{animation framework} allows animations to be + created using both widgets and graphics items. + \o The \l{The State Machine Framework}{state machine framework} provides a robust + state chart implementation based on Harel statecharts and SCXML. + \o Support for \l{QTouchEvent}{touch input} and \l{Gestures Programming}{gestures} + enable developers to create intuitive user interfaces for touch-based devices. + \o A \l{QWebElement}{DOM access API} for QtWebKit provides a cleaner and safer way + to access elements and structures of Web pages without the use of JavaScript. + \o A collection of performance improvements, covering QGraphicsView, QPixmapCache, + QNetworkAccessManager, QContiguousCache class, hardware-accelerated rendering + support through \l{OpenVG Rendering in Qt}{OpenVG}, and the removal of Win9x + support. + \o A collection of \l{QGraphicsEffect}{graphics effects} make it easy to apply + and simple effects to graphics items and combine them to produce more complex + effects. + \o Support for XML schema validation in the QtXmlPatterns module covering + large parts of version 1.0 of the specification. + \o Qt3D enablers, including math primitives for \l{QMatrix4x4}{matrix multiplication}, + \l{QVector3D}{vectors}, \l{QQuaternion}{quaternions} (client-side), and an API + for \l{QGLShader}{vertex and fragment shaders}, GLSL/ES. + \o \l{QtMultimedia Module}{Multimedia services} providing low-level access to the + system's audio system. + \endlist In Qt 4.5: \list @@ -209,7 +255,7 @@ \row \o \l{Qt3Support} \o Qt 3 support classes \row \o \l{QAxContainer} \o ActiveQt client extension \row \o \l{QAxServer} \o ActiveQt server extension - \row \o \l{QtHelp} \o Classes for integrating online documentation + \row \o \l{QtHelp} \o Classes for integrating online documentation \row \o \l{QtDesigner} \o Classes for extending and embedding Qt Designer \row \o \l{QtUiTools} \o Classes for dynamic GUI generation \row \o \l{QtTest} \o Tool classes for unit testing @@ -451,7 +497,7 @@ A list of other Qt 4 features can be found on the \bold{\l{What's New in Qt 4}} page. - \section1 Declarative UI development with Qt Quick + \section1 Declarative UI Development with Qt Quick \image quick_screens.png @@ -508,7 +554,7 @@ For hybrid QtWebKit and C++ projects, Qt 4.7 has added support for transporting \l{QPixmap}s between Qt C++ and WebKit. We have also - improved the documentation hybrid development. Read more here: + improved the documentation for hybrid development. Read more here: \l{The QtWebKit Bridge}. \section1 QtWebKit Performance Benchmarks @@ -680,7 +726,7 @@ See the QTouchEvent class documentation for more information on touch input and QGestureEvent for gestures. - \section1 DOM access API + \section1 DOM Access API Web pages and XML both have very complex document object models. The W3C selector API provides a very simple way to access and @@ -699,7 +745,7 @@ \list \o Rewritten the QGraphicsView rendering algorithm. - \o Made QPixmapCache support efficient Key datastructure. + \o Made QPixmapCache support efficient Key data structure. \o Reduced overhead in QNetworkAccessManager. \o Added the QContiguousCache class, which provides efficient caching of contiguous data. @@ -740,7 +786,7 @@ See the \l{XML Processing} and QXmlSchema class documentation for more information. - \section1 Qt3D enablers + \section1 Qt3D Enablers As more of Qt, and more of the applications built on Qt go 3D, API's should be provided to simplify this. Mainly, the new API @@ -750,7 +796,7 @@ The main features of the Qt3D enablers are currently: Math primitives for matrix multiplication, vectors, quaternions - (client-side), and API for vertex and fragment shaders, GLSL/ES. + (client-side), and an API for vertex and fragment shaders, GLSL/ES. Future research will, among other things include stencils, scissors, vertex buffers and arrays, texture manipulation, and geometry shaders. -- 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 d21eee4fb39ee8378bb87187cec5e46275dc31ed Mon Sep 17 00:00:00 2001 From: aavit Date: Wed, 8 Dec 2010 15:35:54 +0100 Subject: Make protocol less lancelot-specific, prepare use in other testcases --- tests/arthur/baselineserver/src/baselineserver.cpp | 30 +++++----- tests/arthur/baselineserver/src/htmlpage.cpp | 15 +++-- tests/arthur/common/baselineprotocol.cpp | 28 +++++----- tests/arthur/common/baselineprotocol.h | 31 ++++------- tests/auto/lancelot/tst_lancelot.cpp | 65 +++++++++++----------- 5 files changed, 81 insertions(+), 88 deletions(-) diff --git a/tests/arthur/baselineserver/src/baselineserver.cpp b/tests/arthur/baselineserver/src/baselineserver.cpp index 53e40b6..90eb594 100644 --- a/tests/arthur/baselineserver/src/baselineserver.cpp +++ b/tests/arthur/baselineserver/src/baselineserver.cpp @@ -208,8 +208,8 @@ void BaselineHandler::provideBaselineChecksums(const QByteArray &itemListBlock) ImageItemList itemList; QDataStream ds(itemListBlock); ds >> itemList; - qDebug() << runId << logtime() << "Received request for checksums for" << itemList.count() << "items, engine" - << itemList.at(0).engineAsString() << "pixel format" << itemList.at(0).formatAsString(); + qDebug() << runId << logtime() << "Received request for checksums for" << itemList.count() + << "items in test function" << itemList.at(0).testFunction; for (ImageItemList::iterator i = itemList.begin(); i != itemList.end(); ++i) { i->imageChecksums.clear(); @@ -232,10 +232,10 @@ void BaselineHandler::provideBaselineChecksums(const QByteArray &itemListBlock) if (file.open(QIODevice::ReadOnly)) { QTextStream in(&file); do { - QString scriptName = in.readLine(); - if (!scriptName.isNull()) { + QString itemName = in.readLine(); + if (!itemName.isNull()) { for (ImageItemList::iterator i = itemList.begin(); i != itemList.end(); ++i) { - if (i->scriptName == scriptName) + if (i->itemName == itemName) i->status = ImageItem::IgnoreItem; } } @@ -258,7 +258,7 @@ void BaselineHandler::storeImage(const QByteArray &itemBlock, bool isBaseline) ds >> item; QString prefix = pathForItem(item, isBaseline); - qDebug() << runId << logtime() << "Received" << (isBaseline ? "baseline" : "mismatched") << "image for:" << item.scriptName << "Storing in" << prefix; + qDebug() << runId << logtime() << "Received" << (isBaseline ? "baseline" : "mismatched") << "image for:" << item.itemName << "Storing in" << prefix; QString dir = prefix.section(QLC('/'), 0, -2); QDir cwd; @@ -333,17 +333,17 @@ QString BaselineHandler::pathForItem(const ImageItem &item, bool isBaseline, boo if (mapped.isEmpty()) mapPlatformInfo(); - QString itemName = item.scriptName; - if (itemName.contains(QLC('.'))) - itemName.replace(itemName.lastIndexOf(QLC('.')), 1, QLC('_')); + QString itemName = item.itemName; + itemName.replace(QLC('.'), QLC('_')); itemName.append(QLC('_')); - itemName.append(QString::number(item.scriptChecksum, 16).rightJustified(4, QLC('0'))); + itemName.append(QString::number(item.itemChecksum, 16).rightJustified(4, QLC('0'))); QStringList path; if (absolute) path += BaselineServer::storagePath(); + path += mapped.value(PI_TestCase); path += QLS(isBaseline ? "baselines" : "mismatches"); - path += item.engineAsString() + QLC('_') + item.formatAsString(); + path += item.testFunction; path += mapped.value(PI_QtVersion); path += mapped.value(PI_QMakeSpec); path += mapped.value(PI_HostName); @@ -397,6 +397,7 @@ QString BaselineHandler::updateSingleBaseline(const QString &oldBaseline, const return res; } + QString BaselineHandler::blacklistTest(const QString &context, const QString &itemId, bool removeFromBlacklist) { QFile file(BaselineServer::storagePath() + QLC('/') + context + QLS("/BLACKLIST")); @@ -439,11 +440,10 @@ void BaselineHandler::testPathMapping() << QLS("localhost"); ImageItem item; - item.scriptName = QLS("arcs.qps"); - item.engine = ImageItem::Raster; - item.renderFormat = QImage::Format_ARGB32_Premultiplied; + item.testFunction = QLS("testPathMapping"); + item.itemName = QLS("arcs.qps"); item.imageChecksums << 0x0123456789abcdefULL; - item.scriptChecksum = 0x0123; + item.itemChecksum = 0x0123; plat.insert(PI_QtVersion, QLS("4.8.0")); plat.insert(PI_BuildKey, QLS("(nobuildkey)")); diff --git a/tests/arthur/baselineserver/src/htmlpage.cpp b/tests/arthur/baselineserver/src/htmlpage.cpp index 11c2eac..2b16d25 100644 --- a/tests/arthur/baselineserver/src/htmlpage.cpp +++ b/tests/arthur/baselineserver/src/htmlpage.cpp @@ -69,7 +69,7 @@ void HTMLPage::start(const QString &storagepath, const QString &runId, const Pla ctx = context; root = storagepath + QLC('/'); imageItems = itemList; - reportDir = pinfo.value(PI_PulseGitBranch).isEmpty() ? QLS("reports/adhoc/") : QLS("reports/pulse/"); + reportDir = pinfo.value(PI_TestCase) + QLC('/') + (pinfo.value(PI_PulseGitBranch).isEmpty() ? QLS("reports/adhoc/") : QLS("reports/pulse/")); QString dir = root + reportDir; QDir cwd; if (!cwd.exists(dir)) @@ -79,8 +79,7 @@ void HTMLPage::start(const QString &storagepath, const QString &runId, const Pla void HTMLPage::writeHeader(const ImageItem &item) { - path = reportDir + id + QLC('_') + item.engineAsString() - + QLC('_') + item.formatAsString() + QLS(".html"); + path = reportDir + id + QLC('_') + item.testFunction + QLS(".html"); QString pageUrl = BaselineServer::baseUrl() + path; @@ -126,7 +125,7 @@ void HTMLPage::addItem(const QString &baseline, const QString &rendered, const I QString pageUrl = BaselineServer::baseUrl() + path; out << "\n"; - out << "" << item.scriptName << "\n"; + out << "" << item.itemName << "\n"; QStringList images = QStringList() << baseline << rendered << compared; foreach(const QString& img, images) out << "\n"; @@ -135,7 +134,7 @@ void HTMLPage::addItem(const QString &baseline, const QString &rendered, const I << "

Replace baseline with rendered

\n" << "

Blacklist this item

\n" + << "&itemId=" << item.itemName << "&url=" << pageUrl << "\">Blacklist this item

\n" << "

View

\n" << "\n"; @@ -144,7 +143,7 @@ void HTMLPage::addItem(const QString &baseline, const QString &rendered, const I QMutableVectorIterator it(imageItems); while (it.hasNext()) { it.next(); - if (it.value().scriptName == item.scriptName) { + if (it.value().itemName == item.itemName) { it.remove(); break; } @@ -158,11 +157,11 @@ void HTMLPage::end() // Add the names of the scripts that passed the test, or were blacklisted QString pageUrl = BaselineServer::baseUrl() + path; for (int i=0; i" << imageItems.at(i).scriptName << "N/AN/AN/A"; + out << "" << imageItems.at(i).itemName << "N/AN/AN/A"; if (imageItems.at(i).status == ImageItem::IgnoreItem) { out << "Blacklisted " << "Whitelist item"; } else { out << "Test passed"; diff --git a/tests/arthur/common/baselineprotocol.cpp b/tests/arthur/common/baselineprotocol.cpp index 5ed58b4..c7e9e72 100644 --- a/tests/arthur/common/baselineprotocol.cpp +++ b/tests/arthur/common/baselineprotocol.cpp @@ -128,11 +128,10 @@ PlatformInfo::PlatformInfo(bool useLocal) ImageItem &ImageItem::operator=(const ImageItem &other) { - scriptName = other.scriptName; - scriptChecksum = other.scriptChecksum; + testFunction = other.testFunction; + itemName = other.itemName; + itemChecksum = other.itemChecksum; status = other.status; - renderFormat = other.renderFormat; - engine = other.engine; image = other.image; imageChecksums = other.imageChecksums; return *this; @@ -165,6 +164,7 @@ quint64 ImageItem::computeChecksum(const QImage &image) return (quint64(h1) << 32) | h2; } +#if 0 QString ImageItem::engineAsString() const { switch (engine) { @@ -205,6 +205,7 @@ QString ImageItem::formatAsString() const return QLS("UnknownFormat"); return QLS(formatNames[renderFormat]); } +#endif void ImageItem::writeImageToStream(QDataStream &out) const { @@ -249,20 +250,16 @@ void ImageItem::readImageFromStream(QDataStream &in) QDataStream & operator<< (QDataStream &stream, const ImageItem &ii) { - stream << ii.scriptName << ii.scriptChecksum << quint8(ii.status) << quint8(ii.renderFormat) - << quint8(ii.engine) << ii.imageChecksums; + stream << ii.testFunction << ii.itemName << ii.itemChecksum << quint8(ii.status) << ii.imageChecksums; ii.writeImageToStream(stream); return stream; } QDataStream & operator>> (QDataStream &stream, ImageItem &ii) { - quint8 encFormat, encStatus, encEngine; - stream >> ii.scriptName >> ii.scriptChecksum >> encStatus >> encFormat - >> encEngine >> ii.imageChecksums; - ii.renderFormat = QImage::Format(encFormat); + quint8 encStatus; + stream >> ii.testFunction >> ii.itemName >> ii.itemChecksum >> encStatus >> ii.imageChecksums; ii.status = ImageItem::ItemStatus(encStatus); - ii.engine = ImageItem::GraphicsEngine(encEngine); ii.readImageFromStream(stream); return stream; } @@ -275,7 +272,7 @@ BaselineProtocol::~BaselineProtocol() } -bool BaselineProtocol::connect(bool *dryrun) +bool BaselineProtocol::connect(const QString &testCase, bool *dryrun) { errMsg.clear(); QByteArray serverName(qgetenv("QT_LANCELOT_SERVER")); @@ -292,6 +289,7 @@ bool BaselineProtocol::connect(bool *dryrun) } PlatformInfo pi(true); + pi.insert(PI_TestCase, testCase); QByteArray block; QDataStream ds(&block, QIODevice::ReadWrite); ds << pi; @@ -342,11 +340,15 @@ bool BaselineProtocol::acceptConnection(PlatformInfo *pi) } -bool BaselineProtocol::requestBaselineChecksums(ImageItemList *itemList) +bool BaselineProtocol::requestBaselineChecksums(const QString &testFunction, ImageItemList *itemList) { errMsg.clear(); if (!itemList) return false; + + for(ImageItemList::iterator it = itemList->begin(); it != itemList->end(); it++) + it->testFunction = testFunction; + QByteArray block; QDataStream ds(&block, QIODevice::ReadWrite); ds << *itemList; diff --git a/tests/arthur/common/baselineprotocol.h b/tests/arthur/common/baselineprotocol.h index baffb4a..1f4d593 100644 --- a/tests/arthur/common/baselineprotocol.h +++ b/tests/arthur/common/baselineprotocol.h @@ -52,6 +52,7 @@ #define FileFormat "png" +const QString PI_TestCase(QLS("TestCase")); const QString PI_HostName(QLS("HostName")); const QString PI_HostAddress(QLS("HostAddress")); const QString PI_OSName(QLS("OSName")); @@ -73,19 +74,15 @@ struct ImageItem { public: ImageItem() - : status(Ok), renderFormat(QImage::Format_Invalid), engine(Raster), scriptChecksum(0) + : status(Ok), itemChecksum(0) {} ImageItem(const ImageItem &other) { *this = other; } ~ImageItem() {} ImageItem &operator=(const ImageItem &other); - static quint64 computeChecksum(const QImage& image); - QString engineAsString() const; - QString formatAsString() const; - void writeImageToStream(QDataStream &stream) const; - void readImageFromStream(QDataStream &stream); + static quint64 computeChecksum(const QImage& image); enum ItemStatus { Ok = 0, @@ -93,19 +90,15 @@ public: IgnoreItem = 2 }; - enum GraphicsEngine { - Raster = 0, - OpenGL = 1 - }; - - QString scriptName; + QString testFunction; + QString itemName; ItemStatus status; - QImage::Format renderFormat; - GraphicsEngine engine; QImage image; QList imageChecksums; - // tbd: add diffscore - quint16 scriptChecksum; + quint16 itemChecksum; + + void writeImageToStream(QDataStream &stream) const; + void readImageFromStream(QDataStream &stream); }; QDataStream & operator<< (QDataStream &stream, const ImageItem &ii); QDataStream & operator>> (QDataStream &stream, ImageItem& ii); @@ -124,7 +117,7 @@ public: // Important constants here // **************************************************** enum Constant { - ProtocolVersion = 3, + ProtocolVersion = 4, ServerPort = 54129, Timeout = 5000 }; @@ -143,8 +136,8 @@ public: }; // For client: - bool connect(bool *dryrun = 0); - bool requestBaselineChecksums(ImageItemList *itemList); + bool connect(const QString &testCase, bool *dryrun = 0); + bool requestBaselineChecksums(const QString &testFunction, ImageItemList *itemList); bool submitNewBaseline(const ImageItem &item, QByteArray *serverMsg); bool submitMismatch(const ImageItem &item, QByteArray *serverMsg); diff --git a/tests/auto/lancelot/tst_lancelot.cpp b/tests/auto/lancelot/tst_lancelot.cpp index 7c6fe66..d1b093f 100644 --- a/tests/auto/lancelot/tst_lancelot.cpp +++ b/tests/auto/lancelot/tst_lancelot.cpp @@ -66,10 +66,15 @@ public: static bool simfail; private: - ImageItem render(const ImageItem &item); + enum GraphicsEngine { + Raster = 0, + OpenGL = 1 + }; + + bool setupTestSuite(const QStringList& blacklist); + void runTestSuite(GraphicsEngine engine, QImage::Format format); + ImageItem render(const ImageItem &item, GraphicsEngine engine, QImage::Format format); void paint(QPaintDevice *device, const QStringList &script, const QString &filePath); - void runTestSuite(); - bool setupTestSuite(ImageItem::GraphicsEngine engine, QImage::Format format, const QStringList& blacklist); BaselineProtocol proto; ImageItemList baseList; @@ -108,7 +113,7 @@ void tst_Lancelot::initTestCase() #if defined(Q_OS_SOMEPLATFORM) QSKIP("This test is not supported on this platform.", SkipAll); #endif - if (!proto.connect(&dryRunMode)) + if (!proto.connect(QLatin1String("tst_Lancelot"), &dryRunMode)) QSKIP(qPrintable(proto.errorMessage()), SkipAll); QDir qpsDir(scriptsDir); @@ -125,8 +130,8 @@ void tst_Lancelot::initTestCase() file.open(QFile::ReadOnly); QByteArray cont = file.readAll(); scripts.insert(fileName, QString::fromLatin1(cont).split(QLatin1Char('\n'), QString::SkipEmptyParts)); - it->scriptName = fileName; - it->scriptChecksum = qChecksum(cont.constData(), cont.size()); + it->itemName = fileName; + it->itemChecksum = qChecksum(cont.constData(), cont.size()); it++; } } @@ -135,42 +140,42 @@ void tst_Lancelot::initTestCase() void tst_Lancelot::testRasterARGB32PM_data() { QStringList localBlacklist; - if (!setupTestSuite(ImageItem::Raster, QImage::Format_ARGB32_Premultiplied, localBlacklist)) + if (!setupTestSuite(localBlacklist)) QSKIP("Communication with baseline image server failed.", SkipAll); } void tst_Lancelot::testRasterARGB32PM() { - runTestSuite(); + runTestSuite(Raster, QImage::Format_ARGB32_Premultiplied); } void tst_Lancelot::testRasterRGB32_data() { QStringList localBlacklist; - if (!setupTestSuite(ImageItem::Raster, QImage::Format_RGB32, localBlacklist)) + if (!setupTestSuite(localBlacklist)) QSKIP("Communication with baseline image server failed.", SkipAll); } void tst_Lancelot::testRasterRGB32() { - runTestSuite(); + runTestSuite(Raster, QImage::Format_RGB32); } void tst_Lancelot::testRasterRGB16_data() { QStringList localBlacklist; - if (!setupTestSuite(ImageItem::Raster, QImage::Format_RGB16, localBlacklist)) + if (!setupTestSuite(localBlacklist)) QSKIP("Communication with baseline image server failed.", SkipAll); } void tst_Lancelot::testRasterRGB16() { - runTestSuite(); + runTestSuite(Raster, QImage::Format_RGB16); } @@ -178,7 +183,7 @@ void tst_Lancelot::testRasterRGB16() void tst_Lancelot::testOpenGL_data() { QStringList localBlacklist = QStringList() << QLatin1String("rasterops.qps"); - if (!setupTestSuite(ImageItem::OpenGL, QImage::Format_RGB32, localBlacklist)) + if (!setupTestSuite(localBlacklist)) QSKIP("Communication with baseline image server failed.", SkipAll); } @@ -197,45 +202,39 @@ void tst_Lancelot::testOpenGL() ok = true; } if (ok) - runTestSuite(); + runTestSuite(OpenGL, QImage::Format_RGB32); else QSKIP("System under test does not meet preconditions for GL testing. Skipping.", SkipAll); } #endif -bool tst_Lancelot::setupTestSuite(ImageItem::GraphicsEngine engine, QImage::Format format, const QStringList& blacklist) +bool tst_Lancelot::setupTestSuite(const QStringList& blacklist) { QTest::addColumn("baseline"); ImageItemList itemList(baseList); - - for(ImageItemList::iterator it = itemList.begin(); it != itemList.end(); it++) { - it->engine = engine; - it->renderFormat = format; - } - - if (!proto.requestBaselineChecksums(&itemList)) { + if (!proto.requestBaselineChecksums(QTest::currentTestFunction(), &itemList)) { QWARN(qPrintable(proto.errorMessage())); return false; } foreach(const ImageItem& item, itemList) { - if (!blacklist.contains(item.scriptName)) - QTest::newRow(item.scriptName.toLatin1()) << item; + if (!blacklist.contains(item.itemName)) + QTest::newRow(item.itemName.toLatin1()) << item; } return true; } -void tst_Lancelot::runTestSuite() +void tst_Lancelot::runTestSuite(GraphicsEngine engine, QImage::Format format) { QFETCH(ImageItem, baseline); if (baseline.status == ImageItem::IgnoreItem) QSKIP("Blacklisted by baseline server.", SkipSingle); - ImageItem rendered = render(baseline); + ImageItem rendered = render(baseline, engine, format); if (rendered.image.isNull()) { // Assume an error in the test environment, not Qt QWARN("Error: Failed to render image."); QSKIP("Aborted due to errors.", SkipSingle); @@ -258,21 +257,21 @@ void tst_Lancelot::runTestSuite() } -ImageItem tst_Lancelot::render(const ImageItem &item) +ImageItem tst_Lancelot::render(const ImageItem &item, GraphicsEngine engine, QImage::Format format) { ImageItem res = item; res.imageChecksums.clear(); res.image = QImage(); - QString filePath = scriptsDir + item.scriptName; - QStringList script = scripts.value(item.scriptName); + QString filePath = scriptsDir + item.itemName; + QStringList script = scripts.value(item.itemName); - if (item.engine == ImageItem::Raster) { - QImage img(800, 800, item.renderFormat); + if (engine == Raster) { + QImage img(800, 800, format); paint(&img, script, QFileInfo(filePath).absoluteFilePath()); // eh yuck (filePath stuff) res.image = img; res.imageChecksums.append(ImageItem::computeChecksum(img)); #ifndef QT_NO_OPENGL - } else if (item.engine == ImageItem::OpenGL) { + } else if (engine == OpenGL) { QGLWidget glWidget; if (glWidget.isValid()) { glWidget.makeCurrent(); @@ -281,7 +280,7 @@ ImageItem tst_Lancelot::render(const ImageItem &item) fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil); QGLFramebufferObject fbo(800, 800, fboFormat); paint(&fbo, script, QFileInfo(filePath).absoluteFilePath()); // eh yuck (filePath stuff) - res.image = fbo.toImage().convertToFormat(item.renderFormat); + res.image = fbo.toImage().convertToFormat(format); res.imageChecksums.append(ImageItem::computeChecksum(res.image)); } #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 c799f87057d1a61112c0165b15ec37bbef39fffe Mon Sep 17 00:00:00 2001 From: Jerome Pasion Date: Wed, 8 Dec 2010 15:48:39 +0100 Subject: Doc: Added link to QML Basic Types in main Qt Quick page. Reviewed-by: David Boddie --- doc/src/declarative/declarativeui.qdoc | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index 5d9eaaf..f8f47c9 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -108,6 +108,7 @@ Module. \section1 Handling Data \list +\o \l{QML Basic Types}{QML Basic Data Types} \o \l{Using QML Positioner and Repeater Items} \o \l{QML Data Models} \o \l{Presenting Data with QML} -- 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 1e84041247505502fa3b3f4865126719321f70d3 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 9 Dec 2010 10:09:30 +0100 Subject: doc: Removed some empty \row commands from a table. --- doc/src/platforms/platform-notes.qdoc | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/src/platforms/platform-notes.qdoc b/doc/src/platforms/platform-notes.qdoc index 9c5f3c8..a7c05e2 100644 --- a/doc/src/platforms/platform-notes.qdoc +++ b/doc/src/platforms/platform-notes.qdoc @@ -81,14 +81,11 @@ \header \o \o Concurrent \o XmlPatterns \o WebKit(*) \o CLucene \o Phonon \row \o g++ 3.3 \o \o \bold{X} \o \o \bold{X} \o \bold{X} \row \o g++ 3.4 and up \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X} - \row \row \o SunCC 5.5 \o \o \o \o \bold{X} \o \bold{X} - \row \row \o aCC series 3 \o \o \o \o \bold{X} \o \bold{X} \row \o aCC series 6 \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X} \row \o xlC 6 \o \o \o \o \bold{X} \o \bold{X} \row \o Intel CC 10 \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X} - \row \row \o MSVC 2003 \o \bold{X} \o \bold{X} \o \o \bold{X} \o \bold{X} \row \o MSVC 2005 and up \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X} \endtable -- 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 bd4ac06eb3c8ac3a9044689481873ce91aeb3180 Mon Sep 17 00:00:00 2001 From: Geir Vattekar Date: Thu, 9 Dec 2010 12:40:10 +0100 Subject: Doc: Fixed doc bug in Diagram Scene example Task-number: QTBUG-15647 --- doc/src/examples/diagramscene.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/examples/diagramscene.qdoc b/doc/src/examples/diagramscene.qdoc index 98bc983..d5cc4e3 100644 --- a/doc/src/examples/diagramscene.qdoc +++ b/doc/src/examples/diagramscene.qdoc @@ -195,7 +195,7 @@ This function returns a QWidget containing a QToolButton with an image of one of the \c DiagramItems, i.e., flowchart shapes. The image is created by the \c DiagramItem through the \c image() - function. The QButtonGroup class lets us attach a QVariant with + function. The QButtonGroup class lets us attach an id (int) with each button; we store the diagram's type, i.e., the DiagramItem::DiagramType enum. We use the stored diagram type when we create new diagram items for the scene. The widgets created -- 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 ad68c845e3e368dc4235e64b54e15a9ee886b078 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Thu, 9 Dec 2010 14:25:16 +0200 Subject: QLabel wraps text at fixed lengths There are multiple problems with text wrapping and dialogs. First, teh CBA height was assumed to be zero, or fetch from previous layout, which caused the dialog to be half under the CBA. Now, CBA height is always asked from AVKON metrics, since asking it from actual component might fail (or produce incorrect results) due to that the component is not created yet (or might still have previous layout active). Additionally, qinputDialog label is now having a size policy to restrict its growing out of dialog borders. Task-number: QT-4354 Reviewed-by: Janne Koskinen --- src/gui/dialogs/qdialog.cpp | 13 ++++++------- src/gui/dialogs/qinputdialog.cpp | 2 ++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp index fbdc522..16ea045 100644 --- a/src/gui/dialogs/qdialog.cpp +++ b/src/gui/dialogs/qdialog.cpp @@ -901,15 +901,13 @@ bool QDialog::symbianAdjustedPosition() QPoint p; const bool doS60Positioning = !(isFullScreen()||isMaximized()); if (doS60Positioning) { + QPoint oldPos = pos(); // naive way to deduce screen orientation if (S60->screenHeightInPixels > S60->screenWidthInPixels) { int cbaHeight; - const CEikButtonGroupContainer* bgContainer = S60->buttonGroupContainer(); - if (!bgContainer) { - cbaHeight = 0; - } else { - cbaHeight = qt_TSize2QSize(bgContainer->Size()).height(); - } + TRect rect; + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EControlPane, rect); + cbaHeight = rect.Height(); p.setY(S60->screenHeightInPixels - height() - cbaHeight); p.setX(0); } else { @@ -939,7 +937,8 @@ bool QDialog::symbianAdjustedPosition() p.setX(qMax(0,S60->screenWidthInPixels - width())); } } - move(p); + if (oldPos != p || p.y() < 0) + move(p); } return doS60Positioning; #else diff --git a/src/gui/dialogs/qinputdialog.cpp b/src/gui/dialogs/qinputdialog.cpp index ce27bd3..a29376a 100644 --- a/src/gui/dialogs/qinputdialog.cpp +++ b/src/gui/dialogs/qinputdialog.cpp @@ -234,6 +234,8 @@ void QInputDialogPrivate::ensureLayout() //we want to let the input dialog grow to available size on Symbian. #ifndef Q_OS_SYMBIAN mainLayout->setSizeConstraint(QLayout::SetMinAndMaxSize); +#else + label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); #endif mainLayout->addWidget(label); mainLayout->addWidget(inputWidget); -- 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 9d8dac4e4509795b6af8a5885f6e9f1a3ccbaa06 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Fri, 10 Dec 2010 11:12:23 +0200 Subject: QDateTimeEdit is not showing correctly when resizes in symbian The problem boils down to using large square area for QDateTime widget (which is more or less a date-aware combobox). Style tries to make the combobox button as wide as it is tall, and as button is as tall as the combobox frame, it steals the whole square widget for itself. To fix this, we now limit the combobox button height to be no more than fourth of the total width of the widget. Thus, in normal, non-resized case, button is, as tall as the frame, but as widget is made larger, button stops to grow after reaching quarter of width of the widget. Task-number: QT-4312 Reviewed-by: Janne Koskinen --- src/gui/styles/qs60style.cpp | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 2f09529..3c715b7 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -104,11 +104,11 @@ const int QS60StylePrivate::m_numberOfLayouts = const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = { // *** generated pixel metrics *** -{5,0,-909,0,0,2,0,0,-1,7,12,22,15,15,7,198,-909,-909,-909,20,13,2,0,0,21,7,18,30,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1,106}, -{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,28,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1,106}, -{7,0,-909,0,0,2,0,0,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,3,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135}, -{7,0,-909,0,0,2,0,0,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,3,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135}, -{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,30,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1,106} +{5,0,-909,0,0,2,0,2,-1,7,12,22,15,15,7,198,-909,-909,-909,20,13,2,0,0,21,7,18,30,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1,106}, +{5,0,-909,0,0,1,0,2,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,28,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1,106}, +{7,0,-909,0,0,2,0,5,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,3,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135}, +{7,0,-909,0,0,2,0,5,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,3,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135}, +{7,0,-909,0,0,2,0,2,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,30,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1,106} // *** End of generated data *** }; @@ -1071,11 +1071,11 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom // Button frame QStyleOptionFrame buttonOption; buttonOption.QStyleOption::operator=(*cmb); - const int maxHeight = cmbxFrame.height(); - const int maxWidth = cmbxFrame.width() - cmbxEditField.width(); + const int maxButtonSide = cmbxFrame.width() - cmbxEditField.width(); + const int newTop = cmbxEditField.center().y() - maxButtonSide / 2; const int topLeftPoint = direction ? - (cmbxEditField.right() + 1) : (cmbxEditField.left() + 1 - maxWidth); - const QRect buttonRect(topLeftPoint, cmbxEditField.top(), maxWidth, maxHeight); + (cmbxEditField.right() + 1) : (cmbxEditField.left() + 1 - maxButtonSide); + const QRect buttonRect(topLeftPoint, newTop, maxButtonSide, maxButtonSide); buttonOption.rect = buttonRect; buttonOption.state = cmb->state; drawPrimitive(PE_PanelButtonCommand, &buttonOption, painter, widget); @@ -2884,30 +2884,24 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple ret = cmb->rect; const int width = cmb->rect.width(); const int height = cmb->rect.height(); - const int buttonIconSize = QS60StylePrivate::pixelMetric(PM_ButtonIconSize); const int buttonMargin = cmb->frame ? 2 : 0; // lets use spinbox frame here as well, as no combobox specific value available. const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0; - const int buttonWidth = qMax(cmb->rect.height(), buttonIconSize); - + const int buttonMinSize = QS60StylePrivate::pixelMetric(PM_ButtonIconSize) + 2 * buttonMargin; QSize buttonSize; - buttonSize.setWidth(buttonWidth + 2 * buttonMargin); - buttonSize.setHeight(qMax(8, (cmb->rect.height() >> 1) - frameThickness)); //buttons should be squares + //allow button to grow to one fourth of the frame height, if the frame is really tall + buttonSize.setHeight(qMin(height, qMax(width / 4, buttonMinSize))); + buttonSize.setWidth(buttonSize.height()); buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); switch (scontrol) { case SC_ComboBoxArrow: { - const int xposMod = cmb->rect.x() + width - buttonMargin - buttonWidth; + const int xposMod = cmb->rect.x() + width - buttonMargin - buttonSize.width(); const int ypos = cmb->rect.y(); - ret.setRect(xposMod, ypos + buttonMargin, buttonWidth, height - 2 * buttonMargin); + ret.setRect(xposMod, ypos + buttonMargin, buttonSize.width(), height - 2 * buttonMargin); } break; case SC_ComboBoxEditField: { - const int withFrameX = cmb->rect.x() + width - frameThickness - buttonSize.width(); - ret = QRect( - frameThickness, - frameThickness, - withFrameX - frameThickness, - height - 2 * frameThickness); + ret = QRect(0, 0, cmb->rect.x() + width - buttonSize.width(), height); } break; case SC_ComboBoxListBoxPopup: { -- cgit v0.12 From f2ab8acd583941dcd673c627ff03d25e519e1f6b Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Fri, 10 Dec 2010 11:34:45 +0200 Subject: Fix whitespace in qs60style.cpp Reviewed-by: TrustMe --- src/gui/styles/qs60style.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 3c715b7..56d2d19 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -2889,7 +2889,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0; const int buttonMinSize = QS60StylePrivate::pixelMetric(PM_ButtonIconSize) + 2 * buttonMargin; QSize buttonSize; - //allow button to grow to one fourth of the frame height, if the frame is really tall + //allow button to grow to one fourth of the frame height, if the frame is really tall buttonSize.setHeight(qMin(height, qMax(width / 4, buttonMinSize))); buttonSize.setWidth(buttonSize.height()); buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); -- 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 14:57:03 +0100 Subject: Doc: Added a note about the Public Suffix List. Added at the request of Peter Hartmann and Legal. --- doc/src/legal/3rdparty.qdoc | 81 ++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 30 deletions(-) diff --git a/doc/src/legal/3rdparty.qdoc b/doc/src/legal/3rdparty.qdoc index 8b3d5f2..9cc83a6 100644 --- a/doc/src/legal/3rdparty.qdoc +++ b/doc/src/legal/3rdparty.qdoc @@ -683,36 +683,57 @@ 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. - + \hr - jquery 1.4.2.js Copyright 2010 John Resig - This software is dual licensed under the MIT or GPL version 2 licenses. - Nokia has used the software herein under the MIT license. - - jquery includes Sizzle.js Copyright 2010 The Dojo Foundaton and is - licensed under the MIT, BSD and GPL licenses. Nokia has used this - software herein under the MIT license. - - The MIT License - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - - + jquery 1.4.2.js Copyright 2010 John Resig + This software is dual licensed under the MIT or GPL version 2 licenses. + Nokia has used the software herein under the MIT license. + + jquery includes Sizzle.js Copyright 2010 The Dojo Foundaton and is + licensed under the MIT, BSD and GPL licenses. Nokia has used this + software herein under the MIT license. + + The MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + + + \section1 The Public Suffix List + + \e{The Public Suffix List is an initiative of the Mozilla Project, but is + maintained as a community resource. It is available for use in any + software, but was originally created to meet the needs of browser + manufacturers. It allows browsers to, for example:} + \list + \o \e{Avoid privacy-damaging "supercookies" being set for high-level + domain name suffixes} + \o \e{Highlight the most important part of a domain name in the user + interface} + \o \e{Accurately sort history entries by site} + \endlist + -- quoted from \l{publicsuffix.org}. + + The public suffix list is used inside Qt to avoid such "supercookies" + mentioned above being set in the cookie jar supported by Qt (by the + QNetworkCookieJar class). + + See \c src/network/access/qnetworkcookiejartlds_p.h.INFO for more + information about how the list is used. */ -- cgit v0.12 From b121ab1e4894ef8e0df5effff3a5e579675f1d40 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen 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 6160f8541e4d7cb66de7680b5fb439fb757c59dd Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Mon, 13 Dec 2010 10:28:42 +0200 Subject: Symbian specific input methods should use 'Text' mode as default case Currently default case is 'lower'. It makes more sense to set the default as 'Text', as it is natural default case for most text entries. Task-number: QTBUG-10311 Reviewed-by: Miikka Heikkinen --- src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 4a1b9b9..5e8a2e1 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -89,7 +89,7 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent) m_fepState->SetFlags(EAknEditorFlagDefault); m_fepState->SetDefaultInputMode( EAknEditorTextInputMode ); m_fepState->SetPermittedInputModes( EAknEditorAllInputModes ); - m_fepState->SetDefaultCase( EAknEditorLowerCase ); + m_fepState->SetDefaultCase( EAknEditorTextCase ); m_fepState->SetPermittedCases( EAknEditorAllCaseModes ); m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG); m_fepState->SetNumericKeymap( EAknEditorStandardNumberModeKeymap ); -- 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 97954165ddeb8a57d8b6349c00fa50019450213b Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 13 Dec 2010 10:31:07 +0100 Subject: doc: Replaced some \raw and \endraw uses with \table and \endtable In DITA XML, there is no straightforward way to translate raw html into DITA XML, because the XML stream writer automagically escapes all the raw html elements. So I am beginning to replace uses of the \raw command with \table, which gets output correctly. The problem is the XML stream writer must see each XML element start and end, because it keeps them on a stack. When you output XML elements with the writeCharacters() function, it escapes the '<' and '>' of any XML elements the character string contains. --- doc/src/widgets-and-layouts/gallery-cde.qdoc | 427 ++++++--------------------- 1 file changed, 91 insertions(+), 336 deletions(-) diff --git a/doc/src/widgets-and-layouts/gallery-cde.qdoc b/doc/src/widgets-and-layouts/gallery-cde.qdoc index c783399..69287b9 100644 --- a/doc/src/widgets-and-layouts/gallery-cde.qdoc +++ b/doc/src/widgets-and-layouts/gallery-cde.qdoc @@ -34,345 +34,100 @@ This page shows some of the widgets available in Qt when configured to use the "cde" style. -\raw HTML -

Buttons

+\section2 Buttons - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage cde-pushbutton.png -\raw HTML - -\endraw -\inlineimage cde-toolbutton.png -\raw HTML -
-\endraw -The QPushButton widget provides a command button. -\raw HTML - -\endraw -\raw HTML -
-\endraw -\inlineimage cde-checkbox.png -\raw HTML - -\endraw -\inlineimage cde-radiobutton.png -\raw HTML -
-\endraw -The QCheckBox widget provides a checkbox with a text label.\raw HTML - -\endraw -The QRadioButton widget provides a radio button with a text or pixmap label.\raw HTML -
-\endraw -\raw HTML -

Containers

+\table 100% +\row +\o \image cde-checkbox.png + \caption The QCheckBox widget provides a checkbox with a text label. +\o \image cde-radiobutton.png + \caption The QRadioButton widget provides a radio button with a text or pixmap label. +\o \image cde-pushbutton.png + \image cde-toolbutton.png + \caption The QPushButton widget provides a command button. +\endtable - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage cde-groupbox.png -\raw HTML - -\endraw -\inlineimage cde-tabwidget.png -\raw HTML -
-\endraw -The QGroupBox widget provides a group box frame with a title.\raw HTML - -\endraw -The QTabWidget class provides a stack of tabbed widgets.\raw HTML -
-\endraw -\inlineimage cde-frame.png -\raw HTML - -\endraw -\inlineimage cde-toolbox.png -\raw HTML -
-\endraw -The QFrame widget provides a simple decorated container for other widgets.\raw HTML - -\endraw -The QToolBox class provides a column of tabbed widget items.\raw HTML -
-\endraw -\raw HTML -

Item Views

+\section2 Containers - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage cde-listview.png -\raw HTML - -\endraw -\inlineimage cde-treeview.png -\raw HTML -
-\endraw -The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.\raw HTML - -\endraw -The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.\raw HTML -
-\endraw -\inlineimage cde-tableview.png -\raw HTML -
-\endraw -The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\raw HTML -
-\endraw -\raw HTML -

Display Widgets

+\table 100% +\row +\o \image cde-groupbox.png + The The QGroupBox widget provides a group box frame with a title. +\o \image cde-tabwidget.png + The QTabWidget class provides a stack of tabbed widgets. +\o \image cde-frame.png + The QFrame widget provides a simple decorated container for other widgets. +\o \image cde-toolbox.png + The QToolBox class provides a column of tabbed widget items. +\endtable - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage cde-progressbar.png -\raw HTML - -\endraw -\inlineimage cde-lcdnumber.png -\raw HTML -
-\endraw -The QProgressBar widget provides a horizontal progress bar.\raw HTML - -\endraw -The QLCDNumber widget displays a number with LCD-like digits.\raw HTML -
-\endraw -\inlineimage cde-label.png -\raw HTML -
-\endraw -The QLabel widget provides a text or image display.\raw HTML -
-\endraw -\raw HTML -

Input Widgets

+\section2 Item Views + +\table 100% +\row +\o \image cde-listview.png + The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view. +\o \image cde-treeview.png + The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view. +\o \image cde-tableview.png + The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o +\o +\endtable + +\section2 Display Widgets + +\table 100% +\row +\o \image cde-progressbar.png + The QProgressBar widget provides a horizontal progress bar. +\o \image cde-label.png + The QLabel widget provides a text or image display. +\o \image cde-lcdnumber.png + The QLCDNumber widget displays a number with LCD-like digits. +\endtable + +\section2 Input Widgets + +\table 100% +\row +\o \image cde-lineedit.png + The QLineEdit widget is a one-line text editor. +\o \image cde-dateedit.png + The QDateEdit class provides a widget for editing dates. +\o \image cde-timeedit.png + The QTimeEdit class provides a widget for editing times. +\o \image cde-datetimeedit.png + The QDateTimeEdit class provides a widget for editing dates and times. +\endtable + +\table 100% +\row +\o \image cde-slider.png + The QSlider widget provides a vertical or horizontal slider. +\o \image cde-combobox.png + The QComboBox widget is a combined button and pop-up list. +\o \image cde-spinbox.png + The QSpinBox class provides a spin box widget. +\endtable + +\table 100% +\row +\o \image cde-fontcombobox.png + The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts. +\o \image cde-doublespinbox.png + The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered. +\o \image cde-horizontalscrollbar.png + The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation. +\endtable + +\table 100% +\row +\o \image cde-dial.png + The QDial class provides a rounded range control (like a speedometer or potentiometer). +\o \image cde-textedit.png + The QTextEdit class provides a widget that is used to edit and display both plain and rich text. +\o \image cde-calendarwidget.png + The QCalendarWidget class provides a monthly calendar widget that can be used to select dates. +\endtable - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage cde-slider.png -\raw HTML - -\endraw -\inlineimage cde-lineedit.png -\raw HTML -
-\endraw -The QSlider widget provides a vertical or horizontal slider.\raw HTML - -\endraw -The QLineEdit widget is a one-line text editor.\raw HTML -
-\endraw -\inlineimage cde-combobox.png -\raw HTML - -\endraw -\inlineimage cde-doublespinbox.png -\raw HTML -
-\endraw -The QComboBox widget is a combined button and pop-up list.\raw HTML - -\endraw -The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.\raw HTML -
-\endraw -\inlineimage cde-spinbox.png -\raw HTML - -\endraw -\inlineimage cde-timeedit.png -\raw HTML -
-\endraw -The QSpinBox class provides a spin box widget.\raw HTML - -\endraw -The QTimeEdit class provides a widget for editing times.\raw HTML -
-\endraw -\inlineimage cde-dateedit.png -\raw HTML - -\endraw -\inlineimage cde-datetimeedit.png -\raw HTML -
-\endraw -The QDateEdit class provides a widget for editing dates.\raw HTML - -\endraw -The QDateTimeEdit class provides a widget for editing dates and times.\raw HTML -
-\endraw -\inlineimage cde-textedit.png -\raw HTML - -\endraw -\inlineimage cde-horizontalscrollbar.png -\raw HTML -
-\endraw -The QTextEdit class provides a widget that is used to edit and - display both plain and rich text.\raw HTML - -\endraw -The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.\raw HTML -
-\endraw -\inlineimage cde-dial.png -\raw HTML - -\endraw -\inlineimage cde-calendarwidget.png -\raw HTML -
-\endraw -The QDial class provides a rounded range control (like a - speedometer or potentiometer).\raw HTML - -\endraw -The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.\raw HTML -
-\endraw -\inlineimage cde-fontcombobox.png -\raw HTML -
-\endraw -The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.\raw HTML -
-\endraw */ -- 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 ad3783ecd1308d357eb0451fe5b4fc24b49ed15a Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 13 Dec 2010 11:42:38 +0100 Subject: doc: Replaced some \raw and \endraw uses with \table and \endtable In DITA XML, there is no straightforward way to translate raw html into DITA XML, because the XML stream writer automagically escapes all the raw html elements. So I am beginning to replace uses of the \raw command with \table, which gets output correctly. The problem is the XML stream writer must see each XML element start and end, because it keeps them on a stack. When you output XML elements with the writeCharacters() function, it escapes the '<' and '>' of any XML elements the character string contains. --- .../widgets-and-layouts/gallery-cleanlooks.qdoc | 432 +++++--------------- doc/src/widgets-and-layouts/gallery-gtk.qdoc | 436 +++++---------------- doc/src/widgets-and-layouts/gallery-macintosh.qdoc | 432 +++++--------------- doc/src/widgets-and-layouts/gallery-motif.qdoc | 432 +++++--------------- doc/src/widgets-and-layouts/gallery-plastique.qdoc | 432 +++++--------------- doc/src/widgets-and-layouts/gallery-windows.qdoc | 432 +++++--------------- .../widgets-and-layouts/gallery-windowsvista.qdoc | 432 +++++--------------- doc/src/widgets-and-layouts/gallery-windowsxp.qdoc | 432 +++++--------------- 8 files changed, 768 insertions(+), 2692 deletions(-) diff --git a/doc/src/widgets-and-layouts/gallery-cleanlooks.qdoc b/doc/src/widgets-and-layouts/gallery-cleanlooks.qdoc index d03adc8..59e2934 100644 --- a/doc/src/widgets-and-layouts/gallery-cleanlooks.qdoc +++ b/doc/src/widgets-and-layouts/gallery-cleanlooks.qdoc @@ -34,345 +34,105 @@ This page shows some of the widgets available in Qt when configured to use the "cleanlooks" style. -\raw HTML -

Buttons

+\section2 Buttons - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage cleanlooks-pushbutton.png -\raw HTML - -\endraw -\inlineimage cleanlooks-toolbutton.png -\raw HTML -
-\endraw -The QPushButton widget provides a command button.\raw HTML - -\endraw -The QToolButton class provides a quick-access button to commands - or options, usually used inside a QToolBar.\raw HTML -
-\endraw -\inlineimage cleanlooks-checkbox.png -\raw HTML - -\endraw -\inlineimage cleanlooks-radiobutton.png -\raw HTML -
-\endraw -The QCheckBox widget provides a checkbox with a text label.\raw HTML - -\endraw -The QRadioButton widget provides a radio button with a text or pixmap label.\raw HTML -
-\endraw -\raw HTML -

Containers

+\table 100% +\row +\o \image cleanlooks-pushbutton.png + \caption The QPushButton widget provides a command button. +\o \image cleanlooks-toolbutton.png + \caption The QToolButton class provides a quick-access button to commands + or options, usually used inside a QToolBar. +\endtable - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage cleanlooks-groupbox.png -\raw HTML - -\endraw -\inlineimage cleanlooks-tabwidget.png -\raw HTML -
-\endraw -The QGroupBox widget provides a group box frame with a title.\raw HTML - -\endraw -The QTabWidget class provides a stack of tabbed widgets.\raw HTML -
-\endraw -\inlineimage cleanlooks-frame.png -\raw HTML - -\endraw -\inlineimage cleanlooks-toolbox.png -\raw HTML -
-\endraw -The QFrame widget provides a simple decorated container for other widgets.\raw HTML - -\endraw -The QToolBox class provides a column of tabbed widget items.\raw HTML -
-\endraw -\raw HTML -

Item Views

+\table 100% +\row +\o \image cleanlooks-checkbox.png + \caption The QCheckBox widget provides a checkbox with a text label. +\o \image cleanlooks-radiobutton.png + \caption The QRadioButton widget provides a radio button with a text or pixmap label. +\endtable - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage cleanlooks-listview.png -\raw HTML - -\endraw -\inlineimage cleanlooks-treeview.png -\raw HTML -
-\endraw -The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.\raw HTML - -\endraw -The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.\raw HTML -
-\endraw -\inlineimage cleanlooks-tableview.png -\raw HTML -
-\endraw -The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\raw HTML -
-\endraw -\raw HTML -

Display Widgets

+\section2 Containers - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage cleanlooks-progressbar.png -\raw HTML - -\endraw -\inlineimage cleanlooks-lcdnumber.png -\raw HTML -
-\endraw -The QProgressBar widget provides a horizontal progress bar.\raw HTML - -\endraw -The QLCDNumber widget displays a number with LCD-like digits.\raw HTML -
-\endraw -\inlineimage cleanlooks-label.png -\raw HTML -
-\endraw -The QLabel widget provides a text or image display.\raw HTML -
-\endraw -\raw HTML -

Input Widgets

+\table 100% +\row +\o \image cleanlooks-groupbox.png + The The QGroupBox widget provides a group box frame with a title. +\o \image cleanlooks-tabwidget.png + The QTabWidget class provides a stack of tabbed widgets. +\o \image cleanlooks-frame.png + The QFrame widget provides a simple decorated container for other widgets. +\o \image cleanlooks-toolbox.png + The QToolBox class provides a column of tabbed widget items. +\endtable - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage cleanlooks-slider.png -\raw HTML - -\endraw -\inlineimage cleanlooks-lineedit.png -\raw HTML -
-\endraw -The QSlider widget provides a vertical or horizontal slider.\raw HTML - -\endraw -The QLineEdit widget is a one-line text editor.\raw HTML -
-\endraw -\inlineimage cleanlooks-combobox.png -\raw HTML - -\endraw -\inlineimage cleanlooks-doublespinbox.png -\raw HTML -
-\endraw -The QComboBox widget is a combined button and pop-up list.\raw HTML - -\endraw -The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.\raw HTML -
-\endraw -\inlineimage cleanlooks-spinbox.png -\raw HTML - -\endraw -\inlineimage cleanlooks-timeedit.png -\raw HTML -
-\endraw -The QSpinBox class provides a spin box widget.\raw HTML - -\endraw -The QTimeEdit class provides a widget for editing times.\raw HTML -
-\endraw -\inlineimage cleanlooks-dateedit.png -\raw HTML - -\endraw -\inlineimage cleanlooks-datetimeedit.png -\raw HTML -
-\endraw -The QDateEdit class provides a widget for editing dates.\raw HTML - -\endraw -The QDateTimeEdit class provides a widget for editing dates and times.\raw HTML -
-\endraw -\inlineimage cleanlooks-textedit.png -\raw HTML - -\endraw -\inlineimage cleanlooks-horizontalscrollbar.png -\raw HTML -
-\endraw -The QTextEdit class provides a widget that is used to edit and - display both plain and rich text.\raw HTML - -\endraw -The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.\raw HTML -
-\endraw -\inlineimage cleanlooks-dial.png -\raw HTML - -\endraw -\inlineimage cleanlooks-calendarwidget.png -\raw HTML -
-\endraw -The QDial class provides a rounded range control (like a - speedometer or potentiometer).\raw HTML - -\endraw -The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.\raw HTML -
-\endraw -\inlineimage cleanlooks-fontcombobox.png -\raw HTML -
-\endraw -The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.\raw HTML -
-\endraw +\section2 Item Views + +\table 100% +\row +\o \image cleanlooks-listview.png + The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view. +\o \image cleanlooks-treeview.png + The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view. +\o \image cleanlooks-tableview.png + The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o +\o +\endtable + +\section2 Display Widgets + +\table 100% +\row +\o \image cleanlooks-progressbar.png + The QProgressBar widget provides a horizontal progress bar. +\o \image cleanlooks-label.png + The QLabel widget provides a text or image display. +\o \image cleanlooks-lcdnumber.png + The QLCDNumber widget displays a number with LCD-like digits. +\endtable + +\section2 Input Widgets + +\table 100% +\row +\o \image cleanlooks-lineedit.png + The QLineEdit widget is a one-line text editor. +\o \image cleanlooks-dateedit.png + The QDateEdit class provides a widget for editing dates. +\o \image cleanlooks-timeedit.png + The QTimeEdit class provides a widget for editing times. +\o \image cleanlooks-datetimeedit.png + The QDateTimeEdit class provides a widget for editing dates and times. +\endtable + +\table 100% +\row +\o \image cleanlooks-slider.png + The QSlider widget provides a vertical or horizontal slider. +\o \image cleanlooks-combobox.png + The QComboBox widget is a combined button and pop-up list. +\o \image cleanlooks-spinbox.png + The QSpinBox class provides a spin box widget. +\endtable + +\table 100% +\row +\o \image cleanlooks-fontcombobox.png + The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts. +\o \image cleanlooks-doublespinbox.png + The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered. +\o \image cleanlooks-horizontalscrollbar.png + The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation. +\endtable + +\table 100% +\row +\o \image cleanlooks-dial.png + The QDial class provides a rounded range control (like a speedometer or potentiometer). +\o \image cleanlooks-textedit.png + The QTextEdit class provides a widget that is used to edit and display both plain and rich text. +\o \image cleanlooks-calendarwidget.png + The QCalendarWidget class provides a monthly calendar widget that can be used to select dates. +\endtable */ diff --git a/doc/src/widgets-and-layouts/gallery-gtk.qdoc b/doc/src/widgets-and-layouts/gallery-gtk.qdoc index b3a6372..b2f8458 100644 --- a/doc/src/widgets-and-layouts/gallery-gtk.qdoc +++ b/doc/src/widgets-and-layouts/gallery-gtk.qdoc @@ -37,349 +37,105 @@ Take a look at the \l{Qt Widget Gallery} to see how Qt applications appear in other styles. -\raw HTML -

Buttons

+\section2 Buttons - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage gtk-pushbutton.png -\raw HTML - -\endraw -\inlineimage gtk-toolbutton.png -\raw HTML -
-\endraw -The QPushButton widget provides a command button.\raw HTML - -\endraw -The QToolButton class provides a quick-access button to commands - or options, usually used inside a QToolBar.\raw HTML -
-\endraw -\inlineimage gtk-checkbox.png -\raw HTML - -\endraw -\inlineimage gtk-radiobutton.png -\raw HTML -
-\endraw -The QCheckBox widget provides a checkbox with a text label.\raw HTML - -\endraw -The QRadioButton widget provides a radio button with a text or pixmap label.\raw HTML -
-\endraw -\raw HTML -

Containers

+\table 100% +\row +\o \image gtk-pushbutton.png + \caption The QPushButton widget provides a command button. +\o \image gtk-toolbutton.png + \caption The QToolButton class provides a quick-access button to commands + or options, usually used inside a QToolBar. +\endtable - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage gtk-groupbox.png -\raw HTML - -\endraw -\inlineimage gtk-tabwidget.png -\raw HTML -
-\endraw -The QGroupBox widget provides a group box frame with a title.\raw HTML - -\endraw -The QTabWidget class provides a stack of tabbed widgets.\raw HTML -
-\endraw -\inlineimage gtk-toolbox.png -\raw HTML - -\endraw -\inlineimage gtk-frame.png -\raw HTML -
-\endraw -The QToolBox class provides a column of tabbed widget items.\raw HTML - -\endraw -The QFrame widget provides a simple decorated container for other widgets.\raw HTML -
-\endraw -\raw HTML -

Item Views

+\table 100% +\row +\o \image gtk-checkbox.png + \caption The QCheckBox widget provides a checkbox with a text label. +\o \image gtk-radiobutton.png + \caption The QRadioButton widget provides a radio button with a text or pixmap label. +\endtable - -- - - - - - - - - - - - - - - - -
-\endraw -\inlineimage gtk-listview.png -\raw HTML - -\endraw -\inlineimage gtk-treeview.png -\raw HTML -
-\endraw -The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.\raw HTML - -\endraw -The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.\raw HTML -
-\endraw -\inlineimage gtk-tableview.png -\raw HTML -
-\endraw -The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\raw HTML - -\endraw -\raw HTML -
-\endraw -\raw HTML -

Display Widgets

+\section2 Containers - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage gtk-progressbar.png -\raw HTML - -\endraw -\inlineimage gtk-lcdnumber.png -\raw HTML -
-\endraw -The QProgressBar widget provides a horizontal progress bar.\raw HTML - -\endraw -The QLCDNumber widget displays a number with LCD-like digits.\raw HTML -
-\endraw -\inlineimage gtk-label.png -\raw HTML -
-\endraw -The QLabel widget provides a text or image display.\raw HTML -
-\endraw -\raw HTML -

Input Widgets

+\table 100% +\row +\o \image gtk-groupbox.png + The The QGroupBox widget provides a group box frame with a title. +\o \image gtk-tabwidget.png + The QTabWidget class provides a stack of tabbed widgets. +\o \image gtk-frame.png + The QFrame widget provides a simple decorated container for other widgets. +\o \image gtk-toolbox.png + The QToolBox class provides a column of tabbed widget items. +\endtable - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage gtk-slider.png -\raw HTML - -\endraw -\inlineimage gtk-lineedit.png -\raw HTML -
-\endraw -The QSlider widget provides a vertical or horizontal slider.\raw HTML - -\endraw -The QLineEdit widget is a one-line text editor.\raw HTML -
-\endraw -\inlineimage gtk-combobox.png -\raw HTML - -\endraw -\inlineimage gtk-doublespinbox.png -\raw HTML -
-\endraw -The QComboBox widget is a combined button and pop-up list.\raw HTML - -\endraw -The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.\raw HTML -
-\endraw -\inlineimage gtk-spinbox.png -\raw HTML - -\endraw -\inlineimage gtk-timeedit.png -\raw HTML -
-\endraw -The QSpinBox class provides a spin box widget.\raw HTML - -\endraw -The QTimeEdit class provides a widget for editing times.\raw HTML -
-\endraw -\inlineimage gtk-dateedit.png -\raw HTML - -\endraw -\inlineimage gtk-datetimeedit.png -\raw HTML -
-\endraw -The QDateEdit class provides a widget for editing dates.\raw HTML - -\endraw -The QDateTimeEdit class provides a widget for editing dates and times.\raw HTML -
-\endraw -\inlineimage gtk-textedit.png -\raw HTML - -\endraw -\inlineimage gtk-horizontalscrollbar.png -\raw HTML -
-\endraw -The QTextEdit class provides a widget that is used to edit and - display both plain and rich text.\raw HTML - -\endraw -The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.\raw HTML -
-\endraw -\inlineimage gtk-dial.png -\raw HTML - -\endraw -\inlineimage gtk-calendarwidget.png -\raw HTML -
-\endraw -The QDial class provides a rounded range control (like a - speedometer or potentiometer).\raw HTML - -\endraw -The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.\raw HTML -
-\endraw -\inlineimage gtk-fontcombobox.png -\raw HTML -
-\endraw -The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.\raw HTML -
-\endraw +\section2 Item Views + +\table 100% +\row +\o \image gtk-listview.png + The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view. +\o \image gtk-treeview.png + The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view. +\o \image gtk-tableview.png + The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o +\o +\endtable + +\section2 Display Widgets + +\table 100% +\row +\o \image gtk-progressbar.png + The QProgressBar widget provides a horizontal progress bar. +\o \image gtk-label.png + The QLabel widget provides a text or image display. +\o \image gtk-lcdnumber.png + The QLCDNumber widget displays a number with LCD-like digits. +\endtable + +\section2 Input Widgets + +\table 100% +\row +\o \image gtk-lineedit.png + The QLineEdit widget is a one-line text editor. +\o \image gtk-dateedit.png + The QDateEdit class provides a widget for editing dates. +\o \image gtk-timeedit.png + The QTimeEdit class provides a widget for editing times. +\o \image gtk-datetimeedit.png + The QDateTimeEdit class provides a widget for editing dates and times. +\endtable + +\table 100% +\row +\o \image gtk-slider.png + The QSlider widget provides a vertical or horizontal slider. +\o \image gtk-combobox.png + The QComboBox widget is a combined button and pop-up list. +\o \image gtk-spinbox.png + The QSpinBox class provides a spin box widget. +\endtable + +\table 100% +\row +\o \image gtk-fontcombobox.png + The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts. +\o \image gtk-doublespinbox.png + The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered. +\o \image gtk-horizontalscrollbar.png + The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation. +\endtable + +\table 100% +\row +\o \image gtk-dial.png + The QDial class provides a rounded range control (like a speedometer or potentiometer). +\o \image gtk-textedit.png + The QTextEdit class provides a widget that is used to edit and display both plain and rich text. +\o \image gtk-calendarwidget.png + The QCalendarWidget class provides a monthly calendar widget that can be used to select dates. +\endtable */ diff --git a/doc/src/widgets-and-layouts/gallery-macintosh.qdoc b/doc/src/widgets-and-layouts/gallery-macintosh.qdoc index 30a78ca..44d7eb9 100644 --- a/doc/src/widgets-and-layouts/gallery-macintosh.qdoc +++ b/doc/src/widgets-and-layouts/gallery-macintosh.qdoc @@ -34,345 +34,105 @@ This page shows some of the widgets available in Qt when configured to use the "macintosh" style. -\raw HTML -

Buttons

+\section2 Buttons - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage macintosh-pushbutton.png -\raw HTML - -\endraw -\inlineimage macintosh-toolbutton.png -\raw HTML -
-\endraw -The QPushButton widget provides a command button.\raw HTML - -\endraw -The QToolButton class provides a quick-access button to commands - or options, usually used inside a QToolBar.\raw HTML -
-\endraw -\inlineimage macintosh-checkbox.png -\raw HTML - -\endraw -\inlineimage macintosh-radiobutton.png -\raw HTML -
-\endraw -The QCheckBox widget provides a checkbox with a text label.\raw HTML - -\endraw -The QRadioButton widget provides a radio button with a text or pixmap label.\raw HTML -
-\endraw -\raw HTML -

Containers

+\table 100% +\row +\o \image macintosh-pushbutton.png + \caption The QPushButton widget provides a command button. +\o \image macintosh-toolbutton.png + \caption The QToolButton class provides a quick-access button to commands + or options, usually used inside a QToolBar. +\endtable - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage macintosh-groupbox.png -\raw HTML - -\endraw -\inlineimage macintosh-tabwidget.png -\raw HTML -
-\endraw -The QGroupBox widget provides a group box frame with a title.\raw HTML - -\endraw -The QTabWidget class provides a stack of tabbed widgets.\raw HTML -
-\endraw -\inlineimage macintosh-frame.png -\raw HTML - -\endraw -\inlineimage macintosh-toolbox.png -\raw HTML -
-\endraw -The QFrame widget provides a simple decorated container for other widgets.\raw HTML - -\endraw -The QToolBox class provides a column of tabbed widget items.\raw HTML -
-\endraw -\raw HTML -

Item Views

+\table 100% +\row +\o \image macintosh-checkbox.png + \caption The QCheckBox widget provides a checkbox with a text label. +\o \image macintosh-radiobutton.png + \caption The QRadioButton widget provides a radio button with a text or pixmap label. +\endtable - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage macintosh-listview.png -\raw HTML - -\endraw -\inlineimage macintosh-treeview.png -\raw HTML -
-\endraw -The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.\raw HTML - -\endraw -The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.\raw HTML -
-\endraw -\inlineimage macintosh-tableview.png -\raw HTML -
-\endraw -The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\raw HTML -
-\endraw -\raw HTML -

Display Widgets

+\section2 Containers - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage macintosh-progressbar.png -\raw HTML - -\endraw -\inlineimage macintosh-lcdnumber.png -\raw HTML -
-\endraw -The QProgressBar widget provides a horizontal progress bar.\raw HTML - -\endraw -The QLCDNumber widget displays a number with LCD-like digits.\raw HTML -
-\endraw -\inlineimage macintosh-label.png -\raw HTML -
-\endraw -The QLabel widget provides a text or image display.\raw HTML -
-\endraw -\raw HTML -

Input Widgets

+\table 100% +\row +\o \image macintosh-groupbox.png + The The QGroupBox widget provides a group box frame with a title. +\o \image macintosh-tabwidget.png + The QTabWidget class provides a stack of tabbed widgets. +\o \image macintosh-frame.png + The QFrame widget provides a simple decorated container for other widgets. +\o \image macintosh-toolbox.png + The QToolBox class provides a column of tabbed widget items. +\endtable - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage macintosh-slider.png -\raw HTML - -\endraw -\inlineimage macintosh-lineedit.png -\raw HTML -
-\endraw -The QSlider widget provides a vertical or horizontal slider.\raw HTML - -\endraw -The QLineEdit widget is a one-line text editor.\raw HTML -
-\endraw -\inlineimage macintosh-combobox.png -\raw HTML - -\endraw -\inlineimage macintosh-doublespinbox.png -\raw HTML -
-\endraw -The QComboBox widget is a combined button and pop-up list.\raw HTML - -\endraw -The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.\raw HTML -
-\endraw -\inlineimage macintosh-spinbox.png -\raw HTML - -\endraw -\inlineimage macintosh-timeedit.png -\raw HTML -
-\endraw -The QSpinBox class provides a spin box widget.\raw HTML - -\endraw -The QTimeEdit class provides a widget for editing times.\raw HTML -
-\endraw -\inlineimage macintosh-dateedit.png -\raw HTML - -\endraw -\inlineimage macintosh-datetimeedit.png -\raw HTML -
-\endraw -The QDateEdit class provides a widget for editing dates.\raw HTML - -\endraw -The QDateTimeEdit class provides a widget for editing dates and times.\raw HTML -
-\endraw -\inlineimage macintosh-textedit.png -\raw HTML - -\endraw -\inlineimage macintosh-horizontalscrollbar.png -\raw HTML -
-\endraw -The QTextEdit class provides a widget that is used to edit and - display both plain and rich text.\raw HTML - -\endraw -The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.\raw HTML -
-\endraw -\inlineimage macintosh-dial.png -\raw HTML - -\endraw -\inlineimage macintosh-calendarwidget.png -\raw HTML -
-\endraw -The QDial class provides a rounded range control (like a - speedometer or potentiometer).\raw HTML - -\endraw -The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.\raw HTML -
-\endraw -\inlineimage macintosh-fontcombobox.png -\raw HTML -
-\endraw -The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.\raw HTML -
-\endraw +\section2 Item Views + +\table 100% +\row +\o \image macintosh-listview.png + The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view. +\o \image macintosh-treeview.png + The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view. +\o \image macintosh-tableview.png + The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o +\o +\endtable + +\section2 Display Widgets + +\table 100% +\row +\o \image macintosh-progressbar.png + The QProgressBar widget provides a horizontal progress bar. +\o \image macintosh-label.png + The QLabel widget provides a text or image display. +\o \image macintosh-lcdnumber.png + The QLCDNumber widget displays a number with LCD-like digits. +\endtable + +\section2 Input Widgets + +\table 100% +\row +\o \image macintosh-lineedit.png + The QLineEdit widget is a one-line text editor. +\o \image macintosh-dateedit.png + The QDateEdit class provides a widget for editing dates. +\o \image macintosh-timeedit.png + The QTimeEdit class provides a widget for editing times. +\o \image macintosh-datetimeedit.png + The QDateTimeEdit class provides a widget for editing dates and times. +\endtable + +\table 100% +\row +\o \image macintosh-slider.png + The QSlider widget provides a vertical or horizontal slider. +\o \image macintosh-combobox.png + The QComboBox widget is a combined button and pop-up list. +\o \image macintosh-spinbox.png + The QSpinBox class provides a spin box widget. +\endtable + +\table 100% +\row +\o \image macintosh-fontcombobox.png + The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts. +\o \image macintosh-doublespinbox.png + The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered. +\o \image macintosh-horizontalscrollbar.png + The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation. +\endtable + +\table 100% +\row +\o \image macintosh-dial.png + The QDial class provides a rounded range control (like a speedometer or potentiometer). +\o \image macintosh-textedit.png + The QTextEdit class provides a widget that is used to edit and display both plain and rich text. +\o \image macintosh-calendarwidget.png + The QCalendarWidget class provides a monthly calendar widget that can be used to select dates. +\endtable */ diff --git a/doc/src/widgets-and-layouts/gallery-motif.qdoc b/doc/src/widgets-and-layouts/gallery-motif.qdoc index 861c22a..b9c95c8 100644 --- a/doc/src/widgets-and-layouts/gallery-motif.qdoc +++ b/doc/src/widgets-and-layouts/gallery-motif.qdoc @@ -34,345 +34,105 @@ This page shows some of the widgets available in Qt when configured to use the "motif" style. -\raw HTML -

Buttons

+\section2 Buttons - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage motif-pushbutton.png -\raw HTML - -\endraw -\inlineimage motif-toolbutton.png -\raw HTML -
-\endraw -The QPushButton widget provides a command button.\raw HTML - -\endraw -The QToolButton class provides a quick-access button to commands - or options, usually used inside a QToolBar.\raw HTML -
-\endraw -\inlineimage motif-checkbox.png -\raw HTML - -\endraw -\inlineimage motif-radiobutton.png -\raw HTML -
-\endraw -The QCheckBox widget provides a checkbox with a text label.\raw HTML - -\endraw -The QRadioButton widget provides a radio button with a text or pixmap label.\raw HTML -
-\endraw -\raw HTML -

Containers

+\table 100% +\row +\o \image motif-pushbutton.png + \caption The QPushButton widget provides a command button. +\o \image motif-toolbutton.png + \caption The QToolButton class provides a quick-access button to commands + or options, usually used inside a QToolBar. +\endtable - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage motif-groupbox.png -\raw HTML - -\endraw -\inlineimage motif-tabwidget.png -\raw HTML -
-\endraw -The QGroupBox widget provides a group box frame with a title.\raw HTML - -\endraw -The QTabWidget class provides a stack of tabbed widgets.\raw HTML -
-\endraw -\inlineimage motif-frame.png -\raw HTML - -\endraw -\inlineimage motif-toolbox.png -\raw HTML -
-\endraw -The QFrame widget provides a simple decorated container for other widgets.\raw HTML - -\endraw -The QToolBox class provides a column of tabbed widget items.\raw HTML -
-\endraw -\raw HTML -

Item Views

+\table 100% +\row +\o \image motif-checkbox.png + \caption The QCheckBox widget provides a checkbox with a text label. +\o \image motif-radiobutton.png + \caption The QRadioButton widget provides a radio button with a text or pixmap label. +\endtable - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage motif-listview.png -\raw HTML - -\endraw -\inlineimage motif-treeview.png -\raw HTML -
-\endraw -The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.\raw HTML - -\endraw -The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.\raw HTML -
-\endraw -\inlineimage motif-tableview.png -\raw HTML -
-\endraw -The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\raw HTML -
-\endraw -\raw HTML -

Display Widgets

+\section2 Containers - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage motif-progressbar.png -\raw HTML - -\endraw -\inlineimage motif-lcdnumber.png -\raw HTML -
-\endraw -The QProgressBar widget provides a horizontal progress bar.\raw HTML - -\endraw -The QLCDNumber widget displays a number with LCD-like digits.\raw HTML -
-\endraw -\inlineimage motif-label.png -\raw HTML -
-\endraw -The QLabel widget provides a text or image display.\raw HTML -
-\endraw -\raw HTML -

Input Widgets

+\table 100% +\row +\o \image motif-groupbox.png + The The QGroupBox widget provides a group box frame with a title. +\o \image motif-tabwidget.png + The QTabWidget class provides a stack of tabbed widgets. +\o \image motif-frame.png + The QFrame widget provides a simple decorated container for other widgets. +\o \image motif-toolbox.png + The QToolBox class provides a column of tabbed widget items. +\endtable - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage motif-slider.png -\raw HTML - -\endraw -\inlineimage motif-lineedit.png -\raw HTML -
-\endraw -The QSlider widget provides a vertical or horizontal slider.\raw HTML - -\endraw -The QLineEdit widget is a one-line text editor.\raw HTML -
-\endraw -\inlineimage motif-combobox.png -\raw HTML - -\endraw -\inlineimage motif-doublespinbox.png -\raw HTML -
-\endraw -The QComboBox widget is a combined button and pop-up list.\raw HTML - -\endraw -The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.\raw HTML -
-\endraw -\inlineimage motif-spinbox.png -\raw HTML - -\endraw -\inlineimage motif-timeedit.png -\raw HTML -
-\endraw -The QSpinBox class provides a spin box widget.\raw HTML - -\endraw -The QTimeEdit class provides a widget for editing times.\raw HTML -
-\endraw -\inlineimage motif-dateedit.png -\raw HTML - -\endraw -\inlineimage motif-datetimeedit.png -\raw HTML -
-\endraw -The QDateEdit class provides a widget for editing dates.\raw HTML - -\endraw -The QDateTimeEdit class provides a widget for editing dates and times.\raw HTML -
-\endraw -\inlineimage motif-textedit.png -\raw HTML - -\endraw -\inlineimage motif-horizontalscrollbar.png -\raw HTML -
-\endraw -The QTextEdit class provides a widget that is used to edit and - display both plain and rich text.\raw HTML - -\endraw -The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.\raw HTML -
-\endraw -\inlineimage motif-dial.png -\raw HTML - -\endraw -\inlineimage motif-calendarwidget.png -\raw HTML -
-\endraw -The QDial class provides a rounded range control (like a - speedometer or potentiometer).\raw HTML - -\endraw -The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.\raw HTML -
-\endraw -\inlineimage motif-fontcombobox.png -\raw HTML -
-\endraw -The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.\raw HTML -
-\endraw +\section2 Item Views + +\table 100% +\row +\o \image motif-listview.png + The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view. +\o \image motif-treeview.png + The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view. +\o \image motif-tableview.png + The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o +\o +\endtable + +\section2 Display Widgets + +\table 100% +\row +\o \image motif-progressbar.png + The QProgressBar widget provides a horizontal progress bar. +\o \image motif-label.png + The QLabel widget provides a text or image display. +\o \image motif-lcdnumber.png + The QLCDNumber widget displays a number with LCD-like digits. +\endtable + +\section2 Input Widgets + +\table 100% +\row +\o \image motif-lineedit.png + The QLineEdit widget is a one-line text editor. +\o \image motif-dateedit.png + The QDateEdit class provides a widget for editing dates. +\o \image motif-timeedit.png + The QTimeEdit class provides a widget for editing times. +\o \image motif-datetimeedit.png + The QDateTimeEdit class provides a widget for editing dates and times. +\endtable + +\table 100% +\row +\o \image motif-slider.png + The QSlider widget provides a vertical or horizontal slider. +\o \image motif-combobox.png + The QComboBox widget is a combined button and pop-up list. +\o \image motif-spinbox.png + The QSpinBox class provides a spin box widget. +\endtable + +\table 100% +\row +\o \image motif-fontcombobox.png + The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts. +\o \image motif-doublespinbox.png + The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered. +\o \image motif-horizontalscrollbar.png + The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation. +\endtable + +\table 100% +\row +\o \image motif-dial.png + The QDial class provides a rounded range control (like a speedometer or potentiometer). +\o \image motif-textedit.png + The QTextEdit class provides a widget that is used to edit and display both plain and rich text. +\o \image motif-calendarwidget.png + The QCalendarWidget class provides a monthly calendar widget that can be used to select dates. +\endtable */ diff --git a/doc/src/widgets-and-layouts/gallery-plastique.qdoc b/doc/src/widgets-and-layouts/gallery-plastique.qdoc index 0ea62ee..5f2a1ec 100644 --- a/doc/src/widgets-and-layouts/gallery-plastique.qdoc +++ b/doc/src/widgets-and-layouts/gallery-plastique.qdoc @@ -34,345 +34,105 @@ This page shows some of the widgets available in Qt when configured to use the "plastique" style. -\raw HTML -

Buttons

+\section2 Buttons - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage plastique-pushbutton.png -\raw HTML - -\endraw -\inlineimage plastique-toolbutton.png -\raw HTML -
-\endraw -The QPushButton widget provides a command button.\raw HTML - -\endraw -The QToolButton class provides a quick-access button to commands - or options, usually used inside a QToolBar.\raw HTML -
-\endraw -\inlineimage plastique-checkbox.png -\raw HTML - -\endraw -\inlineimage plastique-radiobutton.png -\raw HTML -
-\endraw -The QCheckBox widget provides a checkbox with a text label.\raw HTML - -\endraw -The QRadioButton widget provides a radio button with a text or pixmap label.\raw HTML -
-\endraw -\raw HTML -

Containers

+\table 100% +\row +\o \image plastique-pushbutton.png + \caption The QPushButton widget provides a command button. +\o \image plastique-toolbutton.png + \caption The QToolButton class provides a quick-access button to commands + or options, usually used inside a QToolBar. +\endtable - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage plastique-groupbox.png -\raw HTML - -\endraw -\inlineimage plastique-tabwidget.png -\raw HTML -
-\endraw -The QGroupBox widget provides a group box frame with a title.\raw HTML - -\endraw -The QTabWidget class provides a stack of tabbed widgets.\raw HTML -
-\endraw -\inlineimage plastique-frame.png -\raw HTML - -\endraw -\inlineimage plastique-toolbox.png -\raw HTML -
-\endraw -The QFrame widget provides a simple decorated container for other widgets.\raw HTML - -\endraw -The QToolBox class provides a column of tabbed widget items.\raw HTML -
-\endraw -\raw HTML -

Item Views

+\table 100% +\row +\o \image plastique-checkbox.png + \caption The QCheckBox widget provides a checkbox with a text label. +\o \image plastique-radiobutton.png + \caption The QRadioButton widget provides a radio button with a text or pixmap label. +\endtable - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage plastique-listview.png -\raw HTML - -\endraw -\inlineimage plastique-treeview.png -\raw HTML -
-\endraw -The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.\raw HTML - -\endraw -The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.\raw HTML -
-\endraw -\inlineimage plastique-tableview.png -\raw HTML -
-\endraw -The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\raw HTML -
-\endraw -\raw HTML -

Display Widgets

+\section2 Containers - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage plastique-progressbar.png -\raw HTML - -\endraw -\inlineimage plastique-lcdnumber.png -\raw HTML -
-\endraw -The QProgressBar widget provides a horizontal progress bar.\raw HTML - -\endraw -The QLCDNumber widget displays a number with LCD-like digits.\raw HTML -
-\endraw -\inlineimage plastique-label.png -\raw HTML -
-\endraw -The QLabel widget provides a text or image display.\raw HTML -
-\endraw -\raw HTML -

Input Widgets

+\table 100% +\row +\o \image plastique-groupbox.png + The The QGroupBox widget provides a group box frame with a title. +\o \image plastique-tabwidget.png + The QTabWidget class provides a stack of tabbed widgets. +\o \image plastique-frame.png + The QFrame widget provides a simple decorated container for other widgets. +\o \image plastique-toolbox.png + The QToolBox class provides a column of tabbed widget items. +\endtable - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage plastique-slider.png -\raw HTML - -\endraw -\inlineimage plastique-lineedit.png -\raw HTML -
-\endraw -The QSlider widget provides a vertical or horizontal slider.\raw HTML - -\endraw -The QLineEdit widget is a one-line text editor.\raw HTML -
-\endraw -\inlineimage plastique-combobox.png -\raw HTML - -\endraw -\inlineimage plastique-doublespinbox.png -\raw HTML -
-\endraw -The QComboBox widget is a combined button and pop-up list.\raw HTML - -\endraw -The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.\raw HTML -
-\endraw -\inlineimage plastique-spinbox.png -\raw HTML - -\endraw -\inlineimage plastique-timeedit.png -\raw HTML -
-\endraw -The QSpinBox class provides a spin box widget.\raw HTML - -\endraw -The QTimeEdit class provides a widget for editing times.\raw HTML -
-\endraw -\inlineimage plastique-dateedit.png -\raw HTML - -\endraw -\inlineimage plastique-datetimeedit.png -\raw HTML -
-\endraw -The QDateEdit class provides a widget for editing dates.\raw HTML - -\endraw -The QDateTimeEdit class provides a widget for editing dates and times.\raw HTML -
-\endraw -\inlineimage plastique-textedit.png -\raw HTML - -\endraw -\inlineimage plastique-horizontalscrollbar.png -\raw HTML -
-\endraw -The QTextEdit class provides a widget that is used to edit and - display both plain and rich text.\raw HTML - -\endraw -The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.\raw HTML -
-\endraw -\inlineimage plastique-dial.png -\raw HTML - -\endraw -\inlineimage plastique-calendarwidget.png -\raw HTML -
-\endraw -The QDial class provides a rounded range control (like a - speedometer or potentiometer).\raw HTML - -\endraw -The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.\raw HTML -
-\endraw -\inlineimage plastique-fontcombobox.png -\raw HTML -
-\endraw -The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.\raw HTML -
-\endraw +\section2 Item Views + +\table 100% +\row +\o \image plastique-listview.png + The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view. +\o \image plastique-treeview.png + The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view. +\o \image plastique-tableview.png + The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o +\o +\endtable + +\section2 Display Widgets + +\table 100% +\row +\o \image plastique-progressbar.png + The QProgressBar widget provides a horizontal progress bar. +\o \image plastique-label.png + The QLabel widget provides a text or image display. +\o \image plastique-lcdnumber.png + The QLCDNumber widget displays a number with LCD-like digits. +\endtable + +\section2 Input Widgets + +\table 100% +\row +\o \image plastique-lineedit.png + The QLineEdit widget is a one-line text editor. +\o \image plastique-dateedit.png + The QDateEdit class provides a widget for editing dates. +\o \image plastique-timeedit.png + The QTimeEdit class provides a widget for editing times. +\o \image plastique-datetimeedit.png + The QDateTimeEdit class provides a widget for editing dates and times. +\endtable + +\table 100% +\row +\o \image plastique-slider.png + The QSlider widget provides a vertical or horizontal slider. +\o \image plastique-combobox.png + The QComboBox widget is a combined button and pop-up list. +\o \image plastique-spinbox.png + The QSpinBox class provides a spin box widget. +\endtable + +\table 100% +\row +\o \image plastique-fontcombobox.png + The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts. +\o \image plastique-doublespinbox.png + The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered. +\o \image plastique-horizontalscrollbar.png + The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation. +\endtable + +\table 100% +\row +\o \image plastique-dial.png + The QDial class provides a rounded range control (like a speedometer or potentiometer). +\o \image plastique-textedit.png + The QTextEdit class provides a widget that is used to edit and display both plain and rich text. +\o \image plastique-calendarwidget.png + The QCalendarWidget class provides a monthly calendar widget that can be used to select dates. +\endtable */ diff --git a/doc/src/widgets-and-layouts/gallery-windows.qdoc b/doc/src/widgets-and-layouts/gallery-windows.qdoc index d3464a0..fe38745 100644 --- a/doc/src/widgets-and-layouts/gallery-windows.qdoc +++ b/doc/src/widgets-and-layouts/gallery-windows.qdoc @@ -34,345 +34,105 @@ This page shows some of the widgets available in Qt when configured to use the "windows" style. -\raw HTML -

Buttons

+\section2 Buttons - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage windows-pushbutton.png -\raw HTML - -\endraw -\inlineimage windows-toolbutton.png -\raw HTML -
-\endraw -The QPushButton widget provides a command button.\raw HTML - -\endraw -The QToolButton class provides a quick-access button to commands - or options, usually used inside a QToolBar.\raw HTML -
-\endraw -\inlineimage windows-checkbox.png -\raw HTML - -\endraw -\inlineimage windows-radiobutton.png -\raw HTML -
-\endraw -The QCheckBox widget provides a checkbox with a text label.\raw HTML - -\endraw -The QRadioButton widget provides a radio button with a text or pixmap label.\raw HTML -
-\endraw -\raw HTML -

Containers

+\table 100% +\row +\o \image windows-pushbutton.png + \caption The QPushButton widget provides a command button. +\o \image windows-toolbutton.png + \caption The QToolButton class provides a quick-access button to commands + or options, usually used inside a QToolBar. +\endtable - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage windows-groupbox.png -\raw HTML - -\endraw -\inlineimage windows-tabwidget.png -\raw HTML -
-\endraw -The QGroupBox widget provides a group box frame with a title.\raw HTML - -\endraw -The QTabWidget class provides a stack of tabbed widgets.\raw HTML -
-\endraw -\inlineimage windows-frame.png -\raw HTML - -\endraw -\inlineimage windows-toolbox.png -\raw HTML -
-\endraw -The QFrame widget provides a simple decorated container for other widgets.\raw HTML - -\endraw -The QToolBox class provides a column of tabbed widget items.\raw HTML -
-\endraw -\raw HTML -

Item Views

+\table 100% +\row +\o \image windows-checkbox.png + \caption The QCheckBox widget provides a checkbox with a text label. +\o \image windows-radiobutton.png + \caption The QRadioButton widget provides a radio button with a text or pixmap label. +\endtable - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage windows-listview.png -\raw HTML - -\endraw -\inlineimage windows-treeview.png -\raw HTML -
-\endraw -The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.\raw HTML - -\endraw -The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.\raw HTML -
-\endraw -\inlineimage windows-tableview.png -\raw HTML -
-\endraw -The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\raw HTML -
-\endraw -\raw HTML -

Display Widgets

+\section2 Containers - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage windows-progressbar.png -\raw HTML - -\endraw -\inlineimage windows-lcdnumber.png -\raw HTML -
-\endraw -The QProgressBar widget provides a horizontal progress bar.\raw HTML - -\endraw -The QLCDNumber widget displays a number with LCD-like digits.\raw HTML -
-\endraw -\inlineimage windows-label.png -\raw HTML -
-\endraw -The QLabel widget provides a text or image display.\raw HTML -
-\endraw -\raw HTML -

Input Widgets

+\table 100% +\row +\o \image windows-groupbox.png + The The QGroupBox widget provides a group box frame with a title. +\o \image windows-tabwidget.png + The QTabWidget class provides a stack of tabbed widgets. +\o \image windows-frame.png + The QFrame widget provides a simple decorated container for other widgets. +\o \image windows-toolbox.png + The QToolBox class provides a column of tabbed widget items. +\endtable - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage windows-slider.png -\raw HTML - -\endraw -\inlineimage windows-lineedit.png -\raw HTML -
-\endraw -The QSlider widget provides a vertical or horizontal slider.\raw HTML - -\endraw -The QLineEdit widget is a one-line text editor.\raw HTML -
-\endraw -\inlineimage windows-combobox.png -\raw HTML - -\endraw -\inlineimage windows-doublespinbox.png -\raw HTML -
-\endraw -The QComboBox widget is a combined button and pop-up list.\raw HTML - -\endraw -The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.\raw HTML -
-\endraw -\inlineimage windows-spinbox.png -\raw HTML - -\endraw -\inlineimage windows-timeedit.png -\raw HTML -
-\endraw -The QSpinBox class provides a spin box widget.\raw HTML - -\endraw -The QTimeEdit class provides a widget for editing times.\raw HTML -
-\endraw -\inlineimage windows-dateedit.png -\raw HTML - -\endraw -\inlineimage windows-datetimeedit.png -\raw HTML -
-\endraw -The QDateEdit class provides a widget for editing dates.\raw HTML - -\endraw -The QDateTimeEdit class provides a widget for editing dates and times.\raw HTML -
-\endraw -\inlineimage windows-textedit.png -\raw HTML - -\endraw -\inlineimage windows-horizontalscrollbar.png -\raw HTML -
-\endraw -The QTextEdit class provides a widget that is used to edit and - display both plain and rich text.\raw HTML - -\endraw -The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.\raw HTML -
-\endraw -\inlineimage windows-dial.png -\raw HTML - -\endraw -\inlineimage windows-calendarwidget.png -\raw HTML -
-\endraw -The QDial class provides a rounded range control (like a - speedometer or potentiometer).\raw HTML - -\endraw -The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.\raw HTML -
-\endraw -\inlineimage windows-fontcombobox.png -\raw HTML -
-\endraw -The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.\raw HTML -
-\endraw +\section2 Item Views + +\table 100% +\row +\o \image windows-listview.png + The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view. +\o \image windows-treeview.png + The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view. +\o \image windows-tableview.png + The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o +\o +\endtable + +\section2 Display Widgets + +\table 100% +\row +\o \image windows-progressbar.png + The QProgressBar widget provides a horizontal progress bar. +\o \image windows-label.png + The QLabel widget provides a text or image display. +\o \image windows-lcdnumber.png + The QLCDNumber widget displays a number with LCD-like digits. +\endtable + +\section2 Input Widgets + +\table 100% +\row +\o \image windows-lineedit.png + The QLineEdit widget is a one-line text editor. +\o \image windows-dateedit.png + The QDateEdit class provides a widget for editing dates. +\o \image windows-timeedit.png + The QTimeEdit class provides a widget for editing times. +\o \image windows-datetimeedit.png + The QDateTimeEdit class provides a widget for editing dates and times. +\endtable + +\table 100% +\row +\o \image windows-slider.png + The QSlider widget provides a vertical or horizontal slider. +\o \image windows-combobox.png + The QComboBox widget is a combined button and pop-up list. +\o \image windows-spinbox.png + The QSpinBox class provides a spin box widget. +\endtable + +\table 100% +\row +\o \image windows-fontcombobox.png + The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts. +\o \image windows-doublespinbox.png + The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered. +\o \image windows-horizontalscrollbar.png + The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation. +\endtable + +\table 100% +\row +\o \image windows-dial.png + The QDial class provides a rounded range control (like a speedometer or potentiometer). +\o \image windows-textedit.png + The QTextEdit class provides a widget that is used to edit and display both plain and rich text. +\o \image windows-calendarwidget.png + The QCalendarWidget class provides a monthly calendar widget that can be used to select dates. +\endtable */ diff --git a/doc/src/widgets-and-layouts/gallery-windowsvista.qdoc b/doc/src/widgets-and-layouts/gallery-windowsvista.qdoc index 00afd52..e017a2c 100644 --- a/doc/src/widgets-and-layouts/gallery-windowsvista.qdoc +++ b/doc/src/widgets-and-layouts/gallery-windowsvista.qdoc @@ -34,345 +34,105 @@ This page shows some of the widgets available in Qt when configured to use the "windowsvista" style. -\raw HTML -

Buttons

+\section2 Buttons - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage windowsvista-pushbutton.png -\raw HTML - -\endraw -\inlineimage windowsvista-toolbutton.png -\raw HTML -
-\endraw -The QPushButton widget provides a command button.\raw HTML - -\endraw -The QToolButton class provides a quick-access button to commands - or options, usually used inside a QToolBar.\raw HTML -
-\endraw -\inlineimage windowsvista-checkbox.png -\raw HTML - -\endraw -\inlineimage windowsvista-radiobutton.png -\raw HTML -
-\endraw -The QCheckBox widget provides a checkbox with a text label.\raw HTML - -\endraw -The QRadioButton widget provides a radio button with a text or pixmap label.\raw HTML -
-\endraw -\raw HTML -

Containers

+\table 100% +\row +\o \image windowsvista-pushbutton.png + \caption The QPushButton widget provides a command button. +\o \image windowsvista-toolbutton.png + \caption The QToolButton class provides a quick-access button to commands + or options, usually used inside a QToolBar. +\endtable - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage windowsvista-groupbox.png -\raw HTML - -\endraw -\inlineimage windowsvista-tabwidget.png -\raw HTML -
-\endraw -The QGroupBox widget provides a group box frame with a title.\raw HTML - -\endraw -The QTabWidget class provides a stack of tabbed widgets.\raw HTML -
-\endraw -\inlineimage windowsvista-frame.png -\raw HTML - -\endraw -\inlineimage windowsvista-toolbox.png -\raw HTML -
-\endraw -The QFrame widget provides a simple decorated container for other widgets.\raw HTML - -\endraw -The QToolBox class provides a column of tabbed widget items.\raw HTML -
-\endraw -\raw HTML -

Item Views

+\table 100% +\row +\o \image windowsvista-checkbox.png + \caption The QCheckBox widget provides a checkbox with a text label. +\o \image windowsvista-radiobutton.png + \caption The QRadioButton widget provides a radio button with a text or pixmap label. +\endtable - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage windowsvista-listview.png -\raw HTML - -\endraw -\inlineimage windowsvista-treeview.png -\raw HTML -
-\endraw -The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.\raw HTML - -\endraw -The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.\raw HTML -
-\endraw -\inlineimage windowsvista-tableview.png -\raw HTML -
-\endraw -The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\raw HTML -
-\endraw -\raw HTML -

Display Widgets

+\section2 Containers - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage windowsvista-progressbar.png -\raw HTML - -\endraw -\inlineimage windowsvista-lcdnumber.png -\raw HTML -
-\endraw -The QProgressBar widget provides a horizontal progress bar.\raw HTML - -\endraw -The QLCDNumber widget displays a number with LCD-like digits.\raw HTML -
-\endraw -\inlineimage windowsvista-label.png -\raw HTML -
-\endraw -The QLabel widget provides a text or image display.\raw HTML -
-\endraw -\raw HTML -

Input Widgets

+\table 100% +\row +\o \image windowsvista-groupbox.png + The The QGroupBox widget provides a group box frame with a title. +\o \image windowsvista-tabwidget.png + The QTabWidget class provides a stack of tabbed widgets. +\o \image windowsvista-frame.png + The QFrame widget provides a simple decorated container for other widgets. +\o \image windowsvista-toolbox.png + The QToolBox class provides a column of tabbed widget items. +\endtable - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage windowsvista-slider.png -\raw HTML - -\endraw -\inlineimage windowsvista-lineedit.png -\raw HTML -
-\endraw -The QSlider widget provides a vertical or horizontal slider.\raw HTML - -\endraw -The QLineEdit widget is a one-line text editor.\raw HTML -
-\endraw -\inlineimage windowsvista-combobox.png -\raw HTML - -\endraw -\inlineimage windowsvista-doublespinbox.png -\raw HTML -
-\endraw -The QComboBox widget is a combined button and pop-up list.\raw HTML - -\endraw -The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.\raw HTML -
-\endraw -\inlineimage windowsvista-spinbox.png -\raw HTML - -\endraw -\inlineimage windowsvista-timeedit.png -\raw HTML -
-\endraw -The QSpinBox class provides a spin box widget.\raw HTML - -\endraw -The QTimeEdit class provides a widget for editing times.\raw HTML -
-\endraw -\inlineimage windowsvista-dateedit.png -\raw HTML - -\endraw -\inlineimage windowsvista-datetimeedit.png -\raw HTML -
-\endraw -The QDateEdit class provides a widget for editing dates.\raw HTML - -\endraw -The QDateTimeEdit class provides a widget for editing dates and times.\raw HTML -
-\endraw -\inlineimage windowsvista-textedit.png -\raw HTML - -\endraw -\inlineimage windowsvista-horizontalscrollbar.png -\raw HTML -
-\endraw -The QTextEdit class provides a widget that is used to edit and - display both plain and rich text.\raw HTML - -\endraw -The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.\raw HTML -
-\endraw -\inlineimage windowsvista-dial.png -\raw HTML - -\endraw -\inlineimage windowsvista-calendarwidget.png -\raw HTML -
-\endraw -The QDial class provides a rounded range control (like a - speedometer or potentiometer).\raw HTML - -\endraw -The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.\raw HTML -
-\endraw -\inlineimage windowsvista-fontcombobox.png -\raw HTML -
-\endraw -The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.\raw HTML -
-\endraw +\section2 Item Views + +\table 100% +\row +\o \image windowsvista-listview.png + The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view. +\o \image windowsvista-treeview.png + The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view. +\o \image windowsvista-tableview.png + The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o +\o +\endtable + +\section2 Display Widgets + +\table 100% +\row +\o \image windowsvista-progressbar.png + The QProgressBar widget provides a horizontal progress bar. +\o \image windowsvista-label.png + The QLabel widget provides a text or image display. +\o \image windowsvista-lcdnumber.png + The QLCDNumber widget displays a number with LCD-like digits. +\endtable + +\section2 Input Widgets + +\table 100% +\row +\o \image windowsvista-lineedit.png + The QLineEdit widget is a one-line text editor. +\o \image windowsvista-dateedit.png + The QDateEdit class provides a widget for editing dates. +\o \image windowsvista-timeedit.png + The QTimeEdit class provides a widget for editing times. +\o \image windowsvista-datetimeedit.png + The QDateTimeEdit class provides a widget for editing dates and times. +\endtable + +\table 100% +\row +\o \image windowsvista-slider.png + The QSlider widget provides a vertical or horizontal slider. +\o \image windowsvista-combobox.png + The QComboBox widget is a combined button and pop-up list. +\o \image windowsvista-spinbox.png + The QSpinBox class provides a spin box widget. +\endtable + +\table 100% +\row +\o \image windowsvista-fontcombobox.png + The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts. +\o \image windowsvista-doublespinbox.png + The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered. +\o \image windowsvista-horizontalscrollbar.png + The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation. +\endtable + +\table 100% +\row +\o \image windowsvista-dial.png + The QDial class provides a rounded range control (like a speedometer or potentiometer). +\o \image windowsvista-textedit.png + The QTextEdit class provides a widget that is used to edit and display both plain and rich text. +\o \image windowsvista-calendarwidget.png + The QCalendarWidget class provides a monthly calendar widget that can be used to select dates. +\endtable */ diff --git a/doc/src/widgets-and-layouts/gallery-windowsxp.qdoc b/doc/src/widgets-and-layouts/gallery-windowsxp.qdoc index 60c8ff0..f3c53ee 100644 --- a/doc/src/widgets-and-layouts/gallery-windowsxp.qdoc +++ b/doc/src/widgets-and-layouts/gallery-windowsxp.qdoc @@ -34,345 +34,105 @@ This page shows some of the widgets available in Qt when configured to use the "windowsxp" style. -\raw HTML -

Buttons

+\section2 Buttons - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage windowsxp-pushbutton.png -\raw HTML - -\endraw -\inlineimage windowsxp-toolbutton.png -\raw HTML -
-\endraw -The QPushButton widget provides a command button.\raw HTML - -\endraw -The QToolButton class provides a quick-access button to commands - or options, usually used inside a QToolBar.\raw HTML -
-\endraw -\inlineimage windowsxp-checkbox.png -\raw HTML - -\endraw -\inlineimage windowsxp-radiobutton.png -\raw HTML -
-\endraw -The QCheckBox widget provides a checkbox with a text label.\raw HTML - -\endraw -The QRadioButton widget provides a radio button with a text or pixmap label.\raw HTML -
-\endraw -\raw HTML -

Containers

+\table 100% +\row +\o \image windowsxp-pushbutton.png + \caption The QPushButton widget provides a command button. +\o \image windowsxp-toolbutton.png + \caption The QToolButton class provides a quick-access button to commands + or options, usually used inside a QToolBar. +\endtable - -- - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage windowsxp-groupbox.png -\raw HTML - -\endraw -\inlineimage windowsxp-tabwidget.png -\raw HTML -
-\endraw -The QGroupBox widget provides a group box frame with a title.\raw HTML - -\endraw -The QTabWidget class provides a stack of tabbed widgets.\raw HTML -
-\endraw -\inlineimage windowsxp-frame.png -\raw HTML - -\endraw -\inlineimage windowsxp-toolbox.png -\raw HTML -
-\endraw -The QFrame widget provides a simple decorated container for other widgets.\raw HTML - -\endraw -The QToolBox class provides a column of tabbed widget items.\raw HTML -
-\endraw -\raw HTML -

Item Views

+\table 100% +\row +\o \image windowsxp-checkbox.png + \caption The QCheckBox widget provides a checkbox with a text label. +\o \image windowsxp-radiobutton.png + \caption The QRadioButton widget provides a radio button with a text or pixmap label. +\endtable - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage windowsxp-listview.png -\raw HTML - -\endraw -\inlineimage windowsxp-treeview.png -\raw HTML -
-\endraw -The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.\raw HTML - -\endraw -The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.\raw HTML -
-\endraw -\inlineimage windowsxp-tableview.png -\raw HTML -
-\endraw -The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\raw HTML -
-\endraw -\raw HTML -

Display Widgets

+\section2 Containers - -- - - - - - - - - - - - - - - -
-\endraw -\inlineimage windowsxp-progressbar.png -\raw HTML - -\endraw -\inlineimage windowsxp-lcdnumber.png -\raw HTML -
-\endraw -The QProgressBar widget provides a horizontal progress bar.\raw HTML - -\endraw -The QLCDNumber widget displays a number with LCD-like digits.\raw HTML -
-\endraw -\inlineimage windowsxp-label.png -\raw HTML -
-\endraw -The QLabel widget provides a text or image display.\raw HTML -
-\endraw -\raw HTML -

Input Widgets

+\table 100% +\row +\o \image windowsxp-groupbox.png + The The QGroupBox widget provides a group box frame with a title. +\o \image windowsxp-tabwidget.png + The QTabWidget class provides a stack of tabbed widgets. +\o \image windowsxp-frame.png + The QFrame widget provides a simple decorated container for other widgets. +\o \image windowsxp-toolbox.png + The QToolBox class provides a column of tabbed widget items. +\endtable - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-\endraw -\inlineimage windowsxp-slider.png -\raw HTML - -\endraw -\inlineimage windowsxp-lineedit.png -\raw HTML -
-\endraw -The QSlider widget provides a vertical or horizontal slider.\raw HTML - -\endraw -The QLineEdit widget is a one-line text editor.\raw HTML -
-\endraw -\inlineimage windowsxp-combobox.png -\raw HTML - -\endraw -\inlineimage windowsxp-doublespinbox.png -\raw HTML -
-\endraw -The QComboBox widget is a combined button and pop-up list.\raw HTML - -\endraw -The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.\raw HTML -
-\endraw -\inlineimage windowsxp-spinbox.png -\raw HTML - -\endraw -\inlineimage windowsxp-timeedit.png -\raw HTML -
-\endraw -The QSpinBox class provides a spin box widget.\raw HTML - -\endraw -The QTimeEdit class provides a widget for editing times.\raw HTML -
-\endraw -\inlineimage windowsxp-dateedit.png -\raw HTML - -\endraw -\inlineimage windowsxp-datetimeedit.png -\raw HTML -
-\endraw -The QDateEdit class provides a widget for editing dates.\raw HTML - -\endraw -The QDateTimeEdit class provides a widget for editing dates and times.\raw HTML -
-\endraw -\inlineimage windowsxp-textedit.png -\raw HTML - -\endraw -\inlineimage windowsxp-horizontalscrollbar.png -\raw HTML -
-\endraw -The QTextEdit class provides a widget that is used to edit and - display both plain and rich text.\raw HTML - -\endraw -The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.\raw HTML -
-\endraw -\inlineimage windowsxp-dial.png -\raw HTML - -\endraw -\inlineimage windowsxp-calendarwidget.png -\raw HTML -
-\endraw -The QDial class provides a rounded range control (like a - speedometer or potentiometer).\raw HTML - -\endraw -The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.\raw HTML -
-\endraw -\inlineimage windowsxp-fontcombobox.png -\raw HTML -
-\endraw -The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.\raw HTML -
-\endraw +\section2 Item Views + +\table 100% +\row +\o \image windowsxp-listview.png + The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view. +\o \image windowsxp-treeview.png + The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view. +\o \image windowsxp-tableview.png + The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o +\o +\endtable + +\section2 Display Widgets + +\table 100% +\row +\o \image windowsxp-progressbar.png + The QProgressBar widget provides a horizontal progress bar. +\o \image windowsxp-label.png + The QLabel widget provides a text or image display. +\o \image windowsxp-lcdnumber.png + The QLCDNumber widget displays a number with LCD-like digits. +\endtable + +\section2 Input Widgets + +\table 100% +\row +\o \image windowsxp-lineedit.png + The QLineEdit widget is a one-line text editor. +\o \image windowsxp-dateedit.png + The QDateEdit class provides a widget for editing dates. +\o \image windowsxp-timeedit.png + The QTimeEdit class provides a widget for editing times. +\o \image windowsxp-datetimeedit.png + The QDateTimeEdit class provides a widget for editing dates and times. +\endtable + +\table 100% +\row +\o \image windowsxp-slider.png + The QSlider widget provides a vertical or horizontal slider. +\o \image windowsxp-combobox.png + The QComboBox widget is a combined button and pop-up list. +\o \image windowsxp-spinbox.png + The QSpinBox class provides a spin box widget. +\endtable + +\table 100% +\row +\o \image windowsxp-fontcombobox.png + The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts. +\o \image windowsxp-doublespinbox.png + The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered. +\o \image windowsxp-horizontalscrollbar.png + The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation. +\endtable + +\table 100% +\row +\o \image windowsxp-dial.png + The QDial class provides a rounded range control (like a speedometer or potentiometer). +\o \image windowsxp-textedit.png + The QTextEdit class provides a widget that is used to edit and display both plain and rich text. +\o \image windowsxp-calendarwidget.png + The QCalendarWidget class provides a monthly calendar widget that can be used to select dates. +\endtable */ -- cgit v0.12 From 21fd6c0d818f3f4a3efa8904c8ddbfeb3a1e931d Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 13 Dec 2010 12:25:54 +0100 Subject: doc: Replaced some \raw and \endraw uses with \table and \endtable In DITA XML, there is no straightforward way to translate raw html into DITA XML, because the XML stream writer automagically escapes all the raw html elements. So I am beginning to replace uses of the \raw command with \table, which gets output correctly. The problem is the XML stream writer must see each XML element start and end, because it keeps them on a stack. When you output XML elements with the writeCharacters() function, it escapes the '<' and '>' of any XML elements the character string contains. --- doc/src/widgets-and-layouts/gallery.qdoc | 112 +++++++++---------------------- 1 file changed, 30 insertions(+), 82 deletions(-) diff --git a/doc/src/widgets-and-layouts/gallery.qdoc b/doc/src/widgets-and-layouts/gallery.qdoc index 201817b..d11d9c8 100644 --- a/doc/src/widgets-and-layouts/gallery.qdoc +++ b/doc/src/widgets-and-layouts/gallery.qdoc @@ -34,103 +34,51 @@ with the native desktop enviroment. Below, you can find links to the various widget styles that are supplied with Qt 4. - \raw HTML - - - - - - - - - - - - - - - - - - - - - - - - -
- \endraw - \image plastique-tabwidget.png Plastique Style Widget Gallery - - \bold{\l{Plastique Style Widget Gallery}} + \table + \row + \o \image plastique-tabwidget.png Plastique Style Widget Gallery + \caption \l{Plastique Style Widget Gallery} The Plastique style is provided by QPlastiqueStyle. - \raw HTML - - \endraw - \image windowsxp-tabwidget.png Windows XP Style Widget Gallery - - \bold{\l{Windows XP Style Widget Gallery}} + \o \image windowsxp-tabwidget.png Windows XP Style Widget Gallery + \caption \l{Windows XP Style Widget Gallery} The Windows XP style is provided by QWindowsXPStyle. - \raw HTML -
- \endraw - \image gtk-tabwidget.png GTK Style Widget Gallery + \o \image windows-tabwidget.png Windows Style Widget Gallery + \caption \l{Windows Style Widget Gallery} - \bold{\l{GTK Style Widget Gallery}} - - The GTK style is provided by QGtkStyle. - \raw HTML - - \endraw - \image macintosh-tabwidget.png Macintosh Style Widget Gallery + The Windows style is provided by QWindowsStyle. + \endtable - \bold{\l{Macintosh Style Widget Gallery}} + \table + \row + \o \image macintosh-tabwidget.png Macintosh Style Widget Gallery + \caption \l{Macintosh Style Widget Gallery} The Macintosh style is provided by QMacStyle. - \raw HTML -
- \endraw - \image cleanlooks-tabwidget.png Cleanlooks Style Widget Gallery - - \bold{\l{Cleanlooks Style Widget Gallery}} + \o \image cleanlooks-tabwidget.png Cleanlooks Style Widget Gallery + \caption \l{Cleanlooks Style Widget Gallery} The Cleanlooks style is provided by QCleanlooksStyle. - \raw HTML - - \endraw - \image windowsvista-tabwidget.png Windows Vista Style Widget Gallery - - \bold{\l{Windows Vista Style Widget Gallery}} + \o \image windowsvista-tabwidget.png Windows Vista Style Widget Gallery + \caption \l{Windows Vista Style Widget Gallery} The Windows Vista style is provided by QWindowsVistaStyle. - \raw HTML -
- \endraw - \image motif-tabwidget.png Motif Style Widget Gallery + \endtable - \bold{\l{Motif Style Widget Gallery}} + \table + \row + \o \image gtk-tabwidget.png GTK Style Widget Gallery + \caption \l{GTK Style Widget Gallery} - The Motif style is provided by QMotifStyle. - \raw HTML - - \endraw - \image windows-tabwidget.png Windows Style Widget Gallery - - \bold{\l{Windows Style Widget Gallery}} - - The Windows style is provided by QWindowsStyle. - \raw HTML -
- \endraw - \image cde-tabwidget.png CDE Style Widget Gallery + The GTK style is provided by QGtkStyle. + \o \image motif-tabwidget.png Motif Style Widget Gallery + \caption \l{Motif Style Widget Gallery} - \bold{\l{CDE Style Widget Gallery}} + The Motif style is provided by QMotifStyle. + \o \image cde-tabwidget.png CDE Style Widget Gallery + \caption \l{CDE Style Widget Gallery} The Common Desktop Environment style is provided by QCDEStyle. - \raw HTML -
- \endraw + \endtable */ -- 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 7ee2e9fd873b2c38a1a362170c4a0e4754cfd22a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 18 Oct 2010 09:28:14 +0200 Subject: Cocoa: native child filedialogs sometimes shows non-native on screen The reason is that we make all child dialogs of a modal dialogs non-modaly shaddowed, as documented. But we forgot to check if a window is actually visible before raising it to front. Also adding harmless auto release pool Rev-By: prasanth --- src/gui/kernel/qeventdispatcher_mac.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm index 515c6d3..dc926e0 100644 --- a/src/gui/kernel/qeventdispatcher_mac.mm +++ b/src/gui/kernel/qeventdispatcher_mac.mm @@ -844,7 +844,7 @@ static void setChildrenWorksWhenModal(QWidget *widget, bool worksWhenModal) NSWindow *window = qt_mac_window_for(dialogs[i]); if (window && [window isKindOfClass:[NSPanel class]]) { [static_cast(window) setWorksWhenModal:worksWhenModal]; - if (worksWhenModal && dialogs[i]->isVisible()){ + if (worksWhenModal && [window isVisible]){ [window orderFront:window]; } } @@ -856,6 +856,7 @@ void QEventDispatcherMacPrivate::updateChildrenWorksWhenModal() // Make the dialog children of the widget // active. And make the dialog children of // the previous modal dialog unactive again: + QMacCocoaAutoReleasePool pool; int size = cocoaModalSessionStack.size(); if (size > 0){ if (QWidget *prevModal = cocoaModalSessionStack[size-1].widget) -- cgit v0.12 From a04b19d34c23df5bb6e4f499b6b12c7a1211969a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 18 Oct 2010 15:27:02 +0200 Subject: Cocoa: make sure stays on top child windows are not levelled down [NSWindow addChild] levels the child to the level of the parent. In Qt we do not want this. So we do a check after setting up the parent-child relationship for this. Reviewed-by: cduclos --- src/gui/kernel/qwidget_mac.mm | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 997419b..08af3ac 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2822,8 +2822,12 @@ void QWidgetPrivate::setSubWindowStacking(bool set) if (NSWindow *pwin = [qt_mac_nativeview_for(parent) window]) { if (set) { Qt::WindowType ptype = parent->window()->windowType(); - if ([pwin isVisible] && (ptype == Qt::Window || ptype == Qt::Dialog) && ![qwin parentWindow]) + if ([pwin isVisible] && (ptype == Qt::Window || ptype == Qt::Dialog) && ![qwin parentWindow]) { + NSInteger level = [qwin level]; [pwin addChildWindow:qwin ordered:NSWindowAbove]; + if ([qwin level] < level) + [qwin setLevel:level]; + } } else { [pwin removeChildWindow:qwin]; } @@ -2837,8 +2841,12 @@ void QWidgetPrivate::setSubWindowStacking(bool set) if (NSWindow *cwin = [qt_mac_nativeview_for(child) window]) { if (set) { Qt::WindowType ctype = child->window()->windowType(); - if ([cwin isVisible] && (ctype == Qt::Window || ctype == Qt::Dialog) && ![cwin parentWindow]) + if ([cwin isVisible] && (ctype == Qt::Window || ctype == Qt::Dialog) && ![cwin parentWindow]) { + NSInteger level = [cwin level]; [qwin addChildWindow:cwin ordered:NSWindowAbove]; + if ([cwin level] < level) + [cwin setLevel:level]; + } } else { [qwin removeChildWindow:qt_mac_window_for(child)]; } -- cgit v0.12 From 19148694b1e094ad968e26e6fab448d3d2c7f4d4 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 18 Oct 2010 15:30:12 +0200 Subject: Cocoa: cannot use staysOnTop flag for native file dialogs We cannot mix staysOnTop and native file dialogs, since Cocoa will anyway set it back to NSModalPanelWindowLevel when running it app modal. There are ways to work around this issue, but the file dialog also has a button for showing a "create directory" modal panel, and this we cannot control. Reviewed-by: cduclos --- src/gui/dialogs/qfiledialog_mac.mm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm index 87850a7..1e13113 100644 --- a/src/gui/dialogs/qfiledialog_mac.mm +++ b/src/gui/dialogs/qfiledialog_mac.mm @@ -719,6 +719,14 @@ bool QFileDialogPrivate::setVisible_sys(bool visible) if (!visible == q->isHidden()) return false; + if (q->windowFlags() & Qt::WindowStaysOnTopHint) { + // The native file dialog tries all it can to stay + // on the NSModalPanel level. And it might also show + // its own "create directory" dialog that we cannot control. + // So we need to use the non-native version in this case... + return false; + } + #ifndef QT_MAC_USE_COCOA return visible ? showCarbonNavServicesDialog() : hideCarbonNavServicesDialog(); #else -- cgit v0.12 From 3e2cb226277998a7841c85048493c89bc1ccc95f Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 18 Oct 2010 16:12:46 +0200 Subject: Cocoa: Fix addChildWindow bug where we connect a grandparent to a child A plain bug where we ask for a list of widgets, but forget that qFindChildren is recursive, which is not what we want. Reviewed-by: jbache --- src/gui/kernel/qwidget_mac.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 08af3ac..b89cb88 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2834,9 +2834,9 @@ void QWidgetPrivate::setSubWindowStacking(bool set) } } - QList widgets = q->findChildren(); + QObjectList widgets = q->children(); for (int i=0; i(widgets.at(i)); if (child && child->isWindow()) { if (NSWindow *cwin = [qt_mac_nativeview_for(child) window]) { if (set) { -- cgit v0.12 From 780b4d84205f16c46f6c5e85e6c1925beb4e4dba Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 22 Nov 2010 11:08:34 +0100 Subject: Cocoa: combobox does not hightlight when mouse re-hovers the first item The reason is that on Mac, the highlight is supposed to switch off when the mouse moves out of the drop down menu. On X11, it stays. So there is a separate code path for this in qcombobox.cpp. But it fails to clear the index set in the view when the mouse leaves, which stops the item from re-highligh when the mouse re-enters. Reviewed-by: ogoffart --- src/gui/widgets/qcombobox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index 7859bdc..5a4e507 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -398,7 +398,7 @@ void QComboBoxPrivateContainer::leaveEvent(QEvent *) #ifdef Q_WS_MAC QStyleOptionComboBox opt = comboStyleOption(); if (combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo)) - view->clearSelection(); + view->setCurrentIndex(QModelIndex()); #endif } -- cgit v0.12 From d9004ddf237a09f3b7f25128ceb83a0e79e7b1aa Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 13 Dec 2010 13:39:34 +0100 Subject: Cocoa: popup hides behind window Reason: when cocoa receives a mouse press/release in a window, it finds the correct view inside that window and sends the mouse event to it. But NSWindow also does some other stuff just before sending the event, like raise and lower windows. So when we override sendEvent, and more over, do not call [super sendEvent], we stop this raise/lower etc from working. So, to make this work again, I partially revert change 0b2eab87ad3bd73a0744469a45c29ca098649c9b Task-number: QTBUG-15638, QTBUG-1517 Reviewed-by: Fabien Freling --- src/gui/kernel/qcocoasharedwindowmethods_mac_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h index ddf1a27..1e2e71b 100644 --- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h +++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h @@ -182,7 +182,7 @@ QT_END_NAMESPACE bool handled = false; // sometimes need to redirect mouse events to the popup. QWidget *popup = qAppInstance()->activePopupWidget(); - if (popup) { + if (popup && popup != widget) { switch([event type]) { case NSLeftMouseDown: -- 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 69ed34d2aa77a3bacc7f66797baa514f35358b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 13 Dec 2010 14:21:39 +0100 Subject: Fixed GL 2 engine rendering of images / pixmaps above max texture size. Down-scale images or pixmaps that are above the max texture size. Not optimal performance-wise, but better than failing. Task-number: QTBUG-16033 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 52 +++++++++++++++++++--- .../gl2paintengineex/qpaintengineex_opengl2_p.h | 2 + 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 4a64f39..668a3f0 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -163,6 +163,8 @@ void QGL2PaintEngineExPrivate::setBrush(const QBrush& brush) Q_ASSERT(newStyle != Qt::NoBrush); currentBrush = brush; + if (!currentBrushPixmap.isNull()) + currentBrushPixmap = QPixmap(); brushUniformsDirty = true; // All brushes have at least one uniform if (newStyle > Qt::SolidPattern) @@ -221,10 +223,14 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, q->state()->renderHints & QPainter::SmoothPixmapTransform); } else if (style == Qt::TexturePattern) { - const QPixmap& texPixmap = currentBrush.texture(); + currentBrushPixmap = currentBrush.texture(); + + int max_texture_size = ctx->d_func()->maxTextureSize(); + if (currentBrushPixmap.width() > max_texture_size || currentBrushPixmap.height() > max_texture_size) + currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - QGLTexture *tex = ctx->d_func()->bindTexture(texPixmap, GL_TEXTURE_2D, GL_RGBA, + QGLTexture *tex = ctx->d_func()->bindTexture(currentBrushPixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption | QGLContext::CanFlipNativePixmapBindOption); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); @@ -1305,13 +1311,30 @@ void QGL2PaintEngineEx::transformChanged() } +static const QRectF scaleRect(const QRectF &r, qreal sx, qreal sy) +{ + return QRectF(r.x() * sx, r.y() * sy, r.width() * sx, r.height() * sy); +} + void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, const QRectF & src) { Q_D(QGL2PaintEngineEx); + QGLContext *ctx = d->ctx; + + int max_texture_size = ctx->d_func()->maxTextureSize(); + if (pixmap.width() > max_texture_size || pixmap.height() > max_texture_size) { + QPixmap scaled = pixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); + + const qreal sx = scaled.width() / qreal(pixmap.width()); + const qreal sy = scaled.height() / qreal(pixmap.height()); + + drawPixmap(dest, scaled, scaleRect(src, sx, sy)); + return; + } + ensureActive(); d->transferMode(ImageDrawingMode); - QGLContext *ctx = d->ctx; glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); QGLTexture *texture = ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, @@ -1334,11 +1357,24 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const Qt::ImageConversionFlags) { Q_D(QGL2PaintEngineEx); + QGLContext *ctx = d->ctx; + + int max_texture_size = ctx->d_func()->maxTextureSize(); + if (image.width() > max_texture_size || image.height() > max_texture_size) { + QImage scaled = image.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); + + const qreal sx = scaled.width() / qreal(image.width()); + const qreal sy = scaled.height() / qreal(image.height()); + + drawImage(dest, scaled, scaleRect(src, sx, sy)); + return; + } + ensureActive(); d->transferMode(ImageDrawingMode); - QGLContext *ctx = d->ctx; glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); + QGLTexture *texture = ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption); GLuint id = texture->id; @@ -1737,7 +1773,13 @@ void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *frag } ensureActive(); - d->drawPixmapFragments(fragments, fragmentCount, pixmap, hints); + int max_texture_size = d->ctx->d_func()->maxTextureSize(); + if (pixmap.width() > max_texture_size || pixmap.height() > max_texture_size) { + QPixmap scaled = pixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); + d->drawPixmapFragments(fragments, fragmentCount, scaled, hints); + } else { + d->drawPixmapFragments(fragments, fragmentCount, pixmap, hints); + } } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index b255e75..02b737b 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -274,6 +274,8 @@ public: QBrush currentBrush; // May not be the state's brush! const QBrush noBrush; + QPixmap currentBrushPixmap; + QGL2PEXVertexArray vertexCoordinateArray; QGL2PEXVertexArray textureCoordinateArray; QVector elementIndices; -- cgit v0.12 From 0af1f5508e165f3b494ab236cb1cdf1b0edcffa5 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 13 Dec 2010 11:29:22 +0100 Subject: Fixes text jitter in QtQuick components when using the virtual keyboard QGraphicsView::mapFromScene() returns a QRect instead of a QRectF. Thus, we were prematurely rounding the micro focus rectangle coordinates in QGraphicsView::inputMethodQuery(). (The Qt::ImMicroFocus query returns a QRectF from QGraphicsScene, which is the result of querying QDeclarativeTextEdit and mapping it to the scene.) Auto-test included. Reviewed-by: leo Reviewed-by: bnilsen Task-number: QTCOMPONENTS-288 Task-number: QTBUG-16063 --- src/gui/graphicsview/qgraphicsview.cpp | 2 +- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 39 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index a566c8e..2acea8a 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -2494,7 +2494,7 @@ QVariant QGraphicsView::inputMethodQuery(Qt::InputMethodQuery query) const QVariant value = d->scene->inputMethodQuery(query); if (value.type() == QVariant::RectF) - value = mapFromScene(value.toRectF()).boundingRect(); + value = d->mapRectFromScene(value.toRectF()); else if (value.type() == QVariant::PointF) value = mapFromScene(value.toPointF()); else if (value.type() == QVariant::Rect) diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 0a9633f..e1fbaee 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -246,6 +246,7 @@ private slots: void QTBUG_4151_clipAndIgnore(); void QTBUG_5859_exposedRect(); void QTBUG_7438_cursor(); + void QTBUG_16063_microFocusRect(); public slots: void dummySlot() {} @@ -4450,5 +4451,43 @@ void tst_QGraphicsView::QTBUG_7438_cursor() #endif } +class IMItem : public QGraphicsRectItem +{ +public: + IMItem(QGraphicsItem *parent = 0): + QGraphicsRectItem(mf.adjusted(-5, -5, 5, 5), parent) + { + setFlag(QGraphicsItem::ItemIsFocusable, true); + setFlag(QGraphicsItem::ItemAcceptsInputMethod, true); + } + + QVariant inputMethodQuery(Qt::InputMethodQuery query) const + { + return mf; + } + + static QRectF mf; +}; + +QRectF IMItem::mf(1.5, 1.6, 10, 10); + +void tst_QGraphicsView::QTBUG_16063_microFocusRect() +{ + QGraphicsScene scene; + IMItem *item = new IMItem(); + scene.addItem(item); + + QGraphicsView view(&scene); + + view.setFixedSize(40, 40); + view.show(); + QTest::qWaitForWindowShown(&view); + + scene.setFocusItem(item); + view.setFocus(); + QRectF mfv = view.inputMethodQuery(Qt::ImMicroFocus).toRectF(); + QCOMPARE(mfv, QRectF(13.5, 13.6, 10, 10)); +} + QTEST_MAIN(tst_QGraphicsView) #include "tst_qgraphicsview.moc" -- cgit v0.12 From d5fe82b2ab939727f573429605abd99c039a99d1 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 13 Dec 2010 15:41:16 +0200 Subject: Fix crash when creating more than one QApplication in single test case CBA pointer is stored in static variable and it wasn't cleaned up properly at QApplication destruction, which led to crash. Task-number: QTBUG-15915 Reviewed-by: Sami Merila Reviewed-by: Janne Koskinen --- src/gui/kernel/qapplication_s60.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 8596563..81fa4e6 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1633,6 +1633,13 @@ void qt_cleanup() //Change mouse pointer back S60->wsSession().SetPointerCursorMode(EPointerCursorNone); +#ifdef Q_WS_S60 + // Clear CBA + CEikonEnv::Static()->AppUiFactory()->SwapButtonGroup(0); + delete S60->buttonGroupContainer(); + S60->setButtonGroupContainer(0); +#endif + if (S60->qtOwnsS60Environment) { // Restore the S60 framework trap handler. See qt_init(). User::SetTrapHandler(S60->s60InstalledTrapHandler); -- cgit v0.12 From 50d3c15bd16f4e70327f8de30c8c0df5ed2f995c Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 13 Dec 2010 16:08:36 +0200 Subject: Minor optimization Use already defined factory pointer instead of re-asking it twice. Reviewed-by: Janne Koskinen --- src/gui/kernel/qwidget_s60.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 609307c..d6ad3c3 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -504,7 +504,7 @@ void QWidgetPrivate::show_sys() CEikButtonGroupContainer *cba = CEikButtonGroupContainer::NewL(CEikButtonGroupContainer::ECba, CEikButtonGroupContainer::EHorizontal,ui,R_AVKON_SOFTKEYS_EMPTY_WITH_IDS); - CEikButtonGroupContainer *oldCba = CEikonEnv::Static()->AppUiFactory()->SwapButtonGroup(cba); + CEikButtonGroupContainer *oldCba = factory->SwapButtonGroup(cba); Q_ASSERT(!oldCba); S60->setButtonGroupContainer(cba); @@ -513,7 +513,7 @@ void QWidgetPrivate::show_sys() menuBar->SetMenuType(CEikMenuBar::EMenuOptions); S60->appUi()->AddToStackL(menuBar,ECoeStackPriorityMenu,ECoeStackFlagRefusesFocus); - CEikMenuBar *oldMenu = CEikonEnv::Static()->AppUiFactory()->SwapMenuBar(menuBar); + CEikMenuBar *oldMenu = factory->SwapMenuBar(menuBar); Q_ASSERT(!oldMenu); ) -- cgit v0.12 From 5e0be0aae4aa4011b4dbf7d1d457e4c8b4f6d4dc Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 13 Dec 2010 16:12:25 +0200 Subject: Fix qapplication autotest deployment Necessary default deployment was getting removed from qapplication test Task-number: QTBUG-15915 Reviewed-by: Janne Koskinen --- tests/auto/qapplication/test/test.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qapplication/test/test.pro b/tests/auto/qapplication/test/test.pro index 2c54c37..d946e7e 100644 --- a/tests/auto/qapplication/test/test.pro +++ b/tests/auto/qapplication/test/test.pro @@ -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 } -- cgit v0.12 From 44911b0d44f4840e0d7678f8de7227a3a4018d34 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 13 Dec 2010 16:15:51 +0200 Subject: Non-hacky fix for qwidget autotest Turns out there is a nice way for getting current CBA, CEikButtonGroupContainer::Current(), so using that instead of the previous hack. Task-number: QTBUG-15915 Reviewed-by: Janne Koskinen --- tests/auto/qwidget/tst_qwidget.cpp | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 6069383..d611225 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -10029,28 +10029,6 @@ 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 @@ -10083,7 +10061,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 = cba(); + CEikButtonGroupContainer* buttonGroup = CEikButtonGroupContainer::Current(); QVERIFY(buttonGroup->IsVisible()); } @@ -10100,7 +10078,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 = cba(); + CEikButtonGroupContainer *buttonGroup = CEikButtonGroupContainer::Current(); //Enter widget.showNormal(); @@ -10154,7 +10132,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 = cba(); + CEikButtonGroupContainer *buttonGroup = CEikButtonGroupContainer::Current(); //Enter widget.showNormal(); @@ -10210,7 +10188,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 = cba(); + CEikButtonGroupContainer *buttonGroup = CEikButtonGroupContainer::Current(); //Enter widget.showNormal(); @@ -10266,7 +10244,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 = cba(); + CEikButtonGroupContainer *buttonGroup = CEikButtonGroupContainer::Current(); //Enter widget.showMaximized(); -- cgit v0.12 From b8f639f27a05043f9f9ac371352508d6527f0123 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 10 Dec 2010 10:00:54 +0100 Subject: Comment a bit more the timer ID allocation code. Also add the notes for where to place .loadAcquire when that function exists. Reviewed-By: Bradley T. Hughes --- src/corelib/kernel/qabstracteventdispatcher.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index bcf4477..1c1c6e3 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -120,11 +120,20 @@ void QAbstractEventDispatcherPrivate::init() } } +// Timer IDs are implemented using a free-list; +// there's a vector initialized with: +// X[i] = i + 1 +// and nextFreeTimerId starts with 1. +// +// Allocating a timer ID involves taking the ID from +// X[nextFreeTimerId] +// updating nextFreeTimerId to this value and returning the old value +// (continues below). int QAbstractEventDispatcherPrivate::allocateTimerId() { int timerId, newTimerId; do { - timerId = nextFreeTimerId; + timerId = nextFreeTimerId; //.loadAcquire(); // ### FIXME Proper memory ordering semantics // which bucket are we looking in? int which = timerId & 0x00ffffff; @@ -148,6 +157,17 @@ int QAbstractEventDispatcherPrivate::allocateTimerId() return timerId; } +// Releasing a timer ID requires putting the current ID back in the vector; +// we do it by setting: +// X[timerId] = nextFreeTimerId; +// then we update nextFreeTimerId to the timer we've just released +// +// The extra code in allocateTimerId and releaseTimerId are ABA prevention +// and bucket memory. The buckets are simply to make sure we allocate only +// the necessary number of timers. See above. +// +// ABA prevention simply adds a value to 7 of the top 8 bits when resetting +// nextFreeTimerId. void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId) { int which = timerId & 0x00ffffff; @@ -157,7 +177,7 @@ void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId) int freeId, newTimerId; do { - freeId = nextFreeTimerId; + freeId = nextFreeTimerId;//.loadAcquire(); // ### FIXME Proper memory ordering semantics b[at] = freeId & 0x00ffffff; newTimerId = prepareNewValueWithSerialNumber(freeId, timerId); -- cgit v0.12 From f0a892a46fdc438277c8b401c267db4bd92aec1b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 13 Dec 2010 14:50:07 +0100 Subject: Fix ABA problem with: the serial must be updated on all accesses The nextFreeTimerId's serial counter was only being updated on timer ID releasing. It needs to be updated on allocation too. Reviewed-by: Bradley T. Hughes --- src/corelib/kernel/qabstracteventdispatcher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index 1c1c6e3..5619921 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -151,7 +151,7 @@ int QAbstractEventDispatcherPrivate::allocateTimerId() } } - newTimerId = b[at]; + newTimerId = prepareNewValueWithSerialNumber(timerId, b[at]); } while (!nextFreeTimerId.testAndSetRelaxed(timerId, newTimerId)); return timerId; -- cgit v0.12 From a02a747a9d5294127dfe3e676a2759e228257e70 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 13 Dec 2010 14:58:16 +0100 Subject: Use constants the timer ID masks instead of values everywhere Reviewed-By: Bradley T. Hughes --- src/corelib/kernel/qabstracteventdispatcher.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index 5619921..002d360 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -77,10 +77,14 @@ Q_DESTRUCTOR_FUNCTION(timerIdsDestructorFunction) static QBasicAtomicInt nextFreeTimerId = Q_BASIC_ATOMIC_INITIALIZER(1); +static const int TimerIdMask = 0x00ffffff; +static const int TimerSerialMask = ~TimerIdMask & ~0x80000000; +static const int TimerSerialCounter = TimerIdMask + 1; + // avoid the ABA-problem by using 7 of the top 8 bits of the timerId as a serial number static inline int prepareNewValueWithSerialNumber(int oldId, int newId) { - return (newId & 0x00FFFFFF) | ((oldId + 0x01000000) & 0x7f000000); + return (newId & TimerIdMask) | ((oldId + TimerSerialCounter) & TimerSerialMask); } static inline int bucketOffset(int timerId) @@ -136,7 +140,7 @@ int QAbstractEventDispatcherPrivate::allocateTimerId() timerId = nextFreeTimerId; //.loadAcquire(); // ### FIXME Proper memory ordering semantics // which bucket are we looking in? - int which = timerId & 0x00ffffff; + int which = timerId & TimerIdMask; int bucket = bucketOffset(which); int at = bucketIndex(bucket, which); int *b = timerIds[bucket]; @@ -170,7 +174,7 @@ int QAbstractEventDispatcherPrivate::allocateTimerId() // nextFreeTimerId. void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId) { - int which = timerId & 0x00ffffff; + int which = timerId & TimerIdMask; int bucket = bucketOffset(which); int at = bucketIndex(bucket, which); int *b = timerIds[bucket]; @@ -178,7 +182,7 @@ void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId) int freeId, newTimerId; do { freeId = nextFreeTimerId;//.loadAcquire(); // ### FIXME Proper memory ordering semantics - b[at] = freeId & 0x00ffffff; + b[at] = freeId & TimerIdMask; newTimerId = prepareNewValueWithSerialNumber(freeId, timerId); } while (!nextFreeTimerId.testAndSetRelease(freeId, newTimerId)); -- cgit v0.12 From bd9d5c80235ce6d1b005df96c3058b75e82bd6f0 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 13 Dec 2010 15:02:27 +0100 Subject: Add a small protection against releasing a timer twice. The cell corresponding to an allocated timer ID in the free list is unused (because the ID isn't free). So use it to store an invalid value that we can check against the user's value. This provides some protection against a given timer being released twice. Since we store the serial counter of the nextFreeTimerId, getting the same ID twice is a 1-in-128 chance. Reviewed-By: Bradley T. Hughes --- src/corelib/kernel/qabstracteventdispatcher.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index 002d360..bf675a7 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -132,18 +132,24 @@ void QAbstractEventDispatcherPrivate::init() // Allocating a timer ID involves taking the ID from // X[nextFreeTimerId] // updating nextFreeTimerId to this value and returning the old value +// +// When the timer ID is allocated, its cell in the vector is unused (it's a +// free list). As an added protection, we use the cell to store an invalid +// (negative) value that we can later check for integrity. +// // (continues below). int QAbstractEventDispatcherPrivate::allocateTimerId() { int timerId, newTimerId; + int at, *b; do { timerId = nextFreeTimerId; //.loadAcquire(); // ### FIXME Proper memory ordering semantics // which bucket are we looking in? int which = timerId & TimerIdMask; int bucket = bucketOffset(which); - int at = bucketIndex(bucket, which); - int *b = timerIds[bucket]; + at = bucketIndex(bucket, which); + b = timerIds[bucket]; if (!b) { // allocate a new bucket @@ -158,6 +164,8 @@ int QAbstractEventDispatcherPrivate::allocateTimerId() newTimerId = prepareNewValueWithSerialNumber(timerId, b[at]); } while (!nextFreeTimerId.testAndSetRelaxed(timerId, newTimerId)); + b[at] = -timerId; + return timerId; } @@ -179,6 +187,8 @@ void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId) int at = bucketIndex(bucket, which); int *b = timerIds[bucket]; + Q_ASSERT(b[at] == -timerId); + int freeId, newTimerId; do { freeId = nextFreeTimerId;//.loadAcquire(); // ### FIXME Proper memory ordering semantics -- 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 8d0863f175199384e41a00fa18a9ea7d177c7f0e Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 13 Dec 2010 22:57:17 +0100 Subject: qrgb565: Use the trivial qt_memconvert() and qt_rectconvert() Use memcpy() instead of the generic conversion routines where both template arguments are qrgb565. Yields a massive performance gain for tiling opaque (background) images in WebKit on 16-bit displays. This was previously restricted to Q_WS_QWS for some unknown reason. Reviewed-by: Benjamin Poulain --- src/gui/painting/qdrawhelper_p.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 0cc2e40..33fd21e 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -1684,9 +1684,7 @@ QT_TRIVIAL_MEMCONVERT_IMPL(qrgb888) QT_TRIVIAL_MEMCONVERT_IMPL(qargb6666) QT_TRIVIAL_MEMCONVERT_IMPL(qrgb666) QT_TRIVIAL_MEMCONVERT_IMPL(quint16) -#ifdef Q_WS_QWS QT_TRIVIAL_MEMCONVERT_IMPL(qrgb565) -#endif QT_TRIVIAL_MEMCONVERT_IMPL(qargb8565) QT_TRIVIAL_MEMCONVERT_IMPL(qargb8555) QT_TRIVIAL_MEMCONVERT_IMPL(qrgb555) @@ -1783,9 +1781,7 @@ QT_RECTCONVERT_TRIVIAL_IMPL(quint32) QT_RECTCONVERT_TRIVIAL_IMPL(qrgb888) QT_RECTCONVERT_TRIVIAL_IMPL(qargb6666) QT_RECTCONVERT_TRIVIAL_IMPL(qrgb666) -#ifdef Q_WS_QWS QT_RECTCONVERT_TRIVIAL_IMPL(qrgb565) -#endif QT_RECTCONVERT_TRIVIAL_IMPL(qargb8565) QT_RECTCONVERT_TRIVIAL_IMPL(quint16) QT_RECTCONVERT_TRIVIAL_IMPL(qargb8555) -- cgit v0.12 From 2eee49127b80b5b56c605f76ccea004b03d89577 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Tue, 14 Dec 2010 11:22:50 +1000 Subject: Remove active selection when TextEdit loses focus Task-number: QTBUG-15341 Reviewed-by: Yann Bodson --- .../graphicsitems/qdeclarativetextedit.cpp | 14 ++++++++ .../graphicsitems/qdeclarativetextedit_p.h | 1 + .../tst_qdeclarativetextedit.cpp | 40 ++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index e05f4e4..1042cf1 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -994,6 +994,20 @@ void QDeclarativeTextEditPrivate::focusChanged(bool hasFocus) QDeclarativeItemPrivate::focusChanged(hasFocus); } +void QDeclarativeTextEdit::focusOutEvent(QFocusEvent *event) +{ + Q_D(QDeclarativeTextEdit); + if (event->reason() != Qt::ActiveWindowFocusReason + && event->reason() != Qt::PopupFocusReason) { + QTextCursor cursor = d->control->textCursor(); + if (cursor.hasSelection()) { + cursor.clearSelection(); + d->control->setTextCursor(cursor); + } + } + QDeclarativePaintedItem::focusOutEvent(event); +} + /*! \qmlmethod void TextEdit::selectAll() diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h index 68fde3d..6826cb5 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h @@ -249,6 +249,7 @@ protected: void keyPressEvent(QKeyEvent *); void keyReleaseEvent(QKeyEvent *); void focusInEvent(QFocusEvent *event); + void focusOutEvent(QFocusEvent *event); // mouse filter? void mousePressEvent(QGraphicsSceneMouseEvent *event); diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index a7971cc..ed02451 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -110,6 +110,7 @@ private slots: void mouseSelection_data(); void mouseSelection(); void inputMethodHints(); + void clearSelectionOnFocusLost(); void cursorDelegate(); void delegateLoading_data(); @@ -748,6 +749,45 @@ void tst_qdeclarativetextedit::inputMethodHints() QVERIFY(textEditObject->inputMethodHints() & Qt::ImhUppercaseOnly); } +// QTBUG-15341 +void tst_qdeclarativetextedit::clearSelectionOnFocusLost() +{ + + // create a visible scene with two text edits + QGraphicsScene scene; + QGraphicsView view(&scene); + QDeclarativeTextEdit edit; + QDeclarativeTextEdit secondEdit; + edit.setText("Hello world!"); + scene.addItem(&edit); + scene.addItem(&secondEdit); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&view)); + + int index = 0; + while (index < Qt::NoFocusReason) { + + // focus the first text edit and select text + edit.setFocus(true); + edit.selectAll(); + QVERIFY(edit.hasActiveFocus() && !secondEdit.hasActiveFocus()); + QCOMPARE(edit.selectedText().size(), 12); + + // lose focus in the first text edit + qobject_cast(&secondEdit)->setFocus(Qt::FocusReason(index)); + QVERIFY(!edit.hasActiveFocus() && secondEdit.hasActiveFocus()); + + // depending on the focus reason, selection should now be cleared + bool clearSelection = (index != Qt::ActiveWindowFocusReason && index != Qt::PopupFocusReason); + QCOMPARE(edit.selectedText().isEmpty(), clearSelection); + index++; + } +} + + + void tst_qdeclarativetextedit::cursorDelegate() { QDeclarativeView* view = createView(SRCDIR "/data/cursorTest.qml"); -- cgit v0.12 From e4257e41c1c9e764d27f1c61f9173c34444236f3 Mon Sep 17 00:00:00 2001 From: Aaron McCarthy Date: Tue, 14 Dec 2010 14:27:38 +1000 Subject: Abort working replies with error when network session fails. Otherwise the connections will stay in a zombie state until the TCP keep alive timer times out in a couple of hours. Task-number: Maemo 201619 --- src/network/access/qnetworkreplyimpl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index cf6e674..3d1df06 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -271,8 +271,8 @@ void QNetworkReplyImplPrivate::_q_networkSessionConnected() void QNetworkReplyImplPrivate::_q_networkSessionFailed() { - // Abort waiting replies. - if (state == WaitingForSession) { + // Abort waiting and working replies. + if (state == WaitingForSession || state == Working) { state = Working; error(QNetworkReplyImpl::UnknownNetworkError, QCoreApplication::translate("QNetworkReply", "Network session error.")); -- cgit v0.12 From f58cf707dd5668ca2849f457e951a9cef7d1d544 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Tue, 14 Dec 2010 15:27:23 +1000 Subject: Revert a fix made for bug QTBUG-15341 Reverted a commit 2eee49127b80b5b56c605f76ccea004b03d89577 "Remove active selection when TextEdit loses focus". Contrary to TextInput, by default TextEdit keeps the selection visible when the editor loses active focus. If this is not wanted, a property called persistentSelection can be set false to make selection dependant on the focus. --- .../graphicsitems/qdeclarativetextedit.cpp | 14 -------- .../graphicsitems/qdeclarativetextedit_p.h | 1 - .../tst_qdeclarativetextedit.cpp | 40 ---------------------- 3 files changed, 55 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index 1042cf1..e05f4e4 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -994,20 +994,6 @@ void QDeclarativeTextEditPrivate::focusChanged(bool hasFocus) QDeclarativeItemPrivate::focusChanged(hasFocus); } -void QDeclarativeTextEdit::focusOutEvent(QFocusEvent *event) -{ - Q_D(QDeclarativeTextEdit); - if (event->reason() != Qt::ActiveWindowFocusReason - && event->reason() != Qt::PopupFocusReason) { - QTextCursor cursor = d->control->textCursor(); - if (cursor.hasSelection()) { - cursor.clearSelection(); - d->control->setTextCursor(cursor); - } - } - QDeclarativePaintedItem::focusOutEvent(event); -} - /*! \qmlmethod void TextEdit::selectAll() diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h index 6826cb5..68fde3d 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h @@ -249,7 +249,6 @@ protected: void keyPressEvent(QKeyEvent *); void keyReleaseEvent(QKeyEvent *); void focusInEvent(QFocusEvent *event); - void focusOutEvent(QFocusEvent *event); // mouse filter? void mousePressEvent(QGraphicsSceneMouseEvent *event); diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index ed02451..a7971cc 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -110,7 +110,6 @@ private slots: void mouseSelection_data(); void mouseSelection(); void inputMethodHints(); - void clearSelectionOnFocusLost(); void cursorDelegate(); void delegateLoading_data(); @@ -749,45 +748,6 @@ void tst_qdeclarativetextedit::inputMethodHints() QVERIFY(textEditObject->inputMethodHints() & Qt::ImhUppercaseOnly); } -// QTBUG-15341 -void tst_qdeclarativetextedit::clearSelectionOnFocusLost() -{ - - // create a visible scene with two text edits - QGraphicsScene scene; - QGraphicsView view(&scene); - QDeclarativeTextEdit edit; - QDeclarativeTextEdit secondEdit; - edit.setText("Hello world!"); - scene.addItem(&edit); - scene.addItem(&secondEdit); - view.show(); - QApplication::setActiveWindow(&view); - QTest::qWaitForWindowShown(&view); - QTRY_COMPARE(QApplication::activeWindow(), static_cast(&view)); - - int index = 0; - while (index < Qt::NoFocusReason) { - - // focus the first text edit and select text - edit.setFocus(true); - edit.selectAll(); - QVERIFY(edit.hasActiveFocus() && !secondEdit.hasActiveFocus()); - QCOMPARE(edit.selectedText().size(), 12); - - // lose focus in the first text edit - qobject_cast(&secondEdit)->setFocus(Qt::FocusReason(index)); - QVERIFY(!edit.hasActiveFocus() && secondEdit.hasActiveFocus()); - - // depending on the focus reason, selection should now be cleared - bool clearSelection = (index != Qt::ActiveWindowFocusReason && index != Qt::PopupFocusReason); - QCOMPARE(edit.selectedText().isEmpty(), clearSelection); - index++; - } -} - - - void tst_qdeclarativetextedit::cursorDelegate() { QDeclarativeView* view = createView(SRCDIR "/data/cursorTest.qml"); -- cgit v0.12 From c34225b62ea2dd2a545baf2ade41629be6a55473 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Tue, 14 Dec 2010 13:59:36 +1000 Subject: Clarify that XmlListModel is read only --- src/declarative/util/qdeclarativexmllistmodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index ce5b483..49a12b1 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -503,9 +503,9 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty Date: Tue, 14 Dec 2010 16:38:02 +1000 Subject: Docs: implications of creating network access managers in other threads Task-number: QTBUG-16032 --- .../qdeclarativenetworkaccessmanagerfactory.cpp | 53 ++++++++++++++-------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/src/declarative/qml/qdeclarativenetworkaccessmanagerfactory.cpp b/src/declarative/qml/qdeclarativenetworkaccessmanagerfactory.cpp index d22798d..36e9721 100644 --- a/src/declarative/qml/qdeclarativenetworkaccessmanagerfactory.cpp +++ b/src/declarative/qml/qdeclarativenetworkaccessmanagerfactory.cpp @@ -46,27 +46,44 @@ QT_BEGIN_NAMESPACE /*! \class QDeclarativeNetworkAccessManagerFactory \since 4.7 - \brief The QDeclarativeNetworkAccessManagerFactory class provides a factory for QNetworkAccessManager for use by a Qt Declarative engine. + \brief The QDeclarativeNetworkAccessManagerFactory class creates QNetworkAccessManager instances for a QML engine. - QNetworkAccessManager is used for all network access by QML. - By implementing a factory it is possible to create custom - QNetworkAccessManager with specialized caching, proxy and - cookie support. + A QML engine uses QNetworkAccessManager for all network access. + By implementing a factory, it is possible to provide the QML engine + with custom QNetworkAccessManager instances with specialized caching, + proxy and cookies support. - To implement a factory, subclass QDeclarativeNetworkAccessManagerFactory and implement - the create() method. + To implement a factory, subclass QDeclarativeNetworkAccessManagerFactory and + implement the virtual create() method, then assign it to the relevant QML + engine using QDeclarativeEngine::setNetworkAccessManagerFactory(). - To use a factory, assign it to the relevant QDeclarativeEngine using - QDeclarativeEngine::setNetworkAccessManagerFactory(). + Note the QML engine may create QNetworkAccessManager instances + from multiple threads. Because of this, the implementation of the create() + method must be \l{Reentrancy and Thread-Safety}{reentrant}. In addition, + the developer should be careful if the signals of the object to be + returned from create() are connected to the slots of an object that may + be created in a different thread: - Note: the create() method may be called by multiple threads, so ensure the - implementation of this method is reentrant. + \list + \o The QML engine internally handles all requests, and cleans up any + QNetworkReply objects it creates. Receiving the + QNetworkAccessManager::finished() signal in another thread may not + provide the receiver with a valid reply object if it has already + been deleted. + \o Authentication details provided to QNetworkAccessManager::authenticationRequired() + must be provided immediately, so this signal cannot be connected as a + Qt::QueuedConnection (or as the default Qt::AutoConnection from another + thread). + \endlist + + For more information about signals and threads, see + \l {Threads and QObjects} and \l {Signals and Slots Across Threads}. - \sa QDeclarativeEngine::setNetworkAccessManagerFactory(), {declarative/cppextensions/networkaccessmanagerfactory}{NetworkAccessManagerFactory example} + \sa {declarative/cppextensions/networkaccessmanagerfactory}{NetworkAccessManagerFactory example} */ /*! - The destructor is empty. + Destroys the factory. The default implementation does nothing. */ QDeclarativeNetworkAccessManagerFactory::~QDeclarativeNetworkAccessManagerFactory() { @@ -75,13 +92,9 @@ QDeclarativeNetworkAccessManagerFactory::~QDeclarativeNetworkAccessManagerFactor /*! \fn QNetworkAccessManager *QDeclarativeNetworkAccessManagerFactory::create(QObject *parent) - Implement this method to create a QNetworkAccessManager with \a parent. - This allows proxies, caching and cookie support to be setup appropriately. - - This method must return a new QNetworkAccessManager each time it is called. - The parent of the QNetworkAccessManager must be the \a parent provided. - The QNetworkAccessManager(s) created by this - function will be destroyed automatically when their parent is destroyed. + Creates and returns a network access manager with the specified \a parent. + This method must return a new QNetworkAccessManager instance each time + it is called. Note: this method may be called by multiple threads, so ensure the implementation of this method is reentrant. -- 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 725716bcf158988ac664da8f8bcd2d9a8e91a916 Mon Sep 17 00:00:00 2001 From: axis Date: Fri, 10 Dec 2010 10:32:11 +0100 Subject: Fixed several compile and deployment issues in the mmf phonon plugin. RevBy: Trust me --- src/3rdparty/phonon/mmf/abstractaudioeffect.h | 2 +- src/3rdparty/phonon/mmf/audioequalizer.cpp | 2 +- src/3rdparty/phonon/mmf/bassboost.cpp | 2 +- src/3rdparty/phonon/mmf/environmentalreverb.cpp | 2 +- src/3rdparty/phonon/mmf/loudness.cpp | 2 +- src/3rdparty/phonon/mmf/stereowidening.cpp | 2 +- src/plugins/phonon/mmf/mmf.pro | 4 ++-- src/s60installs/s60installs.pro | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.h b/src/3rdparty/phonon/mmf/abstractaudioeffect.h index 8879636..70adcf6 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.h +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.h @@ -21,7 +21,7 @@ along with this library. If not, see . #include -#include +#include #include diff --git a/src/3rdparty/phonon/mmf/audioequalizer.cpp b/src/3rdparty/phonon/mmf/audioequalizer.cpp index 28433f6..1d2bbd4 100644 --- a/src/3rdparty/phonon/mmf/audioequalizer.cpp +++ b/src/3rdparty/phonon/mmf/audioequalizer.cpp @@ -16,7 +16,7 @@ along with this library. If not, see . */ -#include +#include #include "audioequalizer.h" QT_BEGIN_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/bassboost.cpp b/src/3rdparty/phonon/mmf/bassboost.cpp index 81d9208..67076f6 100644 --- a/src/3rdparty/phonon/mmf/bassboost.cpp +++ b/src/3rdparty/phonon/mmf/bassboost.cpp @@ -16,7 +16,7 @@ along with this library. If not, see . */ -#include +#include #include "bassboost.h" QT_BEGIN_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/environmentalreverb.cpp b/src/3rdparty/phonon/mmf/environmentalreverb.cpp index c500385..d4f5223 100644 --- a/src/3rdparty/phonon/mmf/environmentalreverb.cpp +++ b/src/3rdparty/phonon/mmf/environmentalreverb.cpp @@ -16,7 +16,7 @@ along with this library. If not, see . */ -#include +#include #include "environmentalreverb.h" QT_BEGIN_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/loudness.cpp b/src/3rdparty/phonon/mmf/loudness.cpp index 22d7518..ca05ab0 100644 --- a/src/3rdparty/phonon/mmf/loudness.cpp +++ b/src/3rdparty/phonon/mmf/loudness.cpp @@ -16,7 +16,7 @@ along with this library. If not, see . */ -#include +#include #include "loudness.h" QT_BEGIN_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/stereowidening.cpp b/src/3rdparty/phonon/mmf/stereowidening.cpp index e452160..f90651b 100644 --- a/src/3rdparty/phonon/mmf/stereowidening.cpp +++ b/src/3rdparty/phonon/mmf/stereowidening.cpp @@ -16,7 +16,7 @@ along with this library. If not, see . */ -#include +#include #include "stereowidening.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/phonon/mmf/mmf.pro b/src/plugins/phonon/mmf/mmf.pro index 691fc80..5d7b61d 100644 --- a/src/plugins/phonon/mmf/mmf.pro +++ b/src/plugins/phonon/mmf/mmf.pro @@ -103,7 +103,7 @@ symbian { exists($${EPOCROOT}epoc32/include/mw/downloadmgrclient.h) { HEADERS += $$PHONON_MMF_DIR/download.h SOURCES += $$PHONON_MMF_DIR/download.cpp - LIBS += -ldownloadmgr + LIBS += -lDownloadMgr DEFINES += PHONON_MMF_PROGRESSIVE_DOWNLOAD } } @@ -125,7 +125,7 @@ symbian { LIBS += -lmediaclientaudiostream # For CMdaAudioOutputStream # These are for effects. - LIBS += -lAudioEqualizerEffect -lBassBoostEffect -lDistanceAttenuationEffect -lDopplerBase -lEffectBase -lEnvironmentalReverbEffect -lListenerDopplerEffect -lListenerLocationEffect -lListenerOrientationEffect -lLocationBase -lLoudnessEffect -lOrientationBase -lSourceDopplerEffect -lSourceLocationEffect -lSourceOrientationEffect -lStereoWideningEffect + LIBS += -lAudioEqualizerEffect -lBassBoostEffect -lDistanceAttenuationEffect -lDopplerbase -lEffectBase -lEnvironmentalReverbEffect -lListenerDopplerEffect -lListenerLocationEffect -lListenerOrientationEffect -lLocationBase -lLoudnessEffect -lOrientationBase -lSourceDopplerEffect -lSourceLocationEffect -lSourceOrientationEffect -lStereoWideningEffect # This is needed for having the .qtplugin file properly created on Symbian. QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/phonon_backend diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index ff67bcf..5a435cd 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -132,7 +132,7 @@ symbian: { codecs_plugins.path = c:$$QT_PLUGINS_BASE_DIR/codecs contains(QT_CONFIG, phonon-backend) { - phonon_backend_plugins.sources += $$QMAKE_LIBDIR_QT/phonon_mmf$${QT_LIBINFIX}.dll + phonon_backend_plugins.sources += $$QT_BUILD_TREE/plugins/phonon_backend/phonon_mmf$${QT_LIBINFIX}.dll phonon_backend_plugins.path = c:$$QT_PLUGINS_BASE_DIR/phonon_backend DEPLOYMENT += phonon_backend_plugins -- cgit v0.12 From 6aa1ab84404c92f2048270b1932fa10cecdcc58d Mon Sep 17 00:00:00 2001 From: axis Date: Fri, 10 Dec 2010 15:35:06 +0100 Subject: Fixed a bug in the input methods on S60 with QGraphicsWebView. The bug happened because we did not expect to receive a call to CancelFepInlineEdit() when the widget had not previously been given any preedit text by S60. However, this can happen, and if it happens at the same time that there is a temporarily visible character in the widget (because it will be obscured as a password a second later), then the temporary character would be discarded. Fixed by checking in the beginning of CancelFepInlineEdit() whether we currently have any temporary preedit text or not, and if we do, we don't clear the contents, since it is the input context itself that generated the preedit text, not S60. Also made sure that the temporary preedit text is committed if we receive a call to UpdateFepInlineTextL(), which may sometimes happen without a call to StartFepInlineEditL(). Task: QT-4314 AutoTest: Included RevBy: Shane Kearns --- src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 8 ++ tests/auto/qinputcontext/qinputcontext.pro | 2 + tests/auto/qinputcontext/tst_qinputcontext.cpp | 141 +++++++++++++++++++++++- 3 files changed, 148 insertions(+), 3 deletions(-) diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 4a1b9b9..686f388 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -657,6 +657,8 @@ void QCoeFepInputContext::UpdateFepInlineTextL(const TDesC& aNewInlineText, if (!w) return; + commitTemporaryPreeditString(); + m_inlinePosition = aPositionOfInsertionPointInInlineText; QList attributes; @@ -694,6 +696,12 @@ void QCoeFepInputContext::SetInlineEditingCursorVisibilityL(TBool aCursorVisibil void QCoeFepInputContext::CancelFepInlineEdit() { + // We are not supposed to ever have a tempPreeditString and a real preedit string + // from S60 at the same time, so it should be safe to rely on this test to determine + // whether we should honor S60's request to clear the text or not. + if (m_hasTempPreeditString) + return; + QList attributes; QInputMethodEvent event(QLatin1String(""), attributes); event.setCommitString(QLatin1String(""), 0, 0); diff --git a/tests/auto/qinputcontext/qinputcontext.pro b/tests/auto/qinputcontext/qinputcontext.pro index ec6831e..4b3ab96 100644 --- a/tests/auto/qinputcontext/qinputcontext.pro +++ b/tests/auto/qinputcontext/qinputcontext.pro @@ -1,6 +1,8 @@ load(qttest_p4) SOURCES += tst_qinputcontext.cpp +contains(QT_CONFIG, webkit):QT += webkit + symbian { LIBS += -lws32 -lcone } diff --git a/tests/auto/qinputcontext/tst_qinputcontext.cpp b/tests/auto/qinputcontext/tst_qinputcontext.cpp index 5a258a9..020f177 100644 --- a/tests/auto/qinputcontext/tst_qinputcontext.cpp +++ b/tests/auto/qinputcontext/tst_qinputcontext.cpp @@ -50,6 +50,13 @@ #include #include #include +#include +#include + +#ifdef QT_WEBKIT_LIB +#include +#include +#endif #ifdef Q_OS_SYMBIAN #include @@ -466,6 +473,115 @@ void tst_QInputContext::focusProxy() QCOMPARE(gic->focusWidget(), &proxy); } +#ifdef QT_WEBKIT_LIB +class AutoWebView : public QWebView +{ + Q_OBJECT + +public: + AutoWebView() + : m_length(0) + , m_mode(QLineEdit::Normal) + { + updatePage(); + } + ~AutoWebView() {} + + void updatePage() + { + // The update might reset the input method parameters. + bool imEnabled = testAttribute(Qt::WA_InputMethodEnabled); + Qt::InputMethodHints hints = inputMethodHints(); + + QString page = "" + "
"; + if (m_mode == QLineEdit::Password) + page = page.arg("password"); + else + page = page.arg("text"); + + if (m_length == 0) + page = page.arg(""); + else + page = page.arg("maxlength=\"" + QString::number(m_length) + "\""); + + setHtml(page); + + setAttribute(Qt::WA_InputMethodEnabled, imEnabled); + setInputMethodHints(hints); + } + void setMaxLength(int length) + { + m_length = length; + updatePage(); + } + void setEchoMode(QLineEdit::EchoMode mode) + { + m_mode = mode; + updatePage(); + } + + int m_length; + QLineEdit::EchoMode m_mode; +}; + +class AutoGraphicsWebView : public QGraphicsView +{ + Q_OBJECT + +public: + AutoGraphicsWebView() + : m_length(0) + , m_mode(QLineEdit::Normal) + { + m_scene.addItem(&m_view); + setScene(&m_scene); + m_view.setFocus(); + updatePage(); + } + ~AutoGraphicsWebView() {} + + void updatePage() + { + // The update might reset the input method parameters. + bool imEnabled = testAttribute(Qt::WA_InputMethodEnabled); + Qt::InputMethodHints hints = inputMethodHints(); + + QString page = "" + "
"; + if (m_mode == QLineEdit::Password) + page = page.arg("password"); + else + page = page.arg("text"); + + if (m_length == 0) + page = page.arg(""); + else + page = page.arg("maxlength=\"" + QString::number(m_length) + "\""); + + m_view.setHtml(page); + + setAttribute(Qt::WA_InputMethodEnabled, imEnabled); + setInputMethodHints(hints); + } + void setMaxLength(int length) + { + m_length = length; + updatePage(); + } + void setEchoMode(QLineEdit::EchoMode mode) + { + m_mode = mode; + updatePage(); + } + + int m_length; + QLineEdit::EchoMode m_mode; + QGraphicsScene m_scene; + QGraphicsWebView m_view; +}; +#endif // QT_WEBKIT_LIB + void tst_QInputContext::symbianTestCoeFepInputContext_data() { #ifdef Q_OS_SYMBIAN @@ -481,6 +597,10 @@ void tst_QInputContext::symbianTestCoeFepInputContext_data() symbianTestCoeFepInputContext_addData(); symbianTestCoeFepInputContext_addData(); symbianTestCoeFepInputContext_addData(); +# ifdef QT_WEBKIT_LIB + symbianTestCoeFepInputContext_addData(); + symbianTestCoeFepInputContext_addData(); +# endif #endif } @@ -1087,13 +1207,28 @@ void tst_QInputContext::symbianTestCoeFepInputContext() editwidget->setAttribute(Qt::WA_InputMethodEnabled, inputMethodEnabled); editwidget->setInputMethodHints(inputMethodHints); - QLineEdit *lineedit = qobject_cast(editwidget); - if (lineedit) { + if (QLineEdit *lineedit = qobject_cast(editwidget)) { if (maxLength > 0) lineedit->setMaxLength(maxLength); lineedit->setEchoMode(echoMode); +#ifdef QT_WEBKIT_LIB + } else if (AutoWebView *webView = qobject_cast(editwidget)) { + if (maxLength > 0) + webView->setMaxLength(maxLength); + webView->setEchoMode(echoMode); + // WebKit disables T9 everywhere. + if (inputMethodEnabled && !(inputMethodHints & Qt::ImhNoPredictiveText)) + return; + } else if (AutoGraphicsWebView *webView = qobject_cast(editwidget)) { + if (maxLength > 0) + webView->setMaxLength(maxLength); + webView->setEchoMode(echoMode); + // WebKit disables T9 everywhere. + if (inputMethodEnabled && !(inputMethodHints & Qt::ImhNoPredictiveText)) + return; +#endif } else if (maxLength > 0 || echoMode != QLineEdit::Normal) { - // Only QLineEdits support these features so don't attempt any tests using those + // Only some widgets support these features so don't attempt any tests using those // on other widgets. return; } -- cgit v0.12 From 284211ccbd2cbdfea46cdf4b8628a1a967271985 Mon Sep 17 00:00:00 2001 From: Michael Dominic K Date: Tue, 14 Dec 2010 10:26:39 +0100 Subject: Prevent ::flush from being called on QGLWindowSurface if no painting happened. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge-request: 2527 Reviewed-by: Harald Fernengel Reviewed-by: Samuel Rødal --- src/opengl/qwindowsurface_gl.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index f64b93c..6749826 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -267,6 +267,7 @@ struct QGLWindowSurfacePrivate int tried_pb : 1; int destructive_swap_buffers : 1; int geometry_updated : 1; + int did_paint : 1; QGLContext *ctx; @@ -330,6 +331,7 @@ QGLWindowSurface::QGLWindowSurface(QWidget *window) d_ptr->glDevice.d = d_ptr; d_ptr->q_ptr = this; d_ptr->geometry_updated = false; + d_ptr->did_paint = false; } QGLWindowSurface::~QGLWindowSurface() @@ -461,6 +463,8 @@ void QGLWindowSurface::beginPaint(const QRegion &) glClearColor(0.0, 0.0, 0.0, 0.0); glClear(clearFlags); } + + d_ptr->did_paint = true; } void QGLWindowSurface::endPaint(const QRegion &rgn) @@ -513,6 +517,13 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & if (d_ptr->geometry_updated) return; + // did_paint is set to true in ::beginPaint. ::beginPaint means that we + // at least cleared the background (= painted something). In EGL API it's a + // mistakte to call swapBuffers if nothing was painted. This check protects + // the flush func from being executed if it's for nothing. + if (! d_ptr->did_paint) + return; + QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget(); Q_ASSERT(parent); @@ -736,6 +747,8 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & ctx->swapBuffers(); else glFlush(); + + d_ptr->did_paint = false; } -- cgit v0.12 From 4d93a606ea0438be8062fda82baf639a9ced78ba Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Tue, 14 Dec 2010 10:28:26 +0100 Subject: Trivial: Fix coding style Fix coding style of merge request --- src/opengl/qwindowsurface_gl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 6749826..7dc7dc7 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -521,7 +521,7 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & // at least cleared the background (= painted something). In EGL API it's a // mistakte to call swapBuffers if nothing was painted. This check protects // the flush func from being executed if it's for nothing. - if (! d_ptr->did_paint) + if (!d_ptr->did_paint) return; QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget(); -- cgit v0.12 From e864a530a5c48459c433518ff6ad893f33ec93d8 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 14 Dec 2010 10:57:11 +0100 Subject: Fix failing tst_QGraphicsView::QTBUG_16063_microFocusRect auto-test This ammends commit 0af1f5508e165f3b494ab236cb1cdf1b0edcffa5. Reviewed-by: trust me --- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index e1fbaee..e259177 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -4455,7 +4455,7 @@ class IMItem : public QGraphicsRectItem { public: IMItem(QGraphicsItem *parent = 0): - QGraphicsRectItem(mf.adjusted(-5, -5, 5, 5), parent) + QGraphicsRectItem(QRectF(0, 0, 20, 20), parent) { setFlag(QGraphicsItem::ItemIsFocusable, true); setFlag(QGraphicsItem::ItemAcceptsInputMethod, true); @@ -4486,7 +4486,7 @@ void tst_QGraphicsView::QTBUG_16063_microFocusRect() scene.setFocusItem(item); view.setFocus(); QRectF mfv = view.inputMethodQuery(Qt::ImMicroFocus).toRectF(); - QCOMPARE(mfv, QRectF(13.5, 13.6, 10, 10)); + QCOMPARE(mfv, IMItem::mf.translated(-view.mapToScene(view.sceneRect().toRect()).boundingRect().topLeft())); } QTEST_MAIN(tst_QGraphicsView) -- cgit v0.12 From 736b8205158dd7b98af862a029b273dff6fb716d Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 8 Dec 2010 13:23:23 +0100 Subject: QApplication: fix crash exit whith native windows Regression introduced in 8dd8db250d92521fda619bdcf3e1c859b37b2da0 Patch comes from the task Task-number: QTBUG-15774 --- src/gui/kernel/qapplication.cpp | 6 +++--- tests/auto/qapplication/modal/main.cpp | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index a4ae46b..b4ff7c4 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -1101,6 +1101,9 @@ QApplication::~QApplication() QApplicationPrivate::is_app_closing = true; QApplicationPrivate::is_app_running = false; + delete QWidgetPrivate::mapper; + QWidgetPrivate::mapper = 0; + // delete all widgets if (QWidgetPrivate::allWidgets) { QWidgetSet *mySet = QWidgetPrivate::allWidgets; @@ -1130,9 +1133,6 @@ QApplication::~QApplication() delete d->ignore_cursor; d->ignore_cursor = 0; #endif - delete QWidgetPrivate::mapper; - QWidgetPrivate::mapper = 0; - delete QApplicationPrivate::app_pal; QApplicationPrivate::app_pal = 0; delete QApplicationPrivate::sys_pal; diff --git a/tests/auto/qapplication/modal/main.cpp b/tests/auto/qapplication/modal/main.cpp index f9d8fb4..3eaaa0d 100644 --- a/tests/auto/qapplication/modal/main.cpp +++ b/tests/auto/qapplication/modal/main.cpp @@ -47,6 +47,7 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); + QApplication::setAttribute(Qt::AA_NativeWindows); //QTBUG-15774 base *b = new base(); return app.exec(); } -- 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 From 3778c3f5208f3db99d6b23a2a3c4abf1fe2ec64f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Tue, 14 Dec 2010 11:46:57 +0100 Subject: Make sure that d->init() is called from both ctors. QGraphicsLayout uses the protected ctor that did not call d->init(), so all its subclasses was potentially suffering from this. Task-number: QTBUG-15333 Reviewed-by: John Tapsell --- src/gui/graphicsview/qgraphicslayoutitem.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicslayoutitem.cpp b/src/gui/graphicsview/qgraphicslayoutitem.cpp index df13039..b11dc9e 100644 --- a/src/gui/graphicsview/qgraphicslayoutitem.cpp +++ b/src/gui/graphicsview/qgraphicslayoutitem.cpp @@ -129,7 +129,6 @@ void QGraphicsLayoutItemPrivate::init() { sizeHintCacheDirty = true; sizeHintWithConstraintCacheDirty = true; - sizePolicy = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); } /*! @@ -400,6 +399,7 @@ QGraphicsLayoutItem::QGraphicsLayoutItem(QGraphicsLayoutItem *parent, bool isLay { Q_D(QGraphicsLayoutItem); d->init(); + sizePolicy = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); d->q_ptr = this; } @@ -410,6 +410,7 @@ QGraphicsLayoutItem::QGraphicsLayoutItem(QGraphicsLayoutItemPrivate &dd) : d_ptr(&dd) { Q_D(QGraphicsLayoutItem); + d->init(); d->q_ptr = this; } -- cgit v0.12 From 542fe69cdeff81acb8f986ff4606043613345dc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Tue, 14 Dec 2010 13:03:43 +0100 Subject: Fix to commit 3778c3f5208f3db99d6b23a2a3c4abf1fe2ec64f This is what could happen if you go to lunch before comitting. --- src/gui/graphicsview/qgraphicslayoutitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicslayoutitem.cpp b/src/gui/graphicsview/qgraphicslayoutitem.cpp index b11dc9e..0a24aae 100644 --- a/src/gui/graphicsview/qgraphicslayoutitem.cpp +++ b/src/gui/graphicsview/qgraphicslayoutitem.cpp @@ -399,7 +399,7 @@ QGraphicsLayoutItem::QGraphicsLayoutItem(QGraphicsLayoutItem *parent, bool isLay { Q_D(QGraphicsLayoutItem); d->init(); - sizePolicy = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + d->sizePolicy = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); d->q_ptr = this; } -- cgit v0.12 From 0727539b89898544047d32e63633790fa0c44b5a Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 14 Dec 2010 14:03:08 +0100 Subject: Don't delete FBO when resetting glyph cache When the glyph cache is cleared because the max texture size has been exceeded, we shouldn't delete the fbo as this is only created in setContext() and will thus not be recreated. All subsequent resizing of the cache will fail. Task-number: QT-3971 Reviewed-by: Samuel --- src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 66445cd..1b879c3 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -83,13 +83,9 @@ void QGLTextureGlyphCache::clear() if (ctx) { QGLShareContextScope scope(ctx); - if (!ctx->d_ptr->workaround_brokenFBOReadBack) - glDeleteFramebuffers(1, &m_fbo); - if (m_width || m_height) glDeleteTextures(1, &m_texture); - m_fbo = 0; m_texture = 0; m_width = 0; m_height = 0; @@ -105,6 +101,13 @@ void QGLTextureGlyphCache::clear() QGLTextureGlyphCache::~QGLTextureGlyphCache() { + if (ctx) { + QGLShareContextScope scope(ctx); + + if (!ctx->d_ptr->workaround_brokenFBOReadBack) + glDeleteFramebuffers(1, &m_fbo); + } + clear(); } -- cgit v0.12 From 3c20e7a08aadb08955603d004054a3adacff180f Mon Sep 17 00:00:00 2001 From: aavit Date: Tue, 14 Dec 2010 15:24:20 +0100 Subject: Make the lancelot/baseline test system generically usable To facilitate usage outside of tst_lancelot: - Added new QBaseLineTest simple API - Added "tst_baselineexample" autotest to show usage - Improved reporting - Results from all testfunctions collected in same report --- tests/arthur/baselineserver/src/baselineserver.cpp | 84 +++--- tests/arthur/baselineserver/src/baselineserver.h | 12 +- tests/arthur/baselineserver/src/baselineserver.pro | 4 +- tests/arthur/baselineserver/src/htmlpage.cpp | 244 ----------------- tests/arthur/baselineserver/src/htmlpage.h | 79 ------ tests/arthur/baselineserver/src/main.cpp | 2 +- tests/arthur/baselineserver/src/report.cpp | 296 +++++++++++++++++++++ tests/arthur/baselineserver/src/report.h | 90 +++++++ tests/arthur/common/baselineprotocol.cpp | 5 + tests/arthur/common/baselineprotocol.h | 12 +- tests/arthur/common/qbaselinetest.cpp | 124 +++++++++ tests/arthur/common/qbaselinetest.h | 64 +++++ tests/arthur/common/qbaselinetest.pri | 13 + tests/auto/baselineexample/baselineexample.pro | 18 ++ tests/auto/baselineexample/tst_baselineexample.cpp | 158 +++++++++++ tests/auto/lancelot/lancelot.pro | 5 +- tests/auto/lancelot/tst_lancelot.cpp | 2 +- 17 files changed, 834 insertions(+), 378 deletions(-) delete mode 100644 tests/arthur/baselineserver/src/htmlpage.cpp delete mode 100644 tests/arthur/baselineserver/src/htmlpage.h create mode 100644 tests/arthur/baselineserver/src/report.cpp create mode 100644 tests/arthur/baselineserver/src/report.h create mode 100644 tests/arthur/common/qbaselinetest.cpp create mode 100644 tests/arthur/common/qbaselinetest.h create mode 100644 tests/arthur/common/qbaselinetest.pri create mode 100644 tests/auto/baselineexample/baselineexample.pro create mode 100644 tests/auto/baselineexample/tst_baselineexample.cpp diff --git a/tests/arthur/baselineserver/src/baselineserver.cpp b/tests/arthur/baselineserver/src/baselineserver.cpp index 90eb594..6351dff 100644 --- a/tests/arthur/baselineserver/src/baselineserver.cpp +++ b/tests/arthur/baselineserver/src/baselineserver.cpp @@ -145,36 +145,43 @@ const char *BaselineHandler::logtime() //return QTime::currentTime().toString(QLS("mm:ss.zzz")); } -void BaselineHandler::receiveRequest() +bool BaselineHandler::establishConnection() { - if (!connectionEstablished) { - if (!proto.acceptConnection(&plat)) { - qWarning() << runId << logtime() << "Accepting new connection from" << proto.socket.peerAddress().toString() << "failed." << proto.errorMessage(); - proto.socket.disconnectFromHost(); - return; - } - QString logMsg; - foreach (QString key, plat.keys()) { - if (key != PI_HostName && key != PI_HostAddress) - logMsg += key + QLS(": '") + plat.value(key) + QLS("', "); - } - qDebug() << runId << logtime() << "Connection established with" << plat.value(PI_HostName) - << "[" << qPrintable(plat.value(PI_HostAddress)) << "]" << logMsg; + if (!proto.acceptConnection(&plat)) { + qWarning() << runId << logtime() << "Accepting new connection from" << proto.socket.peerAddress().toString() << "failed." << proto.errorMessage(); + proto.socket.disconnectFromHost(); + return false; + } + QString logMsg; + foreach (QString key, plat.keys()) { + if (key != PI_HostName && key != PI_HostAddress) + logMsg += key + QLS(": '") + plat.value(key) + QLS("', "); + } + qDebug() << runId << logtime() << "Connection established with" << plat.value(PI_HostName) + << "[" << qPrintable(plat.value(PI_HostAddress)) << "]" << logMsg; - // Filter on branch - QString branch = plat.value(PI_PulseGitBranch); - if (branch.isEmpty()) { - // Not run by Pulse, i.e. ad hoc run: Ok. - } - else if (branch != QLS("master-integration") || !plat.value(PI_GitCommit).contains(QLS("Merge branch 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into master-integration"))) { - qDebug() << runId << logtime() << "Did not pass branch/staging repo filter, disconnecting."; - proto.sendBlock(BaselineProtocol::Abort, QByteArray("This branch/staging repo is not assigned to be tested.")); - proto.socket.disconnectFromHost(); - return; - } + // Filter on branch + QString branch = plat.value(PI_PulseGitBranch); + if (branch.isEmpty()) { + // Not run by Pulse, i.e. ad hoc run: Ok. + } + else if (branch != QLS("master-integration") || !plat.value(PI_GitCommit).contains(QLS("Merge branch 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into master-integration"))) { + qDebug() << runId << logtime() << "Did not pass branch/staging repo filter, disconnecting."; + proto.sendBlock(BaselineProtocol::Abort, QByteArray("This branch/staging repo is not assigned to be tested.")); + proto.socket.disconnectFromHost(); + return false; + } + + proto.sendBlock(BaselineProtocol::Ack, QByteArray()); + + report.init(this, runId, plat); + return true; +} - proto.sendBlock(BaselineProtocol::Ack, QByteArray()); - connectionEstablished = true; +void BaselineHandler::receiveRequest() +{ + if (!connectionEstablished) { + connectionEstablished = establishConnection(); return; } @@ -247,7 +254,7 @@ void BaselineHandler::provideBaselineChecksums(const QByteArray &itemListBlock) QDataStream ods(&block, QIODevice::WriteOnly); ods << itemList; proto.sendBlock(BaselineProtocol::Ack, block); - report.start(BaselineServer::storagePath(), runId, plat, context, itemList); + report.addItems(itemList); } @@ -274,19 +281,15 @@ void BaselineHandler::storeImage(const QByteArray &itemBlock, bool isBaseline) file.close(); if (!isBaseline) - report.addItem(pathForItem(item, true, false) + QLS(FileFormat), - pathForItem(item, false, false) + QLS(FileFormat), - item); + report.addMismatch(item); - QByteArray msg(isBaseline ? "New baseline image stored: " : - "Mismatch report: " ); - msg += BaselineServer::baseUrl(); + QString msg; if (isBaseline) - msg += pathForItem(item, true, false).toLatin1() + FileFormat; + msg = QLS("New baseline image stored: ") + pathForItem(item, true, true) + QLS(FileFormat); else - msg += report.filePath(); + msg = BaselineServer::baseUrl() + report.filePath(); - proto.sendBlock(BaselineProtocol::Ack, msg); + proto.sendBlock(BaselineProtocol::Ack, msg.toLatin1()); } @@ -298,7 +301,7 @@ void BaselineHandler::receiveDisconnect() } -void BaselineHandler::mapPlatformInfo() +void BaselineHandler::mapPlatformInfo() const { mapped = plat; @@ -328,12 +331,13 @@ void BaselineHandler::mapPlatformInfo() mapped.insert(PI_QtVersion, ver.prepend(QLS("Qt-"))); //### TBD: remove patch version } -QString BaselineHandler::pathForItem(const ImageItem &item, bool isBaseline, bool absolute) +QString BaselineHandler::pathForItem(const ImageItem &item, bool isBaseline, bool absolute) const { if (mapped.isEmpty()) mapPlatformInfo(); - QString itemName = item.itemName; + QString itemName = item.itemName.simplified(); + itemName.replace(QLC(' '), QLC('_')); itemName.replace(QLC('.'), QLC('_')); itemName.append(QLC('_')); itemName.append(QString::number(item.itemChecksum, 16).rightJustified(4, QLC('0'))); diff --git a/tests/arthur/baselineserver/src/baselineserver.h b/tests/arthur/baselineserver/src/baselineserver.h index 346ce1f..e09a9d0 100644 --- a/tests/arthur/baselineserver/src/baselineserver.h +++ b/tests/arthur/baselineserver/src/baselineserver.h @@ -50,7 +50,7 @@ #include #include "baselineprotocol.h" -#include "htmlpage.h" +#include "report.h" // #seconds between update checks #define HEARTBEAT 10 @@ -99,7 +99,9 @@ class BaselineHandler : public QObject public: BaselineHandler(int socketDescriptor = -1); void testPathMapping(); + QString pathForItem(const ImageItem &item, bool isBaseline = true, bool absolute = true) const; + // CGI callbacks: static QString view(const QString &baseline, const QString &rendered, const QString &compared); static QString clearAllBaselines(const QString &context); static QString updateSingleBaseline(const QString &oldBaseline, const QString &newBaseline); @@ -110,19 +112,19 @@ private slots: void receiveDisconnect(); private: + bool establishConnection(); void provideBaselineChecksums(const QByteArray &itemListBlock); void storeImage(const QByteArray &itemBlock, bool isBaseline); - void mapPlatformInfo(); - QString pathForItem(const ImageItem &item, bool isBaseline = true, bool absolute = true); + void mapPlatformInfo() const; const char *logtime(); QString computeMismatchScore(const QImage& baseline, const QImage& rendered); BaselineProtocol proto; PlatformInfo plat; - PlatformInfo mapped; + mutable PlatformInfo mapped; bool connectionEstablished; QString runId; - HTMLPage report; + Report report; }; #endif // BASELINESERVER_H diff --git a/tests/arthur/baselineserver/src/baselineserver.pro b/tests/arthur/baselineserver/src/baselineserver.pro index defa05a..770662b 100644 --- a/tests/arthur/baselineserver/src/baselineserver.pro +++ b/tests/arthur/baselineserver/src/baselineserver.pro @@ -20,11 +20,11 @@ include(../../common/baselineprotocol.pri) SOURCES += main.cpp \ baselineserver.cpp \ - htmlpage.cpp + report.cpp HEADERS += \ baselineserver.h \ - htmlpage.h + report.h RESOURCES += \ baselineserver.qrc diff --git a/tests/arthur/baselineserver/src/htmlpage.cpp b/tests/arthur/baselineserver/src/htmlpage.cpp deleted file mode 100644 index 2b16d25..0000000 --- a/tests/arthur/baselineserver/src/htmlpage.cpp +++ /dev/null @@ -1,244 +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 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 "htmlpage.h" -#include "baselineprotocol.h" -#include "baselineserver.h" -#include -#include -#include - -HTMLPage::HTMLPage() - : headerWritten(false) -{ -} - -HTMLPage::~HTMLPage() -{ - end(); -} - -QString HTMLPage::filePath() -{ - return path; -} - -void HTMLPage::start(const QString &storagepath, const QString &runId, const PlatformInfo pinfo, const QString &context, const ImageItemList &itemList) -{ - end(); - - id = runId; - plat = pinfo; - ctx = context; - root = storagepath + QLC('/'); - imageItems = itemList; - reportDir = pinfo.value(PI_TestCase) + QLC('/') + (pinfo.value(PI_PulseGitBranch).isEmpty() ? QLS("reports/adhoc/") : QLS("reports/pulse/")); - QString dir = root + reportDir; - QDir cwd; - if (!cwd.exists(dir)) - cwd.mkpath(dir); -} - - -void HTMLPage::writeHeader(const ImageItem &item) -{ - path = reportDir + id + QLC('_') + item.testFunction + QLS(".html"); - - QString pageUrl = BaselineServer::baseUrl() + path; - - file.setFileName(root + path); - if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) - qWarning() << "Failed to open report file" << file.fileName(); - out.setDevice(&file); - - out << "

Lancelot results from run " << id << "

\n\n"; - out << "

Platform Info:

\n"; - out << "\n"; - foreach (QString key, plat.keys()) - out << "\n"; - out << "
" << key << "" << plat.value(key) << "

\n\n"; - - out << "

Clear all baselines (They will be recreated by the next run)

\n\n"; - - out << "

\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "
"; -} - - -void HTMLPage::writeFooter() -{ - out << "
ScriptBaselineRenderedComparison (diffs are RED)Info/Action

\n\n"; -} - - -void HTMLPage::addItem(const QString &baseline, const QString &rendered, const ImageItem &item) -{ - if (!headerWritten) { - writeHeader(item); - headerWritten = true; - } - QString compared = generateCompared(baseline, rendered); - QString pageUrl = BaselineServer::baseUrl() + path; - - out << "\n"; - out << "" << item.itemName << "\n"; - QStringList images = QStringList() << baseline << rendered << compared; - foreach(const QString& img, images) - out << "\n"; - - out << "\n" - << "

Replace baseline with rendered

\n" - << "

Blacklist this item

\n" - << "

View

\n" - << "\n"; - out << "\n\n"; - - QMutableVectorIterator it(imageItems); - while (it.hasNext()) { - it.next(); - if (it.value().itemName == item.itemName) { - it.remove(); - break; - } - } -} - - -void HTMLPage::end() -{ - if (file.isOpen()) { - // Add the names of the scripts that passed the test, or were blacklisted - QString pageUrl = BaselineServer::baseUrl() + path; - for (int i=0; i" << imageItems.at(i).itemName << "N/AN/AN/A"; - if (imageItems.at(i).status == ImageItem::IgnoreItem) { - out << "Blacklisted " - << "Whitelist item"; - } else { - out << "Test passed"; - } - out << "\n"; - } - - writeFooter(); - out.flush(); - file.close(); - path.clear(); - headerWritten = false; - } -} - - -QString HTMLPage::generateCompared(const QString &baseline, const QString &rendered, bool fuzzy) -{ - QString res = rendered; - QFileInfo fi(res); - res.chop(fi.suffix().length() + 1); - res += QLS(fuzzy ? "_fuzzycompared.png" : "_compared.png"); - QStringList args; - if (fuzzy) - args << QLS("-fuzz") << QLS("5%"); - args << root+baseline << root+rendered << root+res; - QProcess::execute(QLS("compare"), args); - return res; -} - - -QString HTMLPage::generateThumbnail(const QString &image) -{ - QString res = image; - QFileInfo imgFI(root+image); - res.chop(imgFI.suffix().length() + 1); - res += QLS("_thumbnail.jpg"); - QFileInfo resFI(root+res); - if (resFI.exists() && resFI.lastModified() > imgFI.lastModified()) - return res; - QStringList args; - args << root+image << QLS("-resize") << QLS("240x240") << QLS("-quality") << QLS("50") << root+res; - QProcess::execute(QLS("convert"), args); - return res; -} - - -void HTMLPage::handleCGIQuery(const QString &query) -{ - QUrl cgiUrl(QLS("http://dummy/cgi-bin/dummy.cgi?") + query); - QTextStream s(stdout); - s << "Content-Type: text/html\r\n\r\n" - << ""; - - QString command(cgiUrl.queryItemValue("cmd")); - - if (command == QLS("view")) { - s << BaselineHandler::view(cgiUrl.queryItemValue(QLS("baseline")), - cgiUrl.queryItemValue(QLS("rendered")), - cgiUrl.queryItemValue(QLS("compared"))); - } - else if (command == QLS("updateSingleBaseline")) { - s << BaselineHandler::updateSingleBaseline(cgiUrl.queryItemValue(QLS("oldBaseline")), - cgiUrl.queryItemValue(QLS("newBaseline"))); - } else if (command == QLS("clearAllBaselines")) { - s << BaselineHandler::clearAllBaselines(cgiUrl.queryItemValue(QLS("context"))); - } else if (command == QLS("blacklist")) { - // blacklist a test - s << BaselineHandler::blacklistTest(cgiUrl.queryItemValue(QLS("context")), - cgiUrl.queryItemValue(QLS("itemId"))); - } else if (command == QLS("whitelist")) { - // whitelist a test - s << BaselineHandler::blacklistTest(cgiUrl.queryItemValue(QLS("context")), - cgiUrl.queryItemValue(QLS("itemId")), true); - } else { - s << "Unknown query:
" << query << "
"; - } - s << "

Back to report"; - s << ""; -} diff --git a/tests/arthur/baselineserver/src/htmlpage.h b/tests/arthur/baselineserver/src/htmlpage.h deleted file mode 100644 index 5f1e051..0000000 --- a/tests/arthur/baselineserver/src/htmlpage.h +++ /dev/null @@ -1,79 +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 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$ -** -****************************************************************************/ -#ifndef HTMLPAGE_H -#define HTMLPAGE_H - -#include "baselineprotocol.h" -#include -#include - -class HTMLPage -{ -public: - HTMLPage(); - ~HTMLPage(); - - void start(const QString &storagePath, const QString &runId, const PlatformInfo pinfo, const QString &context, const ImageItemList &itemList); - void addItem(const QString &baseline, const QString &rendered, const ImageItem &item); - void end(); - QString filePath(); - - static void handleCGIQuery(const QString &query); - -private: - void writeHeader(const ImageItem &item); - void writeFooter(); - QString generateCompared(const QString &baseline, const QString &rendered, bool fuzzy = false); - QString generateThumbnail(const QString &image); - - QString root; - QString path; - QString reportDir; - QFile file; - QTextStream out; - QString id; - PlatformInfo plat; - QString ctx; - ImageItemList imageItems; - bool headerWritten; -}; - -#endif // HTMLPAGE_H diff --git a/tests/arthur/baselineserver/src/main.cpp b/tests/arthur/baselineserver/src/main.cpp index a5ec4db..bf41f41 100644 --- a/tests/arthur/baselineserver/src/main.cpp +++ b/tests/arthur/baselineserver/src/main.cpp @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) QString queryString(qgetenv("QUERY_STRING")); if (!queryString.isEmpty()) { // run as CGI script - HTMLPage::handleCGIQuery(queryString); + Report::handleCGIQuery(queryString); return 0; } diff --git a/tests/arthur/baselineserver/src/report.cpp b/tests/arthur/baselineserver/src/report.cpp new file mode 100644 index 0000000..f5bb418 --- /dev/null +++ b/tests/arthur/baselineserver/src/report.cpp @@ -0,0 +1,296 @@ +/**************************************************************************** +** +** 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 "report.h" +#include "baselineprotocol.h" +#include "baselineserver.h" +#include +#include +#include + +Report::Report() + : written(false), numItems(0), numMismatches(0) +{ +} + +Report::~Report() +{ + end(); +} + +QString Report::filePath() +{ + return path; +} + +void Report::init(const BaselineHandler *h, const QString &r, const PlatformInfo &p) +{ + handler = h; + runId = r; + plat = p; + rootDir = BaselineServer::storagePath() + QLC('/'); + reportDir = plat.value(PI_TestCase) + QLC('/') + (plat.value(PI_PulseGitBranch).isEmpty() ? QLS("reports/adhoc/") : QLS("reports/pulse/")); + QString dir = rootDir + reportDir; + QDir cwd; + if (!cwd.exists(dir)) + cwd.mkpath(dir); + path = reportDir + QLS("Report_") + runId + QLS(".html"); +} + +void Report::addItems(const ImageItemList &items) +{ + if (items.isEmpty()) + return; + numItems += items.size(); + QString func = items.at(0).testFunction; + if (!testFunctions.contains(func)) + testFunctions.append(func); + itemLists[func] += items; +} + +void Report::addMismatch(const ImageItem &item) +{ + if (!testFunctions.contains(item.testFunction)) { + qWarning() << "Report::addMismatch: unknown testfunction" << item.testFunction; + return; + } + bool found = false; + ImageItemList &list = itemLists[item.testFunction]; + for (ImageItemList::iterator it = list.begin(); it != list.end(); ++it) { + if (it->itemName == item.itemName && it->itemChecksum == item.itemChecksum) { + it->status = ImageItem::Mismatch; + found = true; + break; + } + } + if (found) + numMismatches++; + else + qWarning() << "Report::addMismatch: unknown item" << item.itemName << "in testfunction" << item.testFunction; +} + +void Report::end() +{ + if (written || !numMismatches) + return; + write(); + written = true; +} + + +void Report::write() +{ + QFile file(rootDir + path); + if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + qWarning() << "Failed to open report file" << file.fileName(); + return; + } + out.setDevice(&file); + + writeHeader(); + foreach(const QString &func, testFunctions) { + writeFunctionResults(itemLists.value(func)); + } + writeFooter(); + file.close(); +} + + +void Report::writeHeader() +{ + QString title = plat.value(PI_TestCase) + QLS(" Qt Baseline Test Report"); + out << "" << title << "\n" + << "

" << title << "

\n" + << "

Run Id: " << runId << "

\n" + << "

Summary: " << numMismatches << " of " << numItems << " items reported mismatching

\n\n"; + out << "

Platform Info:

\n" + << "\n"; + foreach (QString key, plat.keys()) + out << "\n"; + out << "
" << key << "" << plat.value(key) << "
\n\n"; +} + + +void Report::writeFunctionResults(const ImageItemList &list) +{ + QString testFunction = list.at(0).testFunction; + QString pageUrl = BaselineServer::baseUrl() + path; + QString ctx = handler->pathForItem(list.at(0), true, false).section(QLC('/'), 0, -2); + + out << "\n

 

Test function: " << testFunction << "

\n"; + out << "

Clear all baselines (They will be recreated by the next run)

\n\n"; + + out << "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n\n"; + + foreach (const ImageItem &item, list) { + out << "\n"; + out << "\n"; + QString baseline = handler->pathForItem(item, true, false) + QLS(FileFormat); + if (item.status == ImageItem::Mismatch) { + QString rendered = handler->pathForItem(item, false, false) + QLS(FileFormat); + writeItem(baseline, rendered, item, ctx); + } + else { + out << "\n" + << "\n" + << "\n"; + } + out << "\n\n"; + } + + out << "
ItemBaselineRenderedComparison (diffs are RED)Info/Action
" << item.itemName << "viewn/a"; + switch (item.status) { + case ImageItem::BaselineNotFound: + out << "Baseline not found/regenerated"; + break; + case ImageItem::IgnoreItem: + out << "Blacklisted " + << "Whitelist this item"; + break; + case ImageItem::Ok: + out << "No mismatch reported"; + break; + default: + out << "?"; + break; + } + out << "
\n"; +} + +void Report::writeItem(const QString &baseline, const QString &rendered, const ImageItem &item, const QString &ctx) +{ + QString compared = generateCompared(baseline, rendered); + QString pageUrl = BaselineServer::baseUrl() + path; + + QStringList images = QStringList() << baseline << rendered << compared; + foreach (const QString& img, images) + out << "\n"; + + out << "\n" + << "

Mismatch reported

\n" + << "

Replace baseline with rendered

\n" + << "

Blacklist this item

\n" + << "

Inspect

\n" + << "\n"; +} + +void Report::writeFooter() +{ + out << "\n\n"; +} + + +QString Report::generateCompared(const QString &baseline, const QString &rendered, bool fuzzy) +{ + QString res = rendered; + QFileInfo fi(res); + res.chop(fi.suffix().length() + 1); + res += QLS(fuzzy ? "_fuzzycompared.png" : "_compared.png"); + QStringList args; + if (fuzzy) + args << QLS("-fuzz") << QLS("5%"); + args << rootDir+baseline << rootDir+rendered << rootDir+res; + QProcess::execute(QLS("compare"), args); + return res; +} + + +QString Report::generateThumbnail(const QString &image) +{ + QString res = image; + QFileInfo imgFI(rootDir+image); + res.chop(imgFI.suffix().length() + 1); + res += QLS("_thumbnail.jpg"); + QFileInfo resFI(rootDir+res); + if (resFI.exists() && resFI.lastModified() > imgFI.lastModified()) + return res; + QStringList args; + args << rootDir+image << QLS("-resize") << QLS("240x240>") << QLS("-quality") << QLS("50") << rootDir+res; + QProcess::execute(QLS("convert"), args); + return res; +} + + +void Report::handleCGIQuery(const QString &query) +{ + QUrl cgiUrl(QLS("http://dummy/cgi-bin/dummy.cgi?") + query); + QTextStream s(stdout); + s << "Content-Type: text/html\r\n\r\n" + << ""; + + QString command(cgiUrl.queryItemValue("cmd")); + + if (command == QLS("view")) { + s << BaselineHandler::view(cgiUrl.queryItemValue(QLS("baseline")), + cgiUrl.queryItemValue(QLS("rendered")), + cgiUrl.queryItemValue(QLS("compared"))); + } + else if (command == QLS("updateSingleBaseline")) { + s << BaselineHandler::updateSingleBaseline(cgiUrl.queryItemValue(QLS("oldBaseline")), + cgiUrl.queryItemValue(QLS("newBaseline"))); + } else if (command == QLS("clearAllBaselines")) { + s << BaselineHandler::clearAllBaselines(cgiUrl.queryItemValue(QLS("context"))); + } else if (command == QLS("blacklist")) { + // blacklist a test + s << BaselineHandler::blacklistTest(cgiUrl.queryItemValue(QLS("context")), + cgiUrl.queryItemValue(QLS("itemId"))); + } else if (command == QLS("whitelist")) { + // whitelist a test + s << BaselineHandler::blacklistTest(cgiUrl.queryItemValue(QLS("context")), + cgiUrl.queryItemValue(QLS("itemId")), true); + } else { + s << "Unknown query:
" << query << "
"; + } + s << "

Back to report"; + s << ""; +} diff --git a/tests/arthur/baselineserver/src/report.h b/tests/arthur/baselineserver/src/report.h new file mode 100644 index 0000000..0df613a --- /dev/null +++ b/tests/arthur/baselineserver/src/report.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ +#ifndef REPORT_H +#define REPORT_H + +#include "baselineprotocol.h" +#include +#include +#include +#include + +class BaselineHandler; + +class Report +{ +public: + Report(); + ~Report(); + + void init(const BaselineHandler *h, const QString &r, const PlatformInfo &p); + void addItems(const ImageItemList& items); + void addMismatch(const ImageItem& item); + void end(); + + QString filePath(); + + static void handleCGIQuery(const QString &query); + +private: + void write(); + void writeFunctionResults(const ImageItemList &list); + void writeItem(const QString &baseline, const QString &rendered, const ImageItem &item, const QString &ctx); + void writeHeader(); + void writeFooter(); + QString generateCompared(const QString &baseline, const QString &rendered, bool fuzzy = false); + QString generateThumbnail(const QString &image); + + const BaselineHandler *handler; + QString runId; + PlatformInfo plat; + QString rootDir; + QString reportDir; + QString path; + QStringList testFunctions; + QMap itemLists; + bool written; + int numItems; + int numMismatches; + QTextStream out; +}; + +#endif // REPORT_H diff --git a/tests/arthur/common/baselineprotocol.cpp b/tests/arthur/common/baselineprotocol.cpp index c7e9e72..e4445bd 100644 --- a/tests/arthur/common/baselineprotocol.cpp +++ b/tests/arthur/common/baselineprotocol.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #ifndef QMAKESPEC #define QMAKESPEC "Unknown" @@ -264,6 +265,10 @@ QDataStream & operator>> (QDataStream &stream, ImageItem &ii) return stream; } +BaselineProtocol::BaselineProtocol() +{ +} + BaselineProtocol::~BaselineProtocol() { socket.close(); diff --git a/tests/arthur/common/baselineprotocol.h b/tests/arthur/common/baselineprotocol.h index 1f4d593..2315bc3 100644 --- a/tests/arthur/common/baselineprotocol.h +++ b/tests/arthur/common/baselineprotocol.h @@ -38,6 +38,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef BASELINEPROTOCOL_H #define BASELINEPROTOCOL_H @@ -46,6 +47,7 @@ #include #include #include +#include #define QLS QLatin1String #define QLC QLatin1Char @@ -87,7 +89,8 @@ public: enum ItemStatus { Ok = 0, BaselineNotFound = 1, - IgnoreItem = 2 + IgnoreItem = 2, + Mismatch = 3 }; QString testFunction; @@ -107,12 +110,15 @@ Q_DECLARE_METATYPE(ImageItem); typedef QVector ImageItemList; + class BaselineProtocol { public: - BaselineProtocol() {} + BaselineProtocol(); ~BaselineProtocol(); + static BaselineProtocol *instance(QObject *parent = 0); + // **************************************************** // Important constants here // **************************************************** @@ -136,6 +142,8 @@ public: }; // For client: + + // For advanced client: bool connect(const QString &testCase, bool *dryrun = 0); bool requestBaselineChecksums(const QString &testFunction, ImageItemList *itemList); bool submitNewBaseline(const ImageItem &item, QByteArray *serverMsg); diff --git a/tests/arthur/common/qbaselinetest.cpp b/tests/arthur/common/qbaselinetest.cpp new file mode 100644 index 0000000..e95b510 --- /dev/null +++ b/tests/arthur/common/qbaselinetest.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** 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 "qbaselinetest.h" +#include "baselineprotocol.h" + +namespace QBaselineTest { + +bool connected = false; +bool triedConnecting = false; +BaselineProtocol proto; + + +bool checkImage(const QImage& img, const char *name, quint16 checksum, QByteArray *msg, bool *error) +{ + QByteArray itemName; + bool hasName = qstrlen(name); + const char *tag = QTest::currentDataTag(); + if (qstrlen(tag)) { + itemName = tag; + if (hasName) + itemName.append('_').append(name); + } else { + itemName = hasName ? name : "default_name"; + } + + *msg = "Baseline check of image '" + itemName + "': "; + + if (!triedConnecting) { + triedConnecting = true; + if (!proto.connect(QTest::testObject()->metaObject()->className())) { + *msg += "Failed to connect to baseline server: " + proto.errorMessage().toLatin1(); + *error = true; + return true; + } + connected = true; + } + if (!connected) { + *msg = "Not connected to baseline server."; + *error = true; + return true; + } + + ImageItem item; + item.itemName = QLatin1String(itemName); + item.itemChecksum = checksum; + item.testFunction = QLatin1String(QTest::currentTestFunction()); + ImageItemList list; + list.append(item); + if (!proto.requestBaselineChecksums(QLatin1String(QTest::currentTestFunction()), &list) || list.isEmpty()) { + *msg = "Communication with baseline server failed: " + proto.errorMessage().toLatin1(); + *error = true; + return true; + } + item.image = img; + item.imageChecksums.prepend(ImageItem::computeChecksum(img)); + QByteArray srvMsg; + switch (list.at(0).status) { + case ImageItem::IgnoreItem : + qDebug() << msg->constData() << "Ignored, blacklisted on server."; + return true; + break; + case ImageItem::BaselineNotFound: + if (proto.submitNewBaseline(item, &srvMsg)) + qDebug() << msg->constData() << "Baseline not found on server. New baseline uploaded."; + else + qDebug() << msg->constData() << "Baseline not found on server. Uploading of new baseline failed:" << srvMsg; + return true; + break; + case ImageItem::Ok: + break; + default: + qWarning() << "Unexpected reply from baseline server."; + return true; + break; + } + *error = false; + // The actual comparison of the given image with the baseline: + if (list.at(0).imageChecksums.contains(item.imageChecksums.at(0))) + return true; + proto.submitMismatch(item, &srvMsg); + *msg += "Mismatch. See report:\n " + srvMsg; + return false; +} + +} diff --git a/tests/arthur/common/qbaselinetest.h b/tests/arthur/common/qbaselinetest.h new file mode 100644 index 0000000..3445c72 --- /dev/null +++ b/tests/arthur/common/qbaselinetest.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 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$ +** +****************************************************************************/ + +#ifndef BASELINETEST_H +#define BASELINETEST_H + +#include + +namespace QBaselineTest { +bool checkImage(const QImage& img, const char *name, quint16 checksum, QByteArray *msg, bool *error); +} + +#define QBASELINE_CHECK_SUM(image, name, checksum)\ +do {\ + QByteArray _msg;\ + bool _err = false;\ + if (!QBaselineTest::checkImage((image), (name), (checksum), &_msg, &_err)) {\ + QFAIL(_msg.constData());\ + } else if (_err) {\ + QSKIP(_msg.constData(), SkipSingle);\ + }\ +} while (0) + +#define QBASELINE_CHECK(image, name) QBASELINE_CHECK_SUM(image, name, 0) + +#endif // BASELINETEST_H diff --git a/tests/arthur/common/qbaselinetest.pri b/tests/arthur/common/qbaselinetest.pri new file mode 100644 index 0000000..5420c6e --- /dev/null +++ b/tests/arthur/common/qbaselinetest.pri @@ -0,0 +1,13 @@ +QT *= testlib + +SOURCES += \ + $$PWD/qbaselinetest.cpp + +HEADERS += \ + $$PWD/qbaselinetest.h + +win32|symbian*:MKSPEC=$$replace(QMAKESPEC, \\\\, /) +else:MKSPEC=$$QMAKESPEC +DEFINES += QMAKESPEC=\\\"$$MKSPEC\\\" + +include($$PWD/baselineprotocol.pri) diff --git a/tests/auto/baselineexample/baselineexample.pro b/tests/auto/baselineexample/baselineexample.pro new file mode 100644 index 0000000..30feecc --- /dev/null +++ b/tests/auto/baselineexample/baselineexample.pro @@ -0,0 +1,18 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2010-12-09T14:55:13 +# +#------------------------------------------------- + +QT += testlib + +TARGET = tst_baselineexample +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +SOURCES += tst_baselineexample.cpp +DEFINES += SRCDIR=\\\"$$PWD/\\\" + +include($$QT_SOURCE_TREE/tests/arthur/common/qbaselinetest.pri) diff --git a/tests/auto/baselineexample/tst_baselineexample.cpp b/tests/auto/baselineexample/tst_baselineexample.cpp new file mode 100644 index 0000000..28cbec5 --- /dev/null +++ b/tests/auto/baselineexample/tst_baselineexample.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** 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 + +class tst_BaselineExample : public QObject +{ + Q_OBJECT + +public: + tst_BaselineExample(); + +private Q_SLOTS: + void testBasicUsage(); + void testMultipleImages(); + void testDataDriven_data(); + void testDataDriven(); + void testDataDrivenMultiple_data(); + void testDataDrivenMultiple(); + void testChecksum_data(); + void testChecksum(); +}; + + +tst_BaselineExample::tst_BaselineExample() +{ +} + + +void tst_BaselineExample::testBasicUsage() +{ + // Generate an image: + QPushButton b("Press me!"); + b.resize(100, 50); + b.show(); + QTest::qWaitForWindowShown(&b); + QImage img1 = QPixmap::grabWidget(&b).toImage(); + QVERIFY(!img1.isNull()); + + // Compare it to baseline on server: + QBASELINE_CHECK(img1, "button"); +} + + +void tst_BaselineExample::testMultipleImages() +{ + QPushButton b("Press me!"); + b.resize(100, 50); + b.show(); + QTest::qWaitForWindowShown(&b); + QBASELINE_CHECK(QPixmap::grabWidget(&b).toImage(), "text1"); + + b.setText("Kick me!"); + QTest::qWait(50); + QBASELINE_CHECK(QPixmap::grabWidget(&b).toImage(), "text2"); +} + + +void tst_BaselineExample::testDataDriven_data() +{ + QTest::addColumn("label"); + QTest::newRow("short") << "Ok!"; + QTest::newRow("long") << "A really long button text that just does not seem to end"; + QTest::newRow("empty") << ""; +} + + +void tst_BaselineExample::testDataDriven() +{ + QFETCH(QString, label); + QPushButton b(label); + b.resize(100, 50); + b.show(); + QTest::qWaitForWindowShown(&b); + QBASELINE_CHECK(QPixmap::grabWidget(&b).toImage(), 0); +} + + +void tst_BaselineExample::testDataDrivenMultiple_data() +{ + testDataDriven_data(); +} + + +void tst_BaselineExample::testDataDrivenMultiple() +{ + QFETCH(QString, label); + QPushButton b(label); + b.resize(100, 50); + b.show(); + QTest::qWaitForWindowShown(&b); + QBASELINE_CHECK(QPixmap::grabWidget(&b).toImage(), "normal"); + + b.setText(label.prepend('&')); + QTest::qWait(50); + QBASELINE_CHECK(QPixmap::grabWidget(&b).toImage(), "shortcut"); +} + + +void tst_BaselineExample::testChecksum_data() +{ + testDataDriven_data(); +} + + +void tst_BaselineExample::testChecksum() +{ + QFETCH(QString, label); + QPushButton b(label); + b.resize(100, 50); + b.show(); + QTest::qWaitForWindowShown(&b); + QBASELINE_CHECK_SUM(QPixmap::grabWidget(&b).toImage(), 0, quint16(qHash(label))); +} + + +QTEST_MAIN(tst_BaselineExample); + +#include "tst_baselineexample.moc" diff --git a/tests/auto/lancelot/lancelot.pro b/tests/auto/lancelot/lancelot.pro index 4535b83..6d6edf8 100644 --- a/tests/auto/lancelot/lancelot.pro +++ b/tests/auto/lancelot/lancelot.pro @@ -7,9 +7,6 @@ SOURCES += tst_lancelot.cpp \ HEADERS += $$QT_SOURCE_TREE/tests/arthur/common/paintcommands.h RESOURCES += $$QT_SOURCE_TREE/tests/arthur/common/images.qrc -include($$QT_SOURCE_TREE/tests/arthur/common/baselineprotocol.pri) -win32|symbian*:MKSPEC=$$replace(QMAKESPEC, \\\\, /) -else:MKSPEC=$$QMAKESPEC -DEFINES += QMAKESPEC=\\\"$$MKSPEC\\\" +include($$QT_SOURCE_TREE/tests/arthur/common/qbaselinetest.pri) !symbian:!wince*:DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/lancelot/tst_lancelot.cpp b/tests/auto/lancelot/tst_lancelot.cpp index d1b093f..4bde927 100644 --- a/tests/auto/lancelot/tst_lancelot.cpp +++ b/tests/auto/lancelot/tst_lancelot.cpp @@ -252,7 +252,7 @@ void tst_Lancelot::runTestSuite(GraphicsEngine engine, QImage::Format format) if (dryRunMode) qDebug() << "Dryrun mode, ignoring detected mismatch." << serverMsg; else - QFAIL("Rendered image differs from baseline.\n" + serverMsg); + QFAIL("Rendered image differs from baseline. Report:\n " + serverMsg); } } -- cgit v0.12 From c031e5808ee406277a5401c69801e5c6e2ebfaea Mon Sep 17 00:00:00 2001 From: Aaron McCarthy Date: Wed, 15 Dec 2010 14:16:36 +1000 Subject: Fix invalid configurations being added to bearermonitor list. --- examples/network/bearermonitor/bearermonitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/network/bearermonitor/bearermonitor.cpp b/examples/network/bearermonitor/bearermonitor.cpp index 75ffb01..bfa3d1f 100644 --- a/examples/network/bearermonitor/bearermonitor.cpp +++ b/examples/network/bearermonitor/bearermonitor.cpp @@ -226,7 +226,7 @@ void BearerMonitor::updateConfigurations() if (defaultConfiguration.type() == QNetworkConfiguration::ServiceNetwork) updateSnapConfiguration(defaultItem, defaultConfiguration); - } else { + } else if (defaultConfiguration.isValid()) { configurationAdded(defaultConfiguration); } -- cgit v0.12 From c9faf2defa9fa3209e44e8a5c1ae2da8e630d379 Mon Sep 17 00:00:00 2001 From: Aaron McCarthy Date: Wed, 8 Dec 2010 17:48:14 +1000 Subject: Ensure that DBus is connected before all uses. In early system startup applications may try to use ICD before it is contactable. Ensure that the connection to ICD is established before all calls are made. If ICD is still not contactable QDBusServiceWatcher is used to monitor registration of the com.nokia.icd2 address and reconnection is attempted once ICD is started. Task-number: Maemo 199755 --- src/plugins/bearer/icd/qicdengine.cpp | 93 ++++++++++++++++++++++++++++++----- src/plugins/bearer/icd/qicdengine.h | 6 +++ 2 files changed, 88 insertions(+), 11 deletions(-) diff --git a/src/plugins/bearer/icd/qicdengine.cpp b/src/plugins/bearer/icd/qicdengine.cpp index bdf4e2e..a5a183b 100644 --- a/src/plugins/bearer/icd/qicdengine.cpp +++ b/src/plugins/bearer/icd/qicdengine.cpp @@ -229,7 +229,7 @@ void IapMonitor::iapRemoved(const QString &iap_id) /******************************************************************************/ QIcdEngine::QIcdEngine(QObject *parent) -: QBearerEngine(parent), iapMonitor(0), m_dbusInterface(0), +: QBearerEngine(parent), iapMonitor(0), m_dbusInterface(0), m_icdServiceWatcher(0), firstUpdate(true), m_scanGoingOn(false) { } @@ -248,9 +248,10 @@ QNetworkConfigurationManager::Capabilities QIcdEngine::capabilities() const QNetworkConfigurationManager::NetworkSessionRequired; } -void QIcdEngine::initialize() +bool QIcdEngine::ensureDBusConnection() { - QMutexLocker locker(&mutex); + if (m_dbusInterface) + return true; // Setup DBus Interface for ICD m_dbusInterface = new QDBusInterface(ICD_DBUS_API_INTERFACE, @@ -259,9 +260,22 @@ void QIcdEngine::initialize() QDBusConnection::systemBus(), this); - // abort if cannot connect to DBus. - if (!m_dbusInterface->isValid()) - return; + if (!m_dbusInterface->isValid()) { + delete m_dbusInterface; + m_dbusInterface = 0; + + if (!m_icdServiceWatcher) { + m_icdServiceWatcher = new QDBusServiceWatcher(ICD_DBUS_API_INTERFACE, + QDBusConnection::systemBus(), + QDBusServiceWatcher::WatchForOwnerChange, + this); + + connect(m_icdServiceWatcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)), + this, SLOT(icdServiceOwnerChanged(QString,QString,QString))); + } + + return false; + } connect(&m_scanTimer, SIGNAL(timeout()), this, SLOT(finishAsyncConfigurationUpdate())); m_scanTimer.setSingleShot(true); @@ -289,6 +303,19 @@ void QIcdEngine::initialize() doRequestUpdate(); getIcdInitialState(); + + return true; +} + +void QIcdEngine::initialize() +{ + QMutexLocker locker(&mutex); + + if (!ensureDBusConnection()) { + locker.unlock(); + emit updateCompleted(); + locker.relock(); + } } static inline QString network_attrs_to_security(uint network_attrs) @@ -792,6 +819,9 @@ QNetworkConfigurationPrivatePointer QIcdEngine::defaultConfiguration() { QMutexLocker locker(&mutex); + if (!ensureDBusConnection()) + return QNetworkConfigurationPrivatePointer(); + // Here we just return [ANY] request to icd and let the icd decide which IAP to connect. return userChoiceConfigurations.value(OSSO_IAP_ANY); } @@ -933,13 +963,52 @@ void QIcdEngine::connectionStateSignalsSlot(QDBusMessage msg) locker.relock(); } +void QIcdEngine::icdServiceOwnerChanged(const QString &serviceName, const QString &oldOwner, + const QString &newOwner) +{ + QMutexLocker locker(&mutex); + + if (newOwner.isEmpty()) { + // Disconnected from ICD, remove all configurations + cleanup(); + delete iapMonitor; + iapMonitor = 0; + delete m_dbusInterface; + m_dbusInterface = 0; + + QMutableHashIterator i(accessPointConfigurations); + while (i.hasNext()) { + i.next(); + + QNetworkConfigurationPrivatePointer ptr = i.value(); + i.remove(); + + locker.unlock(); + emit configurationRemoved(ptr); + locker.relock(); + } + + userChoiceConfigurations.clear(); + } else { + // Connected to ICD ensure connection. + ensureDBusConnection(); + } +} + void QIcdEngine::requestUpdate() { QMutexLocker locker(&mutex); - if (m_scanGoingOn) { + if (!ensureDBusConnection()) { + locker.unlock(); + emit updateCompleted(); + locker.relock(); return; } + + if (m_scanGoingOn) + return; + m_scanGoingOn = true; m_dbusInterface->connection().connect(ICD_DBUS_API_INTERFACE, @@ -956,14 +1025,16 @@ void QIcdEngine::requestUpdate() void QIcdEngine::cancelAsyncConfigurationUpdate() { - if (!m_scanGoingOn) { + if (!ensureDBusConnection()) return; - } + + if (!m_scanGoingOn) + return; + m_scanGoingOn = false; - if (m_scanTimer.isActive()) { + if (m_scanTimer.isActive()) m_scanTimer.stop(); - } m_dbusInterface->connection().disconnect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH, diff --git a/src/plugins/bearer/icd/qicdengine.h b/src/plugins/bearer/icd/qicdengine.h index d528f15..d5b4fb3 100644 --- a/src/plugins/bearer/icd/qicdengine.h +++ b/src/plugins/bearer/icd/qicdengine.h @@ -53,6 +53,7 @@ QT_BEGIN_NAMESPACE class QNetworkConfigurationPrivate; class IapMonitor; class QDBusInterface; +class QDBusServiceWatcher; inline QNetworkConfiguration::BearerType bearerTypeFromIapType(const QString &iapType) { @@ -147,12 +148,15 @@ private Q_SLOTS: void finishAsyncConfigurationUpdate(); void asyncUpdateConfigurationsSlot(QDBusMessage msg); void connectionStateSignalsSlot(QDBusMessage msg); + void icdServiceOwnerChanged(const QString &serviceName, const QString &oldOwner, + const QString &newOwner); private: void startListeningStateSignalsForAllConnections(); void doRequestUpdate(QList scanned = QList()); void cancelAsyncConfigurationUpdate(); void getIcdInitialState(); + bool ensureDBusConnection(); private: IapMonitor *iapMonitor; @@ -162,6 +166,8 @@ private: QStringList m_typesToBeScanned; QList m_scanResult; + QDBusServiceWatcher *m_icdServiceWatcher; + bool firstUpdate; bool m_scanGoingOn; }; -- cgit v0.12 From e75980a322ea1088e1c6bf60259b8ba853d32444 Mon Sep 17 00:00:00 2001 From: Aaron McCarthy Date: Wed, 15 Dec 2010 15:30:43 +1000 Subject: Fix possible null pointer dereference. When parsing a new connection an access point with the same SSID may not have been previously seen. Task-number: QTBUG-15276 --- src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index 554f9b7..f93b605 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -743,9 +743,11 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(accessPointId); - mutex.unlock(); - emit configurationRemoved(ptr); - mutex.lock(); + if (ptr) { + mutex.unlock(); + emit configurationRemoved(ptr); + mutex.lock(); + } } break; } -- cgit v0.12 From 27de60f2f6047cb3f698825af96e569fde04ef06 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 15 Dec 2010 17:06:25 +1000 Subject: Add extra type of embedded license. Marketing needs this for commercial customers. Reviewed-by: Trust Me --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 7141880..aa8d047 100755 --- a/configure +++ b/configure @@ -480,7 +480,7 @@ elif [ $COMMERCIAL_USER = "yes" ]; then # Qt All-OS LICENSE_EXTENSION="-ALLOS" ;; - 8M,* | KM,* | S9,* | SC,* | SU,* | SW,* | X9,* | XC,* | XU,* | XW,*) + 8M,* | KM,* | S9,* | SC,* | SM,* | SU,* | SW,* | X9,* | XC,* | XU,* | XW,*) # Qt for Embedded Linux LICENSE_EXTENSION="-EMBEDDED" ;; -- cgit v0.12 From 915a31420c4f8d04c82103e3dd4d33b468a9334d Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 15 Dec 2010 11:44:19 +0200 Subject: Resize event for QDesktopWidget was sent too early Some recent changes had caused a change in events sent from avkon to QSymbianControl, causing QDesktopWidget to be get resize event before the client area of application was correct. Moved the resize event sending from HandleStatusPaneSizeChange to HandleResourceChange (case KEikDynamicLayoutVariantSwitch). Task-number: QTBUG-16095 Reviewed-by: Sami Merila --- src/gui/kernel/qapplication_s60.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 81fa4e6..6db1fa8 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -667,9 +667,6 @@ void QSymbianControl::HandleStatusPaneSizeChange() { QS60MainAppUi *s60AppUi = static_cast(S60->appUi()); s60AppUi->HandleStatusPaneSizeChange(); - // Send resize event to trigger desktopwidget workAreaResized signal - QResizeEvent e(qt_desktopWidget->size(), qt_desktopWidget->size()); - QApplication::sendEvent(qt_desktopWidget, &e); } #endif @@ -1310,6 +1307,9 @@ void QSymbianControl::HandleResourceChange(int resourceType) case KEikDynamicLayoutVariantSwitch: { handleClientAreaChange(); + // Send resize event to trigger desktopwidget workAreaResized signal + QResizeEvent e(qt_desktopWidget->size(), qt_desktopWidget->size()); + QApplication::sendEvent(qt_desktopWidget, &e); break; } #endif -- cgit v0.12 From e0aa9897bc2d04054cc65dbe3452bee2ed2eacd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 15 Dec 2010 12:41:08 +0100 Subject: Prevent crash in drawhelper code when the cpu has MMXEXT but no SSE. We can't use the qdrawhelper_sse.cpp or qdrawhelper_sse3dnow.cpp when SSE is not run-time detected, as those are compiled with -msse and MMXEXT is just a subset of SSE. The compiler might choose to use an instruction not in the subset, causing a crash at run-time. Task-number: QTBUG-15693 Reviewed-by: Thiago Macieira --- src/gui/painting/qdrawhelper.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 024a69d..62af212 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -7711,17 +7711,6 @@ void qInitDrawhelperAsm() } #endif #endif // SSE -#if defined(QT_HAVE_MMXEXT) && defined(QT_HAVE_SSE) - } else if (features & MMXEXT) { - qt_memfill32 = qt_memfill32_sse; - qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse; -# ifdef QT_HAVE_3DNOW - if (features & MMX3DNOW) { - qt_memfill32 = qt_memfill32_sse3dnow; - qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse3dnow; - } -# endif // 3DNOW -#endif // MMXEXT } #ifdef QT_HAVE_MMX if (features & MMX) { -- cgit v0.12 From 21b1b5a9af95af10b281176564f14cafa2339006 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 11 Dec 2010 00:03:14 +0100 Subject: Improve performance of clipping to a scaled QRectF Clipping to a scaled QRectF was so far hitting the slow code path in the raster paintengine that generates clip spans for every line. This is not needed as we also clip translated QRectF's to integer rects. This patch does the same for scaled rectangles and ensures the clipping really happens at the closest pixel boundary. Reviewed-by: Samuel --- src/gui/painting/qpaintengine_raster.cpp | 33 ++++++++++++++++++++++---------- src/gui/painting/qpaintengine_raster_p.h | 2 ++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 89202ac..4d06c9f 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1212,7 +1212,7 @@ void QRasterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) // There are some cases that are not supported by clip(QRect) if (op != Qt::UniteClip && (op != Qt::IntersectClip || !s->clip || s->clip->hasRectClip || s->clip->hasRegionClip)) { - if (s->matrix.type() <= QTransform::TxTranslate + if (s->matrix.type() <= QTransform::TxScale && ((path.shape() == QVectorPath::RectangleHint) || (isRect(points, path.elementCount()) && (!types || (types[0] == QPainterPath::MoveToElement @@ -1224,8 +1224,8 @@ void QRasterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) #endif QRectF r(points[0], points[1], points[4]-points[0], points[5]-points[1]); - clip(r.toRect(), op); - return; + if (setClipRectInDeviceCoords(s->matrix.mapRect(r).toRect(), op)) + return; } } @@ -1286,7 +1286,6 @@ void QRasterPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) qDebug() << "QRasterPaintEngine::clip(): " << rect << op; #endif - Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); if (op == Qt::NoClip) { @@ -1296,11 +1295,23 @@ void QRasterPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) QPaintEngineEx::clip(rect, op); return; - } else if (op == Qt::ReplaceClip || s->clip == 0) { + } else if (!setClipRectInDeviceCoords(s->matrix.mapRect(rect), op)) { + QPaintEngineEx::clip(rect, op); + return; + } +} + + +bool QRasterPaintEngine::setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op) +{ + Q_D(QRasterPaintEngine); + QRect clipRect = r & d->deviceRect; + QRasterPaintEngineState *s = state(); + + if (op == Qt::ReplaceClip || s->clip == 0) { // No current clip, hence we intersect with sysclip and be // done with it... - QRect clipRect = s->matrix.mapRect(rect) & d->deviceRect; QRegion clipRegion = systemClip(); QClipData *clip = new QClipData(d->rasterBuffer->height()); @@ -1316,12 +1327,11 @@ void QRasterPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) s->clip->enabled = true; s->flags.has_clip_ownership = true; - } else { // intersect clip with current clip + } else if (op == Qt::IntersectClip){ // intersect clip with current clip QClipData *base = s->clip; Q_ASSERT(base); if (base->hasRectClip || base->hasRegionClip) { - QRect clipRect = s->matrix.mapRect(rect) & d->deviceRect; if (!s->flags.has_clip_ownership) { s->clip = new QClipData(d->rasterBuffer->height()); s->flags.has_clip_ownership = true; @@ -1332,11 +1342,14 @@ void QRasterPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) s->clip->setClipRegion(base->clipRegion & clipRect); s->clip->enabled = true; } else { - QPaintEngineEx::clip(rect, op); - return; + return false; } + } else { + return false; } + qrasterpaintengine_dirty_clip(d, s); + return true; } diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 1016f8d..7d4d3b6 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -266,6 +266,8 @@ private: void drawGlyphsS60(const QPointF &p, const QTextItemInt &ti); #endif // Q_OS_SYMBIAN && QT_NO_FREETYPE + bool setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op); + inline void ensureBrush(const QBrush &brush) { if (!qbrush_fast_equals(state()->lastBrush, brush) || (brush.style() != Qt::NoBrush && state()->fillFlags)) updateBrush(brush); -- cgit v0.12 From 3e7adcb80a86748608d5517413301cd2b1b8df78 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 15 Dec 2010 16:42:05 +0100 Subject: Check for null-pointer to avoid a crash in textedit demo. Task-number: QTBUG-16125 Reviewed-by: trustme --- demos/textedit/textedit.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/demos/textedit/textedit.cpp b/demos/textedit/textedit.cpp index 165c97c..9fa1949 100644 --- a/demos/textedit/textedit.cpp +++ b/demos/textedit/textedit.cpp @@ -262,7 +262,8 @@ void TextEdit::setupEditActions() tb->addAction(a); menu->addAction(a); #ifndef QT_NO_CLIPBOARD - actionPaste->setEnabled(QApplication::clipboard()->mimeData()->hasText()); + if (const QMimeData *md = QApplication::clipboard()->mimeData()) + actionPaste->setEnabled(md->hasText()); #endif } @@ -681,7 +682,8 @@ void TextEdit::cursorPositionChanged() void TextEdit::clipboardDataChanged() { #ifndef QT_NO_CLIPBOARD - actionPaste->setEnabled(QApplication::clipboard()->mimeData()->hasText()); + if (const QMimeData *md = QApplication::clipboard()->mimeData()) + actionPaste->setEnabled(md->hasText()); #endif } -- cgit v0.12 From 32d200da9cc7a4dfb3f302f22ef5718a286845c9 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Tue, 7 Dec 2010 14:29:28 +0100 Subject: Make QScroller examples Qt-namespace safe. --- examples/scroller/plot/plotwidget.h | 3 ++- examples/scroller/plot/settingswidget.h | 2 ++ examples/scroller/wheel/wheelwidget.h | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/scroller/plot/plotwidget.h b/examples/scroller/plot/plotwidget.h index 3b4d92d..4987ebc 100644 --- a/examples/scroller/plot/plotwidget.h +++ b/examples/scroller/plot/plotwidget.h @@ -45,10 +45,11 @@ #include #include +QT_BEGIN_NAMESPACE class QPushButton; class QLabel; - class QScroller; +QT_END_NAMESPACE class PlotWidget : public QWidget { diff --git a/examples/scroller/plot/settingswidget.h b/examples/scroller/plot/settingswidget.h index 2fb268c..0ea201d 100644 --- a/examples/scroller/plot/settingswidget.h +++ b/examples/scroller/plot/settingswidget.h @@ -44,12 +44,14 @@ #include +QT_BEGIN_NAMESPACE class QScroller; class QGridLayout; class QSpinBox; class QComboBox; class QCheckBox; class QPlainTextEdit; +QT_END_NAMESPACE class MetricItemUpdater; class SnapOverlay; diff --git a/examples/scroller/wheel/wheelwidget.h b/examples/scroller/wheel/wheelwidget.h index 818b6ab..c50f951 100644 --- a/examples/scroller/wheel/wheelwidget.h +++ b/examples/scroller/wheel/wheelwidget.h @@ -45,8 +45,10 @@ #include #include +QT_BEGIN_NAMESPACE class QPainter; class QRect; +QT_END_NAMESPACE class AbstractWheelWidget : public QWidget { Q_OBJECT -- cgit v0.12 From 3e0df49f978933b1e4e6b48c695bf813ec9a2828 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Tue, 7 Dec 2010 14:29:59 +0100 Subject: Fix drag velocity smoothing in QScroller. The algorithm used for smoothing the drag velocity was wrong in many ways. Reviewed-by: Ralf Engels --- examples/scroller/plot/settingswidget.cpp | 2 +- src/gui/util/qscroller.cpp | 16 ++++++++++------ src/gui/util/qscrollerproperties.cpp | 9 +++++---- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/examples/scroller/plot/settingswidget.cpp b/examples/scroller/plot/settingswidget.cpp index af1e621..840e3fc 100644 --- a/examples/scroller/plot/settingswidget.cpp +++ b/examples/scroller/plot/settingswidget.cpp @@ -348,7 +348,7 @@ private: 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(DragVelocitySmoothingFactor), 1, "", qreal(0), qreal(1), qreal(0.1) }, { METRIC(AxisLockThreshold), 1, "", qreal(0), qreal(1), qreal(0.01) }, { METRIC(ScrollingCurve), 1, "", QEasingCurve(), 0, 0 }, diff --git a/src/gui/util/qscroller.cpp b/src/gui/util/qscroller.cpp index b7b5903..0955f58 100644 --- a/src/gui/util/qscroller.cpp +++ b/src/gui/util/qscroller.cpp @@ -1046,6 +1046,9 @@ void QScrollerPrivate::setDpiFromWidget(QWidget *widget) */ void QScrollerPrivate::updateVelocity(const QPointF &deltaPixelRaw, qint64 deltaTime) { + if (deltaTime <= 0) + return; + Q_Q(QScroller); QPointF ppm = q->pixelPerMeter(); const QScrollerPropertiesPrivate *sp = properties.d.data(); @@ -1057,14 +1060,12 @@ void QScrollerPrivate::updateVelocity(const QPointF &deltaPixelRaw, qint64 delta 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 (releaseVelocity != QPointF(0, 0)) + newv = newv * sp->dragVelocitySmoothingFactor + releaseVelocity * (qreal(1) - sp->dragVelocitySmoothingFactor); - if (deltaPixel.x()) - releaseVelocity.setX(qBound(-sp->maximumVelocity, newv.x(), sp->maximumVelocity)); - if (deltaPixel.y()) - releaseVelocity.setY(qBound(-sp->maximumVelocity, newv.y(), sp->maximumVelocity)); + releaseVelocity.setX(qBound(-sp->maximumVelocity, newv.x(), sp->maximumVelocity)); + releaseVelocity.setY(qBound(-sp->maximumVelocity, newv.y(), sp->maximumVelocity)); qScrollerDebug() << " --> new velocity:" << releaseVelocity; } @@ -1569,6 +1570,9 @@ bool QScrollerPrivate::releaseWhileDragging(const QPointF &position, qint64 time Q_Q(QScroller); const QScrollerPropertiesPrivate *sp = properties.d.data(); + // handleDrag updates lastPosition, lastTimestamp and velocity + handleDrag(position, timestamp); + // 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; diff --git a/src/gui/util/qscrollerproperties.cpp b/src/gui/util/qscrollerproperties.cpp index d21f131..4a1f085 100644 --- a/src/gui/util/qscrollerproperties.cpp +++ b/src/gui/util/qscrollerproperties.cpp @@ -61,7 +61,7 @@ QScrollerPropertiesPrivate *QScrollerPropertiesPrivate::defaults() #ifdef Q_WS_MAEMO_5 spp.mousePressEventDelay = qreal(0); spp.dragStartDistance = qreal(2.5 / 1000); - spp.dragVelocitySmoothingFactor = qreal(0.15); + spp.dragVelocitySmoothingFactor = qreal(10); spp.axisLockThreshold = qreal(0); spp.scrollingCurve.setType(QEasingCurve::OutQuad); spp.decelerationFactor = 1.0; @@ -82,7 +82,7 @@ QScrollerPropertiesPrivate *QScrollerPropertiesPrivate::defaults() #else spp.mousePressEventDelay = qreal(0.25); spp.dragStartDistance = qreal(5.0 / 1000); - spp.dragVelocitySmoothingFactor = qreal(0.02); + spp.dragVelocitySmoothingFactor = qreal(0.8); spp.axisLockThreshold = qreal(0); spp.scrollingCurve.setType(QEasingCurve::OutQuad); spp.decelerationFactor = qreal(0.125); @@ -342,8 +342,9 @@ void QScrollerProperties::setScrollMetric(ScrollMetric metric, const QVariant &v 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. + included in the final scrolling velocity. This value should be in the range between \c 0 and + \c 1. The lower the value, the more smoothing will be applied to the dragging velocity. The + default value is \c 0.8. \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 -- cgit v0.12 From 82bbc1c1611bde33680d22a1a3c6449e51d7b0b9 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Wed, 15 Dec 2010 18:20:14 +0100 Subject: Resolve XRRSizes() from libxrandr for QScroller's DPI calculation. Reviewed-by: Denis Dzyubenko --- src/gui/kernel/qapplication_x11.cpp | 3 +++ src/gui/kernel/qt_x11_p.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index ff98229..58ccda2 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -2015,12 +2015,15 @@ void qt_init(QApplicationPrivate *priv, int, (PtrXRRRootToScreen) xrandrLib.resolve("XRRRootToScreen"); X11->ptrXRRQueryExtension = (PtrXRRQueryExtension) xrandrLib.resolve("XRRQueryExtension"); + X11->ptrXRRSizes = + (PtrXRRSizes) xrandrLib.resolve("XRRSizes"); } # else X11->ptrXRRSelectInput = XRRSelectInput; X11->ptrXRRUpdateConfiguration = XRRUpdateConfiguration; X11->ptrXRRRootToScreen = XRRRootToScreen; X11->ptrXRRQueryExtension = XRRQueryExtension; + X11->ptrXRRSizes = XRRSizes; # endif if (X11->ptrXRRQueryExtension diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h index 56c8094..d97264c 100644 --- a/src/gui/kernel/qt_x11_p.h +++ b/src/gui/kernel/qt_x11_p.h @@ -226,6 +226,7 @@ typedef void (*PtrXRRSelectInput)(Display *, Window, int); typedef int (*PtrXRRUpdateConfiguration)(XEvent *); typedef int (*PtrXRRRootToScreen)(Display *, Window); typedef Bool (*PtrXRRQueryExtension)(Display *, int *, int *); +typedef XRRScreenSize *(*PtrXRRSizes)(Display *, int, int *); #endif // QT_NO_XRANDR #ifndef QT_NO_XINPUT @@ -710,6 +711,7 @@ struct QX11Data PtrXRRUpdateConfiguration ptrXRRUpdateConfiguration; PtrXRRRootToScreen ptrXRRRootToScreen; PtrXRRQueryExtension ptrXRRQueryExtension; + PtrXRRSizes ptrXRRSizes; #endif // QT_NO_XRANDR }; -- cgit v0.12 From b78ffe51f9a4c4ac705e435d45fffe39864c032d Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Wed, 15 Dec 2010 18:22:15 +0100 Subject: Use XRandR to get the real DPI values for the screen. This is needed for the Xomap server, but may also apply to others. Reviewed-by: Ralf Engels --- src/gui/util/qscroller.cpp | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/gui/util/qscroller.cpp b/src/gui/util/qscroller.cpp index 0955f58..f651a06 100644 --- a/src/gui/util/qscroller.cpp +++ b/src/gui/util/qscroller.cpp @@ -64,6 +64,10 @@ #include +#if defined(Q_WS_X11) +# include "private/qt_x11_p.h" +#endif + QT_BEGIN_NAMESPACE @@ -986,38 +990,46 @@ bool QScroller::handleInput(Input input, const QPointF &position, qint64 timesta return false; } -#ifdef Q_WS_MAEMO_5 +#if !defined(Q_WS_MAC) +// the Mac version is implemented in qscroller_mac.mm QPointF QScrollerPrivate::realDpi(int screen) { +# ifdef Q_WS_MAEMO_5 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 +# elif defined(Q_WS_X11) && !defined(QT_NO_XRANDR) + if (X11->use_xrandr && X11->ptrXRRSizes) { + int nsizes = 0; + XRRScreenSize *sizes = X11->ptrXRRSizes(X11->display, screen == -1 ? X11->defaultScreen : screen, &nsizes); + if (nsizes > 0 && sizes && sizes->width && sizes->height && sizes->mwidth && sizes->mheight) { + qScrollerDebug() << "XRandR DPI:" << QPointF(qreal(25.4) * qreal(sizes->width) / qreal(sizes->mwidth), + qreal(25.4) * qreal(sizes->height) / qreal(sizes->mheight)); + return QPointF(qreal(25.4) * qreal(sizes->width) / qreal(sizes->mwidth), + qreal(25.4) * qreal(sizes->height) / qreal(sizes->mheight)); + } + } +# endif -QPointF QScrollerPrivate::realDpi(int screen) -{ QWidget *w = QApplication::desktop()->screen(screen); return QPointF(w->physicalDpiX(), w->physicalDpiY()); } -#endif +#endif // !Q_WS_MAC + /*! \internal Returns the resolution of the used screen. */ QPointF QScrollerPrivate::dpi() const { - return pixelPerMeter / qreal(39.3700787); + return pixelPerMeter * qreal(0.0254); } /*! \internal @@ -1028,7 +1040,7 @@ QPointF QScrollerPrivate::dpi() const */ void QScrollerPrivate::setDpi(const QPointF &dpi) { - pixelPerMeter = dpi * qreal(39.3700787); + pixelPerMeter = dpi / qreal(0.0254); } /*! \internal -- cgit v0.12 From fe438d7d828021d7f86301af36fe8dff2768532a Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Wed, 15 Dec 2010 18:37:28 +0100 Subject: QScroller: nicer Overshoot bounce back animation. Reviewed-by: Ralf Engels --- src/gui/util/qscroller.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gui/util/qscroller.cpp b/src/gui/util/qscroller.cpp index f651a06..2ca4a6e 100644 --- a/src/gui/util/qscroller.cpp +++ b/src/gui/util/qscroller.cpp @@ -1367,9 +1367,8 @@ void QScrollerPrivate::createScrollingSegments(qreal v, qreal startPos, qreal pp 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); + pushSegment(ScrollTypeOvershoot, oDeltaTime * 0.3, stopPos, stopPos + oDistance, sp->scrollingCurve.type(), orientation); + pushSegment(ScrollTypeOvershoot, oDeltaTime * 0.7, stopPos + oDistance, stopPos, sp->scrollingCurve.type(), orientation); } return; } -- cgit v0.12 From df30d58de183d13c649ef7e0fbb8e2b3658e0862 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Wed, 15 Dec 2010 18:24:27 +0100 Subject: Removed obsolete Maemo 5 code --- src/gui/util/qscrollerproperties.cpp | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/src/gui/util/qscrollerproperties.cpp b/src/gui/util/qscrollerproperties.cpp index 4a1f085..2e52959 100644 --- a/src/gui/util/qscrollerproperties.cpp +++ b/src/gui/util/qscrollerproperties.cpp @@ -58,28 +58,6 @@ 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(10); - 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.8); @@ -104,7 +82,7 @@ QScrollerPropertiesPrivate *QScrollerPropertiesPrivate::defaults() spp.hOvershootPolicy = QScrollerProperties::OvershootWhenScrollable; spp.vOvershootPolicy = QScrollerProperties::OvershootWhenScrollable; spp.frameRate = QScrollerProperties::Standard; -#endif + systemDefaults = new QScrollerPropertiesPrivate(spp); } return new QScrollerPropertiesPrivate(userDefaults ? *userDefaults : *systemDefaults); -- cgit v0.12 From cb51c2157f870a5c83ae6d9435ec4b1004392bc9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 13 Dec 2010 22:26:39 +0100 Subject: Don't need to set FD_CLOEXEC since qt_safe_* will have done that. Reviewed-By: Trust Me --- src/network/socket/qnativesocketengine_unix.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index f6bfbac..021acd0 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -202,9 +202,6 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc return false; } - // Ensure that the socket is closed on exec*(). - ::fcntl(socket, F_SETFD, FD_CLOEXEC); - socketDescriptor = socket; return true; } @@ -565,16 +562,6 @@ int QNativeSocketEnginePrivate::nativeAccept() #else int acceptedDescriptor = qt_safe_accept(socketDescriptor, 0, 0); #endif - //check if we have valid descriptor at all - if(acceptedDescriptor > 0) { - // Ensure that the socket is closed on exec*() - ::fcntl(acceptedDescriptor, F_SETFD, FD_CLOEXEC); - } -#ifdef Q_OS_SYMBIAN - else { - qWarning("QNativeSocketEnginePrivate::nativeAccept() - acceptedDescriptor <= 0"); - } -#endif return acceptedDescriptor; } -- cgit v0.12 From e1955231478df8990cf8b1f80438abf957c5d6f2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 14 Dec 2010 11:25:32 +0100 Subject: Add a warning about trying to release a timer ID that isn't active Reviewed-By: Trust Me --- src/corelib/kernel/qeventdispatcher_unix.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index f50994c..b2ccc68 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -501,6 +501,7 @@ bool QTimerInfoList::unregisterTimer(int timerId) } } // id not found + qWarning("Application asked to unregister timer 0x%x which is not registered in this thread. Fix application.", timerId); return false; } -- cgit v0.12 From 038927f1208ff346cbe8d2cfefbd39808ffb5711 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Dec 2010 18:48:05 +0100 Subject: Autotest: Add some comments about this obscure test. More information, see commit d9bf386d917c64ad5d8f11f9daadf82b2be9d531 (old qt-history) and old TT task 90183. Reviewed-By: Trust Me --- tests/auto/qprocess/tst_qprocess.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp index fd310f4..13f1d26 100644 --- a/tests/auto/qprocess/tst_qprocess.cpp +++ b/tests/auto/qprocess/tst_qprocess.cpp @@ -1999,11 +1999,15 @@ void tst_QProcess::spaceInName() void tst_QProcess::lockupsInStartDetached() { #if !defined(Q_OS_SYMBIAN) - // What exactly is this call supposed to achieve anyway? + // Check that QProcess doesn't cause a lock up at this program's + // exit if a thread was started and we tried to run a program that + // doesn't exist. Before Qt 4.2, this used to lock up on Unix due + // to calling ::exit instead of ::_exit if execve failed. + QHostInfo::lookupHost(QString("something.invalid"), 0, 0); -#endif QProcess::execute("yjhbrty"); QProcess::startDetached("yjhbrty"); +#endif } //----------------------------------------------------------------------------- -- cgit v0.12 From 7b0809edf975f3226b43d3b43b5fe8035298fde9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Dec 2010 18:48:48 +0100 Subject: ICC: Don't print warning 1259 since it's too annoying. ICC 12 keeps outputting this when you copy a type of larger size to a smaller, or from int to float. --- mkspecs/linux-icc/qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf index af56a9a..ba707e23 100644 --- a/mkspecs/linux-icc/qmake.conf +++ b/mkspecs/linux-icc/qmake.conf @@ -23,7 +23,7 @@ QMAKE_YACC = yacc QMAKE_YACCFLAGS = -d QMAKE_CFLAGS = -falign-stack=maintain-16-byte QMAKE_CFLAGS_DEPS = -M -QMAKE_CFLAGS_WARN_ON = -w1 -Wcheck -wd654,1572,411,873,1125 +QMAKE_CFLAGS_WARN_ON = -w1 -Wcheck -wd654,1572,411,873,1125,2259 QMAKE_CFLAGS_WARN_OFF = -w QMAKE_CFLAGS_RELEASE = -O2 -falign-functions=16 -ansi-alias -fstrict-aliasing QMAKE_CFLAGS_DEBUG = -O0 -g -- cgit v0.12 From 981a83d7832e8cd1ee7bcd42dfaba62f0b04f2c1 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Dec 2010 18:53:57 +0100 Subject: Suppress a warning about killing a timer that isn't active. The timer was active, but it got killed by ~QObject. The QObject d-pointer is deleted after the timers (as is expected), which means that the QBasicTimer destructors in QAbstractItemViewPrivate are run after the timers are already gone. Reviewed-by: Trust Me --- src/gui/itemviews/qabstractitemview.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index acc8deb..177b088 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -595,6 +595,8 @@ QAbstractItemView::QAbstractItemView(QAbstractItemViewPrivate &dd, QWidget *pare */ QAbstractItemView::~QAbstractItemView() { + // stop this timer here before ~QObject + d_func()->delayedReset.stop(); } /*! -- cgit v0.12 From 017a5cfc6462317e6cca0f04a8339e2575bb9130 Mon Sep 17 00:00:00 2001 From: aavit Date: Wed, 15 Dec 2010 21:12:52 +0100 Subject: Satisfy the maketestselftest autotst --- tests/auto/other.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/other.pro b/tests/auto/other.pro index d1a7a86..512cd25 100644 --- a/tests/auto/other.pro +++ b/tests/auto/other.pro @@ -4,6 +4,7 @@ TEMPLATE=subdirs SUBDIRS=\ # exceptionsafety_objects \ shouldn't enable it +# baselineexample \ Just an example demonstrating qbaselinetest usage lancelot \ qaccessibility \ qalgorithms \ -- cgit v0.12 From fa57982fadab625fb022d32f690ef05427920581 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 16 Dec 2010 11:30:17 +0100 Subject: QmlDebugger: Fix runtime warnings about unregistered metatypes Check whether the type of a property is known to the metatype system before trying to read from it. That avoids lots of runtime warnings e.g. for the QSequentialGroup::currentAnimation property, which type QAbstractAnimation * isn't registered by default via qRegisterMetaType<>(). Reviewed-by: Christiaan Janssen Task-number: QTCREATORBUG-2853 --- src/declarative/qml/qdeclarativeenginedebug.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp index bffe681..e54f7d6 100644 --- a/src/declarative/qml/qdeclarativeenginedebug.cpp +++ b/src/declarative/qml/qdeclarativeenginedebug.cpp @@ -146,7 +146,10 @@ QDeclarativeEngineDebugServer::propertyData(QObject *obj, int propIdx) if (binding) rv.binding = binding->expression(); - QVariant value = prop.read(obj); + QVariant value; + if (prop.userType() != 0) { + value = prop.read(obj); + } rv.value = valueContents(value); if (QDeclarativeValueTypeFactory::isValueType(prop.userType())) { -- cgit v0.12 From 6f9642572c392536c07a52037e4c1de587489c49 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 16 Dec 2010 13:21:22 +0100 Subject: Add work around for bug when painting w/glTexSubImage into large texture It seems that copying small rectangles from glTexSubImage2D into a texture which is 2048x2048 is busted on some SGX drivers, even though the driver reports 2048 as the maximum texture size. This caused text to turn into flickering garbage once the texture glyph cache had grown to its max size (e.g. when painting very many Chinese glyphs.) To work around the problem, we hardcore the maximum texture height to 1024 on this driver so that the texture glyph cache is reset whenever that size is exceeded. Task-number: QT-3971 Done-with: Samuel --- src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp | 5 ++++- src/opengl/qgl.cpp | 1 + src/opengl/qgl_egl.cpp | 2 ++ src/opengl/qgl_p.h | 1 + 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 1b879c3..ba311c3 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -323,6 +323,9 @@ int QGLTextureGlyphCache::maxTextureWidth() const int QGLTextureGlyphCache::maxTextureHeight() const { - return ctx->d_ptr->maxTextureSize(); + if (ctx->d_ptr->workaround_brokenTexSubImage) + return qMin(1024, ctx->d_ptr->maxTextureSize()); + else + return ctx->d_ptr->maxTextureSize(); } QT_END_NAMESPACE diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 18f1203..9bf879a 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1706,6 +1706,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) active_engine = 0; workaround_needsFullClearOnEveryFrame = false; workaround_brokenFBOReadBack = false; + workaround_brokenTexSubImage = false; workaroundsCached = false; workaround_brokenTextureFromPixmap = false; diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index 8902099..6f9e39c 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -204,6 +204,8 @@ void QGLContext::makeCurrent() const char *egl_version = eglQueryString(d->eglContext->display(), EGL_VERSION); if (egl_version && strstr(egl_version, "1.3")) d->workaround_brokenFBOReadBack = true; + else if (egl_version && strstr(egl_version, "1.4")) + d->workaround_brokenTexSubImage = true; } } } diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index b46d428..bf830ba 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -401,6 +401,7 @@ public: // workarounds for driver/hw bugs on different platforms uint workaround_needsFullClearOnEveryFrame : 1; uint workaround_brokenFBOReadBack : 1; + uint workaround_brokenTexSubImage : 1; uint workaroundsCached : 1; uint workaround_brokenTextureFromPixmap : 1; -- cgit v0.12 From ab8a9e77d877fd53eaec8dca1eeca619a4ba81d6 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 16 Dec 2010 12:57:06 +0200 Subject: Avoid duplicate resize event No need to have two resize events in queue for same widget, so do not post a new one if one is already pending in QSymbianControl::SizeChanged(). Reviewed-by: Sami Merila --- src/gui/kernel/qapplication_s60.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 6db1fa8..181fcc7 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1174,8 +1174,10 @@ void QSymbianControl::SizeChanged() if (!slowResize && tlwExtra) tlwExtra->inTopLevelResize = false; } else { - QResizeEvent *e = new QResizeEvent(newSize, oldSize); - QApplication::postEvent(qwidget, e); + if (!qwidget->testAttribute(Qt::WA_PendingResizeEvent)) { + QResizeEvent *e = new QResizeEvent(newSize, oldSize); + QApplication::postEvent(qwidget, e); + } } } -- cgit v0.12 From f0347c8c0c37bd90dcaefb8f4b669096f7eb66b5 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 16 Dec 2010 15:23:51 +0200 Subject: Improved orientation change autotest The test wasn't even compiling anymore, so fixed that. Also added additional orientation change and an available geometry check after each orientation change. Reviewed-by: Sami Merila --- .../orientationchange/orientationchange.pro | 1 + .../orientationchange/tst_orientationchange.cpp | 43 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/tests/auto/symbian/orientationchange/orientationchange.pro b/tests/auto/symbian/orientationchange/orientationchange.pro index 08b34f9..98aa2ad 100644 --- a/tests/auto/symbian/orientationchange/orientationchange.pro +++ b/tests/auto/symbian/orientationchange/orientationchange.pro @@ -4,4 +4,5 @@ SOURCES += tst_orientationchange.cpp symbian { INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE + LIBS += -lcone -leikcore -lavkon # Screen orientation } diff --git a/tests/auto/symbian/orientationchange/tst_orientationchange.cpp b/tests/auto/symbian/orientationchange/tst_orientationchange.cpp index eb3709d..2ac2f7f 100644 --- a/tests/auto/symbian/orientationchange/tst_orientationchange.cpp +++ b/tests/auto/symbian/orientationchange/tst_orientationchange.cpp @@ -45,6 +45,8 @@ #include #include +#include +#include class tst_orientationchange : public QObject { @@ -151,6 +153,47 @@ void tst_orientationchange::resizeEventOnOrientationChange() } QCOMPARE(normalWidget->resizeEventCount, 0); + QDesktopWidget desktop; + QRect qtAvail = desktop.availableGeometry(normalWidget); + TRect clientRect = static_cast(CCoeEnv::Static()-> AppUi())->ClientRect(); + QRect symbianAvail = qt_TRect2QRect(clientRect); + QCOMPARE(qtAvail, symbianAvail); + + // Switch orientation back to original + orientation = orientation == CAknAppUi::EAppUiOrientationPortrait + ? CAknAppUi::EAppUiOrientationLandscape + : CAknAppUi::EAppUiOrientationPortrait; + + + fullScreenWidget->reset(); + maximizedWidget->reset(); + normalWidget->reset(); + + TRAP(err, appUi->SetOrientationL(orientation)); + + QCoreApplication::sendPostedEvents(); + QCoreApplication::sendPostedEvents(); + + // setOrientationL is not guaranteed to change orientation + // (if emulator configured to support just portrait or landscape, then + // setOrientationL call shouldn't do anything). + // So let's ensure that we do not get resize event twice. + + QVERIFY(fullScreenWidget->resizeEventCount <= 1); + if (fullScreenWidget->resizeEventCount) { + QCOMPARE(fullScreenWidget->size(), fullScreenWidget->resizeEventSize); + } + QVERIFY(maximizedWidget->resizeEventCount <= 1); + if (fullScreenWidget->resizeEventCount) { + QCOMPARE(maximizedWidget->size(), maximizedWidget->resizeEventSize); + } + QCOMPARE(normalWidget->resizeEventCount, 0); + + qtAvail = desktop.availableGeometry(normalWidget); + clientRect = static_cast(CCoeEnv::Static()-> AppUi())->ClientRect(); + symbianAvail = qt_TRect2QRect(clientRect); + QCOMPARE(qtAvail, symbianAvail); + TRAP(err, appUi->SetOrientationL(CAknAppUi::EAppUiOrientationUnspecified)); delete normalWidget; -- cgit v0.12 From 66eec88591be2e8369e73dc5c86148cb4b09fad8 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 13 Dec 2010 17:20:12 +0100 Subject: clarify setStatus() behavior Reviewed-by: mariusSO --- src/corelib/io/qdatastream.cpp | 3 +++ src/corelib/io/qtextstream.cpp | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp index 58f0190..dffb3c6 100644 --- a/src/corelib/io/qdatastream.cpp +++ b/src/corelib/io/qdatastream.cpp @@ -495,6 +495,9 @@ void QDataStream::resetStatus() /*! Sets the status of the data stream to the \a status given. + Subsequent calls to setStatus() are ignored until resetStatus() + is called. + \sa Status status() resetStatus() */ void QDataStream::setStatus(Status status) diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 6091ec0..f4731f9 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -1593,6 +1593,9 @@ void QTextStream::resetStatus() Sets the status of the text stream to the \a status given. + Subsequent calls to setStatus() are ignored until resetStatus() + is called. + \sa Status status() resetStatus() */ void QTextStream::setStatus(Status status) -- cgit v0.12 From ca062f6ed45acf83720faec8a211d9bf91705b2c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 16 Dec 2010 14:17:22 +0100 Subject: don't report flush error when we didn't flush in the first place this went unnoticed, as the return value is ignored - so far. Reviewed-by: mariusSO --- src/corelib/io/qtextstream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index f4731f9..560766a 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -693,7 +693,7 @@ bool QTextStreamPrivate::flushWriteBuffer() // flush the file #ifndef QT_NO_QOBJECT QFile *file = qobject_cast(device); - bool flushed = file && file->flush(); + bool flushed = !file || file->flush(); #else bool flushed = true; #endif -- cgit v0.12 From 9233143bb25e33c07f73b7d35b0d6cbd14ef1686 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 13 Dec 2010 17:57:55 +0100 Subject: add write error handling to QDataStream add new status flag WriteFailed. use it in all write functions. Task-number: QTBUG-376 Reviewed-by: mariusSO --- src/corelib/io/qdatastream.cpp | 55 +++++++++++++++++++----------- src/corelib/io/qdatastream.h | 3 +- tests/auto/qdatastream/tst_qdatastream.cpp | 51 +++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 20 deletions(-) diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp index dffb3c6..52ee252 100644 --- a/src/corelib/io/qdatastream.cpp +++ b/src/corelib/io/qdatastream.cpp @@ -243,6 +243,11 @@ QT_BEGIN_NAMESPACE } #endif +#define CHECK_STREAM_WRITE_PRECOND(retVal) \ + CHECK_STREAM_PRECOND(retVal) \ + if (q_status != Ok) \ + return retVal; + enum { DefaultStreamVersion = QDataStream::Qt_4_6 }; @@ -995,8 +1000,9 @@ int QDataStream::readRawData(char *s, int len) QDataStream &QDataStream::operator<<(qint8 i) { - CHECK_STREAM_PRECOND(*this) - dev->putChar(i); + CHECK_STREAM_WRITE_PRECOND(*this) + if (!dev->putChar(i)) + q_status = WriteFailed; return *this; } @@ -1018,11 +1024,12 @@ QDataStream &QDataStream::operator<<(qint8 i) QDataStream &QDataStream::operator<<(qint16 i) { - CHECK_STREAM_PRECOND(*this) + CHECK_STREAM_WRITE_PRECOND(*this) if (!noswap) { i = qbswap(i); } - dev->write((char *)&i, sizeof(qint16)); + if (dev->write((char *)&i, sizeof(qint16)) != sizeof(qint16)) + q_status = WriteFailed; return *this; } @@ -1035,11 +1042,12 @@ QDataStream &QDataStream::operator<<(qint16 i) QDataStream &QDataStream::operator<<(qint32 i) { - CHECK_STREAM_PRECOND(*this) + CHECK_STREAM_WRITE_PRECOND(*this) if (!noswap) { i = qbswap(i); } - dev->write((char *)&i, sizeof(qint32)); + if (dev->write((char *)&i, sizeof(qint32)) != sizeof(qint32)) + q_status = WriteFailed; return *this; } @@ -1060,7 +1068,7 @@ QDataStream &QDataStream::operator<<(qint32 i) QDataStream &QDataStream::operator<<(qint64 i) { - CHECK_STREAM_PRECOND(*this) + CHECK_STREAM_WRITE_PRECOND(*this) if (version() < 6) { quint32 i1 = i & 0xffffffff; quint32 i2 = i >> 32; @@ -1069,7 +1077,8 @@ QDataStream &QDataStream::operator<<(qint64 i) if (!noswap) { i = qbswap(i); } - dev->write((char *)&i, sizeof(qint64)); + if (dev->write((char *)&i, sizeof(qint64)) != sizeof(qint64)) + q_status = WriteFailed; } return *this; } @@ -1089,8 +1098,9 @@ QDataStream &QDataStream::operator<<(qint64 i) QDataStream &QDataStream::operator<<(bool i) { - CHECK_STREAM_PRECOND(*this) - dev->putChar(qint8(i)); + CHECK_STREAM_WRITE_PRECOND(*this) + if (!dev->putChar(qint8(i))) + q_status = WriteFailed; return *this; } @@ -1111,7 +1121,7 @@ QDataStream &QDataStream::operator<<(float f) return *this; } - CHECK_STREAM_PRECOND(*this) + CHECK_STREAM_WRITE_PRECOND(*this) float g = f; // fixes float-on-stack problem if (!noswap) { union { @@ -1122,7 +1132,8 @@ QDataStream &QDataStream::operator<<(float f) x.val2 = qbswap(x.val2); g = x.val1; } - dev->write((char *)&g, sizeof(float)); + if (dev->write((char *)&g, sizeof(float)) != sizeof(float)) + q_status = WriteFailed; return *this; } @@ -1144,10 +1155,11 @@ QDataStream &QDataStream::operator<<(double f) return *this; } - CHECK_STREAM_PRECOND(*this) + CHECK_STREAM_WRITE_PRECOND(*this) #ifndef Q_DOUBLE_FORMAT if (noswap) { - dev->write((char *)&f, sizeof(double)); + if (dev->write((char *)&f, sizeof(double)) != sizeof(double)) + q_status = WriteFailed; } else { union { double val1; @@ -1155,7 +1167,8 @@ QDataStream &QDataStream::operator<<(double f) } x; x.val1 = f; x.val2 = qbswap(x.val2); - dev->write((char *)&x.val2, sizeof(double)); + if (dev->write((char *)&x.val2, sizeof(double)) != sizeof(double)) + q_status = WriteFailed; } #else union { @@ -1184,7 +1197,8 @@ QDataStream &QDataStream::operator<<(double f) b[Q_DF(1)] = *p++; b[Q_DF(0)] = *p; } - dev->write(b, 8); + if (dev->write(b, 8) != 8) + q_status = WriteFailed; #endif return *this; } @@ -1224,7 +1238,7 @@ QDataStream &QDataStream::operator<<(const char *s) QDataStream &QDataStream::writeBytes(const char *s, uint len) { - CHECK_STREAM_PRECOND(*this) + CHECK_STREAM_WRITE_PRECOND(*this) *this << (quint32)len; // write length specifier if (len) writeRawData(s, len); @@ -1242,8 +1256,11 @@ QDataStream &QDataStream::writeBytes(const char *s, uint len) int QDataStream::writeRawData(const char *s, int len) { - CHECK_STREAM_PRECOND(-1) - return dev->write(s, len); + CHECK_STREAM_WRITE_PRECOND(-1) + int ret = dev->write(s, len); + if (ret != len) + q_status = WriteFailed; + return ret; } /*! diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h index 774c4bc..05248ac 100644 --- a/src/corelib/io/qdatastream.h +++ b/src/corelib/io/qdatastream.h @@ -101,7 +101,8 @@ public: enum Status { Ok, ReadPastEnd, - ReadCorruptData + ReadCorruptData, + WriteFailed }; enum FloatingPointPrecision { diff --git a/tests/auto/qdatastream/tst_qdatastream.cpp b/tests/auto/qdatastream/tst_qdatastream.cpp index c03bc71..898fb84 100644 --- a/tests/auto/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/qdatastream/tst_qdatastream.cpp @@ -168,6 +168,8 @@ private slots: void stream_atEnd_data(); void stream_atEnd(); + void stream_writeError(); + void stream_QByteArray2(); void setVersion_data(); @@ -2345,6 +2347,55 @@ void tst_QDataStream::stream_atEnd() } } +class FakeBuffer : public QBuffer +{ +protected: + qint64 writeData(const char *c, qint64 i) { return m_lock ? 0 : QBuffer::writeData(c, i); } +public: + FakeBuffer(bool locked = false) : m_lock(locked) {} + void setLocked(bool locked) { m_lock = locked; } +private: + bool m_lock; +}; + +#define TEST_WRITE_ERROR(op) \ + { \ + FakeBuffer fb(false); \ + QVERIFY(fb.open(QBuffer::ReadWrite)); \ + QDataStream fs(&fb); \ + fs.writeRawData("hello", 5); \ + /* first write some initial content */ \ + QCOMPARE(fs.status(), QDataStream::Ok); \ + QCOMPARE(fb.data(), QByteArray("hello")); \ + /* then test that writing can cause an error */ \ + fb.setLocked(true); \ + fs op; \ + QCOMPARE(fs.status(), QDataStream::WriteFailed); \ + QCOMPARE(fb.data(), QByteArray("hello")); \ + /* finally test that writing after an error doesn't change the stream any more */ \ + fb.setLocked(false); \ + fs op; \ + QCOMPARE(fs.status(), QDataStream::WriteFailed); \ + QCOMPARE(fb.data(), QByteArray("hello")); \ + } + +void tst_QDataStream::stream_writeError() +{ + TEST_WRITE_ERROR(<< true) + TEST_WRITE_ERROR(<< (qint8)1) + TEST_WRITE_ERROR(<< (quint8)1) + TEST_WRITE_ERROR(<< (qint16)1) + TEST_WRITE_ERROR(<< (quint16)1) + TEST_WRITE_ERROR(<< (qint32)1) + TEST_WRITE_ERROR(<< (quint32)1) + TEST_WRITE_ERROR(<< (qint64)1) + TEST_WRITE_ERROR(<< (quint64)1) + TEST_WRITE_ERROR(<< "hello") + TEST_WRITE_ERROR(<< (float)1.0) + TEST_WRITE_ERROR(<< (double)1.0) + TEST_WRITE_ERROR(.writeRawData("test", 4)) +} + void tst_QDataStream::stream_QByteArray2() { QByteArray ba; -- cgit v0.12 From 135a6e32522775b182e870130eb12502753c913c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 16 Dec 2010 12:36:41 +0100 Subject: add write error handling to QTextStream add new status flag WriteFailed. use it in flushWriteBuffer(). remove the boolean return values from write(), putString() and putNumber(), as they were ignored anyway - flushWriteBuffer() does it correctly now. Task-number: QTBUG-376 Reviewed-by: mariusSO --- src/corelib/io/qtextstream.cpp | 42 ++++++++++++++++++------------ src/corelib/io/qtextstream.h | 3 ++- tests/auto/qtextstream/tst_qtextstream.cpp | 37 ++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 560766a..242c672 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -396,19 +396,19 @@ public: npsInvalidPrefix }; - inline bool write(const QString &data); inline bool getChar(QChar *ch); inline void ungetChar(const QChar &ch); NumberParsingStatus getNumber(qulonglong *l); bool getReal(double *f); - bool putNumber(qulonglong number, bool negative); - inline bool putString(const QString &ch, bool number = false); + inline void write(const QString &data); + inline void putString(const QString &ch, bool number = false); + void putNumber(qulonglong number, bool negative); // buffers bool fillReadBuffer(qint64 maxBytes = -1); void resetReadBuffer(); - bool flushWriteBuffer(); + void flushWriteBuffer(); QString writeBuffer; QString readBuffer; int readBufferOffset; @@ -642,14 +642,20 @@ void QTextStreamPrivate::resetReadBuffer() /*! \internal */ -bool QTextStreamPrivate::flushWriteBuffer() +void QTextStreamPrivate::flushWriteBuffer() { // no buffer next to the QString itself; this function should only // be called internally, for devices. if (string || !device) - return false; + return; + + // Stream went bye-bye already. Appending further data may succeed again, + // but would create a corrupted stream anyway. + if (status != QTextStream::Ok) + return; + if (writeBuffer.isEmpty()) - return true; + return; #if defined (Q_OS_WIN) // handle text translation and bypass the Text flag in the device. @@ -681,8 +687,10 @@ bool QTextStreamPrivate::flushWriteBuffer() qDebug("QTextStreamPrivate::flushWriteBuffer(), device->write(\"%s\") == %d", qt_prettyDebug(data.constData(), qMin(data.size(),32), data.size()).constData(), int(bytesWritten)); #endif - if (bytesWritten <= 0) - return false; + if (bytesWritten <= 0) { + status = QTextStream::WriteFailed; + return; + } #if defined (Q_OS_WIN) // replace the text flag @@ -702,7 +710,8 @@ bool QTextStreamPrivate::flushWriteBuffer() qDebug("QTextStreamPrivate::flushWriteBuffer() wrote %d bytes", int(bytesWritten)); #endif - return flushed && bytesWritten == qint64(data.size()); + if (!flushed || bytesWritten != qint64(data.size())) + status = QTextStream::WriteFailed; } QString QTextStreamPrivate::read(int maxlen) @@ -908,7 +917,7 @@ inline void QTextStreamPrivate::restoreToSavedConverterState() /*! \internal */ -inline bool QTextStreamPrivate::write(const QString &data) +inline void QTextStreamPrivate::write(const QString &data) { if (string) { // ### What about seek()?? @@ -916,9 +925,8 @@ inline bool QTextStreamPrivate::write(const QString &data) } else { writeBuffer += data; if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE) - return flushWriteBuffer(); + flushWriteBuffer(); } - return true; } /*! \internal @@ -959,7 +967,7 @@ inline void QTextStreamPrivate::ungetChar(const QChar &ch) /*! \internal */ -inline bool QTextStreamPrivate::putString(const QString &s, bool number) +inline void QTextStreamPrivate::putString(const QString &s, bool number) { QString tmp = s; @@ -993,7 +1001,7 @@ inline bool QTextStreamPrivate::putString(const QString &s, bool number) qt_prettyDebug(a.constData(), a.size(), qMax(16, a.size())).constData(), qt_prettyDebug(b.constData(), b.size(), qMax(16, b.size())).constData()); #endif - return write(tmp); + write(tmp); } /*! @@ -2270,7 +2278,7 @@ QTextStream &QTextStream::operator>>(char *c) /*! \internal */ -bool QTextStreamPrivate::putNumber(qulonglong number, bool negative) +void QTextStreamPrivate::putNumber(qulonglong number, bool negative) { QString result; @@ -2310,7 +2318,7 @@ bool QTextStreamPrivate::putNumber(qulonglong number, bool negative) result.prepend(QLatin1Char('0')); } } - return putString(result, true); + putString(result, true); } /*! diff --git a/src/corelib/io/qtextstream.h b/src/corelib/io/qtextstream.h index d82da59..c635691 100644 --- a/src/corelib/io/qtextstream.h +++ b/src/corelib/io/qtextstream.h @@ -89,7 +89,8 @@ public: enum Status { Ok, ReadPastEnd, - ReadCorruptData + ReadCorruptData, + WriteFailed }; enum NumberFlag { ShowBase = 0x1, diff --git a/tests/auto/qtextstream/tst_qtextstream.cpp b/tests/auto/qtextstream/tst_qtextstream.cpp index 4c78ef0..005f686 100644 --- a/tests/auto/qtextstream/tst_qtextstream.cpp +++ b/tests/auto/qtextstream/tst_qtextstream.cpp @@ -228,6 +228,7 @@ private slots: void status_real_read(); void status_integer_read(); void status_word_read(); + void status_write_error(); // use case tests void useCase1(); @@ -4176,6 +4177,42 @@ void tst_QTextStream::status_word_read() QCOMPARE(s.status(), QTextStream::ReadPastEnd); } +class FakeBuffer : public QBuffer +{ +protected: + qint64 writeData(const char *c, qint64 i) { return m_lock ? 0 : QBuffer::writeData(c, i); } +public: + FakeBuffer(bool locked = false) : m_lock(locked) {} + void setLocked(bool locked) { m_lock = locked; } +private: + bool m_lock; +}; + +void tst_QTextStream::status_write_error() +{ + FakeBuffer fb(false); + QVERIFY(fb.open(QBuffer::ReadWrite)); + QTextStream fs(&fb); + fs.setCodec(QTextCodec::codecForName("latin1")); + /* first write some initial content */ + fs << "hello"; + fs.flush(); + QCOMPARE(fs.status(), QTextStream::Ok); + QCOMPARE(fb.data(), QByteArray("hello")); + /* then test that writing can cause an error */ + fb.setLocked(true); + fs << "error"; + fs.flush(); + QCOMPARE(fs.status(), QTextStream::WriteFailed); + QCOMPARE(fb.data(), QByteArray("hello")); + /* finally test that writing after an error doesn't change the stream any more */ + fb.setLocked(false); + fs << "can't do that"; + fs.flush(); + QCOMPARE(fs.status(), QTextStream::WriteFailed); + QCOMPARE(fb.data(), QByteArray("hello")); +} + void tst_QTextStream::task180679_alignAccountingStyle() { { -- cgit v0.12 From 7857e0cf4673fb0defab5af9c60d0c2dea93e55c Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 15 Dec 2010 18:55:48 +0100 Subject: Doc: typo fixed in doc/src/declarative/extending.qdoc Reviewed-by: TrustMe --- doc/src/declarative/extending.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index e23ca91..748ec6c 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -461,7 +461,7 @@ constructing an animation object and manually setting the animation's "target" property, a property value source can be assigned directly to a property of any type and automatically set up this association. -The example shown here is rather contrived: the \c announcment property of the +The example shown here is rather contrived: the \c announcement property of the \c BirthdayParty object is a string that is printed every time it is assigned and the \c HappyBirthdaySong value source generates the lyrics of the song "Happy Birthday". -- cgit v0.12 From ce3dabc8863440a56540d86537848621581afa7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Dec 2010 13:43:02 +0100 Subject: Make parent constructor argument optional Task-number: QTBUG-16100 Reviewed-by: Oswald Buddenhagen --- src/gui/widgets/qvalidator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qvalidator.h b/src/gui/widgets/qvalidator.h index 63734ca..af1b80f 100644 --- a/src/gui/widgets/qvalidator.h +++ b/src/gui/widgets/qvalidator.h @@ -101,7 +101,7 @@ class Q_GUI_EXPORT QIntValidator : public QValidator public: explicit QIntValidator(QObject * parent = 0); - QIntValidator(int bottom, int top, QObject * parent); + QIntValidator(int bottom, int top, QObject *parent = 0); ~QIntValidator(); QValidator::State validate(QString &, int &) const; -- cgit v0.12 From 632016368e26ba06d7d09740a8a1805f4ea911f1 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Fri, 17 Dec 2010 15:24:30 +1000 Subject: Update test bitmaps for QDeclarativeImage::svg() autotest on Linux Task-number: Reviewed-by: Martin Jones --- .../declarative/qdeclarativeimage/data/heart.png | Bin 12424 -> 12577 bytes .../declarative/qdeclarativeimage/data/heart200.png | Bin 7943 -> 8063 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/auto/declarative/qdeclarativeimage/data/heart.png b/tests/auto/declarative/qdeclarativeimage/data/heart.png index ff93f6c..abe97fe 100644 Binary files a/tests/auto/declarative/qdeclarativeimage/data/heart.png and b/tests/auto/declarative/qdeclarativeimage/data/heart.png differ diff --git a/tests/auto/declarative/qdeclarativeimage/data/heart200.png b/tests/auto/declarative/qdeclarativeimage/data/heart200.png index 5a31ae8..7fbb13c 100644 Binary files a/tests/auto/declarative/qdeclarativeimage/data/heart200.png and b/tests/auto/declarative/qdeclarativeimage/data/heart200.png differ -- cgit v0.12 From e0abcb2ff7a3044305580659f9a432a9630a5943 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Fri, 17 Dec 2010 16:18:03 +1000 Subject: Fix QDeclarativeState::reset() autotest Current state reset mechanism does not really work for Text elements as the keeping implicit correct would require relayouting of text twice (See bug QTBUG-15118). Changed QDeclarativeState reset autotest to use Image element instead of Text element until the issue has been fixed. Task-number: Reviewed-by: Yann Bodson --- tests/auto/declarative/qdeclarativestates/data/image.png | Bin 0 -> 173 bytes tests/auto/declarative/qdeclarativestates/data/reset.qml | 9 ++++----- .../qdeclarativestates/tst_qdeclarativestates.cpp | 13 ++++++------- 3 files changed, 10 insertions(+), 12 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativestates/data/image.png diff --git a/tests/auto/declarative/qdeclarativestates/data/image.png b/tests/auto/declarative/qdeclarativestates/data/image.png new file mode 100644 index 0000000..ed1833c Binary files /dev/null and b/tests/auto/declarative/qdeclarativestates/data/image.png differ diff --git a/tests/auto/declarative/qdeclarativestates/data/reset.qml b/tests/auto/declarative/qdeclarativestates/data/reset.qml index 8799c97..a140ffa 100644 --- a/tests/auto/declarative/qdeclarativestates/data/reset.qml +++ b/tests/auto/declarative/qdeclarativestates/data/reset.qml @@ -3,17 +3,16 @@ import QtQuick 1.0 Rectangle { width: 640 height: 480 - Text { - id: theText + Image { + id: image width: 40 - wrapMode: Text.WordWrap - text: "a text string that is longer than 40 pixels" + source: "image.png" } states: State { name: "state1" PropertyChanges { - target: theText + target: image width: undefined } } diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp index b8409a5..870842c 100644 --- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp +++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -1126,15 +1125,15 @@ void tst_qdeclarativestates::reset() QDeclarativeRectangle *rect = qobject_cast(c.create()); QVERIFY(rect != 0); - QDeclarativeText *text = rect->findChild(); - QVERIFY(text != 0); - QCOMPARE(text->width(), qreal(40.)); - QVERIFY(text->width() < text->height()); + QDeclarativeImage *image = rect->findChild(); + QVERIFY(image != 0); + QCOMPARE(image->width(), qreal(40.)); + QCOMPARE(image->height(), qreal(20.)); QDeclarativeItemPrivate::get(rect)->setState("state1"); - QVERIFY(text->width() > 41); - QVERIFY(text->width() > text->height()); + QCOMPARE(image->width(), 20.0); + QCOMPARE(image->height(), qreal(20.)); } void tst_qdeclarativestates::illegalObjectCreation() -- cgit v0.12 From 80eb3ebbfe24738163532494e8866ac20fd1b0e4 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 16 Dec 2010 16:03:13 +0200 Subject: Fix incorrect file name case for OpenGL libraries in symbian.conf. To support linux builds, file names must be cased correctly. Task-number: QT-4375 Reviewed-by: Miikka Heikkinen --- mkspecs/common/symbian/symbian.conf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 707335c..00cf0d7 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -70,12 +70,12 @@ QMAKE_LIBS_CORE = $$QMAKE_LIBS -lefsrv -lhal -lbafl QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE -lfbscli -lbitgdi -lgdi -lws32 -lapgrfx -lcone -leikcore -lmediaclientaudio -lapparc -lcentralrepository QMAKE_LIBS_NETWORK = QMAKE_LIBS_EGL = -llibEGL -QMAKE_LIBS_OPENGL = -llibglesv2 +QMAKE_LIBS_OPENGL = -llibGLESv2 QMAKE_LIBS_OPENGL_ES1 = -llibGLESv1_CM -QMAKE_LIBS_OPENGL_ES2 = -llibglesv2 -QMAKE_LIBS_OPENGL_QT = -llibglesv2 -lcone -lws32 +QMAKE_LIBS_OPENGL_ES2 = -llibGLESv2 +QMAKE_LIBS_OPENGL_QT = -llibGLESv2 -lcone -lws32 QMAKE_LIBS_OPENGL_ES1_QT = -llibGLESv1_CM -lcone -lws32 -QMAKE_LIBS_OPENGL_ES2_QT = -llibglesv2 -lcone -lws32 +QMAKE_LIBS_OPENGL_ES2_QT = -llibGLESv2 -lcone -lws32 QMAKE_LIBS_OPENVG = -llibOpenVG -lfbscli -lbitgdi -lgdi QMAKE_LIBS_THREAD = -llibpthread QMAKE_LIBS_COMPAT = -- cgit v0.12 From d238b0ba236da4c3c33c0707d8dd6f5e5903d6c0 Mon Sep 17 00:00:00 2001 From: Ville Pernu Date: Fri, 17 Dec 2010 11:08:53 +0200 Subject: Fix waitForOpened not working with already active configuration When an active QNetworkConfiguration is already in use (e.g. browser already open), the QNetworkSession::waitForOpened() did not work properly. Changed one if-statement in the function to adapt to the scenario. Reviewed-by: Perttu Pohjonen Task-number: QTBUG-565 --- src/network/bearer/qnetworksession.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp index 226c3c5..db1a37c 100644 --- a/src/network/bearer/qnetworksession.cpp +++ b/src/network/bearer/qnetworksession.cpp @@ -310,8 +310,9 @@ bool QNetworkSession::waitForOpened(int msecs) if (d->isOpen) return true; - if (d->state != Connecting) + if (!(d->state == Connecting || d->state == Connected)) { return false; + } QEventLoop* loop = new QEventLoop(this); QObject::connect(d, SIGNAL(quitPendingWaitsForOpened()), -- cgit v0.12 From b54efea2e97baac1d9442e829be2d6fb322c5085 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 17 Dec 2010 11:37:52 +0200 Subject: Use relative include instead of absolute in default qmake.conf Absolute include path breaks QtP releases which copy mkspecs under epoc32 and do not necessarily have the sources available in the original absolute path and can't patch the paths either at installation time. Task-number: QTBUG-16172 Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index c967dad..915a56d 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3267,8 +3267,14 @@ void Configure::generateConfigfiles() if (qmakeConfFile.open(QFile::WriteOnly | QFile::Text)) { QTextStream qmakeConfStream; qmakeConfStream.setDevice(&qmakeConfFile); + // While QMAKESPEC_ORIGINAL being relative or absolute doesn't matter for the + // primary use of this variable by qmake to identify the original mkspec, the + // variable is also used for few special cases where the absolute path is required. + // Conversely, the include of the original qmake.conf must be done using relative path, + // as some Qt binary deployments are done in a manner that doesn't allow for patching + // the paths at the installation time. qmakeConfStream << "QMAKESPEC_ORIGINAL=" << pltSpec << endl << endl; - qmakeConfStream << "include(" << pltSpec << "/qmake.conf)" << endl; + qmakeConfStream << "include(" << "../" << spec << "/qmake.conf)" << endl << endl; qmakeConfStream.flush(); qmakeConfFile.close(); } -- cgit v0.12 From 5daf1ab79e3dd906664a7af00b311ba7c3f51138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Dec 2010 16:24:11 +0100 Subject: Test doesn't need to depend on temp path Instead, use the current directory for creating test data. Reviewed-by: Oswald Buddenhagen --- tests/auto/qcompleter/tst_qcompleter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp index 650c328..abc86ec 100644 --- a/tests/auto/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/qcompleter/tst_qcompleter.cpp @@ -1455,7 +1455,7 @@ void tst_QCompleter::task247560_keyboardNavigation() void tst_QCompleter::QTBUG_14292_filesystem() { - QDir tmpDir = QDir::temp(); + QDir tmpDir = QDir::currentPath(); qsrand(QTime::currentTime().msec()); QString d = "tst_QCompleter_" + QString::number(qrand()); QVERIFY(tmpDir.mkdir(d)); -- cgit v0.12 From a97cf9553ff841dcfd45bbc85ff05b0aafd4a548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Dec 2010 16:31:34 +0100 Subject: tst_QCompleter: Clean up after one's self The utility class FileSystem uses the RAII idiom to clean up directories created for the purpose of the test. Rubber-stamped-by: Oswald Buddenhagen --- tests/auto/qcompleter/tst_qcompleter.cpp | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp index abc86ec..62e64be 100644 --- a/tests/auto/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/qcompleter/tst_qcompleter.cpp @@ -49,6 +49,7 @@ #include #include "../../shared/util.h" +#include "../../shared/filesystem.h" //TESTED_CLASS= //TESTED_FILES= @@ -1455,24 +1456,16 @@ void tst_QCompleter::task247560_keyboardNavigation() void tst_QCompleter::QTBUG_14292_filesystem() { + FileSystem fs; QDir tmpDir = QDir::currentPath(); + qsrand(QTime::currentTime().msec()); QString d = "tst_QCompleter_" + QString::number(qrand()); - QVERIFY(tmpDir.mkdir(d)); - -#if 0 - struct Cleanup { - QString dir; - ~Cleanup() { - qDebug() << dir << - QFile::remove(dir); } - } cleanup; - cleanup.dir = tmpDir.absolutePath()+"/" +d; -#endif + QVERIFY(fs.createDirectory(tmpDir.filePath(d))); QVERIFY(tmpDir.cd(d)); - QVERIFY(tmpDir.mkdir("hello")); - QVERIFY(tmpDir.mkdir("holla")); + QVERIFY(fs.createDirectory(tmpDir.filePath("hello"))); + QVERIFY(fs.createDirectory(tmpDir.filePath("holla"))); QLineEdit edit; QCompleter comp; @@ -1500,12 +1493,12 @@ void tst_QCompleter::QTBUG_14292_filesystem() QCOMPARE(comp.popup()->model()->rowCount(), 1); QTest::keyClick(&edit, 'r'); QTRY_VERIFY(!comp.popup()->isVisible()); - QVERIFY(tmpDir.mkdir("hero")); + QVERIFY(fs.createDirectory(tmpDir.filePath("hero"))); QTRY_VERIFY(comp.popup()->isVisible()); QCOMPARE(comp.popup()->model()->rowCount(), 1); QTest::keyClick(comp.popup(), Qt::Key_Escape); QTRY_VERIFY(!comp.popup()->isVisible()); - QVERIFY(tmpDir.mkdir("nothingThere")); + QVERIFY(fs.createDirectory(tmpDir.filePath("nothingThere"))); //there is no reason creating a file should open a popup, it did in Qt 4.7.0 QTest::qWait(60); QVERIFY(!comp.popup()->isVisible()); @@ -1522,7 +1515,7 @@ void tst_QCompleter::QTBUG_14292_filesystem() QTest::qWaitForWindowShown(&w); QTRY_VERIFY(!edit.hasFocus() && !comp.popup()->hasFocus()); - QVERIFY(tmpDir.mkdir("hemo")); + QVERIFY(fs.createDirectory(tmpDir.filePath("hemo"))); //there is no reason creating a file should open a popup, it did in Qt 4.7.0 QTest::qWait(60); QVERIFY(!comp.popup()->isVisible()); -- cgit v0.12 From c60a2a5e5136cfec74429114c6c74401fdda65a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Dec 2010 14:09:35 +0100 Subject: Windows Vista and 7 also have animated progress bars Which means they get paint events all the time. Reviewed-by: Jens Bache-Wiig --- tests/auto/qprogressbar/tst_qprogressbar.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/auto/qprogressbar/tst_qprogressbar.cpp b/tests/auto/qprogressbar/tst_qprogressbar.cpp index 7d94e3c..e042fb8 100644 --- a/tests/auto/qprogressbar/tst_qprogressbar.cpp +++ b/tests/auto/qprogressbar/tst_qprogressbar.cpp @@ -179,10 +179,15 @@ void tst_QProgressBar::format() bar.repainted = false; bar.setFormat("%v of %m (%p%)"); qApp->processEvents(); + #ifndef Q_WS_MAC - // The Mac scroll bar is animated, which means we get paint events all the time. + // Animated scroll bars get paint events all the time +#ifdef Q_OS_WIN + if (QSysInfo::WindowsVersion < QSysInfo::WV_VISTA) +#endif QVERIFY(!bar.repainted); #endif + QCOMPARE(bar.text(), QString("1 of 10 (10%)")); bar.setRange(5, 5); bar.setValue(5); -- cgit v0.12 From 912e8a2c90a200300feaef18beedd4e6af3e8623 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Fri, 17 Dec 2010 15:12:30 +0100 Subject: Draw focusrect through style proxy This function call was simply not converted to use the new proxy style, hence preventing people from overriding it properly. Reviewed-by: Andy Shaw Task-number: QTBUG-16127 --- src/gui/styles/qcommonstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 039a6da..296455b 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -2217,7 +2217,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, if (vopt->state & QStyle::State_HasFocus) { QStyleOptionFocusRect o; o.QStyleOption::operator=(*vopt); - o.rect = subElementRect(SE_ItemViewItemFocusRect, vopt, widget); + o.rect = proxy()->subElementRect(SE_ItemViewItemFocusRect, vopt, widget); o.state |= QStyle::State_KeyboardFocusChange; o.state |= QStyle::State_Item; QPalette::ColorGroup cg = (vopt->state & QStyle::State_Enabled) -- cgit v0.12 From 4d5029365ccc045522cb87582c2b2e1a36ed0d24 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 16 Dec 2010 17:06:23 +0100 Subject: document WriteFailed status codes (whoops) --- src/corelib/io/qdatastream.cpp | 1 + src/corelib/io/qtextstream.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp index 52ee252..73ce490 100644 --- a/src/corelib/io/qdatastream.cpp +++ b/src/corelib/io/qdatastream.cpp @@ -223,6 +223,7 @@ QT_BEGIN_NAMESPACE \value ReadPastEnd The data stream has read past the end of the data in the underlying device. \value ReadCorruptData The data stream has read corrupt data. + \value WriteFailed The data stream cannot write to the underlying device. */ /***************************************************************************** diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 242c672..3bdbf32 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -224,6 +224,7 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384; \value ReadPastEnd The text stream has read past the end of the data in the underlying device. \value ReadCorruptData The text stream has read corrupt data. + \value WriteFailed The text stream cannot write to the underlying device. \sa status() */ -- cgit v0.12 From 558fe9383ba0aecbec09cc411c0ebab132aac137 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 16 Dec 2010 17:28:24 +0100 Subject: make QXmlStreamWriterPrivate::write(const char *s) ascii-only it's only ever called with ascii data, and the input encoding semantics weren't all that clear anyway. Reviewed-by: denis --- src/corelib/xml/qxmlstream.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index 91c3a19..50703a4 100644 --- a/src/corelib/xml/qxmlstream.cpp +++ b/src/corelib/xml/qxmlstream.cpp @@ -3083,16 +3083,11 @@ void QXmlStreamWriterPrivate::writeEscaped(const QString &s, bool escapeWhitespa qWarning("QXmlStreamWriter: No device"); } - +// ASCII only! void QXmlStreamWriterPrivate::write(const char *s) { if (device) { -#ifndef QT_NO_TEXTCODEC - if (codec->mibEnum() != 106) - device->write(encoder->fromUnicode(QLatin1String(s))); - else -#endif - device->write(s, strlen(s)); + device->write(s, strlen(s)); } else if (stringDevice) { stringDevice->append(QLatin1String(s)); } else -- cgit v0.12 From 86246bfe354aaf03065cd78d7d5410e5097ada48 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 16 Dec 2010 17:30:52 +0100 Subject: remove some code duplication writeEscaped() can simply call write() once it's done escaping Reviewed-by: denis --- src/corelib/xml/qxmlstream.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index 50703a4..b29bd92 100644 --- a/src/corelib/xml/qxmlstream.cpp +++ b/src/corelib/xml/qxmlstream.cpp @@ -3070,17 +3070,7 @@ void QXmlStreamWriterPrivate::writeEscaped(const QString &s, bool escapeWhitespa escaped += QChar(c); } } - if (device) { -#ifdef QT_NO_TEXTCODEC - device->write(escaped.toLatin1(), escaped.size()); -#else - device->write(encoder->fromUnicode(escaped)); -#endif - } - else if (stringDevice) - stringDevice->append(escaped); - else - qWarning("QXmlStreamWriter: No device"); + write(escaped); } // ASCII only! -- cgit v0.12 From 468328468904d116a5ff70fd4c71c34e453e8593 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 16 Dec 2010 17:44:01 +0100 Subject: optimize writing string constants and byte arrays don't throw away the already known length just to call strlen() on it over and over again. Reviewed-by: denis --- src/corelib/xml/qxmlstream.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index b29bd92..3d8af9b 100644 --- a/src/corelib/xml/qxmlstream.cpp +++ b/src/corelib/xml/qxmlstream.cpp @@ -2965,7 +2965,8 @@ public: void write(const QStringRef &); void write(const QString &); void writeEscaped(const QString &, bool escapeWhitespace = false); - void write(const char *s); + void write(const char *s, int len); + template void write(const char (&s)[N]) { write(s, N - 1); } bool finishStartElement(bool contents = true); void writeStartElement(const QString &namespaceUri, const QString &name); QIODevice *device; @@ -3074,12 +3075,12 @@ void QXmlStreamWriterPrivate::writeEscaped(const QString &s, bool escapeWhitespa } // ASCII only! -void QXmlStreamWriterPrivate::write(const char *s) +void QXmlStreamWriterPrivate::write(const char *s, int len) { if (device) { - device->write(s, strlen(s)); + device->write(s, len); } else if (stringDevice) { - stringDevice->append(QLatin1String(s)); + stringDevice->append(QString::fromLatin1(s, len)); } else qWarning("QXmlStreamWriter: No device"); } @@ -3157,7 +3158,7 @@ void QXmlStreamWriterPrivate::indent(int level) { write("\n"); for (int i = level; i > 0; --i) - write(autoFormattingIndent.constData()); + write(autoFormattingIndent.constData(), autoFormattingIndent.length()); } @@ -3744,7 +3745,7 @@ void QXmlStreamWriter::writeStartDocument(const QString &version) #ifdef QT_NO_TEXTCODEC d->write("iso-8859-1"); #else - d->write(d->codec->name().constData()); + d->write(d->codec->name().constData(), d->codec->name().length()); #endif } d->write("\"?>"); @@ -3767,12 +3768,13 @@ void QXmlStreamWriter::writeStartDocument(const QString &version, bool standalon #ifdef QT_NO_TEXTCODEC d->write("iso-8859-1"); #else - d->write(d->codec->name().constData()); + d->write(d->codec->name().constData(), d->codec->name().length()); #endif } - d->write("\" standalone=\""); - d->write(standalone ? "yes" : "no"); - d->write("\"?>"); + if (standalone) + d->write("\" standalone=\"yes\"?>"); + else + d->write("\" standalone=\"no\"?>"); } -- cgit v0.12 From 8789d4bd9eaba3a90fb3a94edb71ad0c1e01dc66 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 16 Dec 2010 20:32:21 +0100 Subject: add error handling to QXmlStreamWriter introduce QXmlStreamWriter::hasError(). set the error flag when any write error occurs. ignore subsequent writes after the first error. Reviewed-by: denis --- src/corelib/xml/qxmlstream.cpp | 37 ++++++++++++-- src/corelib/xml/qxmlstream.h | 2 + tests/auto/qxmlstream/tst_qxmlstream.cpp | 82 ++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 5 deletions(-) diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index 3d8af9b..64a9857 100644 --- a/src/corelib/xml/qxmlstream.cpp +++ b/src/corelib/xml/qxmlstream.cpp @@ -2941,6 +2941,9 @@ QStringRef QXmlStreamReader::documentEncoding() const By default, QXmlStreamWriter encodes XML in UTF-8. Different encodings can be enforced using setCodec(). + If an error occurs while writing to the underlying device, hasError() + starts returning true and subsequent writes are ignored. + The \l{QXmlStream Bookmarks Example} illustrates how to use a stream writer to write an XML bookmark file (XBEL) that was previously read in by a QXmlStreamReader. @@ -2976,6 +2979,7 @@ public: uint inEmptyElement :1; uint lastWasStartElement :1; uint wroteSomething :1; + uint hasError :1; uint autoFormatting :1; QByteArray autoFormattingIndent; NamespaceDeclaration emptyNamespace; @@ -3008,6 +3012,7 @@ QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q) #endif inStartElement = inEmptyElement = false; wroteSomething = false; + hasError = false; lastWasStartElement = false; lastNamespaceDeclaration = 1; autoFormatting = false; @@ -3017,11 +3022,15 @@ QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q) void QXmlStreamWriterPrivate::write(const QStringRef &s) { if (device) { + if (hasError) + return; #ifdef QT_NO_TEXTCODEC - device->write(s.toString().toLatin1(), s.size()); + QByteArray bytes = s.toLatin1(); #else - device->write(encoder->fromUnicode(s.constData(), s.size())); + QByteArray bytes = encoder->fromUnicode(s.constData(), s.size()); #endif + if (device->write(bytes) != bytes.size()) + hasError = true; } else if (stringDevice) s.appendTo(stringDevice); @@ -3032,11 +3041,15 @@ void QXmlStreamWriterPrivate::write(const QStringRef &s) void QXmlStreamWriterPrivate::write(const QString &s) { if (device) { + if (hasError) + return; #ifdef QT_NO_TEXTCODEC - device->write(s.toLatin1(), s.size()); + QByteArray bytes = s.toLatin1(); #else - device->write(encoder->fromUnicode(s)); + QByteArray bytes = encoder->fromUnicode(s); #endif + if (device->write(bytes) != bytes.size()) + hasError = true; } else if (stringDevice) stringDevice->append(s); @@ -3078,7 +3091,10 @@ void QXmlStreamWriterPrivate::writeEscaped(const QString &s, bool escapeWhitespa void QXmlStreamWriterPrivate::write(const char *s, int len) { if (device) { - device->write(s, len); + if (hasError) + return; + if (device->write(s, len) != len) + hasError = true; } else if (stringDevice) { stringDevice->append(QString::fromLatin1(s, len)); } else @@ -3359,6 +3375,17 @@ int QXmlStreamWriter::autoFormattingIndent() const return d->autoFormattingIndent.count(' ') - d->autoFormattingIndent.count('\t'); } +/*! + Returns \c true if the stream failed to write to the underlying device. + + The error status is never reset. Writes happening after the error + occurred are ignored, even if the error condition is cleared. + */ +bool QXmlStreamWriter::hasError() const +{ + Q_D(const QXmlStreamWriter); + return d->hasError; +} /*! \overload diff --git a/src/corelib/xml/qxmlstream.h b/src/corelib/xml/qxmlstream.h index d7143bd..244d3d4 100644 --- a/src/corelib/xml/qxmlstream.h +++ b/src/corelib/xml/qxmlstream.h @@ -474,6 +474,8 @@ public: void writeCurrentToken(const QXmlStreamReader &reader); #endif + bool hasError() const; + private: Q_DISABLE_COPY(QXmlStreamWriter) Q_DECLARE_PRIVATE(QXmlStreamWriter) diff --git a/tests/auto/qxmlstream/tst_qxmlstream.cpp b/tests/auto/qxmlstream/tst_qxmlstream.cpp index 19e4b90..9e4f3ec 100644 --- a/tests/auto/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/qxmlstream/tst_qxmlstream.cpp @@ -574,6 +574,7 @@ private slots: void checkCommentIndentation() const; void checkCommentIndentation_data() const; void qtbug9196_crash() const; + void hasError() const; private: static QByteArray readFile(const QString &filename); @@ -1560,5 +1561,86 @@ void tst_QXmlStream::qtbug9196_crash() const } } +class FakeBuffer : public QBuffer +{ +protected: + qint64 writeData(const char *c, qint64 i) + { + qint64 ai = qMin(m_capacity, i); + m_capacity -= ai; + return ai ? QBuffer::writeData(c, ai) : 0; + } +public: + void setCapacity(int capacity) { m_capacity = capacity; } +private: + qint64 m_capacity; +}; + +void tst_QXmlStream::hasError() const +{ + { + FakeBuffer fb; + QVERIFY(fb.open(QBuffer::ReadWrite)); + fb.setCapacity(1000); + QXmlStreamWriter writer(&fb); + writer.writeStartDocument(); + writer.writeEndDocument(); + QVERIFY(!writer.hasError()); + QCOMPARE(fb.data(), QByteArray("\n")); + } + + { + // Failure caused by write(QString) + FakeBuffer fb; + QVERIFY(fb.open(QBuffer::ReadWrite)); + fb.setCapacity(strlen(" Date: Mon, 20 Dec 2010 10:32:54 +1000 Subject: Quiet unused parameter warnings. --- src/plugins/bearer/icd/qicdengine.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/bearer/icd/qicdengine.cpp b/src/plugins/bearer/icd/qicdengine.cpp index a5a183b..96827f3 100644 --- a/src/plugins/bearer/icd/qicdengine.cpp +++ b/src/plugins/bearer/icd/qicdengine.cpp @@ -966,6 +966,9 @@ void QIcdEngine::connectionStateSignalsSlot(QDBusMessage msg) void QIcdEngine::icdServiceOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner) { + Q_UNUSED(serviceName); + Q_UNUSED(oldOwner); + QMutexLocker locker(&mutex); if (newOwner.isEmpty()) { -- cgit v0.12 From 95b0418a7ee7aee9658fd19b363e73d583af0b04 Mon Sep 17 00:00:00 2001 From: Damian Jansen Date: Mon, 20 Dec 2010 13:09:48 +1000 Subject: Fix deployment of minehunt for Symbian Task: QT-4298 --- demos/declarative/minehunt/minehunt.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/declarative/minehunt/minehunt.pro b/demos/declarative/minehunt/minehunt.pro index 8a7fdc5..5929ecf 100644 --- a/demos/declarative/minehunt/minehunt.pro +++ b/demos/declarative/minehunt/minehunt.pro @@ -18,6 +18,6 @@ symbian:{ TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) qmlminehuntfiles.sources = MinehuntCore minehunt.qml - DEPLOYMENT = qmlminehuntfiles + DEPLOYMENT += qmlminehuntfiles } -- cgit v0.12 From 0aeebdc851682d2afd63494ddeafa4e745ad2b72 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Mon, 20 Dec 2010 14:30:09 +1000 Subject: Update docs on importing javascript files --- doc/src/declarative/javascriptblocks.qdoc | 4 +++- doc/src/declarative/modules.qdoc | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/src/declarative/javascriptblocks.qdoc b/doc/src/declarative/javascriptblocks.qdoc index 155bd6e..68cb392 100644 --- a/doc/src/declarative/javascriptblocks.qdoc +++ b/doc/src/declarative/javascriptblocks.qdoc @@ -99,7 +99,9 @@ resource, the component's \l {QDeclarativeComponent::status()}{status} is set to 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 -mapping between qualifiers and JavaScript files. +mapping between qualifiers and JavaScript files. (This also means qualifiers cannot +be named the same as built-in JavaScript objects such as \c Date and \c Math). + \section2 Code-Behind Implementation Files diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc index 011eb63..bf9f5fd 100644 --- a/doc/src/declarative/modules.qdoc +++ b/doc/src/declarative/modules.qdoc @@ -216,6 +216,8 @@ JavaScript files must always be imported with a named import: } \endqml +The qualifier ("MyScript" in the above example) must be unique within the QML document. +Unlike ordinary modules, multiple scripts cannot be imported into the same namespace. \section1 Writing a qmldir file -- cgit v0.12 From 327169a6a3fb0bac258cb878019734211a707cce Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Mon, 20 Dec 2010 14:30:27 +1000 Subject: Don't truncate image:// url strings prematurely Url fragments and queries were being removed from the image ids passed to QDeclarativeImageProvider. Task-number: QTBUG-16195 Reviewed-by: Martin Jones --- src/declarative/qml/qdeclarativeengine.cpp | 12 ++++-- src/declarative/qml/qdeclarativeimageprovider.cpp | 16 ++++++-- .../tst_qdeclarativeimageprovider.cpp | 46 ++++++++++++++++++++-- 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 201e675..cf3ea42 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -760,8 +760,10 @@ QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *s QImage image; QSharedPointer provider = imageProviders.value(url.host()); locker.unlock(); - if (provider) - image = provider->requestImage(url.path().mid(1), size, req_size); + if (provider) { + QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1); + image = provider->requestImage(imageId, size, req_size); + } return image; } @@ -771,8 +773,10 @@ QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize QPixmap pixmap; QSharedPointer provider = imageProviders.value(url.host()); locker.unlock(); - if (provider) - pixmap = provider->requestPixmap(url.path().mid(1), size, req_size); + if (provider) { + QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1); + pixmap = provider->requestPixmap(imageId, size, req_size); + } return pixmap; } diff --git a/src/declarative/qml/qdeclarativeimageprovider.cpp b/src/declarative/qml/qdeclarativeimageprovider.cpp index ef31be7..e3da645 100644 --- a/src/declarative/qml/qdeclarativeimageprovider.cpp +++ b/src/declarative/qml/qdeclarativeimageprovider.cpp @@ -182,13 +182,17 @@ QDeclarativeImageProvider::ImageType QDeclarativeImageProvider::imageType() cons Implement this method to return the image with \a id. The default implementation returns an empty image. + The \a id is the requested image source, with the "image:" scheme and + provider identifier removed. For example, if the image \l{Image::}{source} + was "image://myprovider/icons/home", the given \a id would be "icons/home". + The \a requestedSize corresponds to the \l {Image::sourceSize} requested by an Image element. If \a requestedSize is a valid size, the image returned should be of that size. In all cases, \a size must be set to the original size of the image. This - is used to set the \l {Item::}{width} and \l {Item::}{height} of image - elements that should be automatically sized to the loaded image. + is used to set the \l {Item::}{width} and \l {Item::}{height} of the + relevant \l Image if these values have not been set explicitly. \note this method may be called by multiple threads, so ensure the implementation of this method is reentrant. @@ -207,13 +211,17 @@ QImage QDeclarativeImageProvider::requestImage(const QString &id, QSize *size, c Implement this method to return the pixmap with \a id. The default implementation returns an empty pixmap. + The \a id is the requested image source, with the "image:" scheme and + provider identifier removed. For example, if the image \l{Image::}{source} + was "image://myprovider/icons/home", the given \a id would be "icons/home". + The \a requestedSize corresponds to the \l {Image::sourceSize} requested by an Image element. If \a requestedSize is a valid size, the image returned should be of that size. In all cases, \a size must be set to the original size of the image. This - is used to set the \l {Item::}{width} and \l {Item::}{height} of image - elements that should be automatically sized to the loaded image. + is used to set the \l {Item::}{width} and \l {Item::}{height} of the + relevant \l Image if these values have not been set explicitly. */ QPixmap QDeclarativeImageProvider::requestPixmap(const QString &id, QSize *size, const QSize& requestedSize) { diff --git a/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp b/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp index cd12e3a..5b214e6 100644 --- a/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp +++ b/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp @@ -100,6 +100,8 @@ public: QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize) { + lastImageId = id; + if (id == QLatin1String("no-such-file.png")) return QImage(); @@ -114,6 +116,7 @@ public: } bool *deleteWatch; + QString lastImageId; }; Q_DECLARE_METATYPE(TestQImageProvider*); @@ -134,6 +137,8 @@ public: QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize) { + lastImageId = id; + if (id == QLatin1String("no-such-file.png")) return QPixmap(); @@ -148,6 +153,7 @@ public: } bool *deleteWatch; + QString lastImageId; }; Q_DECLARE_METATYPE(TestQPixmapProvider*); @@ -164,22 +170,49 @@ QString tst_qdeclarativeimageprovider::newImageFileName() const void tst_qdeclarativeimageprovider::fillRequestTestsData(const QString &id) { QTest::addColumn("source"); + QTest::addColumn("imageId"); QTest::addColumn("properties"); QTest::addColumn("size"); QTest::addColumn("error"); - QTest::newRow(QTest::toString(id + " exists")) << newImageFileName() << "" << QSize(100,100) << ""; - QTest::newRow(QTest::toString(id + " scaled")) << newImageFileName() << "sourceSize: \"80x30\"" << QSize(80,30) << ""; + QString fileName = newImageFileName(); + QTest::newRow(QTest::toString(id + " simple test")) + << "image://test/" + fileName << fileName << "" << QSize(100,100) << ""; + + fileName = newImageFileName(); + QTest::newRow(QTest::toString(id + " url with no id")) + << "image://test/" + fileName << "" + fileName << "" << QSize(100,100) << ""; + + fileName = newImageFileName(); + QTest::newRow(QTest::toString(id + " url with path")) + << "image://test/test/path" + fileName << "test/path" + fileName << "" << QSize(100,100) << ""; + + fileName = newImageFileName(); + QTest::newRow(QTest::toString(id + " url with fragment")) + << "image://test/faq.html?#question13" + fileName << "faq.html?#question13" + fileName << "" << QSize(100,100) << ""; - QTest::newRow(QTest::toString(id + " missing")) << "image://test/no-such-file.png" << "" << QSize() + fileName = newImageFileName(); + QTest::newRow(QTest::toString(id + " url with query")) + << "image://test/cgi-bin/drawgraph.cgi?type=pie&color=green" + fileName << "cgi-bin/drawgraph.cgi?type=pie&color=green" + fileName + << "" << QSize(100,100) << ""; + + fileName = newImageFileName(); + QTest::newRow(QTest::toString(id + " scaled image")) + << "image://test/" + fileName << fileName << "sourceSize: \"80x30\"" << QSize(80,30) << ""; + + QTest::newRow(QTest::toString(id + " missing")) + << "image://test/no-such-file.png" << "no-such-file.png" << "" << QSize(100,100) << "file::2:1: QML Image: Failed to get image from provider: image://test/no-such-file.png"; - QTest::newRow(QTest::toString(id + " unknown provider")) << "image://bogus/exists.png" << "" << QSize() + + QTest::newRow(QTest::toString(id + " unknown provider")) + << "image://bogus/exists.png" << "" << "" << QSize() << "file::2:1: QML Image: Failed to get image from provider: image://bogus/exists.png"; } void tst_qdeclarativeimageprovider::runTest(bool async, QDeclarativeImageProvider *provider) { QFETCH(QString, source); + QFETCH(QString, imageId); QFETCH(QString, properties); QFETCH(QSize, size); QFETCH(QString, error); @@ -210,6 +243,11 @@ void tst_qdeclarativeimageprovider::runTest(bool async, QDeclarativeImageProvide QTRY_VERIFY(obj->status() == QDeclarativeImage::Ready); else QVERIFY(obj->status() == QDeclarativeImage::Ready); + if (QByteArray(QTest::currentDataTag()).startsWith("qimage")) + QCOMPARE(static_cast(provider)->lastImageId, imageId); + else + QCOMPARE(static_cast(provider)->lastImageId, imageId); + QCOMPARE(obj->width(), qreal(size.width())); QCOMPARE(obj->height(), qreal(size.height())); QCOMPARE(obj->pixmap().width(), size.width()); -- cgit v0.12 From 95e64de1827f9b2bae829d40756f7142c56c460f Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Mon, 20 Dec 2010 15:44:25 +1000 Subject: Update test bitmaps for QDeclarativeImage::svg() autotest on Windows Task-number: Reviewed-by: Martin Jones --- .../qdeclarativeimage/data/heart-win32.png | Bin 12457 -> 12621 bytes .../qdeclarativeimage/data/heart200-win32.png | Bin 7939 -> 8062 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/auto/declarative/qdeclarativeimage/data/heart-win32.png b/tests/auto/declarative/qdeclarativeimage/data/heart-win32.png index 5992e79..351da13 100644 Binary files a/tests/auto/declarative/qdeclarativeimage/data/heart-win32.png and b/tests/auto/declarative/qdeclarativeimage/data/heart-win32.png differ diff --git a/tests/auto/declarative/qdeclarativeimage/data/heart200-win32.png b/tests/auto/declarative/qdeclarativeimage/data/heart200-win32.png index 19b20a8..4976ff9 100644 Binary files a/tests/auto/declarative/qdeclarativeimage/data/heart200-win32.png and b/tests/auto/declarative/qdeclarativeimage/data/heart200-win32.png differ -- cgit v0.12 From 197ec350e4014330851a013501c6dde3068ac26f Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 20 Dec 2010 17:07:34 +1000 Subject: Setting TextInput.cursorPosition outside bounds crashed. Check bounds in TextInput and TextEdit. Task-number: QTBUG-16188 Reviewed-by: Bea Lam --- src/declarative/graphicsitems/qdeclarativetextedit.cpp | 2 ++ src/declarative/graphicsitems/qdeclarativetextinput.cpp | 2 ++ .../qdeclarativetextedit/tst_qdeclarativetextedit.cpp | 13 +++++++++++++ .../qdeclarativetextinput/tst_qdeclarativetextinput.cpp | 13 +++++++++++++ 4 files changed, 30 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index e05f4e4..4e16d24 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -643,6 +643,8 @@ int QDeclarativeTextEdit::cursorPosition() const void QDeclarativeTextEdit::setCursorPosition(int pos) { Q_D(QDeclarativeTextEdit); + if (pos < 0 || pos > d->text.length()) + return; QTextCursor cursor = d->control->textCursor(); if (cursor.position() == pos) return; diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index df103de..521e4ab 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -437,6 +437,8 @@ int QDeclarativeTextInput::cursorPosition() const void QDeclarativeTextInput::setCursorPosition(int cp) { Q_D(QDeclarativeTextInput); + if (cp < 0 || cp > d->control->text().length()) + return; d->control->moveCursor(cp); } diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index a7971cc..c7a51f7 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -652,6 +652,19 @@ void tst_qdeclarativetextedit::selection() QVERIFY(textEditObject->selectionEnd() == 0); QVERIFY(textEditObject->selectedText().isNull()); + // Verify invalid positions are ignored. + textEditObject->setCursorPosition(-1); + QVERIFY(textEditObject->cursorPosition() == 0); + QVERIFY(textEditObject->selectionStart() == 0); + QVERIFY(textEditObject->selectionEnd() == 0); + QVERIFY(textEditObject->selectedText().isNull()); + + textEditObject->setCursorPosition(textEditObject->text().count()+1); + QVERIFY(textEditObject->cursorPosition() == 0); + QVERIFY(textEditObject->selectionStart() == 0); + QVERIFY(textEditObject->selectionEnd() == 0); + QVERIFY(textEditObject->selectedText().isNull()); + //Test selection for(int i=0; i<= testStr.size(); i++) { textEditObject->select(0,i); diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp index 76e0102..7b2310a 100644 --- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp +++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp @@ -354,6 +354,19 @@ void tst_qdeclarativetextinput::selection() QVERIFY(textinputObject->selectionEnd() == 0); QVERIFY(textinputObject->selectedText().isNull()); + // Verify invalid positions are ignored. + textinputObject->setCursorPosition(-1); + QVERIFY(textinputObject->cursorPosition() == 0); + QVERIFY(textinputObject->selectionStart() == 0); + QVERIFY(textinputObject->selectionEnd() == 0); + QVERIFY(textinputObject->selectedText().isNull()); + + textinputObject->setCursorPosition(textinputObject->text().count()+1); + QVERIFY(textinputObject->cursorPosition() == 0); + QVERIFY(textinputObject->selectionStart() == 0); + QVERIFY(textinputObject->selectionEnd() == 0); + QVERIFY(textinputObject->selectedText().isNull()); + //Test selection for(int i=0; i<= testStr.size(); i++) { textinputObject->select(0,i); -- cgit v0.12 From 8605f528930744b2afc594c39afb146bd7ad4b54 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 20 Dec 2010 10:48:50 +0100 Subject: QIntValidator: provide default argument to parent For consistency. Reviewed-by: Joao Reviewed-by: Gabriel Task-number: 16100 --- src/gui/widgets/qvalidator.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/widgets/qvalidator.h b/src/gui/widgets/qvalidator.h index 63734ca..013387d 100644 --- a/src/gui/widgets/qvalidator.h +++ b/src/gui/widgets/qvalidator.h @@ -101,7 +101,7 @@ class Q_GUI_EXPORT QIntValidator : public QValidator public: explicit QIntValidator(QObject * parent = 0); - QIntValidator(int bottom, int top, QObject * parent); + QIntValidator(int bottom, int top, QObject *parent = 0); ~QIntValidator(); QValidator::State validate(QString &, int &) const; @@ -142,7 +142,7 @@ class Q_GUI_EXPORT QDoubleValidator : public QValidator public: explicit QDoubleValidator(QObject * parent = 0); - QDoubleValidator(double bottom, double top, int decimals, QObject * parent); + QDoubleValidator(double bottom, double top, int decimals, QObject *parent = 0); ~QDoubleValidator(); enum Notation { @@ -186,7 +186,7 @@ class Q_GUI_EXPORT QRegExpValidator : public QValidator public: explicit QRegExpValidator(QObject *parent = 0); - QRegExpValidator(const QRegExp& rx, QObject *parent); + QRegExpValidator(const QRegExp& rx, QObject *parent = 0); ~QRegExpValidator(); virtual QValidator::State validate(QString& input, int& pos) const; -- cgit v0.12 From 3677eabde5595194b6fc72cd395a1ae7560c5e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 20 Dec 2010 11:55:32 +0100 Subject: define FSCTL_SET_REPARSE_POINT in test header ... as was already done in windows engine implementation for FSCTL_*GET*_REPARSE_POINT. --- tests/shared/filesystem.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/shared/filesystem.h b/tests/shared/filesystem.h index 8274346..4775671 100644 --- a/tests/shared/filesystem.h +++ b/tests/shared/filesystem.h @@ -55,6 +55,9 @@ #define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) #endif #define REPARSE_MOUNTPOINT_HEADER_SIZE 8 +#ifndef FSCTL_SET_REPARSE_POINT +#define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) +#endif #endif struct FileSystem -- cgit v0.12 From 09317dda494a51d101723131c5a01af4149ac5de Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 20 Dec 2010 13:04:23 +0100 Subject: Micro-optimization for QSpanData::setup() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't call QColor::rgba() in a macro arg that gets evaluated multiple times. Reviewed-by: Samuel Rødal --- src/gui/painting/qpaintengine_raster.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 97dfddf..3186749 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -5152,7 +5152,8 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode case Qt::SolidPattern: { type = Solid; QColor c = qbrush_color(brush); - solid.color = PREMUL(ARGB_COMBINE_ALPHA(c.rgba(), alpha)); + QRgb rgba = c.rgba(); + solid.color = PREMUL(ARGB_COMBINE_ALPHA(rgba, alpha)); if ((solid.color & 0xff000000) == 0 && compositionMode == QPainter::CompositionMode_SourceOver) { type = None; -- cgit v0.12 From 48e7c71d1165f0c60f56e0b769b35df2658e8e96 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 20 Dec 2010 13:05:27 +0100 Subject: Make the QRasterPaintEngineState copy constructor cheaper. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use initializer syntax to avoid default-constructing a throwaway QBrush and QPen. Reviewed-by: Samuel Rødal --- src/gui/painting/qpaintengine_raster.cpp | 34 ++++++++++++-------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 3186749..7fc90b8 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -662,31 +662,23 @@ QRasterPaintEngineState::QRasterPaintEngineState() QRasterPaintEngineState::QRasterPaintEngineState(QRasterPaintEngineState &s) : QPainterState(s) + , stroker(s.stroker) + , lastBrush(s.lastBrush) + , brushData(s.brushData) + , lastPen(s.lastPen) + , penData(s.penData) + , fillFlags(s.fillFlags) + , strokeFlags(s.strokeFlags) + , pixmapFlags(s.pixmapFlags) + , intOpacity(s.intOpacity) + , txscale(s.txscale) + , flag_bits(s.flag_bits) + , clip(s.clip) + , dirty(s.dirty) { - stroker = s.stroker; - - lastBrush = s.lastBrush; - brushData = s.brushData; brushData.tempImage = 0; - - lastPen = s.lastPen; - penData = s.penData; penData.tempImage = 0; - - fillFlags = s.fillFlags; - strokeFlags = s.strokeFlags; - pixmapFlags = s.pixmapFlags; - - intOpacity = s.intOpacity; - - txscale = s.txscale; - - flag_bits = s.flag_bits; - - clip = s.clip; flags.has_clip_ownership = false; - - dirty = s.dirty; } /*! -- cgit v0.12 From daba2c507ad42c66dafa6a29cffa94e9641e0c58 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Mon, 20 Dec 2010 14:26:39 +0100 Subject: Delay creation of the process manager The *nix process manager would create a pipe on every startup. In order to improve startup speed, the QProcessManager is now created when first needed. Reviewed-by: Robert Griebl --- src/corelib/io/qprocess_unix.cpp | 30 ++++++++++++++++++++++++++---- src/corelib/kernel/qcoreapplication.cpp | 18 ++++++++++++------ src/corelib/kernel/qcoreapplication.h | 1 + src/corelib/kernel/qcoreapplication_p.h | 2 ++ 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 216c382..e52d132 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -169,17 +169,27 @@ private: Q_GLOBAL_STATIC(QMutex, processManagerGlobalMutex) -static QProcessManager *processManager() { +static QProcessManager *processManagerInstance = 0; + +static QProcessManager *processManager() +{ // The constructor of QProcessManager should be called only once // so we cannot use Q_GLOBAL_STATIC directly for QProcessManager QMutex *mutex = processManagerGlobalMutex(); QMutexLocker locker(mutex); - static QProcessManager processManager; - return &processManager; + + if (!processManagerInstance) + QProcessPrivate::initializeProcessManager(); + + Q_ASSERT(processManagerInstance); + return processManagerInstance; } QProcessManager::QProcessManager() { + // can only be called from main thread + Q_ASSERT(!qApp || qApp->thread() == QThread::currentThread()); + #if defined (QPROCESS_DEBUG) qDebug() << "QProcessManager::QProcessManager()"; #endif @@ -198,6 +208,8 @@ QProcessManager::QProcessManager() ::sigaction(SIGCHLD, &action, &oldAction); if (oldAction.sa_handler != qt_sa_sigchld_handler) qt_sa_old_sigchld_handler = oldAction.sa_handler; + + processManagerInstance = this; } QProcessManager::~QProcessManager() @@ -226,6 +238,8 @@ QProcessManager::~QProcessManager() if (oldAction.sa_handler != qt_sa_sigchld_handler) { ::sigaction(SIGCHLD, &oldAction, 0); } + + processManagerInstance = 0; } void QProcessManager::run() @@ -1289,7 +1303,15 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a void QProcessPrivate::initializeProcessManager() { - (void) processManager(); + if (qApp && qApp->thread() != QThread::currentThread()) { + // The process manager must be initialized in the main thread + // Note: The call below will re-enter this function, but in the right thread, + // so the else statement below will be executed. + QMetaObject::invokeMethod(qApp, "_q_initializeProcessManager", Qt::BlockingQueuedConnection); + } else { + static QProcessManager processManager; + Q_UNUSED(processManager); + } } QT_END_NAMESPACE diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 0f95ee0..799433b 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -336,6 +336,16 @@ void QCoreApplicationPrivate::createEventDispatcher() #endif } +void QCoreApplicationPrivate::_q_initializeProcessManager() +{ +#ifndef QT_NO_PROCESS +# ifdef Q_OS_UNIX + QProcessPrivate::initializeProcessManager(); +# endif +#endif +} + + QThread *QCoreApplicationPrivate::theMainThread = 0; QThread *QCoreApplicationPrivate::mainThread() { @@ -600,12 +610,6 @@ void QCoreApplication::init() } #endif -#if defined(Q_OS_UNIX) && !(defined(QT_NO_PROCESS)) - // Make sure the process manager thread object is created in the main - // thread. - QProcessPrivate::initializeProcessManager(); -#endif - #ifdef QT_EVAL extern void qt_core_eval_init(uint); qt_core_eval_init(d->application_type); @@ -2666,3 +2670,5 @@ int QCoreApplication::loopLevel() */ QT_END_NAMESPACE + +#include "moc_qcoreapplication.cpp" diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index f1c7c26..17e784e 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -205,6 +205,7 @@ protected: QCoreApplication(QCoreApplicationPrivate &p); private: + Q_PRIVATE_SLOT(d_func(), void _q_initializeProcessManager()) static bool sendSpontaneousEvent(QObject *receiver, QEvent *event); bool notifyInternal(QObject *receiver, QEvent *event); diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 2355c37..aafa821 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -82,6 +82,8 @@ public: bool sendThroughObjectEventFilters(QObject *, QEvent *); bool notify_helper(QObject *, QEvent *); + void _q_initializeProcessManager(); + virtual QString appName() const; virtual void createEventDispatcher(); static void removePostedEvent(QEvent *); -- cgit v0.12 From cb44818623d10d5d6a9f49ddf5651351ebe55f67 Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Mon, 20 Dec 2010 14:40:51 +0100 Subject: Fix the redirection of painting for the toolbar. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-16154 Reviewed-by: Samuel Rødal --- src/gui/painting/qunifiedtoolbarsurface_mac.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp index ace0a46..02ba8db 100644 --- a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp +++ b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp @@ -83,11 +83,11 @@ void QUnifiedToolbarSurface::recursiveRedirect(QObject *object, const QPoint &of widget->d_func()->unifiedSurface = this; widget->d_func()->isInUnifiedToolbar = true; widget->d_func()->toolbar_offset = offset; - } - } - for (int i = 0; i < object->children().size(); ++i) { - recursiveRedirect(object->children().at(i), offset); + for (int i = 0; i < object->children().size(); ++i) { + recursiveRedirect(object->children().at(i), offset); + } + } } } } -- cgit v0.12 From e679392978c21266ec0bf6f960ab8c5f0621e18b Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 30 Sep 2010 17:29:40 +0200 Subject: Add QElapsedTimer::nsecsElapsed() const Allow sub-millisecond resolution on systems where it is possible. On UNIX, with monotonic clock support we get full nanosecond resolution, microsecond otherwise. On Windows we convert the performance counters to nanoseconds if availble, otherwise we only have millisecond resolution. On Mac, the mach time is converted to nanoseconds. On Symbian, we have microsecond resolution. Reviewed-by: joao --- src/corelib/tools/qelapsedtimer.h | 1 + src/corelib/tools/qelapsedtimer_generic.cpp | 16 ++++++++++++++++ src/corelib/tools/qelapsedtimer_mac.cpp | 6 ++++++ src/corelib/tools/qelapsedtimer_symbian.cpp | 22 +++++++++++----------- src/corelib/tools/qelapsedtimer_unix.cpp | 11 +++++++++++ src/corelib/tools/qelapsedtimer_win.cpp | 20 +++++++++++++------- tests/auto/qelapsedtimer/tst_qelapsedtimer.cpp | 7 ++++++- 7 files changed, 64 insertions(+), 19 deletions(-) diff --git a/src/corelib/tools/qelapsedtimer.h b/src/corelib/tools/qelapsedtimer.h index b996f6a..4118389 100644 --- a/src/corelib/tools/qelapsedtimer.h +++ b/src/corelib/tools/qelapsedtimer.h @@ -68,6 +68,7 @@ public: void invalidate(); bool isValid() const; + qint64 nsecsElapsed() const; qint64 elapsed() const; bool hasExpired(qint64 timeout) const; diff --git a/src/corelib/tools/qelapsedtimer_generic.cpp b/src/corelib/tools/qelapsedtimer_generic.cpp index 85986e6..740f496 100644 --- a/src/corelib/tools/qelapsedtimer_generic.cpp +++ b/src/corelib/tools/qelapsedtimer_generic.cpp @@ -103,6 +103,22 @@ qint64 QElapsedTimer::restart() return t1 - old; } +/*! \since 4.8 + + Returns the number of nanoseconds since this QElapsedTimer was last + started. Calling this function in a QElapsedTimer that was invalidated + will result in undefined results. + + On platforms that do not provide nanosecond resolution, the value returned + will be the best estimate available. + + \sa start(), restart(), hasExpired(), invalidate() +*/ +qint64 QElapsedTimer::nsecsElapsed() const +{ + return elapsed() * 1000000; +} + /*! Returns the number of milliseconds since this QElapsedTimer was last started. Calling this function in a QElapsedTimer that was invalidated diff --git a/src/corelib/tools/qelapsedtimer_mac.cpp b/src/corelib/tools/qelapsedtimer_mac.cpp index 8fceb49..e51f8b3 100644 --- a/src/corelib/tools/qelapsedtimer_mac.cpp +++ b/src/corelib/tools/qelapsedtimer_mac.cpp @@ -97,6 +97,12 @@ qint64 QElapsedTimer::restart() return absoluteToMSecs(t1 - old); } +qint64 QElapsedTimer::nsecsElapsed() const +{ + uint64_t cpu_time = mach_absolute_time(); + return absoluteToNSecs(cpu_time - t1); +} + qint64 QElapsedTimer::elapsed() const { uint64_t cpu_time = mach_absolute_time(); diff --git a/src/corelib/tools/qelapsedtimer_symbian.cpp b/src/corelib/tools/qelapsedtimer_symbian.cpp index 038b102..7cd5f1e 100644 --- a/src/corelib/tools/qelapsedtimer_symbian.cpp +++ b/src/corelib/tools/qelapsedtimer_symbian.cpp @@ -64,11 +64,6 @@ static quint64 getMicrosecondFromTick() return nanokernel_tick_period * (val | (quint64(highdword) << 32)); } -static quint64 getMillisecondFromTick() -{ - return getMicrosecondFromTick() / 1000; -} - timeval qt_gettime() { timeval tv; @@ -91,36 +86,41 @@ bool QElapsedTimer::isMonotonic() void QElapsedTimer::start() { - t1 = getMillisecondFromTick(); + t1 = getMicrosecondFromTick(); t2 = 0; } qint64 QElapsedTimer::restart() { qint64 oldt1 = t1; - t1 = getMillisecondFromTick(); + t1 = getMicrosecondFromTick(); t2 = 0; return t1 - oldt1; } +qint64 QElapsedTimer::nsecsElapsed() const +{ + return (getMicrosecondFromTick() - t1) * 1000; +} + qint64 QElapsedTimer::elapsed() const { - return getMillisecondFromTick() - t1; + return (getMicrosecondFromTick() - t1) / 1000; } qint64 QElapsedTimer::msecsSinceReference() const { - return t1; + return t1 / 1000; } qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const { - return other.t1 - t1; + return (other.t1 - t1) / 1000; } qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const { - return msecsTo(other) / 1000; + return msecsTo(other) / 1000000; } bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) diff --git a/src/corelib/tools/qelapsedtimer_unix.cpp b/src/corelib/tools/qelapsedtimer_unix.cpp index 633fa00..7407e1b 100644 --- a/src/corelib/tools/qelapsedtimer_unix.cpp +++ b/src/corelib/tools/qelapsedtimer_unix.cpp @@ -167,6 +167,17 @@ qint64 QElapsedTimer::restart() return elapsedAndRestart(t1, t2, &t1, &t2); } +qint64 QElapsedTimer::nsecsElapsed() const +{ + qint64 sec, frac; + do_gettime(&sec, &frac); + sec = sec - t1; + frac = frac - t2; + if (!monotonicClockAvailable) + frac *= 1000; + return sec * Q_INT64_C(1000000000) + frac; +} + qint64 QElapsedTimer::elapsed() const { qint64 sec, frac; diff --git a/src/corelib/tools/qelapsedtimer_win.cpp b/src/corelib/tools/qelapsedtimer_win.cpp index c77acaa..3f4acc1 100644 --- a/src/corelib/tools/qelapsedtimer_win.cpp +++ b/src/corelib/tools/qelapsedtimer_win.cpp @@ -79,14 +79,14 @@ static void resolveLibs() done = true; } -static inline qint64 ticksToMilliseconds(qint64 ticks) +static inline qint64 ticksToNanoseconds(qint64 ticks) { if (counterFrequency > 0) { // QueryPerformanceCounter uses an arbitrary frequency - return ticks * 1000 / counterFrequency; + return ticks * 1000000000 / counterFrequency; } else { // GetTickCount(64) return milliseconds - return ticks; + return ticks * 1000000; } } @@ -144,24 +144,30 @@ qint64 QElapsedTimer::restart() qint64 oldt1 = t1; t1 = getTickCount(); t2 = 0; - return ticksToMilliseconds(t1 - oldt1); + return ticksToNanoseconds(t1 - oldt1) / 1000000; +} + +qint64 QElapsedTimer::nsecsElapsed() const +{ + qint64 elapsed = getTickCount() - t1; + return ticksToNanoseconds(elapsed); } qint64 QElapsedTimer::elapsed() const { qint64 elapsed = getTickCount() - t1; - return ticksToMilliseconds(elapsed); + return ticksToNanoseconds(elapsed) / 1000000; } qint64 QElapsedTimer::msecsSinceReference() const { - return ticksToMilliseconds(t1); + return ticksToNanoseconds(t1) / 1000000; } qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const { qint64 difference = other.t1 - t1; - return ticksToMilliseconds(difference); + return ticksToNanoseconds(difference) / 1000000; } qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const diff --git a/tests/auto/qelapsedtimer/tst_qelapsedtimer.cpp b/tests/auto/qelapsedtimer/tst_qelapsedtimer.cpp index 87df57d..bc61f52 100644 --- a/tests/auto/qelapsedtimer/tst_qelapsedtimer.cpp +++ b/tests/auto/qelapsedtimer/tst_qelapsedtimer.cpp @@ -122,11 +122,13 @@ void tst_QElapsedTimer::basics() quint64 value1 = t1.msecsSinceReference(); qDebug() << value1 << t1; + qint64 nsecs = t1.nsecsElapsed(); qint64 elapsed = t1.restart(); QVERIFY(elapsed < minResolution); + QVERIFY(nsecs / 1000000 < minResolution); quint64 value2 = t1.msecsSinceReference(); - qDebug() << value2 << t1 << elapsed; + qDebug() << value2 << t1 << elapsed << nsecs; // in theory, elapsed == value2 - value1 // However, since QElapsedTimer keeps internally the full resolution, @@ -150,7 +152,10 @@ void tst_QElapsedTimer::elapsed() // don't check: t1.secsTo(t2) // QVERIFY(t1 - t2 < 0); + QVERIFY(t1.nsecsElapsed() > 0); QVERIFY(t1.elapsed() > 0); + // the number of elapsed nanoseconds and milliseconds should match + QVERIFY(t1.nsecsElapsed() - t1.elapsed() * 1000000 < 1000000); QVERIFY(t1.hasExpired(minResolution)); QVERIFY(!t1.hasExpired(8*minResolution)); QVERIFY(!t2.hasExpired(minResolution)); -- cgit v0.12 From df5403e48df3ab57924a6b85d9cbaa95e3c5e766 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 16 Sep 2010 10:36:22 +0200 Subject: Removed QMutexPrivate::self() declaration This function is not used or implemented anywhere. Reviewed-by: joao --- src/corelib/thread/qmutex_p.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h index 6126423..57a6062 100644 --- a/src/corelib/thread/qmutex_p.h +++ b/src/corelib/thread/qmutex_p.h @@ -65,7 +65,6 @@ public: QMutexPrivate(QMutex::RecursionMode mode); ~QMutexPrivate(); - ulong self(); bool wait(int timeout = -1); void wakeUp(); -- cgit v0.12 From 33b015ae5fe561e48130b07e1ae320131cec3505 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Tue, 28 Sep 2010 11:39:17 +0200 Subject: Add a benchmark for contended and uncontended QMutex performance This benchmark also includes the same benchmark for the native type for comparison. Reviewed-by: joao --- tests/benchmarks/corelib/thread/qmutex/qmutex.pro | 2 +- .../corelib/thread/qmutex/tst_qmutex.cpp | 272 ++++++++++++++++++++- 2 files changed, 261 insertions(+), 13 deletions(-) diff --git a/tests/benchmarks/corelib/thread/qmutex/qmutex.pro b/tests/benchmarks/corelib/thread/qmutex/qmutex.pro index eda2f11..8fda5fa 100644 --- a/tests/benchmarks/corelib/thread/qmutex/qmutex.pro +++ b/tests/benchmarks/corelib/thread/qmutex/qmutex.pro @@ -1,6 +1,6 @@ load(qttest_p4) TEMPLATE = app TARGET = tst_bench_qmutex - +QT -= gui SOURCES += tst_qmutex.cpp diff --git a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp index fded508..9ed5d55 100644 --- a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp +++ b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp @@ -39,34 +39,85 @@ ** ****************************************************************************/ -#include -#include +#include +#include #include -//TESTED_FILES= +#ifdef Q_OS_UNIX +# include +# include +typedef pthread_mutex_t NativeMutexType; +void NativeMutexInitialize(NativeMutexType *mutex) +{ + pthread_mutex_init(mutex, NULL); +} +void NativeMutexDestroy(NativeMutexType *mutex) +{ + pthread_mutex_destroy(mutex); +} +void NativeMutexLock(NativeMutexType *mutex) +{ + pthread_mutex_lock(mutex); +} +void NativeMutexUnlock(NativeMutexType *mutex) +{ + pthread_mutex_unlock(mutex); +} +#elif defined(Q_OS_WIN) +# define _WIN32_WINNT 0x0400 +# include +typedef CRITICAL_SECTION NativeMutexType; +void NativeMutexInitialize(NativeMutexType *mutex) +{ + InitializeCriticalSection(mutex); +} +void NativeMutexDestroy(NativeMutexType *mutex) +{ + DeleteCriticalSection(mutex); +} +void NativeMutexLock(NativeMutexType *mutex) +{ + EnterCriticalSection(mutex); +} +void NativeMutexUnlock(NativeMutexType *mutex) +{ + LeaveCriticalSection(mutex); +} +#endif +//TESTED_FILES= class tst_QMutex : public QObject { Q_OBJECT + int threadCount; + public: - tst_QMutex(); - virtual ~tst_QMutex(); + tst_QMutex() + { + // at least 2 threads, even on single cpu/core machines + threadCount = qMax(2, QThread::idealThreadCount()); + qDebug("thread count: %d", threadCount); + } private slots: void noThread_data(); void noThread(); -}; -tst_QMutex::tst_QMutex() -{ -} + void uncontendedNative(); + void uncontendedQMutex(); + void uncontendedQMutexLocker(); -tst_QMutex::~tst_QMutex() -{ -} + void contendedNative_data(); + void contendedQMutex_data() { contendedNative_data(); } + void contendedQMutexLocker_data() { contendedNative_data(); } + + void contendedNative(); + void contendedQMutex(); + void contendedQMutexLocker(); +}; void tst_QMutex::noThread_data() { @@ -127,5 +178,202 @@ void tst_QMutex::noThread() QCOMPARE(int(count), N); } +void tst_QMutex::uncontendedNative() +{ + NativeMutexType mutex; + NativeMutexInitialize(&mutex); + QBENCHMARK { + NativeMutexLock(&mutex); + NativeMutexUnlock(&mutex); + } + NativeMutexDestroy(&mutex); +} + +void tst_QMutex::uncontendedQMutex() +{ + QMutex mutex; + QBENCHMARK { + mutex.lock(); + mutex.unlock(); + } +} + +void tst_QMutex::uncontendedQMutexLocker() +{ + QMutex mutex; + QBENCHMARK { + QMutexLocker locker(&mutex); + } +} + +void tst_QMutex::contendedNative_data() +{ + QTest::addColumn("iterations"); + QTest::addColumn("msleepDuration"); + QTest::newRow("-1") << 100 << -1; + QTest::newRow("0") << 100 << 0; + QTest::newRow("1") << 10 << 1; + QTest::newRow("2") << 10 << 2; +} + +class NativeMutexThread : public QThread +{ + QSemaphore *semaphore1, *semaphore2; + NativeMutexType *mutex; + int iterations, msleepDuration; +public: + bool done; + NativeMutexThread(QSemaphore *semaphore1, QSemaphore *semaphore2, NativeMutexType *mutex, int iterations, int msleepDuration) + : semaphore1(semaphore1), semaphore2(semaphore2), mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false) + { } + void run() { + forever { + semaphore1->acquire(); + if (done) + break; + for (int i = 0; i < iterations; ++i) { + NativeMutexLock(mutex); + if (msleepDuration >= 0) + msleep(msleepDuration); + NativeMutexUnlock(mutex); + } + semaphore2->release(); + } + } +}; + +void tst_QMutex::contendedNative() +{ + QFETCH(int, iterations); + QFETCH(int, msleepDuration); + + QSemaphore semaphore1, semaphore2; + NativeMutexType mutex; + NativeMutexInitialize(&mutex); + + QVector threads(threadCount); + for (int i = 0; i < threads.count(); ++i) { + threads[i] = new NativeMutexThread(&semaphore1, &semaphore2, &mutex, iterations, msleepDuration); + threads[i]->start(); + } + + QBENCHMARK { + semaphore1.release(threadCount); + semaphore2.acquire(threadCount); + } + + for (int i = 0; i < threads.count(); ++i) + threads[i]->done = true; + semaphore1.release(threadCount); + for (int i = 0; i < threads.count(); ++i) + threads[i]->wait(); + qDeleteAll(threads); + + NativeMutexDestroy(&mutex); +} + +class QMutexThread : public QThread +{ + QSemaphore *semaphore1, *semaphore2; + QMutex *mutex; + int iterations, msleepDuration; +public: + bool done; + QMutexThread(QSemaphore *semaphore1, QSemaphore *semaphore2, QMutex *mutex, int iterations, int msleepDuration) + : semaphore1(semaphore1), semaphore2(semaphore2), mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false) + { } + void run() { + forever { + semaphore1->acquire(); + if (done) + break; + for (int i = 0; i < iterations; ++i) { + mutex->lock(); + if (msleepDuration >= 0) + msleep(msleepDuration); + mutex->unlock(); + } + semaphore2->release(); + } + } +}; + +void tst_QMutex::contendedQMutex() +{ + QFETCH(int, iterations); + QFETCH(int, msleepDuration); + QSemaphore semaphore1, semaphore2; + QMutex mutex; + + QVector threads(threadCount); + for (int i = 0; i < threads.count(); ++i) { + threads[i] = new QMutexThread(&semaphore1, &semaphore2, &mutex, iterations, msleepDuration); + threads[i]->start(); + } + + QBENCHMARK { + semaphore1.release(threadCount); + semaphore2.acquire(threadCount); + } + + for (int i = 0; i < threads.count(); ++i) + threads[i]->done = true; + semaphore1.release(threadCount); + for (int i = 0; i < threads.count(); ++i) + threads[i]->wait(); + qDeleteAll(threads); +} + +class QMutexLockerThread : public QThread +{ + QSemaphore *semaphore1, *semaphore2; + QMutex *mutex; + int iterations, msleepDuration; +public: + bool done; + QMutexLockerThread(QSemaphore *semaphore1, QSemaphore *semaphore2, QMutex *mutex, int iterations, int msleepDuration) + : semaphore1(semaphore1), semaphore2(semaphore2), mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false) + { } + void run() { + forever { + semaphore1->acquire(); + if (done) + break; + for (int i = 0; i < iterations; ++i) { + QMutexLocker locker(mutex); + if (msleepDuration >= 0) + msleep(msleepDuration); + } + semaphore2->release(); + } + } +}; + +void tst_QMutex::contendedQMutexLocker() +{ + QFETCH(int, iterations); + QFETCH(int, msleepDuration); + QSemaphore semaphore1, semaphore2; + QMutex mutex; + + QVector threads(threadCount); + for (int i = 0; i < threads.count(); ++i) { + threads[i] = new QMutexLockerThread(&semaphore1, &semaphore2, &mutex, iterations, msleepDuration); + threads[i]->start(); + } + + QBENCHMARK { + semaphore1.release(threadCount); + semaphore2.acquire(threadCount); + } + + for (int i = 0; i < threads.count(); ++i) + threads[i]->done = true; + semaphore1.release(threadCount); + for (int i = 0; i < threads.count(); ++i) + threads[i]->wait(); + qDeleteAll(threads); +} + QTEST_MAIN(tst_QMutex) #include "tst_qmutex.moc" -- cgit v0.12 From 2a508c6279af71c16d04ad4e764f101ea32a1c05 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 29 Sep 2010 13:42:19 +0200 Subject: Test contention performance for long (10ms) critical sections The performance should be about the same for all cases (meaning that our spinning overhead should not add too much overhead). Reviewed-by: joao --- tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp index 9ed5d55..b918014 100644 --- a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp +++ b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp @@ -214,6 +214,7 @@ void tst_QMutex::contendedNative_data() QTest::newRow("0") << 100 << 0; QTest::newRow("1") << 10 << 1; QTest::newRow("2") << 10 << 2; + QTest::newRow("10") << 10 << 10; } class NativeMutexThread : public QThread -- cgit v0.12 From 00c4e6d3d4e9196dc1c418c9269fcbed2f49dc87 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 1 Oct 2010 10:49:00 +0200 Subject: Add baseline test data to measure test overhead Also give the existing test data meaningful names Reviewed-by: joao --- tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp index b918014..7a6b45c 100644 --- a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp +++ b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp @@ -210,11 +210,12 @@ void tst_QMutex::contendedNative_data() { QTest::addColumn("iterations"); QTest::addColumn("msleepDuration"); - QTest::newRow("-1") << 100 << -1; - QTest::newRow("0") << 100 << 0; - QTest::newRow("1") << 10 << 1; - QTest::newRow("2") << 10 << 2; - QTest::newRow("10") << 10 << 10; + QTest::newRow("baseline") << 0 << -1; + QTest::newRow("no msleep") << 1000 << -1; + QTest::newRow("msleep(0)") << 1000 << 0; + QTest::newRow("msleep(1)") << 10 << 1; + QTest::newRow("msleep(2)") << 10 << 2; + QTest::newRow("msleep(10)") << 10 << 10; } class NativeMutexThread : public QThread -- cgit v0.12 From 6d6c738879bb2ef5b5c1e42908bdd1ed16980f95 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 1 Dec 2010 12:13:27 +0300 Subject: use binary search int the string2PaperSize() helper since it is much much faster Merge-request: 2516 Signed-off-by: axis --- src/gui/painting/qprinterinfo_unix.cpp | 207 ++++++++++----------------------- 1 file changed, 64 insertions(+), 143 deletions(-) diff --git a/src/gui/painting/qprinterinfo_unix.cpp b/src/gui/painting/qprinterinfo_unix.cpp index 2129aa5..0d4cc16 100644 --- a/src/gui/painting/qprinterinfo_unix.cpp +++ b/src/gui/painting/qprinterinfo_unix.cpp @@ -60,6 +60,68 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_PRINTER +#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) +// preserver names in ascending order for the binary search +static const struct NamedPaperSize { + const char *const name; + QPrinter::PaperSize size; +} named_sizes_map[QPrinter::NPageSize] = { + { "A0", QPrinter::A0 }, + { "A1", QPrinter::A1 }, + { "A2", QPrinter::A2 }, + { "A3", QPrinter::A3 }, + { "A4", QPrinter::A4 }, + { "A5", QPrinter::A5 }, + { "A6", QPrinter::A6 }, + { "A7", QPrinter::A7 }, + { "A8", QPrinter::A8 }, + { "A9", QPrinter::A9 }, + { "B0", QPrinter::B0 }, + { "B1", QPrinter::B1 }, + { "B10", QPrinter::B10 }, + { "B2", QPrinter::B2 }, + { "B4", QPrinter::B4 }, + { "B5", QPrinter::B5 }, + { "B6", QPrinter::B6 }, + { "B7", QPrinter::B7 }, + { "B8", QPrinter::B8 }, + { "B9", QPrinter::B9 }, + { "C5E", QPrinter::C5E }, + { "Comm10E", QPrinter::Comm10E }, + { "Custom", QPrinter::Custom }, + { "DLE", QPrinter::DLE }, + { "Executive", QPrinter::Executive }, + { "Folio", QPrinter::Folio }, + { "Ledger", QPrinter::Ledger }, + { "Legal", QPrinter::Legal }, + { "Letter", QPrinter::Letter }, + { "Tabloid", QPrinter::Tabloid } +}; + +inline bool operator<(const char *name, const NamedPaperSize &data) +{ return qstrcmp(name, data.name) < 0; } +inline bool operator<(const NamedPaperSize &data, const char *name) +{ return qstrcmp(data.name, name) < 0; } + +static inline QPrinter::PaperSize string2PaperSize(const char *name) +{ + const NamedPaperSize *r = qBinaryFind(named_sizes_map, named_sizes_map + QPrinter::NPageSize, name); + if (r - named_sizes_map != QPrinter::NPageSize) + return r->size; + return QPrinter::Custom; +} + +static inline const char *paperSize2String(QPrinter::PaperSize size) +{ + for (int i = 0; i < QPrinter::NPageSize; ++i) { + if (size == named_sizes_map[i].size) + return named_sizes_map[i].name; + } + return 0; +} +#endif + + class QPrinterInfoPrivate { Q_DECLARE_PUBLIC(QPrinterInfo) @@ -68,9 +130,6 @@ public: QPrinterInfoPrivate(const QString& name); ~QPrinterInfoPrivate(); - static QPrinter::PaperSize string2PaperSize(const QString& str); - static QString pageSize2String(QPrinter::PaperSize size); - private: QString m_name; bool m_isNull; @@ -977,11 +1036,8 @@ QList< QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const cups.setCurrentPrinter(d->m_cupsPrinterIndex); const ppd_option_t* sizes = cups.pageSizes(); if (sizes) { - for (int j = 0; j < sizes->num_choices; ++j) { - d->m_paperSizes.append( - QPrinterInfoPrivate::string2PaperSize( - QLatin1String(sizes->choices[j].choice))); - } + for (int j = 0; j < sizes->num_choices; ++j) + d->m_paperSizes.append(string2PaperSize(sizes->choices[j].choice)); } } #endif @@ -1016,141 +1072,6 @@ QPrinterInfoPrivate::~QPrinterInfoPrivate() { } -QPrinter::PaperSize QPrinterInfoPrivate::string2PaperSize(const QString& str) -{ - if (str == QLatin1String("A4")) { - return QPrinter::A4; - } else if (str == QLatin1String("B5")) { - return QPrinter::B5; - } else if (str == QLatin1String("Letter")) { - return QPrinter::Letter; - } else if (str == QLatin1String("Legal")) { - return QPrinter::Legal; - } else if (str == QLatin1String("Executive")) { - return QPrinter::Executive; - } else if (str == QLatin1String("A0")) { - return QPrinter::A0; - } else if (str == QLatin1String("A1")) { - return QPrinter::A1; - } else if (str == QLatin1String("A2")) { - return QPrinter::A2; - } else if (str == QLatin1String("A3")) { - return QPrinter::A3; - } else if (str == QLatin1String("A5")) { - return QPrinter::A5; - } else if (str == QLatin1String("A6")) { - return QPrinter::A6; - } else if (str == QLatin1String("A7")) { - return QPrinter::A7; - } else if (str == QLatin1String("A8")) { - return QPrinter::A8; - } else if (str == QLatin1String("A9")) { - return QPrinter::A9; - } else if (str == QLatin1String("B0")) { - return QPrinter::B0; - } else if (str == QLatin1String("B1")) { - return QPrinter::B1; - } else if (str == QLatin1String("B10")) { - return QPrinter::B10; - } else if (str == QLatin1String("B2")) { - return QPrinter::B2; - } else if (str == QLatin1String("B3")) { - return QPrinter::B3; - } else if (str == QLatin1String("B4")) { - return QPrinter::B4; - } else if (str == QLatin1String("B6")) { - return QPrinter::B6; - } else if (str == QLatin1String("B7")) { - return QPrinter::B7; - } else if (str == QLatin1String("B8")) { - return QPrinter::B8; - } else if (str == QLatin1String("B9")) { - return QPrinter::B9; - } else if (str == QLatin1String("C5E")) { - return QPrinter::C5E; - } else if (str == QLatin1String("Comm10E")) { - return QPrinter::Comm10E; - } else if (str == QLatin1String("DLE")) { - return QPrinter::DLE; - } else if (str == QLatin1String("Folio")) { - return QPrinter::Folio; - } else if (str == QLatin1String("Ledger")) { - return QPrinter::Ledger; - } else if (str == QLatin1String("Tabloid")) { - return QPrinter::Tabloid; - } else { - return QPrinter::Custom; - } -} - -QString QPrinterInfoPrivate::pageSize2String(QPrinter::PaperSize size) -{ - switch (size) { - case QPrinter::A4: - return QLatin1String("A4"); - case QPrinter::B5: - return QLatin1String("B5"); - case QPrinter::Letter: - return QLatin1String("Letter"); - case QPrinter::Legal: - return QLatin1String("Legal"); - case QPrinter::Executive: - return QLatin1String("Executive"); - case QPrinter::A0: - return QLatin1String("A0"); - case QPrinter::A1: - return QLatin1String("A1"); - case QPrinter::A2: - return QLatin1String("A2"); - case QPrinter::A3: - return QLatin1String("A3"); - case QPrinter::A5: - return QLatin1String("A5"); - case QPrinter::A6: - return QLatin1String("A6"); - case QPrinter::A7: - return QLatin1String("A7"); - case QPrinter::A8: - return QLatin1String("A8"); - case QPrinter::A9: - return QLatin1String("A9"); - case QPrinter::B0: - return QLatin1String("B0"); - case QPrinter::B1: - return QLatin1String("B1"); - case QPrinter::B10: - return QLatin1String("B10"); - case QPrinter::B2: - return QLatin1String("B2"); - case QPrinter::B3: - return QLatin1String("B3"); - case QPrinter::B4: - return QLatin1String("B4"); - case QPrinter::B6: - return QLatin1String("B6"); - case QPrinter::B7: - return QLatin1String("B7"); - case QPrinter::B8: - return QLatin1String("B8"); - case QPrinter::B9: - return QLatin1String("B9"); - case QPrinter::C5E: - return QLatin1String("C5E"); - case QPrinter::Comm10E: - return QLatin1String("Comm10E"); - case QPrinter::DLE: - return QLatin1String("DLE"); - case QPrinter::Folio: - return QLatin1String("Folio"); - case QPrinter::Ledger: - return QLatin1String("Ledger"); - case QPrinter::Tabloid: - return QLatin1String("Tabloid"); - default: - return QLatin1String("Custom"); - } -} - #endif // QT_NO_PRINTER QT_END_NAMESPACE -- cgit v0.12 From f725c90032b83df62432018af362830e899e71c1 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 1 Dec 2010 07:48:55 +0300 Subject: minor refactoring of QPrinterInfoPrivate use member initialization lists; remove unused Q_DECLARE_PUBLIC stuff and q_ptr member; make members public instead Merge-request: 2516 Signed-off-by: axis --- src/gui/painting/qprinterinfo_mac.cpp | 42 +++++++---------------------- src/gui/painting/qprinterinfo_unix.cpp | 48 +++++++++------------------------- src/gui/painting/qprinterinfo_win.cpp | 42 +++++++---------------------- 3 files changed, 32 insertions(+), 100 deletions(-) diff --git a/src/gui/painting/qprinterinfo_mac.cpp b/src/gui/painting/qprinterinfo_mac.cpp index 9b199f4..6a48c91 100644 --- a/src/gui/painting/qprinterinfo_mac.cpp +++ b/src/gui/painting/qprinterinfo_mac.cpp @@ -49,18 +49,20 @@ QT_BEGIN_NAMESPACE class QPrinterInfoPrivate { -Q_DECLARE_PUBLIC(QPrinterInfo) public: - ~QPrinterInfoPrivate(); - QPrinterInfoPrivate(); - QPrinterInfoPrivate(const QString& name); - -private: - QPrinterInfo* q_ptr; + QPrinterInfoPrivate() : + m_isNull(true), m_default(false) + {} + QPrinterInfoPrivate(const QString& name) : + m_name(name), + m_isNull(false), m_default(false) + {} + ~QPrinterInfoPrivate() + {} QString m_name; - bool m_default; bool m_isNull; + bool m_default; }; static QPrinterInfoPrivate nullQPrinterInfoPrivate; @@ -139,7 +141,6 @@ QPrinterInfo::QPrinterInfo() QPrinterInfo::QPrinterInfo(const QString& name) : d_ptr(new QPrinterInfoPrivate(name)) { - d_ptr->q_ptr = this; } QPrinterInfo::QPrinterInfo(const QPrinterInfo& src) @@ -152,7 +153,6 @@ QPrinterInfo& QPrinterInfo::operator=(const QPrinterInfo& src) { Q_ASSERT(d_ptr); d_ptr.reset(new QPrinterInfoPrivate(*src.d_ptr)); - d_ptr->q_ptr = this; return *this; } @@ -210,28 +210,6 @@ QList QPrinterInfo::supportedPaperSizes() const return paperList; } -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -QPrinterInfoPrivate::QPrinterInfoPrivate() : - q_ptr(NULL), - m_default(false), - m_isNull(true) -{ -} - -QPrinterInfoPrivate::QPrinterInfoPrivate(const QString& name) : - q_ptr(NULL), - m_name(name), - m_default(false), - m_isNull(false) -{ -} - -QPrinterInfoPrivate::~QPrinterInfoPrivate() -{ -} - #endif // QT_NO_PRINTER QT_END_NAMESPACE diff --git a/src/gui/painting/qprinterinfo_unix.cpp b/src/gui/painting/qprinterinfo_unix.cpp index 0d4cc16..eb16a1b 100644 --- a/src/gui/painting/qprinterinfo_unix.cpp +++ b/src/gui/painting/qprinterinfo_unix.cpp @@ -124,21 +124,26 @@ static inline const char *paperSize2String(QPrinter::PaperSize size) class QPrinterInfoPrivate { -Q_DECLARE_PUBLIC(QPrinterInfo) public: - QPrinterInfoPrivate(); - QPrinterInfoPrivate(const QString& name); - ~QPrinterInfoPrivate(); + QPrinterInfoPrivate() : + m_isNull(true), m_default(false), + m_mustGetPaperSizes(true), m_cupsPrinterIndex(0) + {} + QPrinterInfoPrivate(const QString& name) : + m_name(name), + m_isNull(false), m_default(false), + m_mustGetPaperSizes(true), m_cupsPrinterIndex(0) + {} + ~QPrinterInfoPrivate() + {} -private: QString m_name; bool m_isNull; bool m_default; + mutable bool m_mustGetPaperSizes; mutable QList m_paperSizes; int m_cupsPrinterIndex; - - QPrinterInfo* q_ptr; }; static QPrinterInfoPrivate nullQPrinterInfoPrivate; @@ -946,7 +951,6 @@ QPrinterInfo::QPrinterInfo(const QPrinter& printer) { Q_D(QPrinterInfo); - d->q_ptr = this; #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) QCUPSSupport cups; @@ -990,7 +994,6 @@ QPrinterInfo::QPrinterInfo(const QPrinter& printer) QPrinterInfo::QPrinterInfo(const QString& name) : d_ptr(new QPrinterInfoPrivate(name)) { - d_ptr->q_ptr = this; } QPrinterInfo::~QPrinterInfo() @@ -1001,7 +1004,6 @@ QPrinterInfo& QPrinterInfo::operator=(const QPrinterInfo& src) { Q_ASSERT(d_ptr); d_ptr.reset(new QPrinterInfoPrivate(*src.d_ptr)); - d_ptr->q_ptr = this; return *this; } @@ -1046,32 +1048,6 @@ QList< QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const return d->m_paperSizes; } -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -QPrinterInfoPrivate::QPrinterInfoPrivate() -{ - m_isNull = true; - m_default = false; - m_mustGetPaperSizes = true; - m_cupsPrinterIndex = 0; - q_ptr = 0; -} - -QPrinterInfoPrivate::QPrinterInfoPrivate(const QString& name) -{ - m_name = name; - m_isNull = false; - m_default = false; - m_mustGetPaperSizes = true; - m_cupsPrinterIndex = 0; - q_ptr = 0; -} - -QPrinterInfoPrivate::~QPrinterInfoPrivate() -{ -} - #endif // QT_NO_PRINTER QT_END_NAMESPACE diff --git a/src/gui/painting/qprinterinfo_win.cpp b/src/gui/painting/qprinterinfo_win.cpp index caada1f..808de2c 100644 --- a/src/gui/painting/qprinterinfo_win.cpp +++ b/src/gui/painting/qprinterinfo_win.cpp @@ -53,18 +53,20 @@ extern QPrinter::PaperSize mapDevmodePaperSize(int s); class QPrinterInfoPrivate { -Q_DECLARE_PUBLIC(QPrinterInfo) public: - ~QPrinterInfoPrivate(); - QPrinterInfoPrivate(); - QPrinterInfoPrivate(const QString& name); + QPrinterInfoPrivate() : + m_isNull(true), m_default(false) + {} + QPrinterInfoPrivate(const QString& name) : + m_name(name), + m_isNull(false), m_default(false) + {} + ~QPrinterInfoPrivate() + {} -private: QString m_name; - bool m_default; bool m_isNull; - - QPrinterInfo* q_ptr; + bool m_default; }; static QPrinterInfoPrivate nullQPrinterInfoPrivate; @@ -142,7 +144,6 @@ QPrinterInfo::QPrinterInfo() QPrinterInfo::QPrinterInfo(const QString& name) : d_ptr(new QPrinterInfoPrivate(name)) { - d_ptr->q_ptr = this; } QPrinterInfo::QPrinterInfo(const QPrinterInfo& src) @@ -173,7 +174,6 @@ QPrinterInfo& QPrinterInfo::operator=(const QPrinterInfo& src) { Q_ASSERT(d_ptr); d_ptr.reset(new QPrinterInfoPrivate(*src.d_ptr)); - d_ptr->q_ptr = this; return *this; } @@ -218,28 +218,6 @@ QList QPrinterInfo::supportedPaperSizes() const return paperList; } -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -QPrinterInfoPrivate::QPrinterInfoPrivate() : - m_default(false), - m_isNull(true), - q_ptr(NULL) -{ -} - -QPrinterInfoPrivate::QPrinterInfoPrivate(const QString& name) : - m_name(name), - m_default(false), - m_isNull(false), - q_ptr(NULL) -{ -} - -QPrinterInfoPrivate::~QPrinterInfoPrivate() -{ -} - #endif // QT_NO_PRINTER QT_END_NAMESPACE -- cgit v0.12 From 2cf77579cf41594e036beeacf3dc3b6aa9f05cfa Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 1 Dec 2010 12:31:19 +0300 Subject: refactoring of QPrinterInfo move QPrinterInfoPrivate to it's own header file; rename qprinterinfo.qdoc to qprinterinfo.cpp to make it consistent with others; squash the duplicated code into qprinterinfo.cpp; avoid extra d_ptr assignments in the QPrinterInfo copying c-tor; simplify the QPrinterInfo from QPrinter c-tor code; fix styling and few method param names; remove the `m_` prefix of QPrinterInfoPrivate's members (as they are members of a private class anyway ;P) remove the boilerplates Merge-request: 2516 Signed-off-by: axis --- src/gui/painting/painting.pri | 2 + src/gui/painting/qprinterinfo.cpp | 173 +++++++++++++++++++++++++++++++++ src/gui/painting/qprinterinfo.h | 15 +-- src/gui/painting/qprinterinfo.qdoc | 125 ------------------------ src/gui/painting/qprinterinfo_mac.cpp | 100 +------------------ src/gui/painting/qprinterinfo_p.h | 108 ++++++++++++++++++++ src/gui/painting/qprinterinfo_unix.cpp | 159 +++--------------------------- src/gui/painting/qprinterinfo_win.cpp | 106 ++------------------ 8 files changed, 317 insertions(+), 471 deletions(-) create mode 100644 src/gui/painting/qprinterinfo.cpp delete mode 100644 src/gui/painting/qprinterinfo.qdoc create mode 100644 src/gui/painting/qprinterinfo_p.h diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 099619c..51f2538 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -34,6 +34,7 @@ HEADERS += \ painting/qprinter.h \ painting/qprinter_p.h \ painting/qprinterinfo.h \ + painting/qprinterinfo_p.h \ painting/qrasterizer_p.h \ painting/qregion.h \ painting/qstroker_p.h \ @@ -73,6 +74,7 @@ SOURCES += \ painting/qprintengine_pdf.cpp \ painting/qprintengine_ps.cpp \ painting/qprinter.cpp \ + painting/qprinterinfo.cpp \ painting/qrasterizer.cpp \ painting/qregion.cpp \ painting/qstroker.cpp \ diff --git a/src/gui/painting/qprinterinfo.cpp b/src/gui/painting/qprinterinfo.cpp new file mode 100644 index 0000000..21d56f3 --- /dev/null +++ b/src/gui/painting/qprinterinfo.cpp @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** 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$ +** 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 +** 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$ +** +****************************************************************************/ + +#include "qprinterinfo.h" +#include "qprinterinfo_p.h" + +#ifndef QT_NO_PRINTER + +QT_BEGIN_NAMESPACE + +QPrinterInfoPrivate QPrinterInfoPrivate::shared_null; + + +/*! + \class QPrinterInfo + + \brief The QPrinterInfo class gives access to information about + existing printers. + + \ingroup printing + + Use the static functions to generate a list of QPrinterInfo + objects. Each QPrinterInfo object in the list represents a single + printer and can be queried for name, supported paper sizes, and + whether or not it is the default printer. + + \since 4.4 +*/ + +/*! + \fn QList QPrinterInfo::availablePrinters() + + Returns a list of available printers on the system. +*/ + +/*! + \fn QPrinterInfo QPrinterInfo::defaultPrinter() + + Returns the default printer on the system. + + The return value should be checked using isNull() before being + used, in case there is no default printer. + + \sa isNull() +*/ + +/*! + Constructs an empty QPrinterInfo object. + + \sa isNull() +*/ +QPrinterInfo::QPrinterInfo() + : d_ptr(&QPrinterInfoPrivate::shared_null) +{ +} + +/*! + Constructs a copy of \a other. +*/ +QPrinterInfo::QPrinterInfo(const QPrinterInfo &other) + : d_ptr(new QPrinterInfoPrivate(*other.d_ptr)) +{ +} + +/*! + Constructs a QPrinterInfo object from \a printer. +*/ +QPrinterInfo::QPrinterInfo(const QPrinter &printer) + : d_ptr(&QPrinterInfoPrivate::shared_null) +{ + foreach (const QPrinterInfo &printerInfo, availablePrinters()) { + if (printerInfo.printerName() == printer.printerName()) { + d_ptr.reset(new QPrinterInfoPrivate(*printerInfo.d_ptr)); + break; + } + } +} + +/*! + \internal +*/ +QPrinterInfo::QPrinterInfo(const QString &name) + : d_ptr(new QPrinterInfoPrivate(name)) +{ +} + +/*! + Destroys the QPrinterInfo object. References to the values in the + object become invalid. +*/ +QPrinterInfo::~QPrinterInfo() +{ +} + +/*! + Sets the QPrinterInfo object to be equal to \a other. +*/ +QPrinterInfo &QPrinterInfo::operator=(const QPrinterInfo &other) +{ + Q_ASSERT(d_ptr); + d_ptr.reset(new QPrinterInfoPrivate(*other.d_ptr)); + return *this; +} + +/*! + Returns the name of the printer. + + \sa QPrinter::setPrinterName() +*/ +QString QPrinterInfo::printerName() const +{ + const Q_D(QPrinterInfo); + return d->name; +} + +/*! + Returns whether this QPrinterInfo object holds a printer definition. + + An empty QPrinterInfo object could result for example from calling + defaultPrinter() when there are no printers on the system. +*/ +bool QPrinterInfo::isNull() const +{ + const Q_D(QPrinterInfo); + return d->isNull; +} + +/*! + Returns whether this printer is the default printer. +*/ +bool QPrinterInfo::isDefault() const +{ + const Q_D(QPrinterInfo); + return d->isDefault; +} + +/*! + \fn QList< QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const + \since 4.4 + + Returns a list of supported paper sizes by the printer. + + Not all printer drivers support this query, so the list may be empty. + On Mac OS X 10.3, this function always returns an empty list. +*/ + +QT_END_NAMESPACE + +#endif // QT_NO_PRINTER diff --git a/src/gui/painting/qprinterinfo.h b/src/gui/painting/qprinterinfo.h index 063c6b9..c8c9534 100644 --- a/src/gui/painting/qprinterinfo.h +++ b/src/gui/painting/qprinterinfo.h @@ -42,9 +42,10 @@ #ifndef QPRINTERINFO_H #define QPRINTERINFO_H -#include #include +#include + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -56,15 +57,13 @@ class QPrinterInfoPrivate; class QPrinterInfoPrivateDeleter; class Q_GUI_EXPORT QPrinterInfo { -Q_DECLARE_PRIVATE(QPrinterInfo) - public: QPrinterInfo(); - QPrinterInfo(const QPrinterInfo& src); - QPrinterInfo(const QPrinter& printer); + QPrinterInfo(const QPrinterInfo &other); + QPrinterInfo(const QPrinter &printer); ~QPrinterInfo(); - QPrinterInfo& operator=(const QPrinterInfo& src); + QPrinterInfo &operator=(const QPrinterInfo &other); QString printerName() const; bool isNull() const; @@ -75,8 +74,10 @@ public: static QPrinterInfo defaultPrinter(); private: - QPrinterInfo(const QString& name); + QPrinterInfo(const QString &name); +private: + Q_DECLARE_PRIVATE(QPrinterInfo) QScopedPointer d_ptr; }; diff --git a/src/gui/painting/qprinterinfo.qdoc b/src/gui/painting/qprinterinfo.qdoc deleted file mode 100644 index 9193213..0000000 --- a/src/gui/painting/qprinterinfo.qdoc +++ /dev/null @@ -1,125 +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 documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** 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 -** 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$ -** -****************************************************************************/ - -/*! - \class QPrinterInfo - - \brief The QPrinterInfo class gives access to information about - existing printers. - - \ingroup printing - - Use the static functions to generate a list of QPrinterInfo - objects. Each QPrinterInfo object in the list represents a single - printer and can be queried for name, supported paper sizes, and - whether or not it is the default printer. - - \since 4.4 -*/ - -/*! - \fn QList QPrinterInfo::availablePrinters() - - Returns a list of available printers on the system. -*/ - -/*! - \fn QPrinterInfo QPrinterInfo::defaultPrinter() - - Returns the default printer on the system. - - The return value should be checked using isNull() before being - used, in case there is no default printer. - - \sa isNull() -*/ - -/*! - \fn QPrinterInfo::QPrinterInfo() - - Constructs an empty QPrinterInfo object. - - \sa isNull() -*/ - -/*! - \fn QPrinterInfo::QPrinterInfo(const QPrinterInfo& src) - - Constructs a copy of \a src. -*/ - -/*! - \fn QPrinterInfo::QPrinterInfo(const QPrinter& printer) - - Constructs a QPrinterInfo object from \a printer. -*/ - -/*! - \fn QPrinterInfo::~QPrinterInfo() - - Destroys the QPrinterInfo object. References to the values in the - object become invalid. -*/ - -/*! - \fn QPrinterInfo& QPrinterInfo::operator=(const QPrinterInfo& src) - - Sets the QPrinterInfo object to be equal to \a src. -*/ - -/*! - \fn QString QPrinterInfo::printerName() const - - Returns the name of the printer. - - \sa QPrinter::setPrinterName() -*/ - -/*! - \fn bool QPrinterInfo::isNull() const - - Returns whether this QPrinterInfo object holds a printer definition. - - An empty QPrinterInfo object could result for example from calling - defaultPrinter() when there are no printers on the system. -*/ - -/*! - \fn bool QPrinterInfo::isDefault() const - - Returns whether this printer is the default printer. -*/ - -/*! - \fn QList< QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const - \since 4.4 - - Returns a list of supported paper sizes by the printer. - - Not all printer drivers support this query, so the list may be empty. - On Mac OS X 10.3, this function always returns an empty list. -*/ diff --git a/src/gui/painting/qprinterinfo_mac.cpp b/src/gui/painting/qprinterinfo_mac.cpp index 6a48c91..9d0e886 100644 --- a/src/gui/painting/qprinterinfo_mac.cpp +++ b/src/gui/painting/qprinterinfo_mac.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qprinterinfo.h" +#include "qprinterinfo_p.h" #include "private/qt_mac_p.h" @@ -47,40 +48,7 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_PRINTER -class QPrinterInfoPrivate -{ -public: - QPrinterInfoPrivate() : - m_isNull(true), m_default(false) - {} - QPrinterInfoPrivate(const QString& name) : - m_name(name), - m_isNull(false), m_default(false) - {} - ~QPrinterInfoPrivate() - {} - - QString m_name; - bool m_isNull; - bool m_default; -}; - -static QPrinterInfoPrivate nullQPrinterInfoPrivate; - -class QPrinterInfoPrivateDeleter -{ -public: - static inline void cleanup(QPrinterInfoPrivate *d) - { - if (d != &nullQPrinterInfoPrivate) - delete d; - } -}; - -extern QPrinter::PaperSize qSizeFTopaperSize(const QSizeF& size); - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// +extern QPrinter::PaperSize qSizeFTopaperSize(const QSizeF &size); QList QPrinterInfo::availablePrinters() { @@ -96,7 +64,7 @@ QList QPrinterInfo::availablePrinters() QString name = QCFString::toQString(PMPrinterGetName(printer)); printers.append(QPrinterInfo(name)); if (PMPrinterIsDefault(printer)) { - printers[i].d_ptr->m_default = true; + printers[i].d_ptr->isDefault = true; } } } @@ -114,71 +82,11 @@ QPrinterInfo QPrinterInfo::defaultPrinter(){ return QPrinterInfo(); } -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -QPrinterInfo::QPrinterInfo(const QPrinter& prn) - : d_ptr(&nullQPrinterInfoPrivate) -{ - QList list = availablePrinters(); - for (int c = 0; c < list.size(); ++c) { - if (prn.printerName() == list[c].printerName()) { - *this = list[c]; - return; - } - } -} - -QPrinterInfo::~QPrinterInfo() -{ -} - -QPrinterInfo::QPrinterInfo() - : d_ptr(&nullQPrinterInfoPrivate) -{ -} - -QPrinterInfo::QPrinterInfo(const QString& name) - : d_ptr(new QPrinterInfoPrivate(name)) -{ -} - -QPrinterInfo::QPrinterInfo(const QPrinterInfo& src) - : d_ptr(&nullQPrinterInfoPrivate) -{ - *this = src; -} - -QPrinterInfo& QPrinterInfo::operator=(const QPrinterInfo& src) -{ - Q_ASSERT(d_ptr); - d_ptr.reset(new QPrinterInfoPrivate(*src.d_ptr)); - return *this; -} - -QString QPrinterInfo::printerName() const -{ - const Q_D(QPrinterInfo); - return d->m_name; -} - -bool QPrinterInfo::isNull() const -{ - const Q_D(QPrinterInfo); - return d->m_isNull; -} - -bool QPrinterInfo::isDefault() const -{ - const Q_D(QPrinterInfo); - return d->m_default; -} - QList QPrinterInfo::supportedPaperSizes() const { const Q_D(QPrinterInfo); - PMPrinter cfPrn = PMPrinterCreateFromPrinterID(QCFString::toCFStringRef(d->m_name)); + PMPrinter cfPrn = PMPrinterCreateFromPrinterID(QCFString::toCFStringRef(d->name)); if (!cfPrn) return QList(); diff --git a/src/gui/painting/qprinterinfo_p.h b/src/gui/painting/qprinterinfo_p.h new file mode 100644 index 0000000..f5981d4 --- /dev/null +++ b/src/gui/painting/qprinterinfo_p.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** 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 QPRINTERINFO_P_H +#define QPRINTERINFO_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 "QtCore/qglobal.h" + +#ifndef QT_NO_PRINTER + +#include "QtCore/qlist.h" + +QT_BEGIN_NAMESPACE + +class QPrinterInfoPrivate +{ +public: + QPrinterInfoPrivate(const QString& name = QString()) : + name(name), isNull(false), isDefault(false) +#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA) +#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) + , cupsPrinterIndex(0), hasPaperSizes(false) +#endif +#endif + {} + ~QPrinterInfoPrivate() + {} + + static QPrinterInfoPrivate shared_null; + + QString name; + bool isNull; + bool isDefault; + +#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA) +#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) + int cupsPrinterIndex; + mutable bool hasPaperSizes; + mutable QList paperSizes; +#endif +#endif +}; + + +class QPrinterInfoPrivateDeleter +{ +public: + static inline void cleanup(QPrinterInfoPrivate *d) + { + if (d != &QPrinterInfoPrivate::shared_null) + delete d; + } +}; + +QT_END_NAMESPACE + +#endif // QT_NO_PRINTER + +#endif // QPRINTERINFO_P_H diff --git a/src/gui/painting/qprinterinfo_unix.cpp b/src/gui/painting/qprinterinfo_unix.cpp index eb16a1b..c30fcb4 100644 --- a/src/gui/painting/qprinterinfo_unix.cpp +++ b/src/gui/painting/qprinterinfo_unix.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qprinterinfo.h" +#include "qprinterinfo_p.h" #include #include @@ -121,46 +122,6 @@ static inline const char *paperSize2String(QPrinter::PaperSize size) } #endif - -class QPrinterInfoPrivate -{ -public: - QPrinterInfoPrivate() : - m_isNull(true), m_default(false), - m_mustGetPaperSizes(true), m_cupsPrinterIndex(0) - {} - QPrinterInfoPrivate(const QString& name) : - m_name(name), - m_isNull(false), m_default(false), - m_mustGetPaperSizes(true), m_cupsPrinterIndex(0) - {} - ~QPrinterInfoPrivate() - {} - - QString m_name; - bool m_isNull; - bool m_default; - - mutable bool m_mustGetPaperSizes; - mutable QList m_paperSizes; - int m_cupsPrinterIndex; -}; - -static QPrinterInfoPrivate nullQPrinterInfoPrivate; - -class QPrinterInfoPrivateDeleter -{ -public: - static inline void cleanup(QPrinterInfoPrivate *d) - { - if (d != &nullQPrinterInfoPrivate) - delete d; - } -}; - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - void qt_perhapsAddPrinter(QList *printers, const QString &name, QString host, QString comment, QStringList aliases) @@ -891,9 +852,8 @@ QList QPrinterInfo::availablePrinters() QList list; #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - QCUPSSupport cups; if (QCUPSSupport::isAvailable()) { - //const ppd_file_t* cupsPPD = cups.currentPPD(); + QCUPSSupport cups; int cupsPrinterCount = cups.availablePrintersCount(); const cups_dest_t* cupsPrinters = cups.availablePrinters(); @@ -903,8 +863,8 @@ QList QPrinterInfo::availablePrinters() printerName += QLatin1Char('/') + QString::fromLocal8Bit(cupsPrinters[i].instance); list.append(QPrinterInfo(printerName)); if (cupsPrinters[i].is_default) - list[i].d_ptr->m_default = true; - list[i].d_ptr->m_cupsPrinterIndex = i; + list[i].d_ptr->isDefault = true; + list[i].d_ptr->cupsPrinterIndex = i; } } else { #endif @@ -916,7 +876,7 @@ QList QPrinterInfo::availablePrinters() list.append(QPrinterInfo((*i).name)); } if (defprn >= 0 && defprn < lprPrinters.size()) { - list[defprn].d_ptr->m_default = true; + list[defprn].d_ptr->isDefault = true; } #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) } @@ -935,117 +895,30 @@ QPrinterInfo QPrinterInfo::defaultPrinter() return (prnList.size() > 0) ? prnList[0] : QPrinterInfo(); } -QPrinterInfo::QPrinterInfo() - : d_ptr(&nullQPrinterInfoPrivate) +QList QPrinterInfo::supportedPaperSizes() const { -} - -QPrinterInfo::QPrinterInfo(const QPrinterInfo& src) - : d_ptr(&nullQPrinterInfoPrivate) -{ - *this = src; -} - -QPrinterInfo::QPrinterInfo(const QPrinter& printer) - : d_ptr(new QPrinterInfoPrivate(printer.printerName())) -{ - - Q_D(QPrinterInfo); - -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - QCUPSSupport cups; - if (QCUPSSupport::isAvailable()) { - int cupsPrinterCount = cups.availablePrintersCount(); - const cups_dest_t* cupsPrinters = cups.availablePrinters(); - - for (int i = 0; i < cupsPrinterCount; ++i) { - QString printerName(QString::fromLocal8Bit(cupsPrinters[i].name)); - if (cupsPrinters[i].instance) - printerName += QLatin1Char('/') + QString::fromLocal8Bit(cupsPrinters[i].instance); - if (printerName == printer.printerName()) { - if (cupsPrinters[i].is_default) - d->m_default = true; - d->m_cupsPrinterIndex = i; - return; - } - } - } else { -#endif - QList lprPrinters; - int defprn = qt_getLprPrinters(lprPrinters); - // populating printer combo - QList::const_iterator i = lprPrinters.constBegin(); - int c; - for(c = 0; i != lprPrinters.constEnd(); ++i, ++c) { - if (i->name == printer.printerName()) { - if (defprn == c) - d->m_default = true; - return; - } - } #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - } -#endif - - // Printer not found. - d_ptr.reset(&nullQPrinterInfoPrivate); -} - -QPrinterInfo::QPrinterInfo(const QString& name) - : d_ptr(new QPrinterInfoPrivate(name)) -{ -} - -QPrinterInfo::~QPrinterInfo() -{ -} - -QPrinterInfo& QPrinterInfo::operator=(const QPrinterInfo& src) -{ - Q_ASSERT(d_ptr); - d_ptr.reset(new QPrinterInfoPrivate(*src.d_ptr)); - return *this; -} - -QString QPrinterInfo::printerName() const -{ const Q_D(QPrinterInfo); - return d->m_name; -} - -bool QPrinterInfo::isNull() const -{ - const Q_D(QPrinterInfo); - return d->m_isNull; -} - -bool QPrinterInfo::isDefault() const -{ - const Q_D(QPrinterInfo); - return d->m_default; -} -QList< QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const -{ - const Q_D(QPrinterInfo); - if (d->m_mustGetPaperSizes) { - d->m_mustGetPaperSizes = false; + if (!d->hasPaperSizes) { + d->hasPaperSizes = true; -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) - QCUPSSupport cups; if (QCUPSSupport::isAvailable()) { // Find paper sizes from CUPS. - cups.setCurrentPrinter(d->m_cupsPrinterIndex); + QCUPSSupport cups; + cups.setCurrentPrinter(d->cupsPrinterIndex); const ppd_option_t* sizes = cups.pageSizes(); if (sizes) { for (int j = 0; j < sizes->num_choices; ++j) - d->m_paperSizes.append(string2PaperSize(sizes->choices[j].choice)); + d->paperSizes.append(string2PaperSize(sizes->choices[j].choice)); } } -#endif - } - return d->m_paperSizes; + + return d->paperSizes; +#else + return QList(); +#endif } #endif // QT_NO_PRINTER diff --git a/src/gui/painting/qprinterinfo_win.cpp b/src/gui/painting/qprinterinfo_win.cpp index 808de2c..962aa2d 100644 --- a/src/gui/painting/qprinterinfo_win.cpp +++ b/src/gui/painting/qprinterinfo_win.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qprinterinfo.h" +#include "qprinterinfo_p.h" #include @@ -51,39 +52,6 @@ QT_BEGIN_NAMESPACE extern QPrinter::PaperSize mapDevmodePaperSize(int s); -class QPrinterInfoPrivate -{ -public: - QPrinterInfoPrivate() : - m_isNull(true), m_default(false) - {} - QPrinterInfoPrivate(const QString& name) : - m_name(name), - m_isNull(false), m_default(false) - {} - ~QPrinterInfoPrivate() - {} - - QString m_name; - bool m_isNull; - bool m_default; -}; - -static QPrinterInfoPrivate nullQPrinterInfoPrivate; - -class QPrinterInfoPrivateDeleter -{ -public: - static inline void cleanup(QPrinterInfoPrivate *d) - { - if (d != &nullQPrinterInfoPrivate) - delete d; - } -}; - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - QList QPrinterInfo::availablePrinters() { QList printers; @@ -105,7 +73,7 @@ QList QPrinterInfo::availablePrinters() for (uint i = 0; i < returned; ++i) { printers.append(QPrinterInfo(QString::fromWCharArray(infoList[i].pPrinterName))); if (printers.at(i).printerName() == defPrn.printerName()) - printers[i].d_ptr->m_default = true; + printers[i].d_ptr->isDefault = true; } delete [] buffer; } @@ -127,86 +95,24 @@ QPrinterInfo QPrinterInfo::defaultPrinter() QString printerName = noConfiguredPrinters ? QString() : info.at(0); QPrinterInfo prn(printerName); - prn.d_ptr->m_default = true; + prn.d_ptr->isDefault = true; if (noConfiguredPrinters) - prn.d_ptr->m_isNull = true; + prn.d_ptr->isNull = true; return prn; } -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -QPrinterInfo::QPrinterInfo() - : d_ptr(&nullQPrinterInfoPrivate) -{ -} - -QPrinterInfo::QPrinterInfo(const QString& name) - : d_ptr(new QPrinterInfoPrivate(name)) -{ -} - -QPrinterInfo::QPrinterInfo(const QPrinterInfo& src) - : d_ptr(&nullQPrinterInfoPrivate) -{ - *this = src; -} - -QPrinterInfo::QPrinterInfo(const QPrinter& prn) - : d_ptr(&nullQPrinterInfoPrivate) -{ - QList list = availablePrinters(); - for (int c = 0; c < list.size(); ++c) { - if (prn.printerName() == list[c].printerName()) { - *this = list[c]; - return; - } - } - - *this = QPrinterInfo(); -} - -QPrinterInfo::~QPrinterInfo() -{ -} - -QPrinterInfo& QPrinterInfo::operator=(const QPrinterInfo& src) -{ - Q_ASSERT(d_ptr); - d_ptr.reset(new QPrinterInfoPrivate(*src.d_ptr)); - return *this; -} - -QString QPrinterInfo::printerName() const -{ - const Q_D(QPrinterInfo); - return d->m_name; -} - -bool QPrinterInfo::isNull() const -{ - const Q_D(QPrinterInfo); - return d->m_isNull; -} - -bool QPrinterInfo::isDefault() const -{ - const Q_D(QPrinterInfo); - return d->m_default; -} - QList QPrinterInfo::supportedPaperSizes() const { const Q_D(QPrinterInfo); QList paperList; - DWORD size = DeviceCapabilities(reinterpret_cast(d->m_name.utf16()), + DWORD size = DeviceCapabilities(reinterpret_cast(d->name.utf16()), NULL, DC_PAPERS, NULL, NULL); if ((int)size == -1) return paperList; wchar_t *papers = new wchar_t[size]; - size = DeviceCapabilities(reinterpret_cast(d->m_name.utf16()), + size = DeviceCapabilities(reinterpret_cast(d->name.utf16()), NULL, DC_PAPERS, papers, NULL); for (int c = 0; c < (int)size; ++c) { -- cgit v0.12 From 70fd5a220d966279eb66df08ad69539bb26d59cd Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 1 Dec 2010 12:54:52 +0300 Subject: micro-optimizations, clean-ups and styling fixes Merge-request: 2516 Signed-off-by: axis --- src/gui/painting/qprinterinfo_mac.cpp | 67 ++++++++++++++++----------------- src/gui/painting/qprinterinfo_unix.cpp | 46 +++++++++++------------ src/gui/painting/qprinterinfo_win.cpp | 68 +++++++++++++++------------------- 3 files changed, 83 insertions(+), 98 deletions(-) diff --git a/src/gui/painting/qprinterinfo_mac.cpp b/src/gui/painting/qprinterinfo_mac.cpp index 9d0e886..8d41217 100644 --- a/src/gui/painting/qprinterinfo_mac.cpp +++ b/src/gui/painting/qprinterinfo_mac.cpp @@ -54,68 +54,63 @@ QList QPrinterInfo::availablePrinters() { QList printers; - OSStatus status = noErr; - QCFType printerList; - status = PMServerCreatePrinterList(kPMServerLocal, &printerList); - if (status == noErr) { - CFIndex count = CFArrayGetCount(printerList); - for (CFIndex i=0; i(const_cast(CFArrayGetValueAtIndex(printerList, i))); - QString name = QCFString::toQString(PMPrinterGetName(printer)); - printers.append(QPrinterInfo(name)); - if (PMPrinterIsDefault(printer)) { - printers[i].d_ptr->isDefault = true; - } + QCFType array; + if (PMServerCreatePrinterList(kPMServerLocal, &array) == noErr) { + CFIndex count = CFArrayGetCount(array); + for (int i = 0; i < count; ++i) { + PMPrinter printer = static_cast(const_cast(CFArrayGetValueAtIndex(array, i))); + QString printerName = QCFString::toQString(PMPrinterGetName(printer)); + + QPrinterInfo printerInfo(printerName); + if (PMPrinterIsDefault(printer)) + printerInfo.d_ptr->isDefault = true; + printers.append(printerInfo); } } return printers; } -QPrinterInfo QPrinterInfo::defaultPrinter(){ +QPrinterInfo QPrinterInfo::defaultPrinter() +{ QList printers = availablePrinters(); - for (int c = 0; c < printers.size(); ++c) { - if (printers[c].isDefault()) { - return printers[c]; - } + foreach (const QPrinterInfo &printerInfo, printers) { + if (printerInfo.isDefault()) + return printerInfo; } - return QPrinterInfo(); + + return printers.value(0); } QList QPrinterInfo::supportedPaperSizes() const { const Q_D(QPrinterInfo); - PMPrinter cfPrn = PMPrinterCreateFromPrinterID(QCFString::toCFStringRef(d->name)); + QList paperSizes; - if (!cfPrn) return QList(); + PMPrinter cfPrn = PMPrinterCreateFromPrinterID(QCFString::toCFStringRef(d->name)); + if (!cfPrn) + return paperSizes; CFArrayRef array; - OSStatus status = PMPrinterGetPaperList(cfPrn, &array); - - if (status != 0) { + if (PMPrinterGetPaperList(cfPrn, &array) != noErr) { PMRelease(cfPrn); - return QList(); + return paperSizes; } - QList paperList; int count = CFArrayGetCount(array); - for (int c = 0; c < count; c++) { - PMPaper paper = static_cast( - const_cast( - CFArrayGetValueAtIndex(array, c))); + for (int i = 0; i < count; ++i) { + PMPaper paper = static_cast(const_cast(CFArrayGetValueAtIndex(array, i))); double width, height; - status = PMPaperGetWidth(paper, &width); - status |= PMPaperGetHeight(paper, &height); - if (status != 0) continue; - - QSizeF size(width * 0.3527, height * 0.3527); - paperList.append(qSizeFTopaperSize(size)); + if (PMPaperGetWidth(paper, &width) == noErr && PMPaperGetHeight(paper, &height) == noErr) { + QSizeF size(width * 0.3527, height * 0.3527); + paperSizes.append(qSizeFTopaperSize(size)); + } } PMRelease(cfPrn); - return paperList; + return paperSizes; } #endif // QT_NO_PRINTER diff --git a/src/gui/painting/qprinterinfo_unix.cpp b/src/gui/painting/qprinterinfo_unix.cpp index c30fcb4..be24bd7 100644 --- a/src/gui/painting/qprinterinfo_unix.cpp +++ b/src/gui/painting/qprinterinfo_unix.cpp @@ -809,12 +809,12 @@ int qt_getLprPrinters(QList& printers) #endif } + QRegExp ps(QLatin1String("[^a-z]ps(?:[^a-z]|$)")); + QRegExp lp(QLatin1String("[^a-z]lp(?:[^a-z]|$)")); + int quality = 0; int best = 0; for (int i = 0; i < printers.size(); ++i) { - QRegExp ps(QLatin1String("[^a-z]ps(?:[^a-z]|$)")); - QRegExp lp(QLatin1String("[^a-z]lp(?:[^a-z]|$)")); - QString name = printers.at(i).name; QString comment = printers.at(i).comment; if (quality < 5 && name == dollarPrinter) { @@ -849,50 +849,48 @@ int qt_getLprPrinters(QList& printers) QList QPrinterInfo::availablePrinters() { - QList list; + QList printers; #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) if (QCUPSSupport::isAvailable()) { QCUPSSupport cups; int cupsPrinterCount = cups.availablePrintersCount(); const cups_dest_t* cupsPrinters = cups.availablePrinters(); - for (int i = 0; i < cupsPrinterCount; ++i) { QString printerName(QString::fromLocal8Bit(cupsPrinters[i].name)); if (cupsPrinters[i].instance) printerName += QLatin1Char('/') + QString::fromLocal8Bit(cupsPrinters[i].instance); - list.append(QPrinterInfo(printerName)); + + QPrinterInfo printerInfo(printerName); if (cupsPrinters[i].is_default) - list[i].d_ptr->isDefault = true; - list[i].d_ptr->cupsPrinterIndex = i; + printerInfo.d_ptr->isDefault = true; + printerInfo.d_ptr->cupsPrinterIndex = i; + printers.append(printerInfo); } - } else { + } else #endif + { QList lprPrinters; int defprn = qt_getLprPrinters(lprPrinters); // populating printer combo - QList::const_iterator i = lprPrinters.constBegin(); - for(; i != lprPrinters.constEnd(); ++i) { - list.append(QPrinterInfo((*i).name)); - } - if (defprn >= 0 && defprn < lprPrinters.size()) { - list[defprn].d_ptr->isDefault = true; - } -#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) + foreach (const QPrinterDescription &description, lprPrinters) + printers.append(QPrinterInfo(description.name)); + if (defprn >= 0 && defprn < printers.size()) + printers[defprn].d_ptr->isDefault = true; } -#endif - return list; + return printers; } QPrinterInfo QPrinterInfo::defaultPrinter() { - QList prnList = availablePrinters(); - for (int i = 0; i < prnList.size(); ++i) { - if (prnList[i].isDefault()) - return prnList[i]; + QList printers = availablePrinters(); + foreach (const QPrinterInfo &printerInfo, printers) { + if (printerInfo.isDefault()) + return printerInfo; } - return (prnList.size() > 0) ? prnList[0] : QPrinterInfo(); + + return printers.value(0); } QList QPrinterInfo::supportedPaperSizes() const diff --git a/src/gui/painting/qprinterinfo_win.cpp b/src/gui/painting/qprinterinfo_win.cpp index 962aa2d..6adf5a4 100644 --- a/src/gui/painting/qprinterinfo_win.cpp +++ b/src/gui/painting/qprinterinfo_win.cpp @@ -55,25 +55,22 @@ extern QPrinter::PaperSize mapDevmodePaperSize(int s); QList QPrinterInfo::availablePrinters() { QList printers; - LPBYTE buffer; + DWORD needed = 0; DWORD returned = 0; - - if ( !EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned)) - { - buffer = new BYTE[needed]; - if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS , NULL, - 4, buffer, needed, &needed, &returned)) - { - delete [] buffer; - return printers; - } - PPRINTER_INFO_4 infoList = reinterpret_cast(buffer); - QPrinterInfo defPrn = defaultPrinter(); - for (uint i = 0; i < returned; ++i) { - printers.append(QPrinterInfo(QString::fromWCharArray(infoList[i].pPrinterName))); - if (printers.at(i).printerName() == defPrn.printerName()) - printers[i].d_ptr->isDefault = true; + if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned)) { + LPBYTE buffer = new BYTE[needed]; + if (EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer, needed, &needed, &returned)) { + PPRINTER_INFO_4 infoList = reinterpret_cast(buffer); + QPrinterInfo defPrn = defaultPrinter(); + for (uint i = 0; i < returned; ++i) { + QString printerName(QString::fromWCharArray(infoList[i].pPrinterName)); + + QPrinterInfo printerInfo(printerName); + if (printerInfo.printerName() == defPrn.printerName()) + printerInfo.d_ptr->isDefault = true; + printers.append(printerInfo); + } } delete [] buffer; } @@ -88,40 +85,35 @@ QPrinterInfo QPrinterInfo::defaultPrinter() GetProfileString(L"windows", L"device", (wchar_t*)noPrinters.utf16(), buffer, 256); QString output = QString::fromWCharArray(buffer); - // Filter out the name of the printer, which should be everything - // before a comma. + // Filter out the name of the printer, which should be everything before a comma. bool noConfiguredPrinters = (output == noPrinters); - QStringList info = output.split(QLatin1Char(',')); - QString printerName = noConfiguredPrinters ? QString() : info.at(0); + QString printerName = output.split(QLatin1Char(',')).value(0); - QPrinterInfo prn(printerName); - prn.d_ptr->isDefault = true; + QPrinterInfo printerInfo(printerName); + printerInfo.d_ptr->isDefault = true; if (noConfiguredPrinters) - prn.d_ptr->isNull = true; - return prn; + printerInfo.d_ptr->isNull = true; + return printerInfo; } QList QPrinterInfo::supportedPaperSizes() const { const Q_D(QPrinterInfo); - QList paperList; + + QList paperSizes; DWORD size = DeviceCapabilities(reinterpret_cast(d->name.utf16()), NULL, DC_PAPERS, NULL, NULL); - if ((int)size == -1) - return paperList; - - wchar_t *papers = new wchar_t[size]; - size = DeviceCapabilities(reinterpret_cast(d->name.utf16()), - NULL, DC_PAPERS, papers, NULL); - - for (int c = 0; c < (int)size; ++c) { - paperList.append(mapDevmodePaperSize(papers[c])); + if ((int)size != -1) { + wchar_t *papers = new wchar_t[size]; + size = DeviceCapabilities(reinterpret_cast(d->name.utf16()), + NULL, DC_PAPERS, papers, NULL); + for (int c = 0; c < (int)size; ++c) + paperSizes.append(mapDevmodePaperSize(papers[c])); + delete [] papers; } - delete [] papers; - - return paperList; + return paperSizes; } #endif // QT_NO_PRINTER -- cgit v0.12 From ed2abc6f5d8b2fe9e819d473768767c11f9c83ba Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 1 Dec 2010 13:24:44 +0300 Subject: fix QPrinterInfo::defaultPrinter() on win to not return a partially filled invalid printer info. is the default printer couldn't be retrieved, return an invalid QPrinterInfo() rather than a semi-invalid info which has isDefault() == true and printerName() == "qt_no_printers" Merge-request: 2516 Signed-off-by: axis --- src/gui/painting/qprinterinfo_win.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/gui/painting/qprinterinfo_win.cpp b/src/gui/painting/qprinterinfo_win.cpp index 6adf5a4..f7b6874 100644 --- a/src/gui/painting/qprinterinfo_win.cpp +++ b/src/gui/painting/qprinterinfo_win.cpp @@ -84,16 +84,15 @@ QPrinterInfo QPrinterInfo::defaultPrinter() wchar_t buffer[256]; GetProfileString(L"windows", L"device", (wchar_t*)noPrinters.utf16(), buffer, 256); QString output = QString::fromWCharArray(buffer); + if (output != noPrinters) { + // Filter out the name of the printer, which should be everything before a comma. + QString printerName = output.split(QLatin1Char(',')).value(0); + QPrinterInfo printerInfo(printerName); + printerInfo.d_ptr->isDefault = true; + return printerInfo; + } - // Filter out the name of the printer, which should be everything before a comma. - bool noConfiguredPrinters = (output == noPrinters); - QString printerName = output.split(QLatin1Char(',')).value(0); - - QPrinterInfo printerInfo(printerName); - printerInfo.d_ptr->isDefault = true; - if (noConfiguredPrinters) - printerInfo.d_ptr->isNull = true; - return printerInfo; + return QPrinterInfo(); } QList QPrinterInfo::supportedPaperSizes() const -- cgit v0.12 From 50af3716c956be0f50fdd896925da7af91d5da2c Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 1 Dec 2010 13:46:24 +0300 Subject: QPrinterInfo::supportedPaperSizes(): return early if the info is invalid e.g. don't report supported paper sized in any case Merge-request: 2516 Signed-off-by: axis --- src/gui/painting/qprinterinfo_mac.cpp | 2 ++ src/gui/painting/qprinterinfo_unix.cpp | 3 +++ src/gui/painting/qprinterinfo_win.cpp | 2 ++ 3 files changed, 7 insertions(+) diff --git a/src/gui/painting/qprinterinfo_mac.cpp b/src/gui/painting/qprinterinfo_mac.cpp index 8d41217..033682a 100644 --- a/src/gui/painting/qprinterinfo_mac.cpp +++ b/src/gui/painting/qprinterinfo_mac.cpp @@ -87,6 +87,8 @@ QList QPrinterInfo::supportedPaperSizes() const const Q_D(QPrinterInfo); QList paperSizes; + if (isNull()) + return paperSizes; PMPrinter cfPrn = PMPrinterCreateFromPrinterID(QCFString::toCFStringRef(d->name)); if (!cfPrn) diff --git a/src/gui/painting/qprinterinfo_unix.cpp b/src/gui/painting/qprinterinfo_unix.cpp index be24bd7..af2e52a 100644 --- a/src/gui/painting/qprinterinfo_unix.cpp +++ b/src/gui/painting/qprinterinfo_unix.cpp @@ -898,6 +898,9 @@ QList QPrinterInfo::supportedPaperSizes() const #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) const Q_D(QPrinterInfo); + if (isNull()) + return d->paperSizes; + if (!d->hasPaperSizes) { d->hasPaperSizes = true; diff --git a/src/gui/painting/qprinterinfo_win.cpp b/src/gui/painting/qprinterinfo_win.cpp index f7b6874..2d25063 100644 --- a/src/gui/painting/qprinterinfo_win.cpp +++ b/src/gui/painting/qprinterinfo_win.cpp @@ -100,6 +100,8 @@ QList QPrinterInfo::supportedPaperSizes() const const Q_D(QPrinterInfo); QList paperSizes; + if (isNull()) + return paperSizes; DWORD size = DeviceCapabilities(reinterpret_cast(d->name.utf16()), NULL, DC_PAPERS, NULL, NULL); -- cgit v0.12 From 1d6266e751d6b23a15f56bc21c503fe1a71da975 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 1 Dec 2010 14:28:32 +0300 Subject: get rid of QPrinterInfoPrivate::isNull member invalid QPrinterInfo always have d_ptr == &QPrinterInfoPrivate::shared_null; no need in separate flag for that Merge-request: 2516 Signed-off-by: axis --- src/gui/painting/qprinterinfo.cpp | 2 +- src/gui/painting/qprinterinfo_p.h | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qprinterinfo.cpp b/src/gui/painting/qprinterinfo.cpp index 21d56f3..72f8be3 100644 --- a/src/gui/painting/qprinterinfo.cpp +++ b/src/gui/painting/qprinterinfo.cpp @@ -146,7 +146,7 @@ QString QPrinterInfo::printerName() const bool QPrinterInfo::isNull() const { const Q_D(QPrinterInfo); - return d->isNull; + return d == &QPrinterInfoPrivate::shared_null; } /*! diff --git a/src/gui/painting/qprinterinfo_p.h b/src/gui/painting/qprinterinfo_p.h index f5981d4..7781d59 100644 --- a/src/gui/painting/qprinterinfo_p.h +++ b/src/gui/painting/qprinterinfo_p.h @@ -65,7 +65,7 @@ class QPrinterInfoPrivate { public: QPrinterInfoPrivate(const QString& name = QString()) : - name(name), isNull(false), isDefault(false) + name(name), isDefault(false) #if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA) #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) , cupsPrinterIndex(0), hasPaperSizes(false) @@ -78,7 +78,6 @@ public: static QPrinterInfoPrivate shared_null; QString name; - bool isNull; bool isDefault; #if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA) -- cgit v0.12 From b24447e0f20db4a40df724476c6542ea44590935 Mon Sep 17 00:00:00 2001 From: axis Date: Mon, 20 Dec 2010 16:09:50 +0100 Subject: Fixed autotest. --- tests/auto/qprinterinfo/tst_qprinterinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qprinterinfo/tst_qprinterinfo.cpp b/tests/auto/qprinterinfo/tst_qprinterinfo.cpp index c3fad6c..4f767a5 100644 --- a/tests/auto/qprinterinfo/tst_qprinterinfo.cpp +++ b/tests/auto/qprinterinfo/tst_qprinterinfo.cpp @@ -134,7 +134,7 @@ QStringList tst_QPrinterInfo::getPrintersFromSystem() QString output = getOutputFromCommand(command); QStringList list = output.split(QChar::fromLatin1('\n')); - QRegExp reg("^[Pp]rinter ([.a-zA-Z0-9_-]+)"); + QRegExp reg("^[Pp]rinter ([.a-zA-Z0-9-_@]+)"); for (int c = 0; c < list.size(); ++c) { if (reg.indexIn(list[c]) >= 0) { QString printer = reg.cap(1); -- cgit v0.12 From 9a18739c538013a7f2111e68e9255379cfbd9a57 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Tue, 12 Oct 2010 13:11:38 +0200 Subject: Ensure that every thread does contend in the contention tests 2 semaphore barrier is not enough to ensure that every thread does run as part of the benchmark. It is possible that a single thread, given enough time, could do all the work while the other threads remain dormant. Prevent this by making sure that the each thread rendevous with both the semaphore barriers at the start of their run(), yields after unlocking, and then rendevous again at the end. Reviewed-by: joao --- .../corelib/thread/qmutex/tst_qmutex.cpp | 93 ++++++++++++++-------- 1 file changed, 60 insertions(+), 33 deletions(-) diff --git a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp index 7a6b45c..cbfffe5 100644 --- a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp +++ b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp @@ -95,6 +95,9 @@ class tst_QMutex : public QObject int threadCount; public: + // barriers for the contended tests + static QSemaphore semaphore1, semaphore2, semaphore3, semaphore4; + tst_QMutex() { // at least 2 threads, even on single cpu/core machines @@ -119,6 +122,11 @@ private slots: void contendedQMutexLocker(); }; +QSemaphore tst_QMutex::semaphore1; +QSemaphore tst_QMutex::semaphore2; +QSemaphore tst_QMutex::semaphore3; +QSemaphore tst_QMutex::semaphore4; + void tst_QMutex::noThread_data() { QTest::addColumn("t"); @@ -220,17 +228,17 @@ void tst_QMutex::contendedNative_data() class NativeMutexThread : public QThread { - QSemaphore *semaphore1, *semaphore2; NativeMutexType *mutex; int iterations, msleepDuration; public: bool done; - NativeMutexThread(QSemaphore *semaphore1, QSemaphore *semaphore2, NativeMutexType *mutex, int iterations, int msleepDuration) - : semaphore1(semaphore1), semaphore2(semaphore2), mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false) + NativeMutexThread(NativeMutexType *mutex, int iterations, int msleepDuration) + : mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false) { } void run() { forever { - semaphore1->acquire(); + tst_QMutex::semaphore1.release(); + tst_QMutex::semaphore2.acquire(); if (done) break; for (int i = 0; i < iterations; ++i) { @@ -238,8 +246,11 @@ public: if (msleepDuration >= 0) msleep(msleepDuration); NativeMutexUnlock(mutex); + + QThread::yieldCurrentThread(); } - semaphore2->release(); + tst_QMutex::semaphore3.release(); + tst_QMutex::semaphore4.acquire(); } } }; @@ -249,24 +260,26 @@ void tst_QMutex::contendedNative() QFETCH(int, iterations); QFETCH(int, msleepDuration); - QSemaphore semaphore1, semaphore2; NativeMutexType mutex; NativeMutexInitialize(&mutex); QVector threads(threadCount); for (int i = 0; i < threads.count(); ++i) { - threads[i] = new NativeMutexThread(&semaphore1, &semaphore2, &mutex, iterations, msleepDuration); + threads[i] = new NativeMutexThread(&mutex, iterations, msleepDuration); threads[i]->start(); } QBENCHMARK { - semaphore1.release(threadCount); - semaphore2.acquire(threadCount); + semaphore1.acquire(threadCount); + semaphore2.release(threadCount); + semaphore3.acquire(threadCount); + semaphore4.release(threadCount); } for (int i = 0; i < threads.count(); ++i) threads[i]->done = true; - semaphore1.release(threadCount); + semaphore1.acquire(threadCount); + semaphore2.release(threadCount); for (int i = 0; i < threads.count(); ++i) threads[i]->wait(); qDeleteAll(threads); @@ -276,17 +289,17 @@ void tst_QMutex::contendedNative() class QMutexThread : public QThread { - QSemaphore *semaphore1, *semaphore2; QMutex *mutex; int iterations, msleepDuration; public: bool done; - QMutexThread(QSemaphore *semaphore1, QSemaphore *semaphore2, QMutex *mutex, int iterations, int msleepDuration) - : semaphore1(semaphore1), semaphore2(semaphore2), mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false) + QMutexThread(QMutex *mutex, int iterations, int msleepDuration) + : mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false) { } void run() { forever { - semaphore1->acquire(); + tst_QMutex::semaphore1.release(); + tst_QMutex::semaphore2.acquire(); if (done) break; for (int i = 0; i < iterations; ++i) { @@ -294,8 +307,11 @@ public: if (msleepDuration >= 0) msleep(msleepDuration); mutex->unlock(); + + QThread::yieldCurrentThread(); } - semaphore2->release(); + tst_QMutex::semaphore3.release(); + tst_QMutex::semaphore4.acquire(); } } }; @@ -304,23 +320,26 @@ void tst_QMutex::contendedQMutex() { QFETCH(int, iterations); QFETCH(int, msleepDuration); - QSemaphore semaphore1, semaphore2; + QMutex mutex; QVector threads(threadCount); for (int i = 0; i < threads.count(); ++i) { - threads[i] = new QMutexThread(&semaphore1, &semaphore2, &mutex, iterations, msleepDuration); + threads[i] = new QMutexThread(&mutex, iterations, msleepDuration); threads[i]->start(); } QBENCHMARK { - semaphore1.release(threadCount); - semaphore2.acquire(threadCount); + semaphore1.acquire(threadCount); + semaphore2.release(threadCount); + semaphore3.acquire(threadCount); + semaphore4.release(threadCount); } for (int i = 0; i < threads.count(); ++i) threads[i]->done = true; - semaphore1.release(threadCount); + semaphore1.acquire(threadCount); + semaphore2.release(threadCount); for (int i = 0; i < threads.count(); ++i) threads[i]->wait(); qDeleteAll(threads); @@ -328,25 +347,30 @@ void tst_QMutex::contendedQMutex() class QMutexLockerThread : public QThread { - QSemaphore *semaphore1, *semaphore2; QMutex *mutex; int iterations, msleepDuration; public: bool done; - QMutexLockerThread(QSemaphore *semaphore1, QSemaphore *semaphore2, QMutex *mutex, int iterations, int msleepDuration) - : semaphore1(semaphore1), semaphore2(semaphore2), mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false) + QMutexLockerThread(QMutex *mutex, int iterations, int msleepDuration) + : mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false) { } void run() { forever { - semaphore1->acquire(); + tst_QMutex::semaphore1.release(); + tst_QMutex::semaphore2.acquire(); if (done) break; for (int i = 0; i < iterations; ++i) { - QMutexLocker locker(mutex); - if (msleepDuration >= 0) - msleep(msleepDuration); + { + QMutexLocker locker(mutex1); + if (msleepDuration >= 0) + msleep(msleepDuration); + } + + QThread::yieldCurrentThread(); } - semaphore2->release(); + tst_QMutex::semaphore3.release(); + tst_QMutex::semaphore4.acquire(); } } }; @@ -355,23 +379,26 @@ void tst_QMutex::contendedQMutexLocker() { QFETCH(int, iterations); QFETCH(int, msleepDuration); - QSemaphore semaphore1, semaphore2; + QMutex mutex; QVector threads(threadCount); for (int i = 0; i < threads.count(); ++i) { - threads[i] = new QMutexLockerThread(&semaphore1, &semaphore2, &mutex, iterations, msleepDuration); + threads[i] = new QMutexLockerThread(&mutex, iterations, msleepDuration); threads[i]->start(); } QBENCHMARK { - semaphore1.release(threadCount); - semaphore2.acquire(threadCount); + semaphore1.acquire(threadCount); + semaphore2.release(threadCount); + semaphore3.acquire(threadCount); + semaphore4.release(threadCount); } for (int i = 0; i < threads.count(); ++i) threads[i]->done = true; - semaphore1.release(threadCount); + semaphore1.acquire(threadCount); + semaphore2.release(threadCount); for (int i = 0; i < threads.count(); ++i) threads[i]->wait(); qDeleteAll(threads); -- cgit v0.12 From d9c00320a1e1f6aa7d0083b3415704e20e216a1f Mon Sep 17 00:00:00 2001 From: axis Date: Mon, 6 Dec 2010 13:41:51 +0100 Subject: Moved the default dependency targets to default_post.prf. The file that they were in would not be parsed if CONFIG -= qt, but it always needs to be parsed, otherwise apps that don't use Qt will fail the sis file creation. RevBy: Miikka Heikkinen --- mkspecs/features/symbian/default_post.prf | 47 +++++++++++++++++++++++++++++++ mkspecs/features/symbian/qt.prf | 47 ------------------------------- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/mkspecs/features/symbian/default_post.prf b/mkspecs/features/symbian/default_post.prf index a2ac377..89f655d 100644 --- a/mkspecs/features/symbian/default_post.prf +++ b/mkspecs/features/symbian/default_post.prf @@ -53,6 +53,53 @@ isEmpty(TARGET.UID2) { } } +# Allow .pro files to specify include path(s) to be prepended to the list. +# +# This allows the project to override the default ordering, whereby paths +# relative to $$QMAKE_INCDIR_QT always come first. This ordering can cause +# problems when both the epoc32/include tree and a Qt include directory +# contain a header of the same name - in this case, the Qt header is always +# included by virtue of its path appearing first in the SYSTEMINCLUDE +# directives in the generated MMP file. +# +# To work around this situation, the following line can be added to the .pro +# file: +# PREPEND_INCLUDEPATH = /epoc32/include +# +INCLUDEPATH = $$PREPEND_INCLUDEPATH $$INCLUDEPATH + +# Add dependency to Qt package to all other projects besides Qt libs. +# Note: Qt libs package with full capabilities has UID3 of 0x2001E61C, +# while self-signed version typically has temporary UID3 of 0xE001E61C. +contains(CONFIG, qt):!contains(TARGET.UID3, 0x2001E61C):!contains(TARGET.UID3, 0xE001E61C):isEmpty(QT_LIBINFIX) { + qt_pkg_name = Qt + pkg_depends_qt += \ + "; Default dependency to Qt libraries" \ + "(0x2001E61C), $${QT_MAJOR_VERSION}, $${QT_MINOR_VERSION}, $${QT_PATCH_VERSION}, {$$addLanguageDependentPkgItem(qt_pkg_name)}" + + # Projects linking to webkit need dependency to webkit + contains(QT, webkit): { + # these can be overridden by mkspecs/modules/qt_webkit.pri + isEmpty(QT_WEBKIT_MAJOR_VERSION) { + QT_WEBKIT_MAJOR_VERSION = $${QT_MAJOR_VERSION} + QT_WEBKIT_MINOR_VERSION = $${QT_MINOR_VERSION} + QT_WEBKIT_PATCH_VERSION = $${QT_PATCH_VERSION} + } + + webkit_pkg_name = QtWebKit + pkg_depends_webkit += \ + "; Dependency to Qt Webkit" \ + "(0x200267C2), $${QT_WEBKIT_MAJOR_VERSION}, $${QT_WEBKIT_MINOR_VERSION}, $${QT_WEBKIT_PATCH_VERSION}, {$$addLanguageDependentPkgItem(webkit_pkg_name)}" + } else { + default_deployment.pkg_prerules -= pkg_depends_webkit + } +} else { + default_deployment.pkg_prerules -= pkg_depends_webkit pkg_depends_qt +} + +isEmpty(TARGET.EPOCSTACKSIZE):TARGET.EPOCSTACKSIZE = 0x14000 +isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x020000 0x800000 + # Supports S60 3.1, 3.2, 5.0, Symbian^3, and Symbian^4 by default platform_product_id = S60ProductID platform_product_id = $$addLanguageDependentPkgItem(platform_product_id) diff --git a/mkspecs/features/symbian/qt.prf b/mkspecs/features/symbian/qt.prf index c8f97aa..c376b64 100644 --- a/mkspecs/features/symbian/qt.prf +++ b/mkspecs/features/symbian/qt.prf @@ -6,53 +6,6 @@ CONFIG += qtmain load(qt) -# Allow .pro files to specify include path(s) to be prepended to the list. -# -# This allows the project to override the default ordering, whereby paths -# relative to $$QMAKE_INCDIR_QT always come first. This ordering can cause -# problems when both the epoc32/include tree and a Qt include directory -# contain a header of the same name - in this case, the Qt header is always -# included by virtue of its path appearing first in the SYSTEMINCLUDE -# directives in the generated MMP file. -# -# To work around this situation, the following line can be added to the .pro -# file: -# PREPEND_INCLUDEPATH = /epoc32/include -# -INCLUDEPATH = $$PREPEND_INCLUDEPATH $$INCLUDEPATH - -# Add dependency to Qt package to all other projects besides Qt libs. -# Note: Qt libs package with full capabilities has UID3 of 0x2001E61C, -# while self-signed version typically has temporary UID3 of 0xE001E61C. -contains(CONFIG, qt):!contains(TARGET.UID3, 0x2001E61C):!contains(TARGET.UID3, 0xE001E61C):isEmpty(QT_LIBINFIX) { - qt_pkg_name = Qt - pkg_depends_qt += \ - "; Default dependency to Qt libraries" \ - "(0x2001E61C), $${QT_MAJOR_VERSION}, $${QT_MINOR_VERSION}, $${QT_PATCH_VERSION}, {$$addLanguageDependentPkgItem(qt_pkg_name)}" - - # Projects linking to webkit need dependency to webkit - contains(QT, webkit): { - # these can be overridden by mkspecs/modules/qt_webkit.pri - isEmpty(QT_WEBKIT_MAJOR_VERSION) { - QT_WEBKIT_MAJOR_VERSION = $${QT_MAJOR_VERSION} - QT_WEBKIT_MINOR_VERSION = $${QT_MINOR_VERSION} - QT_WEBKIT_PATCH_VERSION = $${QT_PATCH_VERSION} - } - - webkit_pkg_name = QtWebKit - pkg_depends_webkit += \ - "; Dependency to Qt Webkit" \ - "(0x200267C2), $${QT_WEBKIT_MAJOR_VERSION}, $${QT_WEBKIT_MINOR_VERSION}, $${QT_WEBKIT_PATCH_VERSION}, {$$addLanguageDependentPkgItem(webkit_pkg_name)}" - } else { - default_deployment.pkg_prerules -= pkg_depends_webkit - } -} else { - default_deployment.pkg_prerules -= pkg_depends_webkit pkg_depends_qt -} - -isEmpty(TARGET.EPOCSTACKSIZE):TARGET.EPOCSTACKSIZE = 0x14000 -isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x020000 0x800000 - # Workaround for the fact that Gnupoc and Symbian chose different approaches to # the letter casing of headers. contains(CONFIG, is_using_gnupoc) { -- cgit v0.12 From 2d87a865b26250dcecbcf73178f8091e0724106d Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 13 Oct 2010 12:33:27 +0200 Subject: test contention when using 2 mutexes add test data and adapt the test harness to allow testing contention performance when using 2 mutexes (2 mutexes are often used inside of Qt, so we want to ensure that this also performs well). Reviewed-by: joao --- .../corelib/thread/qmutex/tst_qmutex.cpp | 81 ++++++++++++++-------- 1 file changed, 53 insertions(+), 28 deletions(-) diff --git a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp index cbfffe5..b0c5702 100644 --- a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp +++ b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp @@ -218,22 +218,31 @@ void tst_QMutex::contendedNative_data() { QTest::addColumn("iterations"); QTest::addColumn("msleepDuration"); - QTest::newRow("baseline") << 0 << -1; - QTest::newRow("no msleep") << 1000 << -1; - QTest::newRow("msleep(0)") << 1000 << 0; - QTest::newRow("msleep(1)") << 10 << 1; - QTest::newRow("msleep(2)") << 10 << 2; - QTest::newRow("msleep(10)") << 10 << 10; + QTest::addColumn("use2mutexes"); + + QTest::newRow("baseline") << 0 << -1 << false; + + QTest::newRow("no msleep, 1 mutex") << 1000 << -1 << false; + QTest::newRow("no msleep, 2 mutexes") << 1000 << -1 << true; + QTest::newRow("msleep(0), 1 mutex") << 1000 << 0 << false; + QTest::newRow("msleep(0), 2 mutexes") << 1000 << 0 << true; + QTest::newRow("msleep(1), 1 mutex") << 10 << 1 << false; + QTest::newRow("msleep(1), 2 mutexes") << 10 << 1 << true; + QTest::newRow("msleep(2), 1 mutex") << 10 << 2 << false; + QTest::newRow("msleep(2), 2 mutexes") << 10 << 2 << true; + QTest::newRow("msleep(10), 1 mutex") << 10 << 10 << false; + QTest::newRow("msleep(10), 2 mutexes") << 10 << 10 << true; } class NativeMutexThread : public QThread { - NativeMutexType *mutex; + NativeMutexType *mutex1, *mutex2; int iterations, msleepDuration; + bool use2mutexes; public: bool done; - NativeMutexThread(NativeMutexType *mutex, int iterations, int msleepDuration) - : mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false) + NativeMutexThread(NativeMutexType *mutex1, NativeMutexType *mutex2, int iterations, int msleepDuration, bool use2mutexes) + : mutex1(mutex1), mutex2(mutex2), iterations(iterations), msleepDuration(msleepDuration), use2mutexes(use2mutexes), done(false) { } void run() { forever { @@ -242,10 +251,14 @@ public: if (done) break; for (int i = 0; i < iterations; ++i) { - NativeMutexLock(mutex); + NativeMutexLock(mutex1); + if (use2mutexes) + NativeMutexLock(mutex2); if (msleepDuration >= 0) msleep(msleepDuration); - NativeMutexUnlock(mutex); + if (use2mutexes) + NativeMutexUnlock(mutex2); + NativeMutexUnlock(mutex1); QThread::yieldCurrentThread(); } @@ -259,13 +272,15 @@ void tst_QMutex::contendedNative() { QFETCH(int, iterations); QFETCH(int, msleepDuration); + QFETCH(bool, use2mutexes); - NativeMutexType mutex; - NativeMutexInitialize(&mutex); + NativeMutexType mutex1, mutex2; + NativeMutexInitialize(&mutex1); + NativeMutexInitialize(&mutex2); QVector threads(threadCount); for (int i = 0; i < threads.count(); ++i) { - threads[i] = new NativeMutexThread(&mutex, iterations, msleepDuration); + threads[i] = new NativeMutexThread(&mutex1, &mutex2, iterations, msleepDuration, use2mutexes); threads[i]->start(); } @@ -284,17 +299,19 @@ void tst_QMutex::contendedNative() threads[i]->wait(); qDeleteAll(threads); - NativeMutexDestroy(&mutex); + NativeMutexDestroy(&mutex1); + NativeMutexDestroy(&mutex2); } class QMutexThread : public QThread { - QMutex *mutex; + QMutex *mutex1, *mutex2; int iterations, msleepDuration; + bool use2mutexes; public: bool done; - QMutexThread(QMutex *mutex, int iterations, int msleepDuration) - : mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false) + QMutexThread(QMutex *mutex1, QMutex *mutex2, int iterations, int msleepDuration, bool use2mutexes) + : mutex1(mutex1), mutex2(mutex2), iterations(iterations), msleepDuration(msleepDuration), use2mutexes(use2mutexes), done(false) { } void run() { forever { @@ -303,10 +320,14 @@ public: if (done) break; for (int i = 0; i < iterations; ++i) { - mutex->lock(); + mutex1->lock(); + if (use2mutexes) + mutex2->lock(); if (msleepDuration >= 0) msleep(msleepDuration); - mutex->unlock(); + if (use2mutexes) + mutex2->unlock(); + mutex1->unlock(); QThread::yieldCurrentThread(); } @@ -320,12 +341,13 @@ void tst_QMutex::contendedQMutex() { QFETCH(int, iterations); QFETCH(int, msleepDuration); + QFETCH(bool, use2mutexes); - QMutex mutex; + QMutex mutex1, mutex2; QVector threads(threadCount); for (int i = 0; i < threads.count(); ++i) { - threads[i] = new QMutexThread(&mutex, iterations, msleepDuration); + threads[i] = new QMutexThread(&mutex1, &mutex2, iterations, msleepDuration, use2mutexes); threads[i]->start(); } @@ -347,12 +369,13 @@ void tst_QMutex::contendedQMutex() class QMutexLockerThread : public QThread { - QMutex *mutex; + QMutex *mutex1, *mutex2; int iterations, msleepDuration; + bool use2mutexes; public: bool done; - QMutexLockerThread(QMutex *mutex, int iterations, int msleepDuration) - : mutex(mutex), iterations(iterations), msleepDuration(msleepDuration), done(false) + QMutexLockerThread(QMutex *mutex1, QMutex *mutex2, int iterations, int msleepDuration, bool use2mutexes) + : mutex1(mutex1), mutex2(mutex2), iterations(iterations), msleepDuration(msleepDuration), use2mutexes(use2mutexes), done(false) { } void run() { forever { @@ -362,7 +385,8 @@ public: break; for (int i = 0; i < iterations; ++i) { { - QMutexLocker locker(mutex1); + QMutexLocker locker1(mutex1); + QMutexLocker locker2(use2mutexes ? mutex2 : 0); if (msleepDuration >= 0) msleep(msleepDuration); } @@ -379,12 +403,13 @@ void tst_QMutex::contendedQMutexLocker() { QFETCH(int, iterations); QFETCH(int, msleepDuration); + QFETCH(bool, use2mutexes); - QMutex mutex; + QMutex mutex1, mutex2; QVector threads(threadCount); for (int i = 0; i < threads.count(); ++i) { - threads[i] = new QMutexLockerThread(&mutex, iterations, msleepDuration); + threads[i] = new QMutexLockerThread(&mutex1, &mutex2, iterations, msleepDuration, use2mutexes); threads[i]->start(); } -- cgit v0.12 From d9e35493d494df60d771a928a8d0dbde2b66906e Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 16 Sep 2010 10:50:25 +0200 Subject: Move contender count maintenance to QMutexPrivate Make the cross-platform implementation of QMutex in qmutex.cpp only use testAndSetAcquire(0, 1) and testAndSetRelease(1, 0) like in the new inline functions in qmutex.h This will allow us to open up for more platform-specific optimizations to improve performance of contended QMutexes. Reviewed-by: joao --- src/corelib/thread/qmutex.cpp | 43 ++++++++------------------------------ src/corelib/thread/qmutex_unix.cpp | 5 +++++ src/corelib/thread/qmutex_win.cpp | 8 ++++++- 3 files changed, 21 insertions(+), 35 deletions(-) diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index b85a22d..403468a 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -157,15 +157,12 @@ void QMutex::lock() return; } - bool isLocked = d->contenders.fetchAndAddAcquire(1) == 0; + bool isLocked = d->contenders.testAndSetAcquire(0, 1); if (!isLocked) { // didn't get the lock, wait for it isLocked = d->wait(); Q_ASSERT_X(isLocked, "QMutex::lock", "Internal error, infinite wait has timed out."); - - // don't need to wait for the lock anymore - d->contenders.deref(); } d->owner = self; @@ -174,8 +171,7 @@ void QMutex::lock() return; } - - bool isLocked = d->contenders == 0 && d->contenders.testAndSetAcquire(0, 1); + bool isLocked = d->contenders.testAndSetAcquire(0, 1); if (!isLocked) { lockInternal(); } @@ -211,7 +207,7 @@ bool QMutex::tryLock() return true; } - bool isLocked = d->contenders == 0 && d->contenders.testAndSetAcquire(0, 1); + bool isLocked = d->contenders.testAndSetAcquire(0, 1); if (!isLocked) { // some other thread has the mutex locked, or we tried to // recursively lock an non-recursive mutex @@ -224,13 +220,7 @@ bool QMutex::tryLock() return isLocked; } - bool isLocked = d->contenders == 0 && d->contenders.testAndSetAcquire(0, 1); - if (!isLocked) { - // some other thread has the mutex locked, or we tried to - // recursively lock an non-recursive mutex - return isLocked; - } - return isLocked; + return d->contenders.testAndSetAcquire(0, 1); } /*! \overload @@ -269,13 +259,10 @@ bool QMutex::tryLock(int timeout) return true; } - bool isLocked = d->contenders.fetchAndAddAcquire(1) == 0; + bool isLocked = d->contenders.testAndSetAcquire(0, 1); if (!isLocked) { // didn't get the lock, wait for it isLocked = d->wait(timeout); - - // don't need to wait for the lock anymore - d->contenders.deref(); if (!isLocked) return false; } @@ -286,17 +273,9 @@ bool QMutex::tryLock(int timeout) return true; } - bool isLocked = d->contenders.fetchAndAddAcquire(1) == 0; - if (!isLocked) { - // didn't get the lock, wait for it - isLocked = d->wait(timeout); - - // don't need to wait for the lock anymore - d->contenders.deref(); - if (!isLocked) - return false; - } - return true; + return (d->contenders.testAndSetAcquire(0, 1) + // didn't get the lock, wait for it + || d->wait(timeout)); } @@ -310,7 +289,6 @@ bool QMutex::tryLock(int timeout) void QMutex::unlock() { QMutexPrivate *d = static_cast(this->d); - if (d->recursive) { if (!--d->count) { d->owner = 0; @@ -460,16 +438,13 @@ void QMutex::lockInternal() do { if (spinCount++ > maximumSpinCount) { // puts("spinning useless, sleeping"); - bool isLocked = d->contenders.fetchAndAddAcquire(1) == 0; + bool isLocked = d->contenders.testAndSetAcquire(0, 1); if (!isLocked) { // didn't get the lock, wait for it isLocked = d->wait(); Q_ASSERT_X(isLocked, "QMutex::lock", "Internal error, infinite wait has timed out."); - - // don't need to wait for the lock anymore - d->contenders.deref(); } // decrease the lastSpinCount since we didn't actually get the lock by spinning spinCount = -d->lastSpinCount / SpinCountPenalizationDivisor; diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp index 7e7ef22..dcf8b9f 100644 --- a/src/corelib/thread/qmutex_unix.cpp +++ b/src/corelib/thread/qmutex_unix.cpp @@ -77,6 +77,10 @@ QMutexPrivate::~QMutexPrivate() bool QMutexPrivate::wait(int timeout) { + if (contenders.fetchAndAddAcquire(1) == 0) { + // lock acquired without waiting + return true; + } report_error(pthread_mutex_lock(&mutex), "QMutex::lock", "mutex lock"); int errorCode = 0; while (!wakeup) { @@ -101,6 +105,7 @@ bool QMutexPrivate::wait(int timeout) } wakeup = false; report_error(pthread_mutex_unlock(&mutex), "QMutex::lock", "mutex unlock"); + contenders.deref(); return errorCode == 0; } diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp index a810000..c278f04 100644 --- a/src/corelib/thread/qmutex_win.cpp +++ b/src/corelib/thread/qmutex_win.cpp @@ -60,7 +60,13 @@ QMutexPrivate::~QMutexPrivate() bool QMutexPrivate::wait(int timeout) { - return WaitForSingleObject(event, timeout < 0 ? INFINITE : timeout) == WAIT_OBJECT_0; + if (contenders.fetchAndAddAcquire(1) == 0) { + // lock acquired without waiting + return true; + } + bool returnValue = (WaitForSingleObject(event, timeout < 0 ? INFINITE : timeout) == WAIT_OBJECT_0); + contenders.deref(); + return returnValue; } void QMutexPrivate::wakeUp() -- cgit v0.12 From feb0b0cd47808a77a048c6a13686d39a0540a488 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 1 Oct 2010 09:44:55 +0200 Subject: Remove unnecessary testAndSetAcquire from QMutex::lockInternal() QMutexPrivate::wait() will take care of doing another test for the lock before putting the thread to sleep, so we can avoid another if(). Reviewed-by: joao --- src/corelib/thread/qmutex.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index 403468a..19e2457 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -437,15 +437,12 @@ void QMutex::lockInternal() do { if (spinCount++ > maximumSpinCount) { - // puts("spinning useless, sleeping"); - bool isLocked = d->contenders.testAndSetAcquire(0, 1); - if (!isLocked) { - - // didn't get the lock, wait for it - isLocked = d->wait(); - Q_ASSERT_X(isLocked, "QMutex::lock", - "Internal error, infinite wait has timed out."); - } + // didn't get the lock, wait for it + bool isLocked = d->wait(); + Q_ASSERT_X(isLocked, "QMutex::lock", + "Internal error, infinite wait has timed out."); + Q_UNUSED(isLocked); + // decrease the lastSpinCount since we didn't actually get the lock by spinning spinCount = -d->lastSpinCount / SpinCountPenalizationDivisor; break; -- cgit v0.12 From 87bab705ded31559941020d3c500f43f571f9c16 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 1 Oct 2010 09:45:42 +0200 Subject: Disable spinning under lock contention on single CPU machines Spinning is just wasted time on these systems. Reviewed-by: joao --- src/corelib/thread/qmutex.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index 19e2457..54b3ed4 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -429,6 +429,16 @@ void QMutex::unlock() void QMutex::lockInternal() { QMutexPrivate *d = static_cast(this->d); + + if (QThread::idealThreadCount() == 1) { + // don't spin on single cpu machines + bool isLocked = d->wait(); + Q_ASSERT_X(isLocked, "QMutex::lock", + "Internal error, infinite wait has timed out."); + Q_UNUSED(isLocked); + return; + } + int spinCount = 0; int lastSpinCount = d->lastSpinCount; -- cgit v0.12 From cf17b743d2fe84ab259b7232ab07b58a1872e18e Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 16 Sep 2010 15:46:43 +0200 Subject: Improve QMutex contention performance on Mac OS X Use a Mach semaphore to implement QMutexPrivate::wait() and ::wakeup(). This makes QMutex perform more or less identically the same as pthread_mutex_t when contended. Reviewed-by: joao --- src/corelib/thread/qmutex_p.h | 8 +++++- src/corelib/thread/qmutex_unix.cpp | 53 +++++++++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h index 57a6062..e23be94 100644 --- a/src/corelib/thread/qmutex_p.h +++ b/src/corelib/thread/qmutex_p.h @@ -58,6 +58,10 @@ #include #include +#if defined(Q_OS_MAC) +# include +#endif + QT_BEGIN_NAMESPACE class QMutexPrivate : public QMutexData { @@ -72,7 +76,9 @@ public: Qt::HANDLE owner; uint count; -#if defined(Q_OS_UNIX) +#if defined(Q_OS_MAC) + semaphore_t mach_semaphore; +#elif defined(Q_OS_UNIX) volatile bool wakeup; pthread_mutex_t mutex; pthread_cond_t cond; diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp index dcf8b9f..ce1bfc2 100644 --- a/src/corelib/thread/qmutex_unix.cpp +++ b/src/corelib/thread/qmutex_unix.cpp @@ -53,28 +53,77 @@ #undef wakeup #endif +#if defined(Q_OS_MAC) +# include +# include +#endif + QT_BEGIN_NAMESPACE +#if !defined(Q_OS_MAC) static void report_error(int code, const char *where, const char *what) { if (code != 0) qWarning("%s: %s failure: %s", where, what, qPrintable(qt_error_string(code))); } +#endif QMutexPrivate::QMutexPrivate(QMutex::RecursionMode mode) - : QMutexData(mode), lastSpinCount(0), owner(0), count(0), wakeup(false) + : QMutexData(mode), lastSpinCount(0), owner(0), count(0) { +#if defined(Q_OS_MAC) + kern_return_t r = semaphore_create(mach_task_self(), &mach_semaphore, SYNC_POLICY_FIFO, 0); + if (r != KERN_SUCCESS) + qWarning("QMutex: failed to create semaphore, error %d", r); +#else + wakeup = false; report_error(pthread_mutex_init(&mutex, NULL), "QMutex", "mutex init"); report_error(pthread_cond_init(&cond, NULL), "QMutex", "cv init"); +#endif } QMutexPrivate::~QMutexPrivate() { +#if defined(Q_OS_MAC) + kern_return_t r = semaphore_destroy(mach_task_self(), mach_semaphore); + if (r != KERN_SUCCESS) + qWarning("QMutex: failed to destroy semaphore, error %d", r); +#else report_error(pthread_cond_destroy(&cond), "QMutex", "cv destroy"); report_error(pthread_mutex_destroy(&mutex), "QMutex", "mutex destroy"); +#endif } +#if defined(Q_OS_MAC) + +bool QMutexPrivate::wait(int timeout) +{ + if (contenders.fetchAndAddAcquire(1) == 0) { + // lock acquired without waiting + return true; + } + bool returnValue; + if (timeout < 0) { + returnValue = semaphore_wait(mach_semaphore) == KERN_SUCCESS; + } else { + mach_timespec_t ts; + ts.tv_nsec = ((timeout % 1000) * 1000) * 1000; + ts.tv_sec = (timeout / 1000); + kern_return_t r = semaphore_timedwait(mach_semaphore, ts); + returnValue = r == KERN_SUCCESS; + } + contenders.deref(); + return returnValue; +} + +void QMutexPrivate::wakeUp() +{ + semaphore_signal(mach_semaphore); +} + +#else // !Q_OS_MAC + bool QMutexPrivate::wait(int timeout) { if (contenders.fetchAndAddAcquire(1) == 0) { @@ -117,6 +166,8 @@ void QMutexPrivate::wakeUp() report_error(pthread_mutex_unlock(&mutex), "QMutex::unlock", "mutex unlock"); } +#endif // !Q_OS_MAC + QT_END_NAMESPACE #endif // QT_NO_THREAD -- cgit v0.12 From 8a7b5aca7b6575013a4e4ee9b99808d25edf6fdf Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Mon, 27 Sep 2010 15:19:45 +0200 Subject: Improve QMutex contention performance on Linux Use futex(2) to implement QMutexPrivate::wait() and ::wakeup(). This makes QMutex perform more or less identically the same as pthread_mutex_t when contended. We have to use the contender count in a different way due to the way that futex() waiting works. Waiting on a futex atomically checks that the value has not changed from the expected value and then puts the thread to sleep. So, on Linux, the contender QAtomicInt will only ever be one of three values: 0 for unlocked, 1 for locked, 2 for contended. This does mean that there is a slight chance for unfairness due to the fetch-and-store to zero in the wakeUp() function, but unfortunately this cannot be avoid as the code is now. Reviewed-by: joao --- src/corelib/thread/qmutex_p.h | 2 +- src/corelib/thread/qmutex_unix.cpp | 43 +++++++++++++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h index e23be94..2d45cfb 100644 --- a/src/corelib/thread/qmutex_p.h +++ b/src/corelib/thread/qmutex_p.h @@ -78,7 +78,7 @@ public: #if defined(Q_OS_MAC) semaphore_t mach_semaphore; -#elif defined(Q_OS_UNIX) +#elif defined(Q_OS_UNIX) && !defined(Q_OS_LINUX) volatile bool wakeup; pthread_mutex_t mutex; pthread_cond_t cond; diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp index ce1bfc2..e872187 100644 --- a/src/corelib/thread/qmutex_unix.cpp +++ b/src/corelib/thread/qmutex_unix.cpp @@ -56,11 +56,15 @@ #if defined(Q_OS_MAC) # include # include +#elif defined(Q_OS_LINUX) +# include +# include +# include #endif QT_BEGIN_NAMESPACE -#if !defined(Q_OS_MAC) +#if !defined(Q_OS_MAC) && !defined(Q_OS_LINUX) static void report_error(int code, const char *where, const char *what) { if (code != 0) @@ -76,7 +80,7 @@ QMutexPrivate::QMutexPrivate(QMutex::RecursionMode mode) kern_return_t r = semaphore_create(mach_task_self(), &mach_semaphore, SYNC_POLICY_FIFO, 0); if (r != KERN_SUCCESS) qWarning("QMutex: failed to create semaphore, error %d", r); -#else +#elif !defined(Q_OS_LINUX) wakeup = false; report_error(pthread_mutex_init(&mutex, NULL), "QMutex", "mutex init"); report_error(pthread_cond_init(&cond, NULL), "QMutex", "cv init"); @@ -89,7 +93,7 @@ QMutexPrivate::~QMutexPrivate() kern_return_t r = semaphore_destroy(mach_task_self(), mach_semaphore); if (r != KERN_SUCCESS) qWarning("QMutex: failed to destroy semaphore, error %d", r); -#else +#elif !defined(Q_OS_LINUX) report_error(pthread_cond_destroy(&cond), "QMutex", "cv destroy"); report_error(pthread_mutex_destroy(&mutex), "QMutex", "mutex destroy"); #endif @@ -122,7 +126,36 @@ void QMutexPrivate::wakeUp() semaphore_signal(mach_semaphore); } -#else // !Q_OS_MAC +#elif defined(Q_OS_LINUX) + +static inline int _q_futex(volatile int *addr, int op, int val, const struct timespec *timeout, int *addr2, int val2) +{ + return syscall(SYS_futex, addr, op, val, timeout, addr2, val2); +} + +bool QMutexPrivate::wait(int timeout) +{ + while (contenders.fetchAndStoreAcquire(2) > 0) { + struct timespec ts, *pts = 0; + if (timeout >= 0) { + ts.tv_nsec = ((timeout % 1000) * 1000) * 1000; + ts.tv_sec = (timeout / 1000); + pts = &ts; + } + int r = _q_futex(&contenders._q_value, FUTEX_WAIT, 2, pts, 0, 0); + if (r != 0 && errno == ETIMEDOUT) + return false; + } + return true; +} + +void QMutexPrivate::wakeUp() +{ + (void) contenders.fetchAndStoreRelease(0); + (void) _q_futex(&contenders._q_value, FUTEX_WAKE, 1, 0, 0, 0); +} + +#else // !Q_OS_MAC && !Q_OS_LINUX bool QMutexPrivate::wait(int timeout) { @@ -166,7 +199,7 @@ void QMutexPrivate::wakeUp() report_error(pthread_mutex_unlock(&mutex), "QMutex::unlock", "mutex unlock"); } -#endif // !Q_OS_MAC +#endif // !Q_OS_MAC && !Q_OS_LINUX QT_END_NAMESPACE -- cgit v0.12 From 3b6a84de5c5ed2e1970ad2b396292babb9173227 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 1 Oct 2010 09:50:22 +0200 Subject: Optimize adaptive spinning mutex code Change the adaptive spinning code to be elapsed time based instead of iteration based. The new approach will quickly reduce the amount of allowed spinning time when it detects that lock contention is resolved by waiting instead of spinning. We get better results by dynamically adjusting for elapsed running time instead of trying to fine tune iteration counts that won't work for all CPU types, speeds, etc. From observation, lock performance suffers if the spin time is higher than the minimum wait time. Because of this, QMutex never increases the spin time, it only reduces the spin time to the minimum observed wait time. For very long wait times, we disable spinning completely (and always resolve contention by waiting). Use QThread::yieldCurrentThread() when spinning on a contended mutex. Comment from the code: be a good citizen... yielding lets something else run if there is something to run, but may also relieve memory pressure if not. Reviewed-by: joao --- src/corelib/thread/qmutex.cpp | 36 ++++++++++++++++++++---------------- src/corelib/thread/qmutex_p.h | 4 +++- src/corelib/thread/qmutex_unix.cpp | 2 +- src/corelib/thread/qmutex_win.cpp | 2 +- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index 54b3ed4..72f87b7 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -45,6 +45,7 @@ #ifndef QT_NO_THREAD #include "qatomic.h" +#include "qelapsedtimer.h" #include "qthread.h" #include "qmutex_p.h" @@ -439,31 +440,34 @@ void QMutex::lockInternal() return; } - int spinCount = 0; - int lastSpinCount = d->lastSpinCount; - - enum { AdditionalSpins = 20, SpinCountPenalizationDivisor = 4 }; - const int maximumSpinCount = lastSpinCount + AdditionalSpins; - + QElapsedTimer elapsedTimer; + elapsedTimer.start(); do { - if (spinCount++ > maximumSpinCount) { - // didn't get the lock, wait for it + if (elapsedTimer.hasExpired(d->maximumSpinTime)) { + // didn't get the lock, wait for it, since we're not going to gain anything by spinning more + int spinTime = elapsedTimer.restart(); bool isLocked = d->wait(); Q_ASSERT_X(isLocked, "QMutex::lock", "Internal error, infinite wait has timed out."); Q_UNUSED(isLocked); - // decrease the lastSpinCount since we didn't actually get the lock by spinning - spinCount = -d->lastSpinCount / SpinCountPenalizationDivisor; - break; + int maximumSpinTime = d->maximumSpinTime; + int waitTime = elapsedTimer.elapsed(); + // adjust the spin count when spinning does not benefit contention performance + if (spinTime + waitTime > QMutexPrivate::MaximumSpinTimeThreshold) { + // long waits, stop spinning + d->maximumSpinTime = 0; + } else if (waitTime < maximumSpinTime) { + // never spin more than the minimum wait time (otherwise we may perform worse) + d->maximumSpinTime = waitTime; + } + return; } + // be a good citizen... yielding lets something else run if there is something to run, but may also relieve memory pressure if not + QThread::yieldCurrentThread(); } while (d->contenders != 0 || !d->contenders.testAndSetAcquire(0, 1)); - // adjust the last spin lock count - lastSpinCount = d->lastSpinCount; - d->lastSpinCount = spinCount >= 0 - ? qMax(lastSpinCount, spinCount) - : lastSpinCount + spinCount; + // spinning is working, do not change the spin time } /*! diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h index 2d45cfb..6de42ad 100644 --- a/src/corelib/thread/qmutex_p.h +++ b/src/corelib/thread/qmutex_p.h @@ -72,7 +72,9 @@ public: bool wait(int timeout = -1); void wakeUp(); - volatile int lastSpinCount; + // half of a frame (in ms) at 60fps + enum { MaximumSpinTimeThreshold = 8 }; + volatile int maximumSpinTime; Qt::HANDLE owner; uint count; diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp index e872187..48014cc 100644 --- a/src/corelib/thread/qmutex_unix.cpp +++ b/src/corelib/thread/qmutex_unix.cpp @@ -74,7 +74,7 @@ static void report_error(int code, const char *where, const char *what) QMutexPrivate::QMutexPrivate(QMutex::RecursionMode mode) - : QMutexData(mode), lastSpinCount(0), owner(0), count(0) + : QMutexData(mode), maximumSpinTime(MaximumSpinTimeThreshold), owner(0), count(0) { #if defined(Q_OS_MAC) kern_return_t r = semaphore_create(mach_task_self(), &mach_semaphore, SYNC_POLICY_FIFO, 0); diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp index c278f04..89e8b87 100644 --- a/src/corelib/thread/qmutex_win.cpp +++ b/src/corelib/thread/qmutex_win.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE QMutexPrivate::QMutexPrivate(QMutex::RecursionMode mode) - : QMutexData(mode), lastSpinCount(0), owner(0), count(0) + : QMutexData(mode), maximumSpinTime(MaximumSpinTimeThreshold), owner(0), count(0) { event = CreateEvent(0, FALSE, FALSE, 0); if (!event) -- cgit v0.12 From 6c1180505a0ac55bfd0eac87c2a61103a8fdec14 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 1 Oct 2010 10:21:10 +0200 Subject: Store and track spin times in nanosecond resolution Use the new QElapsedTimer::nsecsElapsed() and store all values in qint64 instead of int. The maximum spin time threshold is now 1000000ns, or 1ms. Spinning for longer than 1ms is just a waste of time, CPU, and battery. Reviewed-by: joao --- src/corelib/thread/qmutex.cpp | 9 +++++---- src/corelib/thread/qmutex_p.h | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index 72f87b7..03e623f 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -443,16 +443,17 @@ void QMutex::lockInternal() QElapsedTimer elapsedTimer; elapsedTimer.start(); do { - if (elapsedTimer.hasExpired(d->maximumSpinTime)) { + qint64 spinTime = elapsedTimer.nsecsElapsed(); + if (spinTime > d->maximumSpinTime) { // didn't get the lock, wait for it, since we're not going to gain anything by spinning more - int spinTime = elapsedTimer.restart(); + elapsedTimer.start(); bool isLocked = d->wait(); Q_ASSERT_X(isLocked, "QMutex::lock", "Internal error, infinite wait has timed out."); Q_UNUSED(isLocked); - int maximumSpinTime = d->maximumSpinTime; - int waitTime = elapsedTimer.elapsed(); + qint64 maximumSpinTime = d->maximumSpinTime; + qint64 waitTime = elapsedTimer.nsecsElapsed(); // adjust the spin count when spinning does not benefit contention performance if (spinTime + waitTime > QMutexPrivate::MaximumSpinTimeThreshold) { // long waits, stop spinning diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h index 6de42ad..fa6e879 100644 --- a/src/corelib/thread/qmutex_p.h +++ b/src/corelib/thread/qmutex_p.h @@ -72,9 +72,9 @@ public: bool wait(int timeout = -1); void wakeUp(); - // half of a frame (in ms) at 60fps - enum { MaximumSpinTimeThreshold = 8 }; - volatile int maximumSpinTime; + // 1ms = 1000000ns + enum { MaximumSpinTimeThreshold = 1000000 }; + volatile qint64 maximumSpinTime; Qt::HANDLE owner; uint count; -- cgit v0.12 From 44cf2baeb07bf48270a6a41c8f1433517130ba01 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 1 Oct 2010 10:22:10 +0200 Subject: Track average wait times under our maximum spin time threshold Further observation shows that spin times slightly over the average wait time produce the best results. This change keeps a heavily weighted average of the wait times under 1.5ms (1.5 times the max spin threshold), and adjusts the spin time to be 150% of the average wait time. Introduce spin time adjustments when spin locking works, and adjust to between 150% of the average wait time and the maximum threshold. Reviewed-by: joao --- src/corelib/thread/qmutex.cpp | 24 ++++++++++++++++++------ src/corelib/thread/qmutex_p.h | 1 + src/corelib/thread/qmutex_unix.cpp | 2 +- src/corelib/thread/qmutex_win.cpp | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index 03e623f..1009f7b 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -453,14 +453,20 @@ void QMutex::lockInternal() Q_UNUSED(isLocked); qint64 maximumSpinTime = d->maximumSpinTime; - qint64 waitTime = elapsedTimer.nsecsElapsed(); + qint64 averageWaitTime = d->averageWaitTime; + qint64 actualWaitTime = elapsedTimer.nsecsElapsed(); + if (actualWaitTime < (QMutexPrivate::MaximumSpinTimeThreshold * 3 / 2)) { + // measure the wait times + averageWaitTime = d->averageWaitTime = qMin((averageWaitTime + actualWaitTime) / 2, qint64(QMutexPrivate::MaximumSpinTimeThreshold)); + } + // adjust the spin count when spinning does not benefit contention performance - if (spinTime + waitTime > QMutexPrivate::MaximumSpinTimeThreshold) { + if ((spinTime + actualWaitTime) - qint64(QMutexPrivate::MaximumSpinTimeThreshold) >= qint64(QMutexPrivate::MaximumSpinTimeThreshold)) { // long waits, stop spinning d->maximumSpinTime = 0; - } else if (waitTime < maximumSpinTime) { - // never spin more than the minimum wait time (otherwise we may perform worse) - d->maximumSpinTime = waitTime; + } else { + // allow spinning if wait times decrease, but never spin more than the average wait time (otherwise we may perform worse) + d->maximumSpinTime = qBound(qint64(averageWaitTime * 3 / 2), maximumSpinTime / 2, qint64(QMutexPrivate::MaximumSpinTimeThreshold)); } return; } @@ -468,7 +474,13 @@ void QMutex::lockInternal() QThread::yieldCurrentThread(); } while (d->contenders != 0 || !d->contenders.testAndSetAcquire(0, 1)); - // spinning is working, do not change the spin time + // spinning is working, do not change the spin time (unless we are using much less time than allowed to spin) + qint64 maximumSpinTime = d->maximumSpinTime; + qint64 spinTime = elapsedTimer.nsecsElapsed(); + if (spinTime < maximumSpinTime / 2) { + // we are using much less time than we need, adjust the limit + d->maximumSpinTime = qBound(qint64(d->averageWaitTime * 3 / 2), maximumSpinTime / 2, qint64(QMutexPrivate::MaximumSpinTimeThreshold)); + } } /*! diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h index fa6e879..9d40bea 100644 --- a/src/corelib/thread/qmutex_p.h +++ b/src/corelib/thread/qmutex_p.h @@ -75,6 +75,7 @@ public: // 1ms = 1000000ns enum { MaximumSpinTimeThreshold = 1000000 }; volatile qint64 maximumSpinTime; + volatile qint64 averageWaitTime; Qt::HANDLE owner; uint count; diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp index 48014cc..0e09ea0 100644 --- a/src/corelib/thread/qmutex_unix.cpp +++ b/src/corelib/thread/qmutex_unix.cpp @@ -74,7 +74,7 @@ static void report_error(int code, const char *where, const char *what) QMutexPrivate::QMutexPrivate(QMutex::RecursionMode mode) - : QMutexData(mode), maximumSpinTime(MaximumSpinTimeThreshold), owner(0), count(0) + : QMutexData(mode), maximumSpinTime(MaximumSpinTimeThreshold), averageWaitTime(0), owner(0), count(0) { #if defined(Q_OS_MAC) kern_return_t r = semaphore_create(mach_task_self(), &mach_semaphore, SYNC_POLICY_FIFO, 0); diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp index 89e8b87..a759caa 100644 --- a/src/corelib/thread/qmutex_win.cpp +++ b/src/corelib/thread/qmutex_win.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE QMutexPrivate::QMutexPrivate(QMutex::RecursionMode mode) - : QMutexData(mode), maximumSpinTime(MaximumSpinTimeThreshold), owner(0), count(0) + : QMutexData(mode), maximumSpinTime(MaximumSpinTimeThreshold), averageWaitTime(0), owner(0), count(0) { event = CreateEvent(0, FALSE, FALSE, 0); if (!event) -- cgit v0.12 From 215748d3be876ffec5d72f2d1dfcce56bb7a5937 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 20 Dec 2010 17:38:05 +0200 Subject: Fix using QFileDialog statics in Symbian. Trying to access files outside C:/data with QFileDialog static functions either paniced or simply threw an exception depending on what you were trying to do exactly. To fix this, QFileDialog static functions now will default to QDir::rootPath() if the path specified by user is invalid. Task-number: QTBUG-16204 Reviewed-by: Janne Koskinen --- src/gui/dialogs/qfiledialog_symbian.cpp | 69 ++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/src/gui/dialogs/qfiledialog_symbian.cpp b/src/gui/dialogs/qfiledialog_symbian.cpp index 1f70305..d82ce2b 100644 --- a/src/gui/dialogs/qfiledialog_symbian.cpp +++ b/src/gui/dialogs/qfiledialog_symbian.cpp @@ -119,36 +119,49 @@ static QString launchSymbianDialog(const QString dialogCaption, const QString st { QString selection; #if defined(Q_WS_S60) && defined(SYMBIAN_VERSION_SYMBIAN3) - QT_TRAP_THROWING( - TFileName startFolder; - if (!startDirectory.isEmpty()) { - QString dir = QDir::toNativeSeparators(startDirectory); + TFileName startFolder; + if (!startDirectory.isEmpty()) { + QString dir = QDir::toNativeSeparators(QFileDialogPrivate::workingDirectory(startDirectory)); + startFolder = qt_QString2TPtrC(dir); + } + TInt types = AknCommonDialogsDynMem::EMemoryTypeMMCExternal| + AknCommonDialogsDynMem::EMemoryTypeInternalMassStorage| + AknCommonDialogsDynMem::EMemoryTypePhone; + + TPtrC titlePtr(qt_QString2TPtrC(dialogCaption)); + TFileName target; + bool select = false; + int tryCount = 2; + while (tryCount--) { + TInt err(KErrNone); + TRAP(err, + if (dialogMode == DialogOpen) { + CExtensionFilter* extensionFilter = new (ELeave) CExtensionFilter; + CleanupStack::PushL(extensionFilter); + extensionFilter->setFilter(filter); + select = AknCommonDialogsDynMem::RunSelectDlgLD(types, target, + startFolder, NULL, NULL, titlePtr, extensionFilter); + CleanupStack::Pop(extensionFilter); + } else if (dialogMode == DialogSave) { + select = AknCommonDialogsDynMem::RunSaveDlgLD(types, target, + startFolder, NULL, NULL, titlePtr); + } else if (dialogMode == DialogFolder) { + select = AknCommonDialogsDynMem::RunFolderSelectDlgLD(types, target, startFolder, + 0, 0, titlePtr, NULL, NULL); + } + ); + + if (err == KErrNone) { + tryCount = 0; + } else { + // Symbian native file dialog doesn't allow accessing files outside C:/Data + // It will always leave in that case, so default into QDir::rootPath() in error cases. + QString dir = QDir::toNativeSeparators(QDir::rootPath()); startFolder = qt_QString2TPtrC(dir); } - TInt types = AknCommonDialogsDynMem::EMemoryTypeMMCExternal| - AknCommonDialogsDynMem::EMemoryTypeInternalMassStorage| - AknCommonDialogsDynMem::EMemoryTypePhone; - - TPtrC titlePtr(qt_QString2TPtrC(dialogCaption)); - TFileName target; - bool select = false; - if (dialogMode == DialogOpen) { - CExtensionFilter* extensionFilter = new (ELeave) CExtensionFilter; - CleanupStack::PushL(extensionFilter); - extensionFilter->setFilter(filter); - select = AknCommonDialogsDynMem::RunSelectDlgLD(types, target, - startFolder, NULL, NULL, titlePtr, extensionFilter); - CleanupStack::Pop(extensionFilter); - } else if (dialogMode == DialogSave) { - select = AknCommonDialogsDynMem::RunSaveDlgLD(types, target, - startFolder, NULL, NULL, titlePtr); - } else if (dialogMode == DialogFolder) { - select = AknCommonDialogsDynMem::RunFolderSelectDlgLD(types, target, startFolder, - 0, 0, titlePtr, NULL, NULL); - } - if (select) - selection.append(qt_TDesC2QString(target)); - ); + } + if (select) + selection.append(qt_TDesC2QString(target)); #endif return selection; } -- cgit v0.12 From e8d42e5861bdfd6acec3bf1ccc8d55b09b1cc573 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 20 Dec 2010 17:53:57 +0200 Subject: Remove few compile warnings Reviewed-by: Janne Koskinen --- src/gui/dialogs/qfiledialog_symbian.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/dialogs/qfiledialog_symbian.cpp b/src/gui/dialogs/qfiledialog_symbian.cpp index d82ce2b..1fc5f5e 100644 --- a/src/gui/dialogs/qfiledialog_symbian.cpp +++ b/src/gui/dialogs/qfiledialog_symbian.cpp @@ -64,7 +64,7 @@ public: filterList.clear(); if (filter.left(2) == QLatin1String("*.")) { //Filter has only extensions - filterList << filter.split(" "); + filterList << filter.split(QLatin1String(" ")); return; } else { //Extensions are in parenthesis and there may be several filters @@ -75,7 +75,7 @@ public: return; } } - QRegExp rx("\\(([^\\)]*)\\)"); + QRegExp rx(QLatin1String("\\(([^\\)]*)\\)")); int pos = 0; while ((pos = rx.indexIn(filter, pos)) != -1) { filterList << rx.cap(1).split(QLatin1String(" ")); -- cgit v0.12 From 7747e8864db4518e35d5a472cec37697b85b3b15 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Mon, 20 Dec 2010 16:02:33 +0000 Subject: runonphone: Check that the device->config is valid before dereferencing it In some occasions (encountered on OS X), this can be null for some devices. Merge-request: 834 Reviewed-by: Shane Kearns --- tools/runonphone/serenum_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/runonphone/serenum_unix.cpp b/tools/runonphone/serenum_unix.cpp index db6375e..f65497e 100644 --- a/tools/runonphone/serenum_unix.cpp +++ b/tools/runonphone/serenum_unix.cpp @@ -82,7 +82,7 @@ QList enumerateSerialPorts(int loglevel) for (struct usb_bus *bus = usb_get_busses(); bus; bus = bus->next) { for (struct usb_device *device = bus->devices; device; device = device->next) { - for (int n = 0; n < device->descriptor.bNumConfigurations; ++n) { + for (int n = 0; n < device->descriptor.bNumConfigurations && device->config; ++n) { struct usb_config_descriptor &usbConfig =device->config[n]; QList usableInterfaces; for (int m = 0; m < usbConfig.bNumInterfaces; ++m) { -- cgit v0.12 From 11ea9609129205cd08dc5fbeb889cc60f4f84f65 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Mon, 20 Dec 2010 16:02:37 +0000 Subject: reword: Make the USB serial device enumeration work on OS X, too Tested on OS X Snow Leopard with libusb-0.1.12. The devices are named /dev/cu.usbmodem, where the opaque id doesn't seem to be available via the current libusb interface, but finding it would require usage of native OS X APIs. The interface number is available at least, and searching for cu\.usbmodem.* as a regexp finds the right devices as long as not too many devices are connected. Merge-request: 834 Reviewed-by: Shane Kearns --- tools/runonphone/serenum_unix.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/tools/runonphone/serenum_unix.cpp b/tools/runonphone/serenum_unix.cpp index f65497e..93d8c67 100644 --- a/tools/runonphone/serenum_unix.cpp +++ b/tools/runonphone/serenum_unix.cpp @@ -158,6 +158,10 @@ QList enumerateSerialPorts(int loglevel) << "device" << device->filename << "interface" << descriptor.bInterfaceNumber; } +#ifdef Q_OS_MAC + eligibleInterfaces << QString("^cu\\.usbmodem.*%1$") + .arg(QString("%1").arg(descriptor.bInterfaceNumber, 1, 16).toUpper()); +#else // ### manufacturer and product strings are only readable as root :( if (!manufacturerString.isEmpty() && !productString.isEmpty()) { eligibleInterfaces << QString("usb-%1_%2-if%3") @@ -167,6 +171,7 @@ QList enumerateSerialPorts(int loglevel) } else { eligibleInterfaces << QString("if%1").arg(i, 2, 16, QChar('0')); // fix! } +#endif eligibleInterfacesInfo << InterfaceInfo(manufacturerString, productString, device->descriptor.idVendor, device->descriptor.idProduct); } } @@ -179,14 +184,24 @@ QList enumerateSerialPorts(int loglevel) if (loglevel > 1) qDebug() << " searching for interfaces:" << eligibleInterfaces; +#ifdef Q_OS_MAC + QDir dir("/dev/"); + bool allowAny = false; +#else QDir dir("/dev/serial/by-id/"); - foreach (const QFileInfo &info, dir.entryInfoList()) { + bool allowAny = eligibleInterfaces.isEmpty(); +#endif + foreach (const QFileInfo &info, dir.entryInfoList(QDir::System)) { if (!info.isDir()) { - bool usable = eligibleInterfaces.isEmpty(); + bool usable = allowAny; + QString friendlyName = info.fileName(); foreach (const QString &iface, eligibleInterfaces) { - if (info.fileName().contains(iface)) { + if (info.fileName().contains(QRegExp(iface))) { if (loglevel > 1) qDebug() << " found device file:" << info.fileName() << endl; +#ifdef Q_OS_MAC + friendlyName = eligibleInterfacesInfo[eligibleInterfaces.indexOf(iface)].product; +#endif usable = true; break; } @@ -195,7 +210,7 @@ QList enumerateSerialPorts(int loglevel) continue; SerialPortId id; - id.friendlyName = info.fileName(); + id.friendlyName = friendlyName; id.portName = info.canonicalFilePath(); list << id; } -- cgit v0.12 From d6a7931c5a2b90c0c276a1367135c9dc4e7532cd Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Mon, 20 Dec 2010 16:02:42 +0000 Subject: runonphone: Only print the modprobe instructions on linux Merge-request: 834 Reviewed-by: Shane Kearns --- tools/runonphone/serenum_unix.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/runonphone/serenum_unix.cpp b/tools/runonphone/serenum_unix.cpp index 93d8c67..86e797b 100644 --- a/tools/runonphone/serenum_unix.cpp +++ b/tools/runonphone/serenum_unix.cpp @@ -223,11 +223,15 @@ QList enumerateSerialPorts(int loglevel) << iface.manufacturer << "Product:" << iface.product +#ifdef Q_OS_LINUX << endl << " Load generic driver using:" << QString("sudo modprobe usbserial vendor=0x%1 product=0x%2") .arg(iface.manufacturerid, 4, 16, QChar('0')) .arg(iface.productid, 4, 16, QChar('0')); +#else + ; +#endif } } return list; -- cgit v0.12 From 7d2dc192477c0d10b2c5c9f144e2a37a270093f0 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 21 Dec 2010 10:57:44 +1000 Subject: Add tests for ListView.indexAt() and GridView.IndexAt() --- .../tst_qdeclarativegridview.cpp | 37 ++++++++++++++++++++++ .../tst_qdeclarativelistview.cpp | 33 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index fd5d140..a2dcf1c 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -84,6 +84,7 @@ private slots: void manualHighlight(); void footer(); void header(); + void indexAt(); private: QDeclarativeView *createView(); @@ -1299,6 +1300,42 @@ void tst_QDeclarativeGridView::header() QTRY_COMPARE(header->y(), 0.0); } +void tst_QDeclarativeGridView::indexAt() +{ + QDeclarativeView *canvas = createView(); + + TestModel model; + model.addItem("Fred", "12345"); + model.addItem("John", "2345"); + model.addItem("Bob", "54321"); + model.addItem("Billy", "22345"); + model.addItem("Sam", "2945"); + model.addItem("Ben", "04321"); + model.addItem("Jim", "0780"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); + qApp->processEvents(); + + QDeclarativeGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QDeclarativeItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QTRY_COMPARE(gridview->count(), model.count()); + + QCOMPARE(gridview->indexAt(0, 0), 0); + QCOMPARE(gridview->indexAt(79, 59), 0); + QCOMPARE(gridview->indexAt(80, 0), 1); + QCOMPARE(gridview->indexAt(0, 60), 3); + QCOMPARE(gridview->indexAt(240, 0), -1); + + delete canvas; +} QDeclarativeView *tst_QDeclarativeGridView::createView() { diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index b834d46..3df10a9 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -105,6 +105,7 @@ private slots: void QTBUG_14821(); void resizeDelegate(); void QTBUG_16037(); + void indexAt(); private: template void items(); @@ -1964,6 +1965,38 @@ void tst_QDeclarativeListView::QTBUG_16037() delete canvas; } +void tst_QDeclarativeListView::indexAt() +{ + 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); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); + qApp->processEvents(); + + QDeclarativeListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QDeclarativeItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QCOMPARE(listview->indexAt(0,0), 0); + QCOMPARE(listview->indexAt(0,19), 0); + QCOMPARE(listview->indexAt(239,19), 0); + QCOMPARE(listview->indexAt(0,20), 1); + QCOMPARE(listview->indexAt(240,20), -1); + + delete canvas; +} + void tst_QDeclarativeListView::qListModelInterface_items() { items(); -- cgit v0.12 From bc679ceb8ad36de1da696f7f67e71145ceec7f98 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 21 Dec 2010 11:11:59 +1000 Subject: More testing for KeyNavigation attached properties. --- .../qdeclarativeitem/data/keynavigationtest.qml | 40 ++++++++++++++++++++++ .../qdeclarativeitem/tst_qdeclarativeitem.cpp | 5 +++ 2 files changed, 45 insertions(+) diff --git a/tests/auto/declarative/qdeclarativeitem/data/keynavigationtest.qml b/tests/auto/declarative/qdeclarativeitem/data/keynavigationtest.qml index 229f969..f614a12 100644 --- a/tests/auto/declarative/qdeclarativeitem/data/keynavigationtest.qml +++ b/tests/auto/declarative/qdeclarativeitem/data/keynavigationtest.qml @@ -3,6 +3,46 @@ import QtQuick 1.0 Grid { columns: 2 width: 100; height: 100 + function verify() { + if (item1.KeyNavigation.right != item2) + return false; + if (item1.KeyNavigation.down != item3) + return false; + if (item1.KeyNavigation.tab != item2) + return false; + if (item1.KeyNavigation.backtab != item4) + return false; + + if (item2.KeyNavigation.left != item1) + return false; + if (item2.KeyNavigation.down != item4) + return false; + if (item2.KeyNavigation.tab != item3) + return false; + if (item2.KeyNavigation.backtab != item1) + return false; + + if (item3.KeyNavigation.right != item4) + return false; + if (item3.KeyNavigation.up != item1) + return false; + if (item3.KeyNavigation.tab != item4) + return false; + if (item3.KeyNavigation.backtab != item2) + return false; + + if (item4.KeyNavigation.left != item3) + return false; + if (item4.KeyNavigation.up != item2) + return false; + if (item4.KeyNavigation.tab != item1) + return false; + if (item4.KeyNavigation.backtab != item3) + return false; + + return true; + } + Rectangle { id: item1 objectName: "item1" diff --git a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp index 711bf00..0ebb8b7 100644 --- a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp +++ b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp @@ -393,6 +393,11 @@ void tst_QDeclarativeItem::keyNavigation() QVERIFY(item); QVERIFY(item->hasActiveFocus()); + QVariant result; + QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify", + Q_RETURN_ARG(QVariant, result))); + QVERIFY(result.toBool()); + // right QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); QApplication::sendEvent(canvas, &key); -- cgit v0.12 From 2a340b56c9935ee25bbd0b750d1239cb14051b27 Mon Sep 17 00:00:00 2001 From: axis Date: Tue, 21 Dec 2010 10:46:26 +0100 Subject: Fixed PREPEND_INCLUDEPATH being executed too early. It used to be carried out inside qt.prf, but was moved to default_post.prf. However, since qt.prf is executed after default_post.prf, it would still prepend its own include paths at the very front, which is wrong. Fixed by introducing a new feature profile for PREPEND_INCLUDEPATH, which is run after qt.prf (features in $$CONFIG are executed in reverse order). RevBy: Miikka Heikkinen --- mkspecs/common/symbian/symbian.conf | 2 +- mkspecs/features/symbian/default_post.prf | 15 --------------- mkspecs/features/symbian/prepend_includepath.prf | 14 ++++++++++++++ 3 files changed, 15 insertions(+), 16 deletions(-) create mode 100644 mkspecs/features/symbian/prepend_includepath.prf diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index b8e1d26..8c79d8b 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -3,7 +3,7 @@ # TEMPLATE = app -CONFIG += qt warn_on release incremental link_prl sis_targets run_on_phone +CONFIG += prepend_includepath qt warn_on release incremental link_prl sis_targets run_on_phone QT += core gui QMAKE_INCREMENTAL_STYLE = sublib diff --git a/mkspecs/features/symbian/default_post.prf b/mkspecs/features/symbian/default_post.prf index 89f655d..fffc481 100644 --- a/mkspecs/features/symbian/default_post.prf +++ b/mkspecs/features/symbian/default_post.prf @@ -53,21 +53,6 @@ isEmpty(TARGET.UID2) { } } -# Allow .pro files to specify include path(s) to be prepended to the list. -# -# This allows the project to override the default ordering, whereby paths -# relative to $$QMAKE_INCDIR_QT always come first. This ordering can cause -# problems when both the epoc32/include tree and a Qt include directory -# contain a header of the same name - in this case, the Qt header is always -# included by virtue of its path appearing first in the SYSTEMINCLUDE -# directives in the generated MMP file. -# -# To work around this situation, the following line can be added to the .pro -# file: -# PREPEND_INCLUDEPATH = /epoc32/include -# -INCLUDEPATH = $$PREPEND_INCLUDEPATH $$INCLUDEPATH - # Add dependency to Qt package to all other projects besides Qt libs. # Note: Qt libs package with full capabilities has UID3 of 0x2001E61C, # while self-signed version typically has temporary UID3 of 0xE001E61C. diff --git a/mkspecs/features/symbian/prepend_includepath.prf b/mkspecs/features/symbian/prepend_includepath.prf new file mode 100644 index 0000000..d9fd4fe --- /dev/null +++ b/mkspecs/features/symbian/prepend_includepath.prf @@ -0,0 +1,14 @@ +# Allow .pro files to specify include path(s) to be prepended to the list. +# +# This allows the project to override the default ordering, whereby paths +# relative to $$QMAKE_INCDIR_QT always come first. This ordering can cause +# problems when both the epoc32/include tree and a Qt include directory +# contain a header of the same name - in this case, the Qt header is always +# included by virtue of its path appearing first in the SYSTEMINCLUDE +# directives in the generated MMP file. +# +# To work around this situation, the following line can be added to the .pro +# file: +# PREPEND_INCLUDEPATH = /epoc32/include +# +INCLUDEPATH = $$PREPEND_INCLUDEPATH $$INCLUDEPATH -- cgit v0.12 From 5963b2b92829035d14ab9f5fc5f65dec9460d969 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Tue, 21 Dec 2010 11:14:26 +0100 Subject: Add inter-process binary shader cache for MeeGo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch significantly reduces MeeGo app startup times by caching binary shaders in a shared memory segment. Reviewed-by: Robert Griebl Reviewed-by: Samuel Rødal --- .../gl2paintengineex/qglengineshadermanager.cpp | 294 +++++++------ .../gl2paintengineex/qglshadercache_meego_p.h | 457 +++++++++++++++++++++ src/opengl/gl2paintengineex/qglshadercache_p.h | 98 +++++ src/opengl/opengl.pro | 4 +- src/opengl/util/meego/main.cpp | 48 +++ .../util/meego/shader-cache-introspector.pro | 7 + 6 files changed, 771 insertions(+), 137 deletions(-) create mode 100644 src/opengl/gl2paintengineex/qglshadercache_meego_p.h create mode 100644 src/opengl/gl2paintengineex/qglshadercache_p.h create mode 100644 src/opengl/util/meego/main.cpp create mode 100644 src/opengl/util/meego/shader-cache-introspector.pro diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 93ff3f4..0723c28 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -42,6 +42,7 @@ #include "qglengineshadermanager_p.h" #include "qglengineshadersource_p.h" #include "qpaintengineex_opengl2_p.h" +#include "qglshadercache_p.h" #if defined(QT_DEBUG) #include @@ -170,64 +171,92 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) QGLShader* fragShader; QGLShader* vertexShader; - QByteArray source; + QByteArray vertexSource; + QByteArray fragSource; // Compile up the simple shader: - source.clear(); - source.append(qShaderSnippets[MainVertexShader]); - source.append(qShaderSnippets[PositionOnlyVertexShader]); - vertexShader = new QGLShader(QGLShader::Vertex, context, 0); - shaders.append(vertexShader); - if (!vertexShader->compileSourceCode(source)) - qWarning("Vertex shader for simpleShaderProg (MainVertexShader & PositionOnlyVertexShader) failed to compile"); - - source.clear(); - source.append(qShaderSnippets[MainFragmentShader]); - source.append(qShaderSnippets[ShockingPinkSrcFragmentShader]); - fragShader = new QGLShader(QGLShader::Fragment, context, 0); - shaders.append(fragShader); - if (!fragShader->compileSourceCode(source)) - qWarning("Fragment shader for simpleShaderProg (MainFragmentShader & ShockingPinkSrcFragmentShader) failed to compile"); + vertexSource.append(qShaderSnippets[MainVertexShader]); + vertexSource.append(qShaderSnippets[PositionOnlyVertexShader]); + + fragSource.append(qShaderSnippets[MainFragmentShader]); + fragSource.append(qShaderSnippets[ShockingPinkSrcFragmentShader]); simpleShaderProg = new QGLShaderProgram(context, 0); - simpleShaderProg->addShader(vertexShader); - simpleShaderProg->addShader(fragShader); - simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); - simpleShaderProg->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); - simpleShaderProg->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); - simpleShaderProg->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); + + CachedShader simpleShaderCache(fragSource, vertexSource); + + bool inCache = simpleShaderCache.load(simpleShaderProg, context); + + if (!inCache) { + vertexShader = new QGLShader(QGLShader::Vertex, context, 0); + shaders.append(vertexShader); + if (!vertexShader->compileSourceCode(vertexSource)) + qWarning("Vertex shader for simpleShaderProg (MainVertexShader & PositionOnlyVertexShader) failed to compile"); + + fragShader = new QGLShader(QGLShader::Fragment, context, 0); + shaders.append(fragShader); + if (!fragShader->compileSourceCode(fragSource)) + qWarning("Fragment shader for simpleShaderProg (MainFragmentShader & ShockingPinkSrcFragmentShader) failed to compile"); + + simpleShaderProg->addShader(vertexShader); + simpleShaderProg->addShader(fragShader); + + simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); + simpleShaderProg->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); + simpleShaderProg->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); + simpleShaderProg->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); + } + simpleShaderProg->link(); - if (!simpleShaderProg->isLinked()) { + + if (simpleShaderProg->isLinked()) { + if (!inCache) + simpleShaderCache.store(simpleShaderProg, context); + } else { qCritical() << "Errors linking simple shader:" << simpleShaderProg->log(); } // Compile the blit shader: - source.clear(); - source.append(qShaderSnippets[MainWithTexCoordsVertexShader]); - source.append(qShaderSnippets[UntransformedPositionVertexShader]); - vertexShader = new QGLShader(QGLShader::Vertex, context, 0); - shaders.append(vertexShader); - if (!vertexShader->compileSourceCode(source)) - qWarning("Vertex shader for blitShaderProg (MainWithTexCoordsVertexShader & UntransformedPositionVertexShader) failed to compile"); - - source.clear(); - source.append(qShaderSnippets[MainFragmentShader]); - source.append(qShaderSnippets[ImageSrcFragmentShader]); - fragShader = new QGLShader(QGLShader::Fragment, context, 0); - shaders.append(fragShader); - if (!fragShader->compileSourceCode(source)) - qWarning("Fragment shader for blitShaderProg (MainFragmentShader & ImageSrcFragmentShader) failed to compile"); + vertexSource.clear(); + vertexSource.append(qShaderSnippets[MainWithTexCoordsVertexShader]); + vertexSource.append(qShaderSnippets[UntransformedPositionVertexShader]); + + fragSource.clear(); + fragSource.append(qShaderSnippets[MainFragmentShader]); + fragSource.append(qShaderSnippets[ImageSrcFragmentShader]); blitShaderProg = new QGLShaderProgram(context, 0); - blitShaderProg->addShader(vertexShader); - blitShaderProg->addShader(fragShader); - blitShaderProg->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); - blitShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); + + CachedShader blitShaderCache(fragSource, vertexSource); + + inCache = blitShaderCache.load(blitShaderProg, context); + + if (!inCache) { + vertexShader = new QGLShader(QGLShader::Vertex, context, 0); + shaders.append(vertexShader); + if (!vertexShader->compileSourceCode(vertexSource)) + qWarning("Vertex shader for blitShaderProg (MainWithTexCoordsVertexShader & UntransformedPositionVertexShader) failed to compile"); + + fragShader = new QGLShader(QGLShader::Fragment, context, 0); + shaders.append(fragShader); + if (!fragShader->compileSourceCode(fragSource)) + qWarning("Fragment shader for blitShaderProg (MainFragmentShader & ImageSrcFragmentShader) failed to compile"); + + blitShaderProg->addShader(vertexShader); + blitShaderProg->addShader(fragShader); + + blitShaderProg->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); + blitShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); + } + blitShaderProg->link(); - if (!blitShaderProg->isLinked()) { + if (blitShaderProg->isLinked()) { + if (!inCache) + blitShaderCache.store(blitShaderProg, context); + } else { qCritical() << "Errors linking blit shader:" - << simpleShaderProg->log(); + << blitShaderProg->log(); } #ifdef QT_GL_SHARED_SHADER_DEBUG @@ -279,101 +308,110 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS } } - QGLShader *vertexShader = 0; - QGLShader *fragShader = 0; - QGLEngineShaderProg *newProg = 0; - bool success = false; + QScopedPointer newProg; do { - QByteArray source; + QByteArray fragSource; // Insert the custom stage before the srcPixel shader to work around an ATI driver bug // where you cannot forward declare a function that takes a sampler as argument. if (prog.srcPixelFragShader == CustomImageSrcFragmentShader) - source.append(prog.customStageSource); - source.append(qShaderSnippets[prog.mainFragShader]); - source.append(qShaderSnippets[prog.srcPixelFragShader]); + fragSource.append(prog.customStageSource); + fragSource.append(qShaderSnippets[prog.mainFragShader]); + fragSource.append(qShaderSnippets[prog.srcPixelFragShader]); if (prog.compositionFragShader) - source.append(qShaderSnippets[prog.compositionFragShader]); + fragSource.append(qShaderSnippets[prog.compositionFragShader]); if (prog.maskFragShader) - source.append(qShaderSnippets[prog.maskFragShader]); - fragShader = new QGLShader(QGLShader::Fragment, ctxGuard.context(), 0); - shaders.append(fragShader); - QByteArray description; + fragSource.append(qShaderSnippets[prog.maskFragShader]); + + QByteArray vertexSource; + vertexSource.append(qShaderSnippets[prog.mainVertexShader]); + vertexSource.append(qShaderSnippets[prog.positionVertexShader]); + + QScopedPointer shaderProgram(new QGLShaderProgram(ctxGuard.context(), 0)); + + CachedShader shaderCache(fragSource, vertexSource); + bool inCache = shaderCache.load(shaderProgram.data(), ctxGuard.context()); + + if (!inCache) { + + QScopedPointer fragShader(new QGLShader(QGLShader::Fragment, ctxGuard.context(), 0)); + QByteArray description; #if defined(QT_DEBUG) - // Name the shader for easier debugging - description.append("Fragment shader: main="); - description.append(snippetNameStr(prog.mainFragShader)); - description.append(", srcPixel="); - description.append(snippetNameStr(prog.srcPixelFragShader)); - if (prog.compositionFragShader) { - description.append(", composition="); - description.append(snippetNameStr(prog.compositionFragShader)); - } - if (prog.maskFragShader) { - description.append(", mask="); - description.append(snippetNameStr(prog.maskFragShader)); - } - fragShader->setObjectName(QString::fromLatin1(description)); + // Name the shader for easier debugging + description.append("Fragment shader: main="); + description.append(snippetNameStr(prog.mainFragShader)); + description.append(", srcPixel="); + description.append(snippetNameStr(prog.srcPixelFragShader)); + if (prog.compositionFragShader) { + description.append(", composition="); + description.append(snippetNameStr(prog.compositionFragShader)); + } + if (prog.maskFragShader) { + description.append(", mask="); + description.append(snippetNameStr(prog.maskFragShader)); + } + fragShader->setObjectName(QString::fromLatin1(description)); #endif - if (!fragShader->compileSourceCode(source)) { - qWarning() << "Warning:" << description << "failed to compile!"; - break; - } + if (!fragShader->compileSourceCode(fragSource)) { + qWarning() << "Warning:" << description << "failed to compile!"; + break; + } - source.clear(); - source.append(qShaderSnippets[prog.mainVertexShader]); - source.append(qShaderSnippets[prog.positionVertexShader]); - vertexShader = new QGLShader(QGLShader::Vertex, ctxGuard.context(), 0); - shaders.append(vertexShader); + QScopedPointer vertexShader(new QGLShader(QGLShader::Vertex, ctxGuard.context(), 0)); #if defined(QT_DEBUG) - // Name the shader for easier debugging - description.clear(); - description.append("Vertex shader: main="); - description.append(snippetNameStr(prog.mainVertexShader)); - description.append(", position="); - description.append(snippetNameStr(prog.positionVertexShader)); - vertexShader->setObjectName(QString::fromLatin1(description)); + // Name the shader for easier debugging + description.clear(); + description.append("Vertex shader: main="); + description.append(snippetNameStr(prog.mainVertexShader)); + description.append(", position="); + description.append(snippetNameStr(prog.positionVertexShader)); + vertexShader->setObjectName(QString::fromLatin1(description)); #endif - if (!vertexShader->compileSourceCode(source)) { - qWarning() << "Warning:" << description << "failed to compile!"; - break; - } + if (!vertexShader->compileSourceCode(vertexSource)) { + qWarning() << "Warning:" << description << "failed to compile!"; + break; + } - newProg = new QGLEngineShaderProg(prog); - - // If the shader program's not found in the cache, create it now. - newProg->program = new QGLShaderProgram(ctxGuard.context(), 0); - newProg->program->addShader(vertexShader); - newProg->program->addShader(fragShader); - - // We have to bind the vertex attribute names before the program is linked: - newProg->program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); - if (newProg->useTextureCoords) - newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); - if (newProg->useOpacityAttribute) - newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); - if (newProg->usePmvMatrixAttribute) { - newProg->program->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); - newProg->program->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); - newProg->program->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); + shaders.append(vertexShader.data()); + shaders.append(fragShader.data()); + shaderProgram->addShader(vertexShader.take()); + shaderProgram->addShader(fragShader.take()); + + // We have to bind the vertex attribute names before the program is linked: + shaderProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); + if (prog.useTextureCoords) + shaderProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); + if (prog.useOpacityAttribute) + shaderProgram->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); + if (prog.usePmvMatrixAttribute) { + shaderProgram->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); + shaderProgram->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); + shaderProgram->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); + } } + newProg.reset(new QGLEngineShaderProg(prog)); + newProg->program = shaderProgram.take(); + newProg->program->link(); - if (!newProg->program->isLinked()) { + if (newProg->program->isLinked()) { + if (!inCache) + shaderCache.store(newProg->program, ctxGuard.context()); + } else { QLatin1String none("none"); QLatin1String br("\n"); QString error; - error = QLatin1String("Shader program failed to link,") + error = QLatin1String("Shader program failed to link,"); #if defined(QT_DEBUG) - + br - + QLatin1String(" Shaders Used:") + br - + QLatin1String(" ") + vertexShader->objectName() + QLatin1String(": ") + br - + QLatin1String(vertexShader->sourceCode()) + br - + QLatin1String(" ") + fragShader->objectName() + QLatin1String(": ") + br - + QLatin1String(fragShader->sourceCode()) + br + error += QLatin1String("\n Shaders Used:\n"); + for (int i = 0; i < newProg->program->shaders().count(); ++i) { + QGLShader *shader = newProg->program->shaders().at(i); + error += QLatin1String(" ") + shader->objectName() + QLatin1String(": \n") + + QLatin1String(shader->sourceCode()) + br; + } #endif - + QLatin1String(" Error Log:\n") - + QLatin1String(" ") + newProg->program->log(); + error += QLatin1String(" Error Log:\n") + + QLatin1String(" ") + newProg->program->log(); qWarning() << error; break; } @@ -395,26 +433,10 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS } } - cachedPrograms.insert(0, newProg); - - success = true; + cachedPrograms.insert(0, newProg.data()); } while (false); - // Clean up everything if we weren't successful - if (!success) { - if (newProg) { - delete newProg; // Also deletes the QGLShaderProgram which in turn deletes the QGLShaders - newProg = 0; - } - else { - if (vertexShader) - delete vertexShader; - if (fragShader) - delete fragShader; - } - } - - return newProg; + return newProg.take(); } void QGLEngineSharedShaders::cleanupCustomStage(QGLCustomShaderStage* stage) diff --git a/src/opengl/gl2paintengineex/qglshadercache_meego_p.h b/src/opengl/gl2paintengineex/qglshadercache_meego_p.h new file mode 100644 index 0000000..5f51fc2 --- /dev/null +++ b/src/opengl/gl2paintengineex/qglshadercache_meego_p.h @@ -0,0 +1,457 @@ +/**************************************************************************** +** +** 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 QtOpenGL 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$ +** +****************************************************************************/ + +// +// 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. +// + +#ifndef QGLSHADERCACHE_MEEGO_P_H +#define QGLSHADERCACHE_MEEGO_P_H + +#include + +#if defined(QT_MEEGO_EXPERIMENTAL_SHADERCACHE) && defined(QT_OPENGL_ES_2) + +#include +#include +#include + +#ifndef QT_BOOTSTRAPPED +# include +#endif +#if defined(QT_DEBUG) || defined(QT_MEEGO_EXPERIMENTAL_SHADERCACHE_TRACE) +# include +#endif + +QT_BEGIN_HEADER + +/* + This cache stores internal Qt shader programs in shared memory. + + This header file is ugly on purpose and can only be included once. It is only to be used + for the internal shader cache, not as a generic cache for anyone's shaders. + + The cache stores either ShaderCacheMaxEntries shader programs or ShaderCacheDataSize kilobytes + of shader programs, whatever limit is reached first. + + The layout of the cache is as outlined in the CachedShaders struct. After some + integers, an array of headers is reserved, then comes the space for the actual binaries. + + Shader Programs are identified by the md5sum of their frag and vertex shader source code. + + Shader Programs are never removed. The cache never shrinks or re-shuffles. This is done + on purpose to ensure minimum amount of locking, no alignment problems and very few write + operations. + + Note: Locking the shader cache could be expensive, because the entire system might hang. + That's why the cache is immutable to minimize the time we need to keep it locked. + + Why is it Meego specific? + + First, the size is chosen so that it fits to generic meego usage. Second, on Meego, there's + always at least one Qt application active (the launcher), so the cache will never be destroyed. + Only when the last Qt app exits, the cache dies, which should only be when someone kills the + X11 server. And last but not least it was only tested with Meego's SGX driver. + + There's a small tool in src/opengl/util/meego that dumps the contents of the cache. + */ + +// anonymous namespace, prevent exporting of the private symbols +namespace +{ + +struct CachedShaderHeader +{ + /* the index in the data[] member of CachedShaders */ + int index; + /* the size of the binary shader */ + GLsizei size; + /* the format of the binary shader */ + GLenum format; + /* the md5sum of the frag+vertex shaders */ + char md5Sum[16]; +}; + +enum +{ + /* The maximum amount of shader programs the cache can hold */ + ShaderCacheMaxEntries = 20 +}; + +typedef CachedShaderHeader CachedShaderHeaders[ShaderCacheMaxEntries]; + +enum +{ + // ShaderCacheDataSize is 20k minus the other data members of CachedShaders + ShaderCacheDataSize = 1024 * ShaderCacheMaxEntries - sizeof(CachedShaderHeaders) - 2 * sizeof(int) +}; + +struct CachedShaders +{ + /* How much space is still available in the cache */ + inline int availableSize() const { return ShaderCacheDataSize - dataSize; } + + /* The current amount of cached shaders */ + int shaderCount; + + /* The current amount (in bytes) of cached data */ + int dataSize; + + /* The headers describing the shaders */ + CachedShaderHeaders headers; + + /* The actual binary data of the shader programs */ + char data[ShaderCacheDataSize]; +}; + +//#define QT_DEBUG_SHADER_CACHE +#ifdef QT_DEBUG_SHADER_CACHE +static QDebug shaderCacheDebug() +{ + return QDebug(QtDebugMsg); +} +#else +static inline QNoDebug shaderCacheDebug() { return QNoDebug(); } +#endif + +class ShaderCacheSharedMemory +{ +public: + ShaderCacheSharedMemory() + : shm(QLatin1String("qt_gles2_shadercache_" QT_VERSION_STR)) + { + // we need a system semaphore here, since cache creation and initialization must be atomic + QSystemSemaphore attachSemaphore(QLatin1String("qt_gles2_shadercache_mutex_" QT_VERSION_STR), 1); + + if (!attachSemaphore.acquire()) { + shaderCacheDebug() << "Unable to require shader cache semaphore:" << attachSemaphore.errorString(); + return; + } + + if (shm.attach()) { + // success! + shaderCacheDebug() << "Attached to shader cache"; + } else { + + // no cache exists - create and initialize it + if (shm.create(sizeof(CachedShaders))) { + shaderCacheDebug() << "Created new shader cache"; + initializeCache(); + } else { + shaderCacheDebug() << "Unable to create shader cache:" << shm.errorString(); + } + } + + attachSemaphore.release(); + } + + inline bool isAttached() const { return shm.isAttached(); } + + inline bool lock() { return shm.lock(); } + inline bool unlock() { return shm.unlock(); } + inline void *data() { return shm.data(); } + inline QString errorString() { return shm.errorString(); } + + ~ShaderCacheSharedMemory() + { + if (!shm.detach()) + shaderCacheDebug() << "Unable to detach shader cache" << shm.errorString(); + } + +private: + void initializeCache() + { + // no need to lock the shared memory since we're already protected by the + // attach system semaphore. + + void *data = shm.data(); + Q_ASSERT(data); + + memset(data, 0, sizeof(CachedShaders)); + } + + QSharedMemory shm; +}; + +class ShaderCacheLocker +{ +public: + inline ShaderCacheLocker(ShaderCacheSharedMemory *cache) + : shm(cache->lock() ? cache : (ShaderCacheSharedMemory *)0) + { + if (!shm) + shaderCacheDebug() << "Unable to lock shader cache" << cache->errorString(); + } + + inline bool isLocked() const { return shm; } + + inline ~ShaderCacheLocker() + { + if (!shm) + return; + if (!shm->unlock()) + shaderCacheDebug() << "Unable to unlock shader cache" << shm->errorString(); + } + +private: + ShaderCacheSharedMemory *shm; +}; + +#ifdef QT_BOOTSTRAPPED +} // end namespace +#else + +static void traceCacheOverflow(const char *message) +{ +#if defined(QT_DEBUG) || defined (QT_MEEGO_EXPERIMENTAL_SHADERCACHE_TRACE) + openlog(qPrintable(QCoreApplication::applicationName()), LOG_PID | LOG_ODELAY, LOG_USER); + syslog(LOG_DEBUG, message); + closelog(); +#endif + shaderCacheDebug() << message; +} + +Q_GLOBAL_STATIC(ShaderCacheSharedMemory, shaderCacheSharedMemory) + +/* + Finds the index of the shader program identified by md5Sum in the cache. + Note: Does NOT lock the cache for reading, the cache must already be locked! + + Returns -1 when no shader was found. + */ +static int qt_cache_index_unlocked(const QByteArray &md5Sum, CachedShaders *cache) +{ + for (int i = 0; i < cache->shaderCount; ++i) { + if (qstrncmp(md5Sum.constData(), cache->headers[i].md5Sum, 16) == 0) { + return i; + } + } + return -1; +} + +/* Returns the index of the shader identified by md5Sum */ +static int qt_cache_index(const QByteArray &md5Sum) +{ + ShaderCacheSharedMemory *shm = shaderCacheSharedMemory(); + if (!shm || !shm->isAttached()) + return false; + + Q_ASSERT(md5Sum.length() == 16); + + ShaderCacheLocker locker(shm); + if (!locker.isLocked()) + return false; + + void *data = shm->data(); + Q_ASSERT(data); + + CachedShaders *cache = reinterpret_cast(data); + + return qt_cache_index_unlocked(md5Sum, cache); +} + +/* Loads the cached shader at index \a shaderIndex into \a program + * Note: Since the cache is immutable, this operation doesn't lock the shared memory. + */ +static bool qt_cached_shader(QGLShaderProgram *program, const QGLContext *ctx, int shaderIndex) +{ + Q_ASSERT(shaderIndex >= 0 && shaderIndex <= ShaderCacheMaxEntries); + Q_ASSERT(program); + + ShaderCacheSharedMemory *shm = shaderCacheSharedMemory(); + if (!shm || !shm->isAttached()) + return false; + + void *data = shm->data(); + Q_ASSERT(data); + + CachedShaders *cache = reinterpret_cast(data); + + shaderCacheDebug() << "fetching cached shader at index" << shaderIndex + << "dataIndex" << cache->headers[shaderIndex].index + << "size" << cache->headers[shaderIndex].size + << "format" << cache->headers[shaderIndex].format; + + // call program->programId first, since that resolves the glProgramBinaryOES symbol + GLuint programId = program->programId(); + glProgramBinaryOES(programId, cache->headers[shaderIndex].format, + cache->data + cache->headers[shaderIndex].index, + cache->headers[shaderIndex].size); + + return true; +} + +/* Stores the shader program in the cache. Returns false if there's an error with the cache, or + if the cache is too small to hold the shader. */ +static bool qt_cache_shader(const QGLShaderProgram *shader, const QGLContext *ctx, const QByteArray &md5Sum) +{ + ShaderCacheSharedMemory *shm = shaderCacheSharedMemory(); + if (!shm || !shm->isAttached()) + return false; + + void *data = shm->data(); + Q_ASSERT(data); + + CachedShaders *cache = reinterpret_cast(data); + + ShaderCacheLocker locker(shm); + if (!locker.isLocked()) + return false; + + int cacheIdx = cache->shaderCount; + if (cacheIdx >= ShaderCacheMaxEntries) { + traceCacheOverflow("Qt OpenGL shader cache index overflow!"); + return false; + } + + // now that we have the lock on the shared memory, make sure no one + // inserted the shader already while we were unlocked + if (qt_cache_index_unlocked(md5Sum, cache) != -1) + return true; // already cached + + shaderCacheDebug() << "Caching shader at index" << cacheIdx; + + GLint binaryLength = 0; + glGetProgramiv(shader->programId(), GL_PROGRAM_BINARY_LENGTH_OES, &binaryLength); + + if (!binaryLength) { + shaderCacheDebug() << "Unable to determine binary shader size!"; + return false; + } + + if (binaryLength > cache->availableSize()) { + traceCacheOverflow("Qt OpenGL shader cache data overflow!"); + return false; + } + + GLsizei size = 0; + GLenum format = 0; + glGetProgramBinaryOES(shader->programId(), binaryLength, &size, &format, + cache->data + cache->dataSize); + + if (!size) { + shaderCacheDebug() << "Unable to get binary shader!"; + return false; + } + + cache->headers[cacheIdx].index = cache->dataSize; + cache->dataSize += binaryLength; + ++cache->shaderCount; + cache->headers[cacheIdx].size = binaryLength; + cache->headers[cacheIdx].format = format; + + memcpy(cache->headers[cacheIdx].md5Sum, md5Sum.constData(), 16); + + shaderCacheDebug() << "cached shader size" << size + << "format" << format + << "binarySize" << binaryLength + << "cache index" << cacheIdx + << "data index" << cache->headers[cacheIdx].index; + + return true; +} + +} // namespace + +QT_BEGIN_NAMESPACE + +QT_MODULE(OpenGL) + +class CachedShader +{ +public: + CachedShader(const QByteArray &fragSource, const QByteArray &vertexSource) + : cacheIdx(-1) + { + QCryptographicHash md5Hash(QCryptographicHash::Md5); + + md5Hash.addData(fragSource); + md5Hash.addData(vertexSource); + + md5Sum = md5Hash.result(); + } + + bool isCached() + { + return cacheIndex() != -1; + } + + int cacheIndex() + { + if (cacheIdx != -1) + return cacheIdx; + cacheIdx = qt_cache_index(md5Sum); + return cacheIdx; + } + + bool load(QGLShaderProgram *program, const QGLContext *ctx) + { + if (cacheIndex() == -1) + return false; + return qt_cached_shader(program, ctx, cacheIdx); + } + + bool store(QGLShaderProgram *program, const QGLContext *ctx) + { + return qt_cache_shader(program, ctx, md5Sum); + } + +private: + QByteArray md5Sum; + int cacheIdx; +}; + + +QT_END_NAMESPACE + +#endif + +QT_END_HEADER + +#endif +#endif diff --git a/src/opengl/gl2paintengineex/qglshadercache_p.h b/src/opengl/gl2paintengineex/qglshadercache_p.h new file mode 100644 index 0000000..29616ae --- /dev/null +++ b/src/opengl/gl2paintengineex/qglshadercache_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 QtOpenGL 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$ +** +****************************************************************************/ + +// +// 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. +// + +#ifndef QGLSHADERCACHE_P_H +#define QGLSHADERCACHE_P_H + +#include + +#if defined(QT_MEEGO_EXPERIMENTAL_SHADERCACHE) && defined(QT_OPENGL_ES_2) +# include "qglshadercache_meego_p.h" +#else + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(OpenGL) + +class QGLShaderProgram; +class QGLContext; + +class CachedShader +{ +public: + inline CachedShader(const QByteArray &, const QByteArray &) + {} + + inline bool isCached() + { + return false; + } + + inline bool load(QGLShaderProgram *, const QGLContext *) + { + return false; + } + + inline bool store(QGLShaderProgram *, const QGLContext *) + { + return false; + } +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif +#endif diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 682e620..a089d55 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -60,7 +60,9 @@ SOURCES += qgl.cpp \ gl2paintengineex/qglcustomshaderstage_p.h \ gl2paintengineex/qtriangulatingstroker_p.h \ gl2paintengineex/qtriangulator_p.h \ - gl2paintengineex/qtextureglyphcache_gl_p.h + gl2paintengineex/qtextureglyphcache_gl_p.h \ + gl2paintengineex/qglshadercache_p.h \ + gl2paintengineex/qglshadercache_meego_p.h SOURCES += qglshaderprogram.cpp \ qglpixmapfilter.cpp \ diff --git a/src/opengl/util/meego/main.cpp b/src/opengl/util/meego/main.cpp new file mode 100644 index 0000000..0c9a915 --- /dev/null +++ b/src/opengl/util/meego/main.cpp @@ -0,0 +1,48 @@ +#include + +#define QT_DEBUG_SHADER_CACHE +#define QT_MEEGO_EXPERIMENTAL_SHADERCACHE +#define QT_OPENGL_ES_2 +#define QT_BOOTSTRAPPED + +typedef int GLsizei; +typedef unsigned int GLenum; + +#include "../../gl2paintengineex/qglshadercache_meego_p.h" + +#include +#include + +int main() +{ + ShaderCacheSharedMemory shm; + + if (!shm.isAttached()) { + fprintf(stderr, "Unable to attach to shared memory\n"); + return EXIT_FAILURE; + } + + ShaderCacheLocker locker(&shm); + if (!locker.isLocked()) { + fprintf(stderr, "Unable to lock shared memory\n"); + return EXIT_FAILURE; + } + + void *data = shm.data(); + Q_ASSERT(data); + + CachedShaders *cache = reinterpret_cast(data); + + for (int i = 0; i < cache->shaderCount; ++i) { + printf("Shader %d: %d bytes\n", i, cache->headers[i].size); + } + + printf("\nSummary:\n\n" + " Amount of cached shaders: %d\n" + " Bytes used: %d\n" + " Bytes available: %d\n", + cache->shaderCount, cache->dataSize, cache->availableSize()); + + return EXIT_SUCCESS; +} + diff --git a/src/opengl/util/meego/shader-cache-introspector.pro b/src/opengl/util/meego/shader-cache-introspector.pro new file mode 100644 index 0000000..520e9a5 --- /dev/null +++ b/src/opengl/util/meego/shader-cache-introspector.pro @@ -0,0 +1,7 @@ +TEMPLATE = app + +SOURCES += main.cpp + +TARGET = shader-cache-introspector + +QT = core -- cgit v0.12 From 482e924154a57cf2e37d8224d3c677635aa56317 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Tue, 21 Dec 2010 12:55:49 +0100 Subject: QMessageBox wrong Show/Hide Details button label On LanguageChange event QMessageBox switches Show/Hide Details button label Customer portal case id: 00217646 Merge-request: 973 Reviewed-by: Olivier Goffart --- src/gui/dialogs/qmessagebox.cpp | 2 +- tests/auto/qmessagebox/tst_qmessagebox.cpp | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp index 224a176..af9616d 100644 --- a/src/gui/dialogs/qmessagebox.cpp +++ b/src/gui/dialogs/qmessagebox.cpp @@ -1925,7 +1925,7 @@ void QMessageBoxPrivate::retranslateStrings() { #ifndef QT_NO_TEXTEDIT if (detailsButton) - detailsButton->setLabel(detailsText->isHidden() ? HideLabel : ShowLabel); + detailsButton->setLabel(detailsText->isHidden() ? ShowLabel : HideLabel); #endif } diff --git a/tests/auto/qmessagebox/tst_qmessagebox.cpp b/tests/auto/qmessagebox/tst_qmessagebox.cpp index d4ca064..54d199c 100644 --- a/tests/auto/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/qmessagebox/tst_qmessagebox.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) #include #endif @@ -119,6 +120,7 @@ private slots: void statics(); void about(); void detailsText(); + void detailsButtonText(); void shortcut(); @@ -661,6 +663,26 @@ void tst_QMessageBox::detailsText() QCOMPARE(box.detailedText(), text); } +void tst_QMessageBox::detailsButtonText() +{ + QMessageBox box; + box.setDetailedText("bla"); + box.open(); + QApplication::postEvent(&box, new QEvent(QEvent::LanguageChange)); + QApplication::processEvents(); + QDialogButtonBox* bb = box.findChild("qt_msgbox_buttonbox"); + QVERIFY(bb); //get the detail button + + QList list = bb->buttons(); + QAbstractButton* btn = NULL; + foreach(btn, list) { + if (btn && (btn->inherits("QPushButton"))) { + if(btn->text() != QMessageBox::tr("OK") && btn->text() != QMessageBox::tr("Show Details...")) + QFAIL("Incorrect messagebox button text!"); + } + } +} + void tst_QMessageBox::incorrectDefaultButton() { keyToSend = Qt::Key_Escape; -- cgit v0.12 From ff187688e113ec157dd14abcef0faf602b68901c Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 21 Dec 2010 14:21:21 +0100 Subject: Doc: Added a missing license header. --- doc/src/snippets/declarative/focus/focusColumn.qml | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/doc/src/snippets/declarative/focus/focusColumn.qml b/doc/src/snippets/declarative/focus/focusColumn.qml index eb59309..42ee3da 100644 --- a/doc/src/snippets/declarative/focus/focusColumn.qml +++ b/doc/src/snippets/declarative/focus/focusColumn.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$ +** +****************************************************************************/ import QtQuick 1.0 Rectangle { -- cgit v0.12 From 960c0f28c5c2a52d28f06d4cfda4f7d46becad93 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Mon, 20 Dec 2010 16:31:09 +1000 Subject: Remove redundant docs --- doc/src/declarative/qdeclarativereference.qdoc | 81 -------------------------- 1 file changed, 81 deletions(-) delete mode 100644 doc/src/declarative/qdeclarativereference.qdoc diff --git a/doc/src/declarative/qdeclarativereference.qdoc b/doc/src/declarative/qdeclarativereference.qdoc deleted file mode 100644 index c2c5e91..0000000 --- a/doc/src/declarative/qdeclarativereference.qdoc +++ /dev/null @@ -1,81 +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 documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** 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 -** 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$ -** -****************************************************************************/ - -/*! - \page qdeclarativereference.html - \title QML Reference - - \target qtdeclarativemainpage - - QML is a language for building the animation rich, - highly fluid user interfaces that are becoming common in portable consumer - electronics devices such as mobile phones, media players, set-top boxes and - netbooks. It is also appropriate for highly custom desktop - user interfaces, or special elements in more traditional desktop user interfaces. - - Building fluid applications is done declaratively, rather than procedurally. - That is, you specify \e what the UI should look like and how it should behave - rather than specifying step-by-step \e how to build it. Specifying a UI declaratively - does not just include the layout of the interface items, but also the way each - individual item looks and behaves and the overall flow of the application. - - The QML elements provide a sophisticated set of graphical and behavioral building - blocks. These different elements are combined together in \l {QML Documents}{QML documents} to build components - ranging in complexity from simple buttons and sliders, to complete - internet-enabled applications like a \l {http://www.flickr.com}{Flickr} photo browser. - - Getting Started: - \list - \o \l {Introduction to the QML language} - \o \l {QML Tutorial}{Tutorial: 'Hello World'} - \o \l {QML Advanced Tutorial}{Advanced Tutorial: 'Same Game'} - \o \l {QML Examples and Demos} - \endlist - - \section1 Core QML Features: - \list - \o \l {QML Documents} - \o \l {Property Binding} - \o \l {Integrating JavaScript} - \o \l {QML Scope} - \o \l {Network Transparency} - \o \l {qmlmodels}{Data Models} - \o \l {anchor-layout}{Anchor-based Layout} - \o \l {qmlstates}{States} - \o \l {qdeclarativeanimation.html}{Animation} - \o \l {qdeclarativemodules.html}{Modules} - \o \l {qmlfocus}{Keyboard Focus} - \o \l {Extending types from QML} - \endlist - - QML Reference: - \list - \o \l {elements}{QML Elements} - \o \l {QML Global Object} - \o \l {QML Internationalization} - \endlist -*/ -- cgit v0.12 From 22df95289adc5fca59cc0a42cf18e98c5cc433d9 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Wed, 22 Dec 2010 11:35:39 +1000 Subject: Add double type to QML Basic Types docs --- doc/src/declarative/basictypes.qdoc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/doc/src/declarative/basictypes.qdoc b/doc/src/declarative/basictypes.qdoc index 034b7d1..939f328 100644 --- a/doc/src/declarative/basictypes.qdoc +++ b/doc/src/declarative/basictypes.qdoc @@ -95,6 +95,26 @@ */ /*! + \qmlbasictype double + \ingroup qmlbasictypes + + \brief A double number has a decimal point and is stored in double precision. + + A double number has a decimal point and is stored in double precision, \l + {http://en.wikipedia.org/wiki/IEEE_754} {IEEE floating point} + format. + + Example: + \qml + Item { + property double number: 32155.2355 + } + \endqml + + \sa {QML Basic Types} +*/ + +/*! \qmlbasictype string \ingroup qmlbasictypes -- cgit v0.12 From 2d4d125313d79fb80f513952bed675b7126392fd Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Wed, 22 Dec 2010 12:23:08 +1000 Subject: Document the 'variant' basic type This includes documentation on restrictions and considerations when storing a JavaScript object with this type, since such properties only hold a copy of the object's values and not the actual object. Task-number: QTBUG-16196 Reviewed-by: Michael Brasser --- doc/src/declarative/basictypes.qdoc | 75 ++++++++++++++++++++++++++++++++++++- doc/src/declarative/extending.qdoc | 24 ++++++------ 2 files changed, 87 insertions(+), 12 deletions(-) diff --git a/doc/src/declarative/basictypes.qdoc b/doc/src/declarative/basictypes.qdoc index 939f328..e9d3a44 100644 --- a/doc/src/declarative/basictypes.qdoc +++ b/doc/src/declarative/basictypes.qdoc @@ -432,7 +432,8 @@ list only modify a \e copy of the list and not the actual list. (These current limitations are due to restrictions on \l {Property Binding} where lists are involved.) - To create a modifiable list, create an array object from within a \c .js JavaScript file, + You can, however, modify a copy of the list and then reassign the property to the modified + value. Other options are to create an array object from within a \c .js JavaScript file, or implement a custom list element in C++. Here is a QML element that modifies the list in a JavaScript file: @@ -472,6 +473,78 @@ \sa {QML Basic Types} */ + +/*! + \qmlbasictype variant + \ingroup qmlbasictypes + + \brief A variant type is a generic property type. + + A variant is a generic property type. A variant type property can hold any of the + \l {QML Basic Types}{basic type} values: + + \qml + Item { + property variant aNumber : 100 + property variant aString : "Hello world!" + property variant aList : [ 1, 2, "buckle my shoe" ] + } + \endqml + + The \c variant type can also hold a \e copy of a JavaScript object. For example, the + \c animal property below defines a JavaScript object defined with JSON notation. The + object's properties and values can be examined using the standard JavaScript syntax, + as shown in the \c Component.onCompleted handler. + + \qml + Item { + property variant animal : { 'type': 'bird', 'species': 'galah', 'age': 7 } + + Component.onCompleted: { + for (var attribute in animal) + console.log(attribute, "=", animal[attribute]) + } + } + \endqml + + It must be noted that the \c animal property holds a \e copy of the defined object, and + not the object itself. (This is true even if the property refers to an object defined in + some JavaScript file; the property will hold a copy of the object, and not the actual + object.) The property essentially holds a copy of the contents within the object. This + has several implications: + + \list + \o Changes to any of the property's values (for example, the \c animal.type value + above) only modify the \e copy of the object, not the object itself. You can, however, + modify a copy of the object and then reassign the property to the modified value. + \o Because the property only holds a copy of the object, \l{Property Binding}{bindings} to + any of the property's individual values are not updated until the whole property is + reassigned to a new value. For example: + + \qml + Item { + property variant animal : { 'type': 'bird', 'species': 'galah', 'age': 7 } + + Text { text: "Animal species: " + animal.species } + + Component.onCompleted: { + animal.species = 'kookaburra' // this has no effect on the displayed text + + var newObj = animal + newObj.species = 'kookaburra' + animal = newObj // this will update the displayed text + } + } + \endqml + \o Since the object values are copied, it does not hold any reference to the original + object, and extra data such as the object's JavaScript prototype chain is lost in the + process. + \endlist + + \sa {QML Basic Types} +*/ + + /*! \qmlbasictype vector3d \ingroup qmlbasictypes diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index 748ec6c..ff519f6 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -753,15 +753,15 @@ with their default values and the corresponding C++ type: \table \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 +\row \o \l int \o 0 \o int +\row \o \l bool \o \c false \o bool +\row \o \l double \o 0.0 \o double +\row \o \l real \o 0.0 \o double +\row \o \l string \o "" (empty string) \o QString +\row \o \l url \o "" (empty url) \o QUrl +\row \o \l color \o #000000 (black) \o QColor +\row \o \l date \o \c undefined \o QDateTime +\row \o \l variant \o \c undefined \o QVariant \endtable QML object types can also be used as property types. This includes @@ -776,6 +776,10 @@ property MyCustomType customProperty Such object-type properties default to an \c undefined value. +It is also possible to store a copy of a JavaScript object using the \c variant +property type. This creates some restrictions on how the property should be used; +see the \l {variant}{variant type documentation} for details. + \l{list}{List properties} are created with the \c list syntax, and default to an empty list: @@ -786,8 +790,6 @@ property list listOfItems Note that list properties cannot be modified like ordinary JavaScript arrays. See the \l {list}{list type documentation} for details. -For details about accessing and manipulating QML properties from C++, see \l {Using QML with C++}. - \section2 Property change signals -- cgit v0.12 From e50a0ad18c40322ca0c06a11e7dc7b9a82951f16 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Wed, 22 Dec 2010 16:12:26 +1000 Subject: XmlListModel requests should set 'Accept' header to 'application/xml' Task-number: QTBUG-15836 Reviewed-by: Michael Brasser --- src/declarative/util/qdeclarativexmllistmodel.cpp | 1 + .../tst_qdeclarativexmllistmodel.cpp | 69 ++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 49a12b1..e97cd67 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -924,6 +924,7 @@ void QDeclarativeXmlListModel::reload() } else { d->notifyQueryStarted(true); QNetworkRequest req(d->src); + req.setRawHeader("Accept", "application/xml"); d->reply = qmlContext(this)->engine()->networkAccessManager()->get(req); QObject::connect(d->reply, SIGNAL(finished()), this, SLOT(requestFinished())); QObject::connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp index a14f942..b95b053 100644 --- a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp +++ b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp @@ -38,8 +38,13 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +#include + #include #include +#include +#include +#include #include #include #include @@ -81,6 +86,7 @@ private slots: void roles(); void roleErrors(); void uniqueRoleNames(); + void headers(); void xml(); void xml_data(); void source(); @@ -139,6 +145,44 @@ private: QDeclarativeEngine engine; }; +class CustomNetworkAccessManagerFactory : public QObject, public QDeclarativeNetworkAccessManagerFactory +{ + Q_OBJECT +public: + QVariantMap lastSentHeaders; + +protected: + QNetworkAccessManager *create(QObject *parent); +}; + +class CustomNetworkAccessManager : public QNetworkAccessManager +{ + Q_OBJECT +public: + CustomNetworkAccessManager(CustomNetworkAccessManagerFactory *factory, QObject *parent) + : QNetworkAccessManager(parent), m_factory(factory) {} + +protected: + QNetworkReply *createRequest(Operation op, const QNetworkRequest &req, QIODevice * outgoingData = 0) + { + if (m_factory) { + QVariantMap map; + foreach (const QString &header, req.rawHeaderList()) + map[header] = req.rawHeader(header.toUtf8()); + m_factory->lastSentHeaders = map; + } + return QNetworkAccessManager::createRequest(op, req, outgoingData); + } + + QPointer m_factory; +}; + +QNetworkAccessManager *CustomNetworkAccessManagerFactory::create(QObject *parent) +{ + return new CustomNetworkAccessManager(this, parent); +} + + void tst_qdeclarativexmllistmodel::buildModel() { QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/model.qml")); @@ -312,6 +356,31 @@ void tst_qdeclarativexmllistmodel::xml_data() QTest::newRow("one item") << "HobbesTiger7Large" << 1; } +void tst_qdeclarativexmllistmodel::headers() +{ + // ensure the QNetworkAccessManagers created for this test are immediately deleted + QDeclarativeEngine qmlEng; + + CustomNetworkAccessManagerFactory factory; + qmlEng.setNetworkAccessManagerFactory(&factory); + + QDeclarativeComponent component(&qmlEng, QUrl::fromLocalFile(SRCDIR "/data/model.qml")); + QDeclarativeXmlListModel *model = qobject_cast(component.create()); + QVERIFY(model != 0); + QTRY_COMPARE(model->status(), QDeclarativeXmlListModel::Ready); + + QVariantMap expectedHeaders; + expectedHeaders["Accept"] = "application/xml"; + + QCOMPARE(factory.lastSentHeaders.count(), expectedHeaders.count()); + foreach (const QString &header, expectedHeaders.keys()) { + QVERIFY(factory.lastSentHeaders.contains(header)); + QCOMPARE(factory.lastSentHeaders[header].toString(), expectedHeaders[header].toString()); + } + + delete model; +} + void tst_qdeclarativexmllistmodel::source() { QFETCH(QUrl, source); -- cgit v0.12 From cb31612bf6a48f995fbc05b5e8aa924e13034ae4 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 22 Dec 2010 16:15:28 +1000 Subject: Removing all visible items in ListView resulted in blank view. When delayRemove is true and all visible items are tagged to be removed the visibleIndex became invalid and refill() began filling from 0. Task-number: QTBUG-16183 Reviewed-by: Michael Brasser --- src/declarative/graphicsitems/qdeclarativelistview.cpp | 14 ++++++++++---- .../qdeclarativelistview/tst_qdeclarativelistview.cpp | 3 ++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 2a7f508..86c8756 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -643,7 +643,8 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) int i = visibleItems.count() - 1; while (i > 0 && visibleItems.at(i)->index == -1) --i; - modelIndex = visibleItems.at(i)->index + 1; + if (visibleItems.at(i)->index != -1) + modelIndex = visibleItems.at(i)->index + 1; } bool changed = false; @@ -2804,7 +2805,10 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) int i = d->visibleItems.count() - 1; while (i > 0 && d->visibleItems.at(i)->index == -1) --i; - if (d->visibleItems.at(i)->index + 1 == modelIndex + if (i == 0 && d->visibleItems.first()->index == -1) { + // there are no visible items except items marked for removal + index = d->visibleItems.count(); + } else if (d->visibleItems.at(i)->index + 1 == modelIndex && d->visibleItems.at(i)->endPosition() < d->buffer+d->position()+d->size()-1) { // Special case of appending an item to the model. index = d->visibleItems.count(); @@ -2836,7 +2840,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count) // 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() - : d->visibleItems.at(index-1)->endPosition()+d->spacing+1; + : d->visibleItems.last()->endPosition()+d->spacing+1; int initialPos = pos; int diff = 0; QList added; @@ -2988,14 +2992,16 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) } // update visibleIndex + bool haveVisibleIndex = false; for (it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) { if ((*it)->index != -1) { d->visibleIndex = (*it)->index; + haveVisibleIndex = true; break; } } - if (removedVisible && d->visibleItems.isEmpty()) { + if (removedVisible && !haveVisibleIndex) { d->timeline.clear(); if (d->itemCount == 0) { d->visibleIndex = 0; diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 3df10a9..dba0cc4 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -667,7 +667,8 @@ void tst_QDeclarativeListView::removed(bool animated) listview->setContentY(80); QTest::qWait(300); - model.removeItems(1, 17); + // remove all visible items + model.removeItems(1, 18); QTest::qWait(300); // Confirm items positioned correctly -- cgit v0.12 From 749387a203737e49fb44ce7001ed78ba5512583d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 21 Dec 2010 12:43:16 +0100 Subject: Improve performance of bilinear downscaling of images with neon. Gives a 36 % performance boost for downscaling a 512x512 pixmap to 480x480 with SmoothPixmapFilter enabled. Reviewed-by: Andreas Kling --- src/gui/painting/qdrawhelper.cpp | 133 +++++++++++++++++++++++++++++++-------- 1 file changed, 107 insertions(+), 26 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 62af212..fdb686d 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -712,6 +712,38 @@ static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, i } #endif +#if defined(QT_ALWAYS_HAVE_NEON) +#define interpolate_4_pixels_16_neon(tl, tr, bl, br, distx, disty, disty_, colorMask, invColorMask, v_256, b) \ +{ \ + const int16x8_t dxdy = vmulq_s16(distx, disty); \ + const int16x8_t distx_ = vshlq_n_s16(distx, 4); \ + const int16x8_t idxidy = vaddq_s16(dxdy, vsubq_s16(v_256, vaddq_s16(distx_, disty_))); \ + const int16x8_t dxidy = vsubq_s16(distx_, dxdy); \ + const int16x8_t idxdy = vsubq_s16(disty_, dxdy); \ + \ + int16x8_t tlAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tl), 8)); \ + int16x8_t tlRB = vandq_s16(tl, colorMask); \ + int16x8_t trAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tr), 8)); \ + int16x8_t trRB = vandq_s16(tr, colorMask); \ + int16x8_t blAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bl), 8)); \ + int16x8_t blRB = vandq_s16(bl, colorMask); \ + int16x8_t brAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(br), 8)); \ + int16x8_t brRB = vandq_s16(br, colorMask); \ + \ + int16x8_t rAG = vmulq_s16(tlAG, idxidy); \ + int16x8_t rRB = vmulq_s16(tlRB, idxidy); \ + rAG = vmlaq_s16(rAG, trAG, dxidy); \ + rRB = vmlaq_s16(rRB, trRB, dxidy); \ + rAG = vmlaq_s16(rAG, blAG, idxdy); \ + rRB = vmlaq_s16(rRB, blRB, idxdy); \ + rAG = vmlaq_s16(rAG, brAG, dxdy); \ + rRB = vmlaq_s16(rRB, brRB, dxdy); \ + \ + rAG = vandq_s16(invColorMask, rAG); \ + rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8)); \ + vst1q_s16((int16_t*)(b), vorrq_s16(rAG, rRB)); \ +} +#endif template Q_STATIC_TEMPLATE_FUNCTION inline void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2) @@ -920,35 +952,36 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * const uchar *s2 = data->texture.scanLine(y2); int disty = (fy & 0x0000ffff) >> 12; -#if defined(QT_ALWAYS_HAVE_SSE2) if (blendType != BlendTransformedBilinearTiled && (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)) { - //prolog to get into the bounds - while (b < end) { - int x1 = (fx >> 16); - int x2; - fetchTransformedBilinear_pixelBounds(image_width, image_x1, image_x2, x1, x2); - if (x1 != x2) //break if we are insided the bounds. - break; - uint tl = fetch(s1, x1, data->texture.colorTable); - uint tr = fetch(s1, x2, data->texture.colorTable); - uint bl = fetch(s2, x1, data->texture.colorTable); - uint br = fetch(s2, x2, data->texture.colorTable); - int distx = (fx & 0x0000ffff) >> 12; - *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); - fx += fdx; - ++b; - } - uint *boundedEnd; - if (fdx > 0) - boundedEnd = qMin(end, buffer + uint((image_x2 - (fx >> 16)) / data->m11)); - else - boundedEnd = qMin(end, buffer + uint((image_x1 - (fx >> 16)) / data->m11)); +#define BILINEAR_DOWNSCALE_BOUNDS_PROLOG \ + while (b < end) { \ + int x1 = (fx >> 16); \ + int x2; \ + fetchTransformedBilinear_pixelBounds(image_width, image_x1, image_x2, x1, x2); \ + if (x1 != x2) \ + break; \ + uint tl = fetch(s1, x1, data->texture.colorTable); \ + uint tr = fetch(s1, x2, data->texture.colorTable); \ + uint bl = fetch(s2, x1, data->texture.colorTable); \ + uint br = fetch(s2, x2, data->texture.colorTable); \ + int distx = (fx & 0x0000ffff) >> 12; \ + *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); \ + fx += fdx; \ + ++b; \ + } \ + uint *boundedEnd; \ + if (fdx > 0) \ + boundedEnd = qMin(end, buffer + uint((image_x2 - (fx >> 16)) / data->m11)); \ + else \ + boundedEnd = qMin(end, buffer + uint((image_x1 - (fx >> 16)) / data->m11)); \ boundedEnd -= 3; +#if defined(QT_ALWAYS_HAVE_SSE2) + BILINEAR_DOWNSCALE_BOUNDS_PROLOG + const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); - //const __m128i distShuffleMask = _mm_set_epi8(13, 12, 13, 12, 9, 8, 9, 8, 5, 4, 5, 4, 1, 0, 1, 0); const __m128i v_256 = _mm_set1_epi16(256); const __m128i v_disty = _mm_set1_epi16(disty); __m128i v_fdx = _mm_set1_epi32(fdx*4); @@ -976,8 +1009,7 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * bl.i[i] = *(addr_tl+secondLine); br.i[i] = *(addr_tr+secondLine); } - __m128i v_distx = _mm_srli_epi16(v_fx.vect, 12); //distx = (fx & 0x0000ffff) >> 12; - //v_distx = _mm_shuffle_epi8(v_disty, distShuffleMask); //distx |= distx << 16; + __m128i v_distx = _mm_srli_epi16(v_fx.vect, 12); v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0)); v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0)); @@ -986,8 +1018,57 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * v_fx.vect = _mm_add_epi32(v_fx.vect, v_fdx); } fx = v_fx.i[0]; - } +#elif defined(QT_ALWAYS_HAVE_NEON) + BILINEAR_DOWNSCALE_BOUNDS_PROLOG + + const int16x8_t colorMask = vdupq_n_s16(0x00ff); + const int16x8_t invColorMask = vmvnq_s16(colorMask); + const int16x8_t v_256 = vdupq_n_s16(256); + const int16x8_t v_disty = vdupq_n_s16(disty); + const int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4); + int32x4_t v_fdx = vdupq_n_s32(fdx*4); + + ptrdiff_t secondLine = reinterpret_cast(s2) - reinterpret_cast(s1); + + union Vect_buffer { int32x4_t vect; quint32 i[4]; }; + Vect_buffer v_fx; + + for (int i = 0; i < 4; i++) { + v_fx.i[i] = fx; + fx += fdx; + } + + const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff); + + while (b < boundedEnd) { + + Vect_buffer tl, tr, bl, br; + + Vect_buffer v_fx_shifted; + v_fx_shifted.vect = vshrq_n_s32(v_fx.vect, 16); + + int32x4_t v_distx = vshrq_n_s32(vandq_s32(v_fx.vect, v_ffff_mask), 12); + + for (int i = 0; i < 4; i++) { + int x1 = v_fx_shifted.i[i]; + const uint *addr_tl = reinterpret_cast(s1) + x1; + const uint *addr_tr = addr_tl + 1; + tl.i[i] = *addr_tl; + tr.i[i] = *addr_tr; + bl.i[i] = *(addr_tl+secondLine); + br.i[i] = *(addr_tr+secondLine); + } + + v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16)); + + interpolate_4_pixels_16_neon(vreinterpretq_s16_s32(tl.vect), vreinterpretq_s16_s32(tr.vect), vreinterpretq_s16_s32(bl.vect), vreinterpretq_s16_s32(br.vect), vreinterpretq_s16_s32(v_distx), v_disty, v_disty_, colorMask, invColorMask, v_256, b); + b+=4; + v_fx.vect = vaddq_s32(v_fx.vect, v_fdx); + } + fx = v_fx.i[0]; #endif + } + while (b < end) { int x1 = (fx >> 16); int x2; -- cgit v0.12 From 53f52118efd7587fe604f3d3dd898fa9464809a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 22 Dec 2010 09:34:37 +0100 Subject: Made documentation of QPixmap::createMaskFromColor match behaviour. Task-number: QTBUG-16223 Reviewed-by: Gunnar Sletta --- src/gui/image/qpixmap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index c5d9a7e..3a7be1d 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -775,8 +775,8 @@ QBitmap QPixmap::createHeuristicMask(bool clipTight) const /*! Creates and returns a mask for this pixmap based on the given \a maskColor. If the \a mode is Qt::MaskInColor, all pixels matching the - maskColor will be opaque. If \a mode is Qt::MaskOutColor, all pixels - matching the maskColor will be transparent. + maskColor will be transparent. If \a mode is Qt::MaskOutColor, all pixels + matching the maskColor will be opaque. This function is slow because it involves converting to/from a QImage. -- cgit v0.12 From 07bc01460e72f08550f09de66e0e716471cf61bd Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 22 Dec 2010 12:18:39 +0200 Subject: Fix libinfixed usage in Symbian when def files are used There was a hardcoded lookup on "qtcore.dll" in s60main, which caused loading of wrong dll. Task-number: QTBUG-16221 Reviewed-by: Janne Koskinen --- src/s60main/newallocator_hook.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/s60main/newallocator_hook.cpp b/src/s60main/newallocator_hook.cpp index 9ea2ef0..3e259c2 100644 --- a/src/s60main/newallocator_hook.cpp +++ b/src/s60main/newallocator_hook.cpp @@ -69,6 +69,16 @@ TInt UserHeap::SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo) // So the function is found and called dynamically, by library lookup. If it is not found, we // use the OS allocator creation functions instead. +#if defined(QT_LIBINFIX) +# define QT_LSTRING2(x) L##x +# define QT_LSTRING(x) QT_LSTRING2(x) +# define QT_LIBINFIX_UNICODE QT_LSTRING(QT_LIBINFIX) +#else +# define QT_LIBINFIX_UNICODE L"" +#endif + +_LIT(QtCoreLibName, "qtcore" QT_LIBINFIX_UNICODE L".dll"); + struct SThreadCreateInfo { TAny* iHandle; @@ -106,7 +116,7 @@ TInt UserHeap::SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo) #ifndef __WINS__ // attempt to create the fast allocator through a known export ordinal in qtcore.dll RLibrary qtcore; - if (qtcore.Load(_L("qtcore.dll")) == KErrNone) + if (qtcore.Load(QtCoreLibName) == KErrNone) { const int qt_symbian_SetupThreadHeap_eabi_ordinal = 3713; TLibraryFunction libFunc = qtcore.Lookup(qt_symbian_SetupThreadHeap_eabi_ordinal); -- cgit v0.12 From bdc39d20b4958f7adc95dc5990d601e946213fda Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Wed, 22 Dec 2010 11:37:56 +0100 Subject: add missing license header --- src/opengl/util/meego/main.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/opengl/util/meego/main.cpp b/src/opengl/util/meego/main.cpp index 0c9a915..5522855 100644 --- a/src/opengl/util/meego/main.cpp +++ b/src/opengl/util/meego/main.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 QtOpenGL 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 #define QT_DEBUG_SHADER_CACHE -- cgit v0.12 From 6210542b3fb2b577512f5e2970f14303d1e5f21a Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 22 Dec 2010 14:04:26 +0100 Subject: tst_qmessagebox: add debug to know why it fails --- tests/auto/qmessagebox/tst_qmessagebox.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/qmessagebox/tst_qmessagebox.cpp b/tests/auto/qmessagebox/tst_qmessagebox.cpp index 54d199c..f6ee764 100644 --- a/tests/auto/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/qmessagebox/tst_qmessagebox.cpp @@ -677,8 +677,10 @@ void tst_QMessageBox::detailsButtonText() QAbstractButton* btn = NULL; foreach(btn, list) { if (btn && (btn->inherits("QPushButton"))) { - if(btn->text() != QMessageBox::tr("OK") && btn->text() != QMessageBox::tr("Show Details...")) + if (btn->text() != QMessageBox::tr("OK") && btn->text() != QMessageBox::tr("Show Details...")) { + qDebug() << btn->text(); QFAIL("Incorrect messagebox button text!"); + } } } } -- cgit v0.12 From 6ecb2f699c203fd937495cba844f7888a1d3305f Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 22 Dec 2010 14:30:59 +0100 Subject: Assistant: Get rid of bogus warning. Task-number: QTBUG-16096 --- tools/assistant/tools/assistant/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/assistant/tools/assistant/main.cpp b/tools/assistant/tools/assistant/main.cpp index e3eef34..5883f7b 100644 --- a/tools/assistant/tools/assistant/main.cpp +++ b/tools/assistant/tools/assistant/main.cpp @@ -292,7 +292,8 @@ void setupTranslation(const QString &fileName, const QString &dir) QTranslator *translator = new QTranslator(QCoreApplication::instance()); if (translator->load(fileName, dir)) { QCoreApplication::installTranslator(translator); - } else if (!fileName.endsWith(QLatin1String("en_US"))) { + } else if (!fileName.endsWith(QLatin1String("en_US")) + && !fileName.endsWith(QLatin1String("_C"))) { qWarning("Could not load translation file %s in directory %s.", qPrintable(fileName), qPrintable(dir)); } -- cgit v0.12 From bfd3a0d40932cb4ef2a35424a24e1961c3b21bb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 21 Dec 2010 15:14:23 +0100 Subject: Improve performance of bilinear upscaling of images with neon. Gives an improvement of around 19.6 % for upscaling a 256x256 pixmap to 480x480 with SmoothPixmapFilter enabled. Reviewed-by: Olivier Goffart --- src/gui/painting/qdrawhelper.cpp | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index fdb686d..4fd90ed 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -851,10 +851,9 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * } } -#if defined(QT_ALWAYS_HAVE_SSE2) if (blendType != BlendTransformedBilinearTiled && (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)) { - +#if defined(QT_ALWAYS_HAVE_SSE2) const __m128i disty_ = _mm_set1_epi16(disty); const __m128i idisty_ = _mm_set1_epi16(idisty); const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); @@ -884,8 +883,38 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * rRB = _mm_srli_epi16(rRB, 8); _mm_storeu_si128((__m128i*)(&intermediate_buffer[0][f]), rRB); } - } +#elif defined(QT_ALWAYS_HAVE_NEON) + const int16x8_t disty_ = vdupq_n_s16(disty); + const int16x8_t idisty_ = vdupq_n_s16(idisty); + const int16x8_t colorMask = vdupq_n_s16(0x00ff); + + lim -= 3; + for (; f < lim; x += 4, f += 4) { + // Load 4 pixels from s1, and split the alpha-green and red-blue component + int16x8_t top = vld1q_s16((int16_t*)((const uint *)(s1)+x)); + int16x8_t topAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(top), 8)); + int16x8_t topRB = vandq_s16(top, colorMask); + // Multiplies each colour component by idisty + topAG = vmulq_s16(topAG, idisty_); + topRB = vmulq_s16(topRB, idisty_); + + // Same for the s2 vector + int16x8_t bottom = vld1q_s16((int16_t*)((const uint *)(s2)+x)); + int16x8_t bottomAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bottom), 8)); + int16x8_t bottomRB = vandq_s16(bottom, colorMask); + bottomAG = vmulq_s16(bottomAG, disty_); + bottomRB = vmulq_s16(bottomRB, disty_); + + // Add the values, and shift to only keep 8 significant bits per colors + int16x8_t rAG = vaddq_s16(topAG, bottomAG); + rAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rAG), 8)); + vst1q_s16((int16_t*)(&intermediate_buffer[1][f]), rAG); + int16x8_t rRB = vaddq_s16(topRB, bottomRB); + rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8)); + vst1q_s16((int16_t*)(&intermediate_buffer[0][f]), rRB); + } #endif + } for (; f < count; f++) { // Same as above but without sse2 if (blendType == BlendTransformedBilinearTiled) { if (x >= image_width) x -= image_width; -- cgit v0.12 From a5110b5d40b70fb44ed98aa8861b676df1e78385 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 22 Dec 2010 14:34:16 +0100 Subject: Fix timer regression for indeterminate progressbars Indeterminate progressbars were broken since 4.7.0 due to 0f771c62f5253a969f5a8a81bfd9254b9bd58b8f Since start was never called on QElapsedTimer, the elaped time was undefined and resulted in random repaints and behavior for indeterminate progressbars. Task-number:QTBUG-15227 Reviewed-by:richard --- src/gui/styles/qwindowsstyle.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 720dd6d..654be3c 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -130,6 +130,7 @@ QWindowsStylePrivate::QWindowsStylePrivate() pSHGetStockIconInfo = (PtrSHGetStockIconInfo)shellLib.resolve("SHGetStockIconInfo"); } #endif + startTime.start(); } // Returns true if the toplevel parent of \a widget has seen the Alt-key -- cgit v0.12 From 462f5148a3be5835cc8d5b69685473042789c917 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 22 Dec 2010 15:39:28 +0200 Subject: Fix infinite loop in qmake when reading malformed .ts files. No checking for the end of xml file was done in while loop looking for TS element. Task-number: QTBUG-16261 Reviewed-by: Janne Koskinen --- qmake/generators/symbian/symbiancommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/symbian/symbiancommon.cpp b/qmake/generators/symbian/symbiancommon.cpp index 602bcc2..d9f12b3 100644 --- a/qmake/generators/symbian/symbiancommon.cpp +++ b/qmake/generators/symbian/symbiancommon.cpp @@ -977,7 +977,7 @@ bool SymbianCommonGenerator::parseTsContent(const QString &tsFilename, SymbianLo QXmlStreamReader xml(&tsFile); - while (xml.name() != tsElement) + while (!xml.atEnd() && xml.name() != tsElement) xml.readNextStartElement(); while (xml.readNextStartElement()) { -- cgit v0.12 From a562fd2d201e3b618ed99a316275f20385cc5c25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 16 Dec 2010 14:45:21 +0100 Subject: Added int overloads to QPoint operator* and operator*=. For increased performance to avoid having to convert to qreal and back. Separating the qreal overload into float and double overloads is also necessary to avoid compiler errors about ambiguous overloads. Task-number: QTBUG-15872 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/tools/qpoint.cpp | 63 +++++++++++++++++++++++++++++++++++++++++--- src/corelib/tools/qpoint.h | 38 +++++++++++++++++++++----- 2 files changed, 92 insertions(+), 9 deletions(-) diff --git a/src/corelib/tools/qpoint.cpp b/src/corelib/tools/qpoint.cpp index c297709..592a83d 100644 --- a/src/corelib/tools/qpoint.cpp +++ b/src/corelib/tools/qpoint.cpp @@ -187,7 +187,19 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QPoint &QPoint::operator*=(qreal factor) + \fn QPoint &QPoint::operator*=(float factor) + + Multiplies this point's coordinates by the given \a factor, and + returns a reference to this point. + + Note that the result is rounded to the nearest integer as points are held as + integers. Use QPointF for floating point accuracy. + + \sa operator/=() +*/ + +/*! + \fn QPoint &QPoint::operator*=(double factor) Multiplies this point's coordinates by the given \a factor, and returns a reference to this point. For example: @@ -200,6 +212,14 @@ QT_BEGIN_NAMESPACE \sa operator/=() */ +/*! + \fn QPoint &QPoint::operator*=(int factor) + + Multiplies this point's coordinates by the given \a factor, and + returns a reference to this point. + + \sa operator/=() +*/ /*! \fn bool operator==(const QPoint &p1, const QPoint &p2) @@ -237,7 +257,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn const QPoint operator*(const QPoint &point, qreal factor) + \fn const QPoint operator*(const QPoint &point, float factor) \relates QPoint Returns a copy of the given \a point multiplied by the given \a factor. @@ -249,7 +269,44 @@ QT_BEGIN_NAMESPACE */ /*! - \fn const QPoint operator*(qreal factor, const QPoint &point) + \fn const QPoint operator*(const QPoint &point, double factor) + \relates QPoint + + Returns a copy of the given \a point multiplied by the given \a factor. + + Note that the result is rounded to the nearest integer as points + are held as integers. Use QPointF for floating point accuracy. + + \sa QPoint::operator*=() +*/ + +/*! + \fn const QPoint operator*(const QPoint &point, int factor) + \relates QPoint + + Returns a copy of the given \a point multiplied by the given \a factor. + + \sa QPoint::operator*=() +*/ + +/*! + \fn const QPoint operator*(float factor, const QPoint &point) + \overload + \relates QPoint + + Returns a copy of the given \a point multiplied by the given \a factor. +*/ + +/*! + \fn const QPoint operator*(double factor, const QPoint &point) + \overload + \relates QPoint + + Returns a copy of the given \a point multiplied by the given \a factor. +*/ + +/*! + \fn const QPoint operator*(int factor, const QPoint &point) \overload \relates QPoint diff --git a/src/corelib/tools/qpoint.h b/src/corelib/tools/qpoint.h index 79a7dd8..e57b0ed 100644 --- a/src/corelib/tools/qpoint.h +++ b/src/corelib/tools/qpoint.h @@ -70,15 +70,23 @@ public: QPoint &operator+=(const QPoint &p); QPoint &operator-=(const QPoint &p); - QPoint &operator*=(qreal c); + + QPoint &operator*=(float c); + QPoint &operator*=(double c); + QPoint &operator*=(int c); + QPoint &operator/=(qreal c); friend inline bool operator==(const QPoint &, const QPoint &); friend inline bool operator!=(const QPoint &, const QPoint &); friend inline const QPoint operator+(const QPoint &, const QPoint &); friend inline const QPoint operator-(const QPoint &, const QPoint &); - friend inline const QPoint operator*(const QPoint &, qreal); - friend inline const QPoint operator*(qreal, const QPoint &); + friend inline const QPoint operator*(const QPoint &, float); + friend inline const QPoint operator*(float, const QPoint &); + friend inline const QPoint operator*(const QPoint &, double); + friend inline const QPoint operator*(double, const QPoint &); + friend inline const QPoint operator*(const QPoint &, int); + friend inline const QPoint operator*(int, const QPoint &); friend inline const QPoint operator-(const QPoint &); friend inline const QPoint operator/(const QPoint &, qreal); @@ -141,9 +149,15 @@ inline QPoint &QPoint::operator+=(const QPoint &p) inline QPoint &QPoint::operator-=(const QPoint &p) { xp-=p.xp; yp-=p.yp; return *this; } -inline QPoint &QPoint::operator*=(qreal c) +inline QPoint &QPoint::operator*=(float c) +{ xp = qRound(xp*c); yp = qRound(yp*c); return *this; } + +inline QPoint &QPoint::operator*=(double c) { xp = qRound(xp*c); yp = qRound(yp*c); return *this; } +inline QPoint &QPoint::operator*=(int c) +{ xp = xp*c; yp = yp*c; return *this; } + inline bool operator==(const QPoint &p1, const QPoint &p2) { return p1.xp == p2.xp && p1.yp == p2.yp; } @@ -156,12 +170,24 @@ inline const QPoint operator+(const QPoint &p1, const QPoint &p2) inline const QPoint operator-(const QPoint &p1, const QPoint &p2) { return QPoint(p1.xp-p2.xp, p1.yp-p2.yp); } -inline const QPoint operator*(const QPoint &p, qreal c) +inline const QPoint operator*(const QPoint &p, float c) { return QPoint(qRound(p.xp*c), qRound(p.yp*c)); } -inline const QPoint operator*(qreal c, const QPoint &p) +inline const QPoint operator*(const QPoint &p, double c) { return QPoint(qRound(p.xp*c), qRound(p.yp*c)); } +inline const QPoint operator*(const QPoint &p, int c) +{ return QPoint(p.xp*c, p.yp*c); } + +inline const QPoint operator*(float c, const QPoint &p) +{ return QPoint(qRound(p.xp*c), qRound(p.yp*c)); } + +inline const QPoint operator*(double c, const QPoint &p) +{ return QPoint(qRound(p.xp*c), qRound(p.yp*c)); } + +inline const QPoint operator*(int c, const QPoint &p) +{ return QPoint(p.xp*c, p.yp*c); } + inline const QPoint operator-(const QPoint &p) { return QPoint(-p.xp, -p.yp); } -- cgit v0.12 From ce432e1799111cbed492e46bb62d8dfb40585a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 17 Dec 2010 12:46:44 +0100 Subject: Prevented infinite loop in QMoviePrivate::next(). If we're unable to read the first frame, we shouldn't return an end marker, as that will cause QMoviePrivate::next() to recurse indefinitely when the playCounter is set to -1 (infinite). Reviewed-by: Olivier Goffart --- src/gui/image/qmovie.cpp | 6 +++++- tests/auto/qmovie/animations/corrupt.gif | Bin 0 -> 847 bytes tests/auto/qmovie/qmovie.pro | 1 + tests/auto/qmovie/resources.qrc | 5 +++++ tests/auto/qmovie/tst_qmovie.cpp | 13 +++++++++++++ 5 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 tests/auto/qmovie/animations/corrupt.gif create mode 100644 tests/auto/qmovie/resources.qrc diff --git a/src/gui/image/qmovie.cpp b/src/gui/image/qmovie.cpp index 911a2b5..eb139fa 100644 --- a/src/gui/image/qmovie.cpp +++ b/src/gui/image/qmovie.cpp @@ -381,10 +381,14 @@ QFrameInfo QMoviePrivate::infoForFrame(int frameNumber) QPixmap aPixmap = QPixmap::fromImage(anImage); int aDelay = reader->nextImageDelay(); return QFrameInfo(aPixmap, aDelay); - } else { + } else if (frameNumber != 0) { // We've read all frames now. Return an end marker haveReadAll = true; return QFrameInfo::endMarker(); + } else { + // No readable frames + haveReadAll = true; + return QFrameInfo(); } } diff --git a/tests/auto/qmovie/animations/corrupt.gif b/tests/auto/qmovie/animations/corrupt.gif new file mode 100644 index 0000000..c1545eb Binary files /dev/null and b/tests/auto/qmovie/animations/corrupt.gif differ diff --git a/tests/auto/qmovie/qmovie.pro b/tests/auto/qmovie/qmovie.pro index 6973955..855eb9e 100644 --- a/tests/auto/qmovie/qmovie.pro +++ b/tests/auto/qmovie/qmovie.pro @@ -12,6 +12,7 @@ wince*: { DEPLOYMENT += addFiles } +RESOURCES += resources.qrc symbian: { addFiles.files = animations\\* diff --git a/tests/auto/qmovie/resources.qrc b/tests/auto/qmovie/resources.qrc new file mode 100644 index 0000000..ce459a0 --- /dev/null +++ b/tests/auto/qmovie/resources.qrc @@ -0,0 +1,5 @@ + + + animations/corrupt.gif + + diff --git a/tests/auto/qmovie/tst_qmovie.cpp b/tests/auto/qmovie/tst_qmovie.cpp index 80a551b..d43d4cb 100644 --- a/tests/auto/qmovie/tst_qmovie.cpp +++ b/tests/auto/qmovie/tst_qmovie.cpp @@ -72,6 +72,7 @@ private slots: void jumpToFrame_data(); void jumpToFrame(); void changeMovieFile(); + void infiniteLoop(); }; // Testing get/set functions @@ -208,5 +209,17 @@ void tst_QMovie::changeMovieFile() QVERIFY(movie.currentFrameNumber() == -1); } +void tst_QMovie::infiniteLoop() +{ + QLabel label; + label.show(); + QMovie *movie = new QMovie(QLatin1String(":animations/corrupt.gif"), QByteArray(), &label); + label.setMovie(movie); + movie->start(); + + QTestEventLoop::instance().enterLoop(1); + QTestEventLoop::instance().timeout(); +} + QTEST_MAIN(tst_QMovie) #include "tst_qmovie.moc" -- cgit v0.12 From 8c74ca2677e942bdd86f69527ab8f8ea4a15144a Mon Sep 17 00:00:00 2001 From: Eckhart Koppen Date: Wed, 22 Dec 2010 16:54:54 +0200 Subject: Added initial set of build related files for Symbian config.profiles directory created with initial files needed to compile Qt on Nokia specific build setups during Symbian platform builds. Reviewed-by: Lars Knoll --- config.profiles/symbian/bld.inf | 87 + config.profiles/symbian/confml/qt.confml | 16 + config.profiles/symbian/data_caging_paths.prf | 71 + config.profiles/symbian/environment.prf | 9 + config.profiles/symbian/headerexport | 1138 +++ config.profiles/symbian/implml/qt_copy.implml | 10 + config.profiles/symbian/layers.sysdef.xml | 41 + config.profiles/symbian/loc.prf | 25 + config.profiles/symbian/non_foundation_paths.prf | 115 + config.profiles/symbian/package_definition.xml | 54 + config.profiles/symbian/package_map.xml | 1 + config.profiles/symbian/platform_paths.prf | 251 + config.profiles/symbian/qt.conf | 6 + config.profiles/symbian/qt.iby | 118 + config.profiles/symbian/qtconfig.flm | 88 + config.profiles/symbian/qtconfig.xml | 17 + config.profiles/symbian/sysdef_1_5_1.dtd | 88 + config.profiles/symbian/translations/qt_ar.ts | 7821 ++++++++++++++++++ config.profiles/symbian/translations/qt_fa.ts | 8507 +++++++++++++++++++ .../symbian/translations/qt_fr_symbian.ts | 8519 +++++++++++++++++++ config.profiles/symbian/translations/qt_he.ts | 7781 ++++++++++++++++++ .../symbian/translations/qt_pl_symbian.ts | 8525 ++++++++++++++++++++ .../symbian/translations/qt_ru_symbian.ts | 8522 +++++++++++++++++++ config.profiles/symbian/translations/qt_ur.ts | 8507 +++++++++++++++++++ .../symbian/translations/qt_zh_cn_symbian.ts | 8517 +++++++++++++++++++ .../symbian/translations/qt_zh_tw_symbian.ts | 8505 +++++++++++++++++++ .../symbian/translations_symbian/translations.pro | 16 + 27 files changed, 77355 insertions(+) create mode 100644 config.profiles/symbian/bld.inf create mode 100644 config.profiles/symbian/confml/qt.confml create mode 100644 config.profiles/symbian/data_caging_paths.prf create mode 100644 config.profiles/symbian/environment.prf create mode 100644 config.profiles/symbian/headerexport create mode 100644 config.profiles/symbian/implml/qt_copy.implml create mode 100644 config.profiles/symbian/layers.sysdef.xml create mode 100644 config.profiles/symbian/loc.prf create mode 100644 config.profiles/symbian/non_foundation_paths.prf create mode 100644 config.profiles/symbian/package_definition.xml create mode 100644 config.profiles/symbian/package_map.xml create mode 100644 config.profiles/symbian/platform_paths.prf create mode 100644 config.profiles/symbian/qt.conf create mode 100644 config.profiles/symbian/qt.iby create mode 100644 config.profiles/symbian/qtconfig.flm create mode 100644 config.profiles/symbian/qtconfig.xml create mode 100644 config.profiles/symbian/sysdef_1_5_1.dtd create mode 100644 config.profiles/symbian/translations/qt_ar.ts create mode 100644 config.profiles/symbian/translations/qt_fa.ts create mode 100644 config.profiles/symbian/translations/qt_fr_symbian.ts create mode 100644 config.profiles/symbian/translations/qt_he.ts create mode 100644 config.profiles/symbian/translations/qt_pl_symbian.ts create mode 100644 config.profiles/symbian/translations/qt_ru_symbian.ts create mode 100644 config.profiles/symbian/translations/qt_ur.ts create mode 100644 config.profiles/symbian/translations/qt_zh_cn_symbian.ts create mode 100644 config.profiles/symbian/translations/qt_zh_tw_symbian.ts create mode 100644 config.profiles/symbian/translations_symbian/translations.pro diff --git a/config.profiles/symbian/bld.inf b/config.profiles/symbian/bld.inf new file mode 100644 index 0000000..d3958dd --- /dev/null +++ b/config.profiles/symbian/bld.inf @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* Description: Build information file for Qt configuration +* +*/ + +#include + +PRJ_PLATFORMS +TOOLS2 + +PRJ_EXPORTS +qtconfig.xml /epoc32/tools/makefile_templates/qt/qtconfig.xml +qtconfig.flm /epoc32/tools/makefile_templates/qt/qtconfig.flm + +../../mkspecs/symbian-sbsv2/flm/qt/qmake_emulator_deployment.flm /epoc32/tools/makefile_templates/qt/ +../../mkspecs/symbian-sbsv2/flm/qt/qmake_extra_pre_targetdep.flm /epoc32/tools/makefile_templates/qt/ +../../mkspecs/symbian-sbsv2/flm/qt/qmake_post_link.flm /epoc32/tools/makefile_templates/qt/ +../../mkspecs/symbian-sbsv2/flm/qt/qmake_store_build.flm /epoc32/tools/makefile_templates/qt/ +../../mkspecs/symbian-sbsv2/flm/qt/qt.xml /epoc32/tools/makefile_templates/qt/ + +qt.conf /epoc32/tools/qt.conf + +/* export platform specific configuration */ + +platform_paths.prf /epoc32/include/ +data_caging_paths.prf /epoc32/include/ +non_foundation_paths.prf /epoc32/include/ + +environment.prf /epoc32/tools/qt/mkspecs/features/environment.prf + +//for loc +loc.prf /epoc32/tools/qt/mkspecs/features/loc.prf + +//For UDA image +confml/qt.confml CONFML_EXPORT_PATH(qt.confml,uda_content) +implml/qt_copy.implml CRML_EXPORT_PATH(qt_copy.implml,uda_content) +content/apps/qt.sisx CRML_EXPORT_PATH(../content/sis/,uda_content) +content/apps/qt_stub.sis /epoc32/data/z/system/install/qt_stub.sis + +//tools +../../bin/createpackage.bat /epoc32/tools/createpackage.bat +../../bin/createpackage.pl /epoc32/tools/createpackage.pl +../../bin/patch_capabilities.bat /epoc32/tools/patch_capabilities.bat +../../bin/patch_capabilities.pl /epoc32/tools/patch_capabilities.pl + + +/* export localization *.ts files */ +translations/qt_ur.ts /epoc32/include/platform/qt/translations/ +translations/qt_fa.ts /epoc32/include/platform/qt/translations/ +translations/qt_ar.ts /epoc32/include/platform/qt/translations/ +translations/qt_he.ts /epoc32/include/platform/qt/translations/ + +translations/qt_fr_symbian.ts /epoc32/include/platform/qt/translations/qt_fr.ts +translations/qt_pl_symbian.ts /epoc32/include/platform/qt/translations/qt_pl.ts +translations/qt_ru_symbian.ts /epoc32/include/platform/qt/translations/qt_ru.ts +translations/qt_zh_cn_symbian.ts /epoc32/include/platform/qt/translations/qt_zh_cn.ts +translations/qt_zh_tw_symbian.ts /epoc32/include/platform/qt/translations/qt_zh_tw.ts + +../../translations/qt_ar.ts /epoc32/include/platform/qt/translations/ +../../translations/qt_cs.ts /epoc32/include/platform/qt/translations/ +../../translations/qt_da.ts /epoc32/include/platform/qt/translations/ +../../translations/qt_de.ts /epoc32/include/platform/qt/translations/ +../../translations/qt_es.ts /epoc32/include/platform/qt/translations/ +../../translations/qt_gl.ts /epoc32/include/platform/qt/translations/ +../../translations/qt_hu.ts /epoc32/include/platform/qt/translations/ +../../translations/qt_ja.ts /epoc32/include/platform/qt/translations/ +../../translations/qt_pt.ts /epoc32/include/platform/qt/translations/ +../../translations/qt_sk.ts /epoc32/include/platform/qt/translations/ +../../translations/qt_sl.ts /epoc32/include/platform/qt/translations/ +../../translations/qt_sv.ts /epoc32/include/platform/qt/translations/ +../../translations/qt_uk.ts /epoc32/include/platform/qt/translations/ + + +PRJ_MMPFILES + + +PRJ_TESTMMPFILES + + +PRJ_EXTENSIONS +START EXTENSION qt/qtconfig +OPTION QT_ROOT .. +OPTION OPTIONS -opensource -confirm-license -openvg -opengl-es-2 -script -no-scripttools -no-webkit -make make -graphicssystem openvg -no-phonon-backend -usedeffiles -dont-process -nomake examples -nomake demos -nomake tools -audio-backend -fpu softvfp+vfpv2 +END \ No newline at end of file diff --git a/config.profiles/symbian/confml/qt.confml b/config.profiles/symbian/confml/qt.confml new file mode 100644 index 0000000..f5e9a49 --- /dev/null +++ b/config.profiles/symbian/confml/qt.confml @@ -0,0 +1,16 @@ + + + + QT settings + + To enable QT usage + + + + + true + + + \ No newline at end of file diff --git a/config.profiles/symbian/data_caging_paths.prf b/config.profiles/symbian/data_caging_paths.prf new file mode 100644 index 0000000..8bb0f79 --- /dev/null +++ b/config.profiles/symbian/data_caging_paths.prf @@ -0,0 +1,71 @@ +# +# ============================================================================== +# Name : data_caging_paths.prf +# Part of : +# Interface : Data Caging Path Definitions API for Qt/S60 +# Description : Paths specific to Symbian^3 and later +# +# Usage examples: +# +# # Load these definitions on pro-file if needed: +# load(data_caging_paths) +# +# # These variables are mostly useful when specifying deployment +# +# myLib.sources = myLib.dll +# myLib.path = $$SHARED_LIB_DIR +# DEPLOYMENT += myLib +# +# # Note: Do not use $$PLUGINS_DIR or $$PLUGINS_1_DIR to deploy Qt plugins. +# # $$QT_PUBLIC_PLUGINS_BASE specifies the public base directory for Qt +# # plugin stubs: +# +# myPublicImageFormatPlugin.sources = myImageFormat.dll +# myPublicImageFormatPlugin.path = $$QT_PLUGINS_BASE_DIR/imageformats +# DEPLOYMENT += myPublicImageFormatPlugin +# +# ============================================================================== + +APPARC_RECOGNISER_RESOURCES_DIR = /resource/apps/registrationresourcefiles +APP_BITMAP_DIR = /resource/apps +APP_RESOURCE_DIR = /resource/apps +BITMAP_DIR = /resource/apps +BIOFILE_DIR = /resource/messaging/bif +CHARCONV_PLUGIN_DIR = /resource/charconv +CONTACTS_RESOURCE_DIR = /resource/cntmodel +CTRL_PANEL_RESOURCE_DIR = /resource/controls +CONVERTER_PLUGIN_RESOURCE_DIR = /resource/convert +ECOM_RESOURCE_DIR = /resource/plugins +ERROR_RESOURCE_DIR = /resource/errors +PROGRAMS_DIR = /sys/bin +FEP_RESOURCES_DIR = /resource/fep +HELP_FILE_DIR = /resource/help +LOG_ENGINE_RESOURCE_DIR = /resource/logengine +MTM_RESOURCE_DIR = /resource/messaging +MTM_INFO_FILE_DIR = /resource/messaging/mtm +PRINTER_DRIVER_DIR = /resource/printers +SHARED_LIB_DIR = /sys/bin +UIKLAF_RESOURCE_DIR = /resource/uiklaf +WAPPUSH_PLUGIN_RESOURCE_DIR = /resource/messaging/wappush +WATCHER_PLUGIN_RESOURCE_DIR = /resource/messaging/watchers +RECOGNISERS_DIR = /sys/bin +PARSERS_DIR = /sys/bin +NOTIFIERS_DIR = /sys/bin +PLUGINS_DIR = /sys/bin +PLUGINS_1_DIR = /sys/bin +RESOURCE_FILES_DIR = /resource + +CA_CERTIFICATES_DIR = /private/101f72a6 +COMMDB_DIR = /private/100012a5 +SS_CONFIG_FILE_DIR = /private/101f7989/esock +TRUSTED_FONTS_DIR = /private/10003a16/fonts +UNTRUSTED_FONT_DIR = /private/10003a16/import/fonts +WINDOW_SERVER_INI_DIR = /private/10003b20 +SKINS_DIR = /private/10207114 +BOOTDATA_DIR = /resource/bootdata + +isEmpty(QT_PLUGINS_BASE_DIR): QT_PLUGINS_BASE_DIR = $$RESOURCE_FILES_DIR/qt$${QT_LIBINFIX}/plugins +isEmpty(QT_IMPORTS_BASE_DIR): QT_IMPORTS_BASE_DIR = $$RESOURCE_FILES_DIR/qt/imports +isEmpty(HW_ZDIR): HW_ZDIR = epoc32/data/z +isEmpty(REG_RESOURCE_DIR): REG_RESOURCE_DIR = /private/10003a3f/apps +isEmpty(REG_RESOURCE_IMPORT_DIR): REG_RESOURCE_IMPORT_DIR = /private/10003a3f/import/apps diff --git a/config.profiles/symbian/environment.prf b/config.profiles/symbian/environment.prf new file mode 100644 index 0000000..09ba90d --- /dev/null +++ b/config.profiles/symbian/environment.prf @@ -0,0 +1,9 @@ +# don't export SQLite on Symbian^3 onwards since it is already in the environment +CONFIG *= symbian_no_export_sqlite + +# STL autodetection in clean builds not working, specify it explicitly +CONFIG *= stl + + +S60_VERSION = 5.2 +SYMBIAN_VERSION = Symbian3 \ No newline at end of file diff --git a/config.profiles/symbian/headerexport b/config.profiles/symbian/headerexport new file mode 100644 index 0000000..e9e6f3b --- /dev/null +++ b/config.profiles/symbian/headerexport @@ -0,0 +1,1138 @@ +#!/usr/bin/perl -w +###################################################################### +# +# Synchronizes Qt header files - internal development tool. +# +# Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +# Contact: Nokia Corporation (qt-info@nokia.com) +# +###################################################################### + +# use packages ------------------------------------------------------- +use File::Basename; +use File::Path; +use Cwd; +use Config; +use strict; + +for (my $i = 0; $i < $#ARGV; $i++) { + if ($ARGV[$i] eq "-base-dir" && $i < $#ARGV - 1) { + $ENV{"QTDIR"} = $ARGV[$i + 1]; + last; + } +} + +die "syncqt: QTDIR not defined" if ! $ENV{"QTDIR"}; # sanity check + +# global variables +my $isunix = 0; +my $basedir = $ENV{"QTDIR"}; +$basedir =~ s=\\=/=g; +my %modules = ( # path to module name map + "QtGui" => "$basedir/src/gui", + "QtOpenGL" => "$basedir/src/opengl", + "QtOpenVG" => "$basedir/src/openvg", + "QtCore" => "$basedir/src/corelib", + "QtXml" => "$basedir/src/xml", + "QtXmlPatterns" => "$basedir/src/xmlpatterns", + "QtSql" => "$basedir/src/sql", + "QtNetwork" => "$basedir/src/network", + "QtSvg" => "$basedir/src/svg", + "QtDeclarative" => "$basedir/src/declarative", + "QtScript" => "$basedir/src/script", + "QtScriptTools" => "$basedir/src/scripttools", + "Qt3Support" => "$basedir/src/qt3support", + "ActiveQt" => "$basedir/src/activeqt", + "QtTest" => "$basedir/src/testlib", + "QtHelp" => "$basedir/tools/assistant/lib", + "QtDesigner" => "$basedir/tools/designer/src/lib", + "QtUiTools" => "$basedir/tools/designer/src/uitools", + "QtDBus" => "$basedir/src/dbus", +# "QtWebKit" => "$basedir/src/3rdparty/webkit/WebCore", // :TODO:disabled since QtWebKit built separately, better logic needed here. + "phonon" => "$basedir/src/phonon", + "QtMultimedia" => "$basedir/src/multimedia", + "QtMeeGoGraphicsSystemHelper" => "$basedir/tools/qmeegographicssystemhelper", +); +my %moduleheaders = ( # restrict the module headers to those found in relative path + "QtWebKit" => "../WebKit/qt/Api", + "phonon" => "../3rdparty/phonon/phonon", +); + +#$modules{"QtCore"} .= ";$basedir/mkspecs/" . $ENV{"MKSPEC"} if defined $ENV{"MKSPEC"}; + +# global variables (modified by options) +my $module = 0; +my $showonly = 0; +my $quiet = 0; +my $remove_stale = 1; +my $force_win = 0; +my $force_relative = 0; +my $check_includes = 0; +my $copy_headers = 0; +my $create_uic_class_map = 1; +my $create_private_headers = 1; +my $oneway = 0; +my @modules_to_sync ; +$force_relative = 1 if ( -d "/System/Library/Frameworks" ); +my $out_basedir = $basedir; +$out_basedir =~ s=\\=/=g; +my $out_subdir = 'include'; + +# functions ---------------------------------------------------------- + +###################################################################### +# Syntax: showUsage() +# Params: -none- +# +# Purpose: Show the usage of the script. +# Returns: -none- +###################################################################### +sub showUsage +{ + print "$0 usage:\n"; + print " -copy Copy headers instead of include-fwd(default: " . ($copy_headers ? "yes" : "no") . ")\n"; + print " -remove-stale Removes stale headers (default: " . ($remove_stale ? "yes" : "no") . ")\n"; + print " -relative Force relative symlinks (default: " . ($force_relative ? "yes" : "no") . ")\n"; + print " -windows Force platform to Windows (default: " . ($force_win ? "yes" : "no") . ")\n"; + print " -showonly Show action but not perform (default: " . ($showonly ? "yes" : "no") . ")\n"; + print " -outdir Specify output directory for sync (default: $out_basedir)\n"; + print " -outsubdir

Target subdir under outdir (default: $out_subdir)\n"; + print " -public Create only public headers (default: " . ($create_private_headers ? "no" : "yes") . ")\n"; + print " -oneway Don't sync back from outdir (default: " . ($oneway ? "yes" : "no") . ")\n"; + print " -quiet Only report problems, not activity (default: " . ($quiet ? "yes" : "no") . ")\n"; + print " -separate-module :: Create headers for with original headers in relative to \n"; + print " -help This help\n"; + exit 0; +} + +###################################################################### +# Syntax: checkUnix() +# Params: -none- +# +# Purpose: Check if script runs on a Unix system or not. Cygwin +# systems are _not_ detected as Unix systems. +# Returns: 1 if a unix system, else 0. +###################################################################### +sub checkUnix { + my ($r) = 0; + if ( $force_win != 0) { + return 0; + } elsif ( -f "/bin/uname" ) { + $r = 1; + (-f "\\bin\\uname") && ($r = 0); + } elsif ( -f "/usr/bin/uname" ) { + $r = 1; + (-f "\\usr\\bin\\uname") && ($r = 0); + } + if($r) { + $_ = $Config{'osname'}; + $r = 0 if( /(ms)|(cyg)win/i ); + } + return $r; +} + +sub checkRelative { + my ($dir) = @_; + return 0 if($dir =~ /^\//); + return 0 if(!checkUnix() && $dir =~ /[a-zA-Z]:[\/\\]/); + return 1; +} + +###################################################################### +# Syntax: shouldMasterInclude(iheader) +# Params: iheader, string, filename to verify inclusion +# +# Purpose: Determines if header should be in the master include file. +# Returns: 0 if file contains "#pragma qt_no_master_include" or not +# able to open, else 1. +###################################################################### +sub shouldMasterInclude { + my ($iheader) = @_; + return 0 if(basename($iheader) =~ /_/); + return 0 if(basename($iheader) =~ /qconfig/); + if(open(F, "<$iheader")) { + while() { + chomp; + return 0 if(/^\#pragma qt_no_master_include$/); + } + close(F); + } else { + return 0; + } + return 1; +} + +###################################################################### +# Syntax: classNames(iheader) +# Params: iheader, string, filename to parse for classname "symlinks" +# +# Purpose: Scans through iheader to find all classnames that should be +# synced into library's include structure. +# Returns: List of all class names in a file. +###################################################################### +sub classNames { + my @ret; + my ($iheader) = @_; + if(basename($iheader) eq "qglobal.h") { + push @ret, "QtGlobal"; + } elsif(basename($iheader) eq "qendian.h") { + push @ret, "QtEndian"; + } elsif(basename($iheader) eq "qconfig.h") { + push @ret, "QtConfig"; + } elsif(basename($iheader) eq "qplugin.h") { + push @ret, "QtPlugin"; + } elsif(basename($iheader) eq "qalgorithms.h") { + push @ret, "QtAlgorithms"; + } elsif(basename($iheader) eq "qcontainerfwd.h") { + push @ret, "QtContainerFwd"; + } elsif(basename($iheader) eq "qdebug.h") { + push @ret, "QtDebug"; + } elsif(basename($iheader) eq "qevent.h") { + push @ret, "QtEvents"; + } elsif(basename($iheader) eq "qnamespace.h") { + push @ret, "Qt" + } elsif(basename($iheader) eq "qssl.h") { + push @ret, "QSsl"; + } elsif(basename($iheader) eq "qtest.h") { + push @ret, "QTest" + } elsif(basename($iheader) eq "qtconcurrentmap.h") { + push @ret, "QtConcurrentMap" + } elsif(basename($iheader) eq "qtconcurrentfilter.h") { + push @ret, "QtConcurrentFilter" + } elsif(basename($iheader) eq "qtconcurrentrun.h") { + push @ret, "QtConcurrentRun" + } elsif(basename($iheader) eq "qaudio.h") { + push @ret, "QAudio" + } + + my $parsable = ""; + if(open(F, "<$iheader")) { + while() { + my $line = $_; + chomp $line; + chop $line if ($line =~ /\r$/); + if($line =~ /^\#/) { + if($line =~ /\\$/) { + while($line = ) { + chomp $line; + last unless($line =~ /\\$/); + } + } + return @ret if($line =~ m/^#pragma qt_sync_stop_processing/); + push(@ret, $1) if($line =~ m/^#pragma qt_class\(([^)]*)\)[\r\n]*$/); + $line = 0; + } + if($line) { + $line =~ s,//.*$,,; #remove c++ comments + $line .= ";" if($line =~ m/^Q_[A-Z_]*\(.*\)[\r\n]*$/); #qt macro + $line .= ";" if($line =~ m/^QT_(BEGIN|END)_HEADER[\r\n]*$/); #qt macro + $line .= ";" if($line =~ m/^QT_(BEGIN|END)_NAMESPACE[\r\n]*$/); #qt macro + $line .= ";" if($line =~ m/^QT_MODULE\(.*\)[\r\n]*$/); # QT_MODULE macro + $parsable .= " " . $line; + } + } + close(F); + } + + my $last_definition = 0; + my @namespaces; + for(my $i = 0; $i < length($parsable); $i++) { + my $definition = 0; + my $character = substr($parsable, $i, 1); + if($character eq "/" && substr($parsable, $i+1, 1) eq "*") { #I parse like this for greedy reasons + for($i+=2; $i < length($parsable); $i++) { + my $end = substr($parsable, $i, 2); + if($end eq "*/") { + $last_definition = $i+2; + $i++; + last; + } + } + } elsif($character eq "{") { + my $brace_depth = 1; + my $block_start = $i + 1; + BLOCK: for($i+=1; $i < length($parsable); $i++) { + my $ignore = substr($parsable, $i, 1); + if($ignore eq "{") { + $brace_depth++; + } elsif($ignore eq "}") { + $brace_depth--; + unless($brace_depth) { + for(my $i2 = $i+1; $i2 < length($parsable); $i2++) { + my $end = substr($parsable, $i2, 1); + if($end eq ";" || $end ne " ") { + $definition = substr($parsable, $last_definition, $block_start - $last_definition) . "}"; + $i = $i2 if($end eq ";"); + $last_definition = $i + 1; + last BLOCK; + } + } + } + } + } + } elsif($character eq ";") { + $definition = substr($parsable, $last_definition, $i - $last_definition + 1); + $last_definition = $i + 1; + } elsif($character eq "}") { + # a naked } must be a namespace ending + # if it's not a namespace, it's eaten by the loop above + pop @namespaces; + $last_definition = $i + 1; + } + + if (substr($parsable, $last_definition, $i - $last_definition + 1) =~ m/ namespace ([^ ]*) / + && substr($parsable, $i+1, 1) eq "{") { + push @namespaces, $1; + + # Eat the opening { so that the condensing loop above doesn't see it + $i++; + $last_definition = $i + 1; + } + + if($definition) { + $definition =~ s=[\n\r]==g; + my @symbols; + if($definition =~ m/^ *typedef *.*\(\*([^\)]*)\)\(.*\);$/) { + push @symbols, $1; + } elsif($definition =~ m/^ *typedef +(.*) +([^ ]*);$/) { + push @symbols, $2; + } elsif($definition =~ m/^ *(template *<.*> *)?(class|struct) +([^ ]* +)?([^<\s]+) ?(<[^>]*> ?)?\s*((,|:)\s*(public|protected|private) *.*)? *\{\}$/) { + push @symbols, $4; + } elsif($definition =~ m/^ *Q_DECLARE_.*ITERATOR\((.*)\);$/) { + push @symbols, "Q" . $1 . "Iterator"; + push @symbols, "QMutable" . $1 . "Iterator"; + } + + foreach my $symbol (@symbols) { + $symbol = (join("::", @namespaces) . "::" . $symbol) if (scalar @namespaces); + push @ret, $symbol + if ($symbol =~ /^Q[^:]*$/ # no-namespace, starting with Q + || $symbol =~ /^Phonon::/); # or in the Phonon namespace + } + } + } + return @ret; +} + +###################################################################### +# Syntax: syncHeader(header, iheader, copy, timestamp) +# Params: header, string, filename to create "symlink" for +# iheader, string, destination name of symlink +# copy, forces header to be a copy of iheader +# timestamp, the requested modification time if copying +# +# Purpose: Syncronizes header to iheader +# Returns: 1 if successful, else 0. +###################################################################### +sub syncHeader { + my ($header, $iheader, $copy, $ts) = @_; + $iheader =~ s=\\=/=g; + $header =~ s=\\=/=g; + return copyFile($iheader, $header) if($copy); + + unless(-e $header) { + my $header_dir = dirname($header); + mkpath $header_dir, !$quiet; + + #write it + my $iheader_out = fixPaths($iheader, $header_dir); + open HEADER, ">$header" || die "Could not open $header for writing!\n"; + print HEADER "#include \"$iheader_out\"\n"; + close HEADER; + utime(time, $ts, $header) or die "$iheader, $header"; + return 1; + } + return 0; +} + +###################################################################### +# Syntax: fixPaths(file, dir) +# Params: file, string, filepath to be made relative to dir +# dir, string, dirpath for point of origin +# +# Purpose: file is made relative (if possible) of dir. +# Returns: String with the above applied conversion. +###################################################################### +sub fixPaths { + my ($file, $dir) = @_; + $dir =~ s=^$basedir/=$out_basedir/= if(!($basedir eq $out_basedir)); + $file =~ s=\\=/=g; + $file =~ s/\+/\\+/g; + $dir =~ s=\\=/=g; + $dir =~ s/\+/\\+/g; + + #setup + my $ret = $file; + $ret =~ s,/cygdrive/([a-zA-Z])/,$1:/,g; + my $file_dir = dirname($file); + if($file_dir eq ".") { + $file_dir = getcwd(); + $file_dir =~ s=\\=/=g; + } + $file_dir =~ s,/cygdrive/([a-zA-Z])/,$1:/,g; + if($dir eq ".") { + $dir = getcwd(); + $dir =~ s=\\=/=g; + } + $dir =~ s,/cygdrive/([a-zA-Z])/,$1:/,g; + return basename($file) if($file_dir eq $dir); + + #guts + my $match_dir = 0; + for(my $i = 1; $i < length($file_dir); $i++) { + my $slash = index($file_dir, "/", $i); + last if($slash == -1); + my $tmp = substr($file_dir, 0, $slash); + last unless($dir =~ m,^$tmp/,); + $match_dir = $tmp; + $i = $slash; + } + if($match_dir) { + my $after = substr($dir, length($match_dir)); + my $count = ($after =~ tr,/,,); + my $dots = ""; + for(my $i = 0; $i < $count; $i++) { + $dots .= "../"; + } + $ret =~ s,^$match_dir,$dots,; + } + $ret =~ s,/+,/,g; + return $ret; +} + +###################################################################### +# Syntax: fileContents(filename) +# Params: filename, string, filename of file to return contents +# +# Purpose: Get the contents of a file. +# Returns: String with contents of the file, or empty string if file +# doens't exist. +# Warning: Dies if it does exist but script cannot get read access. +###################################################################### +sub fileContents { + my ($filename) = @_; + my $filecontents = ""; + if (-e $filename) { + open(I, "< $filename") || die "Could not open $filename for reading, read block?"; + local $/; + binmode I; + $filecontents = ; + close I; + } + return $filecontents; +} + +###################################################################### +# Syntax: fileCompare(file1, file2) +# Params: file1, string, filename of first file +# file2, string, filename of second file +# +# Purpose: Determines if files are equal, and which one is newer. +# Returns: 0 if files are equal no matter the timestamp, -1 if file1 +# is newer, 1 if file2 is newer. +###################################################################### +sub fileCompare { + my ($file1, $file2) = @_; + my $file1contents = fileContents($file1); + my $file2contents = fileContents($file2); + if (! -e $file1) { return 1; } + if (! -e $file2) { return -1; } + return $file1contents ne $file2contents ? (stat($file2))[9] <=> (stat($file1))[9] : 0; +} + +###################################################################### +# Syntax: copyFile(file, ifile) +# Params: file, string, filename to create duplicate for +# ifile, string, destination name of duplicate +# +# Purpose: Keeps files in sync so changes in the newer file will be +# written to the other. +# Returns: 1 if files were synced, else 0. +# Warning: Dies if script cannot get write access. +###################################################################### +sub copyFile +{ + my ($file,$ifile, $copy,$knowdiff,$filecontents,$ifilecontents) = @_; + # Bi-directional synchronization + open( I, "< " . $file ) || die "Could not open $file for reading"; + local $/; + binmode I; + $filecontents = ; + close I; + if ( open(I, "< " . $ifile) ) { + local $/; + binmode I; + $ifilecontents = ; + close I; + $copy = fileCompare($file, $ifile); + $knowdiff = 0, + } else { + $copy = -1; + $knowdiff = 1; + } + + if ( $knowdiff || ($filecontents ne $ifilecontents) ) { + if ( $copy > 0 && !$oneway) { + my $file_dir = dirname($file); + mkpath $file_dir, !$quiet unless(-e $file_dir); + open(O, "> " . $file) || die "Could not open $file for writing (no write permission?)"; + local $/; + binmode O; + print O $ifilecontents; + close O; + utime time, (stat($ifile))[9], $file; + return 1; + } elsif ( $copy < 0 ) { + my $ifile_dir = dirname($ifile); + mkpath $ifile_dir, !$quiet unless(-e $ifile_dir); + open(O, "> " . $ifile) || die "Could not open $ifile for writing (no write permission?)"; + local $/; + binmode O; + print O $filecontents; + close O; + utime time, (stat($file))[9], $ifile; + return 1; + } + } + return 0; +} + +###################################################################### +# Syntax: symlinkFile(file, ifile) +# Params: file, string, filename to create "symlink" for +# ifile, string, destination name of symlink +# +# Purpose: File is symlinked to ifile (or copied if filesystem doesn't +# support symlink). +# Returns: 1 on success, else 0. +###################################################################### +sub symlinkFile +{ + my ($file,$ifile) = @_; + + if ($isunix) { + print "symlink created for $file " unless $quiet; + if ( $force_relative && ($ifile =~ /^$basedir/)) { + my $t = getcwd(); + my $c = -1; + my $p = "../"; + $t =~ s-^$basedir/--; + $p .= "../" while( ($c = index( $t, "/", $c + 1)) != -1 ); + $file =~ s-^$basedir/-$p-; + print " ($file)\n" unless $quiet; + } + print "\n" unless $quiet; + return symlink($file, $ifile); + } + return copyFile($file, $ifile); +} + +###################################################################### +# Syntax: findFiles(dir, match, descend) +# Params: dir, string, directory to search for name +# match, string, regular expression to match in dir +# descend, integer, 0 = non-recursive search +# 1 = recurse search into subdirectories +# +# Purpose: Finds files matching a regular expression. +# Returns: List of matching files. +# +# Examples: +# findFiles("/usr","\.cpp$",1) - finds .cpp files in /usr and below +# findFiles("/tmp","^#",0) - finds #* files in /tmp +###################################################################### +sub findFiles { + my ($dir,$match,$descend) = @_; + my ($file,$p,@files); + local(*D); + $dir =~ s=\\=/=g; + ($dir eq "") && ($dir = "."); + if ( opendir(D,$dir) ) { + if ( $dir eq "." ) { + $dir = ""; + } else { + ($dir =~ /\/$/) || ($dir .= "/"); + } + foreach $file ( sort readdir(D) ) { + next if ( $file =~ /^\.\.?$/ ); + $p = $file; + ($file =~ /$match/) && (push @files, $p); + if ( $descend && -d $p && ! -l $p ) { + push @files, &findFiles($p,$match,$descend); + } + } + closedir(D); + } + return @files; +} + +# -------------------------------------------------------------------- +# "main" function +# -------------------------------------------------------------------- + +while ( @ARGV ) { + my $var = 0; + my $val = 0; + + #parse + my $arg = shift @ARGV; + if ($arg eq "-h" || $arg eq "-help" || $arg eq "?") { + $var = "show_help"; + $val = "yes"; + } elsif($arg eq "-copy") { + $var = "copy"; + $val = "yes"; + } elsif($arg eq "-o" || $arg eq "-outdir") { + $var = "output"; + $val = shift @ARGV; + } elsif($arg eq "-showonly" || $arg eq "-remove-stale" || $arg eq "-windows" || + $arg eq "-relative" || $arg eq "-check-includes") { + $var = substr($arg, 1); + $val = "yes"; + } elsif($arg =~ /^-no-(.*)$/) { + $var = $1; + $val = "no"; + #these are for commandline compat + } elsif($arg eq "-inc") { + $var = "output"; + $val = shift @ARGV; + } elsif($arg eq "-module") { + $var = "module"; + $val = shift @ARGV; + } elsif($arg eq "-separate-module") { + $var = "separate-module"; + $val = shift @ARGV; + } elsif($arg eq "-show") { + $var = "showonly"; + $val = "yes"; + } elsif($arg eq "-quiet") { + $var = "quiet"; + $val = "yes"; + } elsif($arg eq "-base-dir") { + # skip, it's been dealt with at the top of the file + shift @ARGV; + next; + } elsif("$arg" eq "-outsubdir") { + $var = "outsubdir"; + $val = shift @ARGV; + } elsif("$arg" eq "-public") { + $var = "public"; + $val = "yes"; + } elsif("$arg" eq "-oneway") { + $var = "oneway"; + $val = "yes"; + } + + #do something + if(!$var || $var eq "show_help") { + print "Unknown option: $arg\n\n" if(!$var); + showUsage(); + } elsif ($var eq "copy") { + if($val eq "yes") { + $copy_headers++; + } elsif($showonly) { + $copy_headers--; + } + } elsif ($var eq "showonly") { + if($val eq "yes") { + $showonly++; + } elsif($showonly) { + $showonly--; + } + } elsif ($var eq "quiet") { + if($val eq "yes") { + $quiet++; + } elsif($quiet) { + $quiet--; + } + } elsif ($var eq "check-includes") { + if($val eq "yes") { + $check_includes++; + } elsif($check_includes) { + $check_includes--; + } + } elsif ($var eq "remove-stale") { + if($val eq "yes") { + $remove_stale++; + } elsif($remove_stale) { + $remove_stale--; + } + } elsif ($var eq "windows") { + if($val eq "yes") { + $force_win++; + } elsif($force_win) { + $force_win--; + } + } elsif ($var eq "relative") { + if($val eq "yes") { + $force_relative++; + } elsif($force_relative) { + $force_relative--; + } + } elsif ("$var" eq "public") { + $create_private_headers = ("$val" eq "yes" ? 0 : 1); + } elsif ("$var" eq "oneway") { + $oneway = ("$val" eq "yes" ? 1 : 0); + } elsif ("$var" eq "outsubdir") { + $out_subdir = $val; + } elsif ($var eq "module") { + print "module :$val:\n" unless $quiet; + die "No such module: $val" unless(defined $modules{$val}); + push @modules_to_sync, $val; + } elsif ($var eq "separate-module") { + my ($module, $prodir, $headerdir) = split(/:/, $val); + $modules{$module} = $prodir; + push @modules_to_sync, $module; + $moduleheaders{$module} = $headerdir; + $create_uic_class_map = 0; + $create_private_headers = 0; + } elsif ($var eq "output") { + my $outdir = $val; + if(checkRelative($outdir)) { + $out_basedir = getcwd(); + chomp $out_basedir; + $out_basedir .= "/" . $outdir; + } else { + $out_basedir = $outdir; + } + # \ -> / + $out_basedir =~ s=\\=/=g; + } +} +@modules_to_sync = keys(%modules) if($#modules_to_sync == -1); + +$isunix = checkUnix; #cache checkUnix + +# create path +mkpath "$out_basedir/include", !$quiet; +mkpath "$out_basedir/$out_subdir/Qt", !$quiet; + +my @ignore_headers = (); +my $class_lib_map_contents = ""; +my @ignore_for_master_contents = ( "qt.h", "qpaintdevicedefs.h" ); +my @ignore_for_include_check = ( "qatomic.h" ); +my @ignore_for_qt_begin_header_check = ( "qiconset.h", "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qt_windows.h" ); +my @ignore_for_qt_begin_namespace_check = ( "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qatomic_arch.h", "qatomic_windowsce.h", "qt_windows.h", "qatomic_macosx.h" ); +my @ignore_for_qt_module_check = ( "$modules{QtCore}/arch", "$modules{QtCore}/global", "$modules{QtSql}/drivers", "$modules{QtTest}", "$modules{QtDesigner}", "$modules{QtUiTools}", "$modules{QtDBus}", "$modules{phonon}" ); +my %colliding_headers = (); +my %inject_headers; +# Force generation of forwarding header for qconfig.h if (and only if) we can't +# find the header by normal means. +%inject_headers = ( "$basedir/src/corelib/global" => ( "*qconfig.h" ) ) unless (-e "$basedir/src/corelib/global/qconfig.h"); + +foreach my $lib (@modules_to_sync) { + #iteration info + my $dir = $modules{$lib}; + my $pathtoheaders = ""; + $pathtoheaders = $moduleheaders{$lib} if ($moduleheaders{$lib}); + + #information used after the syncing + my $pri_install_classes = ""; + my $pri_install_files = ""; + my $pri_install_pfiles = ""; + + my $libcapitals = $lib; + $libcapitals =~ y/a-z/A-Z/; + my $master_contents = "#ifndef QT_".$libcapitals."_MODULE_H\n#define QT_".$libcapitals."_MODULE_H\n"; + + #get dependencies + if(-e "$dir/" . basename($dir) . ".pro") { + if(open(F, "<$dir/" . basename($dir) . ".pro")) { + while(my $line = ) { + chomp $line; + if($line =~ /^ *QT *\+?= *([^\r\n]*)/) { + foreach(split(/ /, $1)) { + $master_contents .= "#include \n" if($_ eq "core"); + $master_contents .= "#include \n" if($_ eq "gui"); + $master_contents .= "#include \n" if($_ eq "network"); + $master_contents .= "#include \n" if($_ eq "svg"); + $master_contents .= "#include \n" if($_ eq "declarative"); + $master_contents .= "#include \n" if($_ eq "script"); + $master_contents .= "#include \n" if($_ eq "scripttools"); + $master_contents .= "#include \n" if($_ eq "qt3support"); + $master_contents .= "#include \n" if($_ eq "sql"); + $master_contents .= "#include \n" if($_ eq "xml"); + $master_contents .= "#include \n" if($_ eq "xmlpatterns"); + $master_contents .= "#include \n" if($_ eq "opengl"); + $master_contents .= "#include \n" if($_ eq "openvg"); + } + } + } + close(F); + } + } + + #remove the old files + if($remove_stale) { + my @subdirs = ("$out_basedir/$out_subdir/$lib"); + foreach my $subdir (@subdirs) { + if (opendir DIR, $subdir) { + while(my $t = readdir(DIR)) { + my $file = "$subdir/$t"; + if(-d $file) { + push @subdirs, $file unless($t eq "." || $t eq ".."); + } else { + my @files = ($file); + #push @files, "$out_basedir/$out_subdir/Qt/$t" if(-e "$out_basedir/$out_subdir/Qt/$t"); + foreach my $file (@files) { + my $remove_file = 0; + if(open(F, "<$file")) { + while(my $line = ) { + chomp $line; + if($line =~ /^\#include \"([^\"]*)\"$/) { + my $include = $1; + $include = $subdir . "/" . $include unless(substr($include, 0, 1) eq "/"); + $remove_file = 1 unless(-e $include); + } else { + $remove_file = 0; + last; + } + } + close(F); + unlink $file if($remove_file); + } + } + } + } + closedir DIR; + } + + } + } + + #create the new ones + foreach my $current_dir (split(/;/, $dir)) { + my $headers_dir = $current_dir; + $headers_dir .= "/$pathtoheaders" if ($pathtoheaders); + #calc subdirs + my @subdirs = ($headers_dir); + foreach my $subdir (@subdirs) { + opendir DIR, $subdir or next; + while(my $t = readdir(DIR)) { + push @subdirs, "$subdir/$t" if(-d "$subdir/$t" && !($t eq ".") && + !($t eq "..") && !($t eq ".obj") && + !($t eq ".moc") && !($t eq ".rcc") && + !($t eq ".uic") && !($t eq "build")); + } + closedir DIR; + } + + #calc files and "copy" them + foreach my $subdir (@subdirs) { + my @headers = findFiles($subdir, "^[-a-z0-9_]*\\.h\$" , 0); + push @headers, $inject_headers{$subdir} if (defined $inject_headers{$subdir}); + foreach my $header (@headers) { + my $shadow = ($header =~ s/^\*//); + $header = 0 if($header =~ /^ui_.*.h/); + foreach (@ignore_headers) { + $header = 0 if($header eq $_); + } + if($header) { + my $header_copies = 0; + #figure out if it is a public header + my $public_header = $header; + if($public_header =~ /_p.h$/ || $public_header =~ /_pch.h$/) { + $public_header = 0; + } else { + foreach (@ignore_for_master_contents) { + $public_header = 0 if($header eq $_); + } + } + + my $iheader = $subdir . "/" . $header; + $iheader =~ s/^\Q$basedir\E/$out_basedir/ if ($shadow); + my @classes = $public_header ? classNames($iheader) : (); + if($showonly) { + print "$header [$lib]\n"; + foreach(@classes) { + print "SYMBOL: $_\n"; + } + } else { + my $ts = (stat($iheader))[9]; + #find out all the places it goes.. + my @headers; + if ($public_header) { + @headers = ( "$out_basedir/$out_subdir/$lib/$header" ); + + # write forwarding headers to include/Qt + if ($lib ne "phonon" && $subdir =~ /^$basedir\/src/) { + my $file_name = "$out_basedir/$out_subdir/Qt/$header"; + my $file_op = '>'; + my $header_content = ''; + if (exists $colliding_headers{$file_name}) { + $file_op = '>>'; + } else { + $colliding_headers{$file_name} = 1; + my $warning_msg = 'Inclusion of header files from include/Qt is deprecated.'; + $header_content = "#ifndef QT_NO_QT_INCLUDE_WARN\n" . + " #if defined(__GNUC__)\n" . + " #warning \"$warning_msg\"\n" . + " #elif defined(_MSC_VER)\n" . + " #pragma message(\"WARNING: $warning_msg\")\n" . + " #endif\n". + "#endif\n\n"; + } + $header_content .= '#include "' . "../$lib/$header" . "\"\n"; + open HEADERFILE, $file_op, $file_name or die "unable to open '$file_name' : $!\n"; + print HEADERFILE $header_content; + close HEADERFILE; + } + + foreach my $full_class (@classes) { + my $header_base = basename($header); + # Strip namespaces: + my $class = $full_class; + $class =~ s/^.*:://; +# if ($class =~ m/::/) { +# class =~ s,::,/,g; +# } + $class_lib_map_contents .= "QT_CLASS_LIB($full_class, $lib, $header_base)\n"; + $header_copies++ if(syncHeader("$out_basedir/$out_subdir/$lib/$class", "$out_basedir/$out_subdir/$lib/$header", 0, $ts)); + + # KDE-Compat headers for Phonon + if ($lib eq "phonon") { + $header_copies++ if (syncHeader("$out_basedir/$out_subdir/phonon_compat/Phonon/$class", "$out_basedir/$out_subdir/$lib/$header", 0, $ts)); + } + } + } elsif ($create_private_headers) { + @headers = ( "$out_basedir/$out_subdir/$lib/private/$header" ); + } + foreach(@headers) { #sync them + $header_copies++ if(syncHeader($_, $iheader, $copy_headers, $ts)); + } + + if($public_header) { + #put it into the master file + $master_contents .= "#include \"$public_header\"\n" if(shouldMasterInclude($iheader)); + + #deal with the install directives + if($public_header) { + my $pri_install_iheader = fixPaths($iheader, $current_dir); + foreach my $class (@classes) { + # Strip namespaces: + $class =~ s/^.*:://; +# if ($class =~ m/::/) { +# $class =~ s,::,/,g; +# } + my $class_header = fixPaths("$out_basedir/$out_subdir/$lib/$class", + $current_dir) . " "; + $pri_install_classes .= $class_header + unless($pri_install_classes =~ $class_header); + } + $pri_install_files.= "$pri_install_iheader ";; + } + } + else { + my $pri_install_iheader = fixPaths($iheader, $current_dir); + $pri_install_pfiles.= "$pri_install_iheader ";; + } + } + print "header created for $iheader ($header_copies)\n" if($header_copies > 0 && !$quiet); + } + } + } + } + + # close the master include: + $master_contents .= "#endif\n"; + + unless($showonly) { + my @master_includes; + push @master_includes, "$out_basedir/$out_subdir/$lib/$lib"; + push @master_includes, "$out_basedir/$out_subdir/phonon_compat/Phonon/Phonon" if ($lib eq "phonon"); + foreach my $master_include (@master_includes) { + #generate the "master" include file + my @tmp = split(/;/,$modules{$lib}); + $pri_install_files .= fixPaths($master_include, $tmp[0]) . " "; #get the master file installed too + if($master_include && -e $master_include) { + open MASTERINCLUDE, "<$master_include"; + local $/; + binmode MASTERINCLUDE; + my $oldmaster = ; + close MASTERINCLUDE; + $oldmaster =~ s/\r//g; # remove \r's , so comparison is ok on all platforms + $master_include = 0 if($oldmaster eq $master_contents); + } + if($master_include && $master_contents) { + my $master_dir = dirname($master_include); + mkpath $master_dir, !$quiet; + print "header (master) created for $lib\n" unless $quiet; + open MASTERINCLUDE, ">$master_include"; + print MASTERINCLUDE $master_contents; + close MASTERINCLUDE; + } + } + + #handle the headers.pri for each module + my $headers_pri_contents = ""; + $headers_pri_contents .= "SYNCQT.HEADER_FILES = $pri_install_files\n"; + $headers_pri_contents .= "SYNCQT.HEADER_CLASSES = $pri_install_classes\n"; + $headers_pri_contents .= "SYNCQT.PRIVATE_HEADER_FILES = $pri_install_pfiles\n"; + my $headers_pri_file = "$out_basedir/$out_subdir/$lib/headers.pri"; + if(-e $headers_pri_file) { + open HEADERS_PRI_FILE, "<$headers_pri_file"; + local $/; + binmode HEADERS_PRI_FILE; + my $old_headers_pri_contents = ; + close HEADERS_PRI_FILE; + $old_headers_pri_contents =~ s/\r//g; # remove \r's , so comparison is ok on all platforms + $headers_pri_file = 0 if($old_headers_pri_contents eq $headers_pri_contents); + } + if($headers_pri_file && $master_contents) { + my $headers_pri_dir = dirname($headers_pri_file); + mkpath $headers_pri_dir, !$quiet; + print "headers.pri file created for $lib\n" unless $quiet; + open HEADERS_PRI_FILE, ">$headers_pri_file"; + print HEADERS_PRI_FILE $headers_pri_contents; + close HEADERS_PRI_FILE; + } + } +} +unless($showonly || !$create_uic_class_map) { + my $class_lib_map = "$out_basedir/src/tools/uic/qclass_lib_map.h"; + if(-e $class_lib_map) { + open CLASS_LIB_MAP, "<$class_lib_map"; + local $/; + binmode CLASS_LIB_MAP; + my $old_class_lib_map_contents = ; + close CLASS_LIB_MAP; + $old_class_lib_map_contents =~ s/\r//g; # remove \r's , so comparison is ok on all platforms + $class_lib_map = 0 if($old_class_lib_map_contents eq $class_lib_map_contents); + } + if($class_lib_map) { + my $class_lib_map_dir = dirname($class_lib_map); + mkpath $class_lib_map_dir, !$quiet; + open CLASS_LIB_MAP, ">$class_lib_map"; + print CLASS_LIB_MAP $class_lib_map_contents; + close CLASS_LIB_MAP; + } +} + +if($check_includes) { + for my $lib (keys(%modules)) { + #calc subdirs + my @subdirs = ($modules{$lib}); + foreach my $subdir (@subdirs) { + opendir DIR, $subdir or die "Huh, directory ".$subdir." cannot be opened."; + while(my $t = readdir(DIR)) { + push @subdirs, "$subdir/$t" if(-d "$subdir/$t" && !($t eq ".") && + !($t eq "..") && !($t eq ".obj") && + !($t eq ".moc") && !($t eq ".rcc") && + !($t eq ".uic") && !($t eq "build")); + } + closedir DIR; + } + + foreach my $subdir (@subdirs) { + my $header_skip_qt_module_test = 0; + foreach(@ignore_for_qt_module_check) { + foreach (split(/;/, $_)) { + $header_skip_qt_module_test = 1 if ($subdir =~ /^$_/); + } + } + my @headers = findFiles($subdir, "^[-a-z0-9_]*\\.h\$" , 0); + foreach my $header (@headers) { + my $header_skip_qt_begin_header_test = 0; + my $header_skip_qt_begin_namespace_test = 0; + $header = 0 if($header =~ /^ui_.*.h/); + foreach (@ignore_headers) { + $header = 0 if($header eq $_); + } + if($header) { + my $public_header = $header; + if($public_header =~ /_p.h$/ || $public_header =~ /_pch.h$/) { + $public_header = 0; + } else { + foreach (@ignore_for_master_contents) { + $public_header = 0 if($header eq $_); + } + if($public_header) { + foreach (@ignore_for_include_check) { + $public_header = 0 if($header eq $_); + } + foreach(@ignore_for_qt_begin_header_check) { + $header_skip_qt_begin_header_test = 1 if ($header eq $_); + } + foreach(@ignore_for_qt_begin_namespace_check) { + $header_skip_qt_begin_namespace_test = 1 if ($header eq $_); + } + } + } + + my $iheader = $subdir . "/" . $header; + if($public_header) { + if(open(F, "<$iheader")) { + my $qt_module_found = 0; + my $qt_begin_header_found = 0; + my $qt_end_header_found = 0; + my $qt_begin_namespace_found = 0; + my $qt_end_namespace_found = 0; + my $line; + while($line = ) { + chomp $line; + my $output_line = 1; + if($line =~ /^ *\# *pragma (qt_no_included_check|qt_sync_stop_processing)/) { + last; + } elsif($line =~ /^ *\# *include/) { + my $include = $line; + if($line =~ /<.*>/) { + $include =~ s,.*<(.*)>.*,$1,; + } elsif($line =~ /".*"/) { + $include =~ s,.*"(.*)".*,$1,; + } else { + $include = 0; + } + if($include) { + for my $trylib (keys(%modules)) { + if(-e "$out_basedir/$out_subdir/$trylib/$include") { + print "WARNING: $iheader includes $include when it should include $trylib/$include\n"; + } + } + } + } elsif ($header_skip_qt_begin_header_test == 0 and $line =~ /^QT_BEGIN_HEADER\s*$/) { + $qt_begin_header_found = 1; + } elsif ($header_skip_qt_begin_header_test == 0 and $line =~ /^QT_END_HEADER\s*$/) { + $qt_end_header_found = 1; + } elsif ($header_skip_qt_begin_namespace_test == 0 and $line =~ /^QT_BEGIN_NAMESPACE\s*$/) { + $qt_begin_namespace_found = 1; + } elsif ($header_skip_qt_begin_namespace_test == 0 and $line =~ /^QT_END_NAMESPACE\s*$/) { + $qt_end_namespace_found = 1; + } elsif ($header_skip_qt_module_test == 0 and $line =~ /^QT_MODULE\(.*\)\s*$/) { + $qt_module_found = 1; + } + } + if ($header_skip_qt_begin_header_test == 0) { + if ($qt_begin_header_found == 0) { + print "WARNING: $iheader does not include QT_BEGIN_HEADER\n"; + } + + if ($qt_begin_header_found && $qt_end_header_found == 0) { + print "WARNING: $iheader has QT_BEGIN_HEADER but no QT_END_HEADER\n"; + } + } + + if ($header_skip_qt_begin_namespace_test == 0) { + if ($qt_begin_namespace_found == 0) { + print "WARNING: $iheader does not include QT_BEGIN_NAMESPACE\n"; + } + + if ($qt_begin_namespace_found && $qt_end_namespace_found == 0) { + print "WARNING: $iheader has QT_BEGIN_NAMESPACE but no QT_END_NAMESPACE\n"; + } + } + + if ($header_skip_qt_module_test == 0) { + if ($qt_module_found == 0) { + print "WARNING: $iheader does not include QT_MODULE\n"; + } + } + close(F); + } + } + } + } + } + } + } + +exit 0; diff --git a/config.profiles/symbian/implml/qt_copy.implml b/config.profiles/symbian/implml/qt_copy.implml new file mode 100644 index 0000000..53d600e --- /dev/null +++ b/config.profiles/symbian/implml/qt_copy.implml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/config.profiles/symbian/layers.sysdef.xml b/config.profiles/symbian/layers.sysdef.xml new file mode 100644 index 0000000..4c1b6f9 --- /dev/null +++ b/config.profiles/symbian/layers.sysdef.xml @@ -0,0 +1,41 @@ + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config.profiles/symbian/loc.prf b/config.profiles/symbian/loc.prf new file mode 100644 index 0000000..9973903 --- /dev/null +++ b/config.profiles/symbian/loc.prf @@ -0,0 +1,25 @@ + +qtPrepareTool(LRELEASE, lrelease) + +loc.CONFIG = no_link +loc.commands = $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} +loc.output = $${EPOCROOT}epoc32/data/z/resource/qt/translations/${QMAKE_FILE_BASE}.qm +loc.input = TRANSLATIONS +loc.variable_out = PRE_TARGETDEPS + +loc_winscwudeb.CONFIG = no_link +loc_winscwudeb.commands = $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} +loc_winscwudeb.output = $${EPOCROOT}epoc32/release/winscw/udeb/z/resource/qt/translations/${QMAKE_FILE_BASE}.qm +loc_winscwudeb.input = TRANSLATIONS +loc_winscwudeb.variable_out = PRE_TARGETDEPS + +loc_winscwurel.CONFIG = no_link +loc_winscwurel.commands = $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} +loc_winscwurel.output = $${EPOCROOT}epoc32/release/winscw/urel/z/resource/qt/translations/${QMAKE_FILE_BASE}.qm +loc_winscwurel.input = TRANSLATIONS +loc_winscwurel.variable_out = PRE_TARGETDEPS + +QMAKE_EXTRA_COMPILERS += loc +QMAKE_EXTRA_COMPILERS += loc_winscwudeb +QMAKE_EXTRA_COMPILERS += loc_winscwurel + diff --git a/config.profiles/symbian/non_foundation_paths.prf b/config.profiles/symbian/non_foundation_paths.prf new file mode 100644 index 0000000..8074ff7 --- /dev/null +++ b/config.profiles/symbian/non_foundation_paths.prf @@ -0,0 +1,115 @@ +# +# ============================================================================== +# Name : non_foundation_paths.prf +# Part of : +# Interface : None foundation code Path Definitions API for Qt/S60 +# Description : Symbian^3 and onwards specific platform paths +# +# Usage examples: +# +# Note: this file will not added automatically. It needs to be included +# when needed. +# +# Variable usages to add the system include paths +# +# The include paths has to be related to the layer in which your SW +# resides. Thus as an example: a component residing in middleware +# layer should use the MW specific macro. +# +# INCLUDEPATH += $$NON_FOUNDATION_APP_LAYER_SYSTEMINCLUDE +# INCLUDEPATH += $$NON_FOUNDATION_MW_LAYER_SYSTEMINCLUDE +# INCLUDEPATH += $$NON_FOUNDATION_OS_LAYER_SYSTEMINCLUDE +# INCLUDEPATH += $$NON_FOUNDATION_ADAPT_LAYER_SYSTEMINCLUDE +# +# Macros related to exporting non-foundation headers into +# correct place in the new system. +# NON_FOUNDATION_APP_LAYER_EXPORT_PATH +# NON_FOUNDATION_MW_LAYER_EXPORT_PATH +# NON_FOUNDATION_OS_LAYER_EXPORT_PATH +# NON_FOUNDATION_ADAPT_LAYER_EXPORT_PATH +# +# ============================================================================== + +# --------------------------------------- +# Location, where the non-foundation app code should export its headers. +# These are specific to app layer to which the non-foundation code belongs to. +# --------------------------------------- +defineReplace(NON_FOUNDATION_APP_LAYER_EXPORT_PATH) { + return (/epoc32/include/ext/app/$$1) +} + +# --------------------------------------- +# Location, where the non-foundation mw code should export its headers. +# These are specific to mw layer to which the non-foundation code belongs to. +# --------------------------------------- +defineReplace(NON_FOUNDATION_MW_LAYER_EXPORT_PATH) { + return (/epoc32/include/ext/mw/$$1) +} + +# --------------------------------------- +# Location, where the non-foundation os code should export its headers. +# These are specific to os layer to which the non-foundation code belongs to. +# --------------------------------------- +defineReplace(NON_FOUNDATION_OS_LAYER_EXPORT_PATH) { + return (/epoc32/include/ext/os/$$1) +} + +# --------------------------------------- +# Location, where the non-foundation adapt code should export its headers. +# These are specific to adapt layer to which the non-foundation code belongs to. +# --------------------------------------- +# Temporarily commented out to help adaptation side migration +# defineReplace(NON_FOUNDATION_ADAPT_LAYER_EXPORT_PATH) { +# return (/epoc32/include/ext/adapt/$$1) +# } + +# ************************************************************************** +# General comments about the 3 define statements related to include paths. +# It should be enough only to have one of the below macros and one of the include macros +# from platform_paths.hrh. +# No other systemincludes to epoc32/include or subdirectories. +# ************************************************************************** + +# This define statements defines the SYSTEMINCLUDE-line, which is intended to be +# used in the mmp-files that are part of the applications-layer. +# +# Applications layer is the last one in the list, since most likely the most of +# the headers come from middleware or os-layer => thus they are first. + +NON_FOUNDATION_APP_LAYER_SYSTEMINCLUDE = \ + /epoc32/include/ext/app \ + /epoc32/include/ext/mw \ + /epoc32/include/ext/os + +# This define statements defines the SYSTEMINCLUDE-line, which is intended to be +# used in the mmp-files that are part of the middleware-layer. + +NON_FOUNDATION_MW_LAYER_SYSTEMINCLUDE = \ + /epoc32/include/ext/mw \ + /epoc32/include/ext/os + +# This define statements defines the SYSTEMINCLUDE-line, which is intended to be +# used in the mmp-files that are part of the os-layer. + +NON_FOUNDATION_OS_LAYER_SYSTEMINCLUDE = \ + /epoc32/include/ext/os + +# This define statements defines the SYSTEMINCLUDE-line, which is intended to be +# used in the mmp-files that are part of the adapt-layer. +# Temporarily commented out to help adaptation side migration +# NON_FOUNDATION_ADAPT_LAYER_SYSTEMINCLUDE = \ +# /epoc32/include/ext/os \ +# /epoc32/include/ext/adapt + + +# **************************************************************************** +# Definitions to export IBY files to different folders where they will be taken +# to ROM image +# **************************************************************************** + +# Following three definitions are used for exporting IBY files to +# Core image (ROM+ROFS1). IBY files are exported according to their layer. + +defineReplace(NON_FOUNDATION_CORE_ADAPT_LAYER_IBY_EXPORT_PATH) { + return (/epoc32/rom/include/$$1) +} diff --git a/config.profiles/symbian/package_definition.xml b/config.profiles/symbian/package_definition.xml new file mode 100644 index 0000000..f0c6652 --- /dev/null +++ b/config.profiles/symbian/package_definition.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config.profiles/symbian/package_map.xml b/config.profiles/symbian/package_map.xml new file mode 100644 index 0000000..6233095 --- /dev/null +++ b/config.profiles/symbian/package_map.xml @@ -0,0 +1 @@ + diff --git a/config.profiles/symbian/platform_paths.prf b/config.profiles/symbian/platform_paths.prf new file mode 100644 index 0000000..0e2131f --- /dev/null +++ b/config.profiles/symbian/platform_paths.prf @@ -0,0 +1,251 @@ +# +# ============================================================================== +# Name : platform_paths.prf +# Part of : +# Interface : Platform Path Definitions API for Qt/S60 +# Description : Symbian^3 and onwards specific platform paths +# +# Usage examples: +# +# Note: this file gets automatically added to all Qt/S60 projects +# +# Variable usages to add the system include paths +# +# The include paths has to be related to the layer in which your SW +# resides. Thus as an example: a component residing in middleware +# layer should use the MW specific macro. +# +# INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE +# INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE +# INCLUDEPATH += $$OS_LAYER_SYSTEMINCLUDE +# +# If there is a need to include public headers of some S60 component, +# various *_EXPORT_PATH macros can be utilized: +# +# INCLUDEPATH += $$OS_LAYER_PUBLIC_EXPORT_PATH(somecomponent) +# +# Variables related to using various parts of stdapis: +# +# To use STLLIB you need to have this in your pro-file: +# +# QMAKE_CXXFLAGS.CW *= $$STLLIB_USAGE_CW_FLAGS +# DEFINES *= $$STLLIB_USAGE_DEFINES +# +# Depending on what module you are using from stdapis you need to have +# one or more of the following variables in your pro-file. +# +# INCLUDEPATH += $$OS_LAYER_LIBC_SYSTEMINCLUDE +# INCLUDEPATH += $$OS_LAYER_GLIB_SYSTEMINCLUDE +# INCLUDEPATH += $$OS_LAYER_SSL_SYSTEMINCLUDE +# INCLUDEPATH += $$OS_LAYER_STDCPP_SYSTEMINCLUDE +# INCLUDEPATH += $$OS_LAYER_BOOST_SYSTEMINCLUDE +# INCLUDEPATH += $$OS_LAYER_DBUS_SYSTEMINCLUDE +# INCLUDEPATH += $$OS_LAYER_LIBUTILITY_SYSTEMINCLUDE +# +# +# +# +# ============================================================================== + +# --------------------------------------- +# Location, where the applications layer specific public headers are exported +# --------------------------------------- + +defineReplace(APP_LAYER_SDK_EXPORT_PATH) { + return (/epoc32/include/app/$$1) +} +defineReplace(APP_LAYER_PUBLIC_EXPORT_PATH) { + return (/epoc32/include/app/$$1) +} + +# --------------------------------------- +# Location, where the applications layer specific platform headers are exported +# --------------------------------------- + +defineReplace(APP_LAYER_DOMAIN_EXPORT_PATH) { + return (/epoc32/include/platform/app/$$1) +} +defineReplace(APP_LAYER_PLATFORM_EXPORT_PATH) { + return (/epoc32/include/platform/app/$$1) +} + +# --------------------------------------- +# Location, where the middleware layer specific public headers are exported +# --------------------------------------- + +defineReplace(MW_LAYER_SDK_EXPORT_PATH) { + return (/epoc32/include/mw/$$1) +} +defineReplace(MW_LAYER_PUBLIC_EXPORT_PATH) { + return (/epoc32/include/mw/$$1) +} + +# --------------------------------------- +# Location, where the middleware layer specific platform headers are exported +# --------------------------------------- + +defineReplace(MW_LAYER_DOMAIN_EXPORT_PATH) { + return (/epoc32/include/platform/mw/$$1) +} +defineReplace(MW_LAYER_PLATFORM_EXPORT_PATH) { + return (/epoc32/include/platform/mw/$$1) +} + +# --------------------------------------- +# Location, where the os layer specific public headers are exported +# --------------------------------------- + +defineReplace(OSEXT_LAYER_SDK_EXPORT_PATH) { + return (/epoc32/include/$$1) +} +# WARNING: If the following path changes see the exists() function around line 219 +defineReplace(OS_LAYER_PUBLIC_EXPORT_PATH) { + return (/epoc32/include/$$1) +} + +# --------------------------------------- +# Location, where the os specific platform headers are exported +# --------------------------------------- + +defineReplace(OSEXT_LAYER_DOMAIN_EXPORT_PATH) { + return (/epoc32/include/platform/$$1) +} +defineReplace(OS_LAYER_PLATFORM_EXPORT_PATH) { + return (/epoc32/include/platform/$$1) +} + +# --------------------------------------- +# General comments about the 3 define statements related to include paths: +# 1) the /epoc32/include/oem is now defined there for backward compability. +# Once the directory is empty, the directory will be removed. However this +# enables us to ensure that if you use these define statements => you do +# not have to remove the statements later on, when the directory no longer +# exists. +# 2) These statements should be enough in normal cases. For certain specific +# cases you might need to add some specific directory from /epoc32/include +# (for instance /epoc32/include/ecom). +# In normal cases the include staments in code should be relative to one of +# the system include paths, but in certain cases, the included files requires +# that the subdirectory is also part of the system include paths. +# --------------------------------------- + +# This variable defines the include paths, which are intended to be +# used in the pro-files that are part of the applications-layer. It includes all +# the needed directories from the /epoc32/include, that are valid ones for the +# application-layer components. +# +# Applications layer is the last one in the list, since most likely the most of +# the headers come from middleware or os-layer => thus they are first. + +APP_LAYER_SYSTEMINCLUDE = \ + /epoc32/include \ + /epoc32/include/mw \ + /epoc32/include/platform/mw \ + /epoc32/include/platform \ + /epoc32/include/app \ + /epoc32/include/platform/app \ + /epoc32/include/platform/loc \ + /epoc32/include/platform/mw/loc \ + /epoc32/include/platform/app/loc \ + /epoc32/include/platform/loc/sc \ + /epoc32/include/platform/mw/loc/sc \ + /epoc32/include/platform/app/loc/sc + +# This define statements defines the include paths, which are intended to be +# used in the pro-files that are part of the middleware-layer. It includes all +# the needed directories from the /epoc32/include, that are valid ones for the +# middleware-layer components. + +MW_LAYER_SYSTEMINCLUDE = \ + /epoc32/include \ + /epoc32/include/mw \ + /epoc32/include/platform/mw \ + /epoc32/include/platform \ + /epoc32/include/platform/loc \ + /epoc32/include/platform/mw/loc \ + /epoc32/include/platform/loc/sc \ + /epoc32/include/platform/mw/loc/sc + +# This define statements defines the include paths, which are intended to be +# used in the pro-files that are part of the osextensions-layer. It includes all +# the needed directories from the /epoc32/include, that are valid ones for the +# os-layer components. + +OS_LAYER_SYSTEMINCLUDE = \ + /epoc32/include \ + /epoc32/include/platform \ + /epoc32/include/platform/loc \ + /epoc32/include/platform/loc/sc + +# This define statements defines the include paths, which are intended to be +# used in the pro-files that are part of the os-layer. This is intended +# to be only used by those components which need to use in their mmp-file either +# kern_ext.mmh or nkern_ext.mmh. Reason is that those +# 2 files already contain the /epoc32/include as system include path. + +OS_LAYER_KERNEL_SYSTEMINCLUDE = \ + /epoc32/include/platform + + +# --------------------------------------- +# Definitions that also define the systeminclude paths for various +# part of stdapis. Append to INCLUDEPATH in pro-file. +# --------------------------------------- + +OS_LAYER_LIBC_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis) \ + $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/sys) + +OS_LAYER_GLIB_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/glib-2.0) \ + $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/glib-2.0/glib) \ + $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/glib-2.0/gObject) + +OS_LAYER_SSL_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/openssl) + +# stlportv5 is preferred over stlport as it has the throwing version of operator new +exists($${EPOCROOT}epoc32/include/stdapis/stlport) \ +:!exists($${EPOCROOT}epoc32/include/stdapis/stlportv5) { + OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlport) +} else { + OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlportv5) +} + +OS_LAYER_BOOST_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/boost) + +OS_LAYER_DBUS_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/dbus-1.0) \ + $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/dbus-1.0/dbus) + +OS_LAYER_LIBUTILITY_SYSTEMINCLUDE = $$OS_LAYER_PLATFORM_EXPORT_PATH(stdapis/utility) + +# --------------------------------------- +# Definitions to export IBY files to different folders where they will be taken +# to ROM image +# --------------------------------------- + +defineReplace(CORE_APP_LAYER_IBY_EXPORT_PATH) { + return(/epoc32/rom/include/core/app/$$1) +} +defineReplace(CORE_MW_LAYER_IBY_EXPORT_PATH) { + return(/epoc32/rom/include/core/mw/$$1) +} +defineReplace(CORE_OSEXT_LAYER_IBY_EXPORT_PATH) { + return(/epoc32/rom/include/core/os/$$1) +} +defineReplace(CORE_OS_LAYER_IBY_EXPORT_PATH) { + return(/epoc32/rom/include/core/os/$$1) +} +defineReplace(CORE_TOOLS_LAYER_IBY_EXPORT_PATH) { + return(/epoc32/rom/include/core/tools/$$1) +} +defineReplace(CORE_ADAPT_LAYER_IBY_EXPORT_PATH) { + return(/epoc32/rom/include/$$1) +} +defineReplace(CUSTOMER_VARIANT_APP_LAYER_IBY_EXPORT_PATH) { + return(/epoc32/rom/include/customervariant/app/$$1) +} + +# You need to define the following in pro-file, if you are using the stllib: +# QMAKE_CXXFLAGS.CW *= $$STLLIB_USAGE_CW_FLAGS +# DEFINES *= $$STLLIB_USAGE_DEFINES +STLLIB_USAGE_CW_FLAGS = "-wchar_t on" +STLLIB_USAGE_DEFINES = _WCHAR_T_DECLARED + diff --git a/config.profiles/symbian/qt.conf b/config.profiles/symbian/qt.conf new file mode 100644 index 0000000..29dfa88 --- /dev/null +++ b/config.profiles/symbian/qt.conf @@ -0,0 +1,6 @@ +[Paths] +Data = $(EPOCROOT)epoc32/tools/qt +Headers = $(EPOCROOT)epoc32/include/mw +Binaries = $(EPOCROOT)epoc32/tools +Prefix = $(EPOCROOT)sf/mw/qt + diff --git a/config.profiles/symbian/qt.iby b/config.profiles/symbian/qt.iby new file mode 100644 index 0000000..2b3be0a --- /dev/null +++ b/config.profiles/symbian/qt.iby @@ -0,0 +1,118 @@ +#ifndef QT_IBY +#define QT_IBY + +#include + +#warning("qt.iby: hack - BINARY_SELECTION_ORDER really needs to be at the baseport/device level as it depends on the device type"); +BINARY_SELECTION_ORDER ARMV6,ARMV5 // hack - this really needs to be at the baseport/device level as it depends on the device type + +file=ABI_DIR\BUILD_DIR\QtCore.dll SHARED_LIB_DIR\QtCore.dll +file=ABI_DIR\BUILD_DIR\QtGui.dll SHARED_LIB_DIR\QtGui.dll +file=ABI_DIR\BUILD_DIR\QtOpenVG.dll SHARED_LIB_DIR\QtOpenVG.dll +file=ABI_DIR\BUILD_DIR\QtSvg.dll SHARED_LIB_DIR\QtSvg.dll +file=ABI_DIR\BUILD_DIR\QtSql.dll SHARED_LIB_DIR\QtSql.dll +file=ABI_DIR\BUILD_DIR\QtXml.dll SHARED_LIB_DIR\QtXml.dll +file=ABI_DIR\BUILD_DIR\QtNetwork.dll SHARED_LIB_DIR\QtNetwork.dll +file=ABI_DIR\BUILD_DIR\QtScript.dll SHARED_LIB_DIR\QtScript.dll +file=ABI_DIR\BUILD_DIR\QtTest.dll SHARED_LIB_DIR\QtTest.dll +file=ABI_DIR\BUILD_DIR\QtWebKit.dll SHARED_LIB_DIR\QtWebKit.dll +file=ABI_DIR\BUILD_DIR\phonon.dll SHARED_LIB_DIR\phonon.dll +file=ABI_DIR\BUILD_DIR\QtMultimedia.dll SHARED_LIB_DIR\QtMultimedia.dll +file=ABI_DIR\BUILD_DIR\QtXmlPatterns.dll SHARED_LIB_DIR\QtXmlPatterns.dll +file=ABI_DIR\BUILD_DIR\QtDeclarative.dll SHARED_LIB_DIR\QtDeclarative.dll +file=ABI_DIR\BUILD_DIR\QtOpenGL.dll SHARED_LIB_DIR\QtOpenGL.dll + +// imageformats +file=ABI_DIR\BUILD_DIR\qgif.dll SHARED_LIB_DIR\qgif.dll +file=ABI_DIR\BUILD_DIR\qico.dll SHARED_LIB_DIR\qico.dll +file=ABI_DIR\BUILD_DIR\qjpeg.dll SHARED_LIB_DIR\qjpeg.dll +file=ABI_DIR\BUILD_DIR\qmng.dll SHARED_LIB_DIR\qmng.dll +file=ABI_DIR\BUILD_DIR\qsvg.dll SHARED_LIB_DIR\qsvg.dll +file=ABI_DIR\BUILD_DIR\qtiff.dll SHARED_LIB_DIR\qtiff.dll + +// codecs +file=ABI_DIR\BUILD_DIR\qcncodecs.dll SHARED_LIB_DIR\qcncodecs.dll +file=ABI_DIR\BUILD_DIR\qjpcodecs.dll SHARED_LIB_DIR\qjpcodecs.dll +file=ABI_DIR\BUILD_DIR\qkrcodecs.dll SHARED_LIB_DIR\qkrcodecs.dll +file=ABI_DIR\BUILD_DIR\qtwcodecs.dll SHARED_LIB_DIR\qtwcodecs.dll + +// iconengines +file=ABI_DIR\BUILD_DIR\qsvgicon.dll SHARED_LIB_DIR\qsvgicon.dll + +// Phonon MMF backend +// This is commented out by default, as normally Helix backend will be used. +// If the Helix backend is present, it will override MMF backend, so make sure to remove it from +// image creation in addition to uncommenting the following lines if you want to use MMF backend. +//file=ABI_DIR\BUILD_DIR\phonon_mmf.dll SHARED_LIB_DIR\phonon_mmf.dll +//data=\epoc32\data\z\resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin + +// QtMultimedia audio backend +file=ABI_DIR\BUILD_DIR\qaudio.dll SHARED_LIB_DIR\qaudio.dll + +// graphicssystems +file=ABI_DIR\BUILD_DIR\qvggraphicssystem.dll SHARED_LIB_DIR\qvggraphicssystem.dll +file=ABI_DIR\BUILD_DIR\qglgraphicssystem.dll SHARED_LIB_DIR\qglgraphicssystem.dll + +// bearer +file=ABI_DIR\BUILD_DIR\qsymbianbearer.dll SHARED_LIB_DIR\qsymbianbearer.dll + +// S60 version compatibility plugins for 5.0 (3.1 and 3.2 devices are never likely to have this in ROM, +// so don't bother including those plugins +file=ABI_DIR\BUILD_DIR\qts60plugin_5_0.dll SHARED_LIB_DIR\qts60plugin_5_0.dll + +file=ABI_DIR\BUILD_DIR\qtactilefeedback.dll SHARED_LIB_DIR\qtactilefeedback.dll + +S60_APP_RESOURCE(s60main) + +// imageformats stubs +data=\epoc32\data\z\resource\qt\plugins\imageformats\qgif.qtplugin resource\qt\plugins\imageformats\qgif.qtplugin +data=\epoc32\data\z\resource\qt\plugins\imageformats\qico.qtplugin resource\qt\plugins\imageformats\qico.qtplugin +data=\epoc32\data\z\resource\qt\plugins\imageformats\qjpeg.qtplugin resource\qt\plugins\imageformats\qjpeg.qtplugin +data=\epoc32\data\z\resource\qt\plugins\imageformats\qmng.qtplugin resource\qt\plugins\imageformats\qmng.qtplugin +data=\epoc32\data\z\resource\qt\plugins\imageformats\qsvg.qtplugin resource\qt\plugins\imageformats\qsvg.qtplugin +data=\epoc32\data\z\resource\qt\plugins\imageformats\qtiff.qtplugin resource\qt\plugins\imageformats\qtiff.qtplugin + +// codecs stubs +data=\epoc32\data\z\resource\qt\plugins\codecs\qcncodecs.qtplugin resource\qt\plugins\codecs\qcncodecs.qtplugin +data=\epoc32\data\z\resource\qt\plugins\codecs\qjpcodecs.qtplugin resource\qt\plugins\codecs\qjpcodecs.qtplugin +data=\epoc32\data\z\resource\qt\plugins\codecs\qkrcodecs.qtplugin resource\qt\plugins\codecs\qkrcodecs.qtplugin +data=\epoc32\data\z\resource\qt\plugins\codecs\qtwcodecs.qtplugin resource\qt\plugins\codecs\qtwcodecs.qtplugin + +// iconengines stubs +data=\epoc32\data\z\resource\qt\plugins\iconengines\qsvgicon.qtplugin resource\qt\plugins\iconengines\qsvgicon.qtplugin + +// qml import plugins +file=ABI_DIR\BUILD_DIR\qmlwebkitplugin.dll SHARED_LIB_DIR\qmlwebkitplugin.dll +file=ABI_DIR\BUILD_DIR\qmlfolderlistmodelplugin.dll SHARED_LIB_DIR\qmlfolderlistmodelplugin.dll +file=ABI_DIR\BUILD_DIR\qmlgesturesplugin.dll SHARED_LIB_DIR\qmlgesturesplugin.dll +file=ABI_DIR\BUILD_DIR\qmlparticlesplugin.dll SHARED_LIB_DIR\qmlparticlesplugin.dll + +data=\epoc32\data\z\resource\qt\imports\QtWebKit\qmlwebkitplugin.qtplugin resource\qt\imports\QtWebKit\qmlwebkitplugin.qtplugin +data=\epoc32\data\z\resource\qt\imports\Qt\labs\folderlistmodel\qmlfolderlistmodelplugin.qtplugin resource\qt\imports\Qt\labs\folderlistmodel\qmlfolderlistmodelplugin.qtplugin +data=\epoc32\data\z\resource\qt\imports\Qt\labs\gestures\qmlgesturesplugin.qtplugin resource\qt\imports\Qt\labs\gestures\qmlgesturesplugin.qtplugin +data=\epoc32\data\z\resource\qt\imports\Qt\labs\particles\qmlparticlesplugin.qtplugin resource\qt\imports\Qt\labs\particles\qmlparticlesplugin.qtplugin + +data=\epoc32\data\z\resource\qt\imports\QtWebKit\qmldir resource\qt\imports\QtWebKit\qmldir +data=\epoc32\data\z\resource\qt\imports\Qt\labs\folderlistmodel\qmldir resource\qt\imports\Qt\labs\folderlistmodel\qmldir +data=\epoc32\data\z\resource\qt\imports\Qt\labs\gestures\qmldir resource\qt\imports\Qt\labs\gestures\qmldir +data=\epoc32\data\z\resource\qt\imports\Qt\labs\particles\qmldir resource\qt\imports\Qt\labs\particles\qmldir + +// QtMultimedia audio backend +data=\epoc32\data\qt\qtlibspluginstubs\qaudio.qtplugin resource\qt\plugins\audio\qaudio.qtplugin + +// graphicssystems +data=\epoc32\data\z\resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin +data=\epoc32\data\z\resource\qt\plugins\graphicssystems\qglgraphicssystem.qtplugin resource\qt\plugins\graphicssystems\qglgraphicssystem.qtplugin + +// bearer stub +data=\epoc32\data\z\resource\qt\plugins\bearer\qsymbianbearer.qtplugin resource\qt\plugins\bearer\qsymbianbearer.qtplugin + +// feedback +data=\epoc32\data\z\resource\qt\plugins\feedback\qtactilefeedback.qtplugin resource\qt\plugins\feedback\qtactilefeedback.qtplugin + +// Stub sis file +data=ZSYSTEM\install\qt_stub.sis System\Install\qt_stub.sis +data=ZSYSTEM\install\qtwebkit_stub.sis System\Install\qtwebkit_stub.sis + +#endif // __QT_IBY__ + diff --git a/config.profiles/symbian/qtconfig.flm b/config.profiles/symbian/qtconfig.flm new file mode 100644 index 0000000..61ee6e6 --- /dev/null +++ b/config.profiles/symbian/qtconfig.flm @@ -0,0 +1,88 @@ +# /**************************************************************************** +# ** +# ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +# ** Contact: +# ** +# ****************************************************************************/ + +# FLM to build Qt tools. + +QT_ROOT:= ../.. +TARGETDIR:=$(EPOCROOT)/$(INSTALLPATH) +MKSPECDIR:=$(EPOCROOT)/$(INSTALLPATH)/qt +SOURCEDIR:=$(EXTENSION_ROOT)/$(QT_ROOT)/bin +TOOLSSRCDIR:=$(EXTENSION_ROOT)/$(QT_ROOT)/src/tools +LANGUAGETOOLDIR:=$(EXTENSION_ROOT)/$(QT_ROOT)/tools/linguist +CONFIGURE_APP:=configure$(DOTEXE) + +$(call makepath,$(TARGETDIR)) + +ifneq ($(filter linux,$(HOSTPLATFORM)),) +PLATFORM:=$(PLATFORM.LINUX) +else +PLATFORM:=$(PLATFORM.WIN32) +endif + +TARGET_TOOLS:=$(TARGETDIR)/qmake$(DOTEXE) $(TARGETDIR)/moc$(DOTEXE) $(TARGETDIR)/rcc$(DOTEXE) $(TARGETDIR)/uic$(DOTEXE) $(TARGETDIR)/lrelease$(DOTEXE) +QT_TOOLS:= $(TOOLSSRCDIR)/uic $(TOOLSSRCDIR)/moc $(TOOLSSRCDIR)/rcc $(LANGUAGETOOLDIR)/lrelease +SOURCE_TOOLS:=$(SOURCEDIR)/qmake$(DOTEXE) $(SOURCEDIR)/moc$(DOTEXE) $(SOURCEDIR)/rcc$(DOTEXE) $(SOURCEDIR)/uic$(DOTEXE) $(SOURCEDIR)/lrelease$(DOTEXE) + +define QtConfiguration +ifneq ($(filter linux,$(HOSTPLATFORM)),) +$(TARGET_TOOLS): $(QT_TOOLS) +else +$(TARGET_TOOLS): $(SOURCEDIR)/qmake$(DOTEXE) +endif + $(call startrule,qtconf_deploy) \ + $(GNUCP) $(SOURCEDIR)/$$(notdir $$@) $$@ \ + $(call endrule,qtconf_deploy) + +ifneq ($(filter linux,$(HOSTPLATFORM)),) +$(QT_TOOLS): $(TOOLSSRCDIR)/bootstrap + $(call startrule,qtconf_tools_build) \ + cd $$@; \ + $(GNUMAKE38); \ + cd .. \ + $(call endrule,qtconf_tools_build) + +$(TOOLSSRCDIR)/bootstrap:$(SOURCEDIR)/qmake$(DOTEXE) + $(call startrule,qtconf_bootstrap_build) \ + cd $(TOOLSSRCDIR)/bootstrap; \ + $(GNUMAKE38); \ + cd .. \ + $(call endrule,qtconf_bootstrap_build) +endif + + +$(SOURCEDIR)/qmake$(DOTEXE): $(EXTENSION_ROOT)/$(QT_ROOT)/$(CONFIGURE_APP) + $(call startrule,qtconf) \ + cd $(EXTENSION_ROOT)/$(QT_ROOT) && unset INCLUDE && unset LIB && $(EXTENSION_ROOT)/$(QT_ROOT)/$(CONFIGURE_APP) -platform $(PLATFORM) -xplatform $(XPLATFORM) $(OPTIONS) \ + $(call endrule,qtconf) + $(call startrule,headerexport) \ + cd $(EXTENSION_ROOT)/$(QT_ROOT)/config.profiles/symbian && \ + perl headerexport -base-dir $(EXTENSION_ROOT)/$(QT_ROOT) -copy -oneway -outdir $(EPOCROOT)/epoc32/include/ -outsubdir mw + $(call endrule,headerexport) + $(call startrule,mkspecexport) \ + $(GNUCP) -R $(EXTENSION_ROOT)/$(QT_ROOT)/mkspecs $(MKSPECDIR) + $(call endrule,mkspecexport) +endef + +# Here a variable named "done_" gets created +GUARD:=done_$(call sanitise,$(TARGETDIR)/qmake$(DOTEXE)) +# If variable "done_..." not set, set it to 1, so that +# UREL and UDEB do not execute makesis twice on the same target +ifeq ($($(GUARD)),) +$(GUARD):=1 +ifneq ($(filter linux,$(HOSTPLATFORM)),) +EXPORT:: $(QT_TOOLS) $(TARGET_TOOLS) +else +EXPORT:: $(TARGET_TOOLS) +endif +$(eval $(call QtConfiguration)) +$(eval $(call whatmacro,$(TARGET_TOOLS))) +ifeq ($(OSTYPE),unix) +$(eval $(call GenerateStandardCleanTarget,$(QT_TOOLS) $(TARGET_TOOLS) $(SOURCE_TOOLS),$(TARGETDIR))) +else +$(eval $(call GenerateStandardCleanTarget,$(TARGET_TOOLS) $(SOURCE_TOOLS),$(TARGETDIR))) +endif +endif diff --git a/config.profiles/symbian/qtconfig.xml b/config.profiles/symbian/qtconfig.xml new file mode 100644 index 0000000..c2244d6 --- /dev/null +++ b/config.profiles/symbian/qtconfig.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + diff --git a/config.profiles/symbian/sysdef_1_5_1.dtd b/config.profiles/symbian/sysdef_1_5_1.dtd new file mode 100644 index 0000000..2defd21 --- /dev/null +++ b/config.profiles/symbian/sysdef_1_5_1.dtd @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config.profiles/symbian/translations/qt_ar.ts b/config.profiles/symbian/translations/qt_ar.ts new file mode 100644 index 0000000..f44dc98 --- /dev/null +++ b/config.profiles/symbian/translations/qt_ar.ts @@ -0,0 +1,7821 @@ + + + + + AudioOutput + + + <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> + + + + + <html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html> + + + + + Revert back to device '%1' + + + + + CloseButton + + + Close Tab + + + + + PPDOptionsModel + + Name + الإسم + + + + Phonon:: + + + Notifications + + + + + Music + + + + + Video + + + + + Communication + + + + + Games + + + + + Accessibility + + + + + Phonon::Gstreamer::Backend + + + Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. + Some video features have been disabled. + + + + + Warning: You do not seem to have the base GStreamer plugins installed. + All audio and video support has been disabled + + + + + Phonon::Gstreamer::MediaObject + + + Cannot start playback. + +Check your Gstreamer installation and make sure you +have libgstreamer-plugins-base installed. + + + + + A required codec is missing. You need to install the following codec(s) to play this content: %0 + + + + + + + + + + + + Could not open media source. + + + + + Invalid source type. + + + + + Could not locate media source. + + + + + Could not open audio device. The device is already in use. + + + + + Could not decode media source. + + + + + Phonon::VolumeSlider + + + + Volume: %1% + + + + + + + Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1% + + + + + Q3Accel + + + %1, %2 not defined + + + + + Ambiguous %1 not handled + + + + + Q3DataTable + + + True + صحيح + + + + False + خاطئ + + + + Insert + إدراج + + + + Update + تحديث + + + + Delete + حذف + + + + Q3FileDialog + + + Copy or Move a File + نسخ أو تحريك ملفّ + + + + Read: %1 + قراءة: %1 + + + + + Write: %1 + كتابة: %1 + + + + + Cancel + إلغاء + + + + + + + All Files (*) + جميع الملفّات (*) + + + + Name + الإسم + + + + Size + السّعة + + + + Type + الطّراز + + + + Date + التّاريخ + + + + Attributes + الخاصّيات + + + + + &OK + &موافقة + + + + Look &in: + بحث &في: + + + + + + File &name: + إ&سم الملفّ: + + + + File &type: + &طراز الملفّ: + + + + Back + رجوع + + + + One directory up + دليل للأعلى + + + + Create New Folder + صنع دليل جديد + + + + List View + معاينة بالقائمة + + + + Detail View + معاينة مفصّلة + + + + Preview File Info + عرض مقدّم لمعلومات الملفّ + + + + Preview File Contents + عرض مقدّم لمحتويات الملفّ + + + + Read-write + قراءة-كتابة + + + + Read-only + قراءة فقط + + + + Write-only + كتابة فقط + + + + Inaccessible + مستحيل التّوصّل إليه + + + + Symlink to File + وصل رمزي لملفّ + + + + Symlink to Directory + وصل رمزي لدليل + + + + Symlink to Special + وصل رمزي لملفّ خاصّ + + + + File + ملفّ + + + + Dir + دليل + + + + Special + ملفّ خاصّ + + + + + + Open + فتح + + + + + Save As + حفظ تحت + + + + + + &Open + &فتح + + + + + &Save + &حفظ + + + + &Rename + ت&غيير الإسم + + + + &Delete + ح&ذف + + + + R&eload + إ&عادة التّحميل + + + + Sort by &Name + فرز بال&إسم + + + + Sort by &Size + فرز بالسّ&عة + + + + Sort by &Date + فرز بالتّا&ريخ + + + + &Unsorted + غير &مفروز + + + + Sort + فرز + + + + Show &hidden files + ع&رض الملفّات المخفية + + + + the file + الملفّ + + + + the directory + الدّليل + + + + the symlink + الوصل الرّمزي + + + + Delete %1 + حذف %1 + + + + <qt>Are you sure you wish to delete %1 "%2"?</qt> + <qt>هل تريد فعلا حذف %1 "%2"؟</qt> + + + + &Yes + &نعم + + + + &No + &لا + + + + New Folder 1 + دليل جديد 1 + + + + New Folder + دليل جديد + + + + New Folder %1 + دليل جديد %1 + + + + Find Directory + إيجاد الدّليل + + + + + Directories + دلائل + + + + Directory: + دليل: + + + + + Error + خطأ + + + + %1 +File not found. +Check path and filename. + %1 +لم يتمّ إيجاد الملفّ. +تحقّق من المسار و إسم الملفّ. + + + + All Files (*.*) + جميع الملفّات (*.*) + + + + Open + فتح + + + + Select a Directory + انتقاء دليل + + + + Q3LocalFs + + + + Could not read directory +%1 + لم أستطع قراءة الدّليل +%1 + + + + Could not create directory +%1 + لم أستطع صنع الدّليل +%1 + + + + Could not remove file or directory +%1 + لم أستطع نزع الملفّ أو الدّليل +%1 + + + + Could not rename +%1 +to +%2 + لم أستطع إعادة تسمية +%1 +إلى +%2 + + + + Could not open +%1 + لم أستطع فتح +%1 + + + + Could not write +%1 + لم أستطع كتابة +%1 + + + + Q3MainWindow + + + Line up + تصفيف + + + + Customize... + تخصيص... + + + + Q3NetworkProtocol + + + Operation stopped by the user + أوقفت العمليّة من طرف المستعمل + + + + Q3ProgressDialog + + + + Cancel + إلغاء + + + + Q3TabDialog + + + + OK + موافقة + + + + Apply + تطبيق + + + + Help + مساعدة + + + + Defaults + افتراضيات + + + + Cancel + إلغاء + + + + Q3TextEdit + + + &Undo + &تراجع + + + + &Redo + إ&عادة + + + + Cu&t + &قصّ + + + + &Copy + &نسخ + + + + &Paste + ت&لصيق + + + + Clear + محو + + + + + Select All + انتقاء الجميع + + + + Q3TitleBar + + + System + + + + + Restore up + + + + + Minimize + تصغير + + + + Restore down + + + + + Maximize + تكبير + + + + Close + إغلاق + + + + Contains commands to manipulate the window + + + + + Puts a minimized back to normal + + + + + Moves the window out of the way + + + + + Puts a maximized window back to normal + + + + + Makes the window full screen + + + + + Closes the window + + + + + Displays the name of the window and contains controls to manipulate it + + + + + Q3ToolBar + + + More... + أكثر... + + + + Q3UrlOperator + + + + + The protocol `%1' is not supported + المراسم '%1' غير مدعومة + + + + The protocol `%1' does not support listing directories + المراسم '%1' لا تدعم وضع قوائم الدّلائل + + + + The protocol `%1' does not support creating new directories + المراسم '%1' لا تدعم صنع دلائل جديدة + + + + The protocol `%1' does not support removing files or directories + المراسم '%1' لا تدعم نزع الملفّات أو الدّلائل + + + + The protocol `%1' does not support renaming files or directories + المراسم '%1' لا تدعم إعادة تسمية الملفّات أو الدّلائل + + + + The protocol `%1' does not support getting files + المراسم '%1' لا تدعم استخلاص الملفّات + + + + The protocol `%1' does not support putting files + المراسم '%1' لا تدعم وضع الملفّات + + + + + The protocol `%1' does not support copying or moving files or directories + المراسم '%1' لا تدعم نسخ أو تحريك الملفّات أو الدّلائل + + + + + (unknown) + (مجهول) + + + + Q3Wizard + + + &Cancel + &إلغاء + + + + < &Back + < &رجوع + + + + &Next > + ال&تّالي > + + + + &Finish + إ&نهاء + + + + &Help + &مساعدة + + + + QAbstractSocket + + + + + + Host not found + + + + + + + Connection refused + رفض الوصل + + + + Connection timed out + + + + + + + Operation on socket is not supported + + + + + Socket operation timed out + + + + + Socket is not connected + + + + + Network unreachable + + + + + QAbstractSpinBox + + + &Step up + + + + + Step &down + + + + + &Select All + + + + + QApplication + + + QT_LAYOUT_DIRECTION + Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. + RTL + + + + Executable '%1' requires Qt %2, found Qt %3. + البرنامج '%1' يتطلّب Qt %2، تمّ إيجاد Qt %3. + + + + Incompatible Qt Library Error + خطأ: مكتبة Qt غير موافقة + + + + Activate + + + + + Activates the program's main window + + + + + QAxSelect + + + Select ActiveX Control + + + + + OK + موافقة + + + + &Cancel + &إلغاء + + + + COM &Object: + + + + + QCheckBox + + + Uncheck + + + + + Check + + + + + Toggle + + + + + QColorDialog + + + Hu&e: + ال&صّبغة: + + + + &Sat: + التّ&شبّع: + + + + &Val: + ال&قيمة: + + + + &Red: + أ&حمر: + + + + &Green: + أ&خضر: + + + + Bl&ue: + أ&زرق: + + + + A&lpha channel: + قناة أ&لفا: + + + + Select Color + + + + + &Basic colors + الألوان القا&عديّة + + + + &Custom colors + الأل&وان المخصّصة + + + &Define Custom Colors >> + تع&ريف الألوان المخصّصة >> + + + OK + موافقة + + + Cancel + إلغاء + + + + &Add to Custom Colors + الإ&ضافة إلى الألوان المخصّصة + + + Select color + إنتقاء اللّون + + + + QComboBox + + + + Open + فتح + + + + False + خاطئ + + + + True + صحيح + + + + Close + إغلاق + + + + QCoreApplication + + + %1: key is empty + QSystemSemaphore + + + + + %1: unable to make key + QSystemSemaphore + + + + + %1: ftok failed + QSystemSemaphore + + + + + QDB2Driver + + + Unable to connect + + + + + Unable to commit transaction + + + + + Unable to rollback transaction + + + + + Unable to set autocommit + + + + + QDB2Result + + + + Unable to execute statement + + + + + Unable to prepare statement + + + + + Unable to bind variable + + + + + Unable to fetch record %1 + + + + + Unable to fetch next + + + + + Unable to fetch first + + + + + QDateTimeEdit + + + AM + + + + + am + + + + + PM + + + + + pm + + + + + QDial + + + QDial + + + + + SpeedoMeter + + + + + SliderHandle + + + + + QDialog + + + What's This? + ما هذا؟ + + + + Done + + + + + QDialogButtonBox + + + + + OK + موافقة + + + + Save + حفظ + + + + &Save + &حفظ + + + + Open + فتح + + + + Cancel + إلغاء + + + + &Cancel + &إلغاء + + + + Close + إغلاق + + + + &Close + إ&غلاق + + + + Apply + تطبيق + + + + Reset + + + + + Help + مساعدة + + + + Don't Save + + + + + Discard + + + + + &Yes + &نعم + + + + Yes to &All + + + + + &No + &لا + + + + N&o to All + + + + + Save All + + + + + Abort + + + + + Retry + + + + + Ignore + + + + + Restore Defaults + + + + + Close without Saving + + + + + &OK + &موافقة + + + + QDirModel + + + Name + الإسم + + + + Size + السّعة + + + + Kind + Match OS X Finder + + + + + Type + All other platforms + الطّراز + + + + Date Modified + + + + + QDockWidget + + + Close + إغلاق + + + + Dock + + + + + Float + + + + + QDoubleSpinBox + + + More + + + + + Less + + + + + QErrorMessage + + + &Show this message again + أ&عرض مجدّداهذاالبلاغ + + + + &OK + &موافقة + + + + Debug Message: + بلاغ تصحيح الأخطاء: + + + + Warning: + إنذار: + + + + Fatal Error: + خطأ قاتل: + + + + QFile + + + + Destination file exists + + + + + Cannot remove source file + + + + + Cannot open %1 for input + + + + + Cannot open for output + + + + + Failure to write block + + + + + Cannot create %1 for output + + + + + QFileDialog + + + + All Files (*) + جميع الملفّات (*) + + + + + Back + رجوع + + + + + List View + معاينة بالقائمة + + + + + Detail View + معاينة مفصّلة + + + + + File + ملفّ + + + + Open + فتح + + + + Save As + حفظ تحت + + + + + + + &Open + &فتح + + + + + &Save + &حفظ + + + + Recent Places + + + + + &Rename + ت&غيير الإسم + + + + &Delete + ح&ذف + + + + Show &hidden files + ع&رض الملفّات المخفية + + + + New Folder + دليل جديد + + + + Find Directory + إيجاد الدّليل + + + + Directories + دلائل + + + + All Files (*.*) + جميع الملفّات (*.*) + + + + + Directory: + دليل: + + + + %1 already exists. +Do you want to replace it? + + + + + %1 +File not found. +Please verify the correct file name was given. + + + + + My Computer + + + + + + Parent Directory + + + + + + Files of type: + + + + + + %1 +Directory not found. +Please verify the correct directory name was given. + + + + + '%1' is write protected. +Do you want to delete it anyway? + + + + + Are sure you want to delete '%1'? + + + + + Could not delete directory. + + + + + Drive + + + + + Unknown + + + + + Show + + + + + + Forward + للأمام + + + + &New Folder + + + + + + &Choose + + + + + Remove + + + + + + File &name: + إ&سم الملفّ: + + + + + Look in: + + + + + + Create New Folder + صنع دليل جديد + + + + QFileSystemModel + + + %1 TB + + + + + %1 GB + + + + + %1 MB + + + + + %1 KB + + + + + %1 bytes + + + + + Invalid filename + + + + + <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. + + + + + Name + الإسم + + + + Size + السّعة + + + + Kind + Match OS X Finder + + + + + Type + All other platforms + الطّراز + + + + Date Modified + + + + + My Computer + + + + + Computer + + + + + QFontDatabase + + + + Normal + + + + + + + Bold + + + + + + Demi Bold + + + + + + + Black + + + + + Demi + + + + + + Light + + + + + + Italic + + + + + + Oblique + + + + + Any + + + + + Latin + + + + + Greek + + + + + Cyrillic + + + + + Armenian + + + + + Hebrew + + + + + Arabic + + + + + Syriac + + + + + Thaana + + + + + Devanagari + + + + + Bengali + + + + + Gurmukhi + + + + + Gujarati + + + + + Oriya + + + + + Tamil + + + + + Telugu + + + + + Kannada + + + + + Malayalam + + + + + Sinhala + + + + + Thai + + + + + Lao + + + + + Tibetan + + + + + Myanmar + + + + + Georgian + + + + + Khmer + + + + + Simplified Chinese + + + + + Traditional Chinese + + + + + Japanese + + + + + Korean + + + + + Vietnamese + + + + + Symbol + + + + + Ogham + + + + + Runic + + + + + QFontDialog + + + &Font + ال&خطّ + + + + Font st&yle + &طراز الخطّ + + + + &Size + ال&حجم + + + + Effects + تأثيرات + + + + Stri&keout + ت&شطيب + + + + &Underline + ت&سطير + + + + Sample + عيّنة + + + + + Select Font + انتقاء الخطّ + + + + Wr&iting System + + + + + QFtp + + + Host %1 found + تمّ إيجاد المضيف %1 + + + + Host found + تمّ إيجاد المضيف + + + + + + Connected to host %1 + تمّ وصل المضيف %1 + + + + Connected to host + تمّ وصل المضيف + + + + Connection to %1 closed + تمّ إغلاق الوصل بالمضيف %1 + + + + + + Connection closed + وصل مغلق + + + + + Host %1 not found + لم يتمّ إيجاد المضيف %1 + + + + + Connection refused to host %1 + رفض الوصل بالمضيف %1 + + + + Connection timed out to host %1 + + + + + + + + Unknown error + خطأ مجهول + + + + + Connecting to host failed: +%1 + فشل وصل المضيف: +%1 + + + + + Login failed: +%1 + فشل التّسجيل: +%1 + + + + + Listing directory failed: +%1 + فشلت عمليّة وضع قائمة للدّليل: +%1 + + + + + Changing directory failed: +%1 + فشلت عمليّة تغيير الدّليل: +%1 + + + + + Downloading file failed: +%1 + فشلت عمليّة تحميل الملفّ: +%1 + + + + + Uploading file failed: +%1 + فشلت عمليّة تحميل (بعث) الملفّ: +%1 + + + + + Removing file failed: +%1 + فشلت عمليّة نزع الملفّ: +%1 + + + + + Creating directory failed: +%1 + فشلت عمليّة صنع الدّليل: +%1 + + + + + Removing directory failed: +%1 + فشلت عمليّة نزع الدّليل: +%1 + + + + + Not connected + غير متصّل + + + + + Connection refused for data connection + رفض وصل المعطيات + + + + QHostInfo + + + Unknown error + خطأ مجهول + + + + QHostInfoAgent + + + + + + + + + + Host not found + + + + + + + + Unknown address type + + + + + + + Unknown error + خطأ مجهول + + + + QHttp + + + + Connection refused + رفض الوصل + + + + + + Host %1 not found + لم يتمّ إيجاد المضيف %1 + + + + + Wrong content length + طول المحتوى خاطئ + + + + HTTPS connection requested but SSL support not compiled in + + + + + + + + HTTP request failed + فشل طلب الHTTP + + + + Host %1 found + تمّ إيجاد المضيف %1 + + + + Host found + تمّ إيجاد المضيف + + + + Connected to host %1 + تمّ وصل المضيف %1 + + + + Connected to host + تمّ وصل المضيف + + + + Connection to %1 closed + تمّ إغلاق الوصل بالمضيف %1 + + + + + Connection closed + وصل مغلق + + + + + + + Unknown error + خطأ مجهول + + + + + Request aborted + تمّ إبطال الطّلب + + + + + No server set to connect to + ليس هناك أيّ خادم للوصل + + + + + Server closed connection unexpectedly + الخادم أغلق الوصل بصفة غير متوقّعة + + + + + Invalid HTTP response header + صديرة استجابة الHTTP غير صالحة + + + + Unknown authentication method + + + + + + + + Invalid HTTP chunked body + مقطع HTTP غير صالح + + + + Error writing response to device + + + + + Proxy authentication required + + + + + Authentication required + + + + + Connection refused (or timed out) + + + + + Proxy requires authentication + + + + + Host requires authentication + + + + + Data corrupted + + + + + Unknown protocol specified + + + + + SSL handshake failed + + + + + QHttpSocketEngine + + + Did not receive HTTP response from proxy + + + + + Error parsing authentication request from proxy + + + + + Authentication required + + + + + Proxy denied connection + + + + + Error communicating with HTTP proxy + + + + + Proxy server not found + + + + + Proxy connection refused + + + + + Proxy server connection timed out + + + + + Proxy connection closed prematurely + + + + + QIBaseDriver + + + Error opening database + + + + + Could not start transaction + + + + + Unable to commit transaction + + + + + Unable to rollback transaction + + + + + QIBaseResult + + + Unable to create BLOB + + + + + Unable to write BLOB + + + + + Unable to open BLOB + + + + + Unable to read BLOB + + + + + + Could not find array + + + + + Could not get array data + + + + + Could not get query info + + + + + Could not start transaction + + + + + Unable to commit transaction + + + + + Could not allocate statement + + + + + Could not prepare statement + + + + + + Could not describe input statement + + + + + Could not describe statement + + + + + Unable to close statement + + + + + Unable to execute query + + + + + Could not fetch next item + + + + + Could not get statement info + + + + + QIODevice + + + Permission denied + + + + + Too many open files + + + + + No such file or directory + + + + + No space left on device + + + + + Unknown error + خطأ مجهول + + + + QInputContext + + + XIM + + + + + XIM input method + + + + + Windows input method + + + + + Mac OS X input method + + + + + QInputDialog + + + Enter a value: + + + + + QLibrary + + + Could not mmap '%1': %2 + + + + + Plugin verification data mismatch in '%1' + + + + + Could not unmap '%1': %2 + + + + + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] + + + + + The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" + + + + + Unknown error + خطأ مجهول + + + + + The shared library was not found. + + + + + The file '%1' is not a valid Qt plugin. + + + + + The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) + + + + + + Cannot load library %1: %2 + + + + + + Cannot unload library %1: %2 + + + + + + Cannot resolve symbol "%1" in %2: %3 + + + + + QLineEdit + + + &Undo + &تراجع + + + + &Redo + إ&عادة + + + + Cu&t + &قصّ + + + + &Copy + &نسخ + + + + &Paste + ت&لصيق + + + + Select All + انتقاء الجميع + + + + Delete + حذف + + + + QLocalServer + + + + %1: Name error + + + + + %1: Permission denied + + + + + %1: Address in use + + + + + + %1: Unknown error %2 + + + + + QLocalSocket + + + + %1: Connection refused + + + + + + %1: Remote closed + + + + + + + + %1: Invalid name + + + + + + %1: Socket access error + + + + + + %1: Socket resource error + + + + + + %1: Socket operation timed out + + + + + + %1: Datagram too large + + + + + + + %1: Connection error + + + + + + %1: The socket operation is not supported + + + + + %1: Unknown error + + + + + + %1: Unknown error %2 + + + + + QMYSQLDriver + + + Unable to open database ' + + + + + Unable to connect + + + + + Unable to begin transaction + + + + + Unable to commit transaction + + + + + Unable to rollback transaction + + + + + QMYSQLResult + + + Unable to fetch data + + + + + Unable to execute query + + + + + Unable to store result + + + + + + Unable to prepare statement + + + + + Unable to reset statement + + + + + Unable to bind value + + + + + Unable to execute statement + + + + + + Unable to bind outvalues + + + + + Unable to store statement results + + + + + Unable to execute next query + + + + + Unable to store next result + + + + + QMdiArea + + + (Untitled) + + + + + QMdiSubWindow + + + %1 - [%2] + %1 - [%2] + + + + Close + إغلاق + + + + Minimize + تصغير + + + + Restore Down + استعاد في الأسفل + + + + &Restore + ا&ستعاد + + + + &Move + &تحريك + + + + &Size + ال&حجم + + + + Mi&nimize + ت&صغير + + + + Ma&ximize + ت&كبير + + + + Stay on &Top + ال&بقاء في الأمام + + + + &Close + إ&غلاق + + + + - [%1] + + + + + Maximize + تكبير + + + + Unshade + + + + + Shade + + + + + Restore + + + + + Help + مساعدة + + + + Menu + قائمة الخيارات + + + + QMenu + + + + Close + إغلاق + + + + + Open + فتح + + + + + + Execute + + + + + QMenuBar + + About + حول + + + Config + تشكيل + + + Preference + تفضيل + + + Options + خيارات + + + Setting + ضبط + + + Setup + إعداد + + + Quit + إنتهاء + + + Exit + خروج + + + + QMessageBox + + + + + + OK + موافقة + + + + About Qt + + + + + Help + مساعدة + + + + Show Details... + + + + + Hide Details... + + + + + <h3>About Qt</h3><p>This program uses Qt version %1.</p><p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://qt.nokia.com/">qt.nokia.com</a> for more information.</p> + + + + + QMultiInputContext + + + Select IM + + + + + QMultiInputContextPlugin + + + Multiple input method switcher + + + + + Multiple input method switcher that uses the context menu of the text widgets + + + + + QNativeSocketEngine + + + The remote host closed the connection + + + + + Network operation timed out + + + + + Out of resources + + + + + Unsupported socket operation + + + + + Protocol type not supported + + + + + Invalid socket descriptor + + + + + Network unreachable + + + + + Permission denied + + + + + Connection timed out + + + + + Connection refused + رفض الوصل + + + + The bound address is already in use + + + + + The address is not available + + + + + The address is protected + + + + + Unable to send a message + + + + + Unable to receive a message + + + + + Unable to write + + + + + Network error + + + + + Another socket is already listening on the same port + + + + + Unable to initialize non-blocking socket + + + + + Unable to initialize broadcast socket + + + + + Attempt to use IPv6 socket on a platform with no IPv6 support + + + + + Host unreachable + + + + + Datagram was too large to send + + + + + Operation on non-socket + + + + + Unknown error + خطأ مجهول + + + + The proxy type is invalid for this operation + + + + + QNetworkAccessCacheBackend + + + Error opening %1 + + + + + QNetworkAccessFileBackend + + + Request for opening non-local file %1 + + + + + Error opening %1: %2 + + + + + Write error writing to %1: %2 + + + + + Cannot open %1: Path is a directory + + + + + Read error reading from %1: %2 + + + + + QNetworkAccessFtpBackend + + + No suitable proxy found + + + + + Cannot open %1: is a directory + + + + + Logging in to %1 failed: authentication required + + + + + Error while downloading %1: %2 + + + + + Error while uploading %1: %2 + + + + + QNetworkAccessHttpBackend + + + No suitable proxy found + + + + + QNetworkReply + + + Error downloading %1 - server replied: %2 + + + + + Protocol "%1" is unknown + + + + + QNetworkReplyImpl + + + + Operation canceled + + + + + QOCIDriver + + + Unable to logon + + + + + Unable to initialize + QOCIDriver + + + + + Unable to begin transaction + + + + + Unable to commit transaction + + + + + Unable to rollback transaction + + + + + QOCIResult + + + + + Unable to bind column for batch execute + + + + + Unable to execute batch statement + + + + + Unable to goto next + + + + + Unable to alloc statement + + + + + Unable to prepare statement + + + + + Unable to bind value + + + + + Unable to execute statement + + + + + QODBCDriver + + + Unable to connect + + + + + Unable to connect - Driver doesn't support all needed functionality + + + + + Unable to disable autocommit + + + + + Unable to commit transaction + + + + + Unable to rollback transaction + + + + + Unable to enable autocommit + + + + + QODBCResult + + + + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration + + + + + + Unable to execute statement + + + + + Unable to fetch next + + + + + Unable to prepare statement + + + + + Unable to bind variable + + + + + + + Unable to fetch last + + + + + Unable to fetch + + + + + Unable to fetch first + + + + + Unable to fetch previous + + + + + QObject + + + Home + منزل + + + + Operation not supported on %1 + + + + + Invalid URI: %1 + + + + + Write error writing to %1: %2 + + + + + Read error reading from %1: %2 + + + + + Socket error on %1: %2 + + + + + Remote host closed the connection prematurely on %1 + + + + + Protocol error: packet of size 0 received + + + + + + No host name given + + + + + QPPDOptionsModel + + + Name + الإسم + + + + Value + + + + + QPSQLDriver + + + Unable to connect + + + + + Could not begin transaction + + + + + Could not commit transaction + + + + + Could not rollback transaction + + + + + Unable to subscribe + + + + + Unable to unsubscribe + + + + + QPSQLResult + + + Unable to create query + + + + + Unable to prepare statement + + + + + QPageSetupWidget + + + Centimeters (cm) + + + + + Millimeters (mm) + + + + + Inches (in) + + + + + Points (pt) + + + + + Form + + + + + Paper + + + + + Page size: + + + + + Width: + + + + + Height: + + + + + Paper source: + + + + + Orientation + + + + + Portrait + صورة + + + + Landscape + منظر + + + + Reverse landscape + + + + + Reverse portrait + + + + + Margins + + + + + top margin + + + + + left margin + + + + + right margin + + + + + bottom margin + + + + + QPluginLoader + + + Unknown error + خطأ مجهول + + + + The plugin was not loaded. + + + + + QPrintDialog + + + locally connected + موصل محليّا + + + + + Aliases: %1 + بدائل: %1 + + + + + unknown + مجهول + + + + OK + موافقة + + + Cancel + إلغاء + + + Print in color if available + طباعة بالألوان إن توفّرت + + + Printer + الطّابعة + + + + Print all + طباعة الجميع + + + + Print range + مدى الطّباعة + + + Print last page first + طباعة الصّفحة الخيرة أوّلا + + + Number of copies: + عدد النّسخ: + + + Paper format + مقاييس الورق + + + Portrait + صورة + + + Landscape + منظر + + + + A0 (841 x 1189 mm) + أ0 (841 × 1189 مم) + + + + A1 (594 x 841 mm) + أ1 (594 × 841 مم) + + + + A2 (420 x 594 mm) + أ2 (420 × 594 مم) + + + + A3 (297 x 420 mm) + أ3 (297 × 420 مم) + + + + A5 (148 x 210 mm) + أ5 (148 × 210 مم) + + + + A6 (105 x 148 mm) + أ6 (105 × 148 مم) + + + + A7 (74 x 105 mm) + أ7 (74 × 105 مم) + + + + A8 (52 x 74 mm) + أ8 (52 × 74 مم) + + + + A9 (37 x 52 mm) + أ9 (37 × 52 مم) + + + + B0 (1000 x 1414 mm) + ب0 (1000 × 1414 مم) + + + + B1 (707 x 1000 mm) + ب1 (707 × 1000 مم) + + + + B2 (500 x 707 mm) + ب2 (500 × 707 مم) + + + + B3 (353 x 500 mm) + ب3 (353 × 500 مم) + + + + B4 (250 x 353 mm) + ب4 (250 × 353 مم) + + + + B6 (125 x 176 mm) + ب6 (125 × 176 مم) + + + + B7 (88 x 125 mm) + ب7 (88 × 125 مم) + + + + B8 (62 x 88 mm) + ب4 (62 × 88 مم) + + + + B9 (44 x 62 mm) + ب9 (44 × 62 مم) + + + + B10 (31 x 44 mm) + ب10 (31 × 44 مم) + + + + C5E (163 x 229 mm) + سي5إي (163 × 229 مم) + + + + DLE (110 x 220 mm) + دي أل إي (110 × 220 مم) + + + + Folio (210 x 330 mm) + ملفّ (210 × 330 مم) + + + + Ledger (432 x 279 mm) + دفتر (432 × 279 مم) + + + + Tabloid (279 x 432 mm) + جريدة (279 × 432 مم) + + + + US Common #10 Envelope (105 x 241 mm) + غلاف رسالة أمريكية متداولة رقم 10 (105 × 241 مم) + + + + A4 (210 x 297 mm, 8.26 x 11.7 inches) + + + + + B5 (176 x 250 mm, 6.93 x 9.84 inches) + + + + + Executive (7.5 x 10 inches, 191 x 254 mm) + + + + + Legal (8.5 x 14 inches, 216 x 356 mm) + + + + + Letter (8.5 x 11 inches, 216 x 279 mm) + + + + + + + Print + طباعة + + + File + ملفّ + + + + Print To File ... + + + + + File %1 is not writable. +Please choose a different file name. + + + + + %1 already exists. +Do you want to overwrite it? + + + + + File exists + + + + + <qt>Do you want to overwrite it?</qt> + + + + + Print selection + + + + + %1 is a directory. +Please choose a different file name. + + + + + A0 + + + + + A1 + + + + + A2 + + + + + A3 + + + + + A4 + + + + + A5 + + + + + A6 + + + + + A7 + + + + + A8 + + + + + A9 + + + + + B0 + + + + + B1 + + + + + B2 + + + + + B3 + + + + + B4 + + + + + B5 + + + + + B6 + + + + + B7 + + + + + B8 + + + + + B9 + + + + + B10 + + + + + C5E + + + + + DLE + + + + + Executive + + + + + Folio + + + + + Ledger + + + + + Legal + + + + + Letter + + + + + Tabloid + + + + + US Common #10 Envelope + + + + + Custom + + + + + + &Options >> + + + + + &Print + + + + + &Options << + + + + + Print to File (PDF) + + + + + Print to File (Postscript) + + + + + Local file + + + + + Write %1 file + + + + + The 'From' value cannot be greater than the 'To' value. + + + + + QPrintPreviewDialog + + + + Page Setup + + + + + %1% + + + + + Print Preview + + + + + Next page + + + + + Previous page + + + + + First page + + + + + Last page + + + + + Fit width + + + + + Fit page + + + + + Zoom in + + + + + Zoom out + + + + + Portrait + صورة + + + + Landscape + منظر + + + + Show single page + + + + + Show facing pages + + + + + Show overview of all pages + + + + + Print + طباعة + + + + Page setup + + + + + Close + إغلاق + + + + Export to PDF + + + + + Export to PostScript + + + + + QPrintPropertiesDialog + + Save + حفظ + + + OK + موافقة + + + + QPrintPropertiesWidget + + + Form + + + + + Page + + + + + Advanced + + + + + QPrintSettingsOutput + + + Form + + + + + Copies + + + + + Print range + مدى الطّباعة + + + + Print all + طباعة الجميع + + + + Pages from + + + + + to + + + + + Selection + + + + + Output Settings + + + + + Copies: + + + + + Collate + + + + + Reverse + + + + + Options + خيارات + + + + Color Mode + + + + + Color + + + + + Grayscale + + + + + Duplex Printing + + + + + None + + + + + Long side + + + + + Short side + + + + + QPrintWidget + + + Form + + + + + Printer + الطّابعة + + + + &Name: + + + + + P&roperties + + + + + Location: + + + + + Preview + + + + + Type: + + + + + Output &file: + + + + + ... + + + + + QProcess + + + + Could not open input redirection for reading + + + + + + Could not open output redirection for writing + + + + + Resource error (fork failure): %1 + + + + + + + + + + + + + Process operation timed out + + + + + + + + Error reading from process + + + + + + + Error writing to process + + + + + Process crashed + + + + + No program defined + + + + + Process failed to start + + + + + QProgressDialog + + + Cancel + إلغاء + + + + QPushButton + + + Open + فتح + + + + QRadioButton + + + Check + + + + + QRegExp + + + no error occurred + لم يحدث هناك أيّ خطأ + + + + disabled feature used + تمّ استعمال خاصيّة التّوقيف + + + + bad char class syntax + خطأ نركيبي: صنف الرّمز + + + + bad lookahead syntax + خطأ تركيبي: النّظر إلى الأمام + + + + bad repetition syntax + خطأ نركيبي: تكرار + + + + invalid octal value + قيمة ثمانية غبر صالحة + + + + missing left delim + الفاصل الأيسر ناقص + + + + unexpected end + نهاية غير متوقّعة + + + + met internal limit + تمّ الوصول إلى الحدّ الدّاخلي + + + + QSQLite2Driver + + + Error to open database + + + + + Unable to begin transaction + + + + + Unable to commit transaction + + + + + Unable to rollback Transaction + + + + + QSQLite2Result + + + Unable to fetch results + + + + + Unable to execute statement + + + + + QSQLiteDriver + + + Error opening database + + + + + Error closing database + + + + + Unable to begin transaction + + + + + Unable to commit transaction + + + + + Unable to rollback transaction + + + + + QSQLiteResult + + + + + Unable to fetch row + + + + + Unable to execute statement + + + + + Unable to reset statement + + + + + Unable to bind parameters + + + + + Parameter count mismatch + + + + + No query + + + + + QScrollBar + + + Scroll here + + + + + Left edge + + + + + Top + + + + + Right edge + + + + + Bottom + + + + + Page left + + + + + + Page up + + + + + Page right + + + + + + Page down + + + + + Scroll left + + + + + Scroll up + + + + + Scroll right + + + + + Scroll down + + + + + Line up + تصفيف + + + + Position + + + + + Line down + + + + + QSharedMemory + + + %1: unable to set key on lock + + + + + %1: create size is less then 0 + + + + + + %1: unable to lock + + + + + %1: unable to unlock + + + + + + %1: permission denied + + + + + + %1: already exists + + + + + + %1: doesn't exists + + + + + + %1: out of resources + + + + + + %1: unknown error %2 + + + + + %1: key is empty + + + + + %1: unix key file doesn't exists + + + + + %1: ftok failed + + + + + + %1: unable to make key + + + + + %1: system-imposed size restrictions + + + + + %1: not attached + + + + + %1: invalid size + + + + + %1: key error + + + + + %1: size query failed + + + + + QShortcut + + + Space + فراغ + + + + Esc + إفلات + + + + Tab + جدولة + + + + Backtab + جدولة للوراء + + + + Backspace + فراغ للوراء + + + + Return + عودة + + + + Enter + إدخال + + + + Ins + إدراج + + + + Del + حذف + + + + Pause + وقف + + + + Print + طباعة + + + + SysReq + نظام + + + + Home + منزل + + + + End + نهاية + + + + Left + يسار + + + + Up + فوق + + + + Right + يمين + + + + Down + تحت + + + + PgUp + صفحة للفوق + + + + PgDown + صفحة للتحت + + + + CapsLock + إقفال الحروف الكبيرة + + + + NumLock + إقفال الأعداد + + + + ScrollLock + إقفال التّحريك + + + + Menu + قائمة الخيارات + + + + Help + مساعدة + + + + Back + رجوع + + + + Forward + للأمام + + + + Stop + توقّف + + + + Refresh + إنعاش + + + + Volume Down + تنقيص الصّوت + + + + Volume Mute + إغلاق الصّوت + + + + Volume Up + زيادة الصّوت + + + + Bass Boost + إنعاش الأصوات الجهورية + + + + Bass Up + زيادة الأصوات الجهورية + + + + Bass Down + تنقيص الأصوات الجهورية + + + + Treble Up + زيادة الأصوات الحادّة + + + + Treble Down + تنقيص الأصوات الحادّة + + + + Media Play + لعب الوسط + + + + Media Stop + توقيف الوسط + + + + Media Previous + الوسط الأسبق + + + + Media Next + الوسط التّالي + + + + Media Record + تسجيل الوسط + + + + Favorites + المفضّلات + + + + Search + بحث + + + + Standby + إنتظار + + + + Open URL + فتح الوصلة + + + + Launch Mail + بدأ البريد + + + + Launch Media + بدأ الوسط + + + + Launch (0) + بدأ (0) + + + + Launch (1) + بدأ (1) + + + + Launch (2) + بدأ (2) + + + + Launch (3) + بدأ (3) + + + + Launch (4) + بدأ (4) + + + + Launch (5) + بدأ (5) + + + + Launch (6) + بدأ (6) + + + + Launch (7) + بدأ (7) + + + + Launch (8) + بدأ (8) + + + + Launch (9) + بدأ (9) + + + + Launch (A) + بدأ (A) + + + + Launch (B) + بدأ (B) + + + + Launch (C) + بدأ (C) + + + + Launch (D) + بدأ (D) + + + + Launch (E) + بدأ (E) + + + + Launch (F) + بدأ (F) + + + + Print Screen + + + + + Page Up + + + + + Page Down + + + + + Caps Lock + + + + + Num Lock + + + + + Number Lock + + + + + Scroll Lock + + + + + Insert + إدراج + + + + Delete + حذف + + + + Escape + + + + + System Request + + + + + Select + + + + + Yes + نعم + + + + No + لا + + + + Context1 + + + + + Context2 + + + + + Context3 + + + + + Context4 + + + + + Call + + + + + Hangup + + + + + Flip + + + + + + Ctrl + تحكّم + + + + + Shift + إزاحة + + + + + Alt + تناوب + + + + + Meta + ما فوق + + + + + + + + + + + F%1 + F%1 + + + + Home Page + + + + + QSlider + + + Page left + + + + + Page up + + + + + Position + + + + + Page right + + + + + Page down + + + + + QSocks5SocketEngine + + + Connection to proxy refused + + + + + Connection to proxy closed prematurely + + + + + Proxy host not found + + + + + Connection to proxy timed out + + + + + Proxy authentication failed + + + + + Proxy authentication failed: %1 + + + + + SOCKS version 5 protocol error + + + + + General SOCKSv5 server failure + + + + + Connection not allowed by SOCKSv5 server + + + + + TTL expired + + + + + SOCKSv5 command not supported + + + + + Address type not supported + + + + + Unknown SOCKSv5 proxy error code 0x%1 + + + + + Network operation timed out + + + + + QSpinBox + + + More + + + + + Less + + + + + QSql + + + Delete + حذف + + + + Delete this record? + حذف هذاالتّسجيل؟ + + + + + + Yes + نعم + + + + + + No + لا + + + + Insert + إدراج + + + + Update + تحديث + + + + Save edits? + حفظ التّغييرات؟ + + + + Cancel + إلغاء + + + + Confirm + تأكيد + + + + Cancel your edits? + إلغاء التّغييرات؟ + + + + QSslSocket + + + Unable to write data: %1 + + + + + Error while reading: %1 + + + + + Error during SSL handshake: %1 + + + + + Error creating SSL context (%1) + + + + + Invalid or empty cipher list (%1) + + + + + Error creating SSL session, %1 + + + + + Error creating SSL session: %1 + + + + + Cannot provide a certificate with no key, %1 + + + + + Error loading local certificate, %1 + + + + + Error loading private key, %1 + + + + + Private key does not certificate public key, %1 + + + + + QSystemSemaphore + + + + %1: out of resources + + + + + + %1: permission denied + + + + + %1: already exists + + + + + %1: does not exist + + + + + + %1: unknown error %2 + + + + + QTDSDriver + + + Unable to open connection + + + + + Unable to use database + + + + + QTabBar + + + Scroll Left + + + + + Scroll Right + + + + + QTcpServer + + + Operation on socket is not supported + + + + + QTextControl + + + &Undo + &تراجع + + + + &Redo + إ&عادة + + + + Cu&t + &قصّ + + + + &Copy + &نسخ + + + + Copy &Link Location + + + + + &Paste + ت&لصيق + + + + Delete + حذف + + + + Select All + انتقاء الجميع + + + + QToolButton + + + + Press + + + + + + Open + فتح + + + + QUdpSocket + + + This platform does not support IPv6 + + + + + QUndoGroup + + + Undo + تراجع + + + + Redo + إعادة + + + + QUndoModel + + + <empty> + + + + + QUndoStack + + + Undo + تراجع + + + + Redo + إعادة + + + + QUnicodeControlCharacterMenu + + + LRM Left-to-right mark + + + + + RLM Right-to-left mark + + + + + ZWJ Zero width joiner + + + + + ZWNJ Zero width non-joiner + + + + + ZWSP Zero width space + + + + + LRE Start of left-to-right embedding + + + + + RLE Start of right-to-left embedding + + + + + LRO Start of left-to-right override + + + + + RLO Start of right-to-left override + + + + + PDF Pop directional formatting + + + + + Insert Unicode control character + + + + + QWebFrame + + + Request cancelled + + + + + Request blocked + + + + + Cannot show URL + + + + + Frame load interruped by policy change + + + + + Cannot show mimetype + + + + + File does not exist + + + + + QWebPage + + + Bad HTTP request + + + + + Submit + default label for Submit buttons in forms on web pages + + + + + Submit + Submit (input element) alt text for <input> elements with no alt, title, or value + + + + + Reset + default label for Reset buttons in forms on web pages + + + + + This is a searchable index. Enter search keywords: + text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' + + + + + Choose File + title for file button used in HTML forms + + + + + No file selected + text to display in file button used in HTML forms when no file is selected + + + + + Open in New Window + Open in New Window context menu item + + + + + Save Link... + Download Linked File context menu item + + + + + Copy Link + Copy Link context menu item + + + + + Open Image + Open Image in New Window context menu item + + + + + Save Image + Download Image context menu item + + + + + Copy Image + Copy Link context menu item + + + + + Open Frame + Open Frame in New Window context menu item + + + + + Copy + Copy context menu item + + + + + Go Back + Back context menu item + + + + + Go Forward + Forward context menu item + + + + + Stop + Stop context menu item + توقّف + + + + Reload + Reload context menu item + + + + + Cut + Cut context menu item + + + + + Paste + Paste context menu item + + + + + No Guesses Found + No Guesses Found context menu item + + + + + Ignore + Ignore Spelling context menu item + + + + + Add To Dictionary + Learn Spelling context menu item + + + + + Search The Web + Search The Web context menu item + + + + + Look Up In Dictionary + Look Up in Dictionary context menu item + + + + + Open Link + Open Link context menu item + + + + + Ignore + Ignore Grammar context menu item + + + + + Spelling + Spelling and Grammar context sub-menu item + + + + + Show Spelling and Grammar + menu item title + + + + + Hide Spelling and Grammar + menu item title + + + + + Check Spelling + Check spelling context menu item + + + + + Check Spelling While Typing + Check spelling while typing context menu item + + + + + Check Grammar With Spelling + Check grammar with spelling context menu item + + + + + Fonts + Font context sub-menu item + + + + + Bold + Bold context menu item + + + + + Italic + Italic context menu item + + + + + Underline + Underline context menu item + + + + + Outline + Outline context menu item + + + + + Direction + Writing direction context sub-menu item + + + + + Text Direction + Text direction context sub-menu item + + + + + Default + Default writing direction context menu item + + + + + LTR + Left to Right context menu item + + + + + RTL + Right to Left context menu item + + + + + Inspect + Inspect Element context menu item + + + + + No recent searches + Label for only item in menu that appears when clicking on the search field image, when no searches have been performed + + + + + Recent searches + label for first item in the menu that appears when clicking on the search field image, used as embedded menu title + + + + + Clear recent searches + menu item in Recent Searches menu that empties menu's contents + + + + + Unknown + Unknown filesize FTP directory listing item + + + + + %1 (%2x%3 pixels) + Title string for images + + + + + Web Inspector - %2 + + + + + Scroll here + + + + + Left edge + + + + + Top + + + + + Right edge + + + + + Bottom + + + + + Page left + + + + + Page up + + + + + Page right + + + + + Page down + + + + + Scroll left + + + + + Scroll up + + + + + Scroll right + + + + + Scroll down + + + + + %n file(s) + number of chosen file + + + + + + + JavaScript Alert - %1 + + + + + JavaScript Confirm - %1 + + + + + JavaScript Prompt - %1 + + + + + Move the cursor to the next character + + + + + Move the cursor to the previous character + + + + + Move the cursor to the next word + + + + + Move the cursor to the previous word + + + + + Move the cursor to the next line + + + + + Move the cursor to the previous line + + + + + Move the cursor to the start of the line + + + + + Move the cursor to the end of the line + + + + + Move the cursor to the start of the block + + + + + Move the cursor to the end of the block + + + + + Move the cursor to the start of the document + + + + + Move the cursor to the end of the document + + + + + Select all + + + + + Select to the next character + + + + + Select to the previous character + + + + + Select to the next word + + + + + Select to the previous word + + + + + Select to the next line + + + + + Select to the previous line + + + + + Select to the start of the line + + + + + Select to the end of the line + + + + + Select to the start of the block + + + + + Select to the end of the block + + + + + Select to the start of the document + + + + + Select to the end of the document + + + + + Delete to the start of the word + + + + + Delete to the end of the word + + + + + Insert a new paragraph + + + + + Insert a new line + + + + + QWhatsThisAction + + + What's This? + ما هذا؟ + + + + QWidget + + + * + + + + + QWizard + + + < &Back + < &رجوع + + + + &Finish + إ&نهاء + + + + &Help + &مساعدة + + + + Go Back + + + + + Continue + + + + + Commit + + + + + Done + + + + Quit + إنتهاء + + + + Help + مساعدة + + + + Cancel + إلغاء + + + + &Next + + + + + &Next > + ال&تّالي > + + + + QWorkspace + + + &Restore + ا&ستعاد + + + + &Move + &تحريك + + + + &Size + &حجم + + + + Mi&nimize + ت&صغير + + + + Ma&ximize + ت&كبير + + + + &Close + إ&غلاق + + + + Stay on &Top + ال&بقاء في الأمام + + + + + Sh&ade + ت&ظليل + + + + + %1 - [%2] + %1 - [%2] + + + + Minimize + تصغير + + + + Restore Down + استعاد في الأسفل + + + + Close + إغلاق + + + + &Unshade + إ&لغاء التّظليل + + + + QXml + + + no error occurred + لم يحدث هناك أيّ خطأ + + + + error triggered by consumer + أطلق الخطأ من طرف المستهلك + + + + unexpected end of file + نهاية غير متوقّعة للملفّ + + + + more than one document type definition + أكثر من تعريف لطراز الوثيقة + + + + error occurred while parsing element + حدث خطأ عند تحليل تركيب العنصر + + + + tag mismatch + عدم تطابق العلامة + + + + error occurred while parsing content + حدث خطأ عند تحليل تركيب المحتوى + + + + unexpected character + رمز غير متوقّع + + + + invalid name for processing instruction + إسم غير صالح لتعليمة المعالجة + + + + version expected while reading the XML declaration + الإصدار متوقّع عند قراءة إعلان الXML + + + + wrong value for standalone declaration + قيمة خاطئة لإعلان مستقلّ + + + + encoding declaration or standalone declaration expected while reading the XML declaration + إعلان التّرميز أو إعلان مستقلّ متوقّع عند قراءة إعلان الXML + + + + standalone declaration expected while reading the XML declaration + إعلان مستقلّ متوقّع عند قراءة إعلان الXML + + + + error occurred while parsing document type definition + حدث خطأ عند تحليل تركيب تعريف طراز الوثيقة + + + + letter is expected + حرف متوقّع + + + + error occurred while parsing comment + حدث خطأ عند تحليل تركيب التّعليق + + + + error occurred while parsing reference + حدث خطأ عند تحليل تركيب المرجع + + + + internal general entity reference not allowed in DTD + المرجع إلى كيان داخلي عامّ غير مسموح به في الDTD + + + + external parsed general entity reference not allowed in attribute value + المرجع إلى كيان خارجي عامّ معرب غير مسموح به في قيمة الخاصّية + + + + external parsed general entity reference not allowed in DTD + المرجع إلى كيان خارجي عامّ معرب غير مسموح به في الDTD + + + + unparsed entity reference in wrong context + مرجع إلى كيان غير معرب في سياق خاطئ + + + + recursive entities + كيانات معاودة + + + + error in the text declaration of an external entity + خطأ في التّعريف النّصّي لكيان خارجي + + + + QXmlStream + + + + Extra content at end of document. + + + + + Invalid entity value. + + + + + Invalid XML character. + + + + + Sequence ']]>' not allowed in content. + + + + + Namespace prefix '%1' not declared + + + + + Attribute redefined. + + + + + Unexpected character '%1' in public id literal. + + + + + Invalid XML version string. + + + + + Unsupported XML version. + + + + + %1 is an invalid encoding name. + + + + + Encoding %1 is unsupported + + + + + Standalone accepts only yes or no. + + + + + Invalid attribute in XML declaration. + + + + + Premature end of document. + + + + + Invalid document. + + + + + Expected + + + + + , but got ' + + + + + Unexpected ' + + + + + Expected character data. + + + + + Recursive entity detected. + + + + + Start tag expected. + + + + + XML declaration not at start of document. + + + + + NDATA in parameter entity declaration. + + + + + %1 is an invalid processing instruction name. + + + + + Invalid processing instruction name. + + + + + + + + Illegal namespace declaration. + + + + + Invalid XML name. + + + + + Opening and ending tag mismatch. + + + + + Reference to unparsed entity '%1'. + + + + + + + Entity '%1' not declared. + + + + + Reference to external entity '%1' in attribute value. + + + + + Invalid character reference. + + + + + + Encountered incorrectly encoded content. + + + + + The standalone pseudo attribute must appear after the encoding. + + + + + %1 is an invalid PUBLIC identifier. + + + + + QtXmlPatterns + + + An %1-attribute with value %2 has already been declared. + + + + + An %1-attribute must have a valid %2 as value, which %3 isn't. + + + + + Network timeout. + + + + + Element %1 can't be serialized because it appears outside the document element. + + + + + Attribute %1 can't be serialized because it appears at the top level. + + + + + Year %1 is invalid because it begins with %2. + + + + + Day %1 is outside the range %2..%3. + + + + + Month %1 is outside the range %2..%3. + + + + + Overflow: Can't represent date %1. + + + + + Day %1 is invalid for month %2. + + + + + Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; + + + + + Time %1:%2:%3.%4 is invalid. + + + + + Overflow: Date can't be represented. + + + + + + At least one component must be present. + + + + + At least one time component must appear after the %1-delimiter. + + + + + No operand in an integer division, %1, can be %2. + + + + + The first operand in an integer division, %1, cannot be infinity (%2). + + + + + The second operand in a division, %1, cannot be zero (%2). + + + + + %1 is not a valid value of type %2. + + + + + When casting to %1 from %2, the source value cannot be %3. + + + + + Integer division (%1) by zero (%2) is undefined. + + + + + Division (%1) by zero (%2) is undefined. + + + + + Modulus division (%1) by zero (%2) is undefined. + + + + + + Dividing a value of type %1 by %2 (not-a-number) is not allowed. + + + + + Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed. + + + + + Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed. + + + + + A value of type %1 cannot have an Effective Boolean Value. + + + + + Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values. + + + + + Value %1 of type %2 exceeds maximum (%3). + + + + + Value %1 of type %2 is below minimum (%3). + + + + + A value of type %1 must contain an even number of digits. The value %2 does not. + + + + + %1 is not valid as a value of type %2. + + + + + Operator %1 cannot be used on type %2. + + + + + Operator %1 cannot be used on atomic values of type %2 and %3. + + + + + The namespace URI in the name for a computed attribute cannot be %1. + + + + + The name for a computed attribute cannot have the namespace URI %1 with the local name %2. + + + + + Type error in cast, expected %1, received %2. + + + + + When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed. + + + + + No casting is possible with %1 as the target type. + + + + + It is not possible to cast from %1 to %2. + + + + + Casting to %1 is not possible because it is an abstract type, and can therefore never be instantiated. + + + + + It's not possible to cast the value %1 of type %2 to %3 + + + + + Failure when casting from %1 to %2: %3 + + + + + A comment cannot contain %1 + + + + + A comment cannot end with a %1. + + + + + No comparisons can be done involving the type %1. + + + + + Operator %1 is not available between atomic values of type %2 and %3. + + + + + An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place. + + + + + A library module cannot be evaluated directly. It must be imported from a main module. + + + + + No template by name %1 exists. + + + + + A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type. + + + + + A positional predicate must evaluate to a single numeric value. + + + + + The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, is %2 invalid. + + + + + %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. + + + + + The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. + + + + + The data of a processing instruction cannot contain the string %1 + + + + + No namespace binding exists for the prefix %1 + + + + + No namespace binding exists for the prefix %1 in %2 + + + + + + %1 is an invalid %2 + + + + + %1 takes at most %n argument(s). %2 is therefore invalid. + + + + + + + %1 requires at least %n argument(s). %2 is therefore invalid. + + + + + + + The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration. + + + + + The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + + + + + The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + + + + + %1 is not a valid XML 1.0 character. + + + + + The first argument to %1 cannot be of type %2. + + + + + If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same. + + + + + %1 was called. + + + + + %1 must be followed by %2 or %3, not at the end of the replacement string. + + + + + In the replacement string, %1 must be followed by at least one digit when not escaped. + + + + + In the replacement string, %1 can only be used to escape itself or %2, not %3 + + + + + %1 matches newline characters + + + + + %1 and %2 match the start and end of a line. + + + + + Matches are case insensitive + + + + + Whitespace characters are removed, except when they appear in character classes + + + + + %1 is an invalid regular expression pattern: %2 + + + + + %1 is an invalid flag for regular expressions. Valid flags are: + + + + + If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified. + + + + + It will not be possible to retrieve %1. + + + + + The root node of the second argument to function %1 must be a document node. %2 is not a document node. + + + + + The default collection is undefined + + + + + %1 cannot be retrieved + + + + + The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization). + + + + + A zone offset must be in the range %1..%2 inclusive. %3 is out of range. + + + + + %1 is not a whole number of minutes. + + + + + Required cardinality is %1; got cardinality %2. + + + + + The item %1 did not match the required type %2. + + + + + + %1 is an unknown schema type. + + + + + Only one %1 declaration can occur in the query prolog. + + + + + The initialization of variable %1 depends on itself + + + + + No variable by name %1 exists + + + + + The variable %1 is unused + + + + + Version %1 is not supported. The supported XQuery version is 1.0. + + + + + The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2. + + + + + No function with signature %1 is available + + + + + + A default namespace declaration must occur before function, variable, and option declarations. + + + + + Namespace declarations must occur before function, variable, and option declarations. + + + + + Module imports must occur before function, variable, and option declarations. + + + + + It is not possible to redeclare prefix %1. + + + + + Prefix %1 is already declared in the prolog. + + + + + The name of an option must have a prefix. There is no default namespace for options. + + + + + The Schema Import feature is not supported, and therefore %1 declarations cannot occur. + + + + + The target namespace of a %1 cannot be empty. + + + + + The module import feature is not supported + + + + + No value is available for the external variable by name %1. + + + + + A construct was encountered which only is allowed in XQuery. + + + + + A template by name %1 has already been declared. + + + + + The keyword %1 cannot occur with any other mode name. + + + + + The value of attribute %1 must of type %2, which %3 isn't. + + + + + The prefix %1 can not be bound. By default, it is already bound to the namespace %2. + + + + + A variable by name %1 has already been declared. + + + + + A stylesheet function must have a prefixed name. + + + + + The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) + + + + + The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. + + + + + The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2 + + + + + A function already exists with the signature %1. + + + + + No external functions are supported. All supported functions can be used directly, without first declaring them as external + + + + + An argument by name %1 has already been declared. Every argument name must be unique. + + + + + When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. + + + + + In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching. + + + + + In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching. + + + + + In an XSL-T pattern, function %1 cannot have a third argument. + + + + + In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. + + + + + In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can. + + + + + %1 is an invalid template mode name. + + + + + The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. + + + + + The Schema Validation Feature is not supported. Hence, %1-expressions may not be used. + + + + + None of the pragma expressions are supported. Therefore, a fallback expression must be present + + + + + Each name of a template parameter must be unique; %1 is duplicated. + + + + + The %1-axis is unsupported in XQuery + + + + + %1 is not a valid name for a processing-instruction. + + + + + %1 is not a valid numeric literal. + + + + + No function by name %1 is available. + + + + + The namespace URI cannot be the empty string when binding to a prefix, %1. + + + + + %1 is an invalid namespace URI. + + + + + It is not possible to bind to the prefix %1 + + + + + Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared). + + + + + Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared). + + + + + Two namespace declaration attributes have the same name: %1. + + + + + The namespace URI must be a constant and cannot use enclosed expressions. + + + + + An attribute by name %1 has already appeared on this element. + + + + + A direct element constructor is not well-formed. %1 is ended with %2. + + + + + The name %1 does not refer to any schema type. + + + + + %1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works. + + + + + %1 is not an atomic type. Casting is only possible to atomic types. + + + + + + %1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported. + + + + + The name of an extension expression must be in a namespace. + + + + + empty + + + + + zero or one + + + + + exactly one + + + + + one or more + + + + + zero or more + + + + + Required type is %1, but %2 was found. + + + + + Promoting %1 to %2 may cause loss of precision. + + + + + The focus is undefined. + + + + + It's not possible to add attributes after any other kind of node. + + + + + An attribute by name %1 has already been created. + + + + + Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported. + + + + + %1 is an unsupported encoding. + + + + + %1 contains octets which are disallowed in the requested encoding %2. + + + + + The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character. + + + + + Ambiguous rule match. + + + + + In a namespace constructor, the value for a namespace cannot be an empty string. + + + + + The prefix must be a valid %1, which %2 is not. + + + + + The prefix %1 cannot be bound. + + + + + Only the prefix %1 can be bound to %2 and vice versa. + + + + + Circularity detected + + + + + The parameter %1 is required, but no corresponding %2 is supplied. + + + + + The parameter %1 is passed, but no corresponding %2 exists. + + + + + The URI cannot have a fragment + + + + + Element %1 is not allowed at this location. + + + + + Text nodes are not allowed at this location. + + + + + Parse error: %1 + + + + + The value of the XSL-T version attribute must be a value of type %1, which %2 isn't. + + + + + Running an XSL-T 1.0 stylesheet with a 2.0 processor. + + + + + Unknown XSL-T attribute %1. + + + + + Attribute %1 and %2 are mutually exclusive. + + + + + In a simplified stylesheet module, attribute %1 must be present. + + + + + If element %1 has no attribute %2, it cannot have attribute %3 or %4. + + + + + Element %1 must have at least one of the attributes %2 or %3. + + + + + At least one mode must be specified in the %1-attribute on element %2. + + + + + Attribute %1 cannot appear on the element %2. Only the standard attributes can appear. + + + + + Attribute %1 cannot appear on the element %2. Only %3 is allowed, and the standard attributes. + + + + + Attribute %1 cannot appear on the element %2. Allowed is %3, %4, and the standard attributes. + + + + + Attribute %1 cannot appear on the element %2. Allowed is %3, and the standard attributes. + + + + + XSL-T attributes on XSL-T elements must be in the null namespace, not in the XSL-T namespace which %1 is. + + + + + The attribute %1 must appear on element %2. + + + + + The element with local name %1 does not exist in XSL-T. + + + + + Element %1 must come last. + + + + + At least one %1-element must occur before %2. + + + + + Only one %1-element can appear. + + + + + At least one %1-element must occur inside %2. + + + + + When attribute %1 is present on %2, a sequence constructor cannot be used. + + + + + Element %1 must have either a %2-attribute or a sequence constructor. + + + + + When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor. + + + + + Element %1 cannot have children. + + + + + Element %1 cannot have a sequence constructor. + + + + + + The attribute %1 cannot appear on %2, when it is a child of %3. + + + + + A parameter in a function cannot be declared to be a tunnel. + + + + + This processor is not Schema-aware and therefore %1 cannot be used. + + + + + Top level stylesheet elements must be in a non-null namespace, which %1 isn't. + + + + + The value for attribute %1 on element %2 must either be %3 or %4, not %5. + + + + + Attribute %1 cannot have the value %2. + + + + + The attribute %1 can only appear on the first %2 element. + + + + + At least one %1 element must appear as child of %2. + + + + + VolumeSlider + + + Muted + + + + + + Volume: %1% + + + + diff --git a/config.profiles/symbian/translations/qt_fa.ts b/config.profiles/symbian/translations/qt_fa.ts new file mode 100644 index 0000000..d876a9d --- /dev/null +++ b/config.profiles/symbian/translations/qt_fa.ts @@ -0,0 +1,8507 @@ + + + + + + CloseButton + + Close Tab + + + + + FakeReply + + Fake error ! + + + + Invalid URL + + + + + Phonon:: + + Notifications + + + + Music + + + + Video + + + + Communication + + + + Games + + + + Accessibility + + + + + Phonon::AudioOutput + + <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> + + + + <html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html> + + + + Revert back to device '%1' + + + + + Phonon::Gstreamer::Backend + + Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. + Some video features have been disabled. + + + + Warning: You do not seem to have the base GStreamer plugins installed. + All audio and video support has been disabled + + + + + Phonon::Gstreamer::MediaObject + + Cannot start playback. + +Check your GStreamer installation and make sure you +have libgstreamer-plugins-base installed. + + + + A required codec is missing. You need to install the following codec(s) to play this content: %0 + + + + Could not open media source. + + + + Invalid source type. + + + + Could not locate media source. + + + + Could not open audio device. The device is already in use. + + + + Could not decode media source. + + + + + Phonon::MMF + + Audio Output + + + + The audio output device + + + + No error + + + + Not found + + + + Out of memory + + + + Not supported + + + + Overflow + + + + Underflow + + + + Already exists + + + + Path not found + + + + In use + + + + Not ready + + + + Access denied + + + + Could not connect + + + + Disconnected + + + + Permission denied + + + + Insufficient bandwidth + + + + Network unavailable + + + + Network communication error + + + + Streaming not supported + + + + Server alert + + + + Invalid protocol + + + + Invalid URL + + + + Multicast error + + + + Proxy server error + + + + Proxy server not supported + + + + Audio output error + + + + Video output error + + + + Decoder error + + + + Audio or video components could not be played + + + + DRM error + + + + Unknown error (%1) + + + + + Phonon::MMF::AbstractMediaPlayer + + Not ready to play + + + + Error opening file + + + + Error opening URL + + + + Setting volume failed + + + + Playback complete + + + + + Phonon::MMF::AudioEqualizer + + %1 Hz + + + + + Phonon::MMF::AudioPlayer + + Getting position failed + + + + Opening clip failed + + + + + Phonon::MMF::EffectFactory + + Enabled + + + + + Phonon::MMF::EnvironmentalReverb + + Decay HF ratio (%) + + + + Decay time (ms) + + + + Density (%) + + + + Diffusion (%) + + + + Reflections delay (ms) + + + + Reflections level (mB) + + + + Reverb delay (ms) + + + + Reverb level (mB) + + + + Room HF level + + + + Room level (mB) + + + + + Phonon::MMF::MediaObject + + Error opening source: type not supported + + + + Error opening source: media type could not be determined + + + + + Phonon::MMF::StereoWidening + + Level (%) + + + + + Phonon::MMF::VideoPlayer + + Pause failed + + + + Seek failed + + + + Getting position failed + + + + Opening clip failed + + + + Buffering clip failed + + + + Video display error + + + + + Phonon::VolumeSlider + + Volume: %1% + + + + Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1% + + + + Muted + + + + + Q3Accel + + %1, %2 not defined + + + + Ambiguous %1 not handled + + + + + Q3DataTable + + True + + + + False + + + + Insert + + + + Update + + + + Delete + + + + + Q3FileDialog + + Copy or Move a File + + + + Read: %1 + + + + Write: %1 + + + + Cancel + + + + All Files (*) + + + + Name + + + + Size + + + + Type + + + + Date + + + + Attributes + + + + &OK + + + + Look &in: + + + + File &name: + + + + File &type: + + + + Back + + + + One directory up + + + + Create New Folder + + + + List View + + + + Detail View + + + + Preview File Info + + + + Preview File Contents + + + + Read-write + + + + Read-only + + + + Write-only + + + + Inaccessible + + + + Symlink to File + + + + Symlink to Directory + + + + Symlink to Special + + + + File + + + + Dir + + + + Special + + + + Open + + + + Save As + + + + &Open + + + + &Save + + + + &Rename + + + + &Delete + + + + R&eload + + + + Sort by &Name + + + + Sort by &Size + + + + Sort by &Date + + + + &Unsorted + + + + Sort + + + + Show &hidden files + + + + the file + + + + the directory + + + + the symlink + + + + Delete %1 + + + + <qt>Are you sure you wish to delete %1 "%2"?</qt> + + + + &Yes + + + + &No + + + + New Folder 1 + + + + New Folder + + + + New Folder %1 + + + + Find Directory + + + + Directories + + + + Directory: + + + + Error + + + + %1 +File not found. +Check path and filename. + + + + All Files (*.*) + + + + Open + + + + Select a Directory + + + + + Q3LocalFs + + Could not read directory +%1 + + + + Could not create directory +%1 + + + + Could not remove file or directory +%1 + + + + Could not rename +%1 +to +%2 + + + + Could not open +%1 + + + + Could not write +%1 + + + + + Q3MainWindow + + Line up + + + + Customize... + + + + + Q3NetworkProtocol + + Operation stopped by the user + + + + + Q3ProgressDialog + + Cancel + + + + + Q3TabDialog + + OK + + + + Apply + + + + Help + + + + Defaults + + + + Cancel + + + + + Q3TextEdit + + &Undo + + + + &Redo + + + + Cu&t + + + + &Copy + + + + &Paste + + + + Clear + + + + Select All + + + + + Q3TitleBar + + System + + + + Restore up + + + + Minimize + + + + Restore down + + + + Maximize + + + + Close + + + + Contains commands to manipulate the window + + + + Puts a minimized window back to normal + + + + Moves the window out of the way + + + + Puts a maximized window back to normal + + + + Makes the window full screen + + + + Closes the window + + + + Displays the name of the window and contains controls to manipulate it + + + + + Q3ToolBar + + More... + + + + + Q3UrlOperator + + The protocol `%1' is not supported + + + + The protocol `%1' does not support listing directories + + + + The protocol `%1' does not support creating new directories + + + + The protocol `%1' does not support removing files or directories + + + + The protocol `%1' does not support renaming files or directories + + + + The protocol `%1' does not support getting files + + + + The protocol `%1' does not support putting files + + + + The protocol `%1' does not support copying or moving files or directories + + + + (unknown) + + + + + Q3Wizard + + &Cancel + + + + < &Back + + + + &Next > + + + + &Finish + + + + &Help + + + + + QAbstractSocket + + Host not found + + + + Connection refused + + + + Connection timed out + + + + Operation on socket is not supported + + + + Socket operation timed out + + + + Socket is not connected + + + + Network unreachable + + + + + QAbstractSpinBox + + &Step up + + + + Step &down + + + + &Select All + + + + + QAccessibleButton + + Press + + + + + QApplication + + QT_LAYOUT_DIRECTION + Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. + RTL + + + Executable '%1' requires Qt %2, found Qt %3. + + + + Incompatible Qt Library Error + + + + Activate + + + + Activates the program's main window + + + + + QAxSelect + + Select ActiveX Control + + + + OK + + + + &Cancel + + + + COM &Object: + + + + + QCheckBox + + Uncheck + + + + Check + + + + Toggle + + + + + QColorDialog + + Hu&e: + Hu&e: + + + &Sat: + &Sat: + + + &Val: + &Val: + + + &Red: + &Red: + + + &Green: + + + + Bl&ue: + + + + A&lpha channel: + + + + Select Color + Select Color + + + &Basic colors + + + + &Custom colors + + + + &Add to Custom Colors + + + + + QComboBox + + Open + Open + + + False + False + + + True + True + + + Close + Close + + + + QCoreApplication + + %1: key is empty + QSystemSemaphore + %1: key is empty + + + %1: unable to make key + QSystemSemaphore + %1: unable to make key + + + %1: ftok failed + QSystemSemaphore + %1: ftok failed + + + %1: already exists + QSystemSemaphore + %1: already exists + + + %1: does not exist + QSystemSemaphore + %1: does not exist + + + %1: out of resources + QSystemSemaphore + %1: out of resources + + + %1: unknown error %2 + QSystemSemaphore + %1: unknown error %2 + + + + QDB2Driver + + Unable to connect + Unable to connect + + + Unable to commit transaction + Unable to commit transaction + + + Unable to rollback transaction + Unable to rollback transaction + + + Unable to set autocommit + Unable to set autocommit + + + + QDB2Result + + Unable to execute statement + Unable to execute statement + + + Unable to prepare statement + Unable to prepare statement + + + Unable to bind variable + Unable to bind variable + + + Unable to fetch record %1 + Unable to fetch record %1 + + + Unable to fetch next + Unable to fetch next + + + Unable to fetch first + Unable to fetch first + + + + QDateTimeEdit + + AM + AM + + + am + am + + + PM + PM + + + pm + pm + + + + QDial + + QDial + QDial + + + SpeedoMeter + SpeedoMeter + + + SliderHandle + SliderHandle + + + + QDialog + + What's This? + What's This? + + + Done + Done + + + + QDialogButtonBox + + OK + OK + + + Save + Save + + + &Save + &Save + + + Open + Open + + + Cancel + Cancel + + + &Cancel + &Cancel + + + Close + Close + + + &Close + &Close + + + Apply + Apply + + + Reset + Reset + + + Help + Help + + + Don't Save + Don't Save + + + Discard + Discard + + + &Yes + &Yes + + + Yes to &All + Yes to &All + + + &No + &No + + + N&o to All + N&o to All + + + Save All + Save All + + + Abort + Abort + + + Retry + Retry + + + Ignore + Ignore + + + Restore Defaults + Restore Defaults + + + Close without Saving + Close without Saving + + + &OK + &OK + + + + QDirModel + + Name + Name + + + Size + Size + + + Kind + Match OS X Finder + Kind + + + Type + All other platforms + Type + + + Date Modified + Date Modified + + + + QDockWidget + + Close + Close + + + Dock + Dock + + + Float + Float + + + + QDoubleSpinBox + + More + More + + + Less + Less + + + + QErrorMessage + + &Show this message again + &Show this message again + + + &OK + &OK + + + Debug Message: + Debug Message: + + + Warning: + Warning: + + + Fatal Error: + Fatal Error: + + + + QFile + + Destination file exists + Destination file exists + + + Will not rename sequential file using block copy + Will not rename sequential file using block copy + + + Cannot remove source file + Cannot remove source file + + + Cannot open %1 for input + Cannot open %1 for input + + + Cannot open for output + Cannot open for output + + + Failure to write block + Failure to write block + + + Cannot create %1 for output + Cannot create %1 for output + + + + QFileDialog + + All Files (*) + All Files (*) + + + Back + Back + + + List View + List View + + + Detail View + Detail View + + + File + File + + + Open + Open + + + Save As + Save As + + + &Open + &Open + + + &Save + &Save + + + Recent Places + Recent Places + + + &Rename + &Rename + + + &Delete + &Delete + + + Show &hidden files + Show &hidden files + + + New Folder + New Folder + + + Find Directory + Find Directory + + + Directories + Directories + + + All Files (*.*) + All Files (*.*) + + + Directory: + Directory: + + + %1 already exists. +Do you want to replace it? + %1 already exists. +Do you want to replace it? + + + %1 +File not found. +Please verify the correct file name was given. + %1 +File not found. +Please verify the correct file name was given. + + + My Computer + My Computer + + + Parent Directory + Parent Directory + + + Files of type: + Files of type: + + + %1 +Directory not found. +Please verify the correct directory name was given. + %1 +Directory not found. +Please verify the correct directory name was given. + + + '%1' is write protected. +Do you want to delete it anyway? + '%1' is write protected. +Do you want to delete it anyway? + + + Are sure you want to delete '%1'? + Are sure you want to delete '%1'? + + + Could not delete directory. + Could not delete directory. + + + Drive + Drive + + + File Folder + Match Windows Explorer + File Folder + + + Folder + All other platforms + Folder + + + Alias + Mac OS X Finder + Alias + + + Shortcut + All other platforms + Shortcut + + + Unknown + Unknown + + + Show + Show + + + Forward + Forward + + + &New Folder + &New Folder + + + &Choose + &Choose + + + Remove + Remove + + + File &name: + File &name: + + + Look in: + Look in: + + + Create New Folder + Create New Folder + + + + QFileSystemModel + + %1 TB + %1 TB + + + %1 GB + %1 GB + + + %1 MB + %1 MB + + + %1 KB + %1 KB + + + %1 bytes + %1 bytes + + + Invalid filename + Invalid filename + + + <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. + <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. + + + Name + Name + + + Size + Size + + + Kind + Match OS X Finder + Kind + + + Type + All other platforms + Type + + + Date Modified + Date Modified + + + My Computer + My Computer + + + Computer + Computer + + + %1 byte(s) + %1 byte(s) + + + + QFontDatabase + + Normal + Normal + + + Bold + Bold + + + Demi Bold + Demi Bold + + + Black + Black + + + Demi + Demi + + + Light + Light + + + Italic + Italic + + + Oblique + Oblique + + + Any + Any + + + Latin + Latin + + + Greek + Greek + + + Cyrillic + Cyrillic + + + Armenian + Armenian + + + Hebrew + Hebrew + + + Arabic + Arabic + + + Syriac + Syriac + + + Thaana + Thaana + + + Devanagari + Devanagari + + + Bengali + Bengali + + + Gurmukhi + Gurmukhi + + + Gujarati + Gujarati + + + Oriya + Oriya + + + Tamil + Tamil + + + Telugu + Telugu + + + Kannada + Kannada + + + Malayalam + Malayalam + + + Sinhala + Sinhala + + + Thai + Thai + + + Lao + Lao + + + Tibetan + Tibetan + + + Myanmar + Myanmar + + + Georgian + Georgian + + + Khmer + Khmer + + + Simplified Chinese + Simplified Chinese + + + Traditional Chinese + Traditional Chinese + + + Japanese + Japanese + + + Korean + Korean + + + Vietnamese + Vietnamese + + + Symbol + Symbol + + + Ogham + Ogham + + + Runic + Runic + + + N'Ko + N'Ko + + + + QFontDialog + + &Font + &Font + + + Font st&yle + Font st&yle + + + &Size + &Size + + + Effects + Effects + + + Stri&keout + Stri&keout + + + &Underline + &Underline + + + Sample + Sample + + + Select Font + Select Font + + + Wr&iting System + Wr&iting System + + + + QFtp + + Host %1 found + Host %1 found + + + Host found + Host found + + + Connected to host %1 + Connected to host %1 + + + Connected to host + Connected to host + + + Connection to %1 closed + Connection to %1 closed + + + Connection closed + Connection closed + + + Host %1 not found + Host %1 not found + + + Connection refused to host %1 + Connection refused to host %1 + + + Connection timed out to host %1 + Connection timed out to host %1 + + + Unknown error + Unknown error + + + Connecting to host failed: +%1 + Connecting to host failed: +%1 + + + Login failed: +%1 + Login failed: +%1 + + + Listing directory failed: +%1 + Listing directory failed: +%1 + + + Changing directory failed: +%1 + Changing directory failed: +%1 + + + Downloading file failed: +%1 + Downloading file failed: +%1 + + + Uploading file failed: +%1 + Uploading file failed: +%1 + + + Removing file failed: +%1 + Removing file failed: +%1 + + + Creating directory failed: +%1 + Creating directory failed: +%1 + + + Removing directory failed: +%1 + Removing directory failed: +%1 + + + Not connected + Not connected + + + Connection refused for data connection + Connection refused for data connection + + + + QHostInfo + + Unknown error + Unknown error + + + + QHostInfoAgent + + Host not found + Host not found + + + Unknown address type + Unknown address type + + + Unknown error + Unknown error + + + No host name given + No host name given + + + Invalid hostname + Invalid hostname + + + + QHttp + + Connection refused + Connection refused + + + Host %1 not found + Host %1 not found + + + Wrong content length + Wrong content length + + + HTTP request failed + HTTP request failed + + + Host %1 found + Host %1 found + + + Host found + Host found + + + Connected to host %1 + Connected to host %1 + + + Connected to host + Connected to host + + + Connection to %1 closed + Connection to %1 closed + + + Connection closed + Connection closed + + + Unknown error + Unknown error + + + Request aborted + Request aborted + + + No server set to connect to + No server set to connect to + + + Server closed connection unexpectedly + Server closed connection unexpectedly + + + Invalid HTTP response header + Invalid HTTP response header + + + Unknown authentication method + Unknown authentication method + + + Invalid HTTP chunked body + Invalid HTTP chunked body + + + Error writing response to device + Error writing response to device + + + Proxy authentication required + Proxy authentication required + + + Authentication required + Authentication required + + + Proxy requires authentication + Proxy requires authentication + + + Host requires authentication + Host requires authentication + + + Data corrupted + Data corrupted + + + SSL handshake failed + SSL handshake failed + + + Unknown protocol specified + Unknown protocol specified + + + Connection refused (or timed out) + Connection refused (or timed out) + + + HTTPS connection requested but SSL support not compiled in + HTTPS connection requested but SSL support not compiled in + + + + QHttpSocketEngine + + Did not receive HTTP response from proxy + Did not receive HTTP response from proxy + + + Error parsing authentication request from proxy + Error parsing authentication request from proxy + + + Authentication required + Authentication required + + + Proxy denied connection + Proxy denied connection + + + Error communicating with HTTP proxy + Error communicating with HTTP proxy + + + Proxy server not found + Proxy server not found + + + Proxy connection refused + Proxy connection refused + + + Proxy server connection timed out + Proxy server connection timed out + + + Proxy connection closed prematurely + Proxy connection closed prematurely + + + + QIBaseDriver + + Error opening database + Error opening database + + + Could not start transaction + Could not start transaction + + + Unable to commit transaction + Unable to commit transaction + + + Unable to rollback transaction + Unable to rollback transaction + + + + QIBaseResult + + Unable to create BLOB + Unable to create BLOB + + + Unable to write BLOB + Unable to write BLOB + + + Unable to open BLOB + Unable to open BLOB + + + Unable to read BLOB + Unable to read BLOB + + + Could not find array + Could not find array + + + Could not get array data + Could not get array data + + + Could not get query info + Could not get query info + + + Could not start transaction + Could not start transaction + + + Unable to commit transaction + Unable to commit transaction + + + Could not allocate statement + Could not allocate statement + + + Could not prepare statement + Could not prepare statement + + + Could not describe input statement + Could not describe input statement + + + Could not describe statement + Could not describe statement + + + Unable to close statement + Unable to close statement + + + Unable to execute query + Unable to execute query + + + Could not fetch next item + Could not fetch next item + + + Could not get statement info + Could not get statement info + + + + QIODevice + + Permission denied + Permission denied + + + Too many open files + Too many open files + + + No such file or directory + No such file or directory + + + No space left on device + No space left on device + + + Unknown error + Unknown error + + + + QInputContext + + XIM + XIM + + + FEP + FEP + + + XIM input method + XIM input method + + + Windows input method + Windows input method + + + Mac OS X input method + Mac OS X input method + + + S60 FEP input method + S60 FEP input method + + + + QInputDialog + + Enter a value: + Enter a value: + + + + QLibrary + + Could not mmap '%1': %2 + Could not mmap '%1': %2 + + + Plugin verification data mismatch in '%1' + Plugin verification data mismatch in '%1' + + + Could not unmap '%1': %2 + Could not unmap '%1': %2 + + + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] + + + The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" + The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" + + + Unknown error + Unknown error + + + The shared library was not found. + The shared library was not found. + + + The file '%1' is not a valid Qt plugin. + The file '%1' is not a valid Qt plugin. + + + The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) + The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) + + + Cannot load library %1: %2 + Cannot load library %1: %2 + + + Cannot unload library %1: %2 + Cannot unload library %1: %2 + + + Cannot resolve symbol "%1" in %2: %3 + Cannot resolve symbol "%1" in %2: %3 + + + + QLineEdit + + Select All + Select All + + + &Undo + &Undo + + + &Redo + &Redo + + + Cu&t + Cu&t + + + &Copy + &Copy + + + &Paste + &Paste + + + Delete + Delete + + + + QLocalServer + + %1: Name error + %1: Name error + + + %1: Permission denied + %1: Permission denied + + + %1: Address in use + %1: Address in use + + + %1: Unknown error %2 + %1: Unknown error %2 + + + + QLocalSocket + + %1: Connection refused + %1: Connection refused + + + %1: Remote closed + %1: Remote closed + + + %1: Invalid name + %1: Invalid name + + + %1: Socket access error + %1: Socket access error + + + %1: Socket resource error + %1: Socket resource error + + + %1: Socket operation timed out + %1: Socket operation timed out + + + %1: Datagram too large + %1: Datagram too large + + + %1: Connection error + %1: Connection error + + + %1: The socket operation is not supported + %1: The socket operation is not supported + + + %1: Unknown error + %1: Unknown error + + + %1: Unknown error %2 + %1: Unknown error %2 + + + + QMYSQLDriver + + Unable to open database ' + Unable to open database ' + + + Unable to connect + Unable to connect + + + Unable to begin transaction + Unable to begin transaction + + + Unable to commit transaction + Unable to commit transaction + + + Unable to rollback transaction + Unable to rollback transaction + + + + QMYSQLResult + + Unable to fetch data + Unable to fetch data + + + Unable to execute query + Unable to execute query + + + Unable to store result + Unable to store result + + + Unable to prepare statement + Unable to prepare statement + + + Unable to reset statement + Unable to reset statement + + + Unable to bind value + Unable to bind value + + + Unable to execute statement + Unable to execute statement + + + Unable to bind outvalues + Unable to bind outvalues + + + Unable to store statement results + Unable to store statement results + + + Unable to execute next query + Unable to execute next query + + + Unable to store next result + Unable to store next result + + + + QMdiArea + + (Untitled) + (Untitled) + + + + QMdiSubWindow + + %1 - [%2] + %1 - [%2] + + + Close + Close + + + Minimize + Minimize + + + Restore Down + Restore Down + + + &Restore + &Restore + + + &Move + &Move + + + &Size + &Size + + + Mi&nimize + Mi&nimize + + + Ma&ximize + Ma&ximize + + + Stay on &Top + Stay on &Top + + + &Close + &Close + + + Maximize + Maximize + + + Unshade + Unshade + + + Shade + Shade + + + Restore + Restore + + + Help + Help + + + Menu + Menu + + + - [%1] + - [%1] + + + + QMenu + + Close + Close + + + Open + Open + + + Execute + Execute + + + + QMenuBar + + Actions + Actions + + + + QMessageBox + + OK + OK + + + <h3>About Qt</h3><p>This program uses Qt version %1.</p> + <h3>About Qt</h3><p>This program uses Qt version %1.</p> + + + <p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p><p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://qt.nokia.com/">qt.nokia.com</a> for more information.</p> + <p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p><p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://qt.nokia.com/">qt.nokia.com</a> for more information.</p> + + + About Qt + About Qt + + + Help + Help + + + Show Details... + Show Details... + + + Hide Details... + Hide Details... + + + + QMultiInputContext + + Select IM + Select IM + + + + QMultiInputContextPlugin + + Multiple input method switcher + Multiple input method switcher + + + Multiple input method switcher that uses the context menu of the text widgets + Multiple input method switcher that uses the context menu of the text widgets + + + + QNativeSocketEngine + + The remote host closed the connection + The remote host closed the connection + + + Network operation timed out + Network operation timed out + + + Out of resources + Out of resources + + + Unsupported socket operation + Unsupported socket operation + + + Protocol type not supported + Protocol type not supported + + + Invalid socket descriptor + Invalid socket descriptor + + + Network unreachable + Network unreachable + + + Permission denied + Permission denied + + + Connection timed out + Connection timed out + + + Connection refused + Connection refused + + + The bound address is already in use + The bound address is already in use + + + The address is not available + The address is not available + + + The address is protected + The address is protected + + + Unable to send a message + Unable to send a message + + + Unable to receive a message + Unable to receive a message + + + Unable to write + Unable to write + + + Network error + Network error + + + Another socket is already listening on the same port + Another socket is already listening on the same port + + + Unable to initialize non-blocking socket + Unable to initialize non-blocking socket + + + Unable to initialize broadcast socket + Unable to initialize broadcast socket + + + Attempt to use IPv6 socket on a platform with no IPv6 support + Attempt to use IPv6 socket on a platform with no IPv6 support + + + Host unreachable + Host unreachable + + + Datagram was too large to send + Datagram was too large to send + + + Operation on non-socket + Operation on non-socket + + + Unknown error + Unknown error + + + The proxy type is invalid for this operation + The proxy type is invalid for this operation + + + + QNetworkAccessCacheBackend + + Error opening %1 + Error opening %1 + + + + QNetworkAccessDebugPipeBackend + + Write error writing to %1: %2 + Write error writing to %1: %2 + + + + QNetworkAccessFileBackend + + Request for opening non-local file %1 + Request for opening non-local file %1 + + + Error opening %1: %2 + Error opening %1: %2 + + + Write error writing to %1: %2 + Write error writing to %1: %2 + + + Cannot open %1: Path is a directory + Cannot open %1: Path is a directory + + + Read error reading from %1: %2 + Read error reading from %1: %2 + + + + QNetworkAccessFtpBackend + + No suitable proxy found + No suitable proxy found + + + Cannot open %1: is a directory + Cannot open %1: is a directory + + + Logging in to %1 failed: authentication required + Logging in to %1 failed: authentication required + + + Error while downloading %1: %2 + Error while downloading %1: %2 + + + Error while uploading %1: %2 + Error while uploading %1: %2 + + + + QNetworkAccessHttpBackend + + No suitable proxy found + No suitable proxy found + + + + QNetworkReply + + Error downloading %1 - server replied: %2 + Error downloading %1 - server replied: %2 + + + Protocol "%1" is unknown + Protocol "%1" is unknown + + + + QNetworkReplyImpl + + Operation canceled + Operation canceled + + + + QOCIDriver + + Unable to logon + Unable to logon + + + Unable to initialize + QOCIDriver + Unable to initialize + + + Unable to begin transaction + Unable to begin transaction + + + Unable to commit transaction + Unable to commit transaction + + + Unable to rollback transaction + Unable to rollback transaction + + + + QOCIResult + + Unable to bind column for batch execute + Unable to bind column for batch execute + + + Unable to execute batch statement + Unable to execute batch statement + + + Unable to goto next + Unable to goto next + + + Unable to alloc statement + Unable to alloc statement + + + Unable to prepare statement + Unable to prepare statement + + + Unable to get statement type + Unable to get statement type + + + Unable to bind value + Unable to bind value + + + Unable to execute statement + Unable to execute statement + + + + QODBCDriver + + Unable to connect + Unable to connect + + + Unable to disable autocommit + Unable to disable autocommit + + + Unable to commit transaction + Unable to commit transaction + + + Unable to rollback transaction + Unable to rollback transaction + + + Unable to enable autocommit + Unable to enable autocommit + + + Unable to connect - Driver doesn't support all functionality required + Unable to connect - Driver doesn't support all functionality required + + + + QODBCResult + + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration + + + Unable to execute statement + Unable to execute statement + + + Unable to fetch next + Unable to fetch next + + + Unable to prepare statement + Unable to prepare statement + + + Unable to bind variable + Unable to bind variable + + + Unable to fetch last + Unable to fetch last + + + Unable to fetch + Unable to fetch + + + Unable to fetch first + Unable to fetch first + + + Unable to fetch previous + Unable to fetch previous + + + + QObject + + Invalid hostname + Invalid hostname + + + Operation not supported on %1 + Operation not supported on %1 + + + Invalid URI: %1 + Invalid URI: %1 + + + Socket error on %1: %2 + Socket error on %1: %2 + + + Remote host closed the connection prematurely on %1 + Remote host closed the connection prematurely on %1 + + + No host name given + No host name given + + + + QPPDOptionsModel + + Name + Name + + + Value + Value + + + + QPSQLDriver + + Unable to connect + Unable to connect + + + Could not begin transaction + Could not begin transaction + + + Could not commit transaction + Could not commit transaction + + + Could not rollback transaction + Could not rollback transaction + + + Unable to subscribe + Unable to subscribe + + + Unable to unsubscribe + Unable to unsubscribe + + + + QPSQLResult + + Unable to create query + Unable to create query + + + Unable to prepare statement + Unable to prepare statement + + + + QPageSetupWidget + + Centimeters (cm) + Centimeters (cm) + + + Millimeters (mm) + Millimeters (mm) + + + Inches (in) + Inches (in) + + + Points (pt) + Points (pt) + + + Form + Form + + + Paper + Paper + + + Page size: + Page size: + + + Width: + Width: + + + Height: + Height: + + + Paper source: + Paper source: + + + Orientation + Orientation + + + Portrait + Portrait + + + Landscape + Landscape + + + Reverse landscape + Reverse landscape + + + Reverse portrait + Reverse portrait + + + Margins + Margins + + + top margin + top margin + + + left margin + left margin + + + right margin + right margin + + + bottom margin + bottom margin + + + + QPluginLoader + + Unknown error + Unknown error + + + The plugin was not loaded. + The plugin was not loaded. + + + + QPrintDialog + + locally connected + locally connected + + + Aliases: %1 + Aliases: %1 + + + unknown + unknown + + + OK + OK + + + Print all + Print all + + + Print range + Print range + + + A0 (841 x 1189 mm) + A0 (841 x 1189 mm) + + + A1 (594 x 841 mm) + A1 (594 x 841 mm) + + + A2 (420 x 594 mm) + A2 (420 x 594 mm) + + + A3 (297 x 420 mm) + A3 (297 x 420 mm) + + + A5 (148 x 210 mm) + A5 (148 x 210 mm) + + + A6 (105 x 148 mm) + A6 (105 x 148 mm) + + + A7 (74 x 105 mm) + A7 (74 x 105 mm) + + + A8 (52 x 74 mm) + A8 (52 x 74 mm) + + + A9 (37 x 52 mm) + A9 (37 x 52 mm) + + + B0 (1000 x 1414 mm) + B0 (1000 x 1414 mm) + + + B1 (707 x 1000 mm) + B1 (707 x 1000 mm) + + + B2 (500 x 707 mm) + B2 (500 x 707 mm) + + + B3 (353 x 500 mm) + B3 (353 x 500 mm) + + + B4 (250 x 353 mm) + B4 (250 x 353 mm) + + + B6 (125 x 176 mm) + B6 (125 x 176 mm) + + + B7 (88 x 125 mm) + B7 (88 x 125 mm) + + + B8 (62 x 88 mm) + B8 (62 x 88 mm) + + + B9 (44 x 62 mm) + B9 (44 x 62 mm) + + + B10 (31 x 44 mm) + B10 (31 x 44 mm) + + + C5E (163 x 229 mm) + C5E (163 x 229 mm) + + + DLE (110 x 220 mm) + DLE (110 x 220 mm) + + + Folio (210 x 330 mm) + Folio (210 x 330 mm) + + + Ledger (432 x 279 mm) + Ledger (432 x 279 mm) + + + Tabloid (279 x 432 mm) + Tabloid (279 x 432 mm) + + + US Common #10 Envelope (105 x 241 mm) + US Common #10 Envelope (105 x 241 mm) + + + A4 (210 x 297 mm, 8.26 x 11.7 inches) + A4 (210 x 297 mm, 8.26 x 11.7 inches) + + + B5 (176 x 250 mm, 6.93 x 9.84 inches) + B5 (176 x 250 mm, 6.93 x 9.84 inches) + + + Executive (7.5 x 10 inches, 191 x 254 mm) + Executive (7.5 x 10 inches, 191 x 254 mm) + + + Legal (8.5 x 14 inches, 216 x 356 mm) + Legal (8.5 x 14 inches, 216 x 356 mm) + + + Letter (8.5 x 11 inches, 216 x 279 mm) + Letter (8.5 x 11 inches, 216 x 279 mm) + + + Print selection + Print selection + + + Print + Print + + + Print To File ... + Print To File ... + + + File %1 is not writable. +Please choose a different file name. + File %1 is not writable. +Please choose a different file name. + + + %1 already exists. +Do you want to overwrite it? + %1 already exists. +Do you want to overwrite it? + + + File exists + File exists + + + <qt>Do you want to overwrite it?</qt> + <qt>Do you want to overwrite it?</qt> + + + %1 is a directory. +Please choose a different file name. + %1 is a directory. +Please choose a different file name. + + + The 'From' value cannot be greater than the 'To' value. + The 'From' value cannot be greater than the 'To' value. + + + A0 + A0 + + + A1 + A1 + + + A2 + A2 + + + A3 + A3 + + + A4 + A4 + + + A5 + A5 + + + A6 + A6 + + + A7 + A7 + + + A8 + A8 + + + A9 + A9 + + + B0 + B0 + + + B1 + B1 + + + B2 + B2 + + + B3 + B3 + + + B4 + B4 + + + B5 + B5 + + + B6 + B6 + + + B7 + B7 + + + B8 + B8 + + + B9 + B9 + + + B10 + B10 + + + C5E + C5E + + + DLE + DLE + + + Executive + Executive + + + Folio + Folio + + + Ledger + Ledger + + + Legal + Legal + + + Letter + Letter + + + Tabloid + Tabloid + + + US Common #10 Envelope + US Common #10 Envelope + + + Custom + Custom + + + &Options >> + &Options >> + + + &Options << + &Options << + + + Print to File (PDF) + Print to File (PDF) + + + Print to File (Postscript) + Print to File (Postscript) + + + Local file + Local file + + + Write %1 file + Write %1 file + + + &Print + &Print + + + + QPrintPreviewDialog + + %1% + %1% + + + Print Preview + Print Preview + + + Next page + Next page + + + Previous page + Previous page + + + First page + First page + + + Last page + Last page + + + Fit width + Fit width + + + Fit page + Fit page + + + Zoom in + Zoom in + + + Zoom out + Zoom out + + + Portrait + Portrait + + + Landscape + Landscape + + + Show single page + Show single page + + + Show facing pages + Show facing pages + + + Show overview of all pages + Show overview of all pages + + + Print + Print + + + Page setup + Page setup + + + Close + Close + + + Export to PDF + Export to PDF + + + Export to PostScript + Export to PostScript + + + Page Setup + Page Setup + + + + QPrintPropertiesWidget + + Form + Form + + + Page + Page + + + Advanced + Advanced + + + + QPrintSettingsOutput + + Form + Form + + + Copies + Copies + + + Print range + Print range + + + Print all + Print all + + + Pages from + Pages from + + + to + to + + + Selection + Selection + + + Output Settings + Output Settings + + + Copies: + Copies: + + + Collate + Collate + + + Reverse + Reverse + + + Options + Options + + + Color Mode + Color Mode + + + Color + Color + + + Grayscale + Grayscale + + + Duplex Printing + Duplex Printing + + + None + None + + + Long side + Long side + + + Short side + Short side + + + + QPrintWidget + + Form + Form + + + Printer + Printer + + + &Name: + &Name: + + + P&roperties + P&roperties + + + Location: + Location: + + + Preview + Preview + + + Type: + Type: + + + Output &file: + Output &file: + + + ... + ... + + + + QProcess + + Could not open input redirection for reading + Could not open input redirection for reading + + + Could not open output redirection for writing + Could not open output redirection for writing + + + Resource error (fork failure): %1 + Resource error (fork failure): %1 + + + Process operation timed out + Process operation timed out + + + Error reading from process + Error reading from process + + + Error writing to process + Error writing to process + + + Process crashed + Process crashed + + + No program defined + No program defined + + + Process failed to start: %1 + Process failed to start: %1 + + + + QProgressDialog + + Cancel + Cancel + + + + QPushButton + + Open + Open + + + + QRadioButton + + Check + Check + + + + QRegExp + + no error occurred + no error occurred + + + disabled feature used + disabled feature used + + + bad char class syntax + bad char class syntax + + + bad lookahead syntax + bad lookahead syntax + + + bad repetition syntax + bad repetition syntax + + + invalid octal value + invalid octal value + + + missing left delim + missing left delim + + + unexpected end + unexpected end + + + met internal limit + met internal limit + + + invalid interval + invalid interval + + + invalid category + invalid category + + + + QSQLite2Driver + + Error opening database + Error opening database + + + Unable to begin transaction + Unable to begin transaction + + + Unable to commit transaction + Unable to commit transaction + + + Unable to rollback transaction + Unable to rollback transaction + + + + QSQLite2Result + + Unable to fetch results + Unable to fetch results + + + Unable to execute statement + Unable to execute statement + + + + QSQLiteDriver + + Error opening database + Error opening database + + + Error closing database + Error closing database + + + Unable to begin transaction + Unable to begin transaction + + + Unable to commit transaction + Unable to commit transaction + + + Unable to rollback transaction + Unable to rollback transaction + + + + QSQLiteResult + + Unable to fetch row + Unable to fetch row + + + Unable to execute statement + Unable to execute statement + + + Unable to reset statement + Unable to reset statement + + + Unable to bind parameters + Unable to bind parameters + + + Parameter count mismatch + Parameter count mismatch + + + No query + No query + + + + QScriptBreakpointsModel + + ID + ID + + + Location + Location + + + Condition + Condition + + + Ignore-count + Ignore-count + + + Single-shot + Single-shot + + + Hit-count + Hit-count + + + + QScriptBreakpointsWidget + + New + New + + + Delete + Delete + + + + QScriptDebugger + + Go to Line + Go to Line + + + Line: + Line: + + + Interrupt + Interrupt + + + Shift+F5 + Shift+F5 + + + Continue + Continue + + + F5 + F5 + + + Step Into + Step Into + + + F11 + F11 + + + Step Over + Step Over + + + F10 + F10 + + + Step Out + Step Out + + + Shift+F11 + Shift+F11 + + + Run to Cursor + Run to Cursor + + + Ctrl+F10 + Ctrl+F10 + + + Run to New Script + Run to New Script + + + Toggle Breakpoint + Toggle Breakpoint + + + F9 + F9 + + + Clear Debug Output + Clear Debug Output + + + Clear Error Log + Clear Error Log + + + Clear Console + Clear Console + + + &Find in Script... + &Find in Script... + + + Ctrl+F + Ctrl+F + + + Find &Next + Find &Next + + + F3 + F3 + + + Find &Previous + Find &Previous + + + Shift+F3 + Shift+F3 + + + Ctrl+G + Ctrl+G + + + Debug + Debug + + + + QScriptDebuggerCodeFinderWidget + + Close + Close + + + Previous + Previous + + + Next + Next + + + Case Sensitive + Case Sensitive + + + Whole words + Whole words + + + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;Search wrapped + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;Search wrapped + + + + QScriptDebuggerLocalsModel + + Name + Name + + + Value + Value + + + + QScriptDebuggerStackModel + + Level + Level + + + Name + Name + + + Location + Location + + + + QScriptEdit + + Toggle Breakpoint + Toggle Breakpoint + + + Disable Breakpoint + Disable Breakpoint + + + Enable Breakpoint + Enable Breakpoint + + + Breakpoint Condition: + Breakpoint Condition: + + + + QScriptEngineDebugger + + Loaded Scripts + Loaded Scripts + + + Breakpoints + Breakpoints + + + Stack + Stack + + + Locals + Locals + + + Console + Console + + + Debug Output + Debug Output + + + Error Log + Error Log + + + Search + Search + + + View + View + + + Qt Script Debugger + Qt Script Debugger + + + + QScriptNewBreakpointWidget + + Close + Close + + + + QScrollBar + + Scroll here + Scroll here + + + Left edge + Left edge + + + Top + Top + + + Right edge + Right edge + + + Bottom + Bottom + + + Page left + Page left + + + Page up + Page up + + + Page right + Page right + + + Page down + Page down + + + Scroll left + Scroll left + + + Scroll up + Scroll up + + + Scroll right + Scroll right + + + Scroll down + Scroll down + + + Line up + Line up + + + Position + Position + + + Line down + Line down + + + + QSharedMemory + + %1: create size is less then 0 + %1: create size is less then 0 + + + %1: unable to lock + %1: unable to lock + + + %1: unable to unlock + %1: unable to unlock + + + %1: permission denied + %1: permission denied + + + %1: already exists + %1: already exists + + + %1: doesn't exists + %1: doesn't exists + + + %1: out of resources + %1: out of resources + + + %1: unknown error %2 + %1: unknown error %2 + + + %1: key is empty + %1: key is empty + + + %1: ftok failed + %1: ftok failed + + + %1: unable to make key + %1: unable to make key + + + %1: doesn't exist + %1: doesn't exist + + + %1: UNIX key file doesn't exist + %1: UNIX key file doesn't exist + + + %1: system-imposed size restrictions + %1: system-imposed size restrictions + + + %1: not attached + %1: not attached + + + %1: invalid size + %1: invalid size + + + %1: key error + %1: key error + + + %1: size query failed + %1: size query failed + + + %1: unable to set key on lock + %1: unable to set key on lock + + + + QShortcut + + Space + Space + + + Esc + Esc + + + Tab + Tab + + + Backtab + Backtab + + + Backspace + Backspace + + + Return + Return + + + Enter + Enter + + + Ins + Ins + + + Del + Del + + + Pause + Pause + + + Print + Print + + + SysReq + SysReq + + + Home + Home + + + End + End + + + Left + Left + + + Up + Up + + + Right + Right + + + Down + Down + + + PgUp + PgUp + + + PgDown + PgDown + + + CapsLock + CapsLock + + + NumLock + NumLock + + + ScrollLock + ScrollLock + + + Menu + Menu + + + Help + Help + + + Back + Back + + + Forward + Forward + + + Stop + Stop + + + Refresh + Refresh + + + Volume Down + Volume Down + + + Volume Mute + Volume Mute + + + Volume Up + Volume Up + + + Bass Boost + Bass Boost + + + Bass Up + Bass Up + + + Bass Down + Bass Down + + + Treble Up + Treble Up + + + Treble Down + Treble Down + + + Media Play + Media Play + + + Media Stop + Media Stop + + + Media Previous + Media Previous + + + Media Next + Media Next + + + Media Record + Media Record + + + Favorites + Favorites + + + Search + Search + + + Standby + Standby + + + Open URL + Open URL + + + Launch Mail + Launch Mail + + + Launch Media + Launch Media + + + Launch (0) + Launch (0) + + + Launch (1) + Launch (1) + + + Launch (2) + Launch (2) + + + Launch (3) + Launch (3) + + + Launch (4) + Launch (4) + + + Launch (5) + Launch (5) + + + Launch (6) + Launch (6) + + + Launch (7) + Launch (7) + + + Launch (8) + Launch (8) + + + Launch (9) + Launch (9) + + + Launch (A) + Launch (A) + + + Launch (B) + Launch (B) + + + Launch (C) + Launch (C) + + + Launch (D) + Launch (D) + + + Launch (E) + Launch (E) + + + Launch (F) + Launch (F) + + + Monitor Brightness Up + Monitor Brightness Up + + + Monitor Brightness Down + Monitor Brightness Down + + + Keyboard Light On/Off + Keyboard Light On/Off + + + Keyboard Brightness Up + Keyboard Brightness Up + + + Keyboard Brightness Down + Keyboard Brightness Down + + + Power Off + Power Off + + + Wake Up + Wake Up + + + Eject + Eject + + + Screensaver + Screensaver + + + WWW + WWW + + + Sleep + Sleep + + + LightBulb + LightBulb + + + Shop + Shop + + + History + History + + + Add Favorite + Add Favorite + + + Hot Links + Hot Links + + + Adjust Brightness + Adjust Brightness + + + Finance + Finance + + + Community + Community + + + Audio Rewind + Audio Rewind + + + Back Forward + Back Forward + + + Application Left + Application Left + + + Application Right + Application Right + + + Book + Book + + + CD + CD + + + Calculator + Calculator + + + Clear + Clear + + + Clear Grab + Clear Grab + + + Close + Close + + + Copy + Copy + + + Cut + Cut + + + Display + Display + + + DOS + DOS + + + Documents + Documents + + + Spreadsheet + Spreadsheet + + + Browser + Browser + + + Game + Game + + + Go + Go + + + iTouch + iTouch + + + Logoff + Logoff + + + Market + Market + + + Meeting + Meeting + + + Keyboard Menu + Keyboard Menu + + + Menu PB + Menu PB + + + My Sites + My Sites + + + News + News + + + Home Office + Home Office + + + Option + Option + + + Paste + Paste + + + Phone + Phone + + + Reply + Reply + + + Reload + Reload + + + Rotate Windows + Rotate Windows + + + Rotation PB + Rotation PB + + + Rotation KB + Rotation KB + + + Save + Save + + + Send + Send + + + Spellchecker + Spellchecker + + + Split Screen + Split Screen + + + Support + Support + + + Task Panel + Task Panel + + + Terminal + Terminal + + + Tools + Tools + + + Travel + Travel + + + Video + Video + + + Word Processor + Word Processor + + + XFer + XFer + + + Zoom In + Zoom In + + + Zoom Out + Zoom Out + + + Away + Away + + + Messenger + Messenger + + + WebCam + WebCam + + + Mail Forward + Mail Forward + + + Pictures + Pictures + + + Music + Music + + + Battery + Battery + + + Bluetooth + Bluetooth + + + Wireless + Wireless + + + Ultra Wide Band + Ultra Wide Band + + + Audio Forward + Audio Forward + + + Audio Repeat + Audio Repeat + + + Audio Random Play + Audio Random Play + + + Subtitle + Subtitle + + + Audio Cycle Track + Audio Cycle Track + + + Time + Time + + + View + View + + + Top Menu + Top Menu + + + Suspend + Suspend + + + Hibernate + Hibernate + + + Print Screen + Print Screen + + + Page Up + Page Up + + + Page Down + Page Down + + + Caps Lock + Caps Lock + + + Num Lock + Num Lock + + + Number Lock + Number Lock + + + Scroll Lock + Scroll Lock + + + Insert + Insert + + + Delete + Delete + + + Escape + Escape + + + System Request + System Request + + + Select + Select + + + Yes + Yes + + + No + No + + + Context1 + Context1 + + + Context2 + Context2 + + + Context3 + Context3 + + + Context4 + Context4 + + + Call + Call + + + Hangup + Hangup + + + Flip + Flip + + + Ctrl + Ctrl + + + Shift + Shift + + + Alt + Alt + + + Meta + Meta + + + + + + + + + F%1 + F%1 + + + Home Page + Home Page + + + + QSlider + + Page left + Page left + + + Page up + Page up + + + Position + Position + + + Page right + Page right + + + Page down + Page down + + + + QSocks5SocketEngine + + Connection to proxy refused + Connection to proxy refused + + + Connection to proxy closed prematurely + Connection to proxy closed prematurely + + + Proxy host not found + Proxy host not found + + + Connection to proxy timed out + Connection to proxy timed out + + + Proxy authentication failed + Proxy authentication failed + + + Proxy authentication failed: %1 + Proxy authentication failed: %1 + + + SOCKS version 5 protocol error + SOCKS version 5 protocol error + + + General SOCKSv5 server failure + General SOCKSv5 server failure + + + Connection not allowed by SOCKSv5 server + Connection not allowed by SOCKSv5 server + + + TTL expired + TTL expired + + + SOCKSv5 command not supported + SOCKSv5 command not supported + + + Address type not supported + Address type not supported + + + Unknown SOCKSv5 proxy error code 0x%1 + Unknown SOCKSv5 proxy error code 0x%1 + + + Network operation timed out + Network operation timed out + + + + QSoftKeyManager + + Ok + Ok + + + Select + Select + + + Done + Done + + + Options + Options + + + Cancel + Cancel + + + Exit + Exit + + + + QSpinBox + + More + More + + + Less + Less + + + + QSql + + Delete + Delete + + + Delete this record? + Delete this record? + + + Yes + Yes + + + No + No + + + Insert + Insert + + + Update + Update + + + Save edits? + Save edits? + + + Cancel + Cancel + + + Confirm + Confirm + + + Cancel your edits? + Cancel your edits? + + + + QSslSocket + + Unable to write data: %1 + Unable to write data: %1 + + + Unable to decrypt data: %1 + Unable to decrypt data: %1 + + + Error while reading: %1 + Error while reading: %1 + + + Error during SSL handshake: %1 + Error during SSL handshake: %1 + + + Error creating SSL context (%1) + Error creating SSL context (%1) + + + Invalid or empty cipher list (%1) + Invalid or empty cipher list (%1) + + + Private key does not certify public key, %1 + Private key does not certify public key, %1 + + + Error creating SSL session, %1 + Error creating SSL session, %1 + + + Error creating SSL session: %1 + Error creating SSL session: %1 + + + Cannot provide a certificate with no key, %1 + Cannot provide a certificate with no key, %1 + + + Error loading local certificate, %1 + Error loading local certificate, %1 + + + Error loading private key, %1 + Error loading private key, %1 + + + No error + No error + + + The issuer certificate could not be found + The issuer certificate could not be found + + + The certificate signature could not be decrypted + The certificate signature could not be decrypted + + + The public key in the certificate could not be read + The public key in the certificate could not be read + + + The signature of the certificate is invalid + The signature of the certificate is invalid + + + The certificate is not yet valid + The certificate is not yet valid + + + The certificate has expired + The certificate has expired + + + The certificate's notBefore field contains an invalid time + The certificate's notBefore field contains an invalid time + + + The certificate's notAfter field contains an invalid time + The certificate's notAfter field contains an invalid time + + + The certificate is self-signed, and untrusted + The certificate is self-signed, and untrusted + + + The root certificate of the certificate chain is self-signed, and untrusted + The root certificate of the certificate chain is self-signed, and untrusted + + + The issuer certificate of a locally looked up certificate could not be found + The issuer certificate of a locally looked up certificate could not be found + + + No certificates could be verified + No certificates could be verified + + + One of the CA certificates is invalid + One of the CA certificates is invalid + + + The basicConstraints path length parameter has been exceeded + The basicConstraints path length parameter has been exceeded + + + The supplied certificate is unsuitable for this purpose + The supplied certificate is unsuitable for this purpose + + + The root CA certificate is not trusted for this purpose + The root CA certificate is not trusted for this purpose + + + The root CA certificate is marked to reject the specified purpose + The root CA certificate is marked to reject the specified purpose + + + The current candidate issuer certificate was rejected because its subject name did not match the issuer name of the current certificate + The current candidate issuer certificate was rejected because its subject name did not match the issuer name of the current certificate + + + The current candidate issuer certificate was rejected because its issuer name and serial number was present and did not match the authority key identifier of the current certificate + The current candidate issuer certificate was rejected because its issuer name and serial number was present and did not match the authority key identifier of the current certificate + + + The peer did not present any certificate + The peer did not present any certificate + + + The host name did not match any of the valid hosts for this certificate + The host name did not match any of the valid hosts for this certificate + + + Unknown error + Unknown error + + + + QStateMachine + + Missing initial state in compound state '%1' + Missing initial state in compound state '%1' + + + Missing default state in history state '%1' + Missing default state in history state '%1' + + + No common ancestor for targets and source of transition from state '%1' + No common ancestor for targets and source of transition from state '%1' + + + Unknown error + Unknown error + + + + QSystemSemaphore + + %1: does not exist + %1: does not exist + + + %1: out of resources + %1: out of resources + + + %1: permission denied + %1: permission denied + + + %1: already exists + %1: already exists + + + %1: unknown error %2 + %1: unknown error %2 + + + + QTDSDriver + + Unable to open connection + Unable to open connection + + + Unable to use database + Unable to use database + + + + QTabBar + + Scroll Left + Scroll Left + + + Scroll Right + Scroll Right + + + + QTcpServer + + Operation on socket is not supported + Operation on socket is not supported + + + + QTextControl + + &Undo + &Undo + + + &Redo + &Redo + + + Cu&t + Cu&t + + + &Copy + &Copy + + + Copy &Link Location + Copy &Link Location + + + &Paste + &Paste + + + Delete + Delete + + + Select All + Select All + + + + QToolButton + + Press + Press + + + Open + Open + + + + QUdpSocket + + This platform does not support IPv6 + This platform does not support IPv6 + + + + QUndoGroup + + Undo + Undo + + + Redo + Redo + + + + QUndoModel + + <empty> + <empty> + + + + QUndoStack + + Undo + Undo + + + Redo + Redo + + + + QUnicodeControlCharacterMenu + + LRM Left-to-right mark + LRM Left-to-right mark + + + RLM Right-to-left mark + RLM Right-to-left mark + + + ZWJ Zero width joiner + ZWJ Zero width joiner + + + ZWNJ Zero width non-joiner + ZWNJ Zero width non-joiner + + + ZWSP Zero width space + ZWSP Zero width space + + + LRE Start of left-to-right embedding + LRE Start of left-to-right embedding + + + RLE Start of right-to-left embedding + RLE Start of right-to-left embedding + + + LRO Start of left-to-right override + LRO Start of left-to-right override + + + RLO Start of right-to-left override + RLO Start of right-to-left override + + + PDF Pop directional formatting + PDF Pop directional formatting + + + Insert Unicode control character + Insert Unicode control character + + + + QWebFrame + + Request cancelled + Request cancelled + + + Request blocked + Request blocked + + + Cannot show URL + Cannot show URL + + + Frame load interrupted by policy change + Frame load interrupted by policy change + + + Cannot show mimetype + Cannot show mimetype + + + File does not exist + File does not exist + + + + QWebPage + + Submit + default label for Submit buttons in forms on web pages + Submit + + + Submit + Submit (input element) alt text for <input> elements with no alt, title, or value + Submit + + + Reset + default label for Reset buttons in forms on web pages + Reset + + + Choose File + title for file button used in HTML forms + Choose File + + + No file selected + text to display in file button used in HTML forms when no file is selected + No file selected + + + Open in New Window + Open in New Window context menu item + Open in New Window + + + Save Link... + Download Linked File context menu item + Save Link... + + + Copy Link + Copy Link context menu item + Copy Link + + + Open Image + Open Image in New Window context menu item + Open Image + + + Save Image + Download Image context menu item + Save Image + + + Copy Image + Copy Link context menu item + Copy Image + + + Open Frame + Open Frame in New Window context menu item + Open Frame + + + Copy + Copy context menu item + Copy + + + Go Back + Back context menu item + Go Back + + + Go Forward + Forward context menu item + Go Forward + + + Stop + Stop context menu item + Stop + + + Reload + Reload context menu item + Reload + + + Cut + Cut context menu item + Cut + + + Paste + Paste context menu item + Paste + + + No Guesses Found + No Guesses Found context menu item + No Guesses Found + + + Ignore + Ignore Spelling context menu item + Ignore + + + Add To Dictionary + Learn Spelling context menu item + Add To Dictionary + + + Search The Web + Search The Web context menu item + Search The Web + + + Look Up In Dictionary + Look Up in Dictionary context menu item + Look Up In Dictionary + + + Open Link + Open Link context menu item + Open Link + + + Ignore + Ignore Grammar context menu item + Ignore + + + Spelling + Spelling and Grammar context sub-menu item + Spelling + + + Show Spelling and Grammar + menu item title + Show Spelling and Grammar + + + Hide Spelling and Grammar + menu item title + Hide Spelling and Grammar + + + Check Spelling + Check spelling context menu item + Check Spelling + + + Check Spelling While Typing + Check spelling while typing context menu item + Check Spelling While Typing + + + Check Grammar With Spelling + Check grammar with spelling context menu item + Check Grammar With Spelling + + + Fonts + Font context sub-menu item + Fonts + + + Bold + Bold context menu item + Bold + + + Italic + Italic context menu item + Italic + + + Underline + Underline context menu item + Underline + + + Outline + Outline context menu item + Outline + + + Direction + Writing direction context sub-menu item + Direction + + + Text Direction + Text direction context sub-menu item + Text Direction + + + Default + Default writing direction context menu item + Default + + + Left to Right + Left to Right context menu item + Left to Right + + + Right to Left + Right to Left context menu item + Right to Left + + + Loading... + Media controller status message when the media is loading + Loading... + + + Live Broadcast + Media controller status message when watching a live broadcast + Live Broadcast + + + Audio Element + Media controller element + Audio Element + + + Video Element + Media controller element + Video Element + + + Mute Button + Media controller element + Mute Button + + + Unmute Button + Media controller element + Unmute Button + + + Play Button + Media controller element + Play Button + + + Pause Button + Media controller element + Pause Button + + + Slider + Media controller element + Slider + + + Slider Thumb + Media controller element + Slider Thumb + + + Rewind Button + Media controller element + Rewind Button + + + Return to Real-time Button + Media controller element + Return to Real-time Button + + + Elapsed Time + Media controller element + Elapsed Time + + + Remaining Time + Media controller element + Remaining Time + + + Status Display + Media controller element + Status Display + + + Fullscreen Button + Media controller element + Fullscreen Button + + + Seek Forward Button + Media controller element + Seek Forward Button + + + Seek Back Button + Media controller element + Seek Back Button + + + Audio element playback controls and status display + Media controller element + Audio element playback controls and status display + + + Video element playback controls and status display + Media controller element + Video element playback controls and status display + + + Mute audio tracks + Media controller element + Mute audio tracks + + + Unmute audio tracks + Media controller element + Unmute audio tracks + + + Begin playback + Media controller element + Begin playback + + + Pause playback + Media controller element + Pause playback + + + Movie time scrubber + Media controller element + Movie time scrubber + + + Movie time scrubber thumb + Media controller element + Movie time scrubber thumb + + + Rewind movie + Media controller element + Rewind movie + + + Return streaming movie to real-time + Media controller element + Return streaming movie to real-time + + + Current movie time + Media controller element + Current movie time + + + Remaining movie time + Media controller element + Remaining movie time + + + Current movie status + Media controller element + Current movie status + + + Play movie in full-screen mode + Media controller element + Play movie in full-screen mode + + + Seek quickly back + Media controller element + Seek quickly back + + + Seek quickly forward + Media controller element + Seek quickly forward + + + Indefinite time + Media time description + Indefinite time + + + %1 days %2 hours %3 minutes %4 seconds + Media time description + %1 days %2 hours %3 minutes %4 seconds + + + %1 hours %2 minutes %3 seconds + Media time description + %1 hours %2 minutes %3 seconds + + + %1 minutes %2 seconds + Media time description + %1 minutes %2 seconds + + + %1 seconds + Media time description + %1 seconds + + + Inspect + Inspect Element context menu item + Inspect + + + No recent searches + Label for only item in menu that appears when clicking on the search field image, when no searches have been performed + No recent searches + + + Recent searches + label for first item in the menu that appears when clicking on the search field image, used as embedded menu title + Recent searches + + + Clear recent searches + menu item in Recent Searches menu that empties menu's contents + Clear recent searches + + + Unknown + Unknown filesize FTP directory listing item + Unknown + + + Web Inspector - %2 + Web Inspector - %2 + + + %1 (%2x%3 pixels) + Title string for images + %1 (%2x%3 pixels) + + + Bad HTTP request + Bad HTTP request + + + This is a searchable index. Enter search keywords: + text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' + This is a searchable index. Enter search keywords: + + + Scroll here + Scroll here + + + Left edge + Left edge + + + Top + Top + + + Right edge + Right edge + + + Bottom + Bottom + + + Page left + Page left + + + Page up + Page up + + + Page right + Page right + + + Page down + Page down + + + Scroll left + Scroll left + + + Scroll up + Scroll up + + + Scroll right + Scroll right + + + Scroll down + Scroll down + + + %n file(s) + number of chosen file + + %n file(s) + %n file(s) + + + + JavaScript Alert - %1 + JavaScript Alert - %1 + + + JavaScript Confirm - %1 + JavaScript Confirm - %1 + + + JavaScript Prompt - %1 + JavaScript Prompt - %1 + + + JavaScript Problem - %1 + JavaScript Problem - %1 + + + The script on this page appears to have a problem. Do you want to stop the script? + The script on this page appears to have a problem. Do you want to stop the script? + + + Move the cursor to the next character + Move the cursor to the next character + + + Move the cursor to the previous character + Move the cursor to the previous character + + + Move the cursor to the next word + Move the cursor to the next word + + + Move the cursor to the previous word + Move the cursor to the previous word + + + Move the cursor to the next line + Move the cursor to the next line + + + Move the cursor to the previous line + Move the cursor to the previous line + + + Move the cursor to the start of the line + Move the cursor to the start of the line + + + Move the cursor to the end of the line + Move the cursor to the end of the line + + + Move the cursor to the start of the block + Move the cursor to the start of the block + + + Move the cursor to the end of the block + Move the cursor to the end of the block + + + Move the cursor to the start of the document + Move the cursor to the start of the document + + + Move the cursor to the end of the document + Move the cursor to the end of the document + + + Select all + Select all + + + Select to the next character + Select to the next character + + + Select to the previous character + Select to the previous character + + + Select to the next word + Select to the next word + + + Select to the previous word + Select to the previous word + + + Select to the next line + Select to the next line + + + Select to the previous line + Select to the previous line + + + Select to the start of the line + Select to the start of the line + + + Select to the end of the line + Select to the end of the line + + + Select to the start of the block + Select to the start of the block + + + Select to the end of the block + Select to the end of the block + + + Select to the start of the document + Select to the start of the document + + + Select to the end of the document + Select to the end of the document + + + Delete to the start of the word + Delete to the start of the word + + + Delete to the end of the word + Delete to the end of the word + + + Insert a new paragraph + Insert a new paragraph + + + Insert a new line + Insert a new line + + + Paste and Match Style + Paste and Match Style + + + Remove formatting + Remove formatting + + + Strikethrough + Strikethrough + + + Subscript + Subscript + + + Superscript + Superscript + + + Insert Bulleted List + Insert Bulleted List + + + Insert Numbered List + Insert Numbered List + + + Indent + Indent + + + Outdent + Outdent + + + Center + Center + + + Justify + Justify + + + Align Left + Align Left + + + Align Right + Align Right + + + + QWhatsThisAction + + What's This? + What's This? + + + + QWidget + + * + * + + + + QWizard + + Cancel + Cancel + + + Help + Help + + + < &Back + < &Back + + + &Finish + &Finish + + + &Help + &Help + + + Go Back + Go Back + + + Continue + Continue + + + Commit + Commit + + + Done + Done + + + &Next + &Next + + + &Next > + &Next > + + + + QWorkspace + + &Restore + &Restore + + + &Move + &Move + + + &Size + &Size + + + Mi&nimize + Mi&nimize + + + Ma&ximize + Ma&ximize + + + &Close + &Close + + + Stay on &Top + Stay on &Top + + + Minimize + Minimize + + + Restore Down + Restore Down + + + Close + Close + + + Sh&ade + Sh&ade + + + %1 - [%2] + %1 - [%2] + + + &Unshade + &Unshade + + + + QXml + + no error occurred + no error occurred + + + error triggered by consumer + error triggered by consumer + + + unexpected end of file + unexpected end of file + + + more than one document type definition + more than one document type definition + + + error occurred while parsing element + error occurred while parsing element + + + tag mismatch + tag mismatch + + + error occurred while parsing content + error occurred while parsing content + + + unexpected character + unexpected character + + + invalid name for processing instruction + invalid name for processing instruction + + + version expected while reading the XML declaration + version expected while reading the XML declaration + + + wrong value for standalone declaration + wrong value for standalone declaration + + + error occurred while parsing document type definition + error occurred while parsing document type definition + + + letter is expected + letter is expected + + + error occurred while parsing comment + error occurred while parsing comment + + + error occurred while parsing reference + error occurred while parsing reference + + + internal general entity reference not allowed in DTD + internal general entity reference not allowed in DTD + + + external parsed general entity reference not allowed in attribute value + external parsed general entity reference not allowed in attribute value + + + external parsed general entity reference not allowed in DTD + external parsed general entity reference not allowed in DTD + + + unparsed entity reference in wrong context + unparsed entity reference in wrong context + + + recursive entities + recursive entities + + + error in the text declaration of an external entity + error in the text declaration of an external entity + + + encoding declaration or standalone declaration expected while reading the XML declaration + encoding declaration or standalone declaration expected while reading the XML declaration + + + standalone declaration expected while reading the XML declaration + standalone declaration expected while reading the XML declaration + + + + QXmlPatternistCLI + + Warning in %1, at line %2, column %3: %4 + Warning in %1, at line %2, column %3: %4 + + + Warning in %1: %2 + Warning in %1: %2 + + + Unknown location + Unknown location + + + Error %1 in %2, at line %3, column %4: %5 + Error %1 in %2, at line %3, column %4: %5 + + + Error %1 in %2: %3 + Error %1 in %2: %3 + + + + QXmlStream + + Extra content at end of document. + Extra content at end of document. + + + Invalid entity value. + Invalid entity value. + + + Invalid XML character. + Invalid XML character. + + + Sequence ']]>' not allowed in content. + Sequence ']]>' not allowed in content. + + + Namespace prefix '%1' not declared + Namespace prefix '%1' not declared + + + Attribute redefined. + Attribute redefined. + + + Unexpected character '%1' in public id literal. + Unexpected character '%1' in public id literal. + + + Invalid XML version string. + Invalid XML version string. + + + Unsupported XML version. + Unsupported XML version. + + + %1 is an invalid encoding name. + %1 is an invalid encoding name. + + + Encoding %1 is unsupported + Encoding %1 is unsupported + + + Standalone accepts only yes or no. + Standalone accepts only yes or no. + + + Invalid attribute in XML declaration. + Invalid attribute in XML declaration. + + + Premature end of document. + Premature end of document. + + + Invalid document. + Invalid document. + + + Expected + Expected + + + , but got ' + , but got ' + + + Unexpected ' + Unexpected ' + + + Expected character data. + Expected character data. + + + Recursive entity detected. + Recursive entity detected. + + + Start tag expected. + Start tag expected. + + + XML declaration not at start of document. + XML declaration not at start of document. + + + NDATA in parameter entity declaration. + NDATA in parameter entity declaration. + + + %1 is an invalid processing instruction name. + %1 is an invalid processing instruction name. + + + Invalid processing instruction name. + Invalid processing instruction name. + + + Illegal namespace declaration. + Illegal namespace declaration. + + + Invalid XML name. + Invalid XML name. + + + Opening and ending tag mismatch. + Opening and ending tag mismatch. + + + Reference to unparsed entity '%1'. + Reference to unparsed entity '%1'. + + + Entity '%1' not declared. + Entity '%1' not declared. + + + Reference to external entity '%1' in attribute value. + Reference to external entity '%1' in attribute value. + + + Invalid character reference. + Invalid character reference. + + + Encountered incorrectly encoded content. + Encountered incorrectly encoded content. + + + The standalone pseudo attribute must appear after the encoding. + The standalone pseudo attribute must appear after the encoding. + + + %1 is an invalid PUBLIC identifier. + %1 is an invalid PUBLIC identifier. + + + + QtXmlPatterns + + At least one component must be present. + At least one component must be present. + + + %1 is not a valid value of type %2. + %1 is not a valid value of type %2. + + + When casting to %1 from %2, the source value cannot be %3. + When casting to %1 from %2, the source value cannot be %3. + + + Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values. + Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values. + + + The data of a processing instruction cannot contain the string %1 + The data of a processing instruction cannot contain the string %1 + + + %1 is an invalid %2 + %1 is an invalid %2 + + + %1 is not a valid XML 1.0 character. + %1 is not a valid XML 1.0 character. + + + %1 was called. + %1 was called. + + + In the replacement string, %1 must be followed by at least one digit when not escaped. + In the replacement string, %1 must be followed by at least one digit when not escaped. + + + In the replacement string, %1 can only be used to escape itself or %2, not %3 + In the replacement string, %1 can only be used to escape itself or %2, not %3 + + + %1 matches newline characters + %1 matches newline characters + + + Matches are case insensitive + Matches are case insensitive + + + %1 is an invalid regular expression pattern: %2 + %1 is an invalid regular expression pattern: %2 + + + It will not be possible to retrieve %1. + It will not be possible to retrieve %1. + + + The default collection is undefined + The default collection is undefined + + + %1 cannot be retrieved + %1 cannot be retrieved + + + The item %1 did not match the required type %2. + The item %1 did not match the required type %2. + + + %1 is an unknown schema type. + %1 is an unknown schema type. + + + A template with name %1 has already been declared. + A template with name %1 has already been declared. + + + Only one %1 declaration can occur in the query prolog. + Only one %1 declaration can occur in the query prolog. + + + The initialization of variable %1 depends on itself + The initialization of variable %1 depends on itself + + + The variable %1 is unused + The variable %1 is unused + + + Version %1 is not supported. The supported XQuery version is 1.0. + Version %1 is not supported. The supported XQuery version is 1.0. + + + No function with signature %1 is available + No function with signature %1 is available + + + It is not possible to redeclare prefix %1. + It is not possible to redeclare prefix %1. + + + Prefix %1 is already declared in the prolog. + Prefix %1 is already declared in the prolog. + + + The name of an option must have a prefix. There is no default namespace for options. + The name of an option must have a prefix. There is no default namespace for options. + + + The Schema Import feature is not supported, and therefore %1 declarations cannot occur. + The Schema Import feature is not supported, and therefore %1 declarations cannot occur. + + + The target namespace of a %1 cannot be empty. + The target namespace of a %1 cannot be empty. + + + The module import feature is not supported + The module import feature is not supported + + + The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2 + The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2 + + + A function already exists with the signature %1. + A function already exists with the signature %1. + + + No external functions are supported. All supported functions can be used directly, without first declaring them as external + No external functions are supported. All supported functions can be used directly, without first declaring them as external + + + The %1-axis is unsupported in XQuery + The %1-axis is unsupported in XQuery + + + The namespace URI cannot be the empty string when binding to a prefix, %1. + The namespace URI cannot be the empty string when binding to a prefix, %1. + + + %1 is an invalid namespace URI. + %1 is an invalid namespace URI. + + + It is not possible to bind to the prefix %1 + It is not possible to bind to the prefix %1 + + + Two namespace declaration attributes have the same name: %1. + Two namespace declaration attributes have the same name: %1. + + + The namespace URI must be a constant and cannot use enclosed expressions. + The namespace URI must be a constant and cannot use enclosed expressions. + + + %1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported. + %1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported. + + + empty + empty + + + zero or one + zero or one + + + exactly one + exactly one + + + one or more + one or more + + + zero or more + zero or more + + + The focus is undefined. + The focus is undefined. + + + An attribute by name %1 has already been created. + An attribute by name %1 has already been created. + + + Network timeout. + Network timeout. + + + Element %1 can't be serialized because it appears outside the document element. + Element %1 can't be serialized because it appears outside the document element. + + + Year %1 is invalid because it begins with %2. + Year %1 is invalid because it begins with %2. + + + Day %1 is outside the range %2..%3. + Day %1 is outside the range %2..%3. + + + Month %1 is outside the range %2..%3. + Month %1 is outside the range %2..%3. + + + Overflow: Can't represent date %1. + Overflow: Can't represent date %1. + + + Day %1 is invalid for month %2. + Day %1 is invalid for month %2. + + + Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; + Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; + + + Time %1:%2:%3.%4 is invalid. + Time %1:%2:%3.%4 is invalid. + + + Overflow: Date can't be represented. + Overflow: Date can't be represented. + + + At least one time component must appear after the %1-delimiter. + At least one time component must appear after the %1-delimiter. + + + Dividing a value of type %1 by %2 (not-a-number) is not allowed. + Dividing a value of type %1 by %2 (not-a-number) is not allowed. + + + Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed. + Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed. + + + Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed. + Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed. + + + A value of type %1 cannot have an Effective Boolean Value. + A value of type %1 cannot have an Effective Boolean Value. + + + Value %1 of type %2 exceeds maximum (%3). + Value %1 of type %2 exceeds maximum (%3). + + + Value %1 of type %2 is below minimum (%3). + Value %1 of type %2 is below minimum (%3). + + + A value of type %1 must contain an even number of digits. The value %2 does not. + A value of type %1 must contain an even number of digits. The value %2 does not. + + + %1 is not valid as a value of type %2. + %1 is not valid as a value of type %2. + + + Operator %1 cannot be used on type %2. + Operator %1 cannot be used on type %2. + + + Operator %1 cannot be used on atomic values of type %2 and %3. + Operator %1 cannot be used on atomic values of type %2 and %3. + + + The namespace URI in the name for a computed attribute cannot be %1. + The namespace URI in the name for a computed attribute cannot be %1. + + + The name for a computed attribute cannot have the namespace URI %1 with the local name %2. + The name for a computed attribute cannot have the namespace URI %1 with the local name %2. + + + Type error in cast, expected %1, received %2. + Type error in cast, expected %1, received %2. + + + When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed. + When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed. + + + A comment cannot contain %1 + A comment cannot contain %1 + + + A comment cannot end with a %1. + A comment cannot end with a %1. + + + An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place. + An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place. + + + A library module cannot be evaluated directly. It must be imported from a main module. + A library module cannot be evaluated directly. It must be imported from a main module. + + + No template by name %1 exists. + No template by name %1 exists. + + + A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type. + A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type. + + + A positional predicate must evaluate to a single numeric value. + A positional predicate must evaluate to a single numeric value. + + + The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, %2 is invalid. + The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, %2 is invalid. + + + %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. + %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. + + + The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. + The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. + + + No namespace binding exists for the prefix %1 + No namespace binding exists for the prefix %1 + + + No namespace binding exists for the prefix %1 in %2 + No namespace binding exists for the prefix %1 in %2 + + + The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration. + The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration. + + + The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + + + The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + + + If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same. + If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same. + + + %1 must be followed by %2 or %3, not at the end of the replacement string. + %1 must be followed by %2 or %3, not at the end of the replacement string. + + + %1 and %2 match the start and end of a line. + %1 and %2 match the start and end of a line. + + + Whitespace characters are removed, except when they appear in character classes + Whitespace characters are removed, except when they appear in character classes + + + %1 is an invalid flag for regular expressions. Valid flags are: + %1 is an invalid flag for regular expressions. Valid flags are: + + + If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified. + If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified. + + + The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization). + The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization). + + + A zone offset must be in the range %1..%2 inclusive. %3 is out of range. + A zone offset must be in the range %1..%2 inclusive. %3 is out of range. + + + Required cardinality is %1; got cardinality %2. + Required cardinality is %1; got cardinality %2. + + + The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2. + The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2. + + + The keyword %1 cannot occur with any other mode name. + The keyword %1 cannot occur with any other mode name. + + + No variable with name %1 exists + No variable with name %1 exists + + + The value of attribute %1 must be of type %2, which %3 isn't. + The value of attribute %1 must be of type %2, which %3 isn't. + + + The prefix %1 cannot be bound. By default, it is already bound to the namespace %2. + The prefix %1 cannot be bound. By default, it is already bound to the namespace %2. + + + A variable with name %1 has already been declared. + A variable with name %1 has already been declared. + + + No value is available for the external variable with name %1. + No value is available for the external variable with name %1. + + + A stylesheet function must have a prefixed name. + A stylesheet function must have a prefixed name. + + + The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. + The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. + + + An argument with name %1 has already been declared. Every argument name must be unique. + An argument with name %1 has already been declared. Every argument name must be unique. + + + When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. + When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. + + + In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching. + In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching. + + + In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching. + In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching. + + + In an XSL-T pattern, function %1 cannot have a third argument. + In an XSL-T pattern, function %1 cannot have a third argument. + + + In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. + In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. + + + In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can. + In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can. + + + %1 is an invalid template mode name. + %1 is an invalid template mode name. + + + The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. + The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. + + + The Schema Validation Feature is not supported. Hence, %1-expressions may not be used. + The Schema Validation Feature is not supported. Hence, %1-expressions may not be used. + + + None of the pragma expressions are supported. Therefore, a fallback expression must be present + None of the pragma expressions are supported. Therefore, a fallback expression must be present + + + Each name of a template parameter must be unique; %1 is duplicated. + Each name of a template parameter must be unique; %1 is duplicated. + + + No function with name %1 is available. + No function with name %1 is available. + + + %1 is not a valid numeric literal. + %1 is not a valid numeric literal. + + + W3C XML Schema identity constraint selector + W3C XML Schema identity constraint selector + + + W3C XML Schema identity constraint field + W3C XML Schema identity constraint field + + + A construct was encountered which is disallowed in the current language(%1). + A construct was encountered which is disallowed in the current language(%1). + + + Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared). + Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared). + + + Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared). + Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared). + + + An attribute with name %1 has already appeared on this element. + An attribute with name %1 has already appeared on this element. + + + A direct element constructor is not well-formed. %1 is ended with %2. + A direct element constructor is not well-formed. %1 is ended with %2. + + + The name %1 does not refer to any schema type. + The name %1 does not refer to any schema type. + + + %1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works. + %1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works. + + + %1 is not an atomic type. Casting is only possible to atomic types. + %1 is not an atomic type. Casting is only possible to atomic types. + + + %1 is not a valid name for a processing-instruction. + %1 is not a valid name for a processing-instruction. + + + The name of an extension expression must be in a namespace. + The name of an extension expression must be in a namespace. + + + Required type is %1, but %2 was found. + Required type is %1, but %2 was found. + + + Promoting %1 to %2 may cause loss of precision. + Promoting %1 to %2 may cause loss of precision. + + + It's not possible to add attributes after any other kind of node. + It's not possible to add attributes after any other kind of node. + + + Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported. + Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported. + + + Integer division (%1) by zero (%2) is undefined. + Integer division (%1) by zero (%2) is undefined. + + + Division (%1) by zero (%2) is undefined. + Division (%1) by zero (%2) is undefined. + + + Modulus division (%1) by zero (%2) is undefined. + Modulus division (%1) by zero (%2) is undefined. + + + %1 takes at most %n argument(s). %2 is therefore invalid. + + %1 takes at most %n argument(s). %2 is therefore invalid. + %1 takes at most %n argument(s). %2 is therefore invalid. + + + + %1 requires at least %n argument(s). %2 is therefore invalid. + + %1 requires at least %n argument(s). %2 is therefore invalid. + %1 requires at least %n argument(s). %2 is therefore invalid. + + + + The root node of the second argument to function %1 must be a document node. %2 is not a document node. + The root node of the second argument to function %1 must be a document node. %2 is not a document node. + + + The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) + The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) + + + A default namespace declaration must occur before function, variable, and option declarations. + A default namespace declaration must occur before function, variable, and option declarations. + + + Namespace declarations must occur before function, variable, and option declarations. + Namespace declarations must occur before function, variable, and option declarations. + + + Module imports must occur before function, variable, and option declarations. + Module imports must occur before function, variable, and option declarations. + + + %1 is not a whole number of minutes. + %1 is not a whole number of minutes. + + + Attribute %1 can't be serialized because it appears at the top level. + Attribute %1 can't be serialized because it appears at the top level. + + + %1 is an unsupported encoding. + %1 is an unsupported encoding. + + + %1 contains octets which are disallowed in the requested encoding %2. + %1 contains octets which are disallowed in the requested encoding %2. + + + The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character. + The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character. + + + Ambiguous rule match. + Ambiguous rule match. + + + In a namespace constructor, the value for a namespace cannot be an empty string. + In a namespace constructor, the value for a namespace cannot be an empty string. + + + The prefix must be a valid %1, which %2 is not. + The prefix must be a valid %1, which %2 is not. + + + The prefix %1 cannot be bound. + The prefix %1 cannot be bound. + + + Only the prefix %1 can be bound to %2 and vice versa. + Only the prefix %1 can be bound to %2 and vice versa. + + + The parameter %1 is required, but no corresponding %2 is supplied. + The parameter %1 is required, but no corresponding %2 is supplied. + + + The parameter %1 is passed, but no corresponding %2 exists. + The parameter %1 is passed, but no corresponding %2 exists. + + + The URI cannot have a fragment + The URI cannot have a fragment + + + Element %1 is not allowed at this location. + Element %1 is not allowed at this location. + + + Text nodes are not allowed at this location. + Text nodes are not allowed at this location. + + + Parse error: %1 + Parse error: %1 + + + The value of the XSL-T version attribute must be a value of type %1, which %2 isn't. + The value of the XSL-T version attribute must be a value of type %1, which %2 isn't. + + + Running an XSL-T 1.0 stylesheet with a 2.0 processor. + Running an XSL-T 1.0 stylesheet with a 2.0 processor. + + + Unknown XSL-T attribute %1. + Unknown XSL-T attribute %1. + + + Attribute %1 and %2 are mutually exclusive. + Attribute %1 and %2 are mutually exclusive. + + + In a simplified stylesheet module, attribute %1 must be present. + In a simplified stylesheet module, attribute %1 must be present. + + + If element %1 has no attribute %2, it cannot have attribute %3 or %4. + If element %1 has no attribute %2, it cannot have attribute %3 or %4. + + + Element %1 must have at least one of the attributes %2 or %3. + Element %1 must have at least one of the attributes %2 or %3. + + + At least one mode must be specified in the %1-attribute on element %2. + At least one mode must be specified in the %1-attribute on element %2. + + + Element %1 must come last. + Element %1 must come last. + + + At least one %1-element must occur before %2. + At least one %1-element must occur before %2. + + + Only one %1-element can appear. + Only one %1-element can appear. + + + At least one %1-element must occur inside %2. + At least one %1-element must occur inside %2. + + + When attribute %1 is present on %2, a sequence constructor cannot be used. + When attribute %1 is present on %2, a sequence constructor cannot be used. + + + Element %1 must have either a %2-attribute or a sequence constructor. + Element %1 must have either a %2-attribute or a sequence constructor. + + + When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor. + When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor. + + + Element %1 cannot have children. + Element %1 cannot have children. + + + Element %1 cannot have a sequence constructor. + Element %1 cannot have a sequence constructor. + + + The attribute %1 cannot appear on %2, when it is a child of %3. + The attribute %1 cannot appear on %2, when it is a child of %3. + + + A parameter in a function cannot be declared to be a tunnel. + A parameter in a function cannot be declared to be a tunnel. + + + This processor is not Schema-aware and therefore %1 cannot be used. + This processor is not Schema-aware and therefore %1 cannot be used. + + + Top level stylesheet elements must be in a non-null namespace, which %1 isn't. + Top level stylesheet elements must be in a non-null namespace, which %1 isn't. + + + The value for attribute %1 on element %2 must either be %3 or %4, not %5. + The value for attribute %1 on element %2 must either be %3 or %4, not %5. + + + Attribute %1 cannot have the value %2. + Attribute %1 cannot have the value %2. + + + The attribute %1 can only appear on the first %2 element. + The attribute %1 can only appear on the first %2 element. + + + At least one %1 element must appear as child of %2. + At least one %1 element must appear as child of %2. + + + %1 has inheritance loop in its base type %2. + %1 has inheritance loop in its base type %2. + + + Circular inheritance of base type %1. + Circular inheritance of base type %1. + + + Circular inheritance of union %1. + Circular inheritance of union %1. + + + %1 is not allowed to derive from %2 by restriction as the latter defines it as final. + %1 is not allowed to derive from %2 by restriction as the latter defines it as final. + + + %1 is not allowed to derive from %2 by extension as the latter defines it as final. + %1 is not allowed to derive from %2 by extension as the latter defines it as final. + + + Base type of simple type %1 cannot be complex type %2. + Base type of simple type %1 cannot be complex type %2. + + + Simple type %1 cannot have direct base type %2. + Simple type %1 cannot have direct base type %2. + + + Simple type %1 is not allowed to have base type %2. + Simple type %1 is not allowed to have base type %2. + + + Simple type %1 can only have simple atomic type as base type. + Simple type %1 can only have simple atomic type as base type. + + + Simple type %1 cannot derive from %2 as the latter defines restriction as final. + Simple type %1 cannot derive from %2 as the latter defines restriction as final. + + + Variety of item type of %1 must be either atomic or union. + Variety of item type of %1 must be either atomic or union. + + + Variety of member types of %1 must be atomic. + Variety of member types of %1 must be atomic. + + + %1 is not allowed to derive from %2 by list as the latter defines it as final. + %1 is not allowed to derive from %2 by list as the latter defines it as final. + + + Simple type %1 is only allowed to have %2 facet. + Simple type %1 is only allowed to have %2 facet. + + + Base type of simple type %1 must have variety of type list. + Base type of simple type %1 must have variety of type list. + + + Base type of simple type %1 has defined derivation by restriction as final. + Base type of simple type %1 has defined derivation by restriction as final. + + + Item type of base type does not match item type of %1. + Item type of base type does not match item type of %1. + + + Simple type %1 contains not allowed facet type %2. + Simple type %1 contains not allowed facet type %2. + + + %1 is not allowed to derive from %2 by union as the latter defines it as final. + %1 is not allowed to derive from %2 by union as the latter defines it as final. + + + %1 is not allowed to have any facets. + %1 is not allowed to have any facets. + + + Base type %1 of simple type %2 must have variety of union. + Base type %1 of simple type %2 must have variety of union. + + + Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute. + Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute. + + + Member type %1 cannot be derived from member type %2 of %3's base type %4. + Member type %1 cannot be derived from member type %2 of %3's base type %4. + + + Derivation method of %1 must be extension because the base type %2 is a simple type. + Derivation method of %1 must be extension because the base type %2 is a simple type. + + + Complex type %1 has duplicated element %2 in its content model. + Complex type %1 has duplicated element %2 in its content model. + + + Complex type %1 has non-deterministic content. + Complex type %1 has non-deterministic content. + + + Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3. + Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3. + + + Content model of complex type %1 is not a valid extension of content model of %2. + Content model of complex type %1 is not a valid extension of content model of %2. + + + Complex type %1 must have simple content. + Complex type %1 must have simple content. + + + Complex type %1 must have the same simple type as its base class %2. + Complex type %1 must have the same simple type as its base class %2. + + + Complex type %1 cannot be derived from base type %2%3. + Complex type %1 cannot be derived from base type %2%3. + + + Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3. + Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3. + + + Complex type %1 with simple content cannot be derived from complex base type %2. + Complex type %1 with simple content cannot be derived from complex base type %2. + + + Item type of simple type %1 cannot be a complex type. + Item type of simple type %1 cannot be a complex type. + + + Member type of simple type %1 cannot be a complex type. + Member type of simple type %1 cannot be a complex type. + + + %1 is not allowed to have a member type with the same name as itself. + %1 is not allowed to have a member type with the same name as itself. + + + %1 facet collides with %2 facet. + %1 facet collides with %2 facet. + + + %1 facet must have the same value as %2 facet of base type. + %1 facet must have the same value as %2 facet of base type. + + + %1 facet must be equal or greater than %2 facet of base type. + %1 facet must be equal or greater than %2 facet of base type. + + + %1 facet must be less than or equal to %2 facet of base type. + %1 facet must be less than or equal to %2 facet of base type. + + + %1 facet contains invalid regular expression + %1 facet contains invalid regular expression + + + Unknown notation %1 used in %2 facet. + Unknown notation %1 used in %2 facet. + + + %1 facet contains invalid value %2: %3. + %1 facet contains invalid value %2: %3. + + + %1 facet cannot be %2 or %3 if %4 facet of base type is %5. + %1 facet cannot be %2 or %3 if %4 facet of base type is %5. + + + %1 facet cannot be %2 if %3 facet of base type is %4. + %1 facet cannot be %2 if %3 facet of base type is %4. + + + %1 facet must be less than or equal to %2 facet. + %1 facet must be less than or equal to %2 facet. + + + %1 facet must be less than %2 facet of base type. + %1 facet must be less than %2 facet of base type. + + + %1 facet and %2 facet cannot appear together. + %1 facet and %2 facet cannot appear together. + + + %1 facet must be greater than %2 facet of base type. + %1 facet must be greater than %2 facet of base type. + + + %1 facet must be less than %2 facet. + %1 facet must be less than %2 facet. + + + %1 facet must be greater than or equal to %2 facet of base type. + %1 facet must be greater than or equal to %2 facet of base type. + + + Simple type contains not allowed facet %1. + Simple type contains not allowed facet %1. + + + %1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list. + %1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list. + + + Only %1 and %2 facets are allowed when derived by union. + Only %1 and %2 facets are allowed when derived by union. + + + %1 contains %2 facet with invalid data: %3. + %1 contains %2 facet with invalid data: %3. + + + Attribute group %1 contains attribute %2 twice. + Attribute group %1 contains attribute %2 twice. + + + Attribute group %1 contains two different attributes that both have types derived from %2. + Attribute group %1 contains two different attributes that both have types derived from %2. + + + Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3. + Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3. + + + Complex type %1 contains attribute %2 twice. + Complex type %1 contains attribute %2 twice. + + + Complex type %1 contains two different attributes that both have types derived from %2. + Complex type %1 contains two different attributes that both have types derived from %2. + + + Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3. + Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3. + + + Element %1 is not allowed to have a value constraint if its base type is complex. + Element %1 is not allowed to have a value constraint if its base type is complex. + + + Element %1 is not allowed to have a value constraint if its type is derived from %2. + Element %1 is not allowed to have a value constraint if its type is derived from %2. + + + Value constraint of element %1 is not of elements type: %2. + Value constraint of element %1 is not of elements type: %2. + + + Element %1 is not allowed to have substitution group affiliation as it is no global element. + Element %1 is not allowed to have substitution group affiliation as it is no global element. + + + Type of element %1 cannot be derived from type of substitution group affiliation. + Type of element %1 cannot be derived from type of substitution group affiliation. + + + Value constraint of attribute %1 is not of attributes type: %2. + Value constraint of attribute %1 is not of attributes type: %2. + + + Attribute %1 has value constraint but has type derived from %2. + Attribute %1 has value constraint but has type derived from %2. + + + %1 attribute in derived complex type must be %2 like in base type. + %1 attribute in derived complex type must be %2 like in base type. + + + Attribute %1 in derived complex type must have %2 value constraint like in base type. + Attribute %1 in derived complex type must have %2 value constraint like in base type. + + + Attribute %1 in derived complex type must have the same %2 value constraint like in base type. + Attribute %1 in derived complex type must have the same %2 value constraint like in base type. + + + Attribute %1 in derived complex type must have %2 value constraint. + Attribute %1 in derived complex type must have %2 value constraint. + + + processContent of base wildcard must be weaker than derived wildcard. + processContent of base wildcard must be weaker than derived wildcard. + + + Element %1 exists twice with different types. + Element %1 exists twice with different types. + + + Particle contains non-deterministic wildcards. + Particle contains non-deterministic wildcards. + + + Base attribute %1 is required but derived attribute is not. + Base attribute %1 is required but derived attribute is not. + + + Type of derived attribute %1 cannot be validly derived from type of base attribute. + Type of derived attribute %1 cannot be validly derived from type of base attribute. + + + Value constraint of derived attribute %1 does not match value constraint of base attribute. + Value constraint of derived attribute %1 does not match value constraint of base attribute. + + + Derived attribute %1 does not exist in the base definition. + Derived attribute %1 does not exist in the base definition. + + + Derived attribute %1 does not match the wildcard in the base definition. + Derived attribute %1 does not match the wildcard in the base definition. + + + Base attribute %1 is required but missing in derived definition. + Base attribute %1 is required but missing in derived definition. + + + Derived definition contains an %1 element that does not exists in the base definition + Derived definition contains an %1 element that does not exists in the base definition + + + Derived wildcard is not a subset of the base wildcard. + Derived wildcard is not a subset of the base wildcard. + + + %1 of derived wildcard is not a valid restriction of %2 of base wildcard + %1 of derived wildcard is not a valid restriction of %2 of base wildcard + + + Attribute %1 from base type is missing in derived type. + Attribute %1 from base type is missing in derived type. + + + Type of derived attribute %1 differs from type of base attribute. + Type of derived attribute %1 differs from type of base attribute. + + + Base definition contains an %1 element that is missing in the derived definition + Base definition contains an %1 element that is missing in the derived definition + + + %1 references unknown %2 or %3 element %4. + %1 references unknown %2 or %3 element %4. + + + %1 references identity constraint %2 that is no %3 or %4 element. + %1 references identity constraint %2 that is no %3 or %4 element. + + + %1 has a different number of fields from the identity constraint %2 that it references. + %1 has a different number of fields from the identity constraint %2 that it references. + + + Base type %1 of %2 element cannot be resolved. + Base type %1 of %2 element cannot be resolved. + + + Item type %1 of %2 element cannot be resolved. + Item type %1 of %2 element cannot be resolved. + + + Member type %1 of %2 element cannot be resolved. + Member type %1 of %2 element cannot be resolved. + + + Type %1 of %2 element cannot be resolved. + Type %1 of %2 element cannot be resolved. + + + Base type %1 of complex type cannot be resolved. + Base type %1 of complex type cannot be resolved. + + + %1 cannot have complex base type that has a %2. + %1 cannot have complex base type that has a %2. + + + Content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type. + Content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type. + + + Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model. + Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model. + + + Type of %1 element must be a simple type, %2 is not. + Type of %1 element must be a simple type, %2 is not. + + + Substitution group %1 of %2 element cannot be resolved. + Substitution group %1 of %2 element cannot be resolved. + + + Substitution group %1 has circular definition. + Substitution group %1 has circular definition. + + + Duplicated element names %1 in %2 element. + Duplicated element names %1 in %2 element. + + + Reference %1 of %2 element cannot be resolved. + Reference %1 of %2 element cannot be resolved. + + + Circular group reference for %1. + Circular group reference for %1. + + + %1 element is not allowed in this scope + %1 element is not allowed in this scope + + + %1 element cannot have %2 attribute with value other than %3. + %1 element cannot have %2 attribute with value other than %3. + + + %1 element cannot have %2 attribute with value other than %3 or %4. + %1 element cannot have %2 attribute with value other than %3 or %4. + + + %1 or %2 attribute of reference %3 does not match with the attribute declaration %4. + %1 or %2 attribute of reference %3 does not match with the attribute declaration %4. + + + Attribute group %1 has circular reference. + Attribute group %1 has circular reference. + + + %1 attribute in %2 must have %3 use like in base type %4. + %1 attribute in %2 must have %3 use like in base type %4. + + + Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2. + Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2. + + + %1 has attribute wildcard but its base type %2 has not. + %1 has attribute wildcard but its base type %2 has not. + + + Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible. + Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible. + + + Enumeration facet contains invalid content: {%1} is not a value of type %2. + Enumeration facet contains invalid content: {%1} is not a value of type %2. + + + Namespace prefix of qualified name %1 is not defined. + Namespace prefix of qualified name %1 is not defined. + + + %1 element %2 is not a valid restriction of the %3 element it redefines: %4. + %1 element %2 is not a valid restriction of the %3 element it redefines: %4. + + + Empty particle cannot be derived from non-empty particle. + Empty particle cannot be derived from non-empty particle. + + + Derived particle is missing element %1. + Derived particle is missing element %1. + + + Derived element %1 is missing value constraint as defined in base particle. + Derived element %1 is missing value constraint as defined in base particle. + + + Derived element %1 has weaker value constraint than base particle. + Derived element %1 has weaker value constraint than base particle. + + + Fixed value constraint of element %1 differs from value constraint in base particle. + Fixed value constraint of element %1 differs from value constraint in base particle. + + + Derived element %1 cannot be nillable as base element is not nillable. + Derived element %1 cannot be nillable as base element is not nillable. + + + Block constraints of derived element %1 must not be more weaker than in the base element. + Block constraints of derived element %1 must not be more weaker than in the base element. + + + Simple type of derived element %1 cannot be validly derived from base element. + Simple type of derived element %1 cannot be validly derived from base element. + + + Complex type of derived element %1 cannot be validly derived from base element. + Complex type of derived element %1 cannot be validly derived from base element. + + + Element %1 is missing in derived particle. + Element %1 is missing in derived particle. + + + Element %1 does not match namespace constraint of wildcard in base particle. + Element %1 does not match namespace constraint of wildcard in base particle. + + + Wildcard in derived particle is not a valid subset of wildcard in base particle. + Wildcard in derived particle is not a valid subset of wildcard in base particle. + + + processContent of wildcard in derived particle is weaker than wildcard in base particle. + processContent of wildcard in derived particle is weaker than wildcard in base particle. + + + Derived particle allows content that is not allowed in the base particle. + Derived particle allows content that is not allowed in the base particle. + + + Can not process unknown element %1, expected elements are: %2. + Can not process unknown element %1, expected elements are: %2. + + + Element %1 is not allowed in this scope, possible elements are: %2. + Element %1 is not allowed in this scope, possible elements are: %2. + + + Child element is missing in that scope, possible child elements are: %1. + Child element is missing in that scope, possible child elements are: %1. + + + Document is not a XML schema. + Document is not a XML schema. + + + %1 attribute of %2 element contains invalid content: {%3} is not a value of type %4. + %1 attribute of %2 element contains invalid content: {%3} is not a value of type %4. + + + %1 attribute of %2 element contains invalid content: {%3}. + %1 attribute of %2 element contains invalid content: {%3}. + + + Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema. + Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema. + + + Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema. + Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema. + + + %1 element is not allowed to have the same %2 attribute value as the target namespace %3. + %1 element is not allowed to have the same %2 attribute value as the target namespace %3. + + + %1 element without %2 attribute is not allowed inside schema without target namespace. + %1 element without %2 attribute is not allowed inside schema without target namespace. + + + %1 element is not allowed inside %2 element if %3 attribute is present. + %1 element is not allowed inside %2 element if %3 attribute is present. + + + %1 element has neither %2 attribute nor %3 child element. + %1 element has neither %2 attribute nor %3 child element. + + + %1 element with %2 child element must not have a %3 attribute. + %1 element with %2 child element must not have a %3 attribute. + + + %1 attribute of %2 element must be %3 or %4. + %1 attribute of %2 element must be %3 or %4. + + + %1 attribute of %2 element must have a value of %3. + %1 attribute of %2 element must have a value of %3. + + + %1 attribute of %2 element must have a value of %3 or %4. + %1 attribute of %2 element must have a value of %3 or %4. + + + %1 element must not have %2 and %3 attribute together. + %1 element must not have %2 and %3 attribute together. + + + Content of %1 attribute of %2 element must not be from namespace %3. + Content of %1 attribute of %2 element must not be from namespace %3. + + + %1 attribute of %2 element must not be %3. + %1 attribute of %2 element must not be %3. + + + %1 attribute of %2 element must have the value %3 because the %4 attribute is set. + %1 attribute of %2 element must have the value %3 because the %4 attribute is set. + + + Specifying use='prohibited' inside an attribute group has no effect. + Specifying use='prohibited' inside an attribute group has no effect. + + + %1 element must have either %2 or %3 attribute. + %1 element must have either %2 or %3 attribute. + + + %1 element must have either %2 attribute or %3 or %4 as child element. + %1 element must have either %2 attribute or %3 or %4 as child element. + + + %1 element requires either %2 or %3 attribute. + %1 element requires either %2 or %3 attribute. + + + Text or entity references not allowed inside %1 element + Text or entity references not allowed inside %1 element + + + %1 attribute of %2 element must contain %3, %4 or a list of URIs. + %1 attribute of %2 element must contain %3, %4 or a list of URIs. + + + %1 element is not allowed in this context. + %1 element is not allowed in this context. + + + %1 attribute of %2 element has larger value than %3 attribute. + %1 attribute of %2 element has larger value than %3 attribute. + + + Prefix of qualified name %1 is not defined. + Prefix of qualified name %1 is not defined. + + + %1 attribute of %2 element must either contain %3 or the other values. + %1 attribute of %2 element must either contain %3 or the other values. + + + Component with ID %1 has been defined previously. + Component with ID %1 has been defined previously. + + + Element %1 already defined. + Element %1 already defined. + + + Attribute %1 already defined. + Attribute %1 already defined. + + + Type %1 already defined. + Type %1 already defined. + + + Attribute group %1 already defined. + Attribute group %1 already defined. + + + Element group %1 already defined. + Element group %1 already defined. + + + Notation %1 already defined. + Notation %1 already defined. + + + Identity constraint %1 already defined. + Identity constraint %1 already defined. + + + Duplicated facets in simple type %1. + Duplicated facets in simple type %1. + + + %1 is not valid according to %2. + %1 is not valid according to %2. + + + String content does not match the length facet. + String content does not match the length facet. + + + String content does not match the minLength facet. + String content does not match the minLength facet. + + + String content does not match the maxLength facet. + String content does not match the maxLength facet. + + + String content does not match pattern facet. + String content does not match pattern facet. + + + String content is not listed in the enumeration facet. + String content is not listed in the enumeration facet. + + + Signed integer content does not match the maxInclusive facet. + Signed integer content does not match the maxInclusive facet. + + + Signed integer content does not match the maxExclusive facet. + Signed integer content does not match the maxExclusive facet. + + + Signed integer content does not match the minInclusive facet. + Signed integer content does not match the minInclusive facet. + + + Signed integer content does not match the minExclusive facet. + Signed integer content does not match the minExclusive facet. + + + Signed integer content is not listed in the enumeration facet. + Signed integer content is not listed in the enumeration facet. + + + Signed integer content does not match pattern facet. + Signed integer content does not match pattern facet. + + + Signed integer content does not match in the totalDigits facet. + Signed integer content does not match in the totalDigits facet. + + + Unsigned integer content does not match the maxInclusive facet. + Unsigned integer content does not match the maxInclusive facet. + + + Unsigned integer content does not match the maxExclusive facet. + Unsigned integer content does not match the maxExclusive facet. + + + Unsigned integer content does not match the minInclusive facet. + Unsigned integer content does not match the minInclusive facet. + + + Unsigned integer content does not match the minExclusive facet. + Unsigned integer content does not match the minExclusive facet. + + + Unsigned integer content is not listed in the enumeration facet. + Unsigned integer content is not listed in the enumeration facet. + + + Unsigned integer content does not match pattern facet. + Unsigned integer content does not match pattern facet. + + + Unsigned integer content does not match in the totalDigits facet. + Unsigned integer content does not match in the totalDigits facet. + + + Double content does not match the maxInclusive facet. + Double content does not match the maxInclusive facet. + + + Double content does not match the maxExclusive facet. + Double content does not match the maxExclusive facet. + + + Double content does not match the minInclusive facet. + Double content does not match the minInclusive facet. + + + Double content does not match the minExclusive facet. + Double content does not match the minExclusive facet. + + + Double content is not listed in the enumeration facet. + Double content is not listed in the enumeration facet. + + + Double content does not match pattern facet. + Double content does not match pattern facet. + + + Decimal content does not match in the fractionDigits facet. + Decimal content does not match in the fractionDigits facet. + + + Decimal content does not match in the totalDigits facet. + Decimal content does not match in the totalDigits facet. + + + Date time content does not match the maxInclusive facet. + Date time content does not match the maxInclusive facet. + + + Date time content does not match the maxExclusive facet. + Date time content does not match the maxExclusive facet. + + + Date time content does not match the minInclusive facet. + Date time content does not match the minInclusive facet. + + + Date time content does not match the minExclusive facet. + Date time content does not match the minExclusive facet. + + + Date time content is not listed in the enumeration facet. + Date time content is not listed in the enumeration facet. + + + Date time content does not match pattern facet. + Date time content does not match pattern facet. + + + Duration content does not match the maxInclusive facet. + Duration content does not match the maxInclusive facet. + + + Duration content does not match the maxExclusive facet. + Duration content does not match the maxExclusive facet. + + + Duration content does not match the minInclusive facet. + Duration content does not match the minInclusive facet. + + + Duration content does not match the minExclusive facet. + Duration content does not match the minExclusive facet. + + + Duration content is not listed in the enumeration facet. + Duration content is not listed in the enumeration facet. + + + Duration content does not match pattern facet. + Duration content does not match pattern facet. + + + Boolean content does not match pattern facet. + Boolean content does not match pattern facet. + + + Binary content does not match the length facet. + Binary content does not match the length facet. + + + Binary content does not match the minLength facet. + Binary content does not match the minLength facet. + + + Binary content does not match the maxLength facet. + Binary content does not match the maxLength facet. + + + Binary content is not listed in the enumeration facet. + Binary content is not listed in the enumeration facet. + + + Invalid QName content: %1. + Invalid QName content: %1. + + + QName content is not listed in the enumeration facet. + QName content is not listed in the enumeration facet. + + + QName content does not match pattern facet. + QName content does not match pattern facet. + + + Notation content is not listed in the enumeration facet. + Notation content is not listed in the enumeration facet. + + + List content does not match length facet. + List content does not match length facet. + + + List content does not match minLength facet. + List content does not match minLength facet. + + + List content does not match maxLength facet. + List content does not match maxLength facet. + + + List content is not listed in the enumeration facet. + List content is not listed in the enumeration facet. + + + List content does not match pattern facet. + List content does not match pattern facet. + + + Union content is not listed in the enumeration facet. + Union content is not listed in the enumeration facet. + + + Union content does not match pattern facet. + Union content does not match pattern facet. + + + Data of type %1 are not allowed to be empty. + Data of type %1 are not allowed to be empty. + + + Element %1 is missing child element. + Element %1 is missing child element. + + + There is one IDREF value with no corresponding ID: %1. + There is one IDREF value with no corresponding ID: %1. + + + Loaded schema file is invalid. + Loaded schema file is invalid. + + + %1 contains invalid data. + %1 contains invalid data. + + + xsi:schemaLocation namespace %1 has already appeared earlier in the instance document. + xsi:schemaLocation namespace %1 has already appeared earlier in the instance document. + + + xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute. + xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute. + + + No schema defined for validation. + No schema defined for validation. + + + No definition for element %1 available. + No definition for element %1 available. + + + Specified type %1 is not known to the schema. + Specified type %1 is not known to the schema. + + + Element %1 is not defined in this scope. + Element %1 is not defined in this scope. + + + Declaration for element %1 does not exist. + Declaration for element %1 does not exist. + + + Element %1 contains invalid content. + Element %1 contains invalid content. + + + Element %1 is declared as abstract. + Element %1 is declared as abstract. + + + Element %1 is not nillable. + Element %1 is not nillable. + + + Attribute %1 contains invalid data: %2 + Attribute %1 contains invalid data: %2 + + + Element contains content although it is nillable. + Element contains content although it is nillable. + + + Fixed value constraint not allowed if element is nillable. + Fixed value constraint not allowed if element is nillable. + + + Element %1 cannot contain other elements, as it has a fixed content. + Element %1 cannot contain other elements, as it has a fixed content. + + + Specified type %1 is not validly substitutable with element type %2. + Specified type %1 is not validly substitutable with element type %2. + + + Complex type %1 is not allowed to be abstract. + Complex type %1 is not allowed to be abstract. + + + Element %1 contains not allowed attributes. + Element %1 contains not allowed attributes. + + + Element %1 contains not allowed child element. + Element %1 contains not allowed child element. + + + Content of element %1 does not match its type definition: %2. + Content of element %1 does not match its type definition: %2. + + + Content of element %1 does not match defined value constraint. + Content of element %1 does not match defined value constraint. + + + Element %1 contains not allowed child content. + Element %1 contains not allowed child content. + + + Element %1 contains not allowed text content. + Element %1 contains not allowed text content. + + + Element %1 is missing required attribute %2. + Element %1 is missing required attribute %2. + + + Attribute %1 does not match the attribute wildcard. + Attribute %1 does not match the attribute wildcard. + + + Declaration for attribute %1 does not exist. + Declaration for attribute %1 does not exist. + + + Element %1 contains two attributes of type %2. + Element %1 contains two attributes of type %2. + + + Attribute %1 contains invalid content. + Attribute %1 contains invalid content. + + + Element %1 contains unknown attribute %2. + Element %1 contains unknown attribute %2. + + + Content of attribute %1 does not match its type definition: %2. + Content of attribute %1 does not match its type definition: %2. + + + Content of attribute %1 does not match defined value constraint. + Content of attribute %1 does not match defined value constraint. + + + Non-unique value found for constraint %1. + Non-unique value found for constraint %1. + + + Key constraint %1 contains absent fields. + Key constraint %1 contains absent fields. + + + Key constraint %1 contains references nillable element %2. + Key constraint %1 contains references nillable element %2. + + + No referenced value found for key reference %1. + No referenced value found for key reference %1. + + + More than one value found for field %1. + More than one value found for field %1. + + + Field %1 has no simple type. + Field %1 has no simple type. + + + ID value '%1' is not unique. + ID value '%1' is not unique. + + + '%1' attribute contains invalid QName content: %2. + '%1' attribute contains invalid QName content: %2. + + + diff --git a/config.profiles/symbian/translations/qt_fr_symbian.ts b/config.profiles/symbian/translations/qt_fr_symbian.ts new file mode 100644 index 0000000..c0b0699 --- /dev/null +++ b/config.profiles/symbian/translations/qt_fr_symbian.ts @@ -0,0 +1,8519 @@ + + + + + + CloseButton + + Close Tab + Fermer l'onglet + + + + FakeReply + + Fake error ! + Fausse erreur! + + + Invalid URL + URL non valide + + + + Phonon:: + + Notifications + Notifications + + + Music + Musique + + + Video + Vidéo + + + Communication + Communication + + + Games + Jeux + + + Accessibility + Accessibilité + + + + Phonon::AudioOutput + + <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> + <html>L'appareil de lecture audio <b>%1</b> ne fonctionne pas.<br/>Retour à <b>%2</b>.</html> + + + <html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html> + <html>Basculement vers l'appareil de lecture audio <b>%1</b><br/>qui vient juste d'être disponible et dont le niveau de préférence est plus élevé.</html> + + + Revert back to device '%1' + Revenir à l'appareil '%1' + + + + Phonon::Gstreamer::Backend + + Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. + Some video features have been disabled. + Attention: Vous n'avez apparemment pas installé le paquet gstreamer0.10-plugins-good. +Des fonctionnalités vidéo ont été desactivées. + + + Warning: You do not seem to have the base GStreamer plugins installed. + All audio and video support has been disabled + Attention: Vous n'avez apparemment pas installées les plugins de base de GStreamer. +Le support audio et vidéo est désactivé + + + + Phonon::Gstreamer::MediaObject + + Cannot start playback. + +Check your GStreamer installation and make sure you +have libgstreamer-plugins-base installed. + + + + A required codec is missing. You need to install the following codec(s) to play this content: %0 + Un codec requis est manquant. Vous devez installer le codec suivant pour jouer le contenu: %0 + + + Could not open media source. + Impossible d'ouvrir le média source. + + + Invalid source type. + Type de source invalide. + + + Could not locate media source. + Impossible de localiser le média source. + + + Could not open audio device. The device is already in use. + Impossible d'ouvrir le périphérique audio. Celui-ci est déjà en cours d'utilisation. + + + Could not decode media source. + Impossible de décoder le média source. + + + + Phonon::MMF + + Audio Output + Sortie audio + + + The audio output device + Appareil de sortie audio + + + No error + Aucune erreur + + + Not found + Introuvable + + + Out of memory + Mémoire insuffisante + + + Not supported + Non supporté + + + Overflow + Dépassement + + + Underflow + Soupassement + + + Already exists + Existe déjà + + + Path not found + Chemin introuvable + + + In use + Utilisé + + + Not ready + Pas prêt + + + Access denied + Accès refusé + + + Could not connect + Connexion impossible + + + Disconnected + Déconnecté + + + Permission denied + Autorisation refusée + + + Insufficient bandwidth + Bande passante insuffisante + + + Network unavailable + Réseau non disponible + + + Network communication error + Erreur de communication réseau + + + Streaming not supported + Streaming non supporté + + + Server alert + Alerte serveur + + + Invalid protocol + Protocole non valide + + + Invalid URL + URL non valide + + + Multicast error + Erreur multicast + + + Proxy server error + Erreur du serveur proxy + + + Proxy server not supported + Serveur proxy non supporté + + + Audio output error + Erreur de sortie audio + + + Video output error + Erreur de sortie vidéo + + + Decoder error + Erreur du décodeur + + + Audio or video components could not be played + Les composants audio ou vidéo n'ont pas pu être lus + + + DRM error + Erreur GDN + + + Unknown error (%1) + Erreur inconnue (%1) + + + + Phonon::MMF::AbstractMediaPlayer + + Not ready to play + Pas prêt pour lecture + + + Error opening file + Erreur lors de l'ouverture du fichier + + + Error opening URL + Erreur lors de l'ouverture de l'URL + + + Setting volume failed + Le réglage du volume a échoué + + + Playback complete + Lecture terminée + + + + Phonon::MMF::AudioEqualizer + + %1 Hz + %1 Hz + + + + Phonon::MMF::AudioPlayer + + Getting position failed + L'obtention de la position a échoué + + + Opening clip failed + L'ouverture du clip a échoué + + + + Phonon::MMF::EffectFactory + + Enabled + Activé + + + + Phonon::MMF::EnvironmentalReverb + + Decay HF ratio (%) + Ratio HF du déclin (%) + + + Decay time (ms) + Temps de déclin (ms) + + + Density (%) + Densité (%) + + + Diffusion (%) + Diffusion (%) + + + Reflections delay (ms) + Délai réflexions (ms) + + + Reflections level (mB) + Niveau réflexions (mB) + + + Reverb delay (ms) + Délai de réverbération (ms) + + + Reverb level (mB) + Niveau de réverbération (mB) + + + Room HF level + Niveau HF pièce + + + Room level (mB) + Niveau pièce (mB) + + + + Phonon::MMF::MediaObject + + Error opening source: type not supported + Erreur lors de l'ouverture de la source: type non supporté + + + Error opening source: media type could not be determined + Erreur lors de l'ouverture de la source: type de média non déterminé + + + + Phonon::MMF::StereoWidening + + Level (%) + Niveau (%) + + + + Phonon::MMF::VideoPlayer + + Pause failed + La mise en pause a échoué + + + Seek failed + La recherche a échoué + + + Getting position failed + L'obtention de la position a échoué + + + Opening clip failed + L'ouverture du clip a échoué + + + Buffering clip failed + La mise en mémoire tampon du clip a échoué + + + Video display error + Erreur de l'affichage vidéo + + + + Phonon::VolumeSlider + + Volume: %1% + Volume: %1% + + + Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1% + Utilisez le slider pour ajuster le volume. La position la plus à gauche est 0%, la plus à droite est %1% + + + Muted + Son coupé + + + + Q3Accel + + %1, %2 not defined + La séquence %1, %2 n'est pas définie + + + Ambiguous %1 not handled + Séquence ambiguë %1 non traitée + + + + Q3DataTable + + True + Vrai + + + False + Faux + + + Insert + Insérer + + + Update + Actualiser + + + Delete + Supprimer + + + + Q3FileDialog + + Copy or Move a File + Copie ou déplace un fichier + + + Read: %1 + Lecture : %1 + + + Write: %1 + Écriture : %1 + + + Cancel + Annuler + + + All Files (*) + Tous les fichiers (*) + + + Name + Nom + + + Size + Taille + + + Type + Type + + + Date + Date + + + Attributes + Attributs + + + &OK + &OK + + + Look &in: + Chercher &dans : + + + File &name: + &Nom de fichier : + + + File &type: + &Type de fichier : + + + Back + Précédent (historique) + + + One directory up + Aller au dossier parent + + + Create New Folder + Créer un nouveau dossier + + + List View + Affichage liste + + + Detail View + Affichage détaillé + + + Preview File Info + Informations du fichier prévisualisé + + + Preview File Contents + Contenu du fichier prévisualisé + + + Read-write + Lecture-écriture + + + Read-only + Lecture seule + + + Write-only + Écriture seule + + + Inaccessible + Inaccessible + + + Symlink to File + Lien symbolique vers un fichier + + + Symlink to Directory + Lien symbolique vers un dossier + + + Symlink to Special + Lien symbolique vers un fichier spécial + + + File + Fichier + + + Dir + Dossier + + + Special + Fichier spécial + + + Open + Ouvrir + + + Save As + Enregistrer sous + + + &Open + &Ouvrir + + + &Save + &Enregistrer + + + &Rename + &Renommer + + + &Delete + Suppri&mer + + + R&eload + R&echarger + + + Sort by &Name + Trier par &nom + + + Sort by &Size + Trier par ta&ille + + + Sort by &Date + Trier par &date + + + &Unsorted + &Non trié + + + Sort + Tri + + + Show &hidden files + Afficher les fic&hiers cachés + + + the file + le fichier + + + the directory + le dossier + + + the symlink + le lien symbolique + + + Delete %1 + Supprimer %1 + + + <qt>Are you sure you wish to delete %1 "%2"?</qt> + <qt>Voulez-vous vraiment supprimer %1 "%2" ?</qt> + + + &Yes + &Oui + + + &No + &Non + + + New Folder 1 + Nouveau dossier 1 + + + New Folder + Nouveau dossier + + + New Folder %1 + Nouveau dossier %1 + + + Find Directory + Chercher dans le dossier + + + Directories + Dossiers + + + Directory: + Dossier : + + + Error + Erreur + + + %1 +File not found. +Check path and filename. + %1 +Impossible de trouver le fichier. +Vérifier le chemin et le nom du fichier. + + + All Files (*.*) + Tous les fichiers (*.*) + + + Open + Ouvrir + + + Select a Directory + Sélectionner un dossier + + + + Q3LocalFs + + Could not read directory +%1 + Impossible de lire le dossier +%1 + + + Could not create directory +%1 + Impossible de créer le dossier +%1 + + + Could not remove file or directory +%1 + Impossible de supprimer le fichier ou dossier +%1 + + + Could not rename +%1 +to +%2 + Impossible de renommer +%1 +en +%2 + + + Could not open +%1 + Impossible d'ouvrir +%1 + + + Could not write +%1 + Impossible d'écrire +%1 + + + + Q3MainWindow + + Line up + Aligner + + + Customize... + Personnaliser... + + + + Q3NetworkProtocol + + Operation stopped by the user + Opération interrompue par l'utilisateur + + + + Q3ProgressDialog + + Cancel + Annuler + + + + Q3TabDialog + + OK + OK + + + Apply + Appliquer + + + Help + Aide + + + Defaults + Par défaut + + + Cancel + Annuler + + + + Q3TextEdit + + &Undo + &Annuler + + + &Redo + &Rétablir + + + Cu&t + Co&uper + + + &Copy + Cop&ier + + + &Paste + Co&ller + + + Clear + Effacer + + + Select All + Tout sélectionner + + + + Q3TitleBar + + System + Système + + + Restore up + Restaurer en haut + + + Minimize + Réduire + + + Restore down + Restaurer en bas + + + Maximize + Maximiser + + + Close + Fermer + + + Contains commands to manipulate the window + Contient des commandes pour manipuler la fenêtre + + + Puts a minimized window back to normal + + + + Moves the window out of the way + Déplace la fenêtre à l'écart + + + Puts a maximized window back to normal + Rend à une fenêtre minimisée son aspect normal + + + Makes the window full screen + Affiche la fenêtre en plein écran + + + Closes the window + Ferme la fenêtre + + + Displays the name of the window and contains controls to manipulate it + Affiche le nom de la fenêtre et contient des contrôles pour la manipuler + + + + Q3ToolBar + + More... + Reste... + + + + Q3UrlOperator + + The protocol `%1' is not supported + Le protocole '%1' n'est pas géré + + + The protocol `%1' does not support listing directories + Le protocole `%1' ne permet pas de lister les fichiers d'un dossier + + + The protocol `%1' does not support creating new directories + Le protocole `%1' ne permet pas de créer de nouveaux dossiers + + + The protocol `%1' does not support removing files or directories + Le protocole `%1' ne permet pas de supprimer des fichiers ou des dossiers + + + The protocol `%1' does not support renaming files or directories + Le protocole `%1' ne permet pas de renommer des fichiers ou des dossiers + + + The protocol `%1' does not support getting files + Le protocole `%1' ne permet pas de recevoir des fichiers + + + The protocol `%1' does not support putting files + Le protocole `%1' ne permet pas d'envoyer des fichiers + + + The protocol `%1' does not support copying or moving files or directories + Le protocole `%1' ne permet pas de copier ou de déplacer des fichiers + + + (unknown) + (inconnu) + + + + Q3Wizard + + &Cancel + &Annuler + + + < &Back + < &Précédent + + + &Next > + &Suivant > + + + &Finish + &Terminer + + + &Help + &Aide + + + + QAbstractSocket + + Host not found + Hôte introuvable + + + Connection refused + Connexion refusée + + + Connection timed out + Connexion expirée + + + Operation on socket is not supported + Opération sur socket non supportée + + + Socket operation timed out + Opération socket expirée + + + Socket is not connected + Le socket n'est pas connecté + + + Network unreachable + Réseau impossible à rejoindre + + + + QAbstractSpinBox + + &Step up + &Augmenter + + + Step &down + &Diminuer + + + &Select All + Tout &sélectionner + + + + QAccessibleButton + + Press + Appuyer + + + + QApplication + + QT_LAYOUT_DIRECTION + Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. + LTR + + + Executable '%1' requires Qt %2, found Qt %3. + L'exécutable '%1' requiert Qt %2 (Qt %3 présent). + + + Incompatible Qt Library Error + Erreur : bibliothèque Qt incompatible + + + Activate + Activer + + + Activates the program's main window + Active la fenêtre principale du programme + + + + QAxSelect + + Select ActiveX Control + Sélectionner un contrôle ActiveX + + + OK + OK + + + &Cancel + &Annuler + + + COM &Object: + &Objet COM : + + + + QCheckBox + + Uncheck + Décocher + + + Check + Cocher + + + Toggle + Changer + + + + QColorDialog + + Hu&e: + &Teinte : + + + &Sat: + &Saturation : + + + &Val: + &Valeur : + + + &Red: + &Rouge : + + + &Green: + &Vert : + + + Bl&ue: + Ble&u : + + + A&lpha channel: + Canal a&lpha : + + + Select Color + Sélectionner une couleur + + + &Basic colors + Couleurs de &base + + + &Custom colors + &Couleurs personnalisées + + + &Add to Custom Colors + &Ajouter aux couleurs personnalisées + + + + QComboBox + + Open + Ouvrir + + + False + Faux + + + True + Vrai + + + Close + Fermer + + + + QCoreApplication + + %1: key is empty + QSystemSemaphore + %1: clé vide + + + %1: unable to make key + QSystemSemaphore + %1: impossible de créer la clé + + + %1: ftok failed + QSystemSemaphore + %1: ftok a échoué + + + %1: already exists + QSystemSemaphore + %1: existe déjà + + + %1: does not exist + QSystemSemaphore + %1: n'existe pas + + + %1: out of resources + QSystemSemaphore + %1: plus de ressources disponibles + + + %1: unknown error %2 + QSystemSemaphore + %1: erreur inconnue %2 + + + + QDB2Driver + + Unable to connect + Incapable d'établir une connexion + + + Unable to commit transaction + Incapable de soumettre la transaction + + + Unable to rollback transaction + Incapable d'annuler la transaction + + + Unable to set autocommit + Impossible d'activer l'auto-soumission + + + + QDB2Result + + Unable to execute statement + Impossible d'exécuter la requête + + + Unable to prepare statement + Impossible de prépare la requête + + + Unable to bind variable + Impossible d'attacher la variable + + + Unable to fetch record %1 + Impossible de récupérer l'enregistrement %1 + + + Unable to fetch next + Impossible de récupérer le suivant + + + Unable to fetch first + Impossible de récupérer le premier + + + + QDateTimeEdit + + AM + AM + + + am + am + + + PM + PM + + + pm + pm + + + + QDial + + QDial + QDial + + + SpeedoMeter + Tachymètre + + + SliderHandle + Poignée + + + + QDialog + + What's This? + Qu'est-ce que c'est ? + + + Done + Terminer + + + + QDialogButtonBox + + OK + OK + + + Save + Enregistrer + + + &Save + Enregi&strer + + + Open + Ouvrir + + + Cancel + Annuler + + + &Cancel + &Annuler + + + Close + Fermer + + + &Close + &Fermer + + + Apply + Appliquer + + + Reset + Réinitialiser + + + Help + Aide + + + Don't Save + Ne pas enregistrer + + + Discard + Ne pas enregistrer + + + &Yes + &Oui + + + Yes to &All + Oui à &tout + + + &No + &Non + + + N&o to All + Non à to&ut + + + Save All + Tout Enregistrer + + + Abort + Abandonner + + + Retry + Réessayer + + + Ignore + Ignorer + + + Restore Defaults + Restaurer les valeurs par défaut + + + Close without Saving + Fermer sans sauvegarder + + + &OK + &OK + + + + QDirModel + + Name + Nom + + + Size + Taille + + + Kind + Match OS X Finder + Type + + + Type + All other platforms + Type + + + Date Modified + Dernière Modification + + + + QDockWidget + + Close + Fermer + + + Dock + Attacher + + + Float + Détacher + + + + QDoubleSpinBox + + More + Plus + + + Less + Moins + + + + QErrorMessage + + &Show this message again + &Afficher ce message de nouveau + + + &OK + &OK + + + Debug Message: + Message de débogage: + + + Warning: + Avertissement: + + + Fatal Error: + Erreur fatale: + + + + QFile + + Destination file exists + Le fichier destination existe + + + Will not rename sequential file using block copy + Ne renommera pas le fichier séquentiel avec la copie bloc + + + Cannot remove source file + Impossible de supprimer le fichier source + + + Cannot open %1 for input + Impossible d'ouvrir %1 pour lecture + + + Cannot open for output + Impossible d'ouvrir pour écriture + + + Failure to write block + Impossible d'écrire un bloc + + + Cannot create %1 for output + Impossible de créer %1 pour écriture + + + + QFileDialog + + All Files (*) + Tous les fichiers (*) + + + Back + Précédent (historique) + + + List View + Affichage liste + + + Detail View + Affichage détaillé + + + File + Fichier + + + Open + Ouvrir + + + Save As + Enregistrer sous + + + &Open + &Ouvrir + + + &Save + &Enregistrer + + + Recent Places + Emplacements récents + + + &Rename + &Renommer + + + &Delete + Suppri&mer + + + Show &hidden files + Afficher les fic&hiers cachés + + + New Folder + Nouveau dossier + + + Find Directory + Chercher dans le dossier + + + Directories + Dossiers + + + All Files (*.*) + Tous les fichiers (*.*) + + + Directory: + Dossier : + + + %1 already exists. +Do you want to replace it? + Le fichier %1 existe déjà. Voulez-vous l'écraser ? + + + %1 +File not found. +Please verify the correct file name was given. + %1 +Fichier introuvable. +Veuillez vérifier que le nom du fichier est correct. + + + My Computer + Poste de travail + + + Parent Directory + Dossier parent + + + Files of type: + Fichiers de type : + + + %1 +Directory not found. +Please verify the correct directory name was given. + %1 +Dossier introuvable. +Veuillez vérifier que le nom du dossier est correct. + + + '%1' is write protected. +Do you want to delete it anyway? + '%1' est protégé en écriture. +Voulez-vous quand même le supprimer ? + + + Are sure you want to delete '%1'? + Etes-vous sûr de vouloir supprimer '%1' ? + + + Could not delete directory. + Impossible de supprimer le dossier. + + + Drive + Unité + + + File Folder + Match Windows Explorer + Fichier Dossier + + + Folder + All other platforms + Dossier + + + Alias + Mac OS X Finder + Pseudo + + + Shortcut + All other platforms + Raccourci + + + Unknown + Inconnu + + + Show + Montrer + + + Forward + Successeur + + + &New Folder + &Nouveau dossier + + + &Choose + &Choisir + + + Remove + Supprimer + + + File &name: + &Nom de fichier : + + + Look in: + Voir dans: + + + Create New Folder + Créer un nouveau dossier + + + + QFileSystemModel + + %1 TB + %1 To + + + %1 GB + %1 Go + + + %1 MB + %1 Mo + + + %1 KB + %1 Ko + + + %1 bytes + %1 octets + + + Invalid filename + Nom de fichier invalide + + + <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. + <b>Le nom "%1" ne peut pas être utilisé.</b><p>Essayez un autre nom avec moins de caractères ou sans ponctuation. + + + Name + Nom + + + Size + Taille + + + Kind + Match OS X Finder + Type + + + Type + All other platforms + Type + + + Date Modified + Dernière modification + + + My Computer + Mon ordinateur + + + Computer + Ordinateur + + + %1 byte(s) + %1 octet(s) + + + + QFontDatabase + + Normal + Normal + + + Bold + Gras + + + Demi Bold + Semi Gras + + + Black + Noir + + + Demi + Demi + + + Light + Léger + + + Italic + Italique + + + Oblique + Oblique + + + Any + Tous + + + Latin + Latin + + + Greek + Grec + + + Cyrillic + Cyrillique + + + Armenian + Arménien + + + Hebrew + Hébreu + + + Arabic + Arabe + + + Syriac + Syriaque + + + Thaana + Thaana + + + Devanagari + Devanagari + + + Bengali + Bengali + + + Gurmukhi + Gurmukhi + + + Gujarati + Gujarati + + + Oriya + Oriya + + + Tamil + Tamil + + + Telugu + Telugu + + + Kannada + Kannada + + + Malayalam + Malayalam + + + Sinhala + Sinhala + + + Thai + Thaï + + + Lao + Lao + + + Tibetan + Tibétain + + + Myanmar + Myanmar + + + Georgian + Géorgien + + + Khmer + Khmer + + + Simplified Chinese + Chinois Simplifié + + + Traditional Chinese + Chinois Traditionnel + + + Japanese + Japonais + + + Korean + Coréen + + + Vietnamese + Vietnamien + + + Symbol + Symbole + + + Ogham + Ogham + + + Runic + Runique + + + N'Ko + N'Ko + + + + QFontDialog + + &Font + &Police + + + Font st&yle + St&yle de police + + + &Size + &Taille + + + Effects + Effets + + + Stri&keout + &Barré + + + &Underline + &Souligné + + + Sample + Exemple + + + Select Font + Choisir une police + + + Wr&iting System + &Système d'écriture + + + + QFtp + + Host %1 found + Hôte %1 trouvé + + + Host found + Hôte trouvé + + + Connected to host %1 + Connecté à l'hôte %1 + + + Connected to host + Connecté à l'hôte + + + Connection to %1 closed + Connexion à %1 arrêtée + + + Connection closed + Connexion arrêtée + + + Host %1 not found + Hôte %1 introuvable + + + Connection refused to host %1 + Connexion à l'hôte %1 refusée + + + Connection timed out to host %1 + Connexion expirée vers l'hôte %1 + + + Unknown error + Erreur inconnue + + + Connecting to host failed: +%1 + Échec de la connexion à l'hôte +%1 + + + Login failed: +%1 + Échec du login: +%1 + + + Listing directory failed: +%1 + Échec du listage du dossier : +%1 + + + Changing directory failed: +%1 + Échec du changement de dossier : +%1 + + + Downloading file failed: +%1 + Échec du téléchargement du fichier : +%1 + + + Uploading file failed: +%1 + Échec du télédéchargement : +%1 + + + Removing file failed: +%1 + Échec de la suppression d'un fichier : +%1 + + + Creating directory failed: +%1 + Échec de la création d'un dossier : +%1 + + + Removing directory failed: +%1 + Échec de la suppression d'un dossier : +%1 + + + Not connected + Non connecté + + + Connection refused for data connection + Connexion donnée refusée + + + + QHostInfo + + Unknown error + Erreur inconnue + + + + QHostInfoAgent + + Host not found + Hôte introuvable + + + Unknown address type + Adresse de type inconnu + + + Unknown error + Erreur inconnue + + + No host name given + Aucun nom d'hôte n'a été donné + + + Invalid hostname + Nom d'hôte non valide + + + + QHttp + + Connection refused + Connexion refusée + + + Host %1 not found + Hôte %1 introuvable + + + Wrong content length + Longueur du contenu invalide + + + HTTP request failed + Échec de la requête HTTP + + + Host %1 found + Hôte %1 trouvé + + + Host found + Hôte trouvé + + + Connected to host %1 + Connecté à l'hôte %1 + + + Connected to host + Connecté à l'hôte + + + Connection to %1 closed + Connexion à %1 arrêtée + + + Connection closed + Connexion arrêtée + + + Unknown error + Erreur inconnue + + + Request aborted + Requête interrompue + + + No server set to connect to + Aucun serveur spécifié + + + Server closed connection unexpectedly + Connexion interrompue par le serveur + + + Invalid HTTP response header + Entête de réponse HTTP invalide + + + Unknown authentication method + Méthode d'authentification inconnue + + + Invalid HTTP chunked body + Fragment HTTP invalide + + + Error writing response to device + Erreur lors de l'écriture de la réponse + + + Proxy authentication required + Le proxy requiert une authentification + + + Authentication required + Authentification requise + + + Proxy requires authentication + Le proxy requiert une authentification + + + Host requires authentication + L'hôte requiert une authentification + + + Data corrupted + Données corrompues + + + SSL handshake failed + le handshake SSL a échoué + + + Unknown protocol specified + Protocole spécifié inconnu + + + Connection refused (or timed out) + Connexion refusée (ou délai expiré) + + + HTTPS connection requested but SSL support not compiled in + Connexion HTTPS requise mais le support SSL n'est pas compilé + + + + QHttpSocketEngine + + Did not receive HTTP response from proxy + Pas de réponse HTTP de la part du proxy + + + Error parsing authentication request from proxy + Erreur dans le reqête d'authentification reçue du proxy + + + Authentication required + Authentification requise + + + Proxy denied connection + Le Proxy a rejeté la connexion + + + Error communicating with HTTP proxy + Erreur de communication avec le proxy HTTP + + + Proxy server not found + Serveur proxy introuvable + + + Proxy connection refused + Connexion au proxy refusée + + + Proxy server connection timed out + La connexion au serveur proxy a expiré + + + Proxy connection closed prematurely + La connexion au serveur proxy a été fermée prématurément + + + + QIBaseDriver + + Error opening database + Erreur d'ouverture de la base de données + + + Could not start transaction + La transaction n'a pas pu être démarrée + + + Unable to commit transaction + Incapable de soumettre la transaction + + + Unable to rollback transaction + Incapable d'annuler la transaction + + + + QIBaseResult + + Unable to create BLOB + Impossible de créer un BLOB + + + Unable to write BLOB + Impossible d'écrire le BLOB + + + Unable to open BLOB + Impossible d'ouvrir le BLOB + + + Unable to read BLOB + Impossible de lire le BLOB + + + Could not find array + Impossible de trouver le tableau + + + Could not get array data + Impossible de trouver le tableau de données + + + Could not get query info + Impossible d'avoir les informations sur la requête + + + Could not start transaction + Impossible de démarrer la transaction + + + Unable to commit transaction + Incapable de soumettre la transaction + + + Could not allocate statement + Impossible d'allouer la requête + + + Could not prepare statement + Impossible de préparer la requête + + + Could not describe input statement + Impossible de décrire la requête + + + Could not describe statement + Impossible de décrire la requête + + + Unable to close statement + Impossible de fermer la requête + + + Unable to execute query + Impossible d'exécuter la requête + + + Could not fetch next item + Impossible de récuperer l'élément suivant + + + Could not get statement info + Impossible d'avoir les informations sur la requête + + + + QIODevice + + Permission denied + Accès refusé + + + Too many open files + Trop de fichiers ouverts simultanément + + + No such file or directory + Aucun fichier ou dossier de ce nom + + + No space left on device + Aucun espace disponible sur le périphérique + + + Unknown error + Erreur inconnue + + + + QInputContext + + XIM + XIM + + + FEP + Processeur frontal + + + XIM input method + Méthode d'entrée XIM + + + Windows input method + Méthode d'entrée Windows + + + Mac OS X input method + Méthode d'entrée Mac OS X + + + S60 FEP input method + Méthode de saisie processeur frontal S60 + + + + QInputDialog + + Enter a value: + Entrer une valeur : + + + + QLibrary + + Could not mmap '%1': %2 + Impossible d'établir la projection en mémoire de '%1' : %2 + + + Plugin verification data mismatch in '%1' + Données de vérification du plugin différente dans '%1' + + + Could not unmap '%1': %2 + Impossible de supprimer la projection en mémoire de '%1' : %2 + + + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] + Le plugin '%1' utilise une bibliothèque Qt incompatible. (%2.%3.%4) [%5] + + + The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" + Le plugin '%1' utilise une bibliothèque Qt incompatible. Clé attendue "%2", reçue "%3" + + + Unknown error + Erreur inconnue + + + The shared library was not found. + La bibliothèque partagée est introuvable. + + + The file '%1' is not a valid Qt plugin. + Le fichier '%1' n'est pas un plugin Qt valide. + + + The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) + Le plugin '%1' utilise une bibliothèque Qt incompatible. (Il est impossible de mélanger des bibliothèques 'debug' et 'release'.) + + + Cannot load library %1: %2 + Impossible de charger la bibliothèque %1 : %2 + + + Cannot unload library %1: %2 + Impossible de décharger la bibliothèque %1 : %2 + + + Cannot resolve symbol "%1" in %2: %3 + Impossible de résoudre le symbole "%1" dans %2 : %3 + + + + QLineEdit + + Select All + Tout sélectionner + + + &Undo + &Annuler + + + &Redo + &Rétablir + + + Cu&t + Co&uper + + + &Copy + Cop&ier + + + &Paste + Co&ller + + + Delete + Supprimer + + + + QLocalServer + + %1: Name error + %1: Erreur de nom + + + %1: Permission denied + %1: Permission refusée + + + %1: Address in use + %1: Address déjà utilisée + + + %1: Unknown error %2 + %1: Erreur inconnue %2 + + + + QLocalSocket + + %1: Connection refused + %1: Connexion refusée + + + %1: Remote closed + %1: Connexion fermée + + + %1: Invalid name + %1: Nom invalide + + + %1: Socket access error + %1: Erreur d'accès au socket + + + %1: Socket resource error + %1: Erreur de ressource du socket + + + %1: Socket operation timed out + %1: L'opération socket a expiré + + + %1: Datagram too large + %1: Datagramme trop grand + + + %1: Connection error + %1: Erreur de connexion + + + %1: The socket operation is not supported + %1: L'opération n'est pas supportée + + + %1: Unknown error + %1 : erreur inconnue + + + %1: Unknown error %2 + %1: Erreur inconnue %2 + + + + QMYSQLDriver + + Unable to open database ' + Impossible d'ouvrir la base de données ' + + + Unable to connect + Impossible d'établir une connexion + + + Unable to begin transaction + Impossible de démarrer la transaction + + + Unable to commit transaction + Impossible de soumettre la transaction + + + Unable to rollback transaction + Impossible d'annuler la transaction + + + + QMYSQLResult + + Unable to fetch data + Impossible de récuperer des données + + + Unable to execute query + Impossible d'exécuter la requête + + + Unable to store result + Impossible de stocker le résultat + + + Unable to prepare statement + Impossible de préparer l'instruction + + + Unable to reset statement + Impossible de réinitialiser l'instruction + + + Unable to bind value + Impossible d'attacher la valeur + + + Unable to execute statement + Impossible d'exécuter la requête + + + Unable to bind outvalues + Impossible d'attacher les valeurs de sortie + + + Unable to store statement results + Impossible de stocker les résultats de la requête + + + Unable to execute next query + Impossible d'exécuterla prochaine requête + + + Unable to store next result + Impossible de stocker le prochain résultat + + + + QMdiArea + + (Untitled) + (Sans titre) + + + + QMdiSubWindow + + %1 - [%2] + %1 - [%2] + + + Close + Fermer + + + Minimize + Réduire + + + Restore Down + Restaurer en bas + + + &Restore + &Restaurer + + + &Move + &Déplacer + + + &Size + &Taille + + + Mi&nimize + Réd&uire + + + Ma&ximize + Ma&ximiser + + + Stay on &Top + &Rester au premier plan + + + &Close + &Fermer + + + Maximize + Maximiser + + + Unshade + Restaurer + + + Shade + Ombrer + + + Restore + Restaurer + + + Help + Aide + + + Menu + Menu + + + - [%1] + - [%1] + + + + QMenu + + Close + Fermer + + + Open + Ouvrir + + + Execute + Exécuter + + + + QMenuBar + + Actions + Actions + + + + QMessageBox + + OK + OK + + + <h3>About Qt</h3><p>This program uses Qt version %1.</p> + <h3>Présentation de Qt</h3><p>Ce programme utilise Qt version %1.</p> + + + <p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p><p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://qt.nokia.com/">qt.nokia.com</a> for more information.</p> + <p>Qt est une boîte à outils C++ pour le développement d’applications multiplateformes.</p><p>Qt fournit une portabilité source unique pour MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux et les principales variantes commerciales d’Unix. Qt est également disponible pour appareils intégrés tels que Qt pour Embedded Linux et Qt pour Windows CE.</p><p>Il existe trois options de licence différentes conçues pour s’adapter aux besoins d’utilisateurs variés.</p><p>Qt concédée sous notre contrat de licence commerciale est destinée au développement de logiciels propriétaires/commerciaux dont vous ne souhaitez pas partager le code source avec des tiers ou qui ne peuvent se conformer aux termes de la LGPL GNU version 2.1 ou GPL GNU version 3.0.</p><p>Qt concédée sous la LGPL GNU version 2.1 est destinée au développement d’applications Qt (propriétaires ou source libre) à condition que vous vous conformiez aux conditions générales de la LGPL GNU version 2.1.</p><p>Qt concédée sous la licence publique générale GNU version 3.0 est destinée au développement d’applications Qt lorsque vous souhaitez utiliser ces applications avec d’autres logiciels soumis aux termes de la GPL GNU version 3.0 ou lorsque vous acceptez les termes de la GPL GNU version 3.0.</p><p>Veuillez consulter<a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a> pour un aperçu des concessions de licences Qt.</p><p>Copyright (C) 2010 Nokia Corporation et/ou ses filiales.</p><p>Qt est un produit Nokia. Voir <a href="http://qt.nokia.com/">qt.nokia.com</a> pour de plus amples informations.</p> + + + About Qt + À propos de Qt + + + Help + Aide + + + Show Details... + Montrer les détails... + + + Hide Details... + Cacher les détails... + + + + QMultiInputContext + + Select IM + Sélectionner IM + + + + QMultiInputContextPlugin + + Multiple input method switcher + Sélectionneur de méthode de saisie + + + Multiple input method switcher that uses the context menu of the text widgets + Sélectionneur de méthode de saisie qui utilise le menu contextuel des widgets de texte + + + + QNativeSocketEngine + + The remote host closed the connection + L'hôte distant a fermé la connexion + + + Network operation timed out + L'opération réseau a expiré + + + Out of resources + Manque de ressources + + + Unsupported socket operation + Opération socket non supportée + + + Protocol type not supported + Protocol non géré + + + Invalid socket descriptor + Descripteur de socket invalide + + + Network unreachable + Réseau impossible à rejoindre + + + Permission denied + Accès refusé + + + Connection timed out + Connexion expirée + + + Connection refused + Connexion refusée + + + The bound address is already in use + L'adresse liée est déjà en usage + + + The address is not available + L'adresse n'est pas disponible + + + The address is protected + L'adresse est protégée + + + Unable to send a message + Impossible d'envoyer un message + + + Unable to receive a message + Impossible de recevoir un message + + + Unable to write + Impossible d'écrire + + + Network error + Erreur réseau + + + Another socket is already listening on the same port + Un autre socket écoute déjà sur le même port + + + Unable to initialize non-blocking socket + Impossible d'initialiser le socket asynchrone + + + Unable to initialize broadcast socket + Impossible d'initialiser le socket broadcast + + + Attempt to use IPv6 socket on a platform with no IPv6 support + Tentative d'utiliser un socket IPv6 sur une plateforme qui ne supporte pas IPv6 + + + Host unreachable + Hôte inaccessible + + + Datagram was too large to send + Le datagramme était trop grand pour être envoyé + + + Operation on non-socket + Operation sur non-socket + + + Unknown error + Erreur inconnue + + + The proxy type is invalid for this operation + Le type de proxy est invalide pour cette opération + + + + QNetworkAccessCacheBackend + + Error opening %1 + Erreur lors de l'ouverture de %1 + + + + QNetworkAccessDebugPipeBackend + + Write error writing to %1: %2 + Erreur lors de l'écriture dans %1: %2 + + + + QNetworkAccessFileBackend + + Request for opening non-local file %1 + Requête d'ouverture de fichier distant %1 + + + Error opening %1: %2 + Erreur lors de l'ouverture de %1 : %2 + + + Write error writing to %1: %2 + Erreur d'écriture de %1 : %2 + + + Cannot open %1: Path is a directory + Impossible d'ouvrir %1 : le chemin est un dossier + + + Read error reading from %1: %2 + Erreur de lecture de %1 : %2 + + + + QNetworkAccessFtpBackend + + No suitable proxy found + Aucun proxy trouvé + + + Cannot open %1: is a directory + Impossible d'ouvrir %1 : le chemin est un dossier + + + Logging in to %1 failed: authentication required + Connexion à %1 a échoué : authentification requise + + + Error while downloading %1: %2 + Erreur lors du téléchargement de %1 : %2 + + + Error while uploading %1: %2 + Erreur lors de l'envoi de %1 : %2 + + + + QNetworkAccessHttpBackend + + No suitable proxy found + Aucun proxy trouvé + + + + QNetworkReply + + Error downloading %1 - server replied: %2 + Erreur lors du téléchargement de %1 - le serveur a répondu: %2 + + + Protocol "%1" is unknown + Le protocole "%1" est inconnu + + + + QNetworkReplyImpl + + Operation canceled + Opération annulée + + + + QOCIDriver + + Unable to logon + Impossible d'ouvrir une session + + + Unable to initialize + QOCIDriver + L'initialisation a échouée + + + Unable to begin transaction + Impossible de démarrer la transaction + + + Unable to commit transaction + Impossible d'enregistrer la transaction + + + Unable to rollback transaction + Impossible d'annuler la transaction + + + + QOCIResult + + Unable to bind column for batch execute + Impossible d'attacher la colonne pour une execution batch + + + Unable to execute batch statement + Impossible d'exécuter l'instruction batch + + + Unable to goto next + Impossible de passer au suivant + + + Unable to alloc statement + Impossible d'allouer la requête + + + Unable to prepare statement + Impossible de préparer la requête + + + Unable to get statement type + + + + Unable to bind value + Impossible d'attacher la valeur + + + Unable to execute statement + Impossible d'exéctuer la requête + + + + QODBCDriver + + Unable to connect + Incapable d'établir une connexion + + + Unable to disable autocommit + Impossible de désactiver l'autocommit + + + Unable to commit transaction + Incapable de soumettre la transaction + + + Unable to rollback transaction + Incapable d'annuler la transaction + + + Unable to enable autocommit + Impossible d'active l'autocommit + + + Unable to connect - Driver doesn't support all functionality required + + + + + QODBCResult + + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration + QODBCResult::reset: Impossible d'utiliser 'SQL_CURSOR_STATIC' comme attribut de requête. Veuillez vérifier la configuration de votre pilote ODBC + + + Unable to execute statement + Impossible d'exéctuer la requête + + + Unable to fetch next + Impossible de récupérer le suivant + + + Unable to prepare statement + Impossible de préparer la requête + + + Unable to bind variable + Impossible d'attacher la variable + + + Unable to fetch last + Impossible de récupérer le dernier + + + Unable to fetch + Impossible de récupérer + + + Unable to fetch first + Impossible de récupérer le premier + + + Unable to fetch previous + Impossible de récupérer le précedent + + + + QObject + + Invalid hostname + Nom d'hôte non valide + + + Operation not supported on %1 + Opération non supportée sur %1 + + + Invalid URI: %1 + URI invalide : %1 + + + Socket error on %1: %2 + Erreur de socket sur %1 : %2 + + + Remote host closed the connection prematurely on %1 + L'hôte distant a fermé sa connexion de façon prématurée sur %1 + + + No host name given + Nom d'hôte manquant + + + + QPPDOptionsModel + + Name + Nom + + + Value + Valeur + + + + QPSQLDriver + + Unable to connect + Impossible d'établir une connexion + + + Could not begin transaction + Impossible de démarrer la transaction + + + Could not commit transaction + Impossible de soumettre la transaction + + + Could not rollback transaction + Impossible d'annuler la transaction + + + Unable to subscribe + Impossible de s'inscrire + + + Unable to unsubscribe + Impossible de se désinscrire + + + + QPSQLResult + + Unable to create query + Impossible de créer la requête + + + Unable to prepare statement + Impossible de préparer la requête + + + + QPageSetupWidget + + Centimeters (cm) + Centimètres (cm) + + + Millimeters (mm) + Millimètres (mm) + + + Inches (in) + Pouces (in) + + + Points (pt) + Points (pts) + + + Form + Formulaire + + + Paper + Papier + + + Page size: + Dimensions : + + + Width: + Largeur : + + + Height: + Hauteur : + + + Paper source: + Source du papier : + + + Orientation + Orientation + + + Portrait + Portrait + + + Landscape + Paysage + + + Reverse landscape + Paysage inversé + + + Reverse portrait + Portrait inversé + + + Margins + Marges + + + top margin + marge haute + + + left margin + marge gauche + + + right margin + marge droite + + + bottom margin + marge basse + + + + QPluginLoader + + Unknown error + Erreur inconnue + + + The plugin was not loaded. + Le plugin n'a pas été chargé. + + + + QPrintDialog + + locally connected + connecté en local + + + Aliases: %1 + Alias : %1 + + + unknown + inconnu + + + OK + OK + + + Print all + Imprimer tout + + + Print range + Imprimer la sélection + + + A0 (841 x 1189 mm) + A0 (841 x 1189 mm) + + + A1 (594 x 841 mm) + A1 (594 x 841 mm) + + + A2 (420 x 594 mm) + A2 (420 x 594 mm) + + + A3 (297 x 420 mm) + A3 (297 x 420 mm) + + + A5 (148 x 210 mm) + A5 (148 x 210 mm) + + + A6 (105 x 148 mm) + A6 (105 x 148 mm) + + + A7 (74 x 105 mm) + A7 (74 x 105 mm) + + + A8 (52 x 74 mm) + A8 (52 x 74 mm) + + + A9 (37 x 52 mm) + A9 (37 x 52 mm) + + + B0 (1000 x 1414 mm) + B0 (1000 x 1414 mm) + + + B1 (707 x 1000 mm) + B1 (707 x 1000 mm) + + + B2 (500 x 707 mm) + B2 (500 x 707 mm) + + + B3 (353 x 500 mm) + B3 (353 x 500 mm) + + + B4 (250 x 353 mm) + B4 (250 x 353 mm) + + + B6 (125 x 176 mm) + B6 (125 x 176 mm) + + + B7 (88 x 125 mm) + B7 (88 x 125 mm) + + + B8 (62 x 88 mm) + B8 (62 x 88 mm) + + + B9 (44 x 62 mm) + B9 (44 x 62 mm) + + + B10 (31 x 44 mm) + B10 (31 x 44 mm) + + + C5E (163 x 229 mm) + C5E (163 x 229 mm) + + + DLE (110 x 220 mm) + DLE (110 x 220 mm) + + + Folio (210 x 330 mm) + Folio (210 x 330 mm) + + + Ledger (432 x 279 mm) + Ledger (432 x 279 mm) + + + Tabloid (279 x 432 mm) + Tabloïde (279 x 432 mm) + + + US Common #10 Envelope (105 x 241 mm) + US Common #10 Envelope (105 x 241 mm) + + + A4 (210 x 297 mm, 8.26 x 11.7 inches) + A4 (210 x 297 mm) + + + B5 (176 x 250 mm, 6.93 x 9.84 inches) + B5 (176 x 250 mm) + + + Executive (7.5 x 10 inches, 191 x 254 mm) + Executive (7,5 x 10 pouces, 191 x 254 mm) + + + Legal (8.5 x 14 inches, 216 x 356 mm) + Legal (8.5 x 14 pouces, 216 x 356 mm) + + + Letter (8.5 x 11 inches, 216 x 279 mm) + Letter (8,5 x 11 pouces, 216 x 279 mm) + + + Print selection + Imprimer la sélection + + + Print + Impr écran + + + Print To File ... + Imprimer dans un fichier... + + + File %1 is not writable. +Please choose a different file name. + Impossible d'écrire dans le fichier %1. +Veuillez choisir un nom de fichier différent. + + + %1 already exists. +Do you want to overwrite it? + %1 existe. +Voulez-vous l'écraser ? + + + File exists + Le fichier existe + + + <qt>Do you want to overwrite it?</qt> + <qt>voulez-vous l'écraser ?</qt> + + + %1 is a directory. +Please choose a different file name. + %1 est un dossier. +Veuillez choisir un nom de fichier différent. + + + The 'From' value cannot be greater than the 'To' value. + La valeur 'de' ne peut pas être plus grande que la valeur 'à'. + + + A0 + + + + A1 + + + + A2 + + + + A3 + + + + A4 + + + + A5 + + + + A6 + + + + A7 + + + + A8 + + + + A9 + + + + B0 + + + + B1 + + + + B2 + + + + B3 + + + + B4 + + + + B5 + + + + B6 + + + + B7 + + + + B8 + + + + B9 + + + + B10 + + + + C5E + + + + DLE + + + + Executive + + + + Folio + + + + Ledger + + + + Legal + + + + Letter + + + + Tabloid + + + + US Common #10 Envelope + + + + Custom + Personnalisé + + + &Options >> + + + + &Options << + + + + Print to File (PDF) + Imprimer dans un fichier (PDF) + + + Print to File (Postscript) + Imprimer dans un fichier (PostScript) + + + Local file + Fichier local + + + Write %1 file + Ecriture du fichier %1 + + + &Print + Im&primer + + + + QPrintPreviewDialog + + %1% + %1% + + + Print Preview + Aperçu avant impression + + + Next page + Page suivante + + + Previous page + Page précédente + + + First page + Première page + + + Last page + Dernière page + + + Fit width + Ajuster la largeur + + + Fit page + Ajuster la page + + + Zoom in + Zoom avant + + + Zoom out + Zoom arrière + + + Portrait + Portrait + + + Landscape + Paysage + + + Show single page + Afficher une seule page + + + Show facing pages + Afficher deux pages + + + Show overview of all pages + Afficher un aperçu de toutes les pages + + + Print + Impr écran + + + Page setup + Configuration de la page + + + Close + Fermer + + + Export to PDF + Exporter vers PDF + + + Export to PostScript + Exporter vers PostScript + + + Page Setup + Configuration de la page + + + + QPrintPropertiesWidget + + Form + Formulaire + + + Page + + + + Advanced + Avancé + + + + QPrintSettingsOutput + + Form + Formulaire + + + Copies + Copies + + + Print range + Imprimer la sélection + + + Print all + Imprimer tout + + + Pages from + Pages + + + to + à + + + Selection + Sélection + + + Output Settings + Paramètres de sortie + + + Copies: + + + + Collate + Assembler + + + Reverse + Inverse + + + Options + Options + + + Color Mode + Mode de couleur + + + Color + Couleur + + + Grayscale + Dégradé de gris + + + Duplex Printing + Impression en duplex + + + None + Aucun + + + Long side + Côté long + + + Short side + Côté court + + + + QPrintWidget + + Form + Formulaire + + + Printer + Imprimante + + + &Name: + &Nom : + + + P&roperties + P&ropriétés + + + Location: + Emplacement : + + + Preview + Prévisualisation + + + Type: + + + + Output &file: + &Fichier de sortie: + + + ... + + + + + QProcess + + Could not open input redirection for reading + Impossible d'ouvrir la redirection d'entrée en lecture + + + Could not open output redirection for writing + Impossible d'ouvrir la redirection de sortie pour écriture + + + Resource error (fork failure): %1 + Erreur de ressouce (fork) : %1 + + + Process operation timed out + Operation de processus a expiré + + + Error reading from process + Erreur de lecture du processus + + + Error writing to process + Erreur d"écriture vers le processus + + + Process crashed + Le processus à planté + + + No program defined + Aucun programme défini + + + Process failed to start: %1 + Le démarrage du processus a échoué: %1 + + + + QProgressDialog + + Cancel + Annuler + + + + QPushButton + + Open + Ouvrir + + + + QRadioButton + + Check + Cocher + + + + QRegExp + + no error occurred + aucune erreur ne s'est produite + + + disabled feature used + option désactivée + + + bad char class syntax + syntaxe invalide pour classe de caractère + + + bad lookahead syntax + syntaxe invalide pour lookahead + + + bad repetition syntax + syntaxe invalide pour répétition + + + invalid octal value + valeur octale invalide + + + missing left delim + délémiteur gauche manquant + + + unexpected end + fin impromptue + + + met internal limit + rencontré limite interne + + + invalid interval + intervalle non valide + + + invalid category + catégorie non valide + + + + QSQLite2Driver + + Error opening database + Erreur lors de l'ouverture de la base de données + + + Unable to begin transaction + Impossible de démarrer la transaction + + + Unable to commit transaction + Impossible de soumettre la transaction + + + Unable to rollback transaction + Impossible de répéter la transaction + + + + QSQLite2Result + + Unable to fetch results + Impossible de récupérer les résultats + + + Unable to execute statement + Impossible d'exécuter la requête + + + + QSQLiteDriver + + Error opening database + Erreur lors de l'ouverture de la base de données + + + Error closing database + Erreur lors de la fermeture de la base de données + + + Unable to begin transaction + Impossible de démarrer la transaction + + + Unable to commit transaction + Incapable de soumettre la transaction + + + Unable to rollback transaction + Impossible d'annuler la transaction + + + + QSQLiteResult + + Unable to fetch row + Impossible de récupérer la rangée + + + Unable to execute statement + Impossible d'exécuter la requête + + + Unable to reset statement + Impossible de réinitialiser la requête + + + Unable to bind parameters + Impossible d'attacher les paramètres + + + Parameter count mismatch + Nombre de paramètres incorrect + + + No query + Pas de requête + + + + QScriptBreakpointsModel + + ID + Identifiant + + + Location + Lieu + + + Condition + Condition + + + Ignore-count + Comptes d'ignorés + + + Single-shot + Un seul tir + + + Hit-count + Compte de coups + + + + QScriptBreakpointsWidget + + New + Créer + + + Delete + Supprimer + + + + QScriptDebugger + + Go to Line + Aller à la ligne + + + Line: + Ligne: + + + Interrupt + Interrompre + + + Shift+F5 + Shift+F5 + + + Continue + Continuer + + + F5 + F5 + + + Step Into + Pas à pas détaillé + + + F11 + F11 + + + Step Over + Pas à pas principal + + + F10 + F10 + + + Step Out + Pas à pas sortant + + + Shift+F11 + Shift+F11 + + + Run to Cursor + Exécuter au curseur + + + Ctrl+F10 + Ctrl+F10 + + + Run to New Script + Exécuter au nouveau script + + + Toggle Breakpoint + Basculer le point d'arrêt + + + F9 + F9 + + + Clear Debug Output + Effacer les résultats du débogage + + + Clear Error Log + Effacer le journal d'erreurs + + + Clear Console + Effacer la console + + + &Find in Script... + &Chercher dans le script... + + + Ctrl+F + Ctrl+F + + + Find &Next + Résultat &suivant + + + F3 + F3 + + + Find &Previous + Chercher &précédent + + + Shift+F3 + Shift+F3 + + + Ctrl+G + Ctrl+G + + + Debug + Déboguer + + + + QScriptDebuggerCodeFinderWidget + + Close + Fermer + + + Previous + Précédent + + + Next + Suivant + + + Case Sensitive + Sensible à la casse + + + Whole words + Mots entiers + + + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;Search wrapped + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;La recherche est revenue au début + + + + QScriptDebuggerLocalsModel + + Name + Nom + + + Value + Valeur + + + + QScriptDebuggerStackModel + + Level + Niveau + + + Name + Nom + + + Location + Lieu + + + + QScriptEdit + + Toggle Breakpoint + Basculer le point d'arrêt + + + Disable Breakpoint + Désactiver le point d'arrêt + + + Enable Breakpoint + Activer le point d'arrêt + + + Breakpoint Condition: + Condition du point d'arrêt: + + + + QScriptEngineDebugger + + Loaded Scripts + Scripts chargés + + + Breakpoints + Points d'arrêt + + + Stack + Empiler + + + Locals + Locaux + + + Console + Console + + + Debug Output + Résultats du débogage + + + Error Log + Journal d'erreurs + + + Search + Chercher + + + View + Afficher + + + Qt Script Debugger + Débogueur de script Qt + + + + QScriptNewBreakpointWidget + + Close + Fermer + + + + QScrollBar + + Scroll here + Défiler jusqu'ici + + + Left edge + Extrême gauche + + + Top + En haut + + + Right edge + Extrême droite + + + Bottom + En bas + + + Page left + Page précédente + + + Page up + Page précédente + + + Page right + Page suivante + + + Page down + Page suivante + + + Scroll left + Défiler vers la gauche + + + Scroll up + Défiler vers le haut + + + Scroll right + Défiler vers la droite + + + Scroll down + Défiler vers le bas + + + Line up + Aligner + + + Position + Position + + + Line down + Aligner en-bas + + + + QSharedMemory + + %1: create size is less then 0 + %1 : taille de création est inférieur à 0 + + + %1: unable to lock + %1 : impossible de vérrouiller + + + %1: unable to unlock + %1 : impossible de déverrouiller + + + %1: permission denied + %1 : permission refusée + + + %1: already exists + %1 : existe déjà + + + %1: doesn't exists + %1 : n'existe pas + + + %1: out of resources + %1 : plus de ressources disponibles + + + %1: unknown error %2 + %1 : erreur inconnue %2 + + + %1: key is empty + %1 : clé vide + + + %1: ftok failed + %1 : ftok a échoué + + + %1: unable to make key + %1 : impossible de créer la clé + + + %1: doesn't exist + %1: n'existe pas + + + %1: UNIX key file doesn't exist + %1: le fichier de clés UNIX n'existe pas + + + %1: system-imposed size restrictions + %1 : le système impose des restrictions sur la taille + + + %1: not attached + %1 : non attaché + + + %1: invalid size + %1 : taille invalide + + + %1: key error + %1 : erreur de clé + + + %1: size query failed + %1 : la requête de taille a échoué + + + %1: unable to set key on lock + %1 : impossible d'affecter la clé au verrou + + + + QShortcut + + Space + Espace + + + Esc + Échap + + + Tab + Tab + + + Backtab + Tab arr + + + Backspace + Effacement + + + Return + Retour + + + Enter + Entrée + + + Ins + Inser + + + Del + Suppr + + + Pause + Pause + + + Print + Impr écran + + + SysReq + Syst + + + Home + Début + + + End + Fin + + + Left + Gauche + + + Up + Haut + + + Right + Droite + + + Down + Bas + + + PgUp + Page préc + + + PgDown + Page suiv + + + CapsLock + Verr maj + + + NumLock + Verr num + + + ScrollLock + Arrêt défil + + + Menu + Menu + + + Help + Aide + + + Back + Précédent (historique) + + + Forward + Successeur (historique) + + + Stop + Stop + + + Refresh + Rafraîchir + + + Volume Down + Volume bas + + + Volume Mute + Volume muet + + + Volume Up + Volume haut + + + + Bass Boost + Graves fort + + + Bass Up + Graves haut + + + Bass Down + Graves bas + + + Treble Up + Aigus haut + + + Treble Down + Aigus bas + + + Media Play + Média démarrer + + + Media Stop + Média arrêt + + + Media Previous + Média précédent + + + Media Next + Média suivant + + + Media Record + Média enregistrer + + + Favorites + Préférés + + + Search + Recherche + + + Standby + Attente + + + Open URL + Ouvrir URL + + + Launch Mail + Lancer courrier + + + Launch Media + Lancer média + + + Launch (0) + Lancer (0) + + + Launch (1) + Lancer (1) + + + Launch (2) + Lancer (2) + + + Launch (3) + Lancer (3) + + + Launch (4) + Lancer (4) + + + Launch (5) + Lancer (5) + + + Launch (6) + Lancer (6) + + + Launch (7) + Lancer (7) + + + Launch (8) + Lancer (8) + + + Launch (9) + Lancer (9) + + + Launch (A) + Lancer (A) + + + Launch (B) + Lancer (B) + + + Launch (C) + Lancer (C) + + + Launch (D) + Lancer (D) + + + Launch (E) + Lancer (E) + + + Launch (F) + Lancer (F) + + + Monitor Brightness Up + Augmenter la luminosité du moniteur + + + Monitor Brightness Down + Baisser la luminosité du moniteur + + + Keyboard Light On/Off + Avec/sans lumière clavier + + + Keyboard Brightness Up + Augmenter la luminosité du clavier + + + Keyboard Brightness Down + Baisser la luminosité du clavier + + + Power Off + Couper l'alimentation + + + Wake Up + Réveiller + + + Eject + Éjecter + + + Screensaver + Économiseur d'écran + + + WWW + WWW + + + Sleep + Dormir + + + LightBulb + Ampoule + + + Shop + Magasin + + + History + Historique + + + Add Favorite + Ajouter favori + + + Hot Links + Liens chauds + + + Adjust Brightness + Régler la luminosité + + + Finance + Finances + + + Community + Communauté + + + Audio Rewind + Audio arrière + + + Back Forward + Retour avant + + + Application Left + Application gauche + + + Application Right + Application droite + + + Book + Livre + + + CD + CD + + + Calculator + Calculatrice + + + Clear + Effacer + + + Clear Grab + Effacer la prise + + + Close + Fermer + + + Copy + Copier + + + Cut + Couper + + + Display + Affichage + + + DOS + DOS + + + Documents + Documents + + + Spreadsheet + Feuille de calcul + + + Browser + Navigateur + + + Game + Jeu + + + Go + Aller + + + iTouch + iTouch + + + Logoff + Fermer une session + + + Market + Marché + + + Meeting + Réunion + + + Keyboard Menu + Menu du clavier + + + Menu PB + Menu PB + + + My Sites + Mes sites + + + News + Actualités + + + Home Office + Bureau à domicile + + + Option + Option + + + Paste + Coller + + + Phone + Téléphone + + + Reply + Répondre + + + Reload + Recharger + + + Rotate Windows + Faire tourner la fenêtre + + + Rotation PB + Rotation PB + + + Rotation KB + Rotation KB + + + Save + Enregistrer + + + Send + Envoyer + + + Spellchecker + Correcteur orthographique + + + Split Screen + Partager l'écran + + + Support + Supporter + + + Task Panel + Panneau de tâches + + + Terminal + Terminal + + + Tools + Outils + + + Travel + Voyager + + + Video + Vidéo + + + Word Processor + Traitement de texte + + + XFer + XFer + + + Zoom In + Agrandir + + + Zoom Out + Rétrécir + + + Away + Absent + + + Messenger + Messenger + + + WebCam + Webcaméra + + + Mail Forward + Faire suivre l'e-mail + + + Pictures + Images + + + Music + Musique + + + Battery + Batterie + + + Bluetooth + Bluetooth + + + Wireless + Sans fil + + + Ultra Wide Band + Bande ultralarge + + + Audio Forward + Audio avant + + + Audio Repeat + Audio répéter + + + Audio Random Play + Audio lecture aléatoire + + + Subtitle + Sous-titre + + + Audio Cycle Track + Piste du cycle audio + + + Time + Heure + + + View + Afficher + + + Top Menu + Haut du menu + + + Suspend + Suspendre + + + Hibernate + Hiberner + + + Print Screen + Capture d'écran + + + Page Up + Page haut + + + Page Down + Page bas + + + Caps Lock + Verrou maj. + + + Num Lock + Verrou num. + + + Number Lock + Verrou numéro + + + Scroll Lock + Arrêt défilement + + + Insert + Insérer + + + Delete + Supprimer + + + Escape + Échapement + + + System Request + Système + + + Select + Sélectionner + + + Yes + Oui + + + No + Non + + + Context1 + Contexte1 + + + Context2 + Contexte2 + + + Context3 + Contexte3 + + + Context4 + Contexte4 + + + Call + Appeler + + + Hangup + Raccrocher + + + Flip + Retourner + + + Ctrl + Ctrl + + + Shift + Maj + + + Alt + Alt + + + Meta + Méta + + + + + + + + + F%1 + F%1 + + + Home Page + Page d'accueil + + + + QSlider + + Page left + Page précédente + + + Page up + Page précédente + + + Position + Position + + + Page right + Page suivante + + + Page down + Page suivante + + + + QSocks5SocketEngine + + Connection to proxy refused + Connexion au proxy refusée + + + Connection to proxy closed prematurely + connexion au proxy fermée prématurément + + + Proxy host not found + Hôte proxy introuvable + + + Connection to proxy timed out + Connexion au proxy expirée + + + Proxy authentication failed + L'authentification proxy a échoué + + + Proxy authentication failed: %1 + L'authentification proxy a échoué : %1 + + + SOCKS version 5 protocol error + Erreur de protocole SOCKS version 5 + + + General SOCKSv5 server failure + Erreur générale du serveur SOCKSv5 + + + Connection not allowed by SOCKSv5 server + Connexion refusée par le serveur SOCKSv5 + + + TTL expired + TTL expiré + + + SOCKSv5 command not supported + Commande SOCKSv5 non supportée + + + Address type not supported + Type d'adresse non supporté + + + Unknown SOCKSv5 proxy error code 0x%1 + Erreur proxy SOCKSv5 inconnue : 0x%1 + + + Network operation timed out + L'opération réseau a expiré + + + + QSoftKeyManager + + Ok + OK + + + Select + Sélectionner + + + Done + Terminer + + + Options + Options + + + Cancel + Annuler + + + Exit + Quitter + + + + QSpinBox + + More + Plus + + + Less + Moins + + + + QSql + + Delete + Supprimer + + + Delete this record? + Supprimer cet enregistrement ? + + + Yes + Oui + + + No + Non + + + Insert + Insérer + + + Update + Actualiser + + + Save edits? + Enregistrer les modifications ? + + + Cancel + Annuler + + + Confirm + Confirmer + + + Cancel your edits? + Annuler vos modifications ? + + + + QSslSocket + + Unable to write data: %1 + Impossible d'écrire les données : %1 + + + Unable to decrypt data: %1 + Impossible de décrypter les données: %1 + + + Error while reading: %1 + Erreur lors de la lecture : %1 + + + Error during SSL handshake: %1 + Erreur lors de la poignée de main SSL : %1 + + + Error creating SSL context (%1) + Erreur lors de la création du contexte SSL (%1) + + + Invalid or empty cipher list (%1) + La list de chiffrements est invalide ou vide (%1) + + + Private key does not certify public key, %1 + La clé privée ne certifie pas la clé publique, %1 + + + Error creating SSL session, %1 + Erreur lors de la création de la session SSL, %1 + + + Error creating SSL session: %1 + Erreur lors de la création de la session SSL : %1 + + + Cannot provide a certificate with no key, %1 + Impossible de fournir un certificat sans clé, %1 + + + Error loading local certificate, %1 + Erreur lors du chargement du certificat local, %1 + + + Error loading private key, %1 + Erreur lors du chargement de la clé privée, %1 + + + No error + Aucune erreur + + + The issuer certificate could not be found + Le certificat de l'émetteur est introuvable + + + The certificate signature could not be decrypted + La signature du certificat n'a pas pu être vérifiée + + + The public key in the certificate could not be read + La clé publique du certificat n'a pas pu être lue + + + The signature of the certificate is invalid + La signature du certificat n'est pas valide + + + The certificate is not yet valid + Le certificat n'est pas encore valide + + + The certificate has expired + Le certificat a expiré + + + The certificate's notBefore field contains an invalid time + Le champ pasAvant du certificat inclut une heure non valide + + + The certificate's notAfter field contains an invalid time + Le champ pasAprès du certificat inclut une heure non valide + + + The certificate is self-signed, and untrusted + Le certificat n'est pas sécurisé car signé automatiquement + + + The root certificate of the certificate chain is self-signed, and untrusted + Le certificat racine de la chaîne de certificats n'est pas sécurisé car signé automatiquement + + + The issuer certificate of a locally looked up certificate could not be found + Le certificat de l'émetteur d'un certificat converti localement est introuvable + + + No certificates could be verified + Aucun certificat n'a pu être vérifié + + + One of the CA certificates is invalid + L'un des certificats CA n'est pas valide + + + The basicConstraints path length parameter has been exceeded + Le paramètre de longueur du chemin basicConstraints a été dépassé + + + The supplied certificate is unsuitable for this purpose + Le certificat fourni ne convient pas pour cet objectif + + + The root CA certificate is not trusted for this purpose + Le certificat CA racine n'est pas sécurisé pour cet objectif + + + The root CA certificate is marked to reject the specified purpose + Le certificat CA racine est marqué pour rejeter l'objectif spécifié + + + The current candidate issuer certificate was rejected because its subject name did not match the issuer name of the current certificate + Le certificat de l'émetteur candidat actuel a été rejeté car le nom de son sujet ne correspondait pas au nom de l'émetteur du certificat actuel + + + The current candidate issuer certificate was rejected because its issuer name and serial number was present and did not match the authority key identifier of the current certificate + Le certificat de l'émetteur candidat actuel a été rejeté car le nom de son sujet et son numéro de série étaient présents et ne correspondaient pas à l'identifiant de la clé d'autorité du certificat actuel + + + The peer did not present any certificate + Le poste ne contient aucun certificat + + + The host name did not match any of the valid hosts for this certificate + Le nom d'hôte ne correspondait à aucun des hôtes valides pour ce certificat + + + Unknown error + Erreur inconnue + + + + QStateMachine + + Missing initial state in compound state '%1' + État initial manquant dans l'état composé '%1' + + + Missing default state in history state '%1' + État par défaut manquant dans l'état de l'historique '%1' + + + No common ancestor for targets and source of transition from state '%1' + Aucun ancêtre commun pour les cibles et la source de transition de l'état '%1' + + + Unknown error + Erreur inconnue + + + + QSystemSemaphore + + %1: does not exist + %1 : n'existe pas + + + %1: out of resources + %1: plus de ressources disponibles + + + %1: permission denied + %1: permission refusée + + + %1: already exists + %1 : existe déjà + + + %1: unknown error %2 + %1: erreur inconnue %2 + + + + QTDSDriver + + Unable to open connection + Impossible d'ouvrir la connexion + + + Unable to use database + Impossible d'utiliser la base de données + + + + QTabBar + + Scroll Left + Défiler vers la gauche + + + Scroll Right + Défiler vers la droite + + + + QTcpServer + + Operation on socket is not supported + Opération sur le socket non supportée + + + + QTextControl + + &Undo + &Annuler + + + &Redo + &Répéter + + + Cu&t + Co&uper + + + &Copy + Cop&ier + + + Copy &Link Location + Copier l'adresse du &lien + + + &Paste + Co&ller + + + Delete + Supprimer + + + Select All + Tout sélectionner + + + + QToolButton + + Press + Presser + + + Open + Ouvrir + + + + QUdpSocket + + This platform does not support IPv6 + Cette plateforme ne supporte pas IPv6 + + + + QUndoGroup + + Undo + Annuler + + + Redo + Répéter + + + + QUndoModel + + <empty> + <vide> + + + + QUndoStack + + Undo + Annuler + + + Redo + Répéter + + + + QUnicodeControlCharacterMenu + + LRM Left-to-right mark + LRM Left-to-right mark + + + RLM Right-to-left mark + RLM Right-to-left mark + + + ZWJ Zero width joiner + ZWJ Zero width joiner + + + ZWNJ Zero width non-joiner + ZWNJ Zero width non-joiner + + + ZWSP Zero width space + ZWSP Zero width space + + + LRE Start of left-to-right embedding + LRE Start of left-to-right embedding + + + RLE Start of right-to-left embedding + RLE Start of right-to-left embedding + + + LRO Start of left-to-right override + LRO Start of left-to-right override + + + RLO Start of right-to-left override + RLO Start of right-to-left override + + + PDF Pop directional formatting + PDF Pop directional formatting + + + Insert Unicode control character + Insérer caractère de contrôle Unicode + + + + QWebFrame + + Request cancelled + Requête annulée + + + Request blocked + Requête bloquée + + + Cannot show URL + Impossible d'afficher l'URL + + + Frame load interrupted by policy change + Charge du cadre interrompue par le changement de politique + + + Cannot show mimetype + Impossible d'afficher le mimetype + + + File does not exist + Le fichier n'existe pas + + + + QWebPage + + Submit + default label for Submit buttons in forms on web pages + + + + Submit + Submit (input element) alt text for <input> elements with no alt, title, or value + + + + Reset + default label for Reset buttons in forms on web pages + + + + Choose File + title for file button used in HTML forms + Choisir le fichier + + + No file selected + text to display in file button used in HTML forms when no file is selected + + + + Open in New Window + Open in New Window context menu item + + + + Save Link... + Download Linked File context menu item + + + + Copy Link + Copy Link context menu item + Copier le lien + + + Open Image + Open Image in New Window context menu item + + + + Save Image + Download Image context menu item + + + + Copy Image + Copy Link context menu item + Copier l'image + + + Open Frame + Open Frame in New Window context menu item + + + + Copy + Copy context menu item + Copier + + + Go Back + Back context menu item + + + + Go Forward + Forward context menu item + + + + Stop + Stop context menu item + + + + Reload + Reload context menu item + + + + Cut + Cut context menu item + Couper + + + Paste + Paste context menu item + + + + No Guesses Found + No Guesses Found context menu item + + + + Ignore + Ignore Spelling context menu item + + + + Add To Dictionary + Learn Spelling context menu item + Ajouter au dictionnaire + + + Search The Web + Search The Web context menu item + + + + Look Up In Dictionary + Look Up in Dictionary context menu item + + + + Open Link + Open Link context menu item + + + + Ignore + Ignore Grammar context menu item + + + + Spelling + Spelling and Grammar context sub-menu item + + + + Show Spelling and Grammar + menu item title + + + + Hide Spelling and Grammar + menu item title + + + + Check Spelling + Check spelling context menu item + Vérifier l'orthographe + + + Check Spelling While Typing + Check spelling while typing context menu item + Vérifier l'orthographe pendant la saisie + + + Check Grammar With Spelling + Check grammar with spelling context menu item + Vérifier la grammaire en même temps que l'orthographe + + + Fonts + Font context sub-menu item + + + + Bold + Bold context menu item + Gras + + + Italic + Italic context menu item + + + + Underline + Underline context menu item + + + + Outline + Outline context menu item + + + + Direction + Writing direction context sub-menu item + Direction + + + Text Direction + Text direction context sub-menu item + + + + Default + Default writing direction context menu item + Défaut + + + Left to Right + Left to Right context menu item + Gauche à droite + + + Right to Left + Right to Left context menu item + Droite à gauche + + + Loading... + Media controller status message when the media is loading + Chargement... + + + Live Broadcast + Media controller status message when watching a live broadcast + Diffusion en direct + + + Audio Element + Media controller element + Élément audio + + + Video Element + Media controller element + Élément vidéo + + + Mute Button + Media controller element + Bouton de désactivation du son + + + Unmute Button + Media controller element + Bouton de réactivation du son + + + Play Button + Media controller element + Bouton de lecture + + + Pause Button + Media controller element + Bouton de pause + + + Slider + Media controller element + Barre de défilement + + + Slider Thumb + Media controller element + Curseur de la barre de défilement + + + Rewind Button + Media controller element + Bouton de retour en arrière + + + Return to Real-time Button + Media controller element + Bouton de retour au temps réel + + + Elapsed Time + Media controller element + Temps écoulé + + + Remaining Time + Media controller element + Durée restante + + + Status Display + Media controller element + Affichage de l'état + + + Fullscreen Button + Media controller element + Bouton de plein écran + + + Seek Forward Button + Media controller element + Bouton de recherche avant + + + Seek Back Button + Media controller element + Bouton de recherche arrière + + + Audio element playback controls and status display + Media controller element + Commandes de lecture et affichage de l'état de l'élément audio + + + Video element playback controls and status display + Media controller element + Commandes de lecture et affichage de l'état de l'élément vidéo + + + Mute audio tracks + Media controller element + Couper le son des pistes audio + + + Unmute audio tracks + Media controller element + Réactiver le son des pistes audio + + + Begin playback + Media controller element + Commencer la lecture + + + Pause playback + Media controller element + Pause lecture + + + Movie time scrubber + Media controller element + Épurateur de la durée du film + + + Movie time scrubber thumb + Media controller element + Case de défilement de l'épurateur de la durée du film + + + Rewind movie + Media controller element + Rembobiner le film + + + Return streaming movie to real-time + Media controller element + Ramener le film en streaming en temps réel + + + Current movie time + Media controller element + Durée du film actuel + + + Remaining movie time + Media controller element + Durée de film restante + + + Current movie status + Media controller element + État du film actuel + + + Play movie in full-screen mode + Media controller element + Regarder le film en mode plein écran + + + Seek quickly back + Media controller element + Recherche rapide arrière + + + Seek quickly forward + Media controller element + Recherche rapide avant + + + Indefinite time + Media time description + Durée indéfinie + + + %1 days %2 hours %3 minutes %4 seconds + Media time description + %1 jours %2 heures %3 minutes %4 secondes + + + %1 hours %2 minutes %3 seconds + Media time description + %1 heures %2 minutes %3 secondes + + + %1 minutes %2 seconds + Media time description + %1 minutes %2 secondes + + + %1 seconds + Media time description + %1 secondes + + + Inspect + Inspect Element context menu item + + + + No recent searches + Label for only item in menu that appears when clicking on the search field image, when no searches have been performed + + + + Recent searches + label for first item in the menu that appears when clicking on the search field image, used as embedded menu title + + + + Clear recent searches + menu item in Recent Searches menu that empties menu's contents + Effacer les recherches récentes + + + Unknown + Unknown filesize FTP directory listing item + + + + Web Inspector - %2 + + + + %1 (%2x%3 pixels) + Title string for images + %1 (%2x%3 pixels) + + + Bad HTTP request + Requête HTTP erronée + + + This is a searchable index. Enter search keywords: + text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' + + + + Scroll here + + + + Left edge + + + + Top + + + + Right edge + + + + Bottom + En bas + + + Page left + + + + Page up + + + + Page right + + + + Page down + + + + Scroll left + + + + Scroll up + + + + Scroll right + + + + Scroll down + + + + %n file(s) + number of chosen file + + + + + + + JavaScript Alert - %1 + + + + JavaScript Confirm - %1 + + + + JavaScript Prompt - %1 + + + + JavaScript Problem - %1 + Problème de JavaScript - %1 + + + The script on this page appears to have a problem. Do you want to stop the script? + Le script de cette page semble avoir un problème. Souhaitez-vous arrêter le script? + + + Move the cursor to the next character + + + + Move the cursor to the previous character + + + + Move the cursor to the next word + + + + Move the cursor to the previous word + + + + Move the cursor to the next line + + + + Move the cursor to the previous line + + + + Move the cursor to the start of the line + + + + Move the cursor to the end of the line + + + + Move the cursor to the start of the block + + + + Move the cursor to the end of the block + + + + Move the cursor to the start of the document + + + + Move the cursor to the end of the document + + + + Select all + + + + Select to the next character + + + + Select to the previous character + + + + Select to the next word + + + + Select to the previous word + + + + Select to the next line + + + + Select to the previous line + + + + Select to the start of the line + + + + Select to the end of the line + + + + Select to the start of the block + + + + Select to the end of the block + + + + Select to the start of the document + + + + Select to the end of the document + + + + Delete to the start of the word + Supprimer jusqu'au début du mot + + + Delete to the end of the word + Supprimer jusqu'à la fin du mot + + + Insert a new paragraph + + + + Insert a new line + + + + Paste and Match Style + Coller et suivre le style + + + Remove formatting + Retirer la mise en forme + + + Strikethrough + Barré + + + Subscript + Indice + + + Superscript + Exposant + + + Insert Bulleted List + Insérer une liste à puces + + + Insert Numbered List + Insérer une liste numérotée + + + Indent + Retrait + + + Outdent + Retrait négatif + + + Center + Centré + + + Justify + Justifié + + + Align Left + Aligner à gauche + + + Align Right + Aligner à droite + + + + QWhatsThisAction + + What's This? + + + + + QWidget + + * + + + + + QWizard + + Cancel + + + + Help + + + + < &Back + + + + &Finish + + + + &Help + + + + Go Back + + + + Continue + + + + Commit + + + + Done + + + + &Next + + + + &Next > + + + + + QWorkspace + + &Restore + + + + &Move + + + + &Size + + + + Mi&nimize + + + + Ma&ximize + + + + &Close + + + + Stay on &Top + + + + Minimize + + + + Restore Down + + + + Close + + + + Sh&ade + + + + %1 - [%2] + + + + &Unshade + + + + + QXml + + no error occurred + + + + error triggered by consumer + + + + unexpected end of file + + + + more than one document type definition + + + + error occurred while parsing element + + + + tag mismatch + + + + error occurred while parsing content + + + + unexpected character + + + + invalid name for processing instruction + + + + version expected while reading the XML declaration + + + + wrong value for standalone declaration + + + + error occurred while parsing document type definition + + + + letter is expected + + + + error occurred while parsing comment + + + + error occurred while parsing reference + + + + internal general entity reference not allowed in DTD + + + + external parsed general entity reference not allowed in attribute value + + + + external parsed general entity reference not allowed in DTD + + + + unparsed entity reference in wrong context + + + + recursive entities + + + + error in the text declaration of an external entity + + + + encoding declaration or standalone declaration expected while reading the XML declaration + + + + standalone declaration expected while reading the XML declaration + + + + + QXmlPatternistCLI + + Warning in %1, at line %2, column %3: %4 + Avertissement dans %1, à la ligne %2, colonne %3: %4 + + + Warning in %1: %2 + Avertissement dans %1: %2 + + + Unknown location + Lieu inconnu + + + Error %1 in %2, at line %3, column %4: %5 + Erreur %1 dans %2, à la ligne %3, colonne %4: %5 + + + Error %1 in %2: %3 + Erreur %1 dans %2: %3 + + + + QXmlStream + + Extra content at end of document. + + + + Invalid entity value. + + + + Invalid XML character. + + + + Sequence ']]>' not allowed in content. + + + + Namespace prefix '%1' not declared + + + + Attribute redefined. + + + + Unexpected character '%1' in public id literal. + + + + Invalid XML version string. + + + + Unsupported XML version. + + + + %1 is an invalid encoding name. + + + + Encoding %1 is unsupported + + + + Standalone accepts only yes or no. + + + + Invalid attribute in XML declaration. + + + + Premature end of document. + + + + Invalid document. + + + + Expected + + + + , but got ' + + + + Unexpected ' + + + + Expected character data. + + + + Recursive entity detected. + + + + Start tag expected. + + + + XML declaration not at start of document. + + + + NDATA in parameter entity declaration. + + + + %1 is an invalid processing instruction name. + + + + Invalid processing instruction name. + + + + Illegal namespace declaration. + + + + Invalid XML name. + + + + Opening and ending tag mismatch. + + + + Reference to unparsed entity '%1'. + + + + Entity '%1' not declared. + + + + Reference to external entity '%1' in attribute value. + + + + Invalid character reference. + + + + Encountered incorrectly encoded content. + + + + The standalone pseudo attribute must appear after the encoding. + + + + %1 is an invalid PUBLIC identifier. + + + + + QtXmlPatterns + + At least one component must be present. + Au moins un composant doit être présent. + + + %1 is not a valid value of type %2. + %1 n'est pas une valeur valide du type %2. + + + When casting to %1 from %2, the source value cannot be %3. + En castant de %2 vers %1, la valeur source ne peut pas être %3. + + + Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values. + Effective Boolean Value ne peut être calculée pour une séquence contenant deux ou plus valeurs atomiques. + + + The data of a processing instruction cannot contain the string %1 + Les données d'une instruction de traitement ne peut contenir la chaîne %1 + + + %1 is an invalid %2 + %1 est un ivalide %2 + + + %1 is not a valid XML 1.0 character. + %1 n'est pas un caractère XML 1.0 valide. + + + %1 was called. + %1 a été appelé. + + + In the replacement string, %1 must be followed by at least one digit when not escaped. + Dans la chaîne de remplacement, %1 doit être suivi par au moins un chiffre s'il n'est pas échappé. + + + In the replacement string, %1 can only be used to escape itself or %2, not %3 + Dans la chaîne de remplacement, %1 peut seulement être utilisé pour échapper lui-même ou %2 mais pas %3 + + + %1 matches newline characters + %1 correspond à des caractères de saut de ligne + + + Matches are case insensitive + Les correspondances ne sont pas sensibles à la casse + + + %1 is an invalid regular expression pattern: %2 + %1 est un modèle d'expression régulière invalide: %2 + + + It will not be possible to retrieve %1. + Il sera impossible de récupérer %1. + + + The default collection is undefined + I'l n'y a pas de collection par défaut + + + %1 cannot be retrieved + %1 ne peut pas être récupéré + + + The item %1 did not match the required type %2. + L'item %1 ne correspond pas au type requis %2. + + + %1 is an unknown schema type. + %1 est un type de schema inconnu. + + + A template with name %1 has already been declared. + + + + Only one %1 declaration can occur in the query prolog. + Seulement une déclaration %1 peut intervenir lors du prologue de la requête. + + + The initialization of variable %1 depends on itself + L'initialisation de la variable %1 dépend d'elle-même + + + The variable %1 is unused + La variable %1 est inutilisée + + + Version %1 is not supported. The supported XQuery version is 1.0. + La version %1 n'est pas supportée. La version de XQuery supportée est 1.0. + + + No function with signature %1 is available + Aucune fonction avec la signature %1 n'est disponible + + + It is not possible to redeclare prefix %1. + Il est impossible de redéclarer le préfixe %1. + + + Prefix %1 is already declared in the prolog. + Le préfixe %1 est déjà déclaré dans le prologue. + + + The name of an option must have a prefix. There is no default namespace for options. + Le nom d'une option doit avoir un préfixe. Il n'y a pas de namespace par défaut pour les options. + + + The Schema Import feature is not supported, and therefore %1 declarations cannot occur. + La fonctionnalité "Schema Import" n'est pas supportée et les déclarations %1 ne peuvent donc intervenir. + + + The target namespace of a %1 cannot be empty. + Le namespace cible d'un %1 ne peut être vide. + + + The module import feature is not supported + La fonctionnalité "module import" n'est pas supportée + + + The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2 + Le namespace d'une fonction utilisateur dans un module de bibliothèque doit être équivalent au namespace du module. En d'autres mots, il devrait être %1 au lieu de %2 + + + A function already exists with the signature %1. + Une fonction avec la signature %1 existe déjà. + + + No external functions are supported. All supported functions can be used directly, without first declaring them as external + Les fonctions externes ne sont pas supportées. Toutes les fonctions supportées peuvent êter utilisées directement sans les déclarer préalablement comme externes + + + The %1-axis is unsupported in XQuery + L'axe %1 n'est pas supporté dans XQuery + + + The namespace URI cannot be the empty string when binding to a prefix, %1. + L'URI de namespace ne peut être une chaîne vide quand on le lie à un préfixe, %1. + + + %1 is an invalid namespace URI. + %1 est un URI de namespace invalide. + + + It is not possible to bind to the prefix %1 + Il est impossible de se lier au préfixe %1 + + + Two namespace declaration attributes have the same name: %1. + Deux attributs de déclarations de namespace ont le même nom : %1. + + + The namespace URI must be a constant and cannot use enclosed expressions. + L'URI de namespace doit être une constante et ne peut contenir d'expressions. + + + %1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported. + %1 n'est pas dans les déclaration d'attribut in-scope. La fonctionnalité d'inport de schéma n'est pas supportée. + + + empty + vide + + + zero or one + zéro ou un + + + exactly one + exactement un + + + one or more + un ou plus + + + zero or more + zéro ou plus + + + The focus is undefined. + Le focus est indéfini. + + + An attribute by name %1 has already been created. + Un attribute de nom %1 a déjà été créé. + + + Network timeout. + Le réseau ne répond pas. + + + Element %1 can't be serialized because it appears outside the document element. + L'élément %1 ne peut pas être sérialisé parce qu'il est hors de l'élément document. + + + Year %1 is invalid because it begins with %2. + L'année %1 est invalide parce qu'elle commence par %2. + + + Day %1 is outside the range %2..%3. + Le jour %1 est hors de l'intervalle %2..%3. + + + Month %1 is outside the range %2..%3. + Le mois %1 est hors de l'intervalle %2..%3. + + + Overflow: Can't represent date %1. + Overflow: ne peut pas représenter la date %1. + + + Day %1 is invalid for month %2. + Jour %1 est invalide pour le mois %2. + + + Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; + L'heure 24:%1:%2.%3 est invalide. L'heure est 24 mais les minutes, seconndes et millisecondes ne sont pas à 0; + + + Time %1:%2:%3.%4 is invalid. + L'heure %1:%2:%3.%4 est invalide. + + + Overflow: Date can't be represented. + Overflow : la date ne peut pas être représentée. + + + At least one time component must appear after the %1-delimiter. + Au moins un composant doit apparaître après le délimiteur %1. + + + Dividing a value of type %1 by %2 (not-a-number) is not allowed. + Diviser une valeur du type %1 par %2 (not-a-number) est interdit. + + + Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed. + Diviser une valeur de type %1 par %2 ou %3 (plus ou moins zéro) est interdit. + + + Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed. + La multiplication d'une valeur du type %1 par %2 ou %3 (plus ou moins infini) est interdite. + + + A value of type %1 cannot have an Effective Boolean Value. + Une valeur de type %1 ne peut pas avoir une Effective Boolean Value. + + + Value %1 of type %2 exceeds maximum (%3). + La valeur %1 de type %2 excède le maximum (%3). + + + Value %1 of type %2 is below minimum (%3). + La valeur %1 de type %2 est inférieur au minimum (%3). + + + A value of type %1 must contain an even number of digits. The value %2 does not. + Une valeur de type %1 doit contenir un nombre pair de chiffre. La valeur %2 n'est pas conforme. + + + %1 is not valid as a value of type %2. + %1 n'est pas une valeur valide de type %2. + + + Operator %1 cannot be used on type %2. + L'opérateur %1 ne peut pas être utilisé pour le type %2. + + + Operator %1 cannot be used on atomic values of type %2 and %3. + L'opérateur %1 ne peut pas être utilisé pour des valeurs atomiques de type %2 ou %3. + + + The namespace URI in the name for a computed attribute cannot be %1. + L'URI de namespace dans le nom d'un attribut calculé ne peut pas être %1. + + + The name for a computed attribute cannot have the namespace URI %1 with the local name %2. + Le nom d'un attribut calculé ne peut pas avoir l'URI de namespace %1 avec le nom local %2. + + + Type error in cast, expected %1, received %2. + Erreur de type lors du cast, attendu %1 mais reçu %2. + + + When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed. + En castant vers %1 ou des types dérivés, la valeur source doit être du même type ou une chaîne. Le type %2 n'est pas autorisé. + + + A comment cannot contain %1 + Un commentaire ne peut pas contenir %1 + + + A comment cannot end with a %1. + Un commentaire ne peut pas finir par %1. + + + An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place. + Un noeuds attribut ne peut être un fils d'un noeuds document. C'est pourquoi l'attribut %1 est mal placé. + + + A library module cannot be evaluated directly. It must be imported from a main module. + Un module de bibliothèque ne peut pas être évalué directement. Il doit être importé d'un module principal. + + + No template by name %1 exists. + Aucun template nommé %1 n'existe. + + + A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type. + Une valeur de type %1 ne peut être un prédicat. Un prédicat doit être de type numérique ou un Effective Boolean Value. + + + A positional predicate must evaluate to a single numeric value. + Un prédicat de position doit être évalué en une unique valeur numérique. + + + The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, %2 is invalid. + Le nom de destination dans une instruction de traitement ne peut être %1. %2 est invalide. + + + %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. + %1 n'est pas un nom de destination valide dans une instruction de traitement. Ce doit être une valeur %2, par ex. %3. + + + The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. + La dernière étape dans un chemin doit contenir soit des noeuds soit des valeurs atomiques. Cela ne peut pas être un mélange des deux. + + + No namespace binding exists for the prefix %1 + Aucun lien de namespace n'existe pour le préfixe %1 + + + No namespace binding exists for the prefix %1 in %2 + Aucun lien de namespace n'existe pour le préfixe %1 dans %2 + + + The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration. + Le premier argument de %1 ne peut être du type %2. Il doit être de type numérique, xs:yearMonthDuration ou xs:dayTimeDuration. + + + The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + Le premier argument de %1 ne peut être du type %2. Il doit être de type %3, %4 ou %5. + + + The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + Le deuxième argument de %1 ne peut être du type %2. Il doit être de type %3, %4 ou %5. + + + If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same. + Si les deux valeurs ont des décalages de zone, elle doivent avoir le même. %1 et %2 sont différents. + + + %1 must be followed by %2 or %3, not at the end of the replacement string. + %1 doit être suivi par %2 ou %3, et non à la fin de la chaîne de remplacement. + + + %1 and %2 match the start and end of a line. + %1 et %2 correspondent au début et à la fin d'une ligne. + + + Whitespace characters are removed, except when they appear in character classes + Les blancs sont supprimés excepté quand ils apparaissent dans les classes de caractère + + + %1 is an invalid flag for regular expressions. Valid flags are: + %1 est un flag invalide pour des expressions régulières. Les flags valides sont : + + + If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified. + Si le premier argument est une sequence vide ou un chaîne vide (sans namespace), un préfixe ne peut être spécifié. Le préfixe %1 a été spécifié. + + + The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization). + Le forme de normalisation %1 n'est pas supportée. Les formes supportées sont %2, %3, %4 et %5, et aucun, ie. une chaîne vide (pas de normalisation). + + + A zone offset must be in the range %1..%2 inclusive. %3 is out of range. + Un décalage de zone doit être dans l'intervalle %1..%2 inclus. %3 est hors de l'intervalle. + + + Required cardinality is %1; got cardinality %2. + La cardinalité requise est %1; reçu %2. + + + The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2. + L'encodage %1 est invalide. Il doit contenir uniquement des caractères latins, sans blanc et doit être conforme à l'expression régulière %2. + + + The keyword %1 cannot occur with any other mode name. + Le mot-clé %1 ne peut pas apparaître avec un autre nom de mode. + + + No variable with name %1 exists + + + + The value of attribute %1 must be of type %2, which %3 isn't. + + + + The prefix %1 cannot be bound. By default, it is already bound to the namespace %2. + + + + A variable with name %1 has already been declared. + + + + No value is available for the external variable with name %1. + + + + A stylesheet function must have a prefixed name. + Une fonction de feuille de style doit avoir un nom préfixé. + + + The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. + Le namespace %1 est réservé; c'est pourquoi les fonctions définies par l'utilisateur ne peuvent l'utiliser. Essayez le préfixe prédéfini %2 qui existe pour ces cas. + + + An argument with name %1 has already been declared. Every argument name must be unique. + + + + When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. + Quand la fonction %1 est utilisée pour vérifier la correspondance dans un pattern, l'argument doit être une référence de variable ou une chaîne de caractères. + + + In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching. + Dans un pattern XSL-T, le premier argument à la fonction %1 doit être une chaîne de caractères quand utilisé pour correspondance. + + + In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching. + Dans un pattern XSL-T, le premier argument à la fonction %1 doit être un litéral ou une référence de variable. + + + In an XSL-T pattern, function %1 cannot have a third argument. + Dans un pattern XSL-T, la fonction %1 ne peut pas avoir de 3e argument. + + + In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. + Dans un pattern XSL-T, seules les fonctions %1 et %2 (pas %3) peuvent être utilisées pour le matching. + + + In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can. + Dans un pattern XSL-T, l'axe %1 ne peut pas être utilisé, seulement %2 ou %3 le peuvent. + + + %1 is an invalid template mode name. + %1 est un nom de mode de template invalide. + + + The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. + Le nom d'une variable liée dans un expression for doit être different de la variable positionnelle. Les deux variables appelées %1 sont en conflit. + + + The Schema Validation Feature is not supported. Hence, %1-expressions may not be used. + La fonctionnalité "Schema Validation" n'est pas supportée. Les expressions %1 ne seront pas utilisées. + + + None of the pragma expressions are supported. Therefore, a fallback expression must be present + Aucune des expressions pragma n'est supportée. Une expression par défault doit être présente + + + Each name of a template parameter must be unique; %1 is duplicated. + Chaque nom d'un paramètre ede template doit être unique; %1 est dupliqué. + + + No function with name %1 is available. + + + + %1 is not a valid numeric literal. + %1 n'est pas une valeur numérique valide. + + + W3C XML Schema identity constraint selector + + + + W3C XML Schema identity constraint field + + + + A construct was encountered which is disallowed in the current language(%1). + + + + Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared). + Le namespace %1 peut seulement être lié à %2 (et doit être pré-déclaré). + + + Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared). + Le préfixe %1 peut seulement être lié à %2 (et doit être prédéclaré). + + + An attribute with name %1 has already appeared on this element. + + + + A direct element constructor is not well-formed. %1 is ended with %2. + Un constructeur direct d'élément est mal-formé. %1 est terminé par %2. + + + The name %1 does not refer to any schema type. + Le nom %1 ne se réfère à aucun type de schema. + + + %1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works. + %1 est une type complexe. Caster vers des types complexes n'est pas possible. Cependant, caster vers des types atomiques comme %2 marche. + + + %1 is not an atomic type. Casting is only possible to atomic types. + %1 n'est pas un type atomique. Il est uniquement possible de caster vers des types atomiques. + + + %1 is not a valid name for a processing-instruction. + %1 n'est pas un nom valide pour une instruction de traitement. + + + The name of an extension expression must be in a namespace. + Le nom d'une expression d'extension doit être dans un namespace. + + + Required type is %1, but %2 was found. + Le type requis est %1, mais %2 a été reçu. + + + Promoting %1 to %2 may cause loss of precision. + La Promotion de %1 vers %2 peut causer un perte de précision. + + + It's not possible to add attributes after any other kind of node. + Il est impossible d'ajouter des attributs après un autre type de noeuds. + + + Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported. + Seule le Unicode CodepointCollation est supporté (%1), %2 n'est pas supporté. + + + Integer division (%1) by zero (%2) is undefined. + Division entière (%1) par zéro (%2) indéfinie. + + + Division (%1) by zero (%2) is undefined. + Division (%1) par zéro (%2) indéfinie. + + + Modulus division (%1) by zero (%2) is undefined. + Module division (%1) par zéro (%2) indéfinie. + + + %1 takes at most %n argument(s). %2 is therefore invalid. + + %1 prend au maximum %n argument. %2 est donc invalide. + %1 prend au maximum %n arguments. %2 est donc invalide. + + + + %1 requires at least %n argument(s). %2 is therefore invalid. + + %1 requiert au moins %n argument. %2 est donc invalide. + %1 requiert au moins %n arguments. %2 est donc invalide. + + + + The root node of the second argument to function %1 must be a document node. %2 is not a document node. + Le noeuds racine du deuxième argument à la fonction %1 doit être un noeuds document. %2 n'est pas un document. + + + The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) + Le namespace d'une fonction utilisateur ne peut pas être vide (essayez le préfixe prédéfini %1 qui existe pour ce genre de cas) + + + A default namespace declaration must occur before function, variable, and option declarations. + Un déclaration de namespace par défaut doit être placée avant toute fonction, variable ou declaration d'option. + + + Namespace declarations must occur before function, variable, and option declarations. + Les declarations de namespace doivent être placées avant tout fonction, variable ou déclaration d'option. + + + Module imports must occur before function, variable, and option declarations. + Les imports de module doivent être placés avant tout fonction, variable ou déclaration d'option. + + + %1 is not a whole number of minutes. + %1 n'est pas un nombre entier de minutes. + + + Attribute %1 can't be serialized because it appears at the top level. + L'attribut %1 ne peut pas être sérialisé car il apparaît à la racine. + + + %1 is an unsupported encoding. + %1 est un encodage non supporté. + + + %1 contains octets which are disallowed in the requested encoding %2. + %1 contient 'octets', qui n'est pas autorisé pour l'encodage %2. + + + The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character. + Le codepoint %1 dans %2 et utilisant l'encodage %3 est un caractère XML invalide. + + + Ambiguous rule match. + Corresonpdance aux règles ambigüe. + + + In a namespace constructor, the value for a namespace cannot be an empty string. + Dans un constructeur d'espace de noms, la valeur pour un espace de noms ne peut pas être une chaîne vide. + + + The prefix must be a valid %1, which %2 is not. + Le préfixe doit être un valide %1; %2 n'e l'est pas. + + + The prefix %1 cannot be bound. + Le préfixe %1 ne peut être lié. + + + Only the prefix %1 can be bound to %2 and vice versa. + Seul le préfixe %1 peut être lié à %2, et vice versa. + + + The parameter %1 is required, but no corresponding %2 is supplied. + Le paramètre %1 est requis, mais aucun %2 correspondant n'est fourni. + + + The parameter %1 is passed, but no corresponding %2 exists. + Le paramètre %1 est passé mais aucun %2 correspondant n'existe. + + + The URI cannot have a fragment + L'URI ne peut pas avoir de fragments + + + Element %1 is not allowed at this location. + L'élément %1 n'est pas autorisé à cet emplacement. + + + Text nodes are not allowed at this location. + Les noeuds de texte ne sont pas autorisés à cet emplacement. + + + Parse error: %1 + Erreur: %1 + + + The value of the XSL-T version attribute must be a value of type %1, which %2 isn't. + La valeur de l'attribut de version XSL-T doit être du type %1, et non %2. + + + Running an XSL-T 1.0 stylesheet with a 2.0 processor. + Lancement d'une feuille de style XSL-T 1.0 avec un processeur 2.0. + + + Unknown XSL-T attribute %1. + Attribut XSL-T inconnu : %1. + + + Attribute %1 and %2 are mutually exclusive. + Les attributs %1 et %2 sont mutuellement exclusifs. + + + In a simplified stylesheet module, attribute %1 must be present. + Dans un module de feuille de style simplifié, l'attribut %1 doit être présent. + + + If element %1 has no attribute %2, it cannot have attribute %3 or %4. + Si l'élément %1 n'a pas d'attribut %2, il ne peut pas avoir d'attribut %3 ou %4. + + + Element %1 must have at least one of the attributes %2 or %3. + L'élement %1 doit avoir au moins un des attributs %2 ou %3. + + + At least one mode must be specified in the %1-attribute on element %2. + Au moins un mode doit être spécifié dans l'attribut %1 sur l'élément %2. + + + Element %1 must come last. + L'élément %1 doit être le dernier. + + + At least one %1-element must occur before %2. + Au moins un élément %1 doit être placé avant %2. + + + Only one %1-element can appear. + Seulement un élément %1 peut apparaître. + + + At least one %1-element must occur inside %2. + Au moins un élément %1 doit apparaître dans %2. + + + When attribute %1 is present on %2, a sequence constructor cannot be used. + Quand l'attribut %1 est présent sur %2, un constructeur de séquence ne peut pas être utilisé. + + + Element %1 must have either a %2-attribute or a sequence constructor. + L'élément %1 doit avoir un attribut %2 ou un constructeur de séquence. + + + When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor. + Quand un paramètre est requis, un valeur par défault ne peut pas être fournie par un attribute %1 ou un constructeur de séquence. + + + Element %1 cannot have children. + L'élément %1 ne peut pas avoir de fils. + + + Element %1 cannot have a sequence constructor. + L'élément %1 ne peut pas avoir un constructuer de séquence. + + + The attribute %1 cannot appear on %2, when it is a child of %3. + L'attribut %1 ne peut pas apparaître sur %2 quand il est fils de %3. + + + A parameter in a function cannot be declared to be a tunnel. + Un paramètre de fonction ne peut pas être déclaré comme un tunnel. + + + This processor is not Schema-aware and therefore %1 cannot be used. + Ce processeur ne comprend pas les Schemas. C'est pourquoi %1 ne peut pas être utilisé. + + + Top level stylesheet elements must be in a non-null namespace, which %1 isn't. + Les élément d'une feuille de style de haut niveau doivent être dans un namespace non nul; %1 ne l'est pas. + + + The value for attribute %1 on element %2 must either be %3 or %4, not %5. + La valeur de l'attribut %1 de l'élement %2 doit être %3 ou %4, et pas %5. + + + Attribute %1 cannot have the value %2. + L'attribut %1 ne peut avoir la valeur %2. + + + The attribute %1 can only appear on the first %2 element. + L'attribute %1 peut seulement apparaître sur le premier élément %2. + + + At least one %1 element must appear as child of %2. + Au moins un élément %1 doit apparaître comme fils de %2. + + + %1 has inheritance loop in its base type %2. + + + + Circular inheritance of base type %1. + + + + Circular inheritance of union %1. + + + + %1 is not allowed to derive from %2 by restriction as the latter defines it as final. + + + + %1 is not allowed to derive from %2 by extension as the latter defines it as final. + + + + Base type of simple type %1 cannot be complex type %2. + + + + Simple type %1 cannot have direct base type %2. + + + + Simple type %1 is not allowed to have base type %2. + + + + Simple type %1 can only have simple atomic type as base type. + + + + Simple type %1 cannot derive from %2 as the latter defines restriction as final. + + + + Variety of item type of %1 must be either atomic or union. + + + + Variety of member types of %1 must be atomic. + + + + %1 is not allowed to derive from %2 by list as the latter defines it as final. + + + + Simple type %1 is only allowed to have %2 facet. + + + + Base type of simple type %1 must have variety of type list. + + + + Base type of simple type %1 has defined derivation by restriction as final. + + + + Item type of base type does not match item type of %1. + + + + Simple type %1 contains not allowed facet type %2. + + + + %1 is not allowed to derive from %2 by union as the latter defines it as final. + + + + %1 is not allowed to have any facets. + + + + Base type %1 of simple type %2 must have variety of union. + + + + Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute. + + + + Member type %1 cannot be derived from member type %2 of %3's base type %4. + + + + Derivation method of %1 must be extension because the base type %2 is a simple type. + + + + Complex type %1 has duplicated element %2 in its content model. + + + + Complex type %1 has non-deterministic content. + + + + Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3. + + + + Content model of complex type %1 is not a valid extension of content model of %2. + + + + Complex type %1 must have simple content. + + + + Complex type %1 must have the same simple type as its base class %2. + + + + Complex type %1 cannot be derived from base type %2%3. + + + + Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3. + + + + Complex type %1 with simple content cannot be derived from complex base type %2. + + + + Item type of simple type %1 cannot be a complex type. + + + + Member type of simple type %1 cannot be a complex type. + + + + %1 is not allowed to have a member type with the same name as itself. + + + + %1 facet collides with %2 facet. + + + + %1 facet must have the same value as %2 facet of base type. + + + + %1 facet must be equal or greater than %2 facet of base type. + + + + %1 facet must be less than or equal to %2 facet of base type. + + + + %1 facet contains invalid regular expression + + + + Unknown notation %1 used in %2 facet. + + + + %1 facet contains invalid value %2: %3. + + + + %1 facet cannot be %2 or %3 if %4 facet of base type is %5. + + + + %1 facet cannot be %2 if %3 facet of base type is %4. + + + + %1 facet must be less than or equal to %2 facet. + + + + %1 facet must be less than %2 facet of base type. + + + + %1 facet and %2 facet cannot appear together. + + + + %1 facet must be greater than %2 facet of base type. + + + + %1 facet must be less than %2 facet. + + + + %1 facet must be greater than or equal to %2 facet of base type. + + + + Simple type contains not allowed facet %1. + + + + %1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list. + + + + Only %1 and %2 facets are allowed when derived by union. + + + + %1 contains %2 facet with invalid data: %3. + + + + Attribute group %1 contains attribute %2 twice. + + + + Attribute group %1 contains two different attributes that both have types derived from %2. + + + + Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3. + + + + Complex type %1 contains attribute %2 twice. + + + + Complex type %1 contains two different attributes that both have types derived from %2. + + + + Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3. + + + + Element %1 is not allowed to have a value constraint if its base type is complex. + + + + Element %1 is not allowed to have a value constraint if its type is derived from %2. + + + + Value constraint of element %1 is not of elements type: %2. + + + + Element %1 is not allowed to have substitution group affiliation as it is no global element. + + + + Type of element %1 cannot be derived from type of substitution group affiliation. + + + + Value constraint of attribute %1 is not of attributes type: %2. + + + + Attribute %1 has value constraint but has type derived from %2. + + + + %1 attribute in derived complex type must be %2 like in base type. + + + + Attribute %1 in derived complex type must have %2 value constraint like in base type. + + + + Attribute %1 in derived complex type must have the same %2 value constraint like in base type. + + + + Attribute %1 in derived complex type must have %2 value constraint. + + + + processContent of base wildcard must be weaker than derived wildcard. + + + + Element %1 exists twice with different types. + + + + Particle contains non-deterministic wildcards. + + + + Base attribute %1 is required but derived attribute is not. + + + + Type of derived attribute %1 cannot be validly derived from type of base attribute. + + + + Value constraint of derived attribute %1 does not match value constraint of base attribute. + + + + Derived attribute %1 does not exist in the base definition. + + + + Derived attribute %1 does not match the wildcard in the base definition. + + + + Base attribute %1 is required but missing in derived definition. + + + + Derived definition contains an %1 element that does not exists in the base definition + + + + Derived wildcard is not a subset of the base wildcard. + + + + %1 of derived wildcard is not a valid restriction of %2 of base wildcard + + + + Attribute %1 from base type is missing in derived type. + + + + Type of derived attribute %1 differs from type of base attribute. + + + + Base definition contains an %1 element that is missing in the derived definition + + + + %1 references unknown %2 or %3 element %4. + + + + %1 references identity constraint %2 that is no %3 or %4 element. + + + + %1 has a different number of fields from the identity constraint %2 that it references. + + + + Base type %1 of %2 element cannot be resolved. + + + + Item type %1 of %2 element cannot be resolved. + + + + Member type %1 of %2 element cannot be resolved. + + + + Type %1 of %2 element cannot be resolved. + + + + Base type %1 of complex type cannot be resolved. + + + + %1 cannot have complex base type that has a %2. + + + + Content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type. + + + + Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model. + + + + Type of %1 element must be a simple type, %2 is not. + + + + Substitution group %1 of %2 element cannot be resolved. + + + + Substitution group %1 has circular definition. + + + + Duplicated element names %1 in %2 element. + + + + Reference %1 of %2 element cannot be resolved. + + + + Circular group reference for %1. + + + + %1 element is not allowed in this scope + + + + %1 element cannot have %2 attribute with value other than %3. + + + + %1 element cannot have %2 attribute with value other than %3 or %4. + + + + %1 or %2 attribute of reference %3 does not match with the attribute declaration %4. + + + + Attribute group %1 has circular reference. + + + + %1 attribute in %2 must have %3 use like in base type %4. + + + + Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2. + + + + %1 has attribute wildcard but its base type %2 has not. + + + + Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible. + + + + Enumeration facet contains invalid content: {%1} is not a value of type %2. + + + + Namespace prefix of qualified name %1 is not defined. + + + + %1 element %2 is not a valid restriction of the %3 element it redefines: %4. + + + + Empty particle cannot be derived from non-empty particle. + + + + Derived particle is missing element %1. + + + + Derived element %1 is missing value constraint as defined in base particle. + + + + Derived element %1 has weaker value constraint than base particle. + + + + Fixed value constraint of element %1 differs from value constraint in base particle. + + + + Derived element %1 cannot be nillable as base element is not nillable. + + + + Block constraints of derived element %1 must not be more weaker than in the base element. + + + + Simple type of derived element %1 cannot be validly derived from base element. + + + + Complex type of derived element %1 cannot be validly derived from base element. + + + + Element %1 is missing in derived particle. + + + + Element %1 does not match namespace constraint of wildcard in base particle. + + + + Wildcard in derived particle is not a valid subset of wildcard in base particle. + + + + processContent of wildcard in derived particle is weaker than wildcard in base particle. + + + + Derived particle allows content that is not allowed in the base particle. + + + + Can not process unknown element %1, expected elements are: %2. + + + + Element %1 is not allowed in this scope, possible elements are: %2. + + + + Child element is missing in that scope, possible child elements are: %1. + + + + Document is not a XML schema. + + + + %1 attribute of %2 element contains invalid content: {%3} is not a value of type %4. + + + + %1 attribute of %2 element contains invalid content: {%3}. + + + + Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema. + + + + Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema. + + + + %1 element is not allowed to have the same %2 attribute value as the target namespace %3. + + + + %1 element without %2 attribute is not allowed inside schema without target namespace. + + + + %1 element is not allowed inside %2 element if %3 attribute is present. + + + + %1 element has neither %2 attribute nor %3 child element. + + + + %1 element with %2 child element must not have a %3 attribute. + + + + %1 attribute of %2 element must be %3 or %4. + + + + %1 attribute of %2 element must have a value of %3. + + + + %1 attribute of %2 element must have a value of %3 or %4. + + + + %1 element must not have %2 and %3 attribute together. + + + + Content of %1 attribute of %2 element must not be from namespace %3. + + + + %1 attribute of %2 element must not be %3. + + + + %1 attribute of %2 element must have the value %3 because the %4 attribute is set. + + + + Specifying use='prohibited' inside an attribute group has no effect. + + + + %1 element must have either %2 or %3 attribute. + + + + %1 element must have either %2 attribute or %3 or %4 as child element. + + + + %1 element requires either %2 or %3 attribute. + + + + Text or entity references not allowed inside %1 element + + + + %1 attribute of %2 element must contain %3, %4 or a list of URIs. + + + + %1 element is not allowed in this context. + + + + %1 attribute of %2 element has larger value than %3 attribute. + + + + Prefix of qualified name %1 is not defined. + + + + %1 attribute of %2 element must either contain %3 or the other values. + + + + Component with ID %1 has been defined previously. + + + + Element %1 already defined. + + + + Attribute %1 already defined. + + + + Type %1 already defined. + + + + Attribute group %1 already defined. + + + + Element group %1 already defined. + + + + Notation %1 already defined. + + + + Identity constraint %1 already defined. + + + + Duplicated facets in simple type %1. + + + + %1 is not valid according to %2. + + + + String content does not match the length facet. + + + + String content does not match the minLength facet. + + + + String content does not match the maxLength facet. + + + + String content does not match pattern facet. + + + + String content is not listed in the enumeration facet. + + + + Signed integer content does not match the maxInclusive facet. + + + + Signed integer content does not match the maxExclusive facet. + + + + Signed integer content does not match the minInclusive facet. + + + + Signed integer content does not match the minExclusive facet. + + + + Signed integer content is not listed in the enumeration facet. + + + + Signed integer content does not match pattern facet. + + + + Signed integer content does not match in the totalDigits facet. + + + + Unsigned integer content does not match the maxInclusive facet. + + + + Unsigned integer content does not match the maxExclusive facet. + + + + Unsigned integer content does not match the minInclusive facet. + + + + Unsigned integer content does not match the minExclusive facet. + + + + Unsigned integer content is not listed in the enumeration facet. + + + + Unsigned integer content does not match pattern facet. + + + + Unsigned integer content does not match in the totalDigits facet. + + + + Double content does not match the maxInclusive facet. + + + + Double content does not match the maxExclusive facet. + + + + Double content does not match the minInclusive facet. + + + + Double content does not match the minExclusive facet. + + + + Double content is not listed in the enumeration facet. + + + + Double content does not match pattern facet. + + + + Decimal content does not match in the fractionDigits facet. + + + + Decimal content does not match in the totalDigits facet. + + + + Date time content does not match the maxInclusive facet. + + + + Date time content does not match the maxExclusive facet. + + + + Date time content does not match the minInclusive facet. + + + + Date time content does not match the minExclusive facet. + + + + Date time content is not listed in the enumeration facet. + + + + Date time content does not match pattern facet. + + + + Duration content does not match the maxInclusive facet. + + + + Duration content does not match the maxExclusive facet. + + + + Duration content does not match the minInclusive facet. + + + + Duration content does not match the minExclusive facet. + + + + Duration content is not listed in the enumeration facet. + + + + Duration content does not match pattern facet. + + + + Boolean content does not match pattern facet. + + + + Binary content does not match the length facet. + + + + Binary content does not match the minLength facet. + + + + Binary content does not match the maxLength facet. + + + + Binary content is not listed in the enumeration facet. + + + + Invalid QName content: %1. + + + + QName content is not listed in the enumeration facet. + + + + QName content does not match pattern facet. + + + + Notation content is not listed in the enumeration facet. + + + + List content does not match length facet. + + + + List content does not match minLength facet. + + + + List content does not match maxLength facet. + + + + List content is not listed in the enumeration facet. + + + + List content does not match pattern facet. + + + + Union content is not listed in the enumeration facet. + + + + Union content does not match pattern facet. + + + + Data of type %1 are not allowed to be empty. + + + + Element %1 is missing child element. + + + + There is one IDREF value with no corresponding ID: %1. + + + + Loaded schema file is invalid. + + + + %1 contains invalid data. + + + + xsi:schemaLocation namespace %1 has already appeared earlier in the instance document. + + + + xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute. + + + + No schema defined for validation. + + + + No definition for element %1 available. + + + + Specified type %1 is not known to the schema. + + + + Element %1 is not defined in this scope. + + + + Declaration for element %1 does not exist. + + + + Element %1 contains invalid content. + + + + Element %1 is declared as abstract. + + + + Element %1 is not nillable. + + + + Attribute %1 contains invalid data: %2 + + + + Element contains content although it is nillable. + + + + Fixed value constraint not allowed if element is nillable. + + + + Element %1 cannot contain other elements, as it has a fixed content. + + + + Specified type %1 is not validly substitutable with element type %2. + + + + Complex type %1 is not allowed to be abstract. + + + + Element %1 contains not allowed attributes. + + + + Element %1 contains not allowed child element. + + + + Content of element %1 does not match its type definition: %2. + + + + Content of element %1 does not match defined value constraint. + + + + Element %1 contains not allowed child content. + + + + Element %1 contains not allowed text content. + + + + Element %1 is missing required attribute %2. + + + + Attribute %1 does not match the attribute wildcard. + + + + Declaration for attribute %1 does not exist. + + + + Element %1 contains two attributes of type %2. + + + + Attribute %1 contains invalid content. + + + + Element %1 contains unknown attribute %2. + + + + Content of attribute %1 does not match its type definition: %2. + + + + Content of attribute %1 does not match defined value constraint. + + + + Non-unique value found for constraint %1. + + + + Key constraint %1 contains absent fields. + + + + Key constraint %1 contains references nillable element %2. + + + + No referenced value found for key reference %1. + + + + More than one value found for field %1. + + + + Field %1 has no simple type. + + + + ID value '%1' is not unique. + + + + '%1' attribute contains invalid QName content: %2. + + + + diff --git a/config.profiles/symbian/translations/qt_he.ts b/config.profiles/symbian/translations/qt_he.ts new file mode 100644 index 0000000..72a6df9 --- /dev/null +++ b/config.profiles/symbian/translations/qt_he.ts @@ -0,0 +1,7781 @@ + + + + + AudioOutput + + + <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> + + + + + <html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html> + + + + + Revert back to device '%1' + + + + + CloseButton + + + Close Tab + + + + + PPDOptionsModel + + Name + שם + + + + Phonon:: + + + Notifications + + + + + Music + + + + + Video + + + + + Communication + + + + + Games + + + + + Accessibility + + + + + Phonon::Gstreamer::Backend + + + Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. + Some video features have been disabled. + + + + + Warning: You do not seem to have the base GStreamer plugins installed. + All audio and video support has been disabled + + + + + Phonon::Gstreamer::MediaObject + + + Cannot start playback. + +Check your Gstreamer installation and make sure you +have libgstreamer-plugins-base installed. + + + + + A required codec is missing. You need to install the following codec(s) to play this content: %0 + + + + + + + + + + + + Could not open media source. + + + + + Invalid source type. + + + + + Could not locate media source. + + + + + Could not open audio device. The device is already in use. + + + + + Could not decode media source. + + + + + Phonon::VolumeSlider + + + + Volume: %1% + + + + + + + Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1% + + + + + Q3Accel + + + %1, %2 not defined + + + + + Ambiguous %1 not handled + + + + + Q3DataTable + + + True + אמת + + + + False + שקר + + + + Insert + הוסף + + + + Update + עדכן + + + + Delete + מחק + + + + Q3FileDialog + + + Copy or Move a File + העתק או העבר קובץ + + + + Read: %1 + קרא: %1 + + + + + Write: %1 + כתוב: %1 + + + + + Cancel + ביטול + + + + + + + All Files (*) + כל הקבצים (*) + + + + Name + שם + + + + Size + גודל + + + + Type + סוג + + + + Date + תאריך + + + + Attributes + מאפיינים + + + + + &OK + &אישור + + + + Look &in: + &חפש ב: + + + + + + File &name: + &שם הקובץ: + + + + File &type: + &סוג הקובץ: + + + + Back + אחורה + + + + One directory up + ספריה אחת למעלה + + + + Create New Folder + צור תיקיה חדשה + + + + List View + תצוגת רשימה + + + + Detail View + תצוגת פרטים + + + + Preview File Info + תצוגה מקדימה של פרטי הקובץ + + + + Preview File Contents + תצוגה מקדימה של תוכן הקובץ + + + + Read-write + קריאה-כתיבה + + + + Read-only + קריאה-בלבד + + + + Write-only + כתיבה-בלבד + + + + Inaccessible + לא נגיש + + + + Symlink to File + קישור סמלי לקובץ + + + + Symlink to Directory + קישור סמלי לספריה + + + + Symlink to Special + קישור סמלי לפריט מיוחד + + + + File + קובץ + + + + Dir + ספריה + + + + Special + מיוחד + + + + + + Open + פתח + + + + + Save As + שמירה בשם + + + + + + &Open + &פתח + + + + + &Save + &שמור + + + + &Rename + ש&נה שם + + + + &Delete + &מחק + + + + R&eload + &טען מחדש + + + + Sort by &Name + סדר לפי ש&ם + + + + Sort by &Size + סדר לפי &גודל + + + + Sort by &Date + סדר לפי &תאריך + + + + &Unsorted + &ללא סדר + + + + Sort + סדר + + + + Show &hidden files + הצג קבצים &מוסתרים + + + + the file + הקובץ + + + + the directory + הספריה + + + + the symlink + הקישור הסמלי + + + + Delete %1 + מחק את %1 + + + + <qt>Are you sure you wish to delete %1 "%2"?</qt> + <qt>האם אתה בטוח שברצונך למחוק %1 "%2"?</qt> + + + + &Yes + &כן + + + + &No + &לא + + + + New Folder 1 + תיקיה חדשה 1 + + + + New Folder + תיקיה חדשה + + + + New Folder %1 + תיקיה חדשה %1 + + + + Find Directory + חפש ספריה + + + + + Directories + ספריות + + + + Directory: + + + + + + Error + שגיאה + + + + %1 +File not found. +Check path and filename. + %1 +הקובץ לא נמצא. +בדוק את הנתיב ואת שם הקובץ. + + + + All Files (*.*) + כל הקבצים (*.*) + + + + Open + פתח + + + + Select a Directory + בחר ספריה + + + + Q3LocalFs + + + + Could not read directory +%1 + + + + + Could not create directory +%1 + + + + + Could not remove file or directory +%1 + + + + + Could not rename +%1 +to +%2 + לא ניתן לשנות את השם של +%1 +אל +%2 + + + + Could not open +%1 + לא ניתן לפתוח את +%1 + + + + Could not write +%1 + לא ניתן לכתוב את +%1 + + + + Q3MainWindow + + + Line up + סדר בשורה + + + + Customize... + התאמה אישית... + + + + Q3NetworkProtocol + + + Operation stopped by the user + הפעולה הופסקה על ידי המשתמש + + + + Q3ProgressDialog + + + + Cancel + ביטול + + + + Q3TabDialog + + + + OK + אישור + + + + Apply + החל + + + + Help + עזרה + + + + Defaults + ברירות מחדל + + + + Cancel + ביטול + + + + Q3TextEdit + + + &Undo + &בטל + + + + &Redo + בצע &שוב + + + + Cu&t + &גזור + + + + &Copy + הע&תק + + + + &Paste + ה&דבק + + + + Clear + נקה + + + + + Select All + בחר הכל + + + + Q3TitleBar + + + System + + + + + Restore up + + + + + Minimize + מזער + + + + Restore down + + + + + Maximize + הגדל + + + + Close + סגור + + + + Contains commands to manipulate the window + + + + + Puts a minimized back to normal + + + + + Moves the window out of the way + + + + + Puts a maximized window back to normal + + + + + Makes the window full screen + + + + + Closes the window + + + + + Displays the name of the window and contains controls to manipulate it + + + + + Q3ToolBar + + + More... + + + + + Q3UrlOperator + + + + + The protocol `%1' is not supported + הפרוטוקול "%1" אינו נתמך + + + + The protocol `%1' does not support listing directories + הפרוטוקול "%1" לא תומך בהצגת ספריות + + + + The protocol `%1' does not support creating new directories + הפרוטוקול "%1" לא תומך ביצירת ספריית חדשות + + + + The protocol `%1' does not support removing files or directories + הפרוטוקול "%1" לא תומך בהסרת קבצים או ספריות + + + + The protocol `%1' does not support renaming files or directories + הפרוטוקול "%1" לא תומך בשינוי שמותיהם של קבצים או ספריות + + + + The protocol `%1' does not support getting files + הפרוטוקול "%1" לא תומך בהורדת קבצים + + + + The protocol `%1' does not support putting files + הפרוטוקול "%1" לא תומך בהעלאת קבצים + + + + + The protocol `%1' does not support copying or moving files or directories + הפרוטוקול "%1" לא תומך בהעתקה או העברה של קבצים או ספריות + + + + + (unknown) + (לא ידוע) + + + + Q3Wizard + + + &Cancel + + + + + < &Back + + + + + &Next > + + + + + &Finish + + + + + &Help + + + + + QAbstractSocket + + + + + + Host not found + + + + + + + Connection refused + החיבור נדחה + + + + Connection timed out + + + + + + + Operation on socket is not supported + + + + + Socket operation timed out + + + + + Socket is not connected + + + + + Network unreachable + + + + + QAbstractSpinBox + + + &Step up + + + + + Step &down + + + + + &Select All + + + + + QApplication + + + QT_LAYOUT_DIRECTION + Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. + RTL + + + + Executable '%1' requires Qt %2, found Qt %3. + + + + + Incompatible Qt Library Error + + + + + Activate + + + + + Activates the program's main window + + + + + QAxSelect + + + Select ActiveX Control + + + + + OK + אישור + + + + &Cancel + + + + + COM &Object: + + + + + QCheckBox + + + Uncheck + + + + + Check + + + + + Toggle + + + + + QColorDialog + + + Hu&e: + &גוון: + + + + &Sat: + &הרוויה: + + + + &Val: + &ערך: + + + + &Red: + &אדום: + + + + &Green: + &ירוק: + + + + Bl&ue: + &כחול: + + + + A&lpha channel: + ע&רוץ אלפא: + + + + Select Color + + + + + &Basic colors + &צבעים בסיסיים + + + + &Custom colors + צבעים &מותאמים אישית + + + &Define Custom Colors >> + &הגדר צבעים מותאמים אישית >> + + + OK + אישור + + + Cancel + ביטול + + + + &Add to Custom Colors + ה&וסף לצבעים מותאמים אישית + + + Select color + בחירת צבע + + + + QComboBox + + + + Open + פתח + + + + False + שקר + + + + True + אמת + + + + Close + סגור + + + + QCoreApplication + + + %1: key is empty + QSystemSemaphore + + + + + %1: unable to make key + QSystemSemaphore + + + + + %1: ftok failed + QSystemSemaphore + + + + + QDB2Driver + + + Unable to connect + + + + + Unable to commit transaction + + + + + Unable to rollback transaction + + + + + Unable to set autocommit + + + + + QDB2Result + + + + Unable to execute statement + + + + + Unable to prepare statement + + + + + Unable to bind variable + + + + + Unable to fetch record %1 + + + + + Unable to fetch next + + + + + Unable to fetch first + + + + + QDateTimeEdit + + + AM + + + + + am + + + + + PM + + + + + pm + + + + + QDial + + + QDial + + + + + SpeedoMeter + + + + + SliderHandle + + + + + QDialog + + + What's This? + מה זה? + + + + Done + + + + + QDialogButtonBox + + + + + OK + אישור + + + + Save + שמור + + + + &Save + &שמור + + + + Open + פתח + + + + Cancel + ביטול + + + + &Cancel + + + + + Close + סגור + + + + &Close + &סגור + + + + Apply + החל + + + + Reset + + + + + Help + עזרה + + + + Don't Save + + + + + Discard + + + + + &Yes + &כן + + + + Yes to &All + + + + + &No + &לא + + + + N&o to All + + + + + Save All + + + + + Abort + + + + + Retry + + + + + Ignore + + + + + Restore Defaults + + + + + Close without Saving + + + + + &OK + &אישור + + + + QDirModel + + + Name + שם + + + + Size + גודל + + + + Kind + Match OS X Finder + + + + + Type + All other platforms + סוג + + + + Date Modified + + + + + QDockWidget + + + Close + סגור + + + + Dock + + + + + Float + + + + + QDoubleSpinBox + + + More + + + + + Less + + + + + QErrorMessage + + + &Show this message again + &הצג הודעה זו שנית + + + + &OK + &אישור + + + + Debug Message: + + + + + Warning: + + + + + Fatal Error: + + + + + QFile + + + + Destination file exists + + + + + Cannot remove source file + + + + + Cannot open %1 for input + + + + + Cannot open for output + + + + + Failure to write block + + + + + Cannot create %1 for output + + + + + QFileDialog + + + + All Files (*) + כל הקבצים (*) + + + + + Back + אחורה + + + + + List View + תצוגת רשימה + + + + + Detail View + תצוגת פרטים + + + + + File + קובץ + + + + Open + פתח + + + + Save As + שמירה בשם + + + + + + + &Open + &פתח + + + + + &Save + &שמור + + + + &Rename + ש&נה שם + + + + &Delete + &מחק + + + + Show &hidden files + הצג קבצים &מוסתרים + + + + New Folder + תיקיה חדשה + + + + Find Directory + חפש ספריה + + + + Directories + ספריות + + + + All Files (*.*) + כל הקבצים (*.*) + + + + %1 already exists. +Do you want to replace it? + + + + + %1 +File not found. +Please verify the correct file name was given. + + + + + My Computer + + + + + + Parent Directory + + + + + + Files of type: + + + + + + Directory: + + + + + + %1 +Directory not found. +Please verify the correct directory name was given. + + + + + '%1' is write protected. +Do you want to delete it anyway? + + + + + Are sure you want to delete '%1'? + + + + + Could not delete directory. + + + + + Recent Places + + + + + Drive + + + + + Unknown + + + + + Show + + + + + + Forward + + + + + &New Folder + + + + + + &Choose + + + + + Remove + + + + + + File &name: + &שם הקובץ: + + + + + Look in: + + + + + + Create New Folder + צור תיקיה חדשה + + + + QFileSystemModel + + + %1 TB + + + + + %1 GB + + + + + %1 MB + + + + + %1 KB + + + + + %1 bytes + + + + + Invalid filename + + + + + <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. + + + + + Name + שם + + + + Size + גודל + + + + Kind + Match OS X Finder + + + + + Type + All other platforms + סוג + + + + Date Modified + + + + + My Computer + + + + + Computer + + + + + QFontDatabase + + + + Normal + + + + + + + Bold + + + + + + Demi Bold + + + + + + + Black + + + + + Demi + + + + + + Light + + + + + + Italic + + + + + + Oblique + + + + + Any + + + + + Latin + + + + + Greek + + + + + Cyrillic + + + + + Armenian + + + + + Hebrew + + + + + Arabic + + + + + Syriac + + + + + Thaana + + + + + Devanagari + + + + + Bengali + + + + + Gurmukhi + + + + + Gujarati + + + + + Oriya + + + + + Tamil + + + + + Telugu + + + + + Kannada + + + + + Malayalam + + + + + Sinhala + + + + + Thai + + + + + Lao + + + + + Tibetan + + + + + Myanmar + + + + + Georgian + + + + + Khmer + + + + + Simplified Chinese + + + + + Traditional Chinese + + + + + Japanese + + + + + Korean + + + + + Vietnamese + + + + + Symbol + + + + + Ogham + + + + + Runic + + + + + QFontDialog + + + &Font + &גופן + + + + Font st&yle + &סגנון גופן + + + + &Size + גו&דל + + + + Effects + אפקטים + + + + Stri&keout + קו &חוצה + + + + &Underline + קו &תחתי + + + + Sample + דוגמה + + + + + Select Font + בחר גופן + + + + Wr&iting System + + + + + QFtp + + + Host %1 found + המארח %1 נמצא + + + + Host found + המארח נמצא + + + + + + Connected to host %1 + מחובר למארח %1 + + + + Connected to host + מחובר למארח + + + + Connection to %1 closed + החיבור אל %1 נסגר + + + + + + Connection closed + החיבור נסגר + + + + + Host %1 not found + המארח %1 לא נמצא + + + + + Connection refused to host %1 + החיבור אל המארח %1 נדחה + + + + Connection timed out to host %1 + + + + + + + + Unknown error + + + + + + Connecting to host failed: +%1 + + + + + + Login failed: +%1 + + + + + + Listing directory failed: +%1 + + + + + + Changing directory failed: +%1 + + + + + + Downloading file failed: +%1 + + + + + + Uploading file failed: +%1 + + + + + + Removing file failed: +%1 + + + + + + Creating directory failed: +%1 + + + + + + Removing directory failed: +%1 + + + + + + Not connected + + + + + + Connection refused for data connection + + + + + QHostInfo + + + Unknown error + + + + + QHostInfoAgent + + + + + + + + + + Host not found + + + + + + + + Unknown address type + + + + + + + Unknown error + + + + + QHttp + + + + Connection refused + החיבור נדחה + + + + + + Host %1 not found + המארח %1 לא נמצא + + + + + Wrong content length + אורך תוכן שגוי + + + + HTTPS connection requested but SSL support not compiled in + + + + + + + + HTTP request failed + בקשת ה-HTTP נכשלה + + + + Host %1 found + המארח %1 נמצא + + + + Host found + המארח נמצא + + + + Connected to host %1 + מחובר למארח %1 + + + + Connected to host + מחובר למארח + + + + Connection to %1 closed + החיבור אל %1 נסגר + + + + + Connection closed + החיבור נסגר + + + + + + + Unknown error + + + + + + Request aborted + + + + + + No server set to connect to + + + + + + Server closed connection unexpectedly + + + + + + Invalid HTTP response header + + + + + Unknown authentication method + + + + + + + + Invalid HTTP chunked body + + + + + Error writing response to device + + + + + Proxy authentication required + + + + + Authentication required + + + + + Connection refused (or timed out) + + + + + Proxy requires authentication + + + + + Host requires authentication + + + + + Data corrupted + + + + + Unknown protocol specified + + + + + SSL handshake failed + + + + + QHttpSocketEngine + + + Did not receive HTTP response from proxy + + + + + Error parsing authentication request from proxy + + + + + Authentication required + + + + + Proxy denied connection + + + + + Error communicating with HTTP proxy + + + + + Proxy server not found + + + + + Proxy connection refused + + + + + Proxy server connection timed out + + + + + Proxy connection closed prematurely + + + + + QIBaseDriver + + + Error opening database + + + + + Could not start transaction + + + + + Unable to commit transaction + + + + + Unable to rollback transaction + + + + + QIBaseResult + + + Unable to create BLOB + + + + + Unable to write BLOB + + + + + Unable to open BLOB + + + + + Unable to read BLOB + + + + + + Could not find array + + + + + Could not get array data + + + + + Could not get query info + + + + + Could not start transaction + + + + + Unable to commit transaction + + + + + Could not allocate statement + + + + + Could not prepare statement + + + + + + Could not describe input statement + + + + + Could not describe statement + + + + + Unable to close statement + + + + + Unable to execute query + + + + + Could not fetch next item + + + + + Could not get statement info + + + + + QIODevice + + + Permission denied + + + + + Too many open files + + + + + No such file or directory + + + + + No space left on device + + + + + Unknown error + + + + + QInputContext + + + XIM + + + + + XIM input method + + + + + Windows input method + + + + + Mac OS X input method + + + + + QInputDialog + + + Enter a value: + + + + + QLibrary + + + Could not mmap '%1': %2 + + + + + Plugin verification data mismatch in '%1' + + + + + Could not unmap '%1': %2 + + + + + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] + + + + + The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" + + + + + Unknown error + + + + + + The shared library was not found. + + + + + The file '%1' is not a valid Qt plugin. + + + + + The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) + + + + + + Cannot load library %1: %2 + + + + + + Cannot unload library %1: %2 + + + + + + Cannot resolve symbol "%1" in %2: %3 + + + + + QLineEdit + + + &Undo + &בטל + + + + &Redo + בצע &שוב + + + + Cu&t + &גזור + + + + &Copy + הע&תק + + + + &Paste + ה&דבק + + + + Select All + בחר הכל + + + + Delete + מחק + + + + QLocalServer + + + + %1: Name error + + + + + %1: Permission denied + + + + + %1: Address in use + + + + + + %1: Unknown error %2 + + + + + QLocalSocket + + + + %1: Connection refused + + + + + + %1: Remote closed + + + + + + + + %1: Invalid name + + + + + + %1: Socket access error + + + + + + %1: Socket resource error + + + + + + %1: Socket operation timed out + + + + + + %1: Datagram too large + + + + + + + %1: Connection error + + + + + + %1: The socket operation is not supported + + + + + %1: Unknown error + + + + + + %1: Unknown error %2 + + + + + QMYSQLDriver + + + Unable to open database ' + + + + + Unable to connect + + + + + Unable to begin transaction + + + + + Unable to commit transaction + + + + + Unable to rollback transaction + + + + + QMYSQLResult + + + Unable to fetch data + + + + + Unable to execute query + + + + + Unable to store result + + + + + + Unable to prepare statement + + + + + Unable to reset statement + + + + + Unable to bind value + + + + + Unable to execute statement + + + + + + Unable to bind outvalues + + + + + Unable to store statement results + + + + + Unable to execute next query + + + + + Unable to store next result + + + + + QMdiArea + + + (Untitled) + + + + + QMdiSubWindow + + + %1 - [%2] + %1 - [%2] + + + + Close + סגור + + + + Minimize + מזער + + + + Restore Down + שחזר למטה + + + + &Restore + ש&חזר + + + + &Move + ה&זז + + + + &Size + גו&דל + + + + Mi&nimize + &מזער + + + + Ma&ximize + &הגדל + + + + Stay on &Top + &תמיד עליון + + + + &Close + &סגור + + + + - [%1] + + + + + Maximize + הגדל + + + + Unshade + + + + + Shade + + + + + Restore + + + + + Help + עזרה + + + + Menu + + + + + QMenu + + + + Close + סגור + + + + + Open + פתח + + + + + + Execute + + + + + QMenuBar + + Options + אפשרויות + + + + QMessageBox + + + + + + OK + אישור + + + + About Qt + + + + + Help + עזרה + + + + Show Details... + + + + + Hide Details... + + + + + <h3>About Qt</h3><p>This program uses Qt version %1.</p><p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://qt.nokia.com/">qt.nokia.com</a> for more information.</p> + + + + + QMultiInputContext + + + Select IM + + + + + QMultiInputContextPlugin + + + Multiple input method switcher + + + + + Multiple input method switcher that uses the context menu of the text widgets + + + + + QNativeSocketEngine + + + The remote host closed the connection + + + + + Network operation timed out + + + + + Out of resources + + + + + Unsupported socket operation + + + + + Protocol type not supported + + + + + Invalid socket descriptor + + + + + Network unreachable + + + + + Permission denied + + + + + Connection timed out + + + + + Connection refused + החיבור נדחה + + + + The bound address is already in use + + + + + The address is not available + + + + + The address is protected + + + + + Unable to send a message + + + + + Unable to receive a message + + + + + Unable to write + + + + + Network error + + + + + Another socket is already listening on the same port + + + + + Unable to initialize non-blocking socket + + + + + Unable to initialize broadcast socket + + + + + Attempt to use IPv6 socket on a platform with no IPv6 support + + + + + Host unreachable + + + + + Datagram was too large to send + + + + + Operation on non-socket + + + + + Unknown error + + + + + The proxy type is invalid for this operation + + + + + QNetworkAccessCacheBackend + + + Error opening %1 + + + + + QNetworkAccessFileBackend + + + Request for opening non-local file %1 + + + + + Error opening %1: %2 + + + + + Write error writing to %1: %2 + + + + + Cannot open %1: Path is a directory + + + + + Read error reading from %1: %2 + + + + + QNetworkAccessFtpBackend + + + No suitable proxy found + + + + + Cannot open %1: is a directory + + + + + Logging in to %1 failed: authentication required + + + + + Error while downloading %1: %2 + + + + + Error while uploading %1: %2 + + + + + QNetworkAccessHttpBackend + + + No suitable proxy found + + + + + QNetworkReply + + + Error downloading %1 - server replied: %2 + + + + + Protocol "%1" is unknown + + + + + QNetworkReplyImpl + + + + Operation canceled + + + + + QOCIDriver + + + Unable to logon + + + + + Unable to initialize + QOCIDriver + + + + + Unable to begin transaction + + + + + Unable to commit transaction + + + + + Unable to rollback transaction + + + + + QOCIResult + + + + + Unable to bind column for batch execute + + + + + Unable to execute batch statement + + + + + Unable to goto next + + + + + Unable to alloc statement + + + + + Unable to prepare statement + + + + + Unable to bind value + + + + + Unable to execute statement + + + + + QODBCDriver + + + Unable to connect + + + + + Unable to connect - Driver doesn't support all needed functionality + + + + + Unable to disable autocommit + + + + + Unable to commit transaction + + + + + Unable to rollback transaction + + + + + Unable to enable autocommit + + + + + QODBCResult + + + + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration + + + + + + Unable to execute statement + + + + + Unable to fetch next + + + + + Unable to prepare statement + + + + + Unable to bind variable + + + + + + + Unable to fetch last + + + + + Unable to fetch + + + + + Unable to fetch first + + + + + Unable to fetch previous + + + + + QObject + + + Home + Home + + + + Operation not supported on %1 + + + + + Invalid URI: %1 + + + + + Write error writing to %1: %2 + + + + + Read error reading from %1: %2 + + + + + Socket error on %1: %2 + + + + + Remote host closed the connection prematurely on %1 + + + + + Protocol error: packet of size 0 received + + + + + + No host name given + + + + + QPPDOptionsModel + + + Name + שם + + + + Value + + + + + QPSQLDriver + + + Unable to connect + + + + + Could not begin transaction + + + + + Could not commit transaction + + + + + Could not rollback transaction + + + + + Unable to subscribe + + + + + Unable to unsubscribe + + + + + QPSQLResult + + + Unable to create query + + + + + Unable to prepare statement + + + + + QPageSetupWidget + + + Centimeters (cm) + + + + + Millimeters (mm) + + + + + Inches (in) + + + + + Points (pt) + + + + + Form + + + + + Paper + + + + + Page size: + + + + + Width: + + + + + Height: + + + + + Paper source: + + + + + Orientation + + + + + Portrait + לאורך + + + + Landscape + לרוחב + + + + Reverse landscape + + + + + Reverse portrait + + + + + Margins + + + + + top margin + + + + + left margin + + + + + right margin + + + + + bottom margin + + + + + QPluginLoader + + + Unknown error + + + + + The plugin was not loaded. + + + + + QPrintDialog + + + locally connected + מחוברת מקומית + + + + + Aliases: %1 + שמות נוספים: %1 + + + + + unknown + לא ידוע + + + + OK + אישור + + + Cancel + ביטול + + + Print in color if available + הדפס בצבע אם הדבר זמין + + + Printer + מדפסת + + + + Print all + הדפס הכל + + + + Print range + טווח הדפסה + + + Print last page first + הדפס את העמוד הראשון אחרון + + + Number of copies: + מספר עותקים: + + + Paper format + תבנית נייר + + + Portrait + לאורך + + + Landscape + לרוחב + + + + A0 (841 x 1189 mm) + A0 (841 x 1189 mm) + + + + A1 (594 x 841 mm) + A1 (594 x 841 mm) + + + + A2 (420 x 594 mm) + A2 (420 x 594 mm) + + + + A3 (297 x 420 mm) + A3 (297 x 420 mm) + + + + A5 (148 x 210 mm) + A5 (148 x 210 mm) + + + + A6 (105 x 148 mm) + A6 (105 x 148 mm) + + + + A7 (74 x 105 mm) + A7 (74 x 105 mm) + + + + A8 (52 x 74 mm) + A8 (52 x 74 mm) + + + + A9 (37 x 52 mm) + A9 (37 x 52 mm) + + + + B0 (1000 x 1414 mm) + B0 (1000 x 1414 mm) + + + + B1 (707 x 1000 mm) + B1 (707 x 1000 mm) + + + + B2 (500 x 707 mm) + B2 (500 x 707 mm) + + + + B3 (353 x 500 mm) + B3 (353 x 500 mm) + + + + B4 (250 x 353 mm) + B4 (250 x 353 mm) + + + + B6 (125 x 176 mm) + B6 (125 x 176 mm) + + + + B7 (88 x 125 mm) + B7 (88 x 125 mm) + + + + B8 (62 x 88 mm) + B8 (62 x 88 mm) + + + + B9 (44 x 62 mm) + B9 (44 x 62 mm) + + + + B10 (31 x 44 mm) + B10 (31 x 44 mm) + + + + C5E (163 x 229 mm) + C5E (163 x 229 mm) + + + + DLE (110 x 220 mm) + DLE (110 x 220 mm) + + + + Folio (210 x 330 mm) + Folio (210 x 330 mm) + + + + Ledger (432 x 279 mm) + Ledger (432 x 279 mm) + + + + Tabloid (279 x 432 mm) + Tabloid (279 x 432 mm) + + + + US Common #10 Envelope (105 x 241 mm) + US Common #10 Envelope (105 x 241 mm) + + + + A4 (210 x 297 mm, 8.26 x 11.7 inches) + + + + + B5 (176 x 250 mm, 6.93 x 9.84 inches) + + + + + Executive (7.5 x 10 inches, 191 x 254 mm) + + + + + Legal (8.5 x 14 inches, 216 x 356 mm) + + + + + Letter (8.5 x 11 inches, 216 x 279 mm) + + + + + + + Print + הדפס + + + File + קובץ + + + + Print To File ... + + + + Other + אחר + + + + File %1 is not writable. +Please choose a different file name. + + + + + %1 already exists. +Do you want to overwrite it? + + + + + File exists + + + + + <qt>Do you want to overwrite it?</qt> + + + + + Print selection + + + + + %1 is a directory. +Please choose a different file name. + + + + + A0 + + + + + A1 + + + + + A2 + + + + + A3 + + + + + A4 + + + + + A5 + + + + + A6 + + + + + A7 + + + + + A8 + + + + + A9 + + + + + B0 + + + + + B1 + + + + + B2 + + + + + B3 + + + + + B4 + + + + + B5 + + + + + B6 + + + + + B7 + + + + + B8 + + + + + B9 + + + + + B10 + + + + + C5E + + + + + DLE + + + + + Executive + + + + + Folio + + + + + Ledger + + + + + Legal + + + + + Letter + + + + + Tabloid + + + + + US Common #10 Envelope + + + + + Custom + + + + + + &Options >> + + + + + &Print + + + + + &Options << + + + + + Print to File (PDF) + + + + + Print to File (Postscript) + + + + + Local file + + + + + Write %1 file + + + + + The 'From' value cannot be greater than the 'To' value. + + + + + QPrintPreviewDialog + + + + Page Setup + + + + + %1% + + + + + Print Preview + + + + + Next page + + + + + Previous page + + + + + First page + + + + + Last page + + + + + Fit width + + + + + Fit page + + + + + Zoom in + + + + + Zoom out + + + + + Portrait + לאורך + + + + Landscape + לרוחב + + + + Show single page + + + + + Show facing pages + + + + + Show overview of all pages + + + + + Print + הדפס + + + + Page setup + + + + + Close + סגור + + + + Export to PDF + + + + + Export to PostScript + + + + + QPrintPropertiesDialog + + Save + שמור + + + OK + אישור + + + + QPrintPropertiesWidget + + + Form + + + + + Page + + + + + Advanced + + + + + QPrintSettingsOutput + + + Form + + + + + Copies + + + + + Print range + טווח הדפסה + + + + Print all + הדפס הכל + + + + Pages from + + + + + to + + + + + Selection + + + + + Output Settings + + + + + Copies: + + + + + Collate + + + + + Reverse + + + + + Options + אפשרויות + + + + Color Mode + + + + + Color + + + + + Grayscale + + + + + Duplex Printing + + + + + None + + + + + Long side + + + + + Short side + + + + + QPrintWidget + + + Form + + + + + Printer + מדפסת + + + + &Name: + + + + + P&roperties + + + + + Location: + + + + + Preview + + + + + Type: + + + + + Output &file: + + + + + ... + + + + + QProcess + + + + Could not open input redirection for reading + + + + + + Could not open output redirection for writing + + + + + Resource error (fork failure): %1 + + + + + + + + + + + + + Process operation timed out + + + + + + + + Error reading from process + + + + + + + Error writing to process + + + + + Process crashed + + + + + No program defined + + + + + Process failed to start + + + + + QProgressDialog + + + Cancel + ביטול + + + + QPushButton + + + Open + פתח + + + + QRadioButton + + + Check + + + + + QRegExp + + + no error occurred + לא אירעה כל שגיאה + + + + disabled feature used + + + + + bad char class syntax + + + + + bad lookahead syntax + + + + + bad repetition syntax + + + + + invalid octal value + + + + + missing left delim + + + + + unexpected end + + + + + met internal limit + + + + + QSQLite2Driver + + + Error to open database + + + + + Unable to begin transaction + + + + + Unable to commit transaction + + + + + Unable to rollback Transaction + + + + + QSQLite2Result + + + Unable to fetch results + + + + + Unable to execute statement + + + + + QSQLiteDriver + + + Error opening database + + + + + Error closing database + + + + + Unable to begin transaction + + + + + Unable to commit transaction + + + + + Unable to rollback transaction + + + + + QSQLiteResult + + + + + Unable to fetch row + + + + + Unable to execute statement + + + + + Unable to reset statement + + + + + Unable to bind parameters + + + + + Parameter count mismatch + + + + + No query + + + + + QScrollBar + + + Scroll here + + + + + Left edge + + + + + Top + + + + + Right edge + + + + + Bottom + + + + + Page left + + + + + + Page up + + + + + Page right + + + + + + Page down + + + + + Scroll left + + + + + Scroll up + + + + + Scroll right + + + + + Scroll down + + + + + Line up + סדר בשורה + + + + Position + + + + + Line down + + + + + QSharedMemory + + + %1: unable to set key on lock + + + + + %1: create size is less then 0 + + + + + + %1: unable to lock + + + + + %1: unable to unlock + + + + + + %1: permission denied + + + + + + %1: already exists + + + + + + %1: doesn't exists + + + + + + %1: out of resources + + + + + + %1: unknown error %2 + + + + + %1: key is empty + + + + + %1: unix key file doesn't exists + + + + + %1: ftok failed + + + + + + %1: unable to make key + + + + + %1: system-imposed size restrictions + + + + + %1: not attached + + + + + %1: invalid size + + + + + %1: key error + + + + + %1: size query failed + + + + + QShortcut + + + Space + רווח + + + + Esc + Esc + + + + Tab + Tab + + + + Backtab + Backtab + + + + Backspace + Backspace + + + + Return + Return + + + + Enter + Enter + + + + Ins + Ins + + + + Del + Del + + + + Pause + Pause + + + + Print + הדפס + + + + SysReq + SysReq + + + + Home + Home + + + + End + End + + + + Left + שמאלה + + + + Up + למעלה + + + + Right + ימינה + + + + Down + למטה + + + + PgUp + PgUp + + + + PgDown + PgDown + + + + CapsLock + CapsLock + + + + NumLock + NumLock + + + + ScrollLock + ScrollLock + + + + Menu + + + + + Help + עזרה + + + + Back + אחורה + + + + Forward + + + + + Stop + + + + + Refresh + + + + + Volume Down + + + + + Volume Mute + + + + + Volume Up + + + + + Bass Boost + + + + + Bass Up + + + + + Bass Down + + + + + Treble Up + + + + + Treble Down + + + + + Media Play + + + + + Media Stop + + + + + Media Previous + + + + + Media Next + + + + + Media Record + + + + + Favorites + + + + + Search + + + + + Standby + + + + + Open URL + + + + + Launch Mail + + + + + Launch Media + + + + + Launch (0) + + + + + Launch (1) + + + + + Launch (2) + + + + + Launch (3) + + + + + Launch (4) + + + + + Launch (5) + + + + + Launch (6) + + + + + Launch (7) + + + + + Launch (8) + + + + + Launch (9) + + + + + Launch (A) + + + + + Launch (B) + + + + + Launch (C) + + + + + Launch (D) + + + + + Launch (E) + + + + + Launch (F) + + + + + Print Screen + + + + + Page Up + + + + + Page Down + + + + + Caps Lock + + + + + Num Lock + + + + + Number Lock + + + + + Scroll Lock + + + + + Insert + הוסף + + + + Delete + מחק + + + + Escape + + + + + System Request + + + + + Select + + + + + Yes + כן + + + + No + לא + + + + Context1 + + + + + Context2 + + + + + Context3 + + + + + Context4 + + + + + Call + + + + + Hangup + + + + + Flip + + + + + + Ctrl + Ctrl + + + + + Shift + Shift + + + + + Alt + Alt + + + + + Meta + + + + + + + + + + + + F%1 + F%1 + + + + Home Page + + + + + QSlider + + + Page left + + + + + Page up + + + + + Position + + + + + Page right + + + + + Page down + + + + + QSocks5SocketEngine + + + Connection to proxy refused + + + + + Connection to proxy closed prematurely + + + + + Proxy host not found + + + + + Connection to proxy timed out + + + + + Proxy authentication failed + + + + + Proxy authentication failed: %1 + + + + + SOCKS version 5 protocol error + + + + + General SOCKSv5 server failure + + + + + Connection not allowed by SOCKSv5 server + + + + + TTL expired + + + + + SOCKSv5 command not supported + + + + + Address type not supported + + + + + Unknown SOCKSv5 proxy error code 0x%1 + + + + + Network operation timed out + + + + + QSpinBox + + + More + + + + + Less + + + + + QSql + + + Delete + מחק + + + + Delete this record? + האם למחוק רשומה זו? + + + + + + Yes + כן + + + + + + No + לא + + + + Insert + הוסף + + + + Update + עדכן + + + + Save edits? + האם לשמור את העריכה? + + + + Cancel + ביטול + + + + Confirm + אישור + + + + Cancel your edits? + האם לבטל את העריכה שלך? + + + + QSslSocket + + + Unable to write data: %1 + + + + + Error while reading: %1 + + + + + Error during SSL handshake: %1 + + + + + Error creating SSL context (%1) + + + + + Invalid or empty cipher list (%1) + + + + + Error creating SSL session, %1 + + + + + Error creating SSL session: %1 + + + + + Cannot provide a certificate with no key, %1 + + + + + Error loading local certificate, %1 + + + + + Error loading private key, %1 + + + + + Private key does not certificate public key, %1 + + + + + QSystemSemaphore + + + + %1: out of resources + + + + + + %1: permission denied + + + + + %1: already exists + + + + + %1: does not exist + + + + + + %1: unknown error %2 + + + + + QTDSDriver + + + Unable to open connection + + + + + Unable to use database + + + + + QTabBar + + + Scroll Left + + + + + Scroll Right + + + + + QTcpServer + + + Operation on socket is not supported + + + + + QTextControl + + + &Undo + &בטל + + + + &Redo + בצע &שוב + + + + Cu&t + &גזור + + + + &Copy + הע&תק + + + + Copy &Link Location + + + + + &Paste + ה&דבק + + + + Delete + מחק + + + + Select All + בחר הכל + + + + QToolButton + + + + Press + + + + + + Open + פתח + + + + QUdpSocket + + + This platform does not support IPv6 + + + + + QUndoGroup + + + Undo + בטל + + + + Redo + שחזר + + + + QUndoModel + + + <empty> + + + + + QUndoStack + + + Undo + בטל + + + + Redo + שחזר + + + + QUnicodeControlCharacterMenu + + + LRM Left-to-right mark + + + + + RLM Right-to-left mark + + + + + ZWJ Zero width joiner + + + + + ZWNJ Zero width non-joiner + + + + + ZWSP Zero width space + + + + + LRE Start of left-to-right embedding + + + + + RLE Start of right-to-left embedding + + + + + LRO Start of left-to-right override + + + + + RLO Start of right-to-left override + + + + + PDF Pop directional formatting + + + + + Insert Unicode control character + + + + + QWebFrame + + + Request cancelled + + + + + Request blocked + + + + + Cannot show URL + + + + + Frame load interruped by policy change + + + + + Cannot show mimetype + + + + + File does not exist + + + + + QWebPage + + + Bad HTTP request + + + + + Submit + default label for Submit buttons in forms on web pages + + + + + Submit + Submit (input element) alt text for <input> elements with no alt, title, or value + + + + + Reset + default label for Reset buttons in forms on web pages + + + + + This is a searchable index. Enter search keywords: + text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' + + + + + Choose File + title for file button used in HTML forms + + + + + No file selected + text to display in file button used in HTML forms when no file is selected + + + + + Open in New Window + Open in New Window context menu item + + + + + Save Link... + Download Linked File context menu item + + + + + Copy Link + Copy Link context menu item + + + + + Open Image + Open Image in New Window context menu item + + + + + Save Image + Download Image context menu item + + + + + Copy Image + Copy Link context menu item + + + + + Open Frame + Open Frame in New Window context menu item + + + + + Copy + Copy context menu item + + + + + Go Back + Back context menu item + + + + + Go Forward + Forward context menu item + + + + + Stop + Stop context menu item + + + + + Reload + Reload context menu item + + + + + Cut + Cut context menu item + + + + + Paste + Paste context menu item + + + + + No Guesses Found + No Guesses Found context menu item + + + + + Ignore + Ignore Spelling context menu item + + + + + Add To Dictionary + Learn Spelling context menu item + + + + + Search The Web + Search The Web context menu item + + + + + Look Up In Dictionary + Look Up in Dictionary context menu item + + + + + Open Link + Open Link context menu item + + + + + Ignore + Ignore Grammar context menu item + + + + + Spelling + Spelling and Grammar context sub-menu item + + + + + Show Spelling and Grammar + menu item title + + + + + Hide Spelling and Grammar + menu item title + + + + + Check Spelling + Check spelling context menu item + + + + + Check Spelling While Typing + Check spelling while typing context menu item + + + + + Check Grammar With Spelling + Check grammar with spelling context menu item + + + + + Fonts + Font context sub-menu item + + + + + Bold + Bold context menu item + + + + + Italic + Italic context menu item + + + + + Underline + Underline context menu item + + + + + Outline + Outline context menu item + + + + + Direction + Writing direction context sub-menu item + + + + + Text Direction + Text direction context sub-menu item + + + + + Default + Default writing direction context menu item + + + + + LTR + Left to Right context menu item + + + + + RTL + Right to Left context menu item + + + + + Inspect + Inspect Element context menu item + + + + + No recent searches + Label for only item in menu that appears when clicking on the search field image, when no searches have been performed + + + + + Recent searches + label for first item in the menu that appears when clicking on the search field image, used as embedded menu title + + + + + Clear recent searches + menu item in Recent Searches menu that empties menu's contents + + + + + Unknown + Unknown filesize FTP directory listing item + + + + + %1 (%2x%3 pixels) + Title string for images + + + + + Web Inspector - %2 + + + + + Scroll here + + + + + Left edge + + + + + Top + + + + + Right edge + + + + + Bottom + + + + + Page left + + + + + Page up + + + + + Page right + + + + + Page down + + + + + Scroll left + + + + + Scroll up + + + + + Scroll right + + + + + Scroll down + + + + + %n file(s) + number of chosen file + + + + + + + JavaScript Alert - %1 + + + + + JavaScript Confirm - %1 + + + + + JavaScript Prompt - %1 + + + + + Move the cursor to the next character + + + + + Move the cursor to the previous character + + + + + Move the cursor to the next word + + + + + Move the cursor to the previous word + + + + + Move the cursor to the next line + + + + + Move the cursor to the previous line + + + + + Move the cursor to the start of the line + + + + + Move the cursor to the end of the line + + + + + Move the cursor to the start of the block + + + + + Move the cursor to the end of the block + + + + + Move the cursor to the start of the document + + + + + Move the cursor to the end of the document + + + + + Select all + + + + + Select to the next character + + + + + Select to the previous character + + + + + Select to the next word + + + + + Select to the previous word + + + + + Select to the next line + + + + + Select to the previous line + + + + + Select to the start of the line + + + + + Select to the end of the line + + + + + Select to the start of the block + + + + + Select to the end of the block + + + + + Select to the start of the document + + + + + Select to the end of the document + + + + + Delete to the start of the word + + + + + Delete to the end of the word + + + + + Insert a new paragraph + + + + + Insert a new line + + + + + QWhatsThisAction + + + What's This? + מה זה? + + + + QWidget + + + * + + + + + QWizard + + + Cancel + ביטול + + + + Help + עזרה + + + + Go Back + + + + + Continue + + + + + Commit + + + + + Done + + + + + < &Back + + + + + &Finish + + + + + &Help + + + + + &Next + + + + + &Next > + + + + + QWorkspace + + + &Restore + ש&חזר + + + + &Move + ה&זז + + + + &Size + &שנה גודל + + + + Mi&nimize + &מזער + + + + Ma&ximize + &הגדל + + + + &Close + &סגור + + + + Stay on &Top + &תמיד עליון + + + + + Sh&ade + &גלול + + + + + %1 - [%2] + %1 - [%2] + + + + Minimize + מזער + + + + Restore Down + שחזר למטה + + + + Close + סגור + + + + &Unshade + &בטל גלילה + + + + QXml + + + no error occurred + לא אירעה כל שגיאה + + + + error triggered by consumer + נגרמה שגיאה על ידי הצרכן + + + + unexpected end of file + סוף קובץ לא צפוי + + + + more than one document type definition + יותר מהגדרה אחת של סוג מסמך + + + + error occurred while parsing element + אירעה שגיאה בעת עיבוד המרכיב + + + + tag mismatch + אי-התאמה בתגית + + + + error occurred while parsing content + אירעה שגיאה בעת עיבוד התוכן + + + + unexpected character + תו לא צפוי + + + + invalid name for processing instruction + שם לא תקף עבור הוראת העיבוד + + + + version expected while reading the XML declaration + הייתה צפויה גירסה בעת קריאה ההכרזה על XML + + + + wrong value for standalone declaration + ערך שגוי עבור ההגדרה העצמאית + + + + encoding declaration or standalone declaration expected while reading the XML declaration + הייתה צפויה הכרזה על קידוד או הכרזה עצמאית בעת קריאת ההכרזה על XML + + + + standalone declaration expected while reading the XML declaration + הייתה צפויה הכרזה עצמאית בעת קריאת ההכרזה על XML + + + + error occurred while parsing document type definition + אירעה שגיאה בעת עיבוד הגדרת סוג המסמך + + + + letter is expected + הייתה צפויה אות + + + + error occurred while parsing comment + אירעה שגיאה בעת עיבוד ההערה + + + + error occurred while parsing reference + אירעה שגיאה בעת עיבוד ההתייחסות + + + + internal general entity reference not allowed in DTD + התייחסות ליישות כללית פנימית אינה מותרת ב-DTD + + + + external parsed general entity reference not allowed in attribute value + התייחסות ליישות כללית מעובדת חיצונית אינה מותרת בערך המאפיין + + + + external parsed general entity reference not allowed in DTD + התייחסות ליישות כללית מעובדת חיצונית אינה מותרת ב-DTD + + + + unparsed entity reference in wrong context + התייחסות ליישות לא מעובדת בהקשר שגוי + + + + recursive entities + יישות רקורסיבית + + + + error in the text declaration of an external entity + שגיאה בהכרזת טקסט של יישות חיצונית + + + + QXmlStream + + + + Extra content at end of document. + + + + + Invalid entity value. + + + + + Invalid XML character. + + + + + Sequence ']]>' not allowed in content. + + + + + Namespace prefix '%1' not declared + + + + + Attribute redefined. + + + + + Unexpected character '%1' in public id literal. + + + + + Invalid XML version string. + + + + + Unsupported XML version. + + + + + %1 is an invalid encoding name. + + + + + Encoding %1 is unsupported + + + + + Standalone accepts only yes or no. + + + + + Invalid attribute in XML declaration. + + + + + Premature end of document. + + + + + Invalid document. + + + + + Expected + + + + + , but got ' + + + + + Unexpected ' + + + + + Expected character data. + + + + + Recursive entity detected. + + + + + Start tag expected. + + + + + XML declaration not at start of document. + + + + + NDATA in parameter entity declaration. + + + + + %1 is an invalid processing instruction name. + + + + + Invalid processing instruction name. + + + + + + + + Illegal namespace declaration. + + + + + Invalid XML name. + + + + + Opening and ending tag mismatch. + + + + + Reference to unparsed entity '%1'. + + + + + + + Entity '%1' not declared. + + + + + Reference to external entity '%1' in attribute value. + + + + + Invalid character reference. + + + + + + Encountered incorrectly encoded content. + + + + + The standalone pseudo attribute must appear after the encoding. + + + + + %1 is an invalid PUBLIC identifier. + + + + + QtXmlPatterns + + + An %1-attribute with value %2 has already been declared. + + + + + An %1-attribute must have a valid %2 as value, which %3 isn't. + + + + + Network timeout. + + + + + Element %1 can't be serialized because it appears outside the document element. + + + + + Attribute %1 can't be serialized because it appears at the top level. + + + + + Year %1 is invalid because it begins with %2. + + + + + Day %1 is outside the range %2..%3. + + + + + Month %1 is outside the range %2..%3. + + + + + Overflow: Can't represent date %1. + + + + + Day %1 is invalid for month %2. + + + + + Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; + + + + + Time %1:%2:%3.%4 is invalid. + + + + + Overflow: Date can't be represented. + + + + + + At least one component must be present. + + + + + At least one time component must appear after the %1-delimiter. + + + + + No operand in an integer division, %1, can be %2. + + + + + The first operand in an integer division, %1, cannot be infinity (%2). + + + + + The second operand in a division, %1, cannot be zero (%2). + + + + + %1 is not a valid value of type %2. + + + + + When casting to %1 from %2, the source value cannot be %3. + + + + + Integer division (%1) by zero (%2) is undefined. + + + + + Division (%1) by zero (%2) is undefined. + + + + + Modulus division (%1) by zero (%2) is undefined. + + + + + + Dividing a value of type %1 by %2 (not-a-number) is not allowed. + + + + + Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed. + + + + + Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed. + + + + + A value of type %1 cannot have an Effective Boolean Value. + + + + + Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values. + + + + + Value %1 of type %2 exceeds maximum (%3). + + + + + Value %1 of type %2 is below minimum (%3). + + + + + A value of type %1 must contain an even number of digits. The value %2 does not. + + + + + %1 is not valid as a value of type %2. + + + + + Operator %1 cannot be used on type %2. + + + + + Operator %1 cannot be used on atomic values of type %2 and %3. + + + + + The namespace URI in the name for a computed attribute cannot be %1. + + + + + The name for a computed attribute cannot have the namespace URI %1 with the local name %2. + + + + + Type error in cast, expected %1, received %2. + + + + + When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed. + + + + + No casting is possible with %1 as the target type. + + + + + It is not possible to cast from %1 to %2. + + + + + Casting to %1 is not possible because it is an abstract type, and can therefore never be instantiated. + + + + + It's not possible to cast the value %1 of type %2 to %3 + + + + + Failure when casting from %1 to %2: %3 + + + + + A comment cannot contain %1 + + + + + A comment cannot end with a %1. + + + + + No comparisons can be done involving the type %1. + + + + + Operator %1 is not available between atomic values of type %2 and %3. + + + + + An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place. + + + + + A library module cannot be evaluated directly. It must be imported from a main module. + + + + + No template by name %1 exists. + + + + + A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type. + + + + + A positional predicate must evaluate to a single numeric value. + + + + + The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, is %2 invalid. + + + + + %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. + + + + + The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. + + + + + The data of a processing instruction cannot contain the string %1 + + + + + No namespace binding exists for the prefix %1 + + + + + No namespace binding exists for the prefix %1 in %2 + + + + + + %1 is an invalid %2 + + + + + %1 takes at most %n argument(s). %2 is therefore invalid. + + + + + + + %1 requires at least %n argument(s). %2 is therefore invalid. + + + + + + + The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration. + + + + + The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + + + + + The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + + + + + %1 is not a valid XML 1.0 character. + + + + + The first argument to %1 cannot be of type %2. + + + + + If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same. + + + + + %1 was called. + + + + + %1 must be followed by %2 or %3, not at the end of the replacement string. + + + + + In the replacement string, %1 must be followed by at least one digit when not escaped. + + + + + In the replacement string, %1 can only be used to escape itself or %2, not %3 + + + + + %1 matches newline characters + + + + + %1 and %2 match the start and end of a line. + + + + + Matches are case insensitive + + + + + Whitespace characters are removed, except when they appear in character classes + + + + + %1 is an invalid regular expression pattern: %2 + + + + + %1 is an invalid flag for regular expressions. Valid flags are: + + + + + If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified. + + + + + It will not be possible to retrieve %1. + + + + + The root node of the second argument to function %1 must be a document node. %2 is not a document node. + + + + + The default collection is undefined + + + + + %1 cannot be retrieved + + + + + The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization). + + + + + A zone offset must be in the range %1..%2 inclusive. %3 is out of range. + + + + + %1 is not a whole number of minutes. + + + + + Required cardinality is %1; got cardinality %2. + + + + + The item %1 did not match the required type %2. + + + + + + %1 is an unknown schema type. + + + + + Only one %1 declaration can occur in the query prolog. + + + + + The initialization of variable %1 depends on itself + + + + + No variable by name %1 exists + + + + + The variable %1 is unused + + + + + Version %1 is not supported. The supported XQuery version is 1.0. + + + + + The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2. + + + + + No function with signature %1 is available + + + + + + A default namespace declaration must occur before function, variable, and option declarations. + + + + + Namespace declarations must occur before function, variable, and option declarations. + + + + + Module imports must occur before function, variable, and option declarations. + + + + + It is not possible to redeclare prefix %1. + + + + + Prefix %1 is already declared in the prolog. + + + + + The name of an option must have a prefix. There is no default namespace for options. + + + + + The Schema Import feature is not supported, and therefore %1 declarations cannot occur. + + + + + The target namespace of a %1 cannot be empty. + + + + + The module import feature is not supported + + + + + No value is available for the external variable by name %1. + + + + + A construct was encountered which only is allowed in XQuery. + + + + + A template by name %1 has already been declared. + + + + + The keyword %1 cannot occur with any other mode name. + + + + + The value of attribute %1 must of type %2, which %3 isn't. + + + + + The prefix %1 can not be bound. By default, it is already bound to the namespace %2. + + + + + A variable by name %1 has already been declared. + + + + + A stylesheet function must have a prefixed name. + + + + + The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) + + + + + The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. + + + + + The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2 + + + + + A function already exists with the signature %1. + + + + + No external functions are supported. All supported functions can be used directly, without first declaring them as external + + + + + An argument by name %1 has already been declared. Every argument name must be unique. + + + + + When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. + + + + + In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching. + + + + + In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching. + + + + + In an XSL-T pattern, function %1 cannot have a third argument. + + + + + In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. + + + + + In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can. + + + + + %1 is an invalid template mode name. + + + + + The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. + + + + + The Schema Validation Feature is not supported. Hence, %1-expressions may not be used. + + + + + None of the pragma expressions are supported. Therefore, a fallback expression must be present + + + + + Each name of a template parameter must be unique; %1 is duplicated. + + + + + The %1-axis is unsupported in XQuery + + + + + %1 is not a valid name for a processing-instruction. + + + + + %1 is not a valid numeric literal. + + + + + No function by name %1 is available. + + + + + The namespace URI cannot be the empty string when binding to a prefix, %1. + + + + + %1 is an invalid namespace URI. + + + + + It is not possible to bind to the prefix %1 + + + + + Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared). + + + + + Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared). + + + + + Two namespace declaration attributes have the same name: %1. + + + + + The namespace URI must be a constant and cannot use enclosed expressions. + + + + + An attribute by name %1 has already appeared on this element. + + + + + A direct element constructor is not well-formed. %1 is ended with %2. + + + + + The name %1 does not refer to any schema type. + + + + + %1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works. + + + + + %1 is not an atomic type. Casting is only possible to atomic types. + + + + + + %1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported. + + + + + The name of an extension expression must be in a namespace. + + + + + empty + + + + + zero or one + + + + + exactly one + + + + + one or more + + + + + zero or more + + + + + Required type is %1, but %2 was found. + + + + + Promoting %1 to %2 may cause loss of precision. + + + + + The focus is undefined. + + + + + It's not possible to add attributes after any other kind of node. + + + + + An attribute by name %1 has already been created. + + + + + Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported. + + + + + %1 is an unsupported encoding. + + + + + %1 contains octets which are disallowed in the requested encoding %2. + + + + + The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character. + + + + + Ambiguous rule match. + + + + + In a namespace constructor, the value for a namespace cannot be an empty string. + + + + + The prefix must be a valid %1, which %2 is not. + + + + + The prefix %1 cannot be bound. + + + + + Only the prefix %1 can be bound to %2 and vice versa. + + + + + Circularity detected + + + + + The parameter %1 is required, but no corresponding %2 is supplied. + + + + + The parameter %1 is passed, but no corresponding %2 exists. + + + + + The URI cannot have a fragment + + + + + Element %1 is not allowed at this location. + + + + + Text nodes are not allowed at this location. + + + + + Parse error: %1 + + + + + The value of the XSL-T version attribute must be a value of type %1, which %2 isn't. + + + + + Running an XSL-T 1.0 stylesheet with a 2.0 processor. + + + + + Unknown XSL-T attribute %1. + + + + + Attribute %1 and %2 are mutually exclusive. + + + + + In a simplified stylesheet module, attribute %1 must be present. + + + + + If element %1 has no attribute %2, it cannot have attribute %3 or %4. + + + + + Element %1 must have at least one of the attributes %2 or %3. + + + + + At least one mode must be specified in the %1-attribute on element %2. + + + + + Attribute %1 cannot appear on the element %2. Only the standard attributes can appear. + + + + + Attribute %1 cannot appear on the element %2. Only %3 is allowed, and the standard attributes. + + + + + Attribute %1 cannot appear on the element %2. Allowed is %3, %4, and the standard attributes. + + + + + Attribute %1 cannot appear on the element %2. Allowed is %3, and the standard attributes. + + + + + XSL-T attributes on XSL-T elements must be in the null namespace, not in the XSL-T namespace which %1 is. + + + + + The attribute %1 must appear on element %2. + + + + + The element with local name %1 does not exist in XSL-T. + + + + + Element %1 must come last. + + + + + At least one %1-element must occur before %2. + + + + + Only one %1-element can appear. + + + + + At least one %1-element must occur inside %2. + + + + + When attribute %1 is present on %2, a sequence constructor cannot be used. + + + + + Element %1 must have either a %2-attribute or a sequence constructor. + + + + + When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor. + + + + + Element %1 cannot have children. + + + + + Element %1 cannot have a sequence constructor. + + + + + + The attribute %1 cannot appear on %2, when it is a child of %3. + + + + + A parameter in a function cannot be declared to be a tunnel. + + + + + This processor is not Schema-aware and therefore %1 cannot be used. + + + + + Top level stylesheet elements must be in a non-null namespace, which %1 isn't. + + + + + The value for attribute %1 on element %2 must either be %3 or %4, not %5. + + + + + Attribute %1 cannot have the value %2. + + + + + The attribute %1 can only appear on the first %2 element. + + + + + At least one %1 element must appear as child of %2. + + + + + VolumeSlider + + + Muted + + + + + + Volume: %1% + + + + diff --git a/config.profiles/symbian/translations/qt_pl_symbian.ts b/config.profiles/symbian/translations/qt_pl_symbian.ts new file mode 100644 index 0000000..4208c55 --- /dev/null +++ b/config.profiles/symbian/translations/qt_pl_symbian.ts @@ -0,0 +1,8525 @@ + + + + + + CloseButton + + Close Tab + Zamknij kartę + + + + FakeReply + + Fake error ! + Fałszywy błąd! + + + Invalid URL + Niepoprawny URL + + + + Phonon:: + + Notifications + Powiadomienia + + + Music + Muzyka + + + Video + Wideo + + + Communication + Komunikacja + + + Games + Gry + + + Accessibility + Dostępność + + + + Phonon::AudioOutput + + <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> + <html>Urządzenie dźwiękowe <b>%1</b> nie działa.<br/>Przywracanie do <b>%2</b>.</html> + + + <html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html> + <html>Przełączanie na urządzenie dźwiękowe <b>%1</b><br/>które właśnie stało się dostępne i ma wyższy priorytet.</html> + + + Revert back to device '%1' + Przywróć do urządzenia '%1' + + + + Phonon::Gstreamer::Backend + + Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. + Some video features have been disabled. + Ostrzeżenie: Wygląda na to, że pakiet gstreamer0.10-plugins-good nie jest zainstalowany w tym systemie. +Niektóre możliwości wideo zostały wyłączone. + + + Warning: You do not seem to have the base GStreamer plugins installed. + All audio and video support has been disabled + Ostrzeżenie: Wygląda na to, że podstawowe wtyczki GStreamer nie są zainstalowane w tym systemie. +Obsługa dźwięku i wideo została wyłączona + + + + Phonon::Gstreamer::MediaObject + + Cannot start playback. + +Check your GStreamer installation and make sure you +have libgstreamer-plugins-base installed. + Nie można rozpocząć odtwarzania. + +Sprawdź instalację Gstreamer i upewnij się że +zainstalowałeś libgstreamer-plugins-base. + + + A required codec is missing. You need to install the following codec(s) to play this content: %0 + Brak wymaganego kodeka. Aby odtworzyć zawartość musisz zainstalować poniższy kodek: %0 + + + Could not open media source. + Nie można otworzyć źródła mediów. + + + Invalid source type. + Niepoprawny typ źródła. + + + Could not locate media source. + Nie można znaleźć źródła mediów. + + + Could not open audio device. The device is already in use. + Nie można otworzyć urządzenia dźwiękowego. Urządzenie jest już używane. + + + Could not decode media source. + Nie można zdekodować źródła mediów. + + + + Phonon::MMF + + Audio Output + Wyjście dźwięku + + + The audio output device + Wyjściowe urządzenie dźwiękowe + + + No error + Brak błędu + + + Not found + Nie znaleziono + + + Out of memory + Brak pamięci + + + Not supported + Nieobsługiwane + + + Overflow + Przepełnienie + + + Underflow + Niedopełnienie + + + Already exists + Już istnieje + + + Path not found + Nie znaleziono ścieżki + + + In use + W użyciu + + + Not ready + Brak gotowości + + + Access denied + Odmowa dostępu + + + Could not connect + Nie można połączyć + + + Disconnected + Rozłączono + + + Permission denied + Odmowa uprawnień + + + Insufficient bandwidth + Niewystarczająca szerokość pasma + + + Network unavailable + Sieć niedostępna + + + Network communication error + Błąd komunikacji sieciowej + + + Streaming not supported + Transmisje strumieniowe nieobsługiwane + + + Server alert + Sygnał serwera + + + Invalid protocol + Nieprawidłowy protokół + + + Invalid URL + Nieprawidłowy adres URL + + + Multicast error + Błąd multiemisji + + + Proxy server error + Błąd serwera proxy + + + Proxy server not supported + Serwer proxy nieobsługiwany + + + Audio output error + Błąd sygnału audio + + + Video output error + Błąd wyjścia wideo + + + Decoder error + Błąd dekodera + + + Audio or video components could not be played + Nie można odtworzyć składników dźwiękowych lub wideo + + + DRM error + Błąd DRM + + + Unknown error (%1) + Nieznany błąd (%1) + + + + Phonon::MMF::AbstractMediaPlayer + + Not ready to play + Brak gotowości do odtworzenia + + + Error opening file + Błąd podczas otwierania pliku + + + Error opening URL + Błąd podczas otwierania adresu URL + + + Setting volume failed + Ustawienie głośności nie powiodło się + + + Playback complete + Zakończono odtwarzanie + + + + Phonon::MMF::AudioEqualizer + + %1 Hz + %1 Hz + + + + Phonon::MMF::AudioPlayer + + Getting position failed + Ustalenie pozycji nie powiodło się + + + Opening clip failed + Otwieranie pliku nie powiodło się + + + + Phonon::MMF::EffectFactory + + Enabled + Włączono + + + + Phonon::MMF::EnvironmentalReverb + + Decay HF ratio (%) + Współczynnik HF zanikania (%) + + + Decay time (ms) + Czas zanikania (ms) + + + Density (%) + Gęstość (%) + + + Diffusion (%) + Rozpraszanie (%) + + + Reflections delay (ms) + Opóźnienie odbić (ms) + + + Reflections level (mB) + Poziom odbić (MB) + + + Reverb delay (ms) + Opóźnienie pogłosu (ms) + + + Reverb level (mB) + Poziom pogłosu (MB) + + + Room HF level + Poziom HF pomieszczenia + + + Room level (mB) + Poziom pomieszczenia (MB) + + + + Phonon::MMF::MediaObject + + Error opening source: type not supported + Błąd podczas otwierania źródła: nieobsługiwany typ + + + Error opening source: media type could not be determined + Błąd podczas otwierania źródła: nie można określić typu multimediów + + + + Phonon::MMF::StereoWidening + + Level (%) + Poziom (%) + + + + Phonon::MMF::VideoPlayer + + Pause failed + Wstrzymanie nie powiodło się + + + Seek failed + Wyszukiwanie nie powiodło się + + + Getting position failed + Ustalenie pozycji nie powiodło się + + + Opening clip failed + Otwieranie pliku nie powiodło się + + + Buffering clip failed + Buforowanie pliku nie powiodło się + + + Video display error + Błąd wyświetlacza wideo + + + + Phonon::VolumeSlider + + Volume: %1% + Głośność: %1% + + + Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1% + Użyj tego suwaka aby zmienić głośność. Skrajnie lewa pozycja to 0%, skrajnie prawa to %1% + + + Muted + Wyciszony + + + + Q3Accel + + %1, %2 not defined + %1, %2 nie określone + + + Ambiguous %1 not handled + Niejednoznaczne %1, nie obsłużone + + + + Q3DataTable + + True + Prawda + + + False + Fałsz + + + Insert + Wstaw + + + Update + Uaktualnij + + + Delete + Skasuj + + + + Q3FileDialog + + Copy or Move a File + Skopiuj lub przenieś plik + + + Read: %1 + Czytaj: %1 + + + Write: %1 + Pisz: %1 + + + Cancel + Anuluj + + + All Files (*) + Wszystkie pliki (*) + + + Name + Nazwa + + + Size + Rozmiar + + + Type + Rodzaj + + + Date + Data + + + Attributes + Atrybuty + + + &OK + &OK + + + Look &in: + Sprawdź &w: + + + File &name: + Nazwa &pliku: + + + File &type: + &Rodzaj pliku: + + + Back + Powrót + + + One directory up + Katalog wyżej + + + Create New Folder + Utwórz nowy katalog + + + List View + Lista + + + Detail View + Szczegóły + + + Preview File Info + Podgląd informacji o pliku + + + Preview File Contents + Podgląd zawartości pliku + + + Read-write + Do zapisu i odczytu + + + Read-only + Tylko do odczytu + + + Write-only + Tylko do zapisu + + + Inaccessible + Niedostępny + + + Symlink to File + Dowiązanie symboliczne do pliku + + + Symlink to Directory + Dowiązanie symboliczne do katalogu + + + Symlink to Special + Specjalny dowiązanie symboliczne + + + File + Plik + + + Dir + Katalog + + + Special + Specjalny + + + Open + Otwórz + + + Save As + Zachowaj jako + + + &Open + &Otwórz + + + &Save + &Zachowaj + + + &Rename + &Zmień nazwę + + + &Delete + &Skasuj + + + R&eload + &Odśwież + + + Sort by &Name + Sortuj &po nazwie + + + Sort by &Size + Sortuj po &rozmiarze + + + Sort by &Date + Sortuj po &dacie + + + &Unsorted + &Bez sortowania + + + Sort + Sortuj + + + Show &hidden files + Pokaż &ukryte pliki + + + the file + plik + + + the directory + katalog + + + the symlink + dowiązanie symboliczne + + + Delete %1 + Skasuj %1 + + + <qt>Are you sure you wish to delete %1 "%2"?</qt> + <qt>Na pewno chcesz skasować %1 "%2"?</qt> + + + &Yes + &Tak + + + &No + &Nie + + + New Folder 1 + Nowy katalog 1 + + + New Folder + Nowy katalog + + + New Folder %1 + Nowy katalog %1 + + + Find Directory + Znajdź katalog + + + Directories + Katalogi + + + Directory: + Katalog: + + + Error + Błąd + + + %1 +File not found. +Check path and filename. + %1 +Plik nie znaleziony. +Sprawdź ścieżkę i nazwę pliku. + + + All Files (*.*) + Wszystkie pliki (*.*) + + + Open + Otwórz + + + Select a Directory + Wybierz katalog + + + + Q3LocalFs + + Could not read directory +%1 + Nie można czytać katalogu +%1 + + + Could not create directory +%1 + Nie można utworzyć katalogu +%1 + + + Could not remove file or directory +%1 + Nie można usunąć pliku lub katalogu +%1 + + + Could not rename +%1 +to +%2 + Nie można zmienić nazwy +%1 +na +%2 + + + Could not open +%1 + Nie można otworzyć +%1 + + + Could not write +%1 + Nie można zapisać +%1 + + + + Q3MainWindow + + Line up + Wyrównaj położenie + + + Customize... + Ustawienia użytkownika... + + + + Q3NetworkProtocol + + Operation stopped by the user + Operacja zatrzymana przez użytkownika + + + + Q3ProgressDialog + + Cancel + Anuluj + + + + Q3TabDialog + + OK + OK + + + Apply + Zatwierdź + + + Help + Pomoc + + + Defaults + Domyślne + + + Cancel + Anuluj + + + + Q3TextEdit + + &Undo + &Cofnij + + + &Redo + &Przywróć + + + Cu&t + W&ytnij + + + &Copy + S&kopiuj + + + &Paste + &Wklej + + + Clear + Wyczyść + + + Select All + Zaznacz wszystko + + + + Q3TitleBar + + System + System + + + Restore up + Przywróć na wierzch + + + Minimize + Zminimalizuj + + + Restore down + Przywróć pod spód + + + Maximize + Zmaksymalizuj + + + Close + Zamknij okno + + + Contains commands to manipulate the window + Zawiera polecenia zarządzające oknem + + + Puts a minimized window back to normal + Przywraca normalny rozmiar uprzednio zminimalizowanego okna + + + Moves the window out of the way + Przenosi okno w inne położenie + + + Puts a maximized window back to normal + Przywraca normalny rozmiar uprzednio zmaksymalizowanego okna + + + Makes the window full screen + Powiększa maksymalnie okno + + + Closes the window + Zamyka okno + + + Displays the name of the window and contains controls to manipulate it + Wyświetla nazwę okna i zawiera elementy do zarządzania nim + + + + Q3ToolBar + + More... + Więcej... + + + + Q3UrlOperator + + The protocol `%1' is not supported + Protokół '%1' nie jest obsługiwany + + + The protocol `%1' does not support listing directories + Protokół '%1' nie obsługuje pokazywania katalogów + + + The protocol `%1' does not support creating new directories + Protokół '%1' nie obsługuje tworzenia nowych katalogów + + + The protocol `%1' does not support removing files or directories + Protokół '%1' nie obsługuje usuwania plików lub katalogów + + + The protocol `%1' does not support renaming files or directories + Protokół '%1' nie obsługuje zmiany nazwy plików lub katalogów + + + The protocol `%1' does not support getting files + Protokół '%1' nie obsługuje pobierania plików + + + The protocol `%1' does not support putting files + Protokół '%1' nie obsługuje wysyłania plików + + + The protocol `%1' does not support copying or moving files or directories + Protokół '%1' nie obsługuje kopiowania lub przenoszenia plików lub katalogów + + + (unknown) + (nieznany) + + + + Q3Wizard + + &Cancel + &Anuluj + + + < &Back + < &Wstecz + + + &Next > + &Dalej > + + + &Finish + &Zakończ + + + &Help + &Pomoc + + + + QAbstractSocket + + Host not found + Host nie znaleziony + + + Connection refused + Połączenie odrzucone + + + Connection timed out + Przekroczony czas połączenia + + + Operation on socket is not supported + Operacja na gnieździe nieobsługiwana + + + Socket operation timed out + Przekroczony czas operacji gniazda + + + Socket is not connected + Gniazdo nie jest podłączone + + + Network unreachable + Sieć niedostępna + + + + QAbstractSpinBox + + &Step up + Krok do &góry + + + Step &down + Krok w &dół + + + &Select All + &Zaznacz wszystko + + + + QAccessibleButton + + Press + Wciśnij + + + + QApplication + + QT_LAYOUT_DIRECTION + Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. + LTR + + + Executable '%1' requires Qt %2, found Qt %3. + Program '%1' wymaga do uruchomienia Qt %2, znaleziono Qt %3. + + + Incompatible Qt Library Error + Niekompatybilność biblioteki Qt + + + Activate + Uaktywnij + + + Activates the program's main window + Uaktywnia główne okno programu + + + + QAxSelect + + Select ActiveX Control + Wybierz kontrolkę ActiveX + + + OK + OK + + + &Cancel + &Anuluj + + + COM &Object: + &Obiekt COM: + + + + QCheckBox + + Uncheck + Odznacz + + + Check + Zaznacz + + + Toggle + Przełącz + + + + QColorDialog + + Hu&e: + &Barwa: + + + &Sat: + &Nasycenie: + + + &Val: + &Wartość: + + + &Red: + &Czerwień: + + + &Green: + &Zieleń: + + + Bl&ue: + Błęki&t: + + + A&lpha channel: + Kanał &alfa: + + + Select Color + Wybierz kolor + + + &Basic colors + &Kolory podstawowe + + + &Custom colors + Wła&sne kolory + + + &Add to Custom Colors + &Dodaj do własnych kolorów + + + + QComboBox + + Open + Otwórz + + + False + Fałsz + + + True + Prawda + + + Close + Zamknij + + + + QCoreApplication + + %1: key is empty + QSystemSemaphore + %1: klucz jest pusty + + + %1: unable to make key + QSystemSemaphore + %1: nie można utworzyć klucza + + + %1: ftok failed + QSystemSemaphore + %1: wystąpił błąd w funkcji ftok() + + + %1: already exists + QSystemSemaphore + %1: już istnieje + + + %1: does not exist + QSystemSemaphore + %1: nie istnieje + + + %1: out of resources + QSystemSemaphore + %1: zasoby wyczerpane + + + %1: unknown error %2 + QSystemSemaphore + %1: nieznany błąd %2 + + + + QDB2Driver + + Unable to connect + Nie można nawiązać połączenia + + + Unable to commit transaction + Nie można dokonać transakcji + + + Unable to rollback transaction + Nie można wycofać transakcji + + + Unable to set autocommit + Nie można ustawić trybu automatycznego dokonywania transakcji + + + + QDB2Result + + Unable to execute statement + Nie można wykonać polecenia + + + Unable to prepare statement + Nie można przygotować polecenia + + + Unable to bind variable + Nie można powiązać zmiennej + + + Unable to fetch record %1 + Nie można pobrać rekordu %1 + + + Unable to fetch next + Nie można pobrać kolejnego wiersza danych + + + Unable to fetch first + Nie można pobrać pierwszego wiersza danych + + + + QDateTimeEdit + + AM + AM + + + am + am + + + PM + PM + + + pm + pm + + + + QDial + + QDial + QDial + + + SpeedoMeter + Miernik prędkości + + + SliderHandle + Uchwyt suwaka + + + + QDialog + + What's This? + Co to jest? + + + Done + Wykonano + + + + QDialogButtonBox + + OK + OK + + + Save + Zachowaj + + + &Save + &Zachowaj + + + Open + Otwórz + + + Cancel + Anuluj + + + &Cancel + &Anuluj + + + Close + Zamknij + + + &Close + &Zamknij + + + Apply + Zastosuj + + + Reset + Resetuj + + + Help + Pomoc + + + Don't Save + Nie zachowuj + + + Discard + Odrzuć + + + &Yes + &Tak + + + Yes to &All + Ta&k dla wszystkich + + + &No + &Nie + + + N&o to All + Ni&e dla wszystkich + + + Save All + Zachowaj wszystko + + + Abort + Przerwij + + + Retry + Ponów + + + Ignore + Zignoruj + + + Restore Defaults + Przywróć ustawienia + + + Close without Saving + Zamknij bez zapisywania + + + &OK + &OK + + + + QDirModel + + Name + Nazwa + + + Size + Rozmiar + + + Kind + Match OS X Finder + Typ + + + Type + All other platforms + Rodzaj + + + Date Modified + Data modyfikacji + + + + QDockWidget + + Close + Zamknij + + + Dock + Zadokuj + + + Float + Uwolnij + + + + QDoubleSpinBox + + More + Więcej + + + Less + Mniej + + + + QErrorMessage + + &Show this message again + &Pokaż ten komunikat ponownie + + + &OK + &OK + + + Debug Message: + Komunikat dla programisty: + + + Warning: + Ostrzeżenie: + + + Fatal Error: + Błąd krytyczny: + + + + QFile + + Destination file exists + Plik wyjściowy już istnieje + + + Will not rename sequential file using block copy + Nie można zmienić nazwy pliku sekwencyjnego używając kopiowania blokowego + + + Cannot remove source file + Nie można usunąć oryginalnego pliku + + + Cannot open %1 for input + Nie można otworzyć pliku wejściowego %1 + + + Cannot open for output + Nie można otworzyć pliku wyjściowego + + + Failure to write block + Nie można zapisać bloku + + + Cannot create %1 for output + Nie można utworzyć pliku wyjściowego %1 + + + + QFileDialog + + All Files (*) + Wszystkie pliki (*) + + + Back + Powrót + + + List View + Lista + + + Detail View + Szczegóły + + + File + Plik + + + Open + Otwórz + + + Save As + Zachowaj jako + + + &Open + &Otwórz + + + &Save + &Zachowaj + + + Recent Places + Ostatnie miejsca + + + &Rename + &Zmień nazwę + + + &Delete + &Skasuj + + + Show &hidden files + Pokaż &ukryte pliki + + + New Folder + Nowy katalog + + + Find Directory + Znajdź katalog + + + Directories + Katalogi + + + All Files (*.*) + Wszystkie pliki (*.*) + + + Directory: + Katalog: + + + %1 already exists. +Do you want to replace it? + %1 już istnieje. +Czy chcesz zamienić? + + + %1 +File not found. +Please verify the correct file name was given. + %1 +Plik nie znaleziony. +Proszę o sprawdzenie podanej nazwy pliku. + + + My Computer + Mój komputer + + + Parent Directory + Katalog wyżej + + + Files of type: + Pliki rodzaju: + + + %1 +Directory not found. +Please verify the correct directory name was given. + %1 +Katalog nie znaleziony. +Sprawdź podaną nazwę katalogu. + + + '%1' is write protected. +Do you want to delete it anyway? + '%1' jest zabezpieczony przed zapisem. +Czy na pewno chcesz go skasować? + + + Are sure you want to delete '%1'? + Czy na pewno chcesz skasować '%1'? + + + Could not delete directory. + Nie można skasować katalogu. + + + Drive + Urządzenie + + + File Folder + Match Windows Explorer + Katalog + + + Folder + All other platforms + Katalog + + + Alias + Mac OS X Finder + Alias + + + Shortcut + All other platforms + Skrót + + + Unknown + Nieznany + + + Show + Pokaż + + + Forward + Do przodu + + + &New Folder + &Nowy katalog + + + &Choose + &Wybierz + + + Remove + Usuń + + + File &name: + Nazwa &pliku: + + + Look in: + Szukaj w: + + + Create New Folder + Utwórz nowy katalog + + + + QFileSystemModel + + %1 TB + %1 TB + + + %1 GB + %1 GB + + + %1 MB + %1 MB + + + %1 KB + %1 KB + + + %1 bytes + %1 bajtów + + + Invalid filename + Niepoprawna nazwa pliku + + + <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. + <b>Nazwa "%1" nie może zostać użyta.</b><p>Spróbuj użyć nowej nazwy z mniejszą liczbą znaków lub bez znaków przystankowych. + + + Name + Nazwa + + + Size + Rozmiar + + + Kind + Match OS X Finder + Typ + + + Type + All other platforms + Rodzaj + + + Date Modified + Data modyfikacji + + + My Computer + Mój komputer + + + Computer + Komputer + + + %1 byte(s) + %1 bajt(ów) + + + + QFontDatabase + + Normal + Normalny + + + Bold + Pogrubiony + + + Demi Bold + Na wpół pogrubiony + + + Black + Bardzo gruby + + + Demi + Na wpół + + + Light + Cienki + + + Italic + Kursywa + + + Oblique + Pochyły + + + Any + Każdy + + + Latin + Łaciński + + + Greek + Grecki + + + Cyrillic + Cyrylica + + + Armenian + Ormiański + + + Hebrew + Hebrajski + + + Arabic + Arabski + + + Syriac + Syryjski + + + Thaana + Thaana + + + Devanagari + Devanagari + + + Bengali + Bengalski + + + Gurmukhi + Gurmukhi + + + Gujarati + Gudżaracki + + + Oriya + Orija + + + Tamil + Tamilski + + + Telugu + Telugu + + + Kannada + Kannada + + + Malayalam + Malajalam + + + Sinhala + Syngaleski + + + Thai + Tajski + + + Lao + Laotański + + + Tibetan + Tybetański + + + Myanmar + Birmański + + + Georgian + Gruziński + + + Khmer + Khmerski + + + Simplified Chinese + Uproszczony chiński + + + Traditional Chinese + Tradycyjny chiński + + + Japanese + Japoński + + + Korean + Koreański + + + Vietnamese + Wietnamski + + + Symbol + Symboliczny + + + Ogham + Ogamiczny + + + Runic + Runiczny + + + N'Ko + N'Ko + + + + QFontDialog + + &Font + &Czcionka + + + Font st&yle + St&yl czcionki + + + &Size + &Rozmiar + + + Effects + Efekty + + + Stri&keout + Pr&zekreślenie + + + &Underline + &Podkreślenie + + + Sample + Przykład + + + Select Font + Wybierz czcionkę + + + Wr&iting System + Sys&tem pisania + + + + QFtp + + Host %1 found + Host %1 znaleziony + + + Host found + Host znaleziony + + + Connected to host %1 + Podłączony do hosta %1 + + + Connected to host + Podłączony do hosta + + + Connection to %1 closed + Połączenie do %1 zakończone + + + Connection closed + Połączenie zamknięte + + + Host %1 not found + Host %1 nie znaleziony + + + Connection refused to host %1 + Połączenie do hosta %1 odrzucone + + + Connection timed out to host %1 + Przekroczony czas połączenia do hosta %1 + + + Unknown error + Nieznany błąd + + + Connecting to host failed: +%1 + Podłączanie do hosta zakończone błędem: +%1 + + + Login failed: +%1 + Logowanie nie powiodło się: +%1 + + + Listing directory failed: +%1 + Listowanie katalogu zakończone błędem: +%1 + + + Changing directory failed: +%1 + Zmiana katalogu zakończona błędem: +%1 + + + Downloading file failed: +%1 + Pobieranie pliku zakończone błędem: +%1 + + + Uploading file failed: +%1 + Wysyłanie pliku zakończone błędem: +%1 + + + Removing file failed: +%1 + Usuwanie pliku zakończone błędem: +%1 + + + Creating directory failed: +%1 + Tworzenie katalogu zakończone błędem: +%1 + + + Removing directory failed: +%1 + Usuwanie katalogu zakończone błędem: +%1 + + + Not connected + Nie podłączony + + + Connection refused for data connection + Połączenie do przesyłu danych odrzucone + + + + QHostInfo + + Unknown error + Nieznany błąd + + + + QHostInfoAgent + + Host not found + Host nie znaleziony + + + Unknown address type + Nieznany typ adresu + + + Unknown error + Nieznany błąd + + + No host name given + Nie podano nazwy hosta + + + Invalid hostname + Niepoprawna nazwa hosta + + + + QHttp + + Connection refused + Połączenie odrzucone + + + Host %1 not found + Host %1 nie znaleziony + + + Wrong content length + Błędna długość zawartości + + + HTTP request failed + Komenda HTTP zakończona błędem + + + Host %1 found + Host %1 znaleziony + + + Host found + Host znaleziony + + + Connected to host %1 + Podłączony do hosta %1 + + + Connected to host + Podłączony do hosta + + + Connection to %1 closed + Połączenie do %1 zamknięte + + + Connection closed + Połączenie zakończone + + + Unknown error + Nieznany błąd + + + Request aborted + Komenda przerwana + + + No server set to connect to + Brak serwera do podłączenia + + + Server closed connection unexpectedly + Serwer niespodziewanie zakończył połączenie + + + Invalid HTTP response header + Niepoprawny nagłówek odpowiedzi HTTP + + + Unknown authentication method + Nieznana metoda autoryzacji + + + Invalid HTTP chunked body + Niepoprawne ciało HTTP + + + Error writing response to device + Błąd zapisywania odpowiedzi do urządzenia + + + Proxy authentication required + Wymagana autoryzacja pośrednika + + + Authentication required + Wymagana autoryzacja + + + Proxy requires authentication + Pośrednik wymaga autoryzacji + + + Host requires authentication + Host wymaga autoryzacji + + + Data corrupted + Dane uszkodzone + + + SSL handshake failed + Nawiązanie sesji SSL nie powiodło się + + + Unknown protocol specified + Podano nieznany protokół + + + Connection refused (or timed out) + Połączenie odrzucone (przekroczony czas połączenia) + + + HTTPS connection requested but SSL support not compiled in + Zażądano połączenia HTTPS lecz obsługa SSL nie jest wkompilowana + + + + QHttpSocketEngine + + Did not receive HTTP response from proxy + Nie odebrano odpowiedzi HTTP od pośrednika + + + Error parsing authentication request from proxy + Błąd parsowania żądania autoryzacji od pośrednika + + + Authentication required + Wymagana autoryzacja + + + Proxy denied connection + Pośrednik odmówił połączenia + + + Error communicating with HTTP proxy + Błąd podczas komunikacji z pośrednikiem HTTP + + + Proxy server not found + Nie znaleziono serwera pośredniczącego + + + Proxy connection refused + Odmowa połączenia z pośrednikiem + + + Proxy server connection timed out + Przekroczony czas połączenia do serwera pośredniczącego + + + Proxy connection closed prematurely + Przedwczesne zakończenie połączenia z pośrednikiem + + + + QIBaseDriver + + Error opening database + Błąd otwierania bazy danych + + + Could not start transaction + Nie można rozpocząć transakcji + + + Unable to commit transaction + Nie można dokonać transakcji + + + Unable to rollback transaction + Nie można wycofać transakcji + + + + QIBaseResult + + Unable to create BLOB + Nie można utworzyć obiektu typu BLOB + + + Unable to write BLOB + Nie można zapisać obiektu typu BLOB + + + Unable to open BLOB + Nie można otworzyć obiektu typu BLOB + + + Unable to read BLOB + Nie można odczytać obiektu typu BLOB + + + Could not find array + Nie można odnaleźć tablicy + + + Could not get array data + Nie można pobrać danych z tablicy + + + Could not get query info + Nie można pobrać informacji o zapytaniu + + + Could not start transaction + Nie można rozpocząć transakcji + + + Unable to commit transaction + Nie można dokonać transakcji + + + Could not allocate statement + Nie można zaallokować polecenia + + + Could not prepare statement + Nie można przygotować polecenia + + + Could not describe input statement + Nie można opisać polecenia wejściowego + + + Could not describe statement + Nie można opisać polecenia + + + Unable to close statement + Nie można zamknąć polecenia + + + Unable to execute query + Nie można wykonać zapytania + + + Could not fetch next item + Nie można pobrać kolejnego elementu + + + Could not get statement info + Nie można pobrać informacji o poleceniu + + + + QIODevice + + Permission denied + Brak dostępu + + + Too many open files + Zbyt wiele otwartych plików + + + No such file or directory + Brak pliku lub katalogu + + + No space left on device + Brak wolnego miejsca na urządzeniu + + + Unknown error + Nieznany błąd + + + + QInputContext + + XIM + XIM + + + FEP + FEP + + + XIM input method + Metoda wprowadzania XIM + + + Windows input method + Metoda wprowadzania Windows + + + Mac OS X input method + Metoda wprowadzania Mac OS X + + + S60 FEP input method + Metoda wprowadzania S60 FEP + + + + QInputDialog + + Enter a value: + Podaj wartość: + + + + QLibrary + + Could not mmap '%1': %2 + Nie można wykonać przypisania '%1': %2 + + + Plugin verification data mismatch in '%1' + Błąd podczas weryfikacji danych we wtyczce '%1' + + + Could not unmap '%1': %2 + Nie można usunąć przypisania '%1': %2 + + + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] + Wtyczka '%1' używa niepoprawnej wersji biblioteki QT. (%2.%3.%4) [%5] + + + The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" + Wtyczka '%1' używa niepoprawnej wersji biblioteki QT. Oczekiwano klucza "%2", uzyskano "%3" + + + Unknown error + Nieznany błąd + + + The shared library was not found. + Biblioteka współdzielona niedostępna. + + + The file '%1' is not a valid Qt plugin. + Plik "%1" nie jest poprawną wtyczką Qt. + + + The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) + Wtyczka "%1" używa innej wersji biblioteki Qt. (Nie można łączyć bibliotek zwykłych i debugowych.) + + + Cannot load library %1: %2 + Nie można załadować biblioteki %1: %2 + + + Cannot unload library %1: %2 + Nie można zwolnić biblioteki %1: %2 + + + Cannot resolve symbol "%1" in %2: %3 + Nie można zidentyfikować symbolu "%1" w %2: %3 + + + + QLineEdit + + Select All + Zaznacz wszystko + + + &Undo + &Cofnij + + + &Redo + &Przywróć + + + Cu&t + W&ytnij + + + &Copy + S&kopiuj + + + &Paste + &Wklej + + + Delete + Skasuj + + + + QLocalServer + + %1: Name error + %1: Błąd nazwy + + + %1: Permission denied + %1: Brak dostępu + + + %1: Address in use + %1: Adres użyty + + + %1: Unknown error %2 + %1: Nieznany błąd %2 + + + + QLocalSocket + + %1: Connection refused + %1: Odmowa połączenia + + + %1: Remote closed + %1: Drugi koniec odłączony + + + %1: Invalid name + %1: Niepoprawna nazwa + + + %1: Socket access error + %1: Błąd dostępu do gniazda + + + %1: Socket resource error + %1: Błąd zasobów gniazda + + + %1: Socket operation timed out + %1: Przekroczony czas operacji gniazda + + + %1: Datagram too large + %1: Za duży datagram + + + %1: Connection error + %1: Błąd połączenia + + + %1: The socket operation is not supported + %1: Operacja nie jest obsługiwana przez gniazdo + + + %1: Unknown error + %1: Nieznany błąd + + + %1: Unknown error %2 + %1: Nieznany błąd %2 + + + + QMYSQLDriver + + Unable to open database ' + Nie można otworzyć bazy danych ' + + + Unable to connect + Nie można nawiązać połączenia + + + Unable to begin transaction + Nie można rozpocząć transakcji + + + Unable to commit transaction + Nie można potwierdzić transakcji + + + Unable to rollback transaction + Nie można wycofać transakcji + + + + QMYSQLResult + + Unable to fetch data + Nie można pobrać danych + + + Unable to execute query + Nie można wykonać zapytania + + + Unable to store result + Nie można zachować wyników + + + Unable to prepare statement + Nie można przygotować polecenia + + + Unable to reset statement + Nie można skasować polecenia + + + Unable to bind value + Nie można powiązać wartości + + + Unable to execute statement + Nie można wykonać polecenia + + + Unable to bind outvalues + Nie można powiązać wartości zewnętrznych + + + Unable to store statement results + Nie można zachować wyników polecenia + + + Unable to execute next query + Nie można wykonać następnego zapytania + + + Unable to store next result + Nie można zachować następnego wyniku + + + + QMdiArea + + (Untitled) + (Nienazwany) + + + + QMdiSubWindow + + %1 - [%2] + %1 - [%2] + + + Close + Zamknij + + + Minimize + Zminimalizuj + + + Restore Down + Przywróć pod spód + + + &Restore + &Przywróć + + + &Move + Prze&nieś + + + &Size + &Rozmiar + + + Mi&nimize + Zmi&nimalizuj + + + Ma&ximize + Zma&ksymalizuj + + + Stay on &Top + Pozostaw na &wierzchu + + + &Close + &Zamknij + + + Maximize + Zmaksymalizuj + + + Unshade + Rozwiń + + + Shade + Zwiń + + + Restore + Przywróć + + + Help + Pomoc + + + Menu + Menu + + + - [%1] + - [%1] + + + + QMenu + + Close + Zamknij + + + Open + Otwórz + + + Execute + Wykonaj + + + + QMenuBar + + Actions + Akcje + + + + QMessageBox + + OK + OK + + + <h3>About Qt</h3><p>This program uses Qt version %1.</p> + <h3>Informacje o Qt</h3><p> Ten program używa Qt w wersji %1.</p> + + + <p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p><p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://qt.nokia.com/">qt.nokia.com</a> for more information.</p> + <p>Qt jest zestawem narzędzi programistycznych dedykowanym dla języka C++. Służy on do opracowywania aplikacji międzyplatformowych.</p><p>Qt umożliwia jednoźródłowe przenoszenie między systemami MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux i wszystkimi głównymi wersjami komercyjnymi systemu Unix. Środowisko Qt jest dostępne dla urządzeń wbudowanych opartych na systemie Linux ( Qt dla wbudowanego systemu Linux) oraz Windows CE.</p><p>Zestaw Qt jest dostępny w trzech różnych opcjach licencjonowania stworzonych w celu zadowolenia naszych różnych użytkowników.</p><p>Qt podlegający licencji zgodnie z naszą komercyjną umową licencyjną jest odpowiedni do opracowywania oprogramowań własnościowych/komercyjnych, dzięki czemu kod źródłowy nie jest udostępniany osobom trzecim. W przeciwnym razie zestaw Qt jest niezgodny z warunkami licencji GNU LGPL w wersji 2.1 lub GNU GPL w wersji 3.0.</p><p>Środowisko Qt objęte licencją GNU LGPL w wersji 2.1 nadaje się do tworzenia aplikacji Qt (własnościowych lub oprogramowań otwartych) tylko wtedy, gdy przestrzegane są warunki licencji GNU LGPL w wersji 2.1.</p><p>Qt objęty Powszechną Licencją Publiczną GNU w wersji 3.0 jest odpowiedni do opracowywania aplikacji QT, aby móc korzystać z aplikacji w połączeniu z oprogramowaniem podlegającym warunkom licencji GNU GPL w wersji 3.0 lub aby przestrzegać warunków licencji GNU GPL w wersji 3.0.</p><p>Więcej informacji na temat licencji Qt można znaleźć na stronie <a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a>.</p><p>Copyright (C) 2010 Nokia Corporation i/lub oddziały firmy.</p><p>Qt jest produktem firmy Nokia. Dodatkowe informacje znajdują się na stronie <a href="http://qt.nokia.com/">qt.nokia.com</a> </p> + + + About Qt + Informacje o Qt + + + Help + Pomoc + + + Show Details... + Pokaż szczegóły... + + + Hide Details... + Ukryj szczegóły... + + + + QMultiInputContext + + Select IM + Wybierz metodę wprowadzania + + + + QMultiInputContextPlugin + + Multiple input method switcher + Przełącznik metody wprowadzania + + + Multiple input method switcher that uses the context menu of the text widgets + Przełącznik metody wprowadzania, który w widżetach tekstowych używa podręcznego menu + + + + QNativeSocketEngine + + The remote host closed the connection + Zdalny host zakończył połączenie + + + Network operation timed out + Przekroczony czas operacji sieciowej + + + Out of resources + Zasoby wyczerpane + + + Unsupported socket operation + Nieobsługiwana operacja gniazda + + + Protocol type not supported + Nieobsługiwany typ protokołu + + + Invalid socket descriptor + Niepoprawny opis gniazda + + + Network unreachable + Sieć niedostępna + + + Permission denied + Brak dostępu + + + Connection timed out + Przekroczony czas połączenia + + + Connection refused + Połączenie odrzucone + + + The bound address is already in use + Adres jest aktualnie w użyciu + + + The address is not available + Adres nie jest dostępny + + + The address is protected + Adres jest zabezpieczony + + + Unable to send a message + Nie można wysłać wiadomości + + + Unable to receive a message + Nie można odebrać wiadomości + + + Unable to write + Nie można zapisać + + + Network error + Błąd sieci + + + Another socket is already listening on the same port + Inne gniazdo nasłuchuje już na tym porcie + + + Unable to initialize non-blocking socket + Nie można uruchomić gniazda w nieblokującym trybie + + + Unable to initialize broadcast socket + Nie można uruchomić gniazda rozsyłającego + + + Attempt to use IPv6 socket on a platform with no IPv6 support + Próba użycia IPv6 na platformie bez obsługi IPv6 + + + Host unreachable + Komputer niedostępny + + + Datagram was too large to send + Datagram za długi do wysłania + + + Operation on non-socket + Nieprawidłowa operacja na gnieździe + + + Unknown error + Nieznany błąd + + + The proxy type is invalid for this operation + Typ pośrednika nie jest poprawny dla tej operacji + + + + QNetworkAccessCacheBackend + + Error opening %1 + Błąd otwierania %1 + + + + QNetworkAccessDebugPipeBackend + + Write error writing to %1: %2 + Błąd w trakcie zapisywania do %1: %2 + + + + QNetworkAccessFileBackend + + Request for opening non-local file %1 + Żądanie otwarcia zdalnego pliku %1 + + + Error opening %1: %2 + Błąd otwierania %1: %2 + + + Write error writing to %1: %2 + Błąd w trakcie zapisywania do %1: %2 + + + Cannot open %1: Path is a directory + Nie można otworzyć %1: Ścieżka jest katalogiem + + + Read error reading from %1: %2 + Błąd w trakcie czytania z %1: %2 + + + + QNetworkAccessFtpBackend + + No suitable proxy found + Nie odnaleziono odpowiedniego pośrednika + + + Cannot open %1: is a directory + Nie można otworzyć %1: jest to katalog + + + Logging in to %1 failed: authentication required + Błąd podczas logowania do %1: wymagana autoryzacja + + + Error while downloading %1: %2 + Błąd podczas pobierania %1: %2 + + + Error while uploading %1: %2 + Błąd podczas wysyłania %1: %2 + + + + QNetworkAccessHttpBackend + + No suitable proxy found + Nie odnaleziono odpowiedniego pośrednika + + + + QNetworkReply + + Error downloading %1 - server replied: %2 + Błąd podczas pobierania %1 - odpowiedź serwera: %2 + + + Protocol "%1" is unknown + Protokół "%1" nie jest znany + + + + QNetworkReplyImpl + + Operation canceled + Operacja anulowana + + + + QOCIDriver + + Unable to logon + Nie można się zalogować + + + Unable to initialize + QOCIDriver + Nie można dokonać inicjalizacji + + + Unable to begin transaction + Nie można rozpocząć transakcji + + + Unable to commit transaction + Nie można dokonać transakcji + + + Unable to rollback transaction + Nie można wycofać transakcji + + + + QOCIResult + + Unable to bind column for batch execute + Nie można powiązać kolumny dla wykonania zestawu poleceń + + + Unable to execute batch statement + Nie można wykonać polecenia wsadowego + + + Unable to goto next + Nie można przejść do kolejnego wiersza danych + + + Unable to alloc statement + Nie można przydzielić miejsca na polecenie + + + Unable to prepare statement + Nie można przygotować polecenia + + + Unable to get statement type + Nie można pobrać typu polecenia + + + Unable to bind value + Nie można powiązać wartości + + + Unable to execute statement + Nie można wykonać polecenia + + + + QODBCDriver + + Unable to connect + Nie można nawiązać połączenia + + + Unable to disable autocommit + Nie można wyłączyć trybu automatycznego dokonywania transakcji + + + Unable to commit transaction + Nie można potwierdzić transakcji + + + Unable to rollback transaction + Nie można wycofać transakcji + + + Unable to enable autocommit + Nie można włączyć trybu automatycznego dokonywania transakcji + + + Unable to connect - Driver doesn't support all functionality required + Nie można nawiązać połączenia - sterownik nie obsługuje całej potrzebnej funkcjonalności + + + + QODBCResult + + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration + QODBCResult::reset: Nie można ustawić 'SQL_CURSOR_STATIC' jako atrybutu polecenia. Proszę sprawdzić konfiguracje sterownika ODBC + + + Unable to execute statement + Nie można wykonać polecenia + + + Unable to fetch next + Nie można pobrać kolejnych danych + + + Unable to prepare statement + Nie można przygotować polecenia + + + Unable to bind variable + Nie można powiązać zmiennej + + + Unable to fetch last + Nie można pobrać ostatnich danych + + + Unable to fetch + Nie można pobrać + + + Unable to fetch first + Nie można pobrać pierwszych danych + + + Unable to fetch previous + Nie można pobrać poprzednich danych + + + + QObject + + Invalid hostname + Niepoprawna nazwa hosta + + + Operation not supported on %1 + Operacja nieobsługiwana na %1 + + + Invalid URI: %1 + Niepoprawny URI: %1 + + + Socket error on %1: %2 + Błąd gniazda na %1: %2 + + + Remote host closed the connection prematurely on %1 + Zdalny host przedwcześnie zakończył połączenie na %1 + + + No host name given + Nie podano nazwy hosta + + + + QPPDOptionsModel + + Name + Nazwa + + + Value + Wartość + + + + QPSQLDriver + + Unable to connect + Nie można nawiązać połączenia + + + Could not begin transaction + Nie można rozpocząć transakcji + + + Could not commit transaction + Nie można potwierdzić transakcji + + + Could not rollback transaction + Nie można wycofać transakcji + + + Unable to subscribe + Nie można wykonać subskrypcji + + + Unable to unsubscribe + Nie można zrezygnować z subskrypcji + + + + QPSQLResult + + Unable to create query + Nie można utworzyć zapytania + + + Unable to prepare statement + Nie można przygotować polecenia + + + + QPageSetupWidget + + Centimeters (cm) + Centymetry (cm) + + + Millimeters (mm) + Milimetry (mm) + + + Inches (in) + Cale (in) + + + Points (pt) + Punkty (pt) + + + Form + Formularz + + + Paper + Papier + + + Page size: + Rozmiar strony: + + + Width: + Szerokość: + + + Height: + Wysokość: + + + Paper source: + Źródło papieru: + + + Orientation + Położenie + + + Portrait + Portret + + + Landscape + Pejzaż + + + Reverse landscape + Odwrócony pejzaż + + + Reverse portrait + Odwrócony portret + + + Margins + Marginesy + + + top margin + Górny margines + + + left margin + Lewy margines + + + right margin + Prawy margines + + + bottom margin + Dolny margines + + + + QPluginLoader + + Unknown error + Nieznany błąd + + + The plugin was not loaded. + Wtyczka nie została załadowana. + + + + QPrintDialog + + locally connected + podłączony lokalnie + + + Aliases: %1 + Aliasy: %1 + + + unknown + nieznany + + + OK + OK + + + Print all + Drukuj wszystko + + + Print range + Drukuj zakres + + + A0 (841 x 1189 mm) + A0 (841 x 1189 mm) + + + A1 (594 x 841 mm) + A1 (594 x 841 mm) + + + A2 (420 x 594 mm) + A2 (420 x 594 mm) + + + A3 (297 x 420 mm) + A3 (297 x 420 mm) + + + A5 (148 x 210 mm) + A5 (148 x 210 mm) + + + A6 (105 x 148 mm) + A6 (105 x 148 mm) + + + A7 (74 x 105 mm) + A7 (74 x 105 mm) + + + A8 (52 x 74 mm) + A8 (52 x 74 mm) + + + A9 (37 x 52 mm) + A9 (37 x 52 mm) + + + B0 (1000 x 1414 mm) + B0 (1000 x 1414 mm) + + + B1 (707 x 1000 mm) + B1 (707 x 1000 mm) + + + B2 (500 x 707 mm) + B2 (500 x 707 mm) + + + B3 (353 x 500 mm) + B3 (353 x 500 mm) + + + B4 (250 x 353 mm) + B4 (250 x 353 mm) + + + B6 (125 x 176 mm) + B6 (125 x 176 mm) + + + B7 (88 x 125 mm) + B7 (88 x 125 mm) + + + B8 (62 x 88 mm) + B8 (62 x 88 mm) + + + B9 (44 x 62 mm) + B9 (44 x 62 mm) + + + B10 (31 x 44 mm) + B10 (31 x 44 mm) + + + C5E (163 x 229 mm) + C5E (163 x 229 mm) + + + DLE (110 x 220 mm) + DLE (110 x 220 mm) + + + Folio (210 x 330 mm) + Folio (210 x 330 mm) + + + Ledger (432 x 279 mm) + Ledger (432 x 279 mm) + + + Tabloid (279 x 432 mm) + Tabloid (279 x 432 mm) + + + US Common #10 Envelope (105 x 241 mm) + US Common #10 Envelope (105 x 241 mm) + + + A4 (210 x 297 mm, 8.26 x 11.7 inches) + A4 (210 x 297 mm, 8.26 x 11.7 cali) + + + B5 (176 x 250 mm, 6.93 x 9.84 inches) + B5 (176 x 250 mm, 6.93 x 9.84 cali) + + + Executive (7.5 x 10 inches, 191 x 254 mm) + Executive (7.5 x 10 cali, 191 x 254 mm) + + + Legal (8.5 x 14 inches, 216 x 356 mm) + Legal (8.5 x 14 cali, 216 x 356 mm) + + + Letter (8.5 x 11 inches, 216 x 279 mm) + Letter (8.5 x 11 cali, 216 x 279 mm) + + + Print selection + Drukuj zaznaczone + + + Print + Drukowanie + + + Print To File ... + Drukuj do pliku ... + + + File %1 is not writable. +Please choose a different file name. + Plik %1 jest plikiem tylko do odczytu. +Proszę wybrać inną nazwę pliku. + + + %1 already exists. +Do you want to overwrite it? + %1 już istnieje. +Czy chcesz nadpisać? + + + File exists + Plik istnieje + + + <qt>Do you want to overwrite it?</qt> + <qt>Czy chcesz nadpisać?</qt> + + + %1 is a directory. +Please choose a different file name. + %1 jest katalogiem. +Proszę wybrać inną nazwę pliku. + + + The 'From' value cannot be greater than the 'To' value. + Wartość "od" nie może być większa od wartości "do". + + + A0 + A0 + + + A1 + A1 + + + A2 + A2 + + + A3 + A3 + + + A4 + A4 + + + A5 + A5 + + + A6 + A6 + + + A7 + A7 + + + A8 + A8 + + + A9 + A9 + + + B0 + B0 + + + B1 + B1 + + + B2 + B2 + + + B3 + B3 + + + B4 + B4 + + + B5 + B5 + + + B6 + B6 + + + B7 + B7 + + + B8 + B8 + + + B9 + B9 + + + B10 + B10 + + + C5E + C5E + + + DLE + DLE + + + Executive + Executive + + + Folio + Folio + + + Ledger + Ledger + + + Legal + Legal + + + Letter + Letter + + + Tabloid + Tabloid + + + US Common #10 Envelope + US Common #10 Envelope + + + Custom + Niestandardowy + + + &Options >> + &Opcje >> + + + &Options << + &Opcje << + + + Print to File (PDF) + Drukuj do pliku (PDF) + + + Print to File (Postscript) + Drukuj do pliku (Postscript) + + + Local file + Plik lokalny + + + Write %1 file + Zapisz %1 plik + + + &Print + Wy&drukuj + + + + QPrintPreviewDialog + + %1% + %1% + + + Print Preview + Podgląd wydruku + + + Next page + Następna strona + + + Previous page + Poprzednia strona + + + First page + Pierwsza strona + + + Last page + Ostatnia strona + + + Fit width + Dopasuj szerokość + + + Fit page + Dopasuj stronę + + + Zoom in + Powiększ + + + Zoom out + Pomniejsz + + + Portrait + Portret + + + Landscape + Pejzaż + + + Show single page + Pokaż pojedynczą stronę + + + Show facing pages + Pokaż sąsiednie strony + + + Show overview of all pages + Pokaż wszystkie strony + + + Print + Wydrukuj + + + Page setup + Ustawienia strony + + + Close + + + + Export to PDF + Wyeksportuj do PDF + + + Export to PostScript + Wyeksportuj do PostScript + + + Page Setup + Ustawienia strony + + + + QPrintPropertiesWidget + + Form + Forma + + + Page + Strona + + + Advanced + Zaawansowane + + + + QPrintSettingsOutput + + Form + Forma + + + Copies + Liczba kopii + + + Print range + Zakres wydruku + + + Print all + Drukuj wszystko + + + Pages from + Strony od + + + to + do + + + Selection + Wybrane strony + + + Output Settings + Ustawienia wyjściowe + + + Copies: + Kopie: + + + Collate + Parami + + + Reverse + Odwróć + + + Options + Opcje + + + Color Mode + Tryb koloru + + + Color + Kolor + + + Grayscale + Skala szarości + + + Duplex Printing + Drukowanie dupleksowe + + + None + Brak + + + Long side + Długa strona + + + Short side + Krótka strona + + + + QPrintWidget + + Form + Forma + + + Printer + Drukarka + + + &Name: + &Nazwa: + + + P&roperties + &Właściwości + + + Location: + Położenie: + + + Preview + Podgląd + + + Type: + Typ: + + + Output &file: + &Plik wyjściowy: + + + ... + ... + + + + QProcess + + Could not open input redirection for reading + Nie można otworzyć wejściowego przekierowania do odczytu + + + Could not open output redirection for writing + Nie można otworzyć wyjściowego przekierowania do zapisu + + + Resource error (fork failure): %1 + Błąd zasobów (błąd forkowania): %1 + + + Process operation timed out + Przekroczony czas operacji procesu + + + Error reading from process + Błąd odczytywania z procesu + + + Error writing to process + Błąd zapisywania do procesu + + + Process crashed + Wystąpił błąd w procesie - proces zakończony + + + No program defined + Nie zdefiniowano programu + + + Process failed to start: %1 + Nie można rozpocząć procesu: %1 + + + + QProgressDialog + + Cancel + Anuluj + + + + QPushButton + + Open + Otwórz + + + + QRadioButton + + Check + Zaznacz + + + + QRegExp + + no error occurred + nie pojawił się żaden błąd + + + disabled feature used + użyta funkcja została wyłączona + + + bad char class syntax + niepoprawna składnia klasy znakowej + + + bad lookahead syntax + niepoprawna składnia "lookahead" + + + bad repetition syntax + niepoprawna składnia powtórzenia + + + invalid octal value + niepoprawna wartość ósemkowa + + + missing left delim + brakujący lewy separator + + + unexpected end + nieoczekiwany koniec + + + met internal limit + napotkano wewnętrzne ograniczenie + + + invalid interval + Niepoprawny interwał + + + invalid category + Niepoprawna kategoria + + + + QSQLite2Driver + + Error opening database + Błąd otwierania bazy danych + + + Unable to begin transaction + Nie można rozpocząć transakcji + + + Unable to commit transaction + Nie można dokonać transakcji + + + Unable to rollback transaction + Nie można wycofać transakcji + + + + QSQLite2Result + + Unable to fetch results + Nie można pobrać wyników + + + Unable to execute statement + Nie można wykonać polecenia + + + + QSQLiteDriver + + Error opening database + Błąd otwierania bazy danych + + + Error closing database + Błąd zamykania bazy danych + + + Unable to begin transaction + Nie można rozpocząć transakcji + + + Unable to commit transaction + Nie można dokonać transakcji + + + Unable to rollback transaction + Nie można wycofać transakcji + + + + QSQLiteResult + + Unable to fetch row + Nie można pobrać wiersza danych + + + Unable to execute statement + Nie można wykonać polecenia + + + Unable to reset statement + Nie można skasować polecenia + + + Unable to bind parameters + Nie można powiązać parametrów + + + Parameter count mismatch + Niezgodna liczba parametrów + + + No query + Brak zapytania + + + + QScriptBreakpointsModel + + ID + Identyfikator + + + Location + Położenie + + + Condition + Warunek + + + Ignore-count + Licznik pominięć + + + Single-shot + ## + + + Hit-count + Licznik trafień + + + + QScriptBreakpointsWidget + + New + Nowy + + + Delete + Skasuj + + + + QScriptDebugger + + Go to Line + Przejdź do linii + + + Line: + Linia: + + + Interrupt + Przerwij + + + Shift+F5 + Shift+F5 + + + Continue + Kontynuuj + + + F5 + F5 + + + Step Into + Wskocz do wnętrza + + + F11 + F11 + + + Step Over + Przeskocz + + + F10 + F10 + + + Step Out + Wyskocz na zewnątrz + + + Shift+F11 + Shift+F11 + + + Run to Cursor + Uruchom do kursora + + + Ctrl+F10 + Ctrl+F10 + + + Run to New Script + Uruchom do nowego skryptu + + + Toggle Breakpoint + Przełącz ustawienie pułapki + + + F9 + F9 + + + Clear Debug Output + Wyczyść wyjście debuggera + + + Clear Error Log + Wyczyść log z błędami + + + Clear Console + Wyczyść konsolę + + + &Find in Script... + &Znajdź w skrypcie... + + + Ctrl+F + Ctrl+F + + + Find &Next + Znajdź &następne + + + F3 + F3 + + + Find &Previous + Znajdź &poprzednie + + + Shift+F3 + Shift+F3 + + + Ctrl+G + Ctrl+G + + + Debug + Debuguj + + + + QScriptDebuggerCodeFinderWidget + + Close + Zamknij + + + Previous + Poprzednie + + + Next + Następne + + + Case Sensitive + Uwzględniaj wielkość liter + + + Whole words + Całe słowa + + + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;Search wrapped + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;Przeszukano od początku + + + + QScriptDebuggerLocalsModel + + Name + Nazwa + + + Value + Wartość + + + + QScriptDebuggerStackModel + + Level + Poziom + + + Name + Nazwa + + + Location + Położenie + + + + QScriptEdit + + Toggle Breakpoint + Przełącz ustawienie pułapki + + + Disable Breakpoint + Wyłącz pułapkę + + + Enable Breakpoint + Włącz pułapkę + + + Breakpoint Condition: + Warunek dla pułapki: + + + + QScriptEngineDebugger + + Loaded Scripts + Załadowane skrypty + + + Breakpoints + Pułapki + + + Stack + Stos + + + Locals + Zmienne lokalne + + + Console + Konsola + + + Debug Output + Wyjście debuggera + + + Error Log + Log z błędami + + + Search + Szukaj + + + View + Widok + + + Qt Script Debugger + Debugger Qt Script + + + + QScriptNewBreakpointWidget + + Close + Zamknij + + + + QScrollBar + + Scroll here + Przewiń tutaj + + + Left edge + Lewa krawędź + + + Top + Do góry + + + Right edge + Prawa krawędź + + + Bottom + W dół + + + Page left + Strona w lewo + + + Page up + Strona do góry + + + Page right + Strona w prawo + + + Page down + Strona w dół + + + Scroll left + Przewiń w lewo + + + Scroll up + Przewiń do góry + + + Scroll right + Przewiń w prawo + + + Scroll down + Przewiń w dół + + + Line up + Linia w górę + + + Position + Pozycja + + + Line down + Linia w dół + + + + QSharedMemory + + %1: create size is less then 0 + %1: rozmiar przy tworzeniu mniejszy od 0 + + + %1: unable to lock + %1: nie można zablokować + + + %1: unable to unlock + %1: nie można odblokować + + + %1: permission denied + %1: brak dostępu + + + %1: already exists + %1: już istnieje + + + %1: doesn't exists + %1: nie istnieje + + + %1: out of resources + %1: zasoby wyczerpane + + + %1: unknown error %2 + %1: nieznany błąd %2 + + + %1: key is empty + %1: klucz jest pusty + + + %1: ftok failed + %1: wystąpił błąd w funkcji ftok() + + + %1: unable to make key + %1: nie można utworzyć klucza + + + %1: doesn't exist + %1: nie istnieje + + + %1: UNIX key file doesn't exist + %1: unixowy plik z kluczem nie istnieje + + + %1: system-imposed size restrictions + %1: ograniczenia rozmiarów narzucone przez system + + + %1: not attached + %1: niedołączony + + + %1: invalid size + %1: niepoprawny rozmiar + + + %1: key error + %1: błąd klucza + + + %1: size query failed + %1: zapytanie o rozmiar nie powiodło się + + + %1: unable to set key on lock + %1: nie można ustawić klucza na zablokowanym segmencie pamięci współdzielonej + + + + QShortcut + + Space + Spacja + + + Esc + Esc + + + Tab + Tabulator + + + Backtab + Backtab + + + Backspace + Backspace + + + Return + Powrót + + + Enter + Enter + + + Ins + Ins + + + Del + Del + + + Pause + Pauza + + + Print + Wydrukuj + + + SysReq + SysReq + + + Home + Home + + + End + End + + + Left + Lewo + + + Up + Góra + + + Right + Prawo + + + Down + Dół + + + PgUp + PgUp + + + PgDown + PgDown + + + CapsLock + CapsLock + + + NumLock + NumLock + + + ScrollLock + ScrollLock + + + Menu + Menu + + + Help + Pomoc + + + Back + Back + + + Forward + Do przodu + + + Stop + Zatrzymaj + + + Refresh + Odśwież + + + Volume Down + Przycisz + + + Volume Mute + Wycisz + + + Volume Up + Zrób głośniej + + + Bass Boost + Wzmocnienie basów + + + Bass Up + Basy w górę + + + Bass Down + Basy w dół + + + Treble Up + Soprany w górę + + + Treble Down + Soprany w dół + + + Media Play + Odtwarzaj + + + Media Stop + Zatrzymaj + + + Media Previous + Poprzednia ścieżka + + + Media Next + Następna ścieżka + + + Media Record + Nagrywaj + + + Favorites + Ulubione + + + Search + Szukaj + + + Standby + Tryb oczekiwania + + + Open URL + Otwórz adres + + + Launch Mail + Uruchom program pocztowy + + + Launch Media + Uruchom przeglądarkę mediów + + + Launch (0) + Uruchom (0) + + + Launch (1) + Uruchom (1) + + + Launch (2) + Uruchom (2) + + + Launch (3) + Uruchom (3) + + + Launch (4) + Uruchom (4) + + + Launch (5) + Uruchom (5) + + + Launch (6) + Uruchom (6) + + + Launch (7) + Uruchom (7) + + + Launch (8) + Uruchom (8) + + + Launch (9) + Uruchom (9) + + + Launch (A) + Uruchom (A) + + + Launch (B) + Uruchom (B) + + + Launch (C) + Uruchom (C) + + + Launch (D) + Uruchom (D) + + + Launch (E) + Uruchom (E) + + + Launch (F) + Uruchom (F) + + + Monitor Brightness Up + Zwiększ jasność monitora + + + Monitor Brightness Down + Zmniejsz jasność monitora + + + Keyboard Light On/Off + Włącz/wyłącz podświetlenie klawiatury + + + Keyboard Brightness Up + Zwiększ jasność klawiatury + + + Keyboard Brightness Down + Zmniejsz jasność klawiatury + + + Power Off + Wyłączenie zasilania + + + Wake Up + ## + + + Eject + Wysuń + + + Screensaver + Wygaszacz ekranu + + + WWW + WWW + + + Sleep + ## + + + LightBulb + Żarówka + + + Shop + Sklep + + + History + Historia + + + Add Favorite + Dodaj do ulubionych + + + Hot Links + Popularne łącza + + + Adjust Brightness + Ustaw jasność + + + Finance + Finanse + + + Community + Społeczność + + + Audio Rewind + Przewijanie do tyłu + + + Back Forward + ## + + + Application Left + ## + + + Application Right + ## + + + Book + Książka + + + CD + CD + + + Calculator + Kalkulator + + + Clear + Wyczyść + + + Clear Grab + ## + + + Close + Zamknij + + + Copy + Skopiuj + + + Cut + Wytnij + + + Display + Wyświetlacz + + + DOS + DOS + + + Documents + Dokumenty + + + Spreadsheet + Arkusz kalkulacyjny + + + Browser + Przeglądarka + + + Game + Gra + + + Go + Przejdź + + + iTouch + iTouch + + + Logoff + Wyloguj + + + Market + Rynek + + + Meeting + Spotkanie + + + Keyboard Menu + Menu klawiatury + + + Menu PB + Menu PG + + + My Sites + Moje strony + + + News + Wiadomości + + + Home Office + ## + + + Option + Opcje + + + Paste + Wklej + + + Phone + Telefon + + + Reply + Odpowiedz + + + Reload + Przeładuj + + + Rotate Windows + Obróć okna + + + Rotation PB + Obrót PB + + + Rotation KB + Obrót KB + + + Save + Zachowaj + + + Send + Wyślij + + + Spellchecker + Funkcja sprawdzania pisowni + + + Split Screen + Podziel ekran + + + Support + Pomoc techniczna + + + Task Panel + Panel zadań + + + Terminal + Terminal + + + Tools + Narzędzia + + + Travel + Podróże + + + Video + Wideo + + + Word Processor + Edytor tekstów + + + XFer + XFer + + + Zoom In + Powiększ + + + Zoom Out + Pomniejsz + + + Away + ## + + + Messenger + Messenger + + + WebCam + WebCam + + + Mail Forward + Przesyłanie wiadomości + + + Pictures + Zdjęcia + + + Music + Muzyka + + + Battery + Bateria + + + Bluetooth + Bluetooth + + + Wireless + Bezprzewodowy + + + Ultra Wide Band + Ultraszerokie pasmo + + + Audio Forward + Przewijanie do przodu + + + Audio Repeat + Powtarzanie + + + Audio Random Play + Odtwarzanie losowe + + + Subtitle + Napisy + + + Audio Cycle Track + ## + + + Time + Czas + + + View + Widok + + + Top Menu + Menu główne + + + Suspend + Wstrzymaj + + + Hibernate + Hibernuj + + + Print Screen + Wydrukuj zawartość ekranu + + + Page Up + Strona w dół + + + Page Down + Strona do góry + + + Caps Lock + Caps Lock + + + Num Lock + Num Lock + + + Number Lock + Number Lock + + + Scroll Lock + Scroll Lock + + + Insert + Insert + + + Delete + Delete + + + Escape + Escape + + + System Request + Żądanie systemu + + + Select + Wybierz + + + Yes + Tak + + + No + Nie + + + Context1 + Kontekst1 + + + Context2 + Kontekst2 + + + Context3 + Kontekst3 + + + Context4 + Kontekst4 + + + Call + Wywołaj + + + Hangup + Zawieś + + + Flip + Odwróć + + + Ctrl + Ctrl + + + Shift + Shift + + + Alt + Alt + + + Meta + Meta + + + + + + + + + F%1 + F%1 + + + Home Page + Strona startowa + + + + QSlider + + Page left + Strona w lewo + + + Page up + Strona do góry + + + Position + Położenie + + + Page right + Strona w prawo + + + Page down + Strona w dół + + + + QSocks5SocketEngine + + Connection to proxy refused + Odmowa połączenia z pośrednikiem + + + Connection to proxy closed prematurely + Przedwczesne zakończenie połączenia z pośrednikiem + + + Proxy host not found + Nie odnaleziono hosta pośredniczącego + + + Connection to proxy timed out + Przekroczony czas połączenia do pośrednika + + + Proxy authentication failed + Autoryzacja pośrednika zakończona błędem + + + Proxy authentication failed: %1 + Autoryzacja pośrednika zakończona błędem: %1 + + + SOCKS version 5 protocol error + Błąd protokołu SOCKS wersji 5 + + + General SOCKSv5 server failure + Generalny błąd serwera SOCKS wersji 5 + + + Connection not allowed by SOCKSv5 server + Połączenie niedozwolone przez serwer SOCKS wersji 5 + + + TTL expired + TTL stracił ważność + + + SOCKSv5 command not supported + Nieobsługiwana komenda SOCKS wersji 5 + + + Address type not supported + Nieobsługiwany typ adresu + + + Unknown SOCKSv5 proxy error code 0x%1 + Nieznany kod błędu (0x%1) pośrednika SOCKS wersji 5 + + + Network operation timed out + Przekroczony czas operacji sieciowej + + + + QSoftKeyManager + + Ok + OK + + + Select + Wybierz + + + Done + Zrobione + + + Options + Opcje + + + Cancel + Anuluj + + + Exit + Wyjście + + + + QSpinBox + + More + Więcej + + + Less + Mniej + + + + QSql + + Delete + Skasuj + + + Delete this record? + Skasować ten rekord? + + + Yes + Tak + + + No + Nie + + + Insert + Wstaw + + + Update + Uaktualnij + + + Save edits? + Zachować zmiany? + + + Cancel + Anuluj + + + Confirm + Potwierdź + + + Cancel your edits? + Anulować zmiany? + + + + QSslSocket + + Unable to write data: %1 + + + + Unable to decrypt data: %1 + Nie można odszyfrować danych: %1 + + + Error while reading: %1 + Błąd podczas czytania: %1 + + + Error during SSL handshake: %1 + Błąd podczas nawiązania sesji SSL: %1 + + + Error creating SSL context (%1) + Błąd tworzenia kontekstu (%1) + + + Invalid or empty cipher list (%1) + Niepoprawna lub pusta lista szyfrów (%1) + + + Private key does not certify public key, %1 + Prywatny klucz nie uwiarygodnia publicznego, %1 + + + Error creating SSL session, %1 + Błąd tworzenia sesji SSL, %1 + + + Error creating SSL session: %1 + Błąd tworzenia sesji SSL: %1 + + + Cannot provide a certificate with no key, %1 + Nie można dostarczyć certyfikatu bez klucza, %1 + + + Error loading local certificate, %1 + Błąd ładowania lokalnego certyfikatu, %1 + + + Error loading private key, %1 + Błąd ładowania prywatnego klucza, %1 + + + No error + Brak błędu + + + The issuer certificate could not be found + Nie można odnaleźć wydawcy certyfikatu + + + The certificate signature could not be decrypted + Nie można odszyfrować podpisu certyfikatu + + + The public key in the certificate could not be read + Nie można odczytać publicznego klucza w certyfikacie + + + The signature of the certificate is invalid + Niepoprawny podpis certyfikatu + + + The certificate is not yet valid + Certyfikat nie jest jeszcze ważny + + + The certificate has expired + Certyfikat utracił ważność + + + The certificate's notBefore field contains an invalid time + Pole "notBefore" certyfikatu zawiera niepoprawną datę + + + The certificate's notAfter field contains an invalid time + Pole "notAfter" certyfikatu zawiera niepoprawną datę + + + The certificate is self-signed, and untrusted + Certyfikat z podpisem własnym, niezaufany + + + The root certificate of the certificate chain is self-signed, and untrusted + Główny certyfikat łańcucha certyfikatów ma własny podpis i jest niezaufany + + + The issuer certificate of a locally looked up certificate could not be found + Nie można znaleźć certyfikatu wydawcy wyszukanego lokalnie + + + No certificates could be verified + Nie można zweryfikować certyfikatów + + + One of the CA certificates is invalid + Jeden z certyfikatów urzędu certyfikacji jest nieprawidłowy + + + The basicConstraints path length parameter has been exceeded + Długość ścieżki określona w podstawowych warunkach ograniczających została przekroczona + + + The supplied certificate is unsuitable for this purpose + Dostarczony certyfikat jest nieodpowiedni do tego celu + + + The root CA certificate is not trusted for this purpose + Główny certyfikat urzędu certyfikacji nie jest zaufany do tego celu + + + The root CA certificate is marked to reject the specified purpose + Główny certyfikat urzędu certyfikacji jest wyznaczony do odrzucania określonego celu + + + The current candidate issuer certificate was rejected because its subject name did not match the issuer name of the current certificate + Certyfikat wydawcy obecnego kandydata został odrzucony, ponieważ nazwa podmiotu nie odpowiadała nazwie wydawcy obecnego certyfikatu + + + The current candidate issuer certificate was rejected because its issuer name and serial number was present and did not match the authority key identifier of the current certificate + Certyfikat wydawcy obecnego kandydata został odrzucony, ponieważ nazwa wydawcy i przedstawiony numer seryjny nie odpowiadały identyfikatorowi klucza urzędu certyfikacji obecnego certyfikatu + + + The peer did not present any certificate + Element równorzędny nie przedstawił żadnego certyfikatu + + + The host name did not match any of the valid hosts for this certificate + Nazwa hosta nie odpowiadała żadnemu z prawidłowych hostów tego certyfikatu + + + Unknown error + + + + + QStateMachine + + Missing initial state in compound state '%1' + + + + Missing default state in history state '%1' + + + + No common ancestor for targets and source of transition from state '%1' + + + + Unknown error + + + + + QSystemSemaphore + + %1: does not exist + + + + %1: out of resources + + + + %1: permission denied + + + + %1: already exists + + + + %1: unknown error %2 + + + + + QTDSDriver + + Unable to open connection + + + + Unable to use database + + + + + QTabBar + + Scroll Left + + + + Scroll Right + + + + + QTcpServer + + Operation on socket is not supported + + + + + QTextControl + + &Undo + + + + &Redo + + + + Cu&t + + + + &Copy + + + + Copy &Link Location + + + + &Paste + + + + Delete + + + + Select All + + + + + QToolButton + + Press + + + + Open + + + + + QUdpSocket + + This platform does not support IPv6 + Ta platforma nie obsługuje IPv6 + + + + QUndoGroup + + Undo + Cofnij + + + Redo + Przywróć + + + + QUndoModel + + <empty> + <pusty> + + + + QUndoStack + + Undo + Cofnij + + + Redo + Przywróć + + + + QUnicodeControlCharacterMenu + + LRM Left-to-right mark + LRM znacznik od prawej do lewej + + + RLM Right-to-left mark + RLM Znacznik od prawej do lewej + + + ZWJ Zero width joiner + ZWJ Łącznik zerowej długości + + + ZWNJ Zero width non-joiner + ZWNJ Rozdzielnik zerowej długości + + + ZWSP Zero width space + ZWSP Przerwa zerowej długości + + + LRE Start of left-to-right embedding + LRE Początek osadzania od lewej do prawej + + + RLE Start of right-to-left embedding + RLE Początek osadzania od prawej do lewej + + + LRO Start of left-to-right override + LRO Początek nadpisania od lewej do prawej + + + RLO Start of right-to-left override + RLO Początek nadpisania od prawej do lewej + + + PDF Pop directional formatting + PDF Formatowanie kierunkowe pop + + + Insert Unicode control character + Wstaw znak kontroli Unicode + + + + QWebFrame + + Request cancelled + Prośba anulowana + + + Request blocked + Prośba zablokowana + + + Cannot show URL + Nie można pokazać URL + + + Frame load interrupted by policy change + Ładowanie ramki przerwane przez zmianę strategii + + + Cannot show mimetype + Nie można pokazać typu MIME + + + File does not exist + Plik nie istnieje + + + + QWebPage + + Submit + default label for Submit buttons in forms on web pages + Wyślij + + + Submit + Submit (input element) alt text for <input> elements with no alt, title, or value + Wyślij + + + Reset + default label for Reset buttons in forms on web pages + Wyczyść + + + Choose File + title for file button used in HTML forms + Wybierz plik + + + No file selected + text to display in file button used in HTML forms when no file is selected + Nie zaznaczono pliku + + + Open in New Window + Open in New Window context menu item + Otwórz w nowym oknie + + + Save Link... + Download Linked File context menu item + Zachowaj odsyłacz... + + + Copy Link + Copy Link context menu item + Skopiuj odsyłacz + + + Open Image + Open Image in New Window context menu item + Otwórz obrazek + + + Save Image + Download Image context menu item + Zachowaj obrazek + + + Copy Image + Copy Link context menu item + Skopiuj obrazek + + + Open Frame + Open Frame in New Window context menu item + Otwórz ramkę + + + Copy + Copy context menu item + Skopiuj + + + Go Back + Back context menu item + Wróć + + + Go Forward + Forward context menu item + Idź dalej + + + Stop + Stop context menu item + Zatrzymaj + + + Reload + Reload context menu item + Przeładuj + + + Cut + Cut context menu item + Wytnij + + + Paste + Paste context menu item + Wklej + + + No Guesses Found + No Guesses Found context menu item + Nie odnaleziono podpowiedzi + + + Ignore + Ignore Spelling context menu item + Zignoruj + + + Add To Dictionary + Learn Spelling context menu item + Dodaj do słownika + + + Search The Web + Search The Web context menu item + Wyszukaj w sieci + + + Look Up In Dictionary + Look Up in Dictionary context menu item + Poszukaj w słowniku + + + Open Link + Open Link context menu item + Otwórz odsyłacz + + + Ignore + Ignore Grammar context menu item + Zignoruj + + + Spelling + Spelling and Grammar context sub-menu item + Pisownia + + + Show Spelling and Grammar + menu item title + Pokaż pisownię i gramatykę + + + Hide Spelling and Grammar + menu item title + Schowaj pisownię i gramatykę + + + Check Spelling + Check spelling context menu item + Sprawdź pisownię + + + Check Spelling While Typing + Check spelling while typing context menu item + Sprawdzaj pisownię podczas pisania + + + Check Grammar With Spelling + Check grammar with spelling context menu item + Sprawdzaj gramatykę wraz z pisownią + + + Fonts + Font context sub-menu item + Czcionki + + + Bold + Bold context menu item + Pogrubiony + + + Italic + Italic context menu item + Kursywa + + + Underline + Underline context menu item + Podkreślenie + + + Outline + Outline context menu item + Kontur + + + Direction + Writing direction context sub-menu item + Kierunek + + + Text Direction + Text direction context sub-menu item + Kierunek tekstu + + + Default + Default writing direction context menu item + Domyślny + + + Left to Right + Left to Right context menu item + Z lewej na prawą + + + Right to Left + Right to Left context menu item + Z prawej na lewą + + + Loading... + Media controller status message when the media is loading + Ładowanie... + + + Live Broadcast + Media controller status message when watching a live broadcast + Transmisja na żywo + + + Audio Element + Media controller element + Element dźwiękowy + + + Video Element + Media controller element + Element wideo + + + Mute Button + Media controller element + Przycisk wyłączania głosu + + + Unmute Button + Media controller element + Przycisk włączania głosu + + + Play Button + Media controller element + Przycisk odtwarzania + + + Pause Button + Media controller element + Przycisk pauzy + + + Slider + Media controller element + Suwak + + + Slider Thumb + Media controller element + Uchwyt suwaka + + + Rewind Button + Media controller element + Przycisk przewijania + + + Return to Real-time Button + Media controller element + Przycisk powrotu do czasu rzeczywistego + + + Elapsed Time + Media controller element + Czas który upłynął + + + Remaining Time + Media controller element + Czas który pozostał + + + Status Display + Media controller element + Wyświetlacz stanu + + + Fullscreen Button + Media controller element + Przycisk trybu pełnoekranowego + + + Seek Forward Button + Media controller element + Przycisk przeszukiwania do przodu + + + Seek Back Button + Media controller element + Przycisk przeszukiwania do tyłu + + + Audio element playback controls and status display + Media controller element + Kontrolki odtwarzania dźwięku i wyświetlacz stanu + + + Video element playback controls and status display + Media controller element + Kontrolki odtwarzania wideo i wyświetlacz stanu + + + Mute audio tracks + Media controller element + Wyłącz ścieżkę dźwiękową + + + Unmute audio tracks + Media controller element + Włącz ścieżkę dźwiękową + + + Begin playback + Media controller element + Rozpocznij odtwarzanie + + + Pause playback + Media controller element + Wstrzymaj odtwarzanie + + + Movie time scrubber + Media controller element + Suwak czasu + + + Movie time scrubber thumb + Media controller element + Uchwyt suwaka czasu + + + Rewind movie + Media controller element + Przewiń film + + + Return streaming movie to real-time + Media controller element + Przywróć przesyłanie filmu do czasu rzeczywistego + + + Current movie time + Media controller element + Czas bieżącego filmu + + + Remaining movie time + Media controller element + Czas do końca filmu + + + Current movie status + Media controller element + Stan bieżącego filmu + + + Play movie in full-screen mode + Media controller element + Odtwarzaj film w trybie pełnoekranowym + + + Seek quickly back + Media controller element + Przeszukaj szybko do tyłu + + + Seek quickly forward + Media controller element + Przeszukaj szybko do przodu + + + Indefinite time + Media time description + Nieokreślony czas + + + %1 days %2 hours %3 minutes %4 seconds + Media time description + %1 dni %2 godzin %3 minut %4 sekund + + + %1 hours %2 minutes %3 seconds + Media time description + %1 godzin %2 minut %3 sekund + + + %1 minutes %2 seconds + Media time description + %1 minut %2 sekund + + + %1 seconds + Media time description + %1 sekund + + + Inspect + Inspect Element context menu item + Zwiedzaj + + + No recent searches + Label for only item in menu that appears when clicking on the search field image, when no searches have been performed + Brak ostatnich wyszukiwań + + + Recent searches + label for first item in the menu that appears when clicking on the search field image, used as embedded menu title + Ostatnie wyszukiwania + + + Clear recent searches + menu item in Recent Searches menu that empties menu's contents + Wyczyść ostatnie wyszukiwania + + + Unknown + Unknown filesize FTP directory listing item + Nieznany + + + Web Inspector - %2 + Wizytator sieciowy - %2 + + + %1 (%2x%3 pixels) + Title string for images + %1 (%2x%3 piksli) + + + Bad HTTP request + Niepoprawna komenda HTTP + + + This is a searchable index. Enter search keywords: + text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' + To jest indeks wyszukiwawczy. Podaj słowa do wyszukania: + + + Scroll here + Przewiń tutaj + + + Left edge + Lewa krawędź + + + Top + Do góry + + + Right edge + Prawa krawędź + + + Bottom + W dół + + + Page left + Strona w lewo + + + Page up + Strona do góry + + + Page right + Strona w prawo + + + Page down + Strona w dół + + + Scroll left + Przewiń w lewo + + + Scroll up + Przewiń do góry + + + Scroll right + Przewiń w prawo + + + Scroll down + Przewiń w dół + + + %n file(s) + number of chosen file + + %n plik + %n pliki + %n plików + + + + JavaScript Alert - %1 + Ostrzeżenie JavaScript - %1 + + + JavaScript Confirm - %1 + Potwierdzenie JavaScript - %1 + + + JavaScript Prompt - %1 + Zachęta JavaScript - %1 + + + JavaScript Problem - %1 + Problem JavaScript - %1 + + + The script on this page appears to have a problem. Do you want to stop the script? + Skrypt na tej stronie nie działa poprawnie. Czy chcesz przerwać ten skrypt? + + + Move the cursor to the next character + Przesuń kursor do następnego znaku + + + Move the cursor to the previous character + Przesuń kursor do poprzedniego znaku + + + Move the cursor to the next word + Przesuń kursor do następnego słowa + + + Move the cursor to the previous word + Przesuń kursor do poprzedniego słowa + + + Move the cursor to the next line + Przesuń kursor do następnej linii + + + Move the cursor to the previous line + Przesuń kursor do poprzedniej linii + + + Move the cursor to the start of the line + Przesuń kursor do początku linii + + + Move the cursor to the end of the line + Przesuń kursor do końca linii + + + Move the cursor to the start of the block + Przesuń kursor do początku bloku + + + Move the cursor to the end of the block + Przesuń kursor do końca bloku + + + Move the cursor to the start of the document + Przesuń kursor do początku dokumentu + + + Move the cursor to the end of the document + Przesuń kursor do końca dokumentu + + + Select all + Zaznacz wszystko + + + Select to the next character + Zaznacz do następnego znaku + + + Select to the previous character + Zaznacz do poprzedniego znaku + + + Select to the next word + Zaznacz do następnego słowa + + + Select to the previous word + Zaznacz do poprzedniego słowa + + + Select to the next line + Zaznacz do następnej linii + + + Select to the previous line + Zaznacz do poprzedniej linii + + + Select to the start of the line + Zaznacz do początku linii + + + Select to the end of the line + Zaznacz do końca linii + + + Select to the start of the block + Zaznacz do początku bloku + + + Select to the end of the block + Zaznacz do końca bloku + + + Select to the start of the document + Zaznacz do początku dokumentu + + + Select to the end of the document + Zaznacz do końca dokumentu + + + Delete to the start of the word + Skasuj do początku słowa + + + Delete to the end of the word + Skasuj do końca słowa + + + Insert a new paragraph + Wstaw nowy paragraf + + + Insert a new line + Wstaw nową linię + + + Paste and Match Style + Wklej i dopasuj styl + + + Remove formatting + Usuń formatowanie + + + Strikethrough + Przekreślenie + + + Subscript + Indeks dolny + + + Superscript + Indeks górny + + + Insert Bulleted List + Wstaw listę wypunktowaną + + + Insert Numbered List + Wstaw listę ponumerowaną + + + Indent + Zwiększ wcięcie + + + Outdent + Zmniejsz wcięcie + + + Center + Wyśrodkuj + + + Justify + Wyjustuj + + + Align Left + Wyrównaj do lewej + + + Align Right + Wyrównaj do prawej + + + + QWhatsThisAction + + What's This? + Co to jest? + + + + QWidget + + * + * + + + + QWizard + + Cancel + Anuluj + + + Help + Pomoc + + + < &Back + < &Wstecz + + + &Finish + &Zakończ + + + &Help + &Pomoc + + + Go Back + Wróć + + + Continue + Kontynuuj + + + Commit + Dokonaj + + + Done + Wykonano + + + &Next + &Dalej + + + &Next > + &Dalej > + + + + QWorkspace + + &Restore + &Przywróć + + + &Move + &Przenieś + + + &Size + &Rozmiar + + + Mi&nimize + Zmi&nimalizuj + + + Ma&ximize + Zma&ksymalizuj + + + &Close + &Zamknij + + + Stay on &Top + Pozostaw na &wierzchu + + + Minimize + Zminimalizuj + + + Restore Down + Przywróć pod spód + + + Close + Zamknij + + + Sh&ade + &Zwiń + + + %1 - [%2] + %1 - [%2] + + + &Unshade + R&ozwiń + + + + QXml + + no error occurred + nie pojawił się żaden błąd + + + error triggered by consumer + błąd wywołany przez konsumenta + + + unexpected end of file + nieoczekiwany koniec pliku + + + more than one document type definition + więcej niż jedna definicja typu dokumentu + + + error occurred while parsing element + wystąpił błąd podczas parsowania elementu + + + tag mismatch + niepoprawny tag + + + error occurred while parsing content + wystąpił błąd podczas parsowania zawartości + + + unexpected character + nieoczekiwany znak + + + invalid name for processing instruction + niepoprawna nazwa dla instrukcji przetwarzającej + + + version expected while reading the XML declaration + oczekiwana wersja podczas czytania deklaracji XML + + + wrong value for standalone declaration + błędna wartość dla deklaracji "standalone" + + + error occurred while parsing document type definition + wystąpił błąd podczas parsowania typu definicji dokumentu + + + letter is expected + oczekiwana jest litera + + + error occurred while parsing comment + wystąpił błąd podczas parsowania komentarza + + + error occurred while parsing reference + wystąpił błąd podczas parsowania odwołania + + + internal general entity reference not allowed in DTD + odwołanie do jednostki ogólnej wewnętrznej nie dozwolone w DTD + + + external parsed general entity reference not allowed in attribute value + odwołanie do jednostki ogólnej zewnętrznie przetworzonej nie dozwolone dla wartości atrybutu + + + external parsed general entity reference not allowed in DTD + odwołanie do jednostki ogólnej zewnętrznie przetworzonej nie dozwolone w DTD + + + unparsed entity reference in wrong context + odwołanie do jednostki nieprzetworzonej w złym kontekście + + + recursive entities + jednostki rekurencyjne + + + error in the text declaration of an external entity + błąd w deklaracji "text" zewnętrznej jednostki + + + encoding declaration or standalone declaration expected while reading the XML declaration + oczekiwano deklaracji "encoding" lub "standalone" podczas odczytywania deklaracji XML + + + standalone declaration expected while reading the XML declaration + deklaracja "standalone" oczekiwana podczas czytania deklaracji XML + + + + QXmlPatternistCLI + + Warning in %1, at line %2, column %3: %4 + Ostrzeżenie w %1, wiersz %2, kolumna %3: %4 + + + Warning in %1: %2 + Ostrzeżenie w %1: %2 + + + Unknown location + Nieznana lokalizacja + + + Error %1 in %2, at line %3, column %4: %5 + Błąd %1 w %2, wiersz %3, kolumna %4: %5 + + + Error %1 in %2: %3 + Błąd %1 w %2: %3 + + + + QXmlStream + + Extra content at end of document. + Dodatkowa treść na końcu dokumentu. + + + Invalid entity value. + Niepoprawna wartość jednostki. + + + Invalid XML character. + Niepoprawny znak XML. + + + Sequence ']]>' not allowed in content. + Ciąg ']]>' niedozwolony w treści. + + + Namespace prefix '%1' not declared + Przedrostek przestrzeni nazw '%1' nie został zadeklarowany + + + Attribute redefined. + Atrybut zdefiniowany wielokrotnie. + + + Unexpected character '%1' in public id literal. + Nieoczekiwany znak '%1' w publicznej stałej znakowej. + + + Invalid XML version string. + Niepoprawna wersja XML. + + + Unsupported XML version. + Nieobsługiwana wersja XML. + + + %1 is an invalid encoding name. + %1 jest niepoprawną nazwą kodowania. + + + Encoding %1 is unsupported + Kodowanie %1 jest nieobsługiwane + + + Standalone accepts only yes or no. + Tylko wartości "tak" lub "nie" są akceptowane przez "standalone". + + + Invalid attribute in XML declaration. + Niepoprawny atrybut w deklaracji XML. + + + Premature end of document. + Przedwczesne zakończenie dokumentu. + + + Invalid document. + Niepoprawny dokument. + + + Expected + Oczekiwano + + + , but got ' + , ale otrzymano ' + + + Unexpected ' + Nieoczekiwany ' + + + Expected character data. + Oczekiwana dana znakowa. + + + Recursive entity detected. + Wykryto jednostkę rekurencyjną. + + + Start tag expected. + Oczekiwano tagu start. + + + XML declaration not at start of document. + Deklaracja XML nie jest na początku dokumentu. + + + NDATA in parameter entity declaration. + NDATA w deklaracji parametru obiektu. + + + %1 is an invalid processing instruction name. + %1 jest niepoprawną nazwą instrukcji przetwarzającej. + + + Invalid processing instruction name. + Niepoprawna nazwa instrukcji przetwarzającej. + + + Illegal namespace declaration. + Niepoprawna deklaracja przestrzeni nazw. + + + Invalid XML name. + Niepoprawna nazwa XML. + + + Opening and ending tag mismatch. + Niezgodne tagi początku i końca. + + + Reference to unparsed entity '%1'. + Odwołanie do nieprzetworzonej jednostki '%1'. + + + Entity '%1' not declared. + Jednostka '%1' nie zadeklarowana. + + + Reference to external entity '%1' in attribute value. + Odwołanie do zewnętrznej jednostki '%1' jako wartość atrybutu. + + + Invalid character reference. + Niepoprawny znak odwołania. + + + Encountered incorrectly encoded content. + Natrafiono na niepoprawnie zakodowaną treść. + + + The standalone pseudo attribute must appear after the encoding. + Pseudo atrybut "standalone" musi pojawić się po "encoding". + + + %1 is an invalid PUBLIC identifier. + %1 jest niepoprawnym publicznym identyfikatorem. + + + + QtXmlPatterns + + At least one component must be present. + Przynajmniej jeden komponent musi być obecny. + + + %1 is not a valid value of type %2. + %1 nie jest poprawną wartością dla typu %2. + + + When casting to %1 from %2, the source value cannot be %3. + W rzutowaniu %1 na %2 wartość źródłowa nie może być %3. + + + Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values. + Efektywna wartość boolowska (EBV) nie może być obliczona dla sekwencji zawierającej dwie lub więcej wartości atomowe. + + + The data of a processing instruction cannot contain the string %1 + Dane instrukcji przetwarzania nie mogą zawierać ciągu %1 + + + %1 is an invalid %2 + %1 jest niepoprawnym %2 + + + %1 is not a valid XML 1.0 character. + %1 nie jest poprawnym znakiem XML 1.0. + + + %1 was called. + Wywołano %1. + + + In the replacement string, %1 must be followed by at least one digit when not escaped. + W ciągu zastępczym, po %1 musi następować przynajmniej jedna cyfra + + + In the replacement string, %1 can only be used to escape itself or %2, not %3 + W ciągu zastępczym, %1 może być użyte tylko do zabezpieczenia samej siebie lub %2, nigdy %3 + + + %1 matches newline characters + %1 dopasowało znak nowej linii + + + Matches are case insensitive + Dopasowania uwzględniają wielkość liter + + + %1 is an invalid regular expression pattern: %2 + %1 jest niepoprawnym wzorcem wyrażenia regularnego: %2 + + + It will not be possible to retrieve %1. + Nie będzie można odzyskać %1. + + + The default collection is undefined + Domyślna kolekcja jest niezdefiniowana + + + %1 cannot be retrieved + + + + The item %1 did not match the required type %2. + Element %1 nie został dopasowany do wymaganego typu %2. + + + %1 is an unknown schema type. + %1 jest nieznanym typem schematu. + + + A template with name %1 has already been declared. + Szablon o nazwie %1 został już zadeklarowany. + + + Only one %1 declaration can occur in the query prolog. + Tylko jedna deklaracja %1 może się pojawić w prologu zapytania. + + + The initialization of variable %1 depends on itself + Inicjalizacja zmiennej %1 zależy od niej samej + + + The variable %1 is unused + Zmienna %1 jest nieużywana + + + Version %1 is not supported. The supported XQuery version is 1.0. + Wersja %1 nie jest obsługiwana. Obsługiwaną wersją XQuery jest wersja 1.0. + + + No function with signature %1 is available + Żadna funkcja w postaci %1 nie jest dostępna + + + It is not possible to redeclare prefix %1. + Nie jest możliwe ponowne zadeklarowanie przedrostka %1. + + + Prefix %1 is already declared in the prolog. + Przedrostek %1 jest już zadeklarowany w prologu. + + + The name of an option must have a prefix. There is no default namespace for options. + Nazwa opcji musi posiadać przedrostek. Nie istnieje domyślna przestrzeń nazw dla opcji. + + + The Schema Import feature is not supported, and therefore %1 declarations cannot occur. + Cecha "Import schematu" nie jest obsługiwana, dlatego deklaracje %1 nie mogą pojawić. + + + The target namespace of a %1 cannot be empty. + Docelowa przestrzeń nazw dla %1 nie może być pusta. + + + The module import feature is not supported + Cecha "Import modułu" nie jest obsługiwana + + + The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2 + Przestrzeń nazw dla funkcji zdefiniowanej przez użytkownika w module bibliotecznym musi odpowiadać przestrzeni nazw modułu. Powinna to być %1 zamiast %2 + + + A function already exists with the signature %1. + Funkcja w postaci %1 już istnieje. + + + No external functions are supported. All supported functions can be used directly, without first declaring them as external + Zewnętrzne funkcje nie są obsługiwane. Wszystkie obsługiwane funkcje mogą być używane bezpośrednio, bez ich uprzedniego deklarowania jako zewnętrzne + + + The %1-axis is unsupported in XQuery + Oś %1 nie jest obsługiwana w XQuery + + + The namespace URI cannot be the empty string when binding to a prefix, %1. + Przestrzeń nazw URI nie może być pustym ciągiem w powiązaniu z przedrostkiem, %1. + + + %1 is an invalid namespace URI. + %1 jest niepoprawną przestrzenią nazw URI. + + + It is not possible to bind to the prefix %1 + Nie jest możliwe powiązanie z przedrostkiem %1 + + + Two namespace declaration attributes have the same name: %1. + Atrybuty deklaracji przestrzeni nazw mają tą samą nazwę: %1. + + + The namespace URI must be a constant and cannot use enclosed expressions. + Przestrzeń nazw URI nie może być stałą i nie może używać zawartych w niej wyrażeń. + + + %1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported. + %1 nie jest wewnątrz zakresu deklaracji atrybutów. Zwróć uwagę że importowanie schematów nie jest obsługiwane. + + + empty + pusty + + + zero or one + zero lub jeden + + + exactly one + dokładnie jeden + + + one or more + jeden lub więcej + + + zero or more + zero lub więcej + + + The focus is undefined. + Focus jest niezdefiniowany. + + + An attribute by name %1 has already been created. + Atrybut o nazwie %1 został już utworzony. + + + Network timeout. + Przekroczony czas połączenia. + + + Element %1 can't be serialized because it appears outside the document element. + Element %1 nie może być zserializowany ponieważ pojawił się poza elementem "document". + + + Year %1 is invalid because it begins with %2. + Rok %1 jest niepoprawny ponieważ rozpoczyna się: %2. + + + Day %1 is outside the range %2..%3. + Dzień %1 jest poza zakresem %2..%3. + + + Month %1 is outside the range %2..%3. + Miesiąc %1 jest poza zakresem %2..%3. + + + Overflow: Can't represent date %1. + Przepełnienie: Nie można wyrazić daty %1. + + + Day %1 is invalid for month %2. + Dzień %1 jest niepoprawny dla miesiąca %2. + + + Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; + Czas 24:%1:%2:%3 jest niepoprawny. Godzina jest 24, ale minuty, sekundy i milisekundy nie są równocześnie zerami; + + + Time %1:%2:%3.%4 is invalid. + Czas %1:%2:%3.%4 jest niepoprawny. + + + Overflow: Date can't be represented. + Przepełnienie: Data nie może być wyrażona. + + + At least one time component must appear after the %1-delimiter. + Przynajmniej jeden komponent musi wystąpić po nawiasie %1. + + + Dividing a value of type %1 by %2 (not-a-number) is not allowed. + Dzielenie wartości typu %1 przez %2 (typ nienumeryczny) jest niedozwolone. + + + Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed. + Dzielenie wartości typu %1 przez %2 lub %3 (plus lub minus zero) jest niedozwolone. + + + Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed. + Mnożenie wartości typu %1 przez %2 lub %3 (plus lub minus nieskończoność) jest niedozwolone. + + + A value of type %1 cannot have an Effective Boolean Value. + Wartość typu %1 nie może posiadać efektywnej wartości boolowskiej (EBV). + + + Value %1 of type %2 exceeds maximum (%3). + Wartość %1 typu %2 przekracza maksimum (%3). + + + Value %1 of type %2 is below minimum (%3). + Wartość %1 typu %2 jest poniżej minimum (%3). + + + A value of type %1 must contain an even number of digits. The value %2 does not. + Wartość typu %1 musi zawierać parzystą liczbę cyfr. Wartość %2 nie zawiera. + + + %1 is not valid as a value of type %2. + Wartość %1 nie jest poprawna jako wartość typu %2. + + + Operator %1 cannot be used on type %2. + Operator %1 nie może być użyty dla typu %2. + + + Operator %1 cannot be used on atomic values of type %2 and %3. + Operator %1 nie może być użyty dla atomowych wartości typu %2 i %3. + + + The namespace URI in the name for a computed attribute cannot be %1. + Przestrzeń nazw URI nie może być %1 w nazwie dla obliczonego atrybutu. + + + The name for a computed attribute cannot have the namespace URI %1 with the local name %2. + Nazwa dla wyliczonego atrybutu nie może zawierać przestrzeni nazw URI %1 z lokalną nazwą %2. + + + Type error in cast, expected %1, received %2. + Błąd typów w rzutowaniu: spodziewano się %1, otrzymano %2. + + + When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed. + Podczas rzutowania na %1 lub na typ pochodny, wartość źródłowa musi być tego samego typu lub musi być zapisem tekstowym. Typ %2 nie jest dozwolony. + + + A comment cannot contain %1 + Komentarz nie może zawierać %1 + + + A comment cannot end with a %1. + Komentarz nie może kończyć się: %1. + + + An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place. + Węzeł "attribute" nie może być podelementem węzła "document". Dlatego atrybut %1 jest w złym miejscu. + + + A library module cannot be evaluated directly. It must be imported from a main module. + Moduł biblioteki nie może być bezpośrednio oceniony. On musi być zaimportowany z głównego modułu. + + + No template by name %1 exists. + Szablon o nazwie %1 nie istnieje. + + + A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type. + Wartość typu %1 nie może być predykatem. Predykat musi być typu liczbowego lub Efektywną Wartość Logiczną. + + + A positional predicate must evaluate to a single numeric value. + Wynikiem predykatu pozycyjnego musi być pojedyncza wartość liczbowa. + + + The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, %2 is invalid. + Docelowa nazwa w instrukcji przetwarzania nie może być %1 w żadnej kombinacji wielkich i małych liter. Dlatego nazwa %2 jest niepoprawna. + + + %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. + %1 nie jest poprawną nazwą docelową w instrukcji przetwarzania. Nazwa musi być wartością %2, np. %3. + + + The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. + Ostatni krok w ścieżce musi zawierać albo węzły albo wartości atomowe. Nie może zawierać obu jednocześnie. + + + No namespace binding exists for the prefix %1 + Żadna przestrzeń nazw nie jest powiązana z przedrostkiem %1 + + + No namespace binding exists for the prefix %1 in %2 + Żadna przestrzeń nazw nie jest powiązana z przedrostkiem %1 w %2 + + + The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration. + Pierwszy argument w %1 nie może być typu %2. Musi on być typu liczbowego: xs:yearMonthDuration lub xs:dayTimeDuration. + + + The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + Pierwszy argument w %1 nie może być typu %2. Musi on być typu: %3, %4 lub %5. + + + The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + Drugi argument w %1 nie może być typu %2. Musi on być typu: %3, %4 lub %5. + + + If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same. + Jeśli oba argumenty mają przesunięcia strefowe, muszą one być takie same. %1 i %2 nie są takie same. + + + %1 must be followed by %2 or %3, not at the end of the replacement string. + Po %1 musi następować %2 lub %3, lecz nie na końcu zastępczego ciągu. + + + %1 and %2 match the start and end of a line. + + + + Whitespace characters are removed, except when they appear in character classes + Spacje są usuwane z wyjątkiem kiedy pojawią się w klasach znakowych + + + %1 is an invalid flag for regular expressions. Valid flags are: + %1 jest niepoprawną flagą dla wyrażeń regularnych. Poprawnymi flagami są: + + + If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified. + Jeśli pierwszy argument jest pustą sekwencją lub zerowej długości ciągiem (przy braku przestrzeni nazw), przedrostek nie może wystąpić. Podano przedrostek %1. + + + The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization). + Znormalizowana forma %1 nie jest obsługiwana. Obsługiwanymi formami są: %2, %3, %4 i %5 oraz pusta forma (brak normalizacji). + + + A zone offset must be in the range %1..%2 inclusive. %3 is out of range. + Przesunięcie strefowe musi być w zakresie %1..%2 włącznie. %3 jest poza tym zakresem. + + + Required cardinality is %1; got cardinality %2. + Wymagana liczność wynosi %1; otrzymano %2. + + + The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2. + Enkodowanie %1 jest niepoprawne. Może ono zawierać jedynie znaki alfabetu łacińskiego, nie może zawierać spacji i musi być dopasowane do wyrażenia regularnego %2. + + + The keyword %1 cannot occur with any other mode name. + Słowo kluczowe %1 nie może wystąpić z inną nazwą trybu. + + + No variable with name %1 exists + Zmienna o nazwie %1 nie istnieje + + + The value of attribute %1 must be of type %2, which %3 isn't. + Wartość atrybutu %1 musi być typu %2, którym nie jest %3. + + + The prefix %1 cannot be bound. By default, it is already bound to the namespace %2. + Przedrostek %1 nie może być powiązany. Jest on domyślnie powiązany z przestrzenią nazw %2. + + + A variable with name %1 has already been declared. + Zmienna o nazwie %1 została już zadeklarowana. + + + No value is available for the external variable with name %1. + Brak wartości dla zewnętrznej zmiennej o nazwie %1. + + + A stylesheet function must have a prefixed name. + Funkcja arkusza stylu musi zawierać nazwę z przedrostkiem. + + + The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. + Przestrzeń nazw %1 jest zarezerwowana, dlatego funkcje zdefiniowane przez użytkownika nie mogą jej użyć. Spróbuj predefiniowany przedrostek %2, który istnieje w takich przypadkach. + + + An argument with name %1 has already been declared. Every argument name must be unique. + Argument o nazwie %1 został już zadeklarowany. Każda nazwa argumentu musi być unikatowa. + + + When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. + Gdy funkcja %1 jest wykorzystana do dopasowania wewnątrz wzorca, jej argument musi być referencją do zmiennej lub napisem. + + + In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching. + We wzorze XSL-T pierwszy argument w funkcji %1 musi być stałą znakową podczas dopasowywania. + + + In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching. + We wzorze XSL-T pierwszy argument w funkcji %1 musi być stałą znakową lub nazwą zmiennej podczas dopasowywania. + + + In an XSL-T pattern, function %1 cannot have a third argument. + We wzorze XSL-T funkcja %1 nie może zawierać trzeciego argumentu. + + + In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. + We wzorze XSL-T tylko funkcje %1 i %2 mogą być użyte do dopasowania, zaś funkcja %3 nie. + + + In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can. + We wzorze XSL-T tylko osie %2 i %3 mogą być użyte, zaś oś %1 nie. + + + %1 is an invalid template mode name. + %1 nie jest poprawną nazwa trybu szablonu. + + + The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. + Nazwa zmiennej powiązanej w wyrażeniu "for" musi być inna od zmiennej pozycjonującej. W związku z tym dwie zmienne o nazwie %1 kolidują ze sobą. + + + The Schema Validation Feature is not supported. Hence, %1-expressions may not be used. + Cecha "Walidacja schematu" nie jest obsługiwana. Dlatego też wyrażenia %1 nie mogą być użyte. + + + None of the pragma expressions are supported. Therefore, a fallback expression must be present + Wyrażenia "pragma" nie są obsługiwane. Dlatego musi wystąpić wyrażenie zastępcze + + + Each name of a template parameter must be unique; %1 is duplicated. + Każda nazwa parametru szablonu musi być unikatowa; %1 się powtarza. + + + No function with name %1 is available. + Żadna funkcja o nazwie %1 nie jest dostępna. + + + %1 is not a valid numeric literal. + %1 nie jest poprawnym zapisem liczbowym. + + + W3C XML Schema identity constraint selector + Selektor narzucenia niepowtarzalności W3C XML Schema + + + W3C XML Schema identity constraint field + Pole narzucenia niepowtarzalności W3C XML Schema + + + A construct was encountered which is disallowed in the current language(%1). + Wystąpiła konstrukcja która jest niedozwolona w bieżącym języku (%1). + + + Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared). + Przestrzeń nazw %1 może być jedynie powiązana z %2 (w przeciwnym wypadku jest ona domyślnie zadeklarowana). + + + Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared). + Przedrostek %1 może być jedynie powiązany z %2 (w przeciwnym wypadku jest on domyślnie zadeklarowany). + + + An attribute with name %1 has already appeared on this element. + Atrybut o nazwie %1 już się pojawił w tym elemencie. + + + A direct element constructor is not well-formed. %1 is ended with %2. + Konstruktor elementu bezpośredniego nie jest dobrze sformatowany. %1 jest zakończony %2. + + + The name %1 does not refer to any schema type. + Nazwa %1 nie odpowiada żadnemu typowi schematu. + + + %1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works. + %1 jest typem złożonym. Rzutowanie na typy złożone nie jest możliwe. Jednakże rzutowanie na typy atomowe np.: %2 jest dozwolone. + + + %1 is not an atomic type. Casting is only possible to atomic types. + %1 nie jest typem atomowym. Możliwe jest rzutowanie tylko na typy atomowe. + + + %1 is not a valid name for a processing-instruction. + %1 nie jest poprawną nazwą dla instrukcji przetwarzającej. + + + The name of an extension expression must be in a namespace. + Nazwa dodatkowego wyrażenia musi znajdować sie w przestrzeni nazw. + + + Required type is %1, but %2 was found. + Odnaleziono typ %2, lecz wymaganym typem jest %1. + + + Promoting %1 to %2 may cause loss of precision. + Przekształcenie %1 do %2 może spowodować utratę precyzji. + + + It's not possible to add attributes after any other kind of node. + Dodanie atrybutu poza węzłami nie jest możliwe. + + + Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported. + Obsługiwane jest jedynie "Unicode Codepoint Collation" (%1), %2 nie jest obsługiwane. + + + Integer division (%1) by zero (%2) is undefined. + Dzielenie w dziedzinie liczb całkowitych (%1) przez zero (%2) jest niezdefiniowane. + + + Division (%1) by zero (%2) is undefined. + Dzielenie (%1) przez zero (%2) jest niezdefiniowane. + + + Modulus division (%1) by zero (%2) is undefined. + Dzielenie modulo (%1) przez zero (%2) jest niezdefiniowane. + + + %1 takes at most %n argument(s). %2 is therefore invalid. + + %1 przyjmuje co najwyżej %n argument. %2 jest dlatego niepoprawne. + %1 przyjmuje co najwyżej %n argumenty. %2 jest dlatego niepoprawne. + %1 przyjmuje co najwyżej %n argumentów. %2 jest dlatego niepoprawne. + + + + %1 requires at least %n argument(s). %2 is therefore invalid. + + %1 wymaga przynajmniej %n argumentu. %2 jest dlatego niepoprawne. + %1 wymaga przynajmniej %n argumentów. %2 jest dlatego niepoprawne. + %1 wymaga przynajmniej %n argumentów. %2 jest dlatego niepoprawne. + + + + The root node of the second argument to function %1 must be a document node. %2 is not a document node. + Głównym węzłem drugiego argumentu w funkcji %1 musi być węzeł "document". %2 nie jest węzłem "document". + + + The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) + Przestrzeń nazw dla funkcji zdefiniowanej przez użytkownika nie może być pusta (spróbuj predefiniowany przedrostek %1, który stworzono specjalnie do takich sytuacji) + + + A default namespace declaration must occur before function, variable, and option declarations. + Domyślna deklaracja przestrzeni nazw musi pojawić się przed deklaracjami funkcji, zmiennych i opcji. + + + Namespace declarations must occur before function, variable, and option declarations. + Deklaracje przestrzeni nazw muszą pojawić się przed deklaracjami funkcji, zmiennych i opcji. + + + Module imports must occur before function, variable, and option declarations. + Importy modułów muszą pojawić się przed deklaracjami funkcji, zmiennych i opcji. + + + %1 is not a whole number of minutes. + %1 nie jest całkowitą liczbą minut. + + + Attribute %1 can't be serialized because it appears at the top level. + Atrybut %1 nie może być zserializowany ponieważ pojawił się na najwyższym poziomie. + + + %1 is an unsupported encoding. + Nieobsługiwane kodowanie %1. + + + %1 contains octets which are disallowed in the requested encoding %2. + + + + The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character. + Kod %1 który pojawił się w %2 i który używa kodowania %3 jest niepoprawnym znakiem XML. + + + Ambiguous rule match. + Dopasowano niejednoznaczną regułę. + + + In a namespace constructor, the value for a namespace cannot be an empty string. + W konstruktorze przestrzeni nazw wartość przestrzeni nazw nie może być pustym ciągiem. + + + The prefix must be a valid %1, which %2 is not. + Przedrostek musi być poprawnym %1, którym %2 nie jest. + + + The prefix %1 cannot be bound. + Przedrostek %1 nie może być powiązany. + + + Only the prefix %1 can be bound to %2 and vice versa. + Tylko przedrostek %1 może być powiązany z %2 i vice versa. + + + The parameter %1 is required, but no corresponding %2 is supplied. + Wymagany jest parametr %1 lecz żaden odpowiadający mu %2 nie został dostarczony. + + + The parameter %1 is passed, but no corresponding %2 exists. + Przekazany jest parametr %1 lecz żaden odpowiadający mu %2 nie istnieje. + + + The URI cannot have a fragment + URI nie może posiadać fragmentu + + + Element %1 is not allowed at this location. + Element %1 jest niedozwolony w tym miejscu. + + + Text nodes are not allowed at this location. + Węzły tekstowe są niedozwolone w tym miejscu. + + + Parse error: %1 + Błąd parsowania: %1 + + + The value of the XSL-T version attribute must be a value of type %1, which %2 isn't. + Wartość atrybutu wersji XSL-T musi być typu %1, którym %2 nie jest. + + + Running an XSL-T 1.0 stylesheet with a 2.0 processor. + Przetwarzanie arkusza XSL-T w wersji 1.0 przez procesor w wersji 2.0. + + + Unknown XSL-T attribute %1. + Nieznany atrybut %1 XSL-T. + + + Attribute %1 and %2 are mutually exclusive. + Atrybuty %1 i %2 wzajemnie się wykluczającą. + + + In a simplified stylesheet module, attribute %1 must be present. + W uproszczonym module arkuszu stylu musi wystąpić atrybut %1. + + + If element %1 has no attribute %2, it cannot have attribute %3 or %4. + Jeśli element %1 nie posiada atrybutu %2, nie może on również posiadać atrybutu %3 ani %4. + + + Element %1 must have at least one of the attributes %2 or %3. + Element %1 musi posiadać przynajmniej jeden z atrybutów: %2 lub %3. + + + At least one mode must be specified in the %1-attribute on element %2. + Przynajmniej jeden tryb musi być podany w atrybucie %1 elementu %2. + + + Element %1 must come last. + Element %1 musi wystąpić jako ostatni. + + + At least one %1-element must occur before %2. + Przynajmniej jeden element %1 musi wystąpić przed %2. + + + Only one %1-element can appear. + Może wystąpić tylko jeden element %1. + + + At least one %1-element must occur inside %2. + Przynajmniej jeden element %1 musi wystąpić wewnątrz %2. + + + When attribute %1 is present on %2, a sequence constructor cannot be used. + Kiedy atrybut %1 występuje w %2 konstruktor sekwencyjny nie może być użyty. + + + Element %1 must have either a %2-attribute or a sequence constructor. + Element %1 musi posiadać albo atrybut %2 albo sekwencyjny konstruktor. + + + When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor. + Kiedy wymagany jest parametr, domyślna wartość nie może być dostarczona przez atrybut %1 ani przez sekwencyjny konstruktor. + + + Element %1 cannot have children. + Element %1 nie może posiadać potomków. + + + Element %1 cannot have a sequence constructor. + Element %1 nie może posiadać sekwencyjnego konstruktora. + + + The attribute %1 cannot appear on %2, when it is a child of %3. + Atrybut %1 nie może wystąpić w %2 kiedy jest on potomkiem %3. + + + A parameter in a function cannot be declared to be a tunnel. + Parametr funkcji nie może być zadeklarowany jako tunelowy. + + + This processor is not Schema-aware and therefore %1 cannot be used. + Procesor nie obsługuje schematów, więc %1 nie może zostać użyte. + + + Top level stylesheet elements must be in a non-null namespace, which %1 isn't. + Elementy arkusza stylu najwyższego poziomu muszą być w niezerowej przestrzeni nazw, którą %1 nie jest. + + + The value for attribute %1 on element %2 must either be %3 or %4, not %5. + Wartością atrybutu %1 w elemencie %2 musi być %3 albo %4, lecz nie %5. + + + Attribute %1 cannot have the value %2. + Atrybut %1 nie może posiadać wartości %2. + + + The attribute %1 can only appear on the first %2 element. + Atrybut %1 może wystąpić jedynie w pierwszym elemencie %2. + + + At least one %1 element must appear as child of %2. + Przynajmniej jeden element %1 musi wystąpić jako potomek %2. + + + %1 has inheritance loop in its base type %2. + %1 ma pętlę w dziedziczeniu w jego podstawowym typie %2. + + + Circular inheritance of base type %1. + Cykliczne dziedziczenie podstawowego typu %1. + + + Circular inheritance of union %1. + Cykliczne dziedziczenie unii %1. + + + %1 is not allowed to derive from %2 by restriction as the latter defines it as final. + Nie można wywieść %1 z %2 ograniczając go ponieważ jest on zdefiniowany jako końcowy. + + + %1 is not allowed to derive from %2 by extension as the latter defines it as final. + Nie można wywieść %1 z %2 rozszerzając go ponieważ jest on zdefiniowany jako końcowy. + + + Base type of simple type %1 cannot be complex type %2. + Typ podstawowy dla typu prostego %1 nie może być typem złożonym %2. + + + Simple type %1 cannot have direct base type %2. + Typ prosty %1 nie może mieć bezpośredniego typu podstawowego %2. + + + Simple type %1 is not allowed to have base type %2. + Typ prosty %1 nie może mieć typu podstawowego %2. + + + Simple type %1 can only have simple atomic type as base type. + Typem podstawowym typu prostego %1 może być tylko typ atomowy. + + + Simple type %1 cannot derive from %2 as the latter defines restriction as final. + Typ prosty %1 nie może wywodzić się z %2 ponieważ ten ostatni jest zdefiniowany jako końcowy. + + + Variety of item type of %1 must be either atomic or union. + Typem elementów listy %1 musi być albo typ atomowy albo unia. + + + Variety of member types of %1 must be atomic. + Typy składników %1 muszą być atomowe. + + + %1 is not allowed to derive from %2 by list as the latter defines it as final. + Nie można wywieść %1 z %2 poprzez listę ponieważ jest to zdefiniowane ostatecznie w typie podstawowym. + + + Simple type %1 is only allowed to have %2 facet. + Typ prosty %1 może jedynie posiadać aspekt %2. + + + Base type of simple type %1 must have variety of type list. + Typ podstawowy dla typu prostego %1 musi być listą typów. + + + Base type of simple type %1 has defined derivation by restriction as final. + Typ podstawowy dla typu prostego %1 ma zdefiniowane wywodzenie poprzez ograniczenie jako końcowe. + + + Item type of base type does not match item type of %1. + Typ elementów listy typu podstawowego nie pasuje do typu elementów listy %1. + + + Simple type %1 contains not allowed facet type %2. + Typ prosty %1 posiada niedozwolony aspekt %2. + + + %1 is not allowed to derive from %2 by union as the latter defines it as final. + Nie można wywieść %1 z %2 poprzez unię ponieważ jest to zdefiniowane ostatecznie w typie podstawowym. + + + %1 is not allowed to have any facets. + %1 nie może posiadać żadnych aspektów. + + + Base type %1 of simple type %2 must have variety of union. + Typ podstawowy %1 dla typu prostego %2 musi być unią. + + + Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute. + Typ podstawowy %1 dla typu prostego %2 nie może posiadać ograniczenia dla atrybutu %3. + + + Member type %1 cannot be derived from member type %2 of %3's base type %4. + Typ %1 składnika nie może być wywiedziony z typu %2 który jest typem składnika %3 typu podstawowego %4. + + + Derivation method of %1 must be extension because the base type %2 is a simple type. + Metodą wywodzenia z %1 musi być rozszerzenie ponieważ typ podstawowy %2 jest typem prostym. + + + Complex type %1 has duplicated element %2 in its content model. + Typ złożony %1 posiada powielony element %2 w jego modelu zawartości. + + + Complex type %1 has non-deterministic content. + Typ złożony %1 posiada nieokreśloną zawartość. + + + Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3. + Atrybuty typu złożonego %1 nie są poprawnym rozszerzeniem atrybutów typu podstawowego %2: %3. + + + Content model of complex type %1 is not a valid extension of content model of %2. + Model zawartości typu złożonego %1 nie jest poprawnym rozszerzeniem modelu zawartości %2. + + + Complex type %1 must have simple content. + Typ złożony %1 musi mieć prostą zawartość. + + + Complex type %1 must have the same simple type as its base class %2. + Typ złożony %1 musi posiadać ten sam prosty typ jaki posiada jego klasa podstawowa %2. + + + Complex type %1 cannot be derived from base type %2%3. + Typ złożony %1 nie może być wywiedziony z typu %2%3. + + + Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3. + Atrybuty typu złożonego %1 nie są poprawnym ograniczeniem atrybutów typu podstawowego %2: %3. + + + Complex type %1 with simple content cannot be derived from complex base type %2. + Typ złożony %1 z prostą zawartością nie może być wywiedziony z podstawowego typu złożonego %2. + + + Item type of simple type %1 cannot be a complex type. + Typ elementów listy w prostym typie %1 nie może być typem złożonym. + + + Member type of simple type %1 cannot be a complex type. + Typ składnika typu prostego %1 nie może być typem złożonym. + + + %1 is not allowed to have a member type with the same name as itself. + %1 nie może posiadać typu składnika o tej samej nazwie jaką on sam posiada. + + + %1 facet collides with %2 facet. + + + + %1 facet must have the same value as %2 facet of base type. + Aspekt %1 musi mieć tą samą wartość jaką ma aspekt %2 typu podstawowego. + + + %1 facet must be equal or greater than %2 facet of base type. + Wartość aspektu %1 musi większa od lub równa wartości aspektu %2 typu podstawowego. + + + %1 facet must be less than or equal to %2 facet of base type. + Wartość aspektu %1 musi być mniejsza od lub równa wartości aspektu %2 typu podstawowego. + + + %1 facet contains invalid regular expression + Aspekt %1 zawiera niepoprawne wyrażenie regularne + + + Unknown notation %1 used in %2 facet. + Nieznany zapis %1 użyty w aspekcie %2. + + + %1 facet contains invalid value %2: %3. + Aspekt %1 zawiera niepoprawną wartość %2: %3. + + + %1 facet cannot be %2 or %3 if %4 facet of base type is %5. + + + + %1 facet cannot be %2 if %3 facet of base type is %4. + + + + %1 facet must be less than or equal to %2 facet. + Wartość aspektu %1 musi być mniejsza od lub równa wartości aspektu %2. + + + %1 facet must be less than %2 facet of base type. + Wartość aspektu %1 musi być mniejsza od wartości aspektu %2 typu podstawowego. + + + %1 facet and %2 facet cannot appear together. + + + + %1 facet must be greater than %2 facet of base type. + Wartość aspektu %1 musi być większa od wartości aspektu %2 typu podstawowego. + + + %1 facet must be less than %2 facet. + Wartość aspektu %1 musi być mniejsza od wartości aspektu %2. + + + %1 facet must be greater than or equal to %2 facet of base type. + Wartość aspektu %1 musi być większa od lub równa wartości aspektu %2 typu podstawowego. + + + Simple type contains not allowed facet %1. + Typ prosty zawiera niedozwolony aspekt %1. + + + %1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list. + + + + Only %1 and %2 facets are allowed when derived by union. + Dozwolone są jedynie aspekty %1 i %2 podczas wywodzenia z unii. + + + %1 contains %2 facet with invalid data: %3. + + + + Attribute group %1 contains attribute %2 twice. + Grupa atrybutów %1 zawiera dwukrotnie atrybut %2. + + + Attribute group %1 contains two different attributes that both have types derived from %2. + Grupa atrybutów %1 zawiera dwa różne atrybuty których typy są wywiedzione z %2. + + + Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3. + Grupa atrybutów %1 zawiera atrybut %2 który ma ograniczenie wartości ale typ wywodzi się z %3. + + + Complex type %1 contains attribute %2 twice. + Typ złożony %1 zawiera atrybut %2 dwukrotnie. + + + Complex type %1 contains two different attributes that both have types derived from %2. + Typ złożony %1 zawiera dwa różne atrybuty których typy są wywiedzione z %2. + + + Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3. + Typ złożony %1 zawiera atrybut %2 który ma ograniczenie wartości ale typ wywodzi się z %3. + + + Element %1 is not allowed to have a value constraint if its base type is complex. + Element %1 nie może zawierać ograniczenia wartości gdy jego typ podstawowy jest złożony. + + + Element %1 is not allowed to have a value constraint if its type is derived from %2. + Element %1 nie może zawierać ograniczenia wartości gdy jego typ jest wywiedziony z %2. + + + Value constraint of element %1 is not of elements type: %2. + Ograniczenie wartości elementu %1 nie jest typu: %2. + + + Element %1 is not allowed to have substitution group affiliation as it is no global element. + Element %1 nie może przynależeć do grupy zastępującej ponieważ nie jest on elementem globalnym. + + + Type of element %1 cannot be derived from type of substitution group affiliation. + Typ elementu %1 nie może być wywiedziony z typu przynależnego do grupy zastępującej. + + + Value constraint of attribute %1 is not of attributes type: %2. + Ograniczenie wartości atrybutu %1 nie jest typu: %2. + + + Attribute %1 has value constraint but has type derived from %2. + Atrybut %1 posiada ograniczenie wartości lecz jego typ wywodzi się z %2. + + + %1 attribute in derived complex type must be %2 like in base type. + + + + Attribute %1 in derived complex type must have %2 value constraint like in base type. + Atrybut %1 w wywiedzionym typie złożonym musi zawierać ograniczenie wartości %2 jak w typie podstawowym. + + + Attribute %1 in derived complex type must have the same %2 value constraint like in base type. + Atrybut %1 w wywiedzionym typie złożonym musi zawierać te same ograniczenie wartości %2 jak w typie podstawowym. + + + Attribute %1 in derived complex type must have %2 value constraint. + Atrybut %1 w wywiedzionym typie złożonym musi zawierać ograniczenie wartości %2. + + + processContent of base wildcard must be weaker than derived wildcard. + "processContent" podstawowego dżokera musi być słabszy od wywiedzionego dżokera. + + + Element %1 exists twice with different types. + Istnieją dwa elementy %1 o różnych typach. + + + Particle contains non-deterministic wildcards. + Element zawiera nieokreślone dżokery. + + + Base attribute %1 is required but derived attribute is not. + Wymagany jest bazowy atrybut %1, wywiedziony zaś nie. + + + Type of derived attribute %1 cannot be validly derived from type of base attribute. + Typ wywiedzionego atrybutu %1 nie może być poprawnie wywiedziony z typu podstawowego atrybutu. + + + Value constraint of derived attribute %1 does not match value constraint of base attribute. + Ograniczenie wartości wywiedzionego atrybutu %1 nie pasuje do ograniczenia wartości podstawowego atrybutu. + + + Derived attribute %1 does not exist in the base definition. + Wywiedziony atrybut %1 nie istnieje w podstawowej definicji. + + + Derived attribute %1 does not match the wildcard in the base definition. + Wywiedziony atrybut %1 nie pasuje do dżokera w podstawowej definicji. + + + Base attribute %1 is required but missing in derived definition. + Brak wymaganego bazowego atrybutu %1 w wywiedzionej definicji. + + + Derived definition contains an %1 element that does not exists in the base definition + Wywiedziona definicja zawiera element %1 który nie istnieje w definicji podstawowej + + + Derived wildcard is not a subset of the base wildcard. + Wywiedziony dżoker nie jest podzbiorem podstawowego dżokera. + + + %1 of derived wildcard is not a valid restriction of %2 of base wildcard + %1 wywiedzionego dżokera nie jest poprawnym ograniczeniem %2 podstawowego dżokera + + + Attribute %1 from base type is missing in derived type. + Brak atrybutu %1 typu bazowego w wywiedzionej definicji. + + + Type of derived attribute %1 differs from type of base attribute. + Typ wywiedzionego atrybutu %1 różni się od typu podstawowego atrybutu. + + + Base definition contains an %1 element that is missing in the derived definition + Podstawowa definicja zawiera element %1 którego brakuje w wywiedzionej definicji + + + %1 references unknown %2 or %3 element %4. + %1 odwołuje się do nieznanego elementu %2 lub %3: %4. + + + %1 references identity constraint %2 that is no %3 or %4 element. + %1 odwołuje się do narzucenia niepowtarzalności %2 które nie jest elementem %3 ani %4. + + + %1 has a different number of fields from the identity constraint %2 that it references. + %1 posiada inna liczbę pól od narzucenia niepowtarzalności %2 które się do niego odwołuje. + + + Base type %1 of %2 element cannot be resolved. + Nie można rozwiązać typu podstawowego %1 elementu %2. + + + Item type %1 of %2 element cannot be resolved. + Nie można rozwiązać typu elementów listy %1 w elemencie %2. + + + Member type %1 of %2 element cannot be resolved. + Nie można rozwiązać typu %1 składnika elementu %2. + + + Type %1 of %2 element cannot be resolved. + Nie można rozwiązać typu %1 elementu %2. + + + Base type %1 of complex type cannot be resolved. + Nie można rozwiązać typu podstawowego %1 dla typu złożonego. + + + %1 cannot have complex base type that has a %2. + + + + Content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type. + Model zawartości typu złożonego %1 posiada element %2 więc nie może być on wywiedziony poprzez rozszerzenie niepustego typu. + + + Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model. + Typ złożony %1 nie może być wywiedziony z %2 poprzez rozszerzenie ponieważ ten ostatni zawiera element %3 w jego modelu zawartości. + + + Type of %1 element must be a simple type, %2 is not. + Typem elementu %1 musi być typ prosty, %2 nim nie jest. + + + Substitution group %1 of %2 element cannot be resolved. + Nie można rozwiązać grupy zastępującej %1 elementu %2. + + + Substitution group %1 has circular definition. + Grupa zastępująca %1 posiada cykliczną definicję. + + + Duplicated element names %1 in %2 element. + Powielona nazwa elementu %1 w elemencie %2. + + + Reference %1 of %2 element cannot be resolved. + Nie można rozwiązać odwołania %1 do elementu %2. + + + Circular group reference for %1. + Cykliczne odwołanie do grupy dla %1. + + + %1 element is not allowed in this scope + + + + %1 element cannot have %2 attribute with value other than %3. + + + + %1 element cannot have %2 attribute with value other than %3 or %4. + + + + %1 or %2 attribute of reference %3 does not match with the attribute declaration %4. + Atrybut %1 lub %2 odwołania %3 nie pasuje do deklaracji atrybutu %4. + + + Attribute group %1 has circular reference. + Grupa atrybutów %1 posiada cykliczne odwołanie. + + + %1 attribute in %2 must have %3 use like in base type %4. + + + + Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2. + Atrybut dżokera %1 nie jest poprawnym ograniczeniem atrybutu dżokera typu podstawowego %2. + + + %1 has attribute wildcard but its base type %2 has not. + %1 posiada atrybut dżokera lecz jego typ podstawowy %2 go nie posiada. + + + Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible. + Nie można wyrazić unii atrybutu dżokera typu %1 i atrybutu dżokera jego typu podstawowego %2. + + + Enumeration facet contains invalid content: {%1} is not a value of type %2. + Aspekt "enumeration" posiada niepoprawną zawartość: {%1} nie jest wartością typu %2. + + + Namespace prefix of qualified name %1 is not defined. + Przedrostek przestrzeni nazw występujący w pełnej nazwie %1 nie jest zdefiniowany. + + + %1 element %2 is not a valid restriction of the %3 element it redefines: %4. + + + + Empty particle cannot be derived from non-empty particle. + Pusty element nie może być wywiedziony z niepustego elementu. + + + Derived particle is missing element %1. + Brak elementu %1 w wywiedzionym elemencie. + + + Derived element %1 is missing value constraint as defined in base particle. + Brak ograniczenia wartości w wywiedzionym elemencie %1 takiego jak w podstawowym elemencie. + + + Derived element %1 has weaker value constraint than base particle. + Wywiedziony element %1 posiada słabsze ograniczenie wartości niż element podstawowy. + + + Fixed value constraint of element %1 differs from value constraint in base particle. + Ograniczenie stałej wartości elementu %1 różni się od ograniczenia wartości w podstawowym elemencie. + + + Derived element %1 cannot be nillable as base element is not nillable. + Wywiedziony element %1 może być zerowalny ponieważ element podstawowy nie jest zerowalny. + + + Block constraints of derived element %1 must not be more weaker than in the base element. + Ograniczenia blokujące dla wywiedzionego elementu %1 nie mogą być słabsze od ograniczeń w elemencie podstawowym. + + + Simple type of derived element %1 cannot be validly derived from base element. + Typ prosty w elemencie wywiedzionym %1 nie może być poprawnie wywiedziony z elementu podstawowego. + + + Complex type of derived element %1 cannot be validly derived from base element. + Typ złożony w elemencie wywiedzionym %1 nie może być poprawnie wywiedziony z elementu podstawowego. + + + Element %1 is missing in derived particle. + Brak elementu %1 w wywiedzionym elemencie. + + + Element %1 does not match namespace constraint of wildcard in base particle. + Element %1 nie pasuje do ograniczenia przestrzeni nazw dżokera w elemencie podstawowym. + + + Wildcard in derived particle is not a valid subset of wildcard in base particle. + Dżoker w wywiedzionym elemencie nie jest poprawnym podzbiorem dżokera w elemencie podstawowym. + + + processContent of wildcard in derived particle is weaker than wildcard in base particle. + "processContent" dżokera w wywiedzionym elemencie jest słabszy od dżokera w podstawowym elemencie. + + + Derived particle allows content that is not allowed in the base particle. + Wywiedziony element pozwala na zawartość która jest niedozwolona w podstawowym elemencie. + + + Can not process unknown element %1, expected elements are: %2. + Nie można przetworzyć nieznanego elementu %1, spodziewanymi elementami są: %2. + + + Element %1 is not allowed in this scope, possible elements are: %2. + Element %1 jest niedozwolony w tym zakresie, możliwymi elementami są: %2. + + + Child element is missing in that scope, possible child elements are: %1. + Brak podelementu w tym zakresie, możliwymi podelementami są: %1. + + + Document is not a XML schema. + Dokument nie jest schematem XML. + + + %1 attribute of %2 element contains invalid content: {%3} is not a value of type %4. + + + + %1 attribute of %2 element contains invalid content: {%3}. + + + + Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema. + Docelowa przestrzeń nazw %1 załączonego schematu jest różna od docelowej przestrzeni nazw %2 która jest zdefiniowana w schemacie załączającym. + + + Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema. + Docelowa przestrzeń nazw %1 zaimportowanego schematu jest różna od docelowej przestrzeni nazw %2 która jest zdefiniowana w schemacie importującym. + + + %1 element is not allowed to have the same %2 attribute value as the target namespace %3. + + + + %1 element without %2 attribute is not allowed inside schema without target namespace. + + + + %1 element is not allowed inside %2 element if %3 attribute is present. + + + + %1 element has neither %2 attribute nor %3 child element. + + + + %1 element with %2 child element must not have a %3 attribute. + + + + %1 attribute of %2 element must be %3 or %4. + + + + %1 attribute of %2 element must have a value of %3. + + + + %1 attribute of %2 element must have a value of %3 or %4. + + + + %1 element must not have %2 and %3 attribute together. + + + + Content of %1 attribute of %2 element must not be from namespace %3. + Zawartość atrybutu %1 elementu %2 nie może pochodzić z przestrzeni nazw %3. + + + %1 attribute of %2 element must not be %3. + + + + %1 attribute of %2 element must have the value %3 because the %4 attribute is set. + + + + Specifying use='prohibited' inside an attribute group has no effect. + Podawanie: use='prohibited' wewnątrz grupy atrybutów nie przynosi żadnego efektu. + + + %1 element must have either %2 or %3 attribute. + + + + %1 element must have either %2 attribute or %3 or %4 as child element. + + + + %1 element requires either %2 or %3 attribute. + + + + Text or entity references not allowed inside %1 element + Tekst ani odwołanie nie są dozwolone wewnątrz elementu %1 + + + %1 attribute of %2 element must contain %3, %4 or a list of URIs. + + + + %1 element is not allowed in this context. + + + + %1 attribute of %2 element has larger value than %3 attribute. + + + + Prefix of qualified name %1 is not defined. + Przedrostek w pełnej nazwie %1 nie jest zdefiniowany. + + + %1 attribute of %2 element must either contain %3 or the other values. + + + + Component with ID %1 has been defined previously. + Komponent o identyfikatorze %1 został uprzednio zdefiniowany. + + + Element %1 already defined. + Element %1 jest już zdefiniowany. + + + Attribute %1 already defined. + Atrybut %1 jest już zdefiniowany. + + + Type %1 already defined. + Typ %1 jest już zdefiniowany. + + + Attribute group %1 already defined. + Grupa atrybutów %1 jest już zdefiniowana. + + + Element group %1 already defined. + Grupa elementów %1 jest już zdefiniowana. + + + Notation %1 already defined. + Zapis %1 jest już zdefiniowany. + + + Identity constraint %1 already defined. + Narzucenie niepowtarzalności %1 jest już zdefiniowane. + + + Duplicated facets in simple type %1. + Powielone aspekty w prostym typie %1. + + + %1 is not valid according to %2. + %1 nie jest poprawne według %2. + + + String content does not match the length facet. + Wartość ciągu koliduje z aspektem "length". + + + String content does not match the minLength facet. + Wartość ciągu koliduje z aspektem "minLength". + + + String content does not match the maxLength facet. + Wartość ciągu koliduje z aspektem "maxLength". + + + String content does not match pattern facet. + Wartość ciągu koliduje z aspektem "pattern". + + + String content is not listed in the enumeration facet. + Wartość ciągu nie widnieje na liście aspektu "enumeration". + + + Signed integer content does not match the maxInclusive facet. + Wartość liczby całkowitej koliduje z aspektem "maxInclusive". + + + Signed integer content does not match the maxExclusive facet. + Wartość liczby całkowitej koliduje z aspektem "maxExclusive". + + + Signed integer content does not match the minInclusive facet. + Wartość liczby całkowitej koliduje z aspektem "minInclusive". + + + Signed integer content does not match the minExclusive facet. + Wartość liczby całkowitej koliduje z aspektem "minExclusive". + + + Signed integer content is not listed in the enumeration facet. + Wartość liczby całkowitej nie widnieje na liście aspektu "enumeration". + + + Signed integer content does not match pattern facet. + Wartość liczby całkowitej koliduje z aspektem "pattern". + + + Signed integer content does not match in the totalDigits facet. + Wartość liczby całkowitej koliduje z aspektem "totalDigits". + + + Unsigned integer content does not match the maxInclusive facet. + Wartość liczby naturalnej koliduje z aspektem "maxInclusive". + + + Unsigned integer content does not match the maxExclusive facet. + Wartość liczby naturalnej koliduje z aspektem "maxExclusive". + + + Unsigned integer content does not match the minInclusive facet. + Wartość liczby naturalnej koliduje z aspektem "minInclusive". + + + Unsigned integer content does not match the minExclusive facet. + Wartość liczby naturalnej koliduje z aspektem "minExclusive". + + + Unsigned integer content is not listed in the enumeration facet. + Wartość liczby naturalnej nie widnieje na liście aspektu "enumeration". + + + Unsigned integer content does not match pattern facet. + Wartość liczby naturalnej koliduje z aspektem "pattern". + + + Unsigned integer content does not match in the totalDigits facet. + Wartość liczby naturalnej koliduje z aspektem "totalDigits". + + + Double content does not match the maxInclusive facet. + Wartość liczby rzeczywistej koliduje z aspektem "maxInclusive". + + + Double content does not match the maxExclusive facet. + Wartość liczby rzeczywistej koliduje z aspektem "maxExclusive". + + + Double content does not match the minInclusive facet. + Wartość liczby rzeczywistej koliduje z aspektem "minInclusive". + + + Double content does not match the minExclusive facet. + Wartość liczby rzeczywistej koliduje z aspektem "minExclusive". + + + Double content is not listed in the enumeration facet. + Wartość liczby rzeczywistej nie widnieje na liście aspektu "enumeration". + + + Double content does not match pattern facet. + Wartość liczby rzeczywistej koliduje z aspektem "pattern". + + + Decimal content does not match in the fractionDigits facet. + Wartość liczby rzeczywistej koliduje z aspektem "fractionDigits". + + + Decimal content does not match in the totalDigits facet. + Wartość liczby rzeczywistej koliduje z aspektem "totalDigits". + + + Date time content does not match the maxInclusive facet. + Zawartość daty i czasu koliduje z aspektem "maxInclusive". + + + Date time content does not match the maxExclusive facet. + Zawartość daty i czasu koliduje z aspektem "maxExclusive". + + + Date time content does not match the minInclusive facet. + Zawartość daty i czasu koliduje z aspektem "minInclusive". + + + Date time content does not match the minExclusive facet. + Zawartość daty i czasu koliduje z aspektem "minExclusive". + + + Date time content is not listed in the enumeration facet. + Zawartość daty i czasu nie widnieje na liście aspektu "enumeration". + + + Date time content does not match pattern facet. + Zawartość daty i czasu koliduje z aspektem "pattern". + + + Duration content does not match the maxInclusive facet. + Wartość długości okresu czasu koliduje z aspektem "maxInclusive". + + + Duration content does not match the maxExclusive facet. + Wartość długości okresu czasu koliduje z aspektem "maxExclusive". + + + Duration content does not match the minInclusive facet. + Wartość długości okresu czasu koliduje z aspektem "minInclusive". + + + Duration content does not match the minExclusive facet. + Wartość długości okresu czasu koliduje z aspektem "minExclusive". + + + Duration content is not listed in the enumeration facet. + Wartość długości okresu czasu nie widnieje na liście aspektu "enumeration". + + + Duration content does not match pattern facet. + Wartość długości okresu czasu koliduje z aspektem "pattern". + + + Boolean content does not match pattern facet. + Wartość boolowska koliduje z aspektem "pattern". + + + Binary content does not match the length facet. + Wartość binarna koliduje z aspektem "length". + + + Binary content does not match the minLength facet. + Wartość binarna koliduje z aspektem "minLength". + + + Binary content does not match the maxLength facet. + Wartość binarna koliduje z aspektem "maxLength". + + + Binary content is not listed in the enumeration facet. + Wartość binarna nie widnieje na liście aspektu "enumeration". + + + Invalid QName content: %1. + Niepoprawna zawartość QName: %1. + + + QName content is not listed in the enumeration facet. + Zawartość QName nie widnieje na liście aspektu "enumeration". + + + QName content does not match pattern facet. + Zawartość QName koliduje z aspektem "pattern". + + + Notation content is not listed in the enumeration facet. + Zapis zawartości nie widnieje na liście aspektu "enumeration". + + + List content does not match length facet. + Zawartość listy koliduje z aspektem "length". + + + List content does not match minLength facet. + Zawartość listy koliduje z aspektem "minLength". + + + List content does not match maxLength facet. + Zawartość listy koliduje z aspektem "maxLength". + + + List content is not listed in the enumeration facet. + Zawartość listy nie widnieje na liście aspektu "enumeration". + + + List content does not match pattern facet. + Zawartość listy koliduje z aspektem "pattern". + + + Union content is not listed in the enumeration facet. + Zawartość unii nie widnieje na liście aspektu "enumeration". + + + Union content does not match pattern facet. + Zawartość unii koliduje z aspektem "pattern". + + + Data of type %1 are not allowed to be empty. + Dane typu %1 nie mogą być puste. + + + Element %1 is missing child element. + Brak wymaganego podelementu w elemencie %1. + + + There is one IDREF value with no corresponding ID: %1. + Istnieje wartość IDREF bez odpowiadającej jej wartości ID: %1. + + + Loaded schema file is invalid. + Załadowany plik nie jest poprawnym plikiem ze schematem. + + + %1 contains invalid data. + + + + xsi:schemaLocation namespace %1 has already appeared earlier in the instance document. + Przestrzeń nazw "xsi:schemaLocation" %1 wystąpiła już wcześniej w dokumencie. + + + xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute. + "xsi:noNamespaceSchemaLocation" nie może wystąpić po pierwszym elemencie lub atrybucie który nie jest przestrzenią nazw. + + + No schema defined for validation. + Brak zdefiniowanego schematu dla walidacji. + + + No definition for element %1 available. + Brak dostępnej definicji dla elementu %1. + + + Specified type %1 is not known to the schema. + Podany typ %1 nie jest schematowi znany. + + + Element %1 is not defined in this scope. + Element %1 nie jest zdefiniowany w tym zakresie. + + + Declaration for element %1 does not exist. + Brak deklaracji dla elementu %1. + + + Element %1 contains invalid content. + Element %1 posiada niepoprawną zawartość. + + + Element %1 is declared as abstract. + Element %1 jest zadeklarowany jako abstrakcyjny. + + + Element %1 is not nillable. + Element %1 nie jest zerowalny. + + + Attribute %1 contains invalid data: %2 + Atrybut %1 zawiera niepoprawne dane: %2 + + + Element contains content although it is nillable. + Element posiada zawartość chociaż jest zerowalny. + + + Fixed value constraint not allowed if element is nillable. + Ograniczenie stałej wartości jest niedozwolone gdy element jest zerowalny. + + + Element %1 cannot contain other elements, as it has a fixed content. + Element %1 nie może zawierać innych elementów ponieważ posiada on stałą zawartość. + + + Specified type %1 is not validly substitutable with element type %2. + Podany typ %1 nie jest poprawnie zastępowalny typem elementu %2. + + + Complex type %1 is not allowed to be abstract. + Typ złożony %1 nie może być abstrakcyjny. + + + Element %1 contains not allowed attributes. + Element %1 zawiera niedozwolone atrybuty. + + + Element %1 contains not allowed child element. + Element %1 zawiera niedozwolony podelement. + + + Content of element %1 does not match its type definition: %2. + Zawartość elementu %1 nie pasuje do jego definicji typu: %2. + + + Content of element %1 does not match defined value constraint. + Zawartość elementu %1 nie pasuje do zdefiniowanego ograniczenia wartości. + + + Element %1 contains not allowed child content. + Element %1 zawiera niedozwolony podelement. + + + Element %1 contains not allowed text content. + Element %1 zawiera niedozwolony text. + + + Element %1 is missing required attribute %2. + Brak wymaganego atrybutu %2 w elemencie %1. + + + Attribute %1 does not match the attribute wildcard. + Atrybut %1 nie pasuje do atrybutu dżokera. + + + Declaration for attribute %1 does not exist. + Brak deklaracji atrybutu %1. + + + Element %1 contains two attributes of type %2. + Element %1 posiada dwa atrybuty typu %2. + + + Attribute %1 contains invalid content. + Atrybut %1 posiada niepoprawną zawartość. + + + Element %1 contains unknown attribute %2. + Element %1 posiada nieznany atrybut %2. + + + Content of attribute %1 does not match its type definition: %2. + Zawartość atrybutu %1 nie pasuje do jego definicji typu: %2. + + + Content of attribute %1 does not match defined value constraint. + Zawartość elementu %1 nie pasuje do zdefiniowanego ograniczenia wartości. + + + Non-unique value found for constraint %1. + Znaleziono nieunikatową wartość dla ograniczenia %1. + + + Key constraint %1 contains absent fields. + Ograniczenie klucza %1 zawiera nieobecne pola. + + + Key constraint %1 contains references nillable element %2. + + + + No referenced value found for key reference %1. + Brak wartości do której odwołuje się klucz %1. + + + More than one value found for field %1. + Znaleziono więcej niż jedną wartość dla pola %1. + + + Field %1 has no simple type. + Pole %1 nie posiada prostego typu. + + + ID value '%1' is not unique. + Wartość ID "%1" nie jest unikatowa. + + + '%1' attribute contains invalid QName content: %2. + + + + diff --git a/config.profiles/symbian/translations/qt_ru_symbian.ts b/config.profiles/symbian/translations/qt_ru_symbian.ts new file mode 100644 index 0000000..b7e69cb --- /dev/null +++ b/config.profiles/symbian/translations/qt_ru_symbian.ts @@ -0,0 +1,8522 @@ + + + + + + CloseButton + + Close Tab + Закрыть вкладку + + + + FakeReply + + Fake error ! + Ошибка: фальшивый! + + + Invalid URL + Некорректный URL + + + + Phonon:: + + Notifications + Уведомления + + + Music + Музыка + + + Video + Видео + + + Communication + Общение + + + Games + Игры + + + Accessibility + Специальные возможности + + + + Phonon::AudioOutput + + <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> + <html>Звуковое устройство <b>%1</b> не работает.<br/>Будет использоваться <b>%2</b>.</html> + + + <html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html> + <html>Переключение на звуковое устройство <b>%1</b><br/>, которое доступно и имеет высший приоритет.</html> + + + Revert back to device '%1' + Возвращение к устройству '%1' + + + + Phonon::Gstreamer::Backend + + Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. + Some video features have been disabled. + Внимание: Похоже, пакет gstreamer0.10-plugins-good не установлен. + Некоторые возможности воспроизведения видео недоступны. + + + Warning: You do not seem to have the base GStreamer plugins installed. + All audio and video support has been disabled + Внимание: Похоже, основной модуль GStreamer не установлен. + Поддержка видео и аудио отключена + + + + Phonon::Gstreamer::MediaObject + + Cannot start playback. + +Check your GStreamer installation and make sure you +have libgstreamer-plugins-base installed. + + + + A required codec is missing. You need to install the following codec(s) to play this content: %0 + Отсутствует необходимый кодек. Вам нужно установить следующие кодеки для воспроизведения данного содержимого: %0 + + + Could not open media source. + Не удалось открыть источник медиа-данных. + + + Invalid source type. + Неверный тип источника медиа-данных. + + + Could not locate media source. + Не удалось найти источник медиа-данных. + + + Could not open audio device. The device is already in use. + Не удалось открыть звуковое устройство. Устройство уже используется. + + + Could not decode media source. + Не удалось декодировать источник медиа-данных. + + + + Phonon::MMF + + Audio Output + Воспроизведение звука + + + The audio output device + Устройство воспроизведения звука + + + No error + Нет ошибки + + + Not found + Не найдено + + + Out of memory + Недостаточно памяти + + + Not supported + Не поддерживается + + + Overflow + Переполнение + + + Underflow + Потеря значимости + + + Already exists + Уже существует + + + Path not found + Путь не найден + + + In use + Используется + + + Not ready + Не готово + + + Access denied + Доступ запрещен + + + Could not connect + Подключение невозможно + + + Disconnected + Разъединено + + + Permission denied + Отказано в разрешении + + + Insufficient bandwidth + Недостаточная скорость передачи + + + Network unavailable + Сеть недоступна + + + Network communication error + Сетевая ошибка связи + + + Streaming not supported + Потоки не поддерживаются + + + Server alert + Сигнал сервера + + + Invalid protocol + Неверный протокол + + + Invalid URL + Неверный адрес URL + + + Multicast error + Ошибка групповой передачи + + + Proxy server error + Ошибка прокси-сервера + + + Proxy server not supported + Прокси-сервер не поддерживается + + + Audio output error + Ошибка вывода аудио + + + Video output error + Ошибка вывода видео + + + Decoder error + Ошибка декодера + + + Audio or video components could not be played + Невозможно воспроизвести аудио или видеокомпоненты + + + DRM error + Ошибка DRM + + + Unknown error (%1) + Неизвестная ошибка (%1) + + + + Phonon::MMF::AbstractMediaPlayer + + Not ready to play + Не готов к воспроизведению + + + Error opening file + Ошибка при открытии файла + + + Error opening URL + Ошибка при открытии адреса URL + + + Setting volume failed + Сбой при настройке громкости + + + Playback complete + Воспроизведение завершено + + + + Phonon::MMF::AudioEqualizer + + %1 Hz + %1 Гц + + + + Phonon::MMF::AudioPlayer + + Getting position failed + Сбой определения позиции + + + Opening clip failed + Сбой при открытии клипа + + + + Phonon::MMF::EffectFactory + + Enabled + Включено + + + + Phonon::MMF::EnvironmentalReverb + + Decay HF ratio (%) + Коэффициент затухания ВЧ (%) + + + Decay time (ms) + Время затухания (мс) + + + Density (%) + Плотность (%) + + + Diffusion (%) + Рассеяние (%) + + + Reflections delay (ms) + Затухание отражений (мс) + + + Reflections level (mB) + Уровень отражений (Мбит) + + + Reverb delay (ms) + Задержка реверберации (мс) + + + Reverb level (mB) + Уровень реверберации (Мбит) + + + Room HF level + Уровень ВЧ помещения + + + Room level (mB) + Уровень помещения (Мбит) + + + + Phonon::MMF::MediaObject + + Error opening source: type not supported + Ошибка при открытии источника: тип не поддерживается + + + Error opening source: media type could not be determined + Ошибка при открытии источника: тип носителя определить невозможно + + + + Phonon::MMF::StereoWidening + + Level (%) + Уровень (%) + + + + Phonon::MMF::VideoPlayer + + Pause failed + Сбой паузы + + + Seek failed + Сбой при поиске + + + Getting position failed + Сбой определения позиции + + + Opening clip failed + Сбой при открытии клипа + + + Buffering clip failed + Сбой при буферизации клипа + + + Video display error + Ошибка отображения видео + + + + Phonon::VolumeSlider + + Volume: %1% + Громкость: %1% + + + Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1% + Используйте данный ползунок для настройки громкости. Крайнее левое положение соответствует 0%, крайнее правое - %1% + + + Muted + Без звука + + + + Q3Accel + + %1, %2 not defined + %1, %2 не определён + + + Ambiguous %1 not handled + + + + + Q3DataTable + + True + Да + + + False + Нет + + + Insert + Вставить + + + Update + Обновить + + + Delete + Удалить + + + + Q3FileDialog + + Copy or Move a File + Копировать или переместить файл + + + Read: %1 + Чтение: %1 + + + Write: %1 + Запись: %1 + + + Cancel + Отмена + + + All Files (*) + Все файлы (*) + + + Name + Имя + + + Size + Размер + + + Type + Тип + + + Date + Дата + + + Attributes + Атрибуты + + + &OK + &ОК + + + Look &in: + &Папка: + + + File &name: + &Имя файла: + + + File &type: + &Тип файла: + + + Back + Назад + + + One directory up + Вверх на один уровень + + + Create New Folder + Создать папку + + + List View + Список + + + Detail View + Подробный вид + + + Preview File Info + Предпросмотр информации о файле + + + Preview File Contents + Предпросмотр содержимого файла + + + Read-write + Чтение и запись + + + Read-only + Только чтение + + + Write-only + Только запись + + + Inaccessible + Нет доступа + + + Symlink to File + Ссылка на файл + + + Symlink to Directory + Ссылка на каталог + + + Symlink to Special + Ссылка на спецфайл + + + File + Файл + + + Dir + Каталог + + + Special + Спецфайл + + + Open + Открыть + + + Save As + Сохранить как + + + &Open + &Открыть + + + &Save + &Сохранить + + + &Rename + &Переименовать + + + &Delete + &Удалить + + + R&eload + О&бновить + + + Sort by &Name + По &имени + + + Sort by &Size + По &размеру + + + Sort by &Date + По &дате + + + &Unsorted + &Не упорядочивать + + + Sort + Упорядочить + + + Show &hidden files + Показать ск&рытые файлы + + + the file + файл + + + the directory + каталог + + + the symlink + ссылку + + + Delete %1 + Удалить %1 + + + <qt>Are you sure you wish to delete %1 "%2"?</qt> + <qt>Вы действительно хотите удалить %1 "%2"?</qt> + + + &Yes + &Да + + + &No + &Нет + + + New Folder 1 + Новая папка 1 + + + New Folder + Новая папка + + + New Folder %1 + Новая папка %1 + + + Find Directory + Найти каталог + + + Directories + Каталоги + + + Directory: + Каталог: + + + Error + Ошибка + + + %1 +File not found. +Check path and filename. + %1 +Файл не найден. +Проверьте правильность пути и имени файла. + + + All Files (*.*) + Все файлы (*.*) + + + Open + Открыть + + + Select a Directory + Выбрать каталог + + + + Q3LocalFs + + Could not read directory +%1 + Не удалось прочитать каталог +%1 + + + Could not create directory +%1 + Не удалось создать каталог +%1 + + + Could not remove file or directory +%1 + Не удалось удалить файл или каталог +%1 + + + Could not rename +%1 +to +%2 + Не удалось переименовать +%1 +в +%2 + + + Could not open +%1 + Не удалось открыть +%1 + + + Could not write +%1 + Не удалось записать +%1 + + + + Q3MainWindow + + Line up + Выровнять + + + Customize... + Настроить... + + + + Q3NetworkProtocol + + Operation stopped by the user + Операция остановлена пользователем + + + + Q3ProgressDialog + + Cancel + Отмена + + + + Q3TabDialog + + OK + ОК + + + Apply + Применить + + + Help + Справка + + + Defaults + По умолчанию + + + Cancel + Отмена + + + + Q3TextEdit + + &Undo + &Отменить действие + + + &Redo + &Повторить действие + + + Cu&t + &Вырезать + + + &Copy + &Копировать + + + &Paste + В&ставить + + + Clear + Очистить + + + Select All + Выделить всё + + + + Q3TitleBar + + System + Системное меню + + + Restore up + Восстановить + + + Minimize + Свернуть + + + Restore down + Восстановить + + + Maximize + Распахнуть + + + Close + Закрыть + + + Contains commands to manipulate the window + Содержит команды управления окном + + + Puts a minimized window back to normal + Возвращает свёрнутое окно в нормальное состояние + + + Moves the window out of the way + Сворачивает окно + + + Puts a maximized window back to normal + Возвращает распахнутое окно в нормальное состояние + + + Makes the window full screen + Разворачивает окно на весь экран + + + Closes the window + Зыкрывает окно + + + Displays the name of the window and contains controls to manipulate it + Отображает название окна и содержит команды управления им + + + + Q3ToolBar + + More... + Больше... + + + + Q3UrlOperator + + The protocol `%1' is not supported + Протокол '%1' не поддерживается + + + The protocol `%1' does not support listing directories + Протокол '%1' не поддерживает просмотр каталогов + + + The protocol `%1' does not support creating new directories + Протокол '%1' не поддерживает создание каталогов + + + The protocol `%1' does not support removing files or directories + Протокол '%1' не поддерживает удаление файлов или каталогов + + + The protocol `%1' does not support renaming files or directories + Протокол '%1' не поддерживает переименование файлов или каталогов + + + The protocol `%1' does not support getting files + Протокол '%1' не поддерживает доставку файлов + + + The protocol `%1' does not support putting files + Протокол '%1' не поддерживает отправку файлов + + + The protocol `%1' does not support copying or moving files or directories + Протокол '%1' не поддерживает копирование или перемещение файлов или каталогов + + + (unknown) + (неизвестно) + + + + Q3Wizard + + &Cancel + От&мена + + + < &Back + < &Назад + + + &Next > + &Далее > + + + &Finish + &Завершить + + + &Help + &Справка + + + + QAbstractSocket + + Host not found + Узел не найден + + + Connection refused + Отказано в соединении + + + Connection timed out + Время на соединение истекло + + + Operation on socket is not supported + Операция с сокетом не поддерживается + + + Socket operation timed out + Время на операцию с сокетом истекло + + + Socket is not connected + Сокет не подключён + + + Network unreachable + Сеть недоступна + + + + QAbstractSpinBox + + &Step up + Шаг вв&ерх + + + Step &down + Шаг вн&из + + + &Select All + &Выделить всё + + + + QAccessibleButton + + Press + Нажмите + + + + QApplication + + QT_LAYOUT_DIRECTION + Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. + LTR + + + Executable '%1' requires Qt %2, found Qt %3. + Программный модуль '%1' требует Qt %2, найдена версия %3. + + + Incompatible Qt Library Error + Ошибка совместимости библиотеки Qt + + + Activate + Активировать + + + Activates the program's main window + Активирует главное окно программы + + + + QAxSelect + + Select ActiveX Control + Выбор компоненты ActiveX + + + OK + Выбрать + + + &Cancel + От&мена + + + COM &Object: + &Объект COM: + + + + QCheckBox + + Uncheck + Снять отметку + + + Check + Отметить + + + Toggle + Переключить + + + + QColorDialog + + Hu&e: + &Тон: + + + &Sat: + &Нас: + + + &Val: + &Ярк: + + + &Red: + &Красный: + + + &Green: + &Зелёный: + + + Bl&ue: + С&иний: + + + A&lpha channel: + &Альфа-канал: + + + Select Color + Выбор цвета + + + &Basic colors + &Основные цвета + + + &Custom colors + &Пользовательские цвета + + + &Add to Custom Colors + &Добавить к пользовательским цветам + + + + QComboBox + + Open + Открыть + + + False + Нет + + + True + Да + + + Close + Закрыть + + + + QCoreApplication + + %1: key is empty + QSystemSemaphore + %1: пустой ключ + + + %1: unable to make key + QSystemSemaphore + %1: невозможно создать ключ + + + %1: ftok failed + QSystemSemaphore + %1: ошибка ftok + + + %1: already exists + QSystemSemaphore + %1: уже существует + + + %1: does not exist + QSystemSemaphore + %1: не существует + + + %1: out of resources + QSystemSemaphore + %1: недостаточно ресурсов + + + %1: unknown error %2 + QSystemSemaphore + %1: неизвестная ошибка %2 + + + + QDB2Driver + + Unable to connect + Невозможно соединиться + + + Unable to commit transaction + Невозможно завершить транзакцию + + + Unable to rollback transaction + Невозможно отозвать транзакцию + + + Unable to set autocommit + Невозможно установить автозавершение транзакций + + + + QDB2Result + + Unable to execute statement + Невозможно выполнить выражение + + + Unable to prepare statement + Невозможно подготовить выражение + + + Unable to bind variable + Невозможно привязать значение + + + Unable to fetch record %1 + Невозможно получить запись %1 + + + Unable to fetch next + Невозможно получить следующую строку + + + Unable to fetch first + Невозможно получить первую строку + + + + QDateTimeEdit + + AM + AM + + + am + am + + + PM + PM + + + pm + pm + + + + QDial + + QDial + QDial + + + SpeedoMeter + SpeedoMeter + + + SliderHandle + SliderHandle + + + + QDialog + + What's This? + Что это? + + + Done + Готово + + + + QDialogButtonBox + + OK + ОК + + + Save + Сохранить + + + &Save + &Сохранить + + + Open + Открыть + + + Cancel + Отмена + + + &Cancel + От&мена + + + Close + Закрыть + + + &Close + &Закрыть + + + Apply + Применить + + + Reset + Сбросить + + + Help + Справка + + + Don't Save + Не сохранять + + + Discard + Отклонить + + + &Yes + &Да + + + Yes to &All + Да для &всех + + + &No + &Нет + + + N&o to All + Н&ет для всех + + + Save All + Сохранить все + + + Abort + Прервать + + + Retry + Повторить + + + Ignore + Пропустить + + + Restore Defaults + Восстановить значения + + + Close without Saving + Закрыть без сохранения + + + &OK + &ОК + + + + QDirModel + + Name + Имя + + + Size + Размер + + + Kind + Match OS X Finder + Вид + + + Type + All other platforms + Тип + + + Date Modified + Дата изменения + + + + QDockWidget + + Close + Закрыть + + + Dock + Прикрепить + + + Float + Открепить + + + + QDoubleSpinBox + + More + Больше + + + Less + Меньше + + + + QErrorMessage + + &Show this message again + &Показывать это сообщение в дальнейшем + + + &OK + &Закрыть + + + Debug Message: + Отладочное сообщение: + + + Warning: + Предупреждение: + + + Fatal Error: + Критическая ошибка: + + + + QFile + + Destination file exists + Файл существует + + + Will not rename sequential file using block copy + Последовательный файл не будет переименован с использованием поблочного копирования + + + Cannot remove source file + Невозможно удалить исходный файл + + + Cannot open %1 for input + Невозможно открыть %1 для ввода + + + Cannot open for output + Невозможно открыть для вывода + + + Failure to write block + Сбой записи блока + + + Cannot create %1 for output + Невозможно создать %1 для вывода + + + + QFileDialog + + All Files (*) + Все файлы (*) + + + Back + Назад + + + List View + Список + + + Detail View + Подробный вид + + + File + Файл + + + Open + Открыть + + + Save As + Сохранить как + + + &Open + &Открыть + + + &Save + &Сохранить + + + Recent Places + Недавние документы + + + &Rename + &Переименовать + + + &Delete + &Удалить + + + Show &hidden files + Показать ск&рытые файлы + + + New Folder + Новая папка + + + Find Directory + Найти каталог + + + Directories + Каталоги + + + All Files (*.*) + Все файлы (*.*) + + + Directory: + Каталог: + + + %1 already exists. +Do you want to replace it? + %1 уже существует. +Хотите заменить его? + + + %1 +File not found. +Please verify the correct file name was given. + %1 +Файл не найден. +Проверьте правильность указанного имени файла. + + + My Computer + Мой компьютер + + + Parent Directory + Родительский каталог + + + Files of type: + Типы файлов: + + + %1 +Directory not found. +Please verify the correct directory name was given. + %1 +Каталог не найден. +Проверьте правильность указанного имени каталога. + + + '%1' is write protected. +Do you want to delete it anyway? + '%1' защищён от записи. +Всё-равно хотите удалить? + + + Are sure you want to delete '%1'? + Вы действительно хотите удалить '%1'? + + + Could not delete directory. + Не удалось удалить каталог. + + + Drive + Диск + + + File Folder + Match Windows Explorer + Папка с файлами + + + Folder + All other platforms + Папка + + + Alias + Mac OS X Finder + Псевдоним + + + Shortcut + All other platforms + Ярлык + + + Unknown + Неизвестный + + + Show + Показать + + + Forward + Вперёд + + + &New Folder + &Новая папка + + + &Choose + &Выбрать + + + Remove + Удалить + + + File &name: + &Имя файла: + + + Look in: + Перейти к: + + + Create New Folder + Создать папку + + + + QFileSystemModel + + %1 TB + %1 Тб + + + %1 GB + %1 Гб + + + %1 MB + %1 Мб + + + %1 KB + %1 Кб + + + %1 bytes + %1 байт + + + Invalid filename + Некорректное имя файла + + + <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. + <b>Имя "%1" не может быть использовано.</b><p>Попробуйте использовать имя меньшей длины и/или без символов пунктуации. + + + Name + Имя + + + Size + Размер + + + Kind + Match OS X Finder + Вид + + + Type + All other platforms + Тип + + + Date Modified + Дата изменения + + + My Computer + Мой компьютер + + + Computer + Компьютер + + + %1 byte(s) + %1 байт(ов) + + + + QFontDatabase + + Normal + Обычный + + + Bold + Жирный + + + Demi Bold + Полужирный + + + Black + Чёрный + + + Demi + Средний + + + Light + Светлый + + + Italic + Курсив + + + Oblique + Наклонный + + + Any + Любая + + + Latin + Латиница + + + Greek + Греческая + + + Cyrillic + Кириллица + + + Armenian + Армянская + + + Hebrew + Иврит + + + Arabic + Арабская + + + Syriac + Сирийская + + + Thaana + Таана + + + Devanagari + Деванагири + + + Bengali + Бенгальская + + + Gurmukhi + Гурмукхи + + + Gujarati + Гуджарати + + + Oriya + Ория + + + Tamil + Тамильская + + + Telugu + Телугу + + + Kannada + Каннада + + + Malayalam + Малайялам + + + Sinhala + Сингальская + + + Thai + Тайская + + + Lao + Лаосская + + + Tibetan + Тибетская + + + Myanmar + Мьянма + + + Georgian + Грузинская + + + Khmer + Кхмерская + + + Simplified Chinese + Китайская упрощенная + + + Traditional Chinese + Китайская традиционная + + + Japanese + Японская + + + Korean + Корейская + + + Vietnamese + Вьетнамская + + + Symbol + Символьная + + + Ogham + Огамическая + + + Runic + Руническая + + + N'Ko + ## + + + + QFontDialog + + &Font + &Шрифт + + + Font st&yle + &Начертание + + + &Size + &Размер + + + Effects + Эффекты + + + Stri&keout + Зачёр&кнутый + + + &Underline + П&одчёркнутый + + + Sample + Пример + + + Select Font + Выбор шрифта + + + Wr&iting System + &Система письма + + + + QFtp + + Host %1 found + Узел %1 найден + + + Host found + Узел найден + + + Connected to host %1 + Установлено соединение с узлом %1 + + + Connected to host + Соединение с узлом установлено + + + Connection to %1 closed + Соединение с %1 закрыто + + + Connection closed + Соединение закрыто + + + Host %1 not found + Узел %1 не найден + + + Connection refused to host %1 + В соединении с узлом %1 отказано + + + Connection timed out to host %1 + Время на соединение с узлом %1 истекло + + + Unknown error + Неизвестная ошибка + + + Connecting to host failed: +%1 + Не удалось соединиться с узлом: +%1 + + + Login failed: +%1 + Не удалось авторизоваться: +%1 + + + Listing directory failed: +%1 + Не удалось прочитать каталог: +%1 + + + Changing directory failed: +%1 + Не удалось сменить каталог: +%1 + + + Downloading file failed: +%1 + Не удалось загрузить файл: +%1 + + + Uploading file failed: +%1 + Не удалось отгрузить файл: +%1 + + + Removing file failed: +%1 + Не удалось удалить файл: +%1 + + + Creating directory failed: +%1 + Не удалось создать каталог: +%1 + + + Removing directory failed: +%1 + Не удалось удалить каталог: +%1 + + + Not connected + Соединение не установлено + + + Connection refused for data connection + Отказ в соединении для передачи данных + + + + QHostInfo + + Unknown error + Неизвестная ошибка + + + + QHostInfoAgent + + Host not found + Узел не найден + + + Unknown address type + Неизвестный тип адреса + + + Unknown error + Неизвестная ошибка + + + No host name given + Имя узла не задано + + + Invalid hostname + Некорректное имя узла + + + + QHttp + + Connection refused + Отказано в соединении + + + Host %1 not found + Узел %1 не найден + + + Wrong content length + Неверная длина содержимого + + + HTTP request failed + HTTP-запрос не удался + + + Host %1 found + Узел %1 найден + + + Host found + Узел найден + + + Connected to host %1 + Установлено соединение с узлом %1 + + + Connected to host + Соединение с узлом установлено + + + Connection to %1 closed + Соединение с узлом %1 закрыто + + + Connection closed + Соединение закрыто + + + Unknown error + Неизвестная ошибка + + + Request aborted + Запрос прерван + + + No server set to connect to + Не указан сервер для подключения + + + Server closed connection unexpectedly + Сервер неожиданно разорвал соединение + + + Invalid HTTP response header + Некорректный HTTP-заголовок ответа + + + Unknown authentication method + Неизвестный метод авторизации + + + Invalid HTTP chunked body + Некорректное HTTP-фрагментирование данных + + + Error writing response to device + Ошибка записи ответа на устройство + + + Proxy authentication required + Требуется авторизация на прокси-сервере + + + Authentication required + Требуется авторизация + + + Proxy requires authentication + Прокси-сервер требует авторизацию + + + Host requires authentication + Узел требует авторизацию + + + Data corrupted + Данные повреждены + + + SSL handshake failed + Квитирование SSL не удалось + + + Unknown protocol specified + Указан неизвестный протокол + + + Connection refused (or timed out) + В соединении отказано (или время ожидания истекло) + + + HTTPS connection requested but SSL support not compiled in + Запрошено соединение по протоколу HTTPS, но поддержка SSL не скомпилирована + + + + QHttpSocketEngine + + Did not receive HTTP response from proxy + Не получен HTTP-ответ от прокси-сервера + + + Error parsing authentication request from proxy + Ошибка разбора запроса авторизации от прокси-сервера + + + Authentication required + Требуется авторизация + + + Proxy denied connection + Прокси-сервер запретил соединение + + + Error communicating with HTTP proxy + Ошибка обмена данными с прокси-сервером HTTP + + + Proxy server not found + Прокси-сервер не найден + + + Proxy connection refused + В соединении прокси-сервером отказано + + + Proxy server connection timed out + Время на соединение с прокси-сервером истекло + + + Proxy connection closed prematurely + Соединение с прокси-сервером неожиданно закрыто + + + + QIBaseDriver + + Error opening database + Ошибка открытия базы данных + + + Could not start transaction + Не удалось начать транзакцию + + + Unable to commit transaction + Невозможно завершить транзакцию + + + Unable to rollback transaction + Невозможно отозвать транзакцию + + + + QIBaseResult + + Unable to create BLOB + Невозможно создать BLOB + + + Unable to write BLOB + Невозможно записать BLOB + + + Unable to open BLOB + Невозможно открыть BLOB + + + Unable to read BLOB + Невозможно прочитать BLOB + + + Could not find array + Не удалось найти массив + + + Could not get array data + Не удалось найти данные массива + + + Could not get query info + Не удалось найти информацию о запросе + + + Could not start transaction + Не удалось начать транзакцию + + + Unable to commit transaction + Невозможно завершить транзакцию + + + Could not allocate statement + Не удалось получить ресурсы для создания выражения + + + Could not prepare statement + Не удалось подготовить выражение + + + Could not describe input statement + Не удалось описать входящее выражение + + + Could not describe statement + Не удалось описать выражение + + + Unable to close statement + Невозможно закрыть выражение + + + Unable to execute query + Невозможно выполнить запрос + + + Could not fetch next item + Не удалось получить следующий элемент + + + Could not get statement info + Не удалось найти информацию о выражении + + + + QIODevice + + Permission denied + Доступ запрещён + + + Too many open files + Слишком много открытых файлов + + + No such file or directory + Файл или каталог не существует + + + No space left on device + Нет свободного места на устройстве + + + Unknown error + Неизвестная ошибка + + + + QInputContext + + XIM + Метод ввода X-сервера + + + FEP + Метод ввода S60 FEP + + + XIM input method + Метод ввода X-сервера + + + Windows input method + Метод ввода Windows + + + Mac OS X input method + Метод ввода Mac OS X + + + S60 FEP input method + Метод ввода S60 FEP + + + + QInputDialog + + Enter a value: + Укажите значение: + + + + QLibrary + + Could not mmap '%1': %2 + Не удалось выполнить mmap '%1': %2 + + + Plugin verification data mismatch in '%1' + Проверочная информация для модуля '%1' не совпадает + + + Could not unmap '%1': %2 + Не удалось выполнить unmap '%1': %2 + + + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] + Модуль '%1' использует несоместимую библиотеку Qt. (%2.%3.%4) [%5] + + + The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" + Модуль '%1' использует несоместимую библиотеку Qt. Ожидается ключ "%2", но получен ключ "%3" + + + Unknown error + Неизвестная ошибка + + + The shared library was not found. + Динамическая библиотека не найдена. + + + The file '%1' is not a valid Qt plugin. + Файл '%1' - не является корректным модулем Qt. + + + The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) + Модуль '%1' использует несоместимую библиотеку Qt. (Невозможно совместить релизные и отладочные библиотеки.) + + + Cannot load library %1: %2 + Невозможно загрузить библиотеку %1: %2 + + + Cannot unload library %1: %2 + Невозможно выгрузить библиотеку %1: %2 + + + Cannot resolve symbol "%1" in %2: %3 + Невозможно разрешить символ "%1" в %2: %3 + + + + QLineEdit + + Select All + Выделить всё + + + &Undo + &Отменить действие + + + &Redo + &Повторить действие + + + Cu&t + &Вырезать + + + &Copy + &Копировать + + + &Paste + В&ставить + + + Delete + Удалить + + + + QLocalServer + + %1: Name error + %1: Некорректное имя + + + %1: Permission denied + %1: Доступ запрещён + + + %1: Address in use + %1: Адрес используется + + + %1: Unknown error %2 + %1: Неизвестная ошибка %2 + + + + QLocalSocket + + %1: Connection refused + %1: Отказано в соединении + + + %1: Remote closed + %1: Закрыто удаленной стороной + + + %1: Invalid name + %1: Некорректное имя + + + %1: Socket access error + %1: Ошибка обращения к сокету + + + %1: Socket resource error + %1: Ошибка выделения ресурсов сокета + + + %1: Socket operation timed out + %1: Время на операцию с сокетом истекло + + + %1: Datagram too large + %1: Датаграмма слишком большая + + + %1: Connection error + %1: Ошибка соединения + + + %1: The socket operation is not supported + %1: Операция с сокетом не поддерживается + + + %1: Unknown error + %1: Неизвестная ошибка + + + %1: Unknown error %2 + %1: Неизвестная ошибка %2 + + + + QMYSQLDriver + + Unable to open database ' + Невозможно открыть базу данных ' + + + Unable to connect + Невозможно соединиться + + + Unable to begin transaction + Невозможно начать транзакцию + + + Unable to commit transaction + Невозможно завершить транзакцию + + + Unable to rollback transaction + Невозможно отозвать транзакцию + + + + QMYSQLResult + + Unable to fetch data + Невозможно получить данные + + + Unable to execute query + Невозможно выполнить запрос + + + Unable to store result + Невозможно сохранить результат + + + Unable to prepare statement + Невозможно подготовить выражение + + + Unable to reset statement + Невозможно сбросить выражение + + + Unable to bind value + Невозможно привязать значение + + + Unable to execute statement + Невозможно выполнить выражение + + + Unable to bind outvalues + Невозможно привязать результирующие значения + + + Unable to store statement results + Невозможно сохранить результаты выполнения выражения + + + Unable to execute next query + Невозможно выполнить следующий запрос + + + Unable to store next result + Невозможно сохранить следующий результат + + + + QMdiArea + + (Untitled) + (Неозаглавлено) + + + + QMdiSubWindow + + %1 - [%2] + %1 - [%2] + + + Close + Закрыть + + + Minimize + Свернуть + + + Restore Down + Восстановить + + + &Restore + &Восстановить + + + &Move + &Переместить + + + &Size + &Размер + + + Mi&nimize + &Свернуть + + + Ma&ximize + Р&аспахнуть + + + Stay on &Top + Оставаться &сверху + + + &Close + &Закрыть + + + Maximize + Распахнуть + + + Unshade + Восстановить из заголовка + + + Shade + Свернуть в заголовок + + + Restore + Восстановить + + + Help + Справка + + + Menu + Меню + + + - [%1] + - [%1] + + + + QMenu + + Close + Закрыть + + + Open + Открыть + + + Execute + Выполнить + + + + QMenuBar + + Actions + Действия + + + + QMessageBox + + OK + Закрыть + + + <h3>About Qt</h3><p>This program uses Qt version %1.</p> + <h3>О Qt</h3><p>Данная программа использует Qt версии %1.</p> + + + <p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p><p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://qt.nokia.com/">qt.nokia.com</a> for more information.</p> + <p>Qt - это инструментарий для разработки кроссплатформенных приложений на C++.</p><p>Qt предоставляет совместимость на уровне исходных текстов между MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux и всеми популярными коммерческими вариантами Unix. Также Qt доступна для встраиваемых устройств в виде Qt для Embedded Linux и Qt для Windows CE.</p><p>Qt доступна под тремя различными лицензиями, разработанными для удовлетворения различных требований.</p><p>Qt под нашей коммерческой лицензией предназначена для развития проприетарного/коммерческого программного обеспечения, когда Вы не желаете предоставлять исходные тексты третьим сторонам, или в случае невозможности принятия условий лицензий GNU LGPL версии 2.1 или GNU GPL версии 3.0.</p><p>Qt под лицензией GNU LGPL версии 2.1 предназначена для разработки программного обеспечения с открытыми исходными текстами или коммерческого программного обеспечения при соблюдении условий лицензии GNU LGPL версии 2.1.</p><p>Qt под лицензией GNU General Public License версии 3.0 предназначена для разработки программных приложений в тех случаях, когда Вы хотели бы использовать такие приложения в сочетании с программным обеспечением на условиях лицензии GNU GPL с версии 3.0 или если Вы готовы соблюдать условия лицензии GNU GPL версии 3.0.</p><p>Обратитесь к <a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a> для обзора лицензий Qt.</p><p>Copyright (C) 2010 Корпорация Nokia и/или её дочерние подразделения.</p><p>Qt - продукт компании Nokia. Обратитесь к <a href="http://qt.nokia.com/">qt.nokia.com</a> для получения дополнительной информации.</p> + + + About Qt + О Qt + + + Help + Справка + + + Show Details... + Показать подробности... + + + Hide Details... + Скрыть подробности... + + + + QMultiInputContext + + Select IM + Выбор режима ввода + + + + QMultiInputContextPlugin + + Multiple input method switcher + Переключатель режима множественного ввода + + + Multiple input method switcher that uses the context menu of the text widgets + Переключатель режима множественного ввода, используемый в контекстном меню текстовых виджетов + + + + QNativeSocketEngine + + The remote host closed the connection + Удалённый узел закрыл соединение + + + Network operation timed out + Время на сетевую операцию истекло + + + Out of resources + Недостаточно ресурсов + + + Unsupported socket operation + Операция с сокетом не поддерживается + + + Protocol type not supported + Протокол не поддерживается + + + Invalid socket descriptor + Некорректный дескриптор сокета + + + Network unreachable + Сеть недоступна + + + Permission denied + Доступ запрещён + + + Connection timed out + Время на соединение истекло + + + Connection refused + Отказано в соединении + + + The bound address is already in use + Адрес уже используется + + + The address is not available + Адрес недоступен + + + The address is protected + Адрес защищён + + + Unable to send a message + Невозможно отправить сообщение + + + Unable to receive a message + Невозможно получить сообщение + + + Unable to write + Невозможно записать + + + Network error + Ошибка сети + + + Another socket is already listening on the same port + Другой сокет уже прослушивает этот порт + + + Unable to initialize non-blocking socket + Невозможно инициализировать не-блочный сокет + + + Unable to initialize broadcast socket + Невозможно инициализировать широковещательный сокет + + + Attempt to use IPv6 socket on a platform with no IPv6 support + Попытка использовать IPv6 на платформе, не поддерживающей IPv6 + + + Host unreachable + Узел недоступен + + + Datagram was too large to send + Датаграмма слишком большая для отправки + + + Operation on non-socket + Операция с не-сокетом + + + Unknown error + Неизвестная ошибка + + + The proxy type is invalid for this operation + Некорректный тип прокси-сервера для данной операции + + + + QNetworkAccessCacheBackend + + Error opening %1 + Ошибка открытия %1 + + + + QNetworkAccessDebugPipeBackend + + Write error writing to %1: %2 + Ошибка записи в %1: %2 + + + + QNetworkAccessFileBackend + + Request for opening non-local file %1 + Запрос на открытие файла вне файловой системы %1 + + + Error opening %1: %2 + Ошибка открытия %1: %2 + + + Write error writing to %1: %2 + Ошибка записи в %1: %2 + + + Cannot open %1: Path is a directory + Невозможно открыть %1: Указан путь к каталогу + + + Read error reading from %1: %2 + Ошибка чтения из %1: %2 + + + + QNetworkAccessFtpBackend + + No suitable proxy found + Подходящий прокси-сервер не найден + + + Cannot open %1: is a directory + Невозможно открыть %1: Указан путь к каталогу + + + Logging in to %1 failed: authentication required + Соединение с %1 не удалось: требуется авторизация + + + Error while downloading %1: %2 + Ошибка в процессе загрузки %1: %2 + + + Error while uploading %1: %2 + Ошибка в процессе отгрузки %1: %2 + + + + QNetworkAccessHttpBackend + + No suitable proxy found + Подходящий прокси-сервер не найден + + + + QNetworkReply + + Error downloading %1 - server replied: %2 + Ошибка загрузки %1 - ответ сервера: %2 + + + Protocol "%1" is unknown + Неизвестный протокол "%1" + + + + QNetworkReplyImpl + + Operation canceled + Операция отменена + + + + QOCIDriver + + Unable to logon + Невозможно авторизоваться + + + Unable to initialize + QOCIDriver + Невозможно инициализировать + + + Unable to begin transaction + Невозможно начать транзакцию + + + Unable to commit transaction + Невозможно завершить транзакцию + + + Unable to rollback transaction + Невозможно отозвать транзакцию + + + + QOCIResult + + Unable to bind column for batch execute + Невозможно привязать столбец для пакетного выполнения + + + Unable to execute batch statement + Невозможно выполнить пакетное выражение + + + Unable to goto next + Невозможно перейти к следующей строке + + + Unable to alloc statement + Невозможно создать выражение + + + Unable to prepare statement + Невозможно подготовить выражение + + + Unable to get statement type + Невозможно определить тип выражения + + + Unable to bind value + Невозможно привязать результирующие значения + + + Unable to execute statement + Невозможно выполнить выражение + + + + QODBCDriver + + Unable to connect + Невозможно соединиться + + + Unable to disable autocommit + Невозможно отключить автозавершение транзакций + + + Unable to commit transaction + Невозможно завершить транзакцию + + + Unable to rollback transaction + Невозможно отозвать транзакцию + + + Unable to enable autocommit + Невозможно включить автозавершение транзакций + + + Unable to connect - Driver doesn't support all functionality required + Невозможно соединиться - Драйвер не поддерживает требуемый функционал + + + + QODBCResult + + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration + QODBCResult::reset: Невозможно установить 'SQL_CURSOR_STATIC' атрибутом выражение. Проверьте настройки драйвера ODBC + + + Unable to execute statement + Невозможно выполнить выражение + + + Unable to fetch next + Невозможно получить следующую строку + + + Unable to prepare statement + Невозможно подготовить выражение + + + Unable to bind variable + Невозможно привязать значение + + + Unable to fetch last + Невозможно получить последнюю строку + + + Unable to fetch + Невозможно получить данные + + + Unable to fetch first + Невозможно получить первую строку + + + Unable to fetch previous + Невозможно получить предыдущую строку + + + + QObject + + Invalid hostname + Некорректное имя узла + + + Operation not supported on %1 + Операция не поддерживается для %1 + + + Invalid URI: %1 + Некорректный URI: %1 + + + Socket error on %1: %2 + Ошика сокета для %1: %2 + + + Remote host closed the connection prematurely on %1 + Удалённый узел неожиданно прервал соединение для %1 + + + No host name given + Имя узла не задано + + + + QPPDOptionsModel + + Name + Имя + + + Value + Значение + + + + QPSQLDriver + + Unable to connect + Невозможно соединиться + + + Could not begin transaction + Не удалось начать транзакцию + + + Could not commit transaction + Не удалось завершить транзакцию + + + Could not rollback transaction + Не удалось отозвать транзакцию + + + Unable to subscribe + Невозможно подписаться + + + Unable to unsubscribe + Невозможно отписаться + + + + QPSQLResult + + Unable to create query + Невозможно создать запрос + + + Unable to prepare statement + Невозможно подготовить выражение + + + + QPageSetupWidget + + Centimeters (cm) + Сантиметры (cm) + + + Millimeters (mm) + Миллиметры (mm) + + + Inches (in) + Дюймы (in) + + + Points (pt) + Точки (pt) + + + Form + Форма + + + Paper + Бумага + + + Page size: + Размер страницы: + + + Width: + Ширина: + + + Height: + Высота: + + + Paper source: + Источник бумаги: + + + Orientation + Ориентация + + + Portrait + Книжная + + + Landscape + Альбомная + + + Reverse landscape + Перевёрнутая альбомная + + + Reverse portrait + Перевёрнутая книжная + + + Margins + Поля + + + top margin + верхнее поле + + + left margin + левое поле + + + right margin + правое поле + + + bottom margin + нижнее поле + + + + QPluginLoader + + Unknown error + Неизвестная ошибка + + + The plugin was not loaded. + Модуль не был загружен. + + + + QPrintDialog + + locally connected + соединено локально + + + Aliases: %1 + Псевдонимы: %1 + + + unknown + неизвестно + + + OK + Закрыть + + + Print all + Печатать все + + + Print range + Печатать диапазон + + + A0 (841 x 1189 mm) + A0 (841 x 1189 мм) + + + A1 (594 x 841 mm) + A1 (594 x 841 мм) + + + A2 (420 x 594 mm) + A2 (420 x 594 мм) + + + A3 (297 x 420 mm) + A3 (297 x 420 мм) + + + A5 (148 x 210 mm) + A5 (148 x 210 мм) + + + A6 (105 x 148 mm) + A6 (105 x 148 мм) + + + A7 (74 x 105 mm) + A7 (74 x 105 мм) + + + A8 (52 x 74 mm) + A8 (52 x 74 мм) + + + A9 (37 x 52 mm) + A9 (37 x 52 мм) + + + B0 (1000 x 1414 mm) + B0 (1000 x 1414 мм) + + + B1 (707 x 1000 mm) + B1 (707 x 1000 мм) + + + B2 (500 x 707 mm) + B2 (500 x 707 мм) + + + B3 (353 x 500 mm) + B3 (353 x 500 мм) + + + B4 (250 x 353 mm) + B4 (250 x 353 мм) + + + B6 (125 x 176 mm) + B6 (125 x 176 мм) + + + B7 (88 x 125 mm) + B7 (88 x 125 мм) + + + B8 (62 x 88 mm) + B8 (62 x 88 мм) + + + B9 (44 x 62 mm) + B9 (44 x 62 мм) + + + B10 (31 x 44 mm) + B10 (31 x 44 мм) + + + C5E (163 x 229 mm) + C5E (163 x 229 мм) + + + DLE (110 x 220 mm) + DLE (110 x 220 мм) + + + Folio (210 x 330 mm) + Folio (210 x 330 мм) + + + Ledger (432 x 279 mm) + Ledger (432 x 279 мм) + + + Tabloid (279 x 432 mm) + Tabloid (279 x 432 мм) + + + US Common #10 Envelope (105 x 241 mm) + Конверт US #10 (105x241 мм) + + + A4 (210 x 297 mm, 8.26 x 11.7 inches) + A4 (210 x 297 мм, 8.26 x 11.7 дюймов) + + + B5 (176 x 250 mm, 6.93 x 9.84 inches) + B5 (176 x 250 мм, 6.93 x 9.84 дюймов) + + + Executive (7.5 x 10 inches, 191 x 254 mm) + Executive (191 x 254 мм, 7.5 x 10 дюймов) + + + Legal (8.5 x 14 inches, 216 x 356 mm) + Legal (216 x 356 мм, 8.5 x 14 дюймов) + + + Letter (8.5 x 11 inches, 216 x 279 mm) + Letter (216 x 279 мм, 8.5 x 11 дюймов) + + + Print selection + Выделенный фрагмент + + + Print + Печать + + + Print To File ... + Печать в файл ... + + + File %1 is not writable. +Please choose a different file name. + %1 недоступен для записи. +Выберите другое имя файла. + + + %1 already exists. +Do you want to overwrite it? + %1 уже существует. +Хотите заменить его? + + + File exists + Файл существует + + + <qt>Do you want to overwrite it?</qt> + <qt>Хотите заменить?</qt> + + + %1 is a directory. +Please choose a different file name. + %1 - это каталог. +Выберите другое имя файла. + + + The 'From' value cannot be greater than the 'To' value. + Значение 'от' не может быть больше значения 'до'. + + + A0 + A0 + + + A1 + A1 + + + A2 + A2 + + + A3 + A3 + + + A4 + A4 + + + A5 + A5 + + + A6 + A6 + + + A7 + A7 + + + A8 + A8 + + + A9 + A9 + + + B0 + B0 + + + B1 + B1 + + + B2 + B2 + + + B3 + B3 + + + B4 + B4 + + + B5 + B5 + + + B6 + B6 + + + B7 + B7 + + + B8 + B8 + + + B9 + B9 + + + B10 + B10 + + + C5E + C5E + + + DLE + DLE + + + Executive + Executive + + + Folio + Folio + + + Ledger + Ledger + + + Legal + Legal + + + Letter + Letter + + + Tabloid + Tabloid + + + US Common #10 Envelope + US Common #10 Envelope + + + Custom + Пользовательский + + + &Options >> + &Параметры >> + + + &Options << + &Параметры << + + + Print to File (PDF) + Печать в файл (PDF) + + + Print to File (Postscript) + Печать в файл (Postscript) + + + Local file + Локальный файл + + + Write %1 file + Запись %1 файла + + + &Print + &Печать + + + + QPrintPreviewDialog + + %1% + %1% + + + Print Preview + Просмотр печати + + + Next page + Следующая страница + + + Previous page + Предыдущая страница + + + First page + Первая страница + + + Last page + Последняя страница + + + Fit width + По ширине + + + Fit page + На всю страницу + + + Zoom in + Увеличить + + + Zoom out + Уменьшить + + + Portrait + Книжная + + + Landscape + Альбомная + + + Show single page + Показать одну страницу + + + Show facing pages + Показать титульные страницы + + + Show overview of all pages + Показать обзор всех страниц + + + Print + Печать + + + Page setup + Параметры страницы + + + Close + + + + Export to PDF + Экспорт в PDF + + + Export to PostScript + Экспорт в Postscript + + + Page Setup + Параметры страницы + + + + QPrintPropertiesWidget + + Form + Форма + + + Page + Страница + + + Advanced + Дополнительно + + + + QPrintSettingsOutput + + Form + Форма + + + Copies + Копии + + + Print range + Диапазон печати + + + Print all + Все + + + Pages from + Страницы от + + + to + до + + + Selection + Выделенный фрагмент + + + Output Settings + Настройки вывода + + + Copies: + Количество копий: + + + Collate + Разобрать про копиям + + + Reverse + Обратный порядок + + + Options + Параметры + + + Color Mode + Режим цвета + + + Color + Цвет + + + Grayscale + Оттенки серого + + + Duplex Printing + Двусторонняя печать + + + None + Нет + + + Long side + По длинной стороне + + + Short side + По короткой стороне + + + + QPrintWidget + + Form + Форма + + + Printer + Принтер + + + &Name: + &Название: + + + P&roperties + С&войства + + + Location: + Расположение: + + + Preview + Просмотр + + + Type: + Тип: + + + Output &file: + Вывод в &файл: + + + ... + ... + + + + QProcess + + Could not open input redirection for reading + Не удалось открыть перенаправление ввода для чтения + + + Could not open output redirection for writing + Не удалось открыть перенаправление вывода для записи + + + Resource error (fork failure): %1 + Ошибка выделения ресурсов (сбой fork): %1 + + + Process operation timed out + Время на операцию с процессом истекло + + + Error reading from process + Ошибка получения данных от процесса + + + Error writing to process + Ошибка отправки данных процессу + + + Process crashed + Процесс завершился с ошибкой + + + No program defined + Программа не указана + + + Process failed to start: %1 + Не удалось запустить процесс: %1 + + + + QProgressDialog + + Cancel + Отмена + + + + QPushButton + + Open + Открыть + + + + QRadioButton + + Check + Отметить + + + + QRegExp + + no error occurred + ошибки отсутствуют + + + disabled feature used + использование отключённых возможностей + + + bad char class syntax + неправильный синтаксис класса символов + + + bad lookahead syntax + неправильный предварительный синтаксис + + + bad repetition syntax + неправильный синтаксис повторения + + + invalid octal value + некорректное восьмеричное значение + + + missing left delim + отсутствует левый разделитель + + + unexpected end + неожиданный конец + + + met internal limit + достигнуто внутреннее ограничение + + + invalid interval + некорректный интервал + + + invalid category + некорректная категория + + + + QSQLite2Driver + + Error opening database + Ошибка открытия базы данных + + + Unable to begin transaction + Невозможно начать транзакцию + + + Unable to commit transaction + Невозможно завершить транзакцию + + + Unable to rollback transaction + Невозможно отозвать транзакцию + + + + QSQLite2Result + + Unable to fetch results + Невозможно получить результаты + + + Unable to execute statement + Невозможно выполнить выражение + + + + QSQLiteDriver + + Error opening database + Ошибка открытия базы данных + + + Error closing database + Ошибка закрытия базы данных + + + Unable to begin transaction + Невозможно начать транзакцию + + + Unable to commit transaction + Невозможно завершить транзакцию + + + Unable to rollback transaction + Невозможно отозвать транзакцию + + + + QSQLiteResult + + Unable to fetch row + Невозможно получить строку + + + Unable to execute statement + Невозможно выполнить выражение + + + Unable to reset statement + Невозможно сбросить выражение + + + Unable to bind parameters + Невозможно привязать параметр + + + Parameter count mismatch + Количество параметров не совпадает + + + No query + Отсутствует запрос + + + + QScriptBreakpointsModel + + ID + ID + + + Location + Размещение + + + Condition + Условие + + + Ignore-count + Пропустить + + + Single-shot + Один раз + + + Hit-count + Попаданий + + + + QScriptBreakpointsWidget + + New + Новая + + + Delete + Удалить + + + + QScriptDebugger + + Go to Line + Перейти к строке + + + Line: + Строка: + + + Interrupt + Прервать + + + Shift+F5 + Shift+F5 + + + Continue + Продолжить + + + F5 + F5 + + + Step Into + Войти в + + + F11 + F11 + + + Step Over + Перейти через + + + F10 + F10 + + + Step Out + Выйти из функции + + + Shift+F11 + Shift+F11 + + + Run to Cursor + Выполнить до курсора + + + Ctrl+F10 + Ctrl+F10 + + + Run to New Script + Выполнить до нового сценария + + + Toggle Breakpoint + Установить/убрать точку останова + + + F9 + F9 + + + Clear Debug Output + Очистить отладочный вывод + + + Clear Error Log + Очистить журнал ошибок + + + Clear Console + Очистить консоль + + + &Find in Script... + &Найти в сценарии... + + + Ctrl+F + Ctrl+F + + + Find &Next + Найти &следующее + + + F3 + F3 + + + Find &Previous + Найти &предыдущее + + + Shift+F3 + Shift+F3 + + + Ctrl+G + Ctrl+G + + + Debug + Отладка + + + + QScriptDebuggerCodeFinderWidget + + Close + Закрыть + + + Previous + Предыдущий + + + Next + Следующий + + + Case Sensitive + Учитывать регистр + + + Whole words + Слова целиком + + + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;Search wrapped + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;Поиск с начала + + + + QScriptDebuggerLocalsModel + + Name + Название + + + Value + Значение + + + + QScriptDebuggerStackModel + + Level + Уровень + + + Name + Название + + + Location + Размещение + + + + QScriptEdit + + Toggle Breakpoint + Установить/убрать точку останова + + + Disable Breakpoint + Убрать точку останова + + + Enable Breakpoint + Установить точку останова + + + Breakpoint Condition: + Условие точки останова: + + + + QScriptEngineDebugger + + Loaded Scripts + Загруженные сценарии + + + Breakpoints + Точки останова + + + Stack + Стек + + + Locals + Локальные переменные + + + Console + Консоль + + + Debug Output + Отладочный вывод + + + Error Log + Журнал ошибок + + + Search + Поиск + + + View + Вид + + + Qt Script Debugger + Отладчик сценариев Qt + + + + QScriptNewBreakpointWidget + + Close + Закрыть + + + + QScrollBar + + Scroll here + Прокрутить сюда + + + Left edge + К левой границе + + + Top + Вверх + + + Right edge + К правой границе + + + Bottom + Вниз + + + Page left + На страницу влево + + + Page up + На страницу вверх + + + Page right + На страницу вправо + + + Page down + На страницу вниз + + + Scroll left + Прокрутить влево + + + Scroll up + Прокрутить вверх + + + Scroll right + Прокрутить вправо + + + Scroll down + Прокрутить вниз + + + Line up + На строку вверх + + + Position + Положение + + + Line down + На строку вниз + + + + QSharedMemory + + %1: create size is less then 0 + %1: размер меньше нуля + + + %1: unable to lock + %1: невозможно заблокировать + + + %1: unable to unlock + %1: невозможно разблокировать + + + %1: permission denied + %1: доступ запрещён + + + %1: already exists + %1: уже существует + + + %1: doesn't exists + %1: не существует + + + %1: out of resources + %1: недостаточно ресурсов + + + %1: unknown error %2 + %1: неизвестная ошибка %2 + + + %1: key is empty + %1: пустой ключ + + + %1: ftok failed + %1: ошибка ftok + + + %1: unable to make key + %1: невозможно создать ключ + + + %1: doesn't exist + %1: не существует + + + %1: UNIX key file doesn't exist + %1: специфический ключ UNIX не существует + + + %1: system-imposed size restrictions + %1: системой наложены ограничения на размер + + + %1: not attached + %1: не приложенный + + + %1: invalid size + %1: некорректный размер + + + %1: key error + %1: некорректный ключ + + + %1: size query failed + %1: не удалось запросить размер + + + %1: unable to set key on lock + %1: невозможно установить ключ на блокировку + + + + QShortcut + + Space + Пробел + + + Esc + Esc + + + Tab + Tab + + + Backtab + Обратная табуляция + + + Backspace + Backspace + + + Return + Возврат + + + Enter + Ввод + + + Ins + Ins + + + Del + Del + + + Pause + Пауза + + + Print + Распечатать + + + SysReq + SysReq + + + Home + Главный + + + End + Завершить + + + Left + Влево + + + Up + Вверх + + + Right + Вправо + + + Down + Вниз + + + PgUp + PgUp + + + PgDown + PgDown + + + CapsLock + CapsLock + + + NumLock + NumLock + + + ScrollLock + ScrollLock + + + Menu + Меню + + + Help + Справка + + + Back + Назад + + + Forward + Вперёд + + + Stop + Остановить + + + Refresh + Обновить + + + Volume Down + Тише + + + Volume Mute + Выключить звук + + + Volume Up + Громче + + + Bass Boost + Усиление басов + + + Bass Up + Увеличить басы + + + Bass Down + Уменьшить басы + + + Treble Up + Увеличить ВЧ + + + Treble Down + Уменьшить ВЧ + + + Media Play + Воспроизведение + + + Media Stop + Остановить воспроизведение + + + Media Previous + Воспроизвести предыдущее + + + Media Next + Воспроизвести следующее + + + Media Record + Запись + + + Favorites + Избранное + + + Search + Поиск + + + Standby + Режим ожидания + + + Open URL + Открыть URL + + + Launch Mail + Почта + + + Launch Media + Проигрыватель + + + Launch (0) + Запустить (0) + + + Launch (1) + Запустить (1) + + + Launch (2) + Запустить (2) + + + Launch (3) + Запустить (3) + + + Launch (4) + Запустить (4) + + + Launch (5) + Запустить (5) + + + Launch (6) + Запустить (6) + + + Launch (7) + Запустить (7) + + + Launch (8) + Запустить (8) + + + Launch (9) + Запустить (9) + + + Launch (A) + Запустить (A) + + + Launch (B) + Запустить (B) + + + Launch (C) + Запустить (C) + + + Launch (D) + Запустить (D) + + + Launch (E) + Запустить (E) + + + Launch (F) + Запустить (F) + + + Monitor Brightness Up + Увеличить яркость монитора + + + Monitor Brightness Down + Уменьшить яркость монитора + + + Keyboard Light On/Off + Вкл./Откл. подсветку клавиатуры + + + Keyboard Brightness Up + Увеличить яркость клавиатуры + + + Keyboard Brightness Down + Уменьшить яркость клавиатуры + + + Power Off + Откл. питание + + + Wake Up + Проснуться + + + Eject + Извлечь + + + Screensaver + Экранная заставка + + + WWW + WWW + + + Sleep + Спящий режим + + + LightBulb + Лампочка + + + Shop + Магазин + + + History + История + + + Add Favorite + Добавить избранные + + + Hot Links + Активные ссылки + + + Adjust Brightness + Настроить яркость + + + Finance + Финансы + + + Community + Сообщество + + + Audio Rewind + Перемотка аудио назад + + + Back Forward + ## + + + Application Left + Приложение слева + + + Application Right + Приложение справа + + + Book + Книга + + + CD + Компакт-диск + + + Calculator + Калькулятор + + + Clear + Очистить + + + Clear Grab + Очистить буфер + + + Close + Закрыть + + + Copy + Скопировать + + + Cut + Вырезать + + + Display + Дисплей + + + DOS + DOS + + + Documents + Документы + + + Spreadsheet + Электронная таблица + + + Browser + Браузер + + + Game + Игра + + + Go + Перейти + + + iTouch + iTouch + + + Logoff + Выйти + + + Market + Рынок + + + Meeting + Встреча + + + Keyboard Menu + Меню клавиатуры + + + Menu PB + Меню PB + + + My Sites + Мои сайты + + + News + Новости + + + Home Office + Домашний офис + + + Option + Функция + + + Paste + Вставить + + + Phone + Телефон + + + Reply + Ответить + + + Reload + Перезагрузить + + + Rotate Windows + Повернуть Windows + + + Rotation PB + Поворот PB + + + Rotation KB + Поворот KB + + + Save + Сохранить + + + Send + Передать + + + Spellchecker + Проверка правописания + + + Split Screen + Разделить экран + + + Support + Поддержка + + + Task Panel + Панель задач + + + Terminal + Терминал + + + Tools + Инструменты + + + Travel + ## + + + Video + Видео + + + Word Processor + Редактор текста + + + XFer + XFer + + + Zoom In + Увеличить + + + Zoom Out + Уменьшить + + + Away + Отсутствует + + + Messenger + Messenger + + + WebCam + WebCam + + + Mail Forward + Переслать почту + + + Pictures + Фотографии + + + Music + Музыка + + + Battery + Аккумулятор + + + Bluetooth + Bluetooth + + + Wireless + Беспроводной + + + Ultra Wide Band + Сверхширокий диапазон + + + Audio Forward + Перемотка аудио вперед + + + Audio Repeat + Повтор аудио + + + Audio Random Play + Воспроизведение аудио в случайном порядке + + + Subtitle + Подзаголовок + + + Audio Cycle Track + Повтор аудиодорожки + + + Time + Время + + + View + Вид + + + Top Menu + Верхнее меню + + + Suspend + Приостановить + + + Hibernate + Спящий режим + + + Print Screen + Печать экрана + + + Page Up + Страница вверх + + + Page Down + Страница вниз + + + Caps Lock + Caps Lock + + + Num Lock + Num Lock + + + Number Lock + Режим ввода цифр + + + Scroll Lock + Блокировка прокрутки + + + Insert + Вставить + + + Delete + Удалить + + + Escape + Выход + + + System Request + Системный запрос + + + Select + Выбрать + + + Yes + Да + + + No + Нет + + + Context1 + Контекст1 + + + Context2 + Контекст2 + + + Context3 + Контекст3 + + + Context4 + Контекст4 + + + Call + Вызов + + + Hangup + Завершить вызов + + + Flip + Перевернуть + + + Ctrl + Ctrl + + + Shift + Shift + + + Alt + Alt + + + Meta + ## + + + + + + + + + F%1 + F%1 + + + Home Page + Главная страница + + + + QSlider + + Page left + Страница влево + + + Page up + Страница вверх + + + Position + Положение + + + Page right + Страница вправо + + + Page down + Страница вниз + + + + QSocks5SocketEngine + + Connection to proxy refused + В соединении с прокси-сервером отказано + + + Connection to proxy closed prematurely + Соединение с прокси-сервером неожиданно закрыто + + + Proxy host not found + Прокси-сервер не найден + + + Connection to proxy timed out + Время на соединение с прокси-сервером истекло + + + Proxy authentication failed + Не удалось авторизоваться на прокси-сервере + + + Proxy authentication failed: %1 + Не удалось авторизоваться на прокси-сервере: %1 + + + SOCKS version 5 protocol error + Ошибка протокола SOCKSv5 + + + General SOCKSv5 server failure + Ошибка сервере SOCKSv5 + + + Connection not allowed by SOCKSv5 server + Соединение не разрешено сервером SOCKSv5 + + + TTL expired + TTL истекло + + + SOCKSv5 command not supported + Команда SOCKSv5 не поддерживается + + + Address type not supported + Тип адреса не поддерживается + + + Unknown SOCKSv5 proxy error code 0x%1 + Неизвестная ошибка SOCKSv5 прокси (код 0x%1) + + + Network operation timed out + Время на сетевую операцию истекло + + + + QSoftKeyManager + + Ok + ОК + + + Select + Выбрать + + + Done + Готово + + + Options + Параметры + + + Cancel + Отмена + + + Exit + Выход + + + + QSpinBox + + More + Больше + + + Less + Меньше + + + + QSql + + Delete + Удалить + + + Delete this record? + Удалить данную запись? + + + Yes + Да + + + No + Нет + + + Insert + Вставить + + + Update + Обновить + + + Save edits? + Сохранить изменения? + + + Cancel + Отмена + + + Confirm + Подтверждение + + + Cancel your edits? + Отменить изменения? + + + + QSslSocket + + Unable to write data: %1 + Невозможно записать данные: %1 + + + Unable to decrypt data: %1 + Невозможно расшифровать данные: %1 + + + Error while reading: %1 + Ошибка чтения: %1 + + + Error during SSL handshake: %1 + Ошибка квитирования SSL: %1 + + + Error creating SSL context (%1) + Ошибка создания контекста SSL: (%1) + + + Invalid or empty cipher list (%1) + Неправильный или пустой список шифров (%1) + + + Private key does not certify public key, %1 + Частный ключ не подтверждает общий ключ, %1 + + + Error creating SSL session, %1 + Ошибка создания сессии SSL, %1 + + + Error creating SSL session: %1 + Ошибка создания сессии SSL: %1 + + + Cannot provide a certificate with no key, %1 + Невозможно предоставить сертификат без ключа, %1 + + + Error loading local certificate, %1 + Ошибка загрузки локального сертификата, %1 + + + Error loading private key, %1 + Ошибка загрузки закрытого ключа, %1 + + + No error + Нет ошибки + + + The issuer certificate could not be found + Невозможно найти сертификат издателя + + + The certificate signature could not be decrypted + Невозможно расшифровать подпись сертификата + + + The public key in the certificate could not be read + Невозможно прочитать общий ключ сертификата + + + The signature of the certificate is invalid + Неверная подпись сертификата + + + The certificate is not yet valid + Сертификат еще не действует + + + The certificate has expired + Сертификат истек + + + The certificate's notBefore field contains an invalid time + Поле notBefore сертификата содержит неверное время + + + The certificate's notAfter field contains an invalid time + Поле notAfter сертификата содержит неверное время + + + The certificate is self-signed, and untrusted + Сертификаты с внутренней подписью и не проверены + + + The root certificate of the certificate chain is self-signed, and untrusted + Корневой сертификат цепочки сертификатов имеет внутреннюю подппись и не проверен + + + The issuer certificate of a locally looked up certificate could not be found + Невозможно найти сертификат издателя локального сертификата + + + No certificates could be verified + Невозможно проверить сертификаты + + + One of the CA certificates is invalid + Один из сертификатов центра сертификации неверный + + + The basicConstraints path length parameter has been exceeded + Превышено значение параметра длины пути basicConstraints + + + The supplied certificate is unsuitable for this purpose + Представленный сертификат непригоден для этой цели + + + The root CA certificate is not trusted for this purpose + Корневой сертификат ЦС не проверен для этой цели + + + The root CA certificate is marked to reject the specified purpose + Корневой сертификат ЦС отмечен для отклонения для указанной цели + + + The current candidate issuer certificate was rejected because its subject name did not match the issuer name of the current certificate + Текущий кандидат сертификат издателя отклонен, так как название темы не совпадает с названием издателя текущего сертификата + + + The current candidate issuer certificate was rejected because its issuer name and serial number was present and did not match the authority key identifier of the current certificate + Текущий кандидат сертификат издателя отклонен, так как его название издателя и серийный номер не совпадают с идентификатором ключа текущего сертификата + + + The peer did not present any certificate + Сертификат не представлен + + + The host name did not match any of the valid hosts for this certificate + Имя владельца не совпадает с допустимыми владельцами сертификата + + + Unknown error + Неизвестная ошибка + + + + QStateMachine + + Missing initial state in compound state '%1' + Отсутствует исходное состояние в составном состоянии '%1' + + + Missing default state in history state '%1' + Отсутствует состояние по умолчанию в историческом состоянии '%1' + + + No common ancestor for targets and source of transition from state '%1' + Нет общего предка для целей и источника перехода из состояния '%1' + + + Unknown error + Неизвестная ошибка + + + + QSystemSemaphore + + %1: does not exist + %1: не существует + + + %1: out of resources + %1: недостаточно ресурсов + + + %1: permission denied + %1: доступ запрещён + + + %1: already exists + %1: уже существует + + + %1: unknown error %2 + %1: неизвестная ошибка %2 + + + + QTDSDriver + + Unable to open connection + Невозможно открыть соединение + + + Unable to use database + Невозможно использовать базу данных + + + + QTabBar + + Scroll Left + Прокрутить влево + + + Scroll Right + Прокрутить вправо + + + + QTcpServer + + Operation on socket is not supported + Операция с сокетом не поддерживается + + + + QTextControl + + &Undo + &Отменить действие + + + &Redo + &Повторить действие + + + Cu&t + &Вырезать + + + &Copy + &Копировать + + + Copy &Link Location + Скопировать &адрес ссылки + + + &Paste + В&ставить + + + Delete + Удалить + + + Select All + Выделить всё + + + + QToolButton + + Press + Нажать + + + Open + Открыть + + + + QUdpSocket + + This platform does not support IPv6 + Данная платформа не поддерживает IPv6 + + + + QUndoGroup + + Undo + Отменить действие + + + Redo + Повторить действие + + + + QUndoModel + + <empty> + <пусто> + + + + QUndoStack + + Undo + Отменить действие + + + Redo + Повторить действие + + + + QUnicodeControlCharacterMenu + + LRM Left-to-right mark + LRM Признак письма слева направо + + + RLM Right-to-left mark + RLM Признак письма справа налево + + + ZWJ Zero width joiner + ZWJ Объединяющий символ нулевой ширины + + + ZWNJ Zero width non-joiner + ZWNJ Не объединяющий символ нулевой ширины + + + ZWSP Zero width space + ZWSP Пробел нулевой ширины + + + LRE Start of left-to-right embedding + LRE Начать встраивание слева направо + + + RLE Start of right-to-left embedding + RLE Начать встраивание справа налево + + + LRO Start of left-to-right override + LRE Начать замену слева направо + + + RLO Start of right-to-left override + RLE Начать замену справа налево + + + PDF Pop directional formatting + ## + + + Insert Unicode control character + Вставить управляющий символ Unicode + + + + QWebFrame + + Request cancelled + Запрос отменён + + + Request blocked + Запрос блокирован + + + Cannot show URL + Невозможно отобразить URL + + + Frame load interrupted by policy change + Загрузка фрейма прервана изменением политики + + + Cannot show mimetype + Невозможно отобразить тип MIME + + + File does not exist + Файл не существует + + + + QWebPage + + Submit + default label for Submit buttons in forms on web pages + Отправить + + + Submit + Submit (input element) alt text for <input> elements with no alt, title, or value + Отправить + + + Reset + default label for Reset buttons in forms on web pages + Сбросить + + + Choose File + title for file button used in HTML forms + Обзор... + + + No file selected + text to display in file button used in HTML forms when no file is selected + Файл не указан + + + Open in New Window + Open in New Window context menu item + Открыть в новом окне + + + Save Link... + Download Linked File context menu item + Сохранить по ссылке как... + + + Copy Link + Copy Link context menu item + Копировать адрес ссылки + + + Open Image + Open Image in New Window context menu item + Открыть изображение + + + Save Image + Download Image context menu item + Сохранить изображение + + + Copy Image + Copy Link context menu item + Копировать изображение в буффер обмена + + + Open Frame + Open Frame in New Window context menu item + Открыть фрейм + + + Copy + Copy context menu item + Копировать + + + Go Back + Back context menu item + Назад + + + Go Forward + Forward context menu item + Вперёд + + + Stop + Stop context menu item + Остановить + + + Reload + Reload context menu item + Обновить + + + Cut + Cut context menu item + Вырезать + + + Paste + Paste context menu item + Вставить + + + No Guesses Found + No Guesses Found context menu item + Неверное слово + + + Ignore + Ignore Spelling context menu item + Пропустить + + + Add To Dictionary + Learn Spelling context menu item + Добавить в словарь + + + Search The Web + Search The Web context menu item + Искать в Интернет + + + Look Up In Dictionary + Look Up in Dictionary context menu item + Искать в словаре + + + Open Link + Open Link context menu item + Открыть ссылку + + + Ignore + Ignore Grammar context menu item + Пропустить + + + Spelling + Spelling and Grammar context sub-menu item + Орфография + + + Show Spelling and Grammar + menu item title + Показать панель проверки правописания + + + Hide Spelling and Grammar + menu item title + Скрыть панель проверки правописания + + + Check Spelling + Check spelling context menu item + Проверка орфографии + + + Check Spelling While Typing + Check spelling while typing context menu item + Проверять орфографию при наборе текста + + + Check Grammar With Spelling + Check grammar with spelling context menu item + Проверять грамматику с орфографией + + + Fonts + Font context sub-menu item + Шрифты + + + Bold + Bold context menu item + Жирный + + + Italic + Italic context menu item + Курсив + + + Underline + Underline context menu item + Подчёркнутый + + + Outline + Outline context menu item + Перечёркнутый + + + Direction + Writing direction context sub-menu item + Направление письма + + + Text Direction + Text direction context sub-menu item + Направление текста + + + Default + Default writing direction context menu item + По умолчанию + + + Left to Right + Left to Right context menu item + Слева направо + + + Right to Left + Right to Left context menu item + Справа налево + + + Loading... + Media controller status message when the media is loading + Загрузка... + + + Live Broadcast + Media controller status message when watching a live broadcast + Потоковое вещание + + + Audio Element + Media controller element + Аудио-элемент + + + Video Element + Media controller element + Видеоэлемент + + + Mute Button + Media controller element + Кнопка "Отключить звук" + + + Unmute Button + Media controller element + Кнопка "Включить звук" + + + Play Button + Media controller element + Кнопка воспроизведения + + + Pause Button + Media controller element + Кнопка "Пауза" + + + Slider + Media controller element + Регулятор + + + Slider Thumb + Media controller element + Метка регулятора + + + Rewind Button + Media controller element + Кнопка "Перемотка назад" + + + Return to Real-time Button + Media controller element + Кнопка "Вернуть в реальное время" + + + Elapsed Time + Media controller element + Прошедшее время + + + Remaining Time + Media controller element + Оставшееся время + + + Status Display + Media controller element + Экран состояния + + + Fullscreen Button + Media controller element + Кнопка "На весь экран" + + + Seek Forward Button + Media controller element + Кнопка "Поиск вперед" + + + Seek Back Button + Media controller element + Кнопка "Поиск назад" + + + Audio element playback controls and status display + Media controller element + Органы управления воспроизведением аудио-элементов и отображением состояния + + + Video element playback controls and status display + Media controller element + Органы управления воспроизведением видеоэлементов и отображением состояния + + + Mute audio tracks + Media controller element + Отключить звук аудиодорожек + + + Unmute audio tracks + Media controller element + Включить звук аудиодорожек + + + Begin playback + Media controller element + Начать воспроизведение + + + Pause playback + Media controller element + Воспроизведение после паузы + + + Movie time scrubber + Media controller element + Очиститель времени фильма + + + Movie time scrubber thumb + Media controller element + Метка очистителя времени фильма + + + Rewind movie + Media controller element + Перемотать фильм назад + + + Return streaming movie to real-time + Media controller element + Вернуть потоковое воспроизведение фильма в реальное время + + + Current movie time + Media controller element + Время текущего фильма + + + Remaining movie time + Media controller element + Оставшееся время фильма + + + Current movie status + Media controller element + Состояние текущего фильма + + + Play movie in full-screen mode + Media controller element + Воспроизведение фильма в режиме отображения на весь экран + + + Seek quickly back + Media controller element + Быстрый поиск назад + + + Seek quickly forward + Media controller element + Быстрый поиск вперед + + + Indefinite time + Media time description + Неопределенное время + + + %1 days %2 hours %3 minutes %4 seconds + Media time description + %1 дн. %2 ч. %3 мин. %4 сек. + + + %1 hours %2 minutes %3 seconds + Media time description + %1 ч. %2 мин. %3 сек. + + + %1 minutes %2 seconds + Media time description + %1 мин. %2 сек. + + + %1 seconds + Media time description + %1 сек. + + + Inspect + Inspect Element context menu item + Проверить + + + No recent searches + Label for only item in menu that appears when clicking on the search field image, when no searches have been performed + История поиска пуста + + + Recent searches + label for first item in the menu that appears when clicking on the search field image, used as embedded menu title + История поиска + + + Clear recent searches + menu item in Recent Searches menu that empties menu's contents + Очистить историю поиска + + + Unknown + Unknown filesize FTP directory listing item + Неизвестно + + + Web Inspector - %2 + + + + %1 (%2x%3 pixels) + Title string for images + %1 (%2x%3 px) + + + Bad HTTP request + Некорректный HTTP-запрос + + + This is a searchable index. Enter search keywords: + text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' + Индекс поиска. Введите ключевые слова для поиска: + + + Scroll here + Прокрутить сюда + + + Left edge + К левой границе + + + Top + Вверх + + + Right edge + К правой границе + + + Bottom + Вниз + + + Page left + На страницу влево + + + Page up + На страницу вверх + + + Page right + На страницу вправо + + + Page down + На страницу вниз + + + Scroll left + Прокрутить влево + + + Scroll up + Прокрутить вверх + + + Scroll right + Прокрутить вправо + + + Scroll down + Прокрутить вниз + + + %n file(s) + number of chosen file + + %n файл(а) + %n файла + %n файлов + + + + JavaScript Alert - %1 + JavaScript: Предупреждение - %1 + + + JavaScript Confirm - %1 + JavaScript: Подтверждение - %1 + + + JavaScript Prompt - %1 + JavaScript: Запрос - %1 + + + JavaScript Problem - %1 + JavaScript: Проблема - %1 + + + The script on this page appears to have a problem. Do you want to stop the script? + Сбой выполнения сценария на данной странице. Желаете остановить выполение сценария? + + + Move the cursor to the next character + Переместить указатель к следующему символу + + + Move the cursor to the previous character + Переместить указатель к предыдущему символу + + + Move the cursor to the next word + Переместить указатель к следующему слову + + + Move the cursor to the previous word + Переместить указатель к предыдущему слову + + + Move the cursor to the next line + Переместить указатель на следующую строку + + + Move the cursor to the previous line + Переместить указатель на предыдущую строку + + + Move the cursor to the start of the line + Переместить указатель в начало строки + + + Move the cursor to the end of the line + Переместить указатель в конец строки + + + Move the cursor to the start of the block + Переместить указатель в начало блока + + + Move the cursor to the end of the block + Переместить указатель в конец блока + + + Move the cursor to the start of the document + Переместить указатель в начало документа + + + Move the cursor to the end of the document + Переместить указатель в конец документа + + + Select all + Выделить всё + + + Select to the next character + Выделить до следующего символа + + + Select to the previous character + Выделить до предыдущего символа + + + Select to the next word + Выделить до следующего слова + + + Select to the previous word + Выделить до предыдущего слова + + + Select to the next line + Выделить до следующей строки + + + Select to the previous line + Выделить до предыдущей строки + + + Select to the start of the line + Выделить до начала строки + + + Select to the end of the line + Выделить до конца строки + + + Select to the start of the block + Выделить до начала блока + + + Select to the end of the block + Выделить до конца блока + + + Select to the start of the document + Выделить до начала документа + + + Select to the end of the document + Выделить до конца документа + + + Delete to the start of the word + Удалить до начала слова + + + Delete to the end of the word + Удалить до конца слова + + + Insert a new paragraph + Вставить новый параграф + + + Insert a new line + Вставить новую строку + + + Paste and Match Style + Вставить, сохранив стиль + + + Remove formatting + Удалить форматирование + + + Strikethrough + Зачёркнутый + + + Subscript + Подстрочный + + + Superscript + Надстрочный + + + Insert Bulleted List + Вставить маркированный список + + + Insert Numbered List + Вставить нумерованный список + + + Indent + Увеличить отступ + + + Outdent + Уменьшить отступ + + + Center + По центру + + + Justify + По ширине + + + Align Left + По левому краю + + + Align Right + По правому краю + + + + QWhatsThisAction + + What's This? + + + + + QWidget + + * + + + + + QWizard + + Cancel + + + + Help + + + + < &Back + + + + &Finish + + + + &Help + + + + Go Back + + + + Continue + + + + Commit + + + + Done + + + + &Next + + + + &Next > + + + + + QWorkspace + + &Restore + + + + &Move + + + + &Size + + + + Mi&nimize + + + + Ma&ximize + + + + &Close + + + + Stay on &Top + + + + Minimize + + + + Restore Down + + + + Close + + + + Sh&ade + + + + %1 - [%2] + + + + &Unshade + + + + + QXml + + no error occurred + + + + error triggered by consumer + + + + unexpected end of file + + + + more than one document type definition + + + + error occurred while parsing element + + + + tag mismatch + + + + error occurred while parsing content + + + + unexpected character + + + + invalid name for processing instruction + + + + version expected while reading the XML declaration + + + + wrong value for standalone declaration + + + + error occurred while parsing document type definition + + + + letter is expected + + + + error occurred while parsing comment + + + + error occurred while parsing reference + + + + internal general entity reference not allowed in DTD + + + + external parsed general entity reference not allowed in attribute value + + + + external parsed general entity reference not allowed in DTD + + + + unparsed entity reference in wrong context + + + + recursive entities + + + + error in the text declaration of an external entity + + + + encoding declaration or standalone declaration expected while reading the XML declaration + + + + standalone declaration expected while reading the XML declaration + + + + + QXmlPatternistCLI + + Warning in %1, at line %2, column %3: %4 + Предупреждение в %1, в строке %2, столбце%3: %4 + + + Warning in %1: %2 + Предупреждение в %1: %2 + + + Unknown location + Неизвестное местоположение + + + Error %1 in %2, at line %3, column %4: %5 + Ошибка %1 в %2, в строке %3, столбце %4: %5 + + + Error %1 in %2: %3 + Ошибка %1 в %2: %3 + + + + QXmlStream + + Extra content at end of document. + + + + Invalid entity value. + + + + Invalid XML character. + + + + Sequence ']]>' not allowed in content. + + + + Namespace prefix '%1' not declared + + + + Attribute redefined. + + + + Unexpected character '%1' in public id literal. + + + + Invalid XML version string. + + + + Unsupported XML version. + + + + %1 is an invalid encoding name. + + + + Encoding %1 is unsupported + + + + Standalone accepts only yes or no. + + + + Invalid attribute in XML declaration. + + + + Premature end of document. + + + + Invalid document. + + + + Expected + + + + , but got ' + + + + Unexpected ' + + + + Expected character data. + + + + Recursive entity detected. + + + + Start tag expected. + + + + XML declaration not at start of document. + + + + NDATA in parameter entity declaration. + + + + %1 is an invalid processing instruction name. + + + + Invalid processing instruction name. + + + + Illegal namespace declaration. + + + + Invalid XML name. + + + + Opening and ending tag mismatch. + + + + Reference to unparsed entity '%1'. + + + + Entity '%1' not declared. + + + + Reference to external entity '%1' in attribute value. + + + + Invalid character reference. + + + + Encountered incorrectly encoded content. + + + + The standalone pseudo attribute must appear after the encoding. + + + + %1 is an invalid PUBLIC identifier. + + + + + QtXmlPatterns + + At least one component must be present. + Должна присутствовать как минимум одна компонента. + + + %1 is not a valid value of type %2. + %1 не является правильным значением типа %2. + + + When casting to %1 from %2, the source value cannot be %3. + При преобразовании %2 в %1 исходное значение не может быть %3. + + + Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values. + Булево значение не может быть вычислено для последовательностей, которые содержат два и более атомарных значения. + + + The data of a processing instruction cannot contain the string %1 + Данные обрабатываемой инструкции не могут содержать строку '%1' + + + %1 is an invalid %2 + %1 некоррекно для %2 + + + %1 is not a valid XML 1.0 character. + Символ %1 недопустим для XML 1.0. + + + %1 was called. + %1 было вызвано. + + + In the replacement string, %1 must be followed by at least one digit when not escaped. + В замещаемой строке '%1' должно сопровождаться как минимум одной цифрой, если неэкранировано. + + + In the replacement string, %1 can only be used to escape itself or %2, not %3 + В замещаемой строке символ '%1' может использоваться только для экранирования самого себя или '%2', но не '%3' + + + %1 matches newline characters + %1 соответствует символам конца строки + + + Matches are case insensitive + Соответствия регистронезависимы + + + %1 is an invalid regular expression pattern: %2 + %1 - неверный шаблон регулярного выражения: %2 + + + It will not be possible to retrieve %1. + Будет невозможно восстановить %1. + + + The default collection is undefined + Набор по умолчанию не определён + + + %1 cannot be retrieved + %1 не может быть восстановлен + + + The item %1 did not match the required type %2. + Элемент %1 не соответствует необходимому типу %2. + + + %1 is an unknown schema type. + %1 является схемой неизвестного типа. + + + A template with name %1 has already been declared. + + + + Only one %1 declaration can occur in the query prolog. + Только одно объявление %1 может присутствовать в прологе запроса. + + + The initialization of variable %1 depends on itself + Инициализация переменной %1 зависит от себя самой + + + The variable %1 is unused + Переменная %1 не используется + + + Version %1 is not supported. The supported XQuery version is 1.0. + Версия %1 не поддерживается. Поддерживается XQuery версии 1.0. + + + No function with signature %1 is available + Функция с сигнатурой %1 отсутствует + + + It is not possible to redeclare prefix %1. + Невозможно переопределить префикс %1. + + + Prefix %1 is already declared in the prolog. + Префикс %1 уже объявлен в прологе. + + + The name of an option must have a prefix. There is no default namespace for options. + Название опции должно содержать префикс. Нет пространства имён по умолчанию для опций. + + + The Schema Import feature is not supported, and therefore %1 declarations cannot occur. + Возможность импорта схем не поддерживается, следовательно, объявлений %1 быть не должно. + + + The target namespace of a %1 cannot be empty. + Целевое пространство имён %1 не может быть пустым. + + + The module import feature is not supported + Возможность импорта модулей не поддерживается + + + The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2 + Пространство имён пользовательской функции в модуле библиотеки должен соответствовать пространству имён модуля. Другими словами, он должен быть %1 вместо %2 + + + A function already exists with the signature %1. + Функция с сигнатурой %1 уже существует. + + + No external functions are supported. All supported functions can be used directly, without first declaring them as external + Внешние функции не поддерживаются. Все поддерживаемые функции могут использоваться напрямую без первоначального объявления их в качестве внешних + + + The %1-axis is unsupported in XQuery + Ось %1 не поддерживается в XQuery + + + The namespace URI cannot be the empty string when binding to a prefix, %1. + URI пространства имён не может быть пустой строкой при связывании с префиксом %1. + + + %1 is an invalid namespace URI. + %1 - неверный URI пространства имён. + + + It is not possible to bind to the prefix %1 + Невозможно связать с префиксом %1 + + + Two namespace declaration attributes have the same name: %1. + Два атрибута объявления пространств имён имеют одинаковое имя: %1. + + + The namespace URI must be a constant and cannot use enclosed expressions. + URI пространства имён должно быть константой и не может содержать выражений. + + + %1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported. + %1 является объявлением атрибута вне области объявлений. Имейте в виду, возможность импорта схем не поддерживается. + + + empty + пусто + + + zero or one + нуль или один + + + exactly one + ровно один + + + one or more + один или более + + + zero or more + нуль или более + + + The focus is undefined. + Фокус не определён. + + + An attribute by name %1 has already been created. + Атрибут с именем %1 уже существует. + + + Network timeout. + Время ожидания сети истекло. + + + Element %1 can't be serialized because it appears outside the document element. + Элемент %1 не может быть сериализован, так как присутствует вне документа. + + + Year %1 is invalid because it begins with %2. + Год %1 неверен, так как начинается с %2. + + + Day %1 is outside the range %2..%3. + День %1 вне диапазона %2..%3. + + + Month %1 is outside the range %2..%3. + Месяц %1 вне диапазона %2..%3. + + + Overflow: Can't represent date %1. + Переполнение: Не удается представить дату %1. + + + Day %1 is invalid for month %2. + День %1 неверен для месяца %2. + + + Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; + Время 24:%1:%2.%3 неверно. 24 часа, но минуты, секунды и/или миллисекунды отличны от 0; + + + Time %1:%2:%3.%4 is invalid. + Время %1:%2:%3.%4 неверно. + + + Overflow: Date can't be represented. + Переполнение: невозможно представить дату. + + + At least one time component must appear after the %1-delimiter. + Как минимум одна компонента времени должна следовать за разделителем '%1'. + + + Dividing a value of type %1 by %2 (not-a-number) is not allowed. + Деление числа типа %1 на %2 (не числовое выражение) недопустимо. + + + Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed. + Деление числа типа %1 на %2 или %3 (плюс или минус нуль) недопустимо. + + + Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed. + Умножение числа типа %1 на %2 или %3 (плюс-минус бесконечность) недопустимо. + + + A value of type %1 cannot have an Effective Boolean Value. + Значение типа %1 не может быть булевым значением. + + + Value %1 of type %2 exceeds maximum (%3). + Значение %1 типа %2 больше максимума (%3). + + + Value %1 of type %2 is below minimum (%3). + Значение %1 типа %2 меньше минимума (%3). + + + A value of type %1 must contain an even number of digits. The value %2 does not. + Значение типа %1 должно содержать четное количество цифр. Значение %2 этому требованию не удовлетворяет. + + + %1 is not valid as a value of type %2. + Значение %1 некорректно для типа %2. + + + Operator %1 cannot be used on type %2. + Оператор %1 не может использоваться для типа %2. + + + Operator %1 cannot be used on atomic values of type %2 and %3. + Оператор %1 не может использоваться для атомарных значений типов %2 и %3. + + + The namespace URI in the name for a computed attribute cannot be %1. + URI пространства имён в названии рассчитываемого атрибута не может быть %1. + + + The name for a computed attribute cannot have the namespace URI %1 with the local name %2. + Название расчитываемого атрибута не может иметь URI пространства имён %1 с локальным именем %2. + + + Type error in cast, expected %1, received %2. + Ошибка типов в преобразовании, ожидалось %1, получено %2. + + + When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed. + При преобразовании в %1 или производные от него типы исходное значение должно быть того же типа или строковым литералом. Тип %2 недопустим. + + + A comment cannot contain %1 + Комментарий не может содержать %1 + + + A comment cannot end with a %1. + Комментарий не может оканчиваться на %1. + + + An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place. + Узел-атрибут не может быть потомком узла-документа. Атрибут %1 неуместен. + + + A library module cannot be evaluated directly. It must be imported from a main module. + Модуль библиотеки не может использоваться напрямую. Он должен быть импортирован из основного модуля. + + + No template by name %1 exists. + Шаблон с именем %1 отсутствует. + + + A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type. + Значение типа %1 не может быть условием. Условием могут являться числовой и булевый типы. + + + A positional predicate must evaluate to a single numeric value. + Позиционный предикат должен вычисляться как числовое выражение. + + + The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, %2 is invalid. + Целевое имя в обрабатываемой инструкции не может быть %1 в любой комбинации нижнего и верхнего регистров. Имя %2 некорректно. + + + %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. + %1 некорректное целевое имя в обрабатываемой инструкции. Имя должно быть значением типа %2, например: %3. + + + The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. + Последняя часть пути должна содержать узлы или атомарные значения, но не может содержать и то, и другое одновременно. + + + No namespace binding exists for the prefix %1 + Отсутствует привязка к пространству имён для префикса %1 + + + No namespace binding exists for the prefix %1 in %2 + Отсутствует привязка к пространству имён для префикса %1 в %2 + + + The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration. + Первый аргумент %1 не может быть типа %2. Он должен быть числового типа, типа xs:yearMonthDuration или типа xs:dayTimeDuration. + + + The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + Первый аргумент %1 не может быть типа %2. Он должен быть типа %3, %4 или %5. + + + The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + Второй аргумент %1 не может быть типа %2. Он должен быть типа %3, %4 или %5. + + + If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same. + Если оба значения имеют региональные смещения, смещения должны быть одинаковы. %1 и %2 не одинаковы. + + + %1 must be followed by %2 or %3, not at the end of the replacement string. + '%1' должно сопровождаться '%2' или '%3', но не в конце замещаемой строки. + + + %1 and %2 match the start and end of a line. + %1 и %2 соответствуют началу и концу строки. + + + Whitespace characters are removed, except when they appear in character classes + Символы пробелов удалены, за исключением тех, что были в классах символов + + + %1 is an invalid flag for regular expressions. Valid flags are: + %1 - неверный флаг для регулярного выражения. Допустимые флаги: + + + If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified. + Префикс не должен быть указан, если первый параметр - пустая последовательность или пустая строка (вне пространства имён). Был указан префикс %1. + + + The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization). + Форма нормализации %1 не поддерживается. Поддерживаются только %2, %3, %4, %5 и пустая, т.е. пустая строка (без нормализации). + + + A zone offset must be in the range %1..%2 inclusive. %3 is out of range. + Региональное смещение должно быть в переделах от %1 до %2 включительно. %3 выходит за допустимые пределы. + + + Required cardinality is %1; got cardinality %2. + Необходимо %1 элементов, получено %2. + + + The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2. + Кодировка %1 неверна. Имя кодировки должно содержать только символы латиницы без пробелов и должно удовлетворять регулярному выражению %2. + + + The keyword %1 cannot occur with any other mode name. + Ключевое слово %1 не может встречаться с любым другим названием режима. + + + No variable with name %1 exists + + + + The value of attribute %1 must be of type %2, which %3 isn't. + + + + The prefix %1 cannot be bound. By default, it is already bound to the namespace %2. + + + + A variable with name %1 has already been declared. + + + + No value is available for the external variable with name %1. + + + + A stylesheet function must have a prefixed name. + Функция стилей должна иметь имя с префиксом. + + + The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. + Пространтсво имён %1 зарезервировано, поэтому пользовательские функции не могут его использовать. Попробуйте предопределённый префикс %2, который существует для подобных ситуаций. + + + An argument with name %1 has already been declared. Every argument name must be unique. + + + + When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. + Если функция %1 используется для сравнения внутри шаблона, аргумент должен быть ссылкой на переменную или строковым литералом. + + + In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching. + В шаблоне XSL-T первый аргумент функции %1 должен быть строковым литералом, если функция используется для сравнения. + + + In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching. + В шаблоне XSL-T первый аргумент функции %1 должен быть литералом или ссылкой на переменную, если функция используется для сравнения. + + + In an XSL-T pattern, function %1 cannot have a third argument. + В шаблоне XSL-T у функции %1 не должно быть третьего аргумента. + + + In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. + В шаблоне XSL-T только функции %1 и %2 могут использоваться для сравнения, но не %3. + + + In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can. + В шаблоне XSL-T не может быть использована ось %1 - только оси %2 или %3. + + + %1 is an invalid template mode name. + %1 является неверным шаблоном имени режима. + + + The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. + Имя переменной, связанной с выражением for, должно отличаться от позиционной переменной. Две переменные с именем %1 конфликтуют. + + + The Schema Validation Feature is not supported. Hence, %1-expressions may not be used. + Возможность проверки по схеме не поддерживается. Выражения %1 не могут использоваться. + + + None of the pragma expressions are supported. Therefore, a fallback expression must be present + Ни одно из выражений pragma не поддерживается. Должно существовать запасное выражение + + + Each name of a template parameter must be unique; %1 is duplicated. + Имя каждого параметра шаблона должно быть уникальным, но %1 повторяется. + + + No function with name %1 is available. + + + + %1 is not a valid numeric literal. + %1 является неверным числовым литералом. + + + W3C XML Schema identity constraint selector + + + + W3C XML Schema identity constraint field + + + + A construct was encountered which is disallowed in the current language(%1). + Встречена конструкция, запрещённая для текущего языка (%1). + + + Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared). + Пространство имён %1 может быть связано только с %2 (в данном случае уже предопределено). + + + Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared). + Префикс %1 может быть связан только с %2 (в данном случае уже предопределено). + + + An attribute with name %1 has already appeared on this element. + + + + A direct element constructor is not well-formed. %1 is ended with %2. + Прямой конструктор элемента составлен некорректно. %1 заканчивается на %2. + + + The name %1 does not refer to any schema type. + Название %1 не соответствует ни одному типу схемы. + + + %1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works. + %1 - сложный тип. Преобразование к сложным типам невозможно. Однако, преобразование к атомарным типам как %2 работает. + + + %1 is not an atomic type. Casting is only possible to atomic types. + %1 - не атомарный тип. Преобразование возможно только к атомарным типам. + + + %1 is not a valid name for a processing-instruction. + %1 является неверным названием для инструкции обработки. + + + The name of an extension expression must be in a namespace. + Название выражения расширения должно быть в пространстве имён. + + + Required type is %1, but %2 was found. + Требуется тип %1, но обнаружен %2. + + + Promoting %1 to %2 may cause loss of precision. + Преобразование %1 к %2 может снизить точность. + + + It's not possible to add attributes after any other kind of node. + Невозможно добавлять атрибуты после любого другого вида узла. + + + Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported. + Поддерживается только Unicode Codepoint Collation (%1). %2 не поддерживается. + + + Integer division (%1) by zero (%2) is undefined. + Целочисленное деление (%1) на нуль (%2) не определено. + + + Division (%1) by zero (%2) is undefined. + Деление (%1) на нуль (%2) не определено. + + + Modulus division (%1) by zero (%2) is undefined. + Деление по модулю (%1) на нуль (%2) не определено. + + + %1 takes at most %n argument(s). %2 is therefore invalid. + + %1 принимает не более %n аргумента. Следовательно, %2 неверно. + %1 принимает не более %n аргументов. Следовательно, %2 неверно. + %1 принимает не более %n аргументов. Следовательно, %2 неверно. + + + + %1 requires at least %n argument(s). %2 is therefore invalid. + + %1 принимает не менее %n аргумента. Следовательно, %2 неверно. + %1 принимает не менее %n аргументов. Следовательно, %2 неверно. + %1 принимает не менее %n аргументов. Следовательно, %2 неверно. + + + + The root node of the second argument to function %1 must be a document node. %2 is not a document node. + Корневой узел второго аргумента функции %1 должен быть документом. %2 не является документом. + + + The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) + Пространство имён для пользовательских функций не может быть пустым (попробуйте предопределённый префикс %1, который существует для подобных ситуаций) + + + A default namespace declaration must occur before function, variable, and option declarations. + Объявление пространство имён по умолчанию должно быть до объявления функций, переменных и опций. + + + Namespace declarations must occur before function, variable, and option declarations. + Объявление пространства имён должно быть до объявления функций, переменных и опций. + + + Module imports must occur before function, variable, and option declarations. + Импортируемые модули должны быть указаны до объявления функций, переменных и опций. + + + %1 is not a whole number of minutes. + %1 не является полным количеством минут. + + + Attribute %1 can't be serialized because it appears at the top level. + Атрибут %1 не может быть сериализован, так как присутствует на верхнем уровне. + + + %1 is an unsupported encoding. + Кодировка %1 не поддерживается. + + + %1 contains octets which are disallowed in the requested encoding %2. + %1 содержит октеты, которые недопустимы в требуемой кодировке %2. + + + The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character. + Символ с кодом %1, присутствующий в %2 при использовании кодировки %3, не является допустимым символом XML. + + + Ambiguous rule match. + Неоднозначное соответствие правилу. + + + In a namespace constructor, the value for a namespace cannot be an empty string. + В конструкторе пространства имён значение пространства имён не может быть пустой строкой. + + + The prefix must be a valid %1, which %2 is not. + Префикс должен быть корректным %1, но %2 им не является. + + + The prefix %1 cannot be bound. + Префикс%1 не может быть связан. + + + Only the prefix %1 can be bound to %2 and vice versa. + Только префикс %1 может быть связан с %2 и наоборот. + + + The parameter %1 is required, but no corresponding %2 is supplied. + Необходим параметр %1 , но соответствующего %2 не передано. + + + The parameter %1 is passed, but no corresponding %2 exists. + Передан параметр %1 , но соответствующего %2 не существует. + + + The URI cannot have a fragment + URI не может содержать фрагмент + + + Element %1 is not allowed at this location. + Элемент %1 недопустим в этом месте. + + + Text nodes are not allowed at this location. + Текстовые узлы недопустимы в этом месте. + + + Parse error: %1 + Ошибка разбора: %1 + + + The value of the XSL-T version attribute must be a value of type %1, which %2 isn't. + Значение атрибута версии XSL-T должно быть типа %1, но %2 им не является. + + + Running an XSL-T 1.0 stylesheet with a 2.0 processor. + Выполняется таблица стилей XSL-T 1.0 с обработчиком версии 2.0. + + + Unknown XSL-T attribute %1. + Неизвествный атрибут XSL-T %1. + + + Attribute %1 and %2 are mutually exclusive. + Атрибуты %1 и %2 взаимоисключающие. + + + In a simplified stylesheet module, attribute %1 must be present. + В модуле упрощённой таблицы стилей обязан присутствовать атрибут %1. + + + If element %1 has no attribute %2, it cannot have attribute %3 or %4. + Если элемент %1 не имеет атрибут %2, у него не может быть атрибутов %3 и %4. + + + Element %1 must have at least one of the attributes %2 or %3. + Элемент %1 должен иметь как минимум один из атрибутов %2 или %3. + + + At least one mode must be specified in the %1-attribute on element %2. + Как минимум один режим должен быть указан в атрибуте %1 элемента %2. + + + Element %1 must come last. + Элемент %1 должен идти последним. + + + At least one %1-element must occur before %2. + Как минимум один элемент %1 должен быть перед %2. + + + Only one %1-element can appear. + Должен быть только один элемент %1. + + + At least one %1-element must occur inside %2. + Как минимум один элемент %1 должен быть внутри %2. + + + When attribute %1 is present on %2, a sequence constructor cannot be used. + Если %2 содержит атрибут %1, конструктор последовательности не может быть использован. + + + Element %1 must have either a %2-attribute or a sequence constructor. + Элемент %1 должен иметь атрибут %2 или конструктор последовательности. + + + When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor. + Если параметр необходим, значение по умолчание не может быть передано через атрибут %1 или конструктор последовательности. + + + Element %1 cannot have children. + У элемента %1 не может быть потомков. + + + Element %1 cannot have a sequence constructor. + У элемента %1 не может быть конструктора последовательности. + + + The attribute %1 cannot appear on %2, when it is a child of %3. + У %2 не может быть атрибута %1, когда он является потомком %3. + + + A parameter in a function cannot be declared to be a tunnel. + Параметр в функции не может быть объявлен туннелем. + + + This processor is not Schema-aware and therefore %1 cannot be used. + Данный обработчик не работает со схемами, следовательно, %1 не может использоваться. + + + Top level stylesheet elements must be in a non-null namespace, which %1 isn't. + Элементы верхнего уровня таблицы стилей должны быть в пространстве имен, которым %1 не является. + + + The value for attribute %1 on element %2 must either be %3 or %4, not %5. + Значение атрибута %1 элемента %2 должно быть или %3, или %4, но не %5. + + + Attribute %1 cannot have the value %2. + Атрибут %1 не может принимать значение %2. + + + The attribute %1 can only appear on the first %2 element. + Атрибут %1 может быть только у первого элемента %2. + + + At least one %1 element must appear as child of %2. + Как минимум один элемент %1 должен быть в %2. + + + %1 has inheritance loop in its base type %2. + + + + Circular inheritance of base type %1. + + + + Circular inheritance of union %1. + + + + %1 is not allowed to derive from %2 by restriction as the latter defines it as final. + + + + %1 is not allowed to derive from %2 by extension as the latter defines it as final. + + + + Base type of simple type %1 cannot be complex type %2. + + + + Simple type %1 cannot have direct base type %2. + + + + Simple type %1 is not allowed to have base type %2. + + + + Simple type %1 can only have simple atomic type as base type. + + + + Simple type %1 cannot derive from %2 as the latter defines restriction as final. + + + + Variety of item type of %1 must be either atomic or union. + + + + Variety of member types of %1 must be atomic. + + + + %1 is not allowed to derive from %2 by list as the latter defines it as final. + + + + Simple type %1 is only allowed to have %2 facet. + + + + Base type of simple type %1 must have variety of type list. + + + + Base type of simple type %1 has defined derivation by restriction as final. + + + + Item type of base type does not match item type of %1. + + + + Simple type %1 contains not allowed facet type %2. + + + + %1 is not allowed to derive from %2 by union as the latter defines it as final. + + + + %1 is not allowed to have any facets. + + + + Base type %1 of simple type %2 must have variety of union. + + + + Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute. + + + + Member type %1 cannot be derived from member type %2 of %3's base type %4. + + + + Derivation method of %1 must be extension because the base type %2 is a simple type. + + + + Complex type %1 has duplicated element %2 in its content model. + + + + Complex type %1 has non-deterministic content. + + + + Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3. + + + + Content model of complex type %1 is not a valid extension of content model of %2. + + + + Complex type %1 must have simple content. + + + + Complex type %1 must have the same simple type as its base class %2. + + + + Complex type %1 cannot be derived from base type %2%3. + + + + Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3. + + + + Complex type %1 with simple content cannot be derived from complex base type %2. + + + + Item type of simple type %1 cannot be a complex type. + + + + Member type of simple type %1 cannot be a complex type. + + + + %1 is not allowed to have a member type with the same name as itself. + + + + %1 facet collides with %2 facet. + + + + %1 facet must have the same value as %2 facet of base type. + + + + %1 facet must be equal or greater than %2 facet of base type. + + + + %1 facet must be less than or equal to %2 facet of base type. + + + + %1 facet contains invalid regular expression + + + + Unknown notation %1 used in %2 facet. + + + + %1 facet contains invalid value %2: %3. + + + + %1 facet cannot be %2 or %3 if %4 facet of base type is %5. + + + + %1 facet cannot be %2 if %3 facet of base type is %4. + + + + %1 facet must be less than or equal to %2 facet. + + + + %1 facet must be less than %2 facet of base type. + + + + %1 facet and %2 facet cannot appear together. + + + + %1 facet must be greater than %2 facet of base type. + + + + %1 facet must be less than %2 facet. + + + + %1 facet must be greater than or equal to %2 facet of base type. + + + + Simple type contains not allowed facet %1. + + + + %1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list. + + + + Only %1 and %2 facets are allowed when derived by union. + + + + %1 contains %2 facet with invalid data: %3. + + + + Attribute group %1 contains attribute %2 twice. + + + + Attribute group %1 contains two different attributes that both have types derived from %2. + + + + Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3. + + + + Complex type %1 contains attribute %2 twice. + + + + Complex type %1 contains two different attributes that both have types derived from %2. + + + + Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3. + + + + Element %1 is not allowed to have a value constraint if its base type is complex. + + + + Element %1 is not allowed to have a value constraint if its type is derived from %2. + + + + Value constraint of element %1 is not of elements type: %2. + + + + Element %1 is not allowed to have substitution group affiliation as it is no global element. + + + + Type of element %1 cannot be derived from type of substitution group affiliation. + + + + Value constraint of attribute %1 is not of attributes type: %2. + + + + Attribute %1 has value constraint but has type derived from %2. + + + + %1 attribute in derived complex type must be %2 like in base type. + + + + Attribute %1 in derived complex type must have %2 value constraint like in base type. + + + + Attribute %1 in derived complex type must have the same %2 value constraint like in base type. + + + + Attribute %1 in derived complex type must have %2 value constraint. + + + + processContent of base wildcard must be weaker than derived wildcard. + + + + Element %1 exists twice with different types. + + + + Particle contains non-deterministic wildcards. + + + + Base attribute %1 is required but derived attribute is not. + + + + Type of derived attribute %1 cannot be validly derived from type of base attribute. + + + + Value constraint of derived attribute %1 does not match value constraint of base attribute. + + + + Derived attribute %1 does not exist in the base definition. + + + + Derived attribute %1 does not match the wildcard in the base definition. + + + + Base attribute %1 is required but missing in derived definition. + + + + Derived definition contains an %1 element that does not exists in the base definition + + + + Derived wildcard is not a subset of the base wildcard. + + + + %1 of derived wildcard is not a valid restriction of %2 of base wildcard + + + + Attribute %1 from base type is missing in derived type. + + + + Type of derived attribute %1 differs from type of base attribute. + + + + Base definition contains an %1 element that is missing in the derived definition + + + + %1 references unknown %2 or %3 element %4. + + + + %1 references identity constraint %2 that is no %3 or %4 element. + + + + %1 has a different number of fields from the identity constraint %2 that it references. + + + + Base type %1 of %2 element cannot be resolved. + + + + Item type %1 of %2 element cannot be resolved. + + + + Member type %1 of %2 element cannot be resolved. + + + + Type %1 of %2 element cannot be resolved. + + + + Base type %1 of complex type cannot be resolved. + + + + %1 cannot have complex base type that has a %2. + + + + Content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type. + + + + Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model. + + + + Type of %1 element must be a simple type, %2 is not. + + + + Substitution group %1 of %2 element cannot be resolved. + + + + Substitution group %1 has circular definition. + + + + Duplicated element names %1 in %2 element. + + + + Reference %1 of %2 element cannot be resolved. + + + + Circular group reference for %1. + + + + %1 element is not allowed in this scope + + + + %1 element cannot have %2 attribute with value other than %3. + + + + %1 element cannot have %2 attribute with value other than %3 or %4. + + + + %1 or %2 attribute of reference %3 does not match with the attribute declaration %4. + + + + Attribute group %1 has circular reference. + + + + %1 attribute in %2 must have %3 use like in base type %4. + + + + Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2. + + + + %1 has attribute wildcard but its base type %2 has not. + + + + Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible. + + + + Enumeration facet contains invalid content: {%1} is not a value of type %2. + + + + Namespace prefix of qualified name %1 is not defined. + + + + %1 element %2 is not a valid restriction of the %3 element it redefines: %4. + + + + Empty particle cannot be derived from non-empty particle. + + + + Derived particle is missing element %1. + + + + Derived element %1 is missing value constraint as defined in base particle. + + + + Derived element %1 has weaker value constraint than base particle. + + + + Fixed value constraint of element %1 differs from value constraint in base particle. + + + + Derived element %1 cannot be nillable as base element is not nillable. + + + + Block constraints of derived element %1 must not be more weaker than in the base element. + + + + Simple type of derived element %1 cannot be validly derived from base element. + + + + Complex type of derived element %1 cannot be validly derived from base element. + + + + Element %1 is missing in derived particle. + + + + Element %1 does not match namespace constraint of wildcard in base particle. + + + + Wildcard in derived particle is not a valid subset of wildcard in base particle. + + + + processContent of wildcard in derived particle is weaker than wildcard in base particle. + + + + Derived particle allows content that is not allowed in the base particle. + + + + Can not process unknown element %1, expected elements are: %2. + + + + Element %1 is not allowed in this scope, possible elements are: %2. + + + + Child element is missing in that scope, possible child elements are: %1. + + + + Document is not a XML schema. + + + + %1 attribute of %2 element contains invalid content: {%3} is not a value of type %4. + + + + %1 attribute of %2 element contains invalid content: {%3}. + + + + Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema. + + + + Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema. + + + + %1 element is not allowed to have the same %2 attribute value as the target namespace %3. + + + + %1 element without %2 attribute is not allowed inside schema without target namespace. + + + + %1 element is not allowed inside %2 element if %3 attribute is present. + + + + %1 element has neither %2 attribute nor %3 child element. + + + + %1 element with %2 child element must not have a %3 attribute. + + + + %1 attribute of %2 element must be %3 or %4. + + + + %1 attribute of %2 element must have a value of %3. + + + + %1 attribute of %2 element must have a value of %3 or %4. + + + + %1 element must not have %2 and %3 attribute together. + + + + Content of %1 attribute of %2 element must not be from namespace %3. + + + + %1 attribute of %2 element must not be %3. + + + + %1 attribute of %2 element must have the value %3 because the %4 attribute is set. + + + + Specifying use='prohibited' inside an attribute group has no effect. + + + + %1 element must have either %2 or %3 attribute. + + + + %1 element must have either %2 attribute or %3 or %4 as child element. + + + + %1 element requires either %2 or %3 attribute. + + + + Text or entity references not allowed inside %1 element + + + + %1 attribute of %2 element must contain %3, %4 or a list of URIs. + + + + %1 element is not allowed in this context. + + + + %1 attribute of %2 element has larger value than %3 attribute. + + + + Prefix of qualified name %1 is not defined. + + + + %1 attribute of %2 element must either contain %3 or the other values. + + + + Component with ID %1 has been defined previously. + + + + Element %1 already defined. + + + + Attribute %1 already defined. + + + + Type %1 already defined. + + + + Attribute group %1 already defined. + + + + Element group %1 already defined. + + + + Notation %1 already defined. + + + + Identity constraint %1 already defined. + + + + Duplicated facets in simple type %1. + + + + %1 is not valid according to %2. + + + + String content does not match the length facet. + + + + String content does not match the minLength facet. + + + + String content does not match the maxLength facet. + + + + String content does not match pattern facet. + + + + String content is not listed in the enumeration facet. + + + + Signed integer content does not match the maxInclusive facet. + + + + Signed integer content does not match the maxExclusive facet. + + + + Signed integer content does not match the minInclusive facet. + + + + Signed integer content does not match the minExclusive facet. + + + + Signed integer content is not listed in the enumeration facet. + + + + Signed integer content does not match pattern facet. + + + + Signed integer content does not match in the totalDigits facet. + + + + Unsigned integer content does not match the maxInclusive facet. + + + + Unsigned integer content does not match the maxExclusive facet. + + + + Unsigned integer content does not match the minInclusive facet. + + + + Unsigned integer content does not match the minExclusive facet. + + + + Unsigned integer content is not listed in the enumeration facet. + + + + Unsigned integer content does not match pattern facet. + + + + Unsigned integer content does not match in the totalDigits facet. + + + + Double content does not match the maxInclusive facet. + + + + Double content does not match the maxExclusive facet. + + + + Double content does not match the minInclusive facet. + + + + Double content does not match the minExclusive facet. + + + + Double content is not listed in the enumeration facet. + + + + Double content does not match pattern facet. + + + + Decimal content does not match in the fractionDigits facet. + + + + Decimal content does not match in the totalDigits facet. + + + + Date time content does not match the maxInclusive facet. + + + + Date time content does not match the maxExclusive facet. + + + + Date time content does not match the minInclusive facet. + + + + Date time content does not match the minExclusive facet. + + + + Date time content is not listed in the enumeration facet. + + + + Date time content does not match pattern facet. + + + + Duration content does not match the maxInclusive facet. + + + + Duration content does not match the maxExclusive facet. + + + + Duration content does not match the minInclusive facet. + + + + Duration content does not match the minExclusive facet. + + + + Duration content is not listed in the enumeration facet. + + + + Duration content does not match pattern facet. + + + + Boolean content does not match pattern facet. + + + + Binary content does not match the length facet. + + + + Binary content does not match the minLength facet. + + + + Binary content does not match the maxLength facet. + + + + Binary content is not listed in the enumeration facet. + + + + Invalid QName content: %1. + + + + QName content is not listed in the enumeration facet. + + + + QName content does not match pattern facet. + + + + Notation content is not listed in the enumeration facet. + + + + List content does not match length facet. + + + + List content does not match minLength facet. + + + + List content does not match maxLength facet. + + + + List content is not listed in the enumeration facet. + + + + List content does not match pattern facet. + + + + Union content is not listed in the enumeration facet. + + + + Union content does not match pattern facet. + + + + Data of type %1 are not allowed to be empty. + + + + Element %1 is missing child element. + + + + There is one IDREF value with no corresponding ID: %1. + + + + Loaded schema file is invalid. + + + + %1 contains invalid data. + + + + xsi:schemaLocation namespace %1 has already appeared earlier in the instance document. + + + + xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute. + + + + No schema defined for validation. + + + + No definition for element %1 available. + + + + Specified type %1 is not known to the schema. + + + + Element %1 is not defined in this scope. + + + + Declaration for element %1 does not exist. + + + + Element %1 contains invalid content. + + + + Element %1 is declared as abstract. + + + + Element %1 is not nillable. + + + + Attribute %1 contains invalid data: %2 + + + + Element contains content although it is nillable. + + + + Fixed value constraint not allowed if element is nillable. + + + + Element %1 cannot contain other elements, as it has a fixed content. + + + + Specified type %1 is not validly substitutable with element type %2. + + + + Complex type %1 is not allowed to be abstract. + + + + Element %1 contains not allowed attributes. + + + + Element %1 contains not allowed child element. + + + + Content of element %1 does not match its type definition: %2. + + + + Content of element %1 does not match defined value constraint. + + + + Element %1 contains not allowed child content. + + + + Element %1 contains not allowed text content. + + + + Element %1 is missing required attribute %2. + + + + Attribute %1 does not match the attribute wildcard. + + + + Declaration for attribute %1 does not exist. + + + + Element %1 contains two attributes of type %2. + + + + Attribute %1 contains invalid content. + + + + Element %1 contains unknown attribute %2. + + + + Content of attribute %1 does not match its type definition: %2. + + + + Content of attribute %1 does not match defined value constraint. + + + + Non-unique value found for constraint %1. + + + + Key constraint %1 contains absent fields. + + + + Key constraint %1 contains references nillable element %2. + + + + No referenced value found for key reference %1. + + + + More than one value found for field %1. + + + + Field %1 has no simple type. + + + + ID value '%1' is not unique. + + + + '%1' attribute contains invalid QName content: %2. + + + + diff --git a/config.profiles/symbian/translations/qt_ur.ts b/config.profiles/symbian/translations/qt_ur.ts new file mode 100644 index 0000000..13797d5 --- /dev/null +++ b/config.profiles/symbian/translations/qt_ur.ts @@ -0,0 +1,8507 @@ + + + + + + CloseButton + + Close Tab + + + + + FakeReply + + Fake error ! + + + + Invalid URL + + + + + Phonon:: + + Notifications + + + + Music + + + + Video + + + + Communication + + + + Games + + + + Accessibility + + + + + Phonon::AudioOutput + + <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> + + + + <html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html> + + + + Revert back to device '%1' + + + + + Phonon::Gstreamer::Backend + + Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. + Some video features have been disabled. + + + + Warning: You do not seem to have the base GStreamer plugins installed. + All audio and video support has been disabled + + + + + Phonon::Gstreamer::MediaObject + + Cannot start playback. + +Check your GStreamer installation and make sure you +have libgstreamer-plugins-base installed. + + + + A required codec is missing. You need to install the following codec(s) to play this content: %0 + + + + Could not open media source. + + + + Invalid source type. + + + + Could not locate media source. + + + + Could not open audio device. The device is already in use. + + + + Could not decode media source. + + + + + Phonon::MMF + + Audio Output + + + + The audio output device + + + + No error + + + + Not found + + + + Out of memory + + + + Not supported + + + + Overflow + + + + Underflow + + + + Already exists + + + + Path not found + + + + In use + + + + Not ready + + + + Access denied + + + + Could not connect + + + + Disconnected + + + + Permission denied + + + + Insufficient bandwidth + + + + Network unavailable + + + + Network communication error + + + + Streaming not supported + + + + Server alert + + + + Invalid protocol + + + + Invalid URL + + + + Multicast error + + + + Proxy server error + + + + Proxy server not supported + + + + Audio output error + + + + Video output error + + + + Decoder error + + + + Audio or video components could not be played + + + + DRM error + + + + Unknown error (%1) + + + + + Phonon::MMF::AbstractMediaPlayer + + Not ready to play + + + + Error opening file + + + + Error opening URL + + + + Setting volume failed + + + + Playback complete + + + + + Phonon::MMF::AudioEqualizer + + %1 Hz + + + + + Phonon::MMF::AudioPlayer + + Getting position failed + + + + Opening clip failed + + + + + Phonon::MMF::EffectFactory + + Enabled + + + + + Phonon::MMF::EnvironmentalReverb + + Decay HF ratio (%) + + + + Decay time (ms) + + + + Density (%) + + + + Diffusion (%) + + + + Reflections delay (ms) + + + + Reflections level (mB) + + + + Reverb delay (ms) + + + + Reverb level (mB) + + + + Room HF level + + + + Room level (mB) + + + + + Phonon::MMF::MediaObject + + Error opening source: type not supported + + + + Error opening source: media type could not be determined + + + + + Phonon::MMF::StereoWidening + + Level (%) + + + + + Phonon::MMF::VideoPlayer + + Pause failed + + + + Seek failed + + + + Getting position failed + + + + Opening clip failed + + + + Buffering clip failed + + + + Video display error + + + + + Phonon::VolumeSlider + + Volume: %1% + + + + Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1% + + + + Muted + + + + + Q3Accel + + %1, %2 not defined + + + + Ambiguous %1 not handled + + + + + Q3DataTable + + True + + + + False + + + + Insert + + + + Update + + + + Delete + + + + + Q3FileDialog + + Copy or Move a File + + + + Read: %1 + + + + Write: %1 + + + + Cancel + + + + All Files (*) + + + + Name + + + + Size + + + + Type + + + + Date + + + + Attributes + + + + &OK + + + + Look &in: + + + + File &name: + + + + File &type: + + + + Back + + + + One directory up + + + + Create New Folder + + + + List View + + + + Detail View + + + + Preview File Info + + + + Preview File Contents + + + + Read-write + + + + Read-only + + + + Write-only + + + + Inaccessible + + + + Symlink to File + + + + Symlink to Directory + + + + Symlink to Special + + + + File + + + + Dir + + + + Special + + + + Open + + + + Save As + + + + &Open + + + + &Save + + + + &Rename + + + + &Delete + + + + R&eload + + + + Sort by &Name + + + + Sort by &Size + + + + Sort by &Date + + + + &Unsorted + + + + Sort + + + + Show &hidden files + + + + the file + + + + the directory + + + + the symlink + + + + Delete %1 + + + + <qt>Are you sure you wish to delete %1 "%2"?</qt> + + + + &Yes + + + + &No + + + + New Folder 1 + + + + New Folder + + + + New Folder %1 + + + + Find Directory + + + + Directories + + + + Directory: + + + + Error + + + + %1 +File not found. +Check path and filename. + + + + All Files (*.*) + + + + Open + + + + Select a Directory + + + + + Q3LocalFs + + Could not read directory +%1 + + + + Could not create directory +%1 + + + + Could not remove file or directory +%1 + + + + Could not rename +%1 +to +%2 + + + + Could not open +%1 + + + + Could not write +%1 + + + + + Q3MainWindow + + Line up + + + + Customize... + + + + + Q3NetworkProtocol + + Operation stopped by the user + + + + + Q3ProgressDialog + + Cancel + + + + + Q3TabDialog + + OK + + + + Apply + + + + Help + + + + Defaults + + + + Cancel + + + + + Q3TextEdit + + &Undo + + + + &Redo + + + + Cu&t + + + + &Copy + + + + &Paste + + + + Clear + + + + Select All + + + + + Q3TitleBar + + System + + + + Restore up + + + + Minimize + + + + Restore down + + + + Maximize + + + + Close + + + + Contains commands to manipulate the window + + + + Puts a minimized window back to normal + + + + Moves the window out of the way + + + + Puts a maximized window back to normal + + + + Makes the window full screen + + + + Closes the window + + + + Displays the name of the window and contains controls to manipulate it + + + + + Q3ToolBar + + More... + + + + + Q3UrlOperator + + The protocol `%1' is not supported + + + + The protocol `%1' does not support listing directories + + + + The protocol `%1' does not support creating new directories + + + + The protocol `%1' does not support removing files or directories + + + + The protocol `%1' does not support renaming files or directories + + + + The protocol `%1' does not support getting files + + + + The protocol `%1' does not support putting files + + + + The protocol `%1' does not support copying or moving files or directories + + + + (unknown) + + + + + Q3Wizard + + &Cancel + + + + < &Back + + + + &Next > + + + + &Finish + + + + &Help + + + + + QAbstractSocket + + Host not found + + + + Connection refused + + + + Connection timed out + + + + Operation on socket is not supported + + + + Socket operation timed out + + + + Socket is not connected + + + + Network unreachable + + + + + QAbstractSpinBox + + &Step up + + + + Step &down + + + + &Select All + + + + + QAccessibleButton + + Press + + + + + QApplication + + QT_LAYOUT_DIRECTION + Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. + RTL + + + Executable '%1' requires Qt %2, found Qt %3. + + + + Incompatible Qt Library Error + + + + Activate + + + + Activates the program's main window + + + + + QAxSelect + + Select ActiveX Control + + + + OK + + + + &Cancel + + + + COM &Object: + + + + + QCheckBox + + Uncheck + + + + Check + + + + Toggle + + + + + QColorDialog + + Hu&e: + Hu&e: + + + &Sat: + &Sat: + + + &Val: + &Val: + + + &Red: + &Red: + + + &Green: + + + + Bl&ue: + + + + A&lpha channel: + + + + Select Color + Select Color + + + &Basic colors + + + + &Custom colors + + + + &Add to Custom Colors + + + + + QComboBox + + Open + Open + + + False + False + + + True + True + + + Close + Close + + + + QCoreApplication + + %1: key is empty + QSystemSemaphore + %1: key is empty + + + %1: unable to make key + QSystemSemaphore + %1: unable to make key + + + %1: ftok failed + QSystemSemaphore + %1: ftok failed + + + %1: already exists + QSystemSemaphore + %1: already exists + + + %1: does not exist + QSystemSemaphore + %1: does not exist + + + %1: out of resources + QSystemSemaphore + %1: out of resources + + + %1: unknown error %2 + QSystemSemaphore + %1: unknown error %2 + + + + QDB2Driver + + Unable to connect + Unable to connect + + + Unable to commit transaction + Unable to commit transaction + + + Unable to rollback transaction + Unable to rollback transaction + + + Unable to set autocommit + Unable to set autocommit + + + + QDB2Result + + Unable to execute statement + Unable to execute statement + + + Unable to prepare statement + Unable to prepare statement + + + Unable to bind variable + Unable to bind variable + + + Unable to fetch record %1 + Unable to fetch record %1 + + + Unable to fetch next + Unable to fetch next + + + Unable to fetch first + Unable to fetch first + + + + QDateTimeEdit + + AM + AM + + + am + am + + + PM + PM + + + pm + pm + + + + QDial + + QDial + QDial + + + SpeedoMeter + SpeedoMeter + + + SliderHandle + SliderHandle + + + + QDialog + + What's This? + What's This? + + + Done + Done + + + + QDialogButtonBox + + OK + OK + + + Save + Save + + + &Save + &Save + + + Open + Open + + + Cancel + Cancel + + + &Cancel + &Cancel + + + Close + Close + + + &Close + &Close + + + Apply + Apply + + + Reset + Reset + + + Help + Help + + + Don't Save + Don't Save + + + Discard + Discard + + + &Yes + &Yes + + + Yes to &All + Yes to &All + + + &No + &No + + + N&o to All + N&o to All + + + Save All + Save All + + + Abort + Abort + + + Retry + Retry + + + Ignore + Ignore + + + Restore Defaults + Restore Defaults + + + Close without Saving + Close without Saving + + + &OK + &OK + + + + QDirModel + + Name + Name + + + Size + Size + + + Kind + Match OS X Finder + Kind + + + Type + All other platforms + Type + + + Date Modified + Date Modified + + + + QDockWidget + + Close + Close + + + Dock + Dock + + + Float + Float + + + + QDoubleSpinBox + + More + More + + + Less + Less + + + + QErrorMessage + + &Show this message again + &Show this message again + + + &OK + &OK + + + Debug Message: + Debug Message: + + + Warning: + Warning: + + + Fatal Error: + Fatal Error: + + + + QFile + + Destination file exists + Destination file exists + + + Will not rename sequential file using block copy + Will not rename sequential file using block copy + + + Cannot remove source file + Cannot remove source file + + + Cannot open %1 for input + Cannot open %1 for input + + + Cannot open for output + Cannot open for output + + + Failure to write block + Failure to write block + + + Cannot create %1 for output + Cannot create %1 for output + + + + QFileDialog + + All Files (*) + All Files (*) + + + Back + Back + + + List View + List View + + + Detail View + Detail View + + + File + File + + + Open + Open + + + Save As + Save As + + + &Open + &Open + + + &Save + &Save + + + Recent Places + Recent Places + + + &Rename + &Rename + + + &Delete + &Delete + + + Show &hidden files + Show &hidden files + + + New Folder + New Folder + + + Find Directory + Find Directory + + + Directories + Directories + + + All Files (*.*) + All Files (*.*) + + + Directory: + Directory: + + + %1 already exists. +Do you want to replace it? + %1 already exists. +Do you want to replace it? + + + %1 +File not found. +Please verify the correct file name was given. + %1 +File not found. +Please verify the correct file name was given. + + + My Computer + My Computer + + + Parent Directory + Parent Directory + + + Files of type: + Files of type: + + + %1 +Directory not found. +Please verify the correct directory name was given. + %1 +Directory not found. +Please verify the correct directory name was given. + + + '%1' is write protected. +Do you want to delete it anyway? + '%1' is write protected. +Do you want to delete it anyway? + + + Are sure you want to delete '%1'? + Are sure you want to delete '%1'? + + + Could not delete directory. + Could not delete directory. + + + Drive + Drive + + + File Folder + Match Windows Explorer + File Folder + + + Folder + All other platforms + Folder + + + Alias + Mac OS X Finder + Alias + + + Shortcut + All other platforms + Shortcut + + + Unknown + Unknown + + + Show + Show + + + Forward + Forward + + + &New Folder + &New Folder + + + &Choose + &Choose + + + Remove + Remove + + + File &name: + File &name: + + + Look in: + Look in: + + + Create New Folder + Create New Folder + + + + QFileSystemModel + + %1 TB + %1 TB + + + %1 GB + %1 GB + + + %1 MB + %1 MB + + + %1 KB + %1 KB + + + %1 bytes + %1 bytes + + + Invalid filename + Invalid filename + + + <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. + <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. + + + Name + Name + + + Size + Size + + + Kind + Match OS X Finder + Kind + + + Type + All other platforms + Type + + + Date Modified + Date Modified + + + My Computer + My Computer + + + Computer + Computer + + + %1 byte(s) + %1 byte(s) + + + + QFontDatabase + + Normal + Normal + + + Bold + Bold + + + Demi Bold + Demi Bold + + + Black + Black + + + Demi + Demi + + + Light + Light + + + Italic + Italic + + + Oblique + Oblique + + + Any + Any + + + Latin + Latin + + + Greek + Greek + + + Cyrillic + Cyrillic + + + Armenian + Armenian + + + Hebrew + Hebrew + + + Arabic + Arabic + + + Syriac + Syriac + + + Thaana + Thaana + + + Devanagari + Devanagari + + + Bengali + Bengali + + + Gurmukhi + Gurmukhi + + + Gujarati + Gujarati + + + Oriya + Oriya + + + Tamil + Tamil + + + Telugu + Telugu + + + Kannada + Kannada + + + Malayalam + Malayalam + + + Sinhala + Sinhala + + + Thai + Thai + + + Lao + Lao + + + Tibetan + Tibetan + + + Myanmar + Myanmar + + + Georgian + Georgian + + + Khmer + Khmer + + + Simplified Chinese + Simplified Chinese + + + Traditional Chinese + Traditional Chinese + + + Japanese + Japanese + + + Korean + Korean + + + Vietnamese + Vietnamese + + + Symbol + Symbol + + + Ogham + Ogham + + + Runic + Runic + + + N'Ko + N'Ko + + + + QFontDialog + + &Font + &Font + + + Font st&yle + Font st&yle + + + &Size + &Size + + + Effects + Effects + + + Stri&keout + Stri&keout + + + &Underline + &Underline + + + Sample + Sample + + + Select Font + Select Font + + + Wr&iting System + Wr&iting System + + + + QFtp + + Host %1 found + Host %1 found + + + Host found + Host found + + + Connected to host %1 + Connected to host %1 + + + Connected to host + Connected to host + + + Connection to %1 closed + Connection to %1 closed + + + Connection closed + Connection closed + + + Host %1 not found + Host %1 not found + + + Connection refused to host %1 + Connection refused to host %1 + + + Connection timed out to host %1 + Connection timed out to host %1 + + + Unknown error + Unknown error + + + Connecting to host failed: +%1 + Connecting to host failed: +%1 + + + Login failed: +%1 + Login failed: +%1 + + + Listing directory failed: +%1 + Listing directory failed: +%1 + + + Changing directory failed: +%1 + Changing directory failed: +%1 + + + Downloading file failed: +%1 + Downloading file failed: +%1 + + + Uploading file failed: +%1 + Uploading file failed: +%1 + + + Removing file failed: +%1 + Removing file failed: +%1 + + + Creating directory failed: +%1 + Creating directory failed: +%1 + + + Removing directory failed: +%1 + Removing directory failed: +%1 + + + Not connected + Not connected + + + Connection refused for data connection + Connection refused for data connection + + + + QHostInfo + + Unknown error + Unknown error + + + + QHostInfoAgent + + Host not found + Host not found + + + Unknown address type + Unknown address type + + + Unknown error + Unknown error + + + No host name given + No host name given + + + Invalid hostname + Invalid hostname + + + + QHttp + + Connection refused + Connection refused + + + Host %1 not found + Host %1 not found + + + Wrong content length + Wrong content length + + + HTTP request failed + HTTP request failed + + + Host %1 found + Host %1 found + + + Host found + Host found + + + Connected to host %1 + Connected to host %1 + + + Connected to host + Connected to host + + + Connection to %1 closed + Connection to %1 closed + + + Connection closed + Connection closed + + + Unknown error + Unknown error + + + Request aborted + Request aborted + + + No server set to connect to + No server set to connect to + + + Server closed connection unexpectedly + Server closed connection unexpectedly + + + Invalid HTTP response header + Invalid HTTP response header + + + Unknown authentication method + Unknown authentication method + + + Invalid HTTP chunked body + Invalid HTTP chunked body + + + Error writing response to device + Error writing response to device + + + Proxy authentication required + Proxy authentication required + + + Authentication required + Authentication required + + + Proxy requires authentication + Proxy requires authentication + + + Host requires authentication + Host requires authentication + + + Data corrupted + Data corrupted + + + SSL handshake failed + SSL handshake failed + + + Unknown protocol specified + Unknown protocol specified + + + Connection refused (or timed out) + Connection refused (or timed out) + + + HTTPS connection requested but SSL support not compiled in + HTTPS connection requested but SSL support not compiled in + + + + QHttpSocketEngine + + Did not receive HTTP response from proxy + Did not receive HTTP response from proxy + + + Error parsing authentication request from proxy + Error parsing authentication request from proxy + + + Authentication required + Authentication required + + + Proxy denied connection + Proxy denied connection + + + Error communicating with HTTP proxy + Error communicating with HTTP proxy + + + Proxy server not found + Proxy server not found + + + Proxy connection refused + Proxy connection refused + + + Proxy server connection timed out + Proxy server connection timed out + + + Proxy connection closed prematurely + Proxy connection closed prematurely + + + + QIBaseDriver + + Error opening database + Error opening database + + + Could not start transaction + Could not start transaction + + + Unable to commit transaction + Unable to commit transaction + + + Unable to rollback transaction + Unable to rollback transaction + + + + QIBaseResult + + Unable to create BLOB + Unable to create BLOB + + + Unable to write BLOB + Unable to write BLOB + + + Unable to open BLOB + Unable to open BLOB + + + Unable to read BLOB + Unable to read BLOB + + + Could not find array + Could not find array + + + Could not get array data + Could not get array data + + + Could not get query info + Could not get query info + + + Could not start transaction + Could not start transaction + + + Unable to commit transaction + Unable to commit transaction + + + Could not allocate statement + Could not allocate statement + + + Could not prepare statement + Could not prepare statement + + + Could not describe input statement + Could not describe input statement + + + Could not describe statement + Could not describe statement + + + Unable to close statement + Unable to close statement + + + Unable to execute query + Unable to execute query + + + Could not fetch next item + Could not fetch next item + + + Could not get statement info + Could not get statement info + + + + QIODevice + + Permission denied + Permission denied + + + Too many open files + Too many open files + + + No such file or directory + No such file or directory + + + No space left on device + No space left on device + + + Unknown error + Unknown error + + + + QInputContext + + XIM + XIM + + + FEP + FEP + + + XIM input method + XIM input method + + + Windows input method + Windows input method + + + Mac OS X input method + Mac OS X input method + + + S60 FEP input method + S60 FEP input method + + + + QInputDialog + + Enter a value: + Enter a value: + + + + QLibrary + + Could not mmap '%1': %2 + Could not mmap '%1': %2 + + + Plugin verification data mismatch in '%1' + Plugin verification data mismatch in '%1' + + + Could not unmap '%1': %2 + Could not unmap '%1': %2 + + + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] + + + The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" + The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" + + + Unknown error + Unknown error + + + The shared library was not found. + The shared library was not found. + + + The file '%1' is not a valid Qt plugin. + The file '%1' is not a valid Qt plugin. + + + The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) + The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) + + + Cannot load library %1: %2 + Cannot load library %1: %2 + + + Cannot unload library %1: %2 + Cannot unload library %1: %2 + + + Cannot resolve symbol "%1" in %2: %3 + Cannot resolve symbol "%1" in %2: %3 + + + + QLineEdit + + Select All + Select All + + + &Undo + &Undo + + + &Redo + &Redo + + + Cu&t + Cu&t + + + &Copy + &Copy + + + &Paste + &Paste + + + Delete + Delete + + + + QLocalServer + + %1: Name error + %1: Name error + + + %1: Permission denied + %1: Permission denied + + + %1: Address in use + %1: Address in use + + + %1: Unknown error %2 + %1: Unknown error %2 + + + + QLocalSocket + + %1: Connection refused + %1: Connection refused + + + %1: Remote closed + %1: Remote closed + + + %1: Invalid name + %1: Invalid name + + + %1: Socket access error + %1: Socket access error + + + %1: Socket resource error + %1: Socket resource error + + + %1: Socket operation timed out + %1: Socket operation timed out + + + %1: Datagram too large + %1: Datagram too large + + + %1: Connection error + %1: Connection error + + + %1: The socket operation is not supported + %1: The socket operation is not supported + + + %1: Unknown error + %1: Unknown error + + + %1: Unknown error %2 + %1: Unknown error %2 + + + + QMYSQLDriver + + Unable to open database ' + Unable to open database ' + + + Unable to connect + Unable to connect + + + Unable to begin transaction + Unable to begin transaction + + + Unable to commit transaction + Unable to commit transaction + + + Unable to rollback transaction + Unable to rollback transaction + + + + QMYSQLResult + + Unable to fetch data + Unable to fetch data + + + Unable to execute query + Unable to execute query + + + Unable to store result + Unable to store result + + + Unable to prepare statement + Unable to prepare statement + + + Unable to reset statement + Unable to reset statement + + + Unable to bind value + Unable to bind value + + + Unable to execute statement + Unable to execute statement + + + Unable to bind outvalues + Unable to bind outvalues + + + Unable to store statement results + Unable to store statement results + + + Unable to execute next query + Unable to execute next query + + + Unable to store next result + Unable to store next result + + + + QMdiArea + + (Untitled) + (Untitled) + + + + QMdiSubWindow + + %1 - [%2] + %1 - [%2] + + + Close + Close + + + Minimize + Minimize + + + Restore Down + Restore Down + + + &Restore + &Restore + + + &Move + &Move + + + &Size + &Size + + + Mi&nimize + Mi&nimize + + + Ma&ximize + Ma&ximize + + + Stay on &Top + Stay on &Top + + + &Close + &Close + + + Maximize + Maximize + + + Unshade + Unshade + + + Shade + Shade + + + Restore + Restore + + + Help + Help + + + Menu + Menu + + + - [%1] + - [%1] + + + + QMenu + + Close + Close + + + Open + Open + + + Execute + Execute + + + + QMenuBar + + Actions + Actions + + + + QMessageBox + + OK + OK + + + <h3>About Qt</h3><p>This program uses Qt version %1.</p> + <h3>About Qt</h3><p>This program uses Qt version %1.</p> + + + <p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p><p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://qt.nokia.com/">qt.nokia.com</a> for more information.</p> + <p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p><p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://qt.nokia.com/">qt.nokia.com</a> for more information.</p> + + + About Qt + About Qt + + + Help + Help + + + Show Details... + Show Details... + + + Hide Details... + Hide Details... + + + + QMultiInputContext + + Select IM + Select IM + + + + QMultiInputContextPlugin + + Multiple input method switcher + Multiple input method switcher + + + Multiple input method switcher that uses the context menu of the text widgets + Multiple input method switcher that uses the context menu of the text widgets + + + + QNativeSocketEngine + + The remote host closed the connection + The remote host closed the connection + + + Network operation timed out + Network operation timed out + + + Out of resources + Out of resources + + + Unsupported socket operation + Unsupported socket operation + + + Protocol type not supported + Protocol type not supported + + + Invalid socket descriptor + Invalid socket descriptor + + + Network unreachable + Network unreachable + + + Permission denied + Permission denied + + + Connection timed out + Connection timed out + + + Connection refused + Connection refused + + + The bound address is already in use + The bound address is already in use + + + The address is not available + The address is not available + + + The address is protected + The address is protected + + + Unable to send a message + Unable to send a message + + + Unable to receive a message + Unable to receive a message + + + Unable to write + Unable to write + + + Network error + Network error + + + Another socket is already listening on the same port + Another socket is already listening on the same port + + + Unable to initialize non-blocking socket + Unable to initialize non-blocking socket + + + Unable to initialize broadcast socket + Unable to initialize broadcast socket + + + Attempt to use IPv6 socket on a platform with no IPv6 support + Attempt to use IPv6 socket on a platform with no IPv6 support + + + Host unreachable + Host unreachable + + + Datagram was too large to send + Datagram was too large to send + + + Operation on non-socket + Operation on non-socket + + + Unknown error + Unknown error + + + The proxy type is invalid for this operation + The proxy type is invalid for this operation + + + + QNetworkAccessCacheBackend + + Error opening %1 + Error opening %1 + + + + QNetworkAccessDebugPipeBackend + + Write error writing to %1: %2 + Write error writing to %1: %2 + + + + QNetworkAccessFileBackend + + Request for opening non-local file %1 + Request for opening non-local file %1 + + + Error opening %1: %2 + Error opening %1: %2 + + + Write error writing to %1: %2 + Write error writing to %1: %2 + + + Cannot open %1: Path is a directory + Cannot open %1: Path is a directory + + + Read error reading from %1: %2 + Read error reading from %1: %2 + + + + QNetworkAccessFtpBackend + + No suitable proxy found + No suitable proxy found + + + Cannot open %1: is a directory + Cannot open %1: is a directory + + + Logging in to %1 failed: authentication required + Logging in to %1 failed: authentication required + + + Error while downloading %1: %2 + Error while downloading %1: %2 + + + Error while uploading %1: %2 + Error while uploading %1: %2 + + + + QNetworkAccessHttpBackend + + No suitable proxy found + No suitable proxy found + + + + QNetworkReply + + Error downloading %1 - server replied: %2 + Error downloading %1 - server replied: %2 + + + Protocol "%1" is unknown + Protocol "%1" is unknown + + + + QNetworkReplyImpl + + Operation canceled + Operation canceled + + + + QOCIDriver + + Unable to logon + Unable to logon + + + Unable to initialize + QOCIDriver + Unable to initialize + + + Unable to begin transaction + Unable to begin transaction + + + Unable to commit transaction + Unable to commit transaction + + + Unable to rollback transaction + Unable to rollback transaction + + + + QOCIResult + + Unable to bind column for batch execute + Unable to bind column for batch execute + + + Unable to execute batch statement + Unable to execute batch statement + + + Unable to goto next + Unable to goto next + + + Unable to alloc statement + Unable to alloc statement + + + Unable to prepare statement + Unable to prepare statement + + + Unable to get statement type + Unable to get statement type + + + Unable to bind value + Unable to bind value + + + Unable to execute statement + Unable to execute statement + + + + QODBCDriver + + Unable to connect + Unable to connect + + + Unable to disable autocommit + Unable to disable autocommit + + + Unable to commit transaction + Unable to commit transaction + + + Unable to rollback transaction + Unable to rollback transaction + + + Unable to enable autocommit + Unable to enable autocommit + + + Unable to connect - Driver doesn't support all functionality required + Unable to connect - Driver doesn't support all functionality required + + + + QODBCResult + + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration + + + Unable to execute statement + Unable to execute statement + + + Unable to fetch next + Unable to fetch next + + + Unable to prepare statement + Unable to prepare statement + + + Unable to bind variable + Unable to bind variable + + + Unable to fetch last + Unable to fetch last + + + Unable to fetch + Unable to fetch + + + Unable to fetch first + Unable to fetch first + + + Unable to fetch previous + Unable to fetch previous + + + + QObject + + Invalid hostname + Invalid hostname + + + Operation not supported on %1 + Operation not supported on %1 + + + Invalid URI: %1 + Invalid URI: %1 + + + Socket error on %1: %2 + Socket error on %1: %2 + + + Remote host closed the connection prematurely on %1 + Remote host closed the connection prematurely on %1 + + + No host name given + No host name given + + + + QPPDOptionsModel + + Name + Name + + + Value + Value + + + + QPSQLDriver + + Unable to connect + Unable to connect + + + Could not begin transaction + Could not begin transaction + + + Could not commit transaction + Could not commit transaction + + + Could not rollback transaction + Could not rollback transaction + + + Unable to subscribe + Unable to subscribe + + + Unable to unsubscribe + Unable to unsubscribe + + + + QPSQLResult + + Unable to create query + Unable to create query + + + Unable to prepare statement + Unable to prepare statement + + + + QPageSetupWidget + + Centimeters (cm) + Centimeters (cm) + + + Millimeters (mm) + Millimeters (mm) + + + Inches (in) + Inches (in) + + + Points (pt) + Points (pt) + + + Form + Form + + + Paper + Paper + + + Page size: + Page size: + + + Width: + Width: + + + Height: + Height: + + + Paper source: + Paper source: + + + Orientation + Orientation + + + Portrait + Portrait + + + Landscape + Landscape + + + Reverse landscape + Reverse landscape + + + Reverse portrait + Reverse portrait + + + Margins + Margins + + + top margin + top margin + + + left margin + left margin + + + right margin + right margin + + + bottom margin + bottom margin + + + + QPluginLoader + + Unknown error + Unknown error + + + The plugin was not loaded. + The plugin was not loaded. + + + + QPrintDialog + + locally connected + locally connected + + + Aliases: %1 + Aliases: %1 + + + unknown + unknown + + + OK + OK + + + Print all + Print all + + + Print range + Print range + + + A0 (841 x 1189 mm) + A0 (841 x 1189 mm) + + + A1 (594 x 841 mm) + A1 (594 x 841 mm) + + + A2 (420 x 594 mm) + A2 (420 x 594 mm) + + + A3 (297 x 420 mm) + A3 (297 x 420 mm) + + + A5 (148 x 210 mm) + A5 (148 x 210 mm) + + + A6 (105 x 148 mm) + A6 (105 x 148 mm) + + + A7 (74 x 105 mm) + A7 (74 x 105 mm) + + + A8 (52 x 74 mm) + A8 (52 x 74 mm) + + + A9 (37 x 52 mm) + A9 (37 x 52 mm) + + + B0 (1000 x 1414 mm) + B0 (1000 x 1414 mm) + + + B1 (707 x 1000 mm) + B1 (707 x 1000 mm) + + + B2 (500 x 707 mm) + B2 (500 x 707 mm) + + + B3 (353 x 500 mm) + B3 (353 x 500 mm) + + + B4 (250 x 353 mm) + B4 (250 x 353 mm) + + + B6 (125 x 176 mm) + B6 (125 x 176 mm) + + + B7 (88 x 125 mm) + B7 (88 x 125 mm) + + + B8 (62 x 88 mm) + B8 (62 x 88 mm) + + + B9 (44 x 62 mm) + B9 (44 x 62 mm) + + + B10 (31 x 44 mm) + B10 (31 x 44 mm) + + + C5E (163 x 229 mm) + C5E (163 x 229 mm) + + + DLE (110 x 220 mm) + DLE (110 x 220 mm) + + + Folio (210 x 330 mm) + Folio (210 x 330 mm) + + + Ledger (432 x 279 mm) + Ledger (432 x 279 mm) + + + Tabloid (279 x 432 mm) + Tabloid (279 x 432 mm) + + + US Common #10 Envelope (105 x 241 mm) + US Common #10 Envelope (105 x 241 mm) + + + A4 (210 x 297 mm, 8.26 x 11.7 inches) + A4 (210 x 297 mm, 8.26 x 11.7 inches) + + + B5 (176 x 250 mm, 6.93 x 9.84 inches) + B5 (176 x 250 mm, 6.93 x 9.84 inches) + + + Executive (7.5 x 10 inches, 191 x 254 mm) + Executive (7.5 x 10 inches, 191 x 254 mm) + + + Legal (8.5 x 14 inches, 216 x 356 mm) + Legal (8.5 x 14 inches, 216 x 356 mm) + + + Letter (8.5 x 11 inches, 216 x 279 mm) + Letter (8.5 x 11 inches, 216 x 279 mm) + + + Print selection + Print selection + + + Print + Print + + + Print To File ... + Print To File ... + + + File %1 is not writable. +Please choose a different file name. + File %1 is not writable. +Please choose a different file name. + + + %1 already exists. +Do you want to overwrite it? + %1 already exists. +Do you want to overwrite it? + + + File exists + File exists + + + <qt>Do you want to overwrite it?</qt> + <qt>Do you want to overwrite it?</qt> + + + %1 is a directory. +Please choose a different file name. + %1 is a directory. +Please choose a different file name. + + + The 'From' value cannot be greater than the 'To' value. + The 'From' value cannot be greater than the 'To' value. + + + A0 + A0 + + + A1 + A1 + + + A2 + A2 + + + A3 + A3 + + + A4 + A4 + + + A5 + A5 + + + A6 + A6 + + + A7 + A7 + + + A8 + A8 + + + A9 + A9 + + + B0 + B0 + + + B1 + B1 + + + B2 + B2 + + + B3 + B3 + + + B4 + B4 + + + B5 + B5 + + + B6 + B6 + + + B7 + B7 + + + B8 + B8 + + + B9 + B9 + + + B10 + B10 + + + C5E + C5E + + + DLE + DLE + + + Executive + Executive + + + Folio + Folio + + + Ledger + Ledger + + + Legal + Legal + + + Letter + Letter + + + Tabloid + Tabloid + + + US Common #10 Envelope + US Common #10 Envelope + + + Custom + Custom + + + &Options >> + &Options >> + + + &Options << + &Options << + + + Print to File (PDF) + Print to File (PDF) + + + Print to File (Postscript) + Print to File (Postscript) + + + Local file + Local file + + + Write %1 file + Write %1 file + + + &Print + &Print + + + + QPrintPreviewDialog + + %1% + %1% + + + Print Preview + Print Preview + + + Next page + Next page + + + Previous page + Previous page + + + First page + First page + + + Last page + Last page + + + Fit width + Fit width + + + Fit page + Fit page + + + Zoom in + Zoom in + + + Zoom out + Zoom out + + + Portrait + Portrait + + + Landscape + Landscape + + + Show single page + Show single page + + + Show facing pages + Show facing pages + + + Show overview of all pages + Show overview of all pages + + + Print + Print + + + Page setup + Page setup + + + Close + Close + + + Export to PDF + Export to PDF + + + Export to PostScript + Export to PostScript + + + Page Setup + Page Setup + + + + QPrintPropertiesWidget + + Form + Form + + + Page + Page + + + Advanced + Advanced + + + + QPrintSettingsOutput + + Form + Form + + + Copies + Copies + + + Print range + Print range + + + Print all + Print all + + + Pages from + Pages from + + + to + to + + + Selection + Selection + + + Output Settings + Output Settings + + + Copies: + Copies: + + + Collate + Collate + + + Reverse + Reverse + + + Options + Options + + + Color Mode + Color Mode + + + Color + Color + + + Grayscale + Grayscale + + + Duplex Printing + Duplex Printing + + + None + None + + + Long side + Long side + + + Short side + Short side + + + + QPrintWidget + + Form + Form + + + Printer + Printer + + + &Name: + &Name: + + + P&roperties + P&roperties + + + Location: + Location: + + + Preview + Preview + + + Type: + Type: + + + Output &file: + Output &file: + + + ... + ... + + + + QProcess + + Could not open input redirection for reading + Could not open input redirection for reading + + + Could not open output redirection for writing + Could not open output redirection for writing + + + Resource error (fork failure): %1 + Resource error (fork failure): %1 + + + Process operation timed out + Process operation timed out + + + Error reading from process + Error reading from process + + + Error writing to process + Error writing to process + + + Process crashed + Process crashed + + + No program defined + No program defined + + + Process failed to start: %1 + Process failed to start: %1 + + + + QProgressDialog + + Cancel + Cancel + + + + QPushButton + + Open + Open + + + + QRadioButton + + Check + Check + + + + QRegExp + + no error occurred + no error occurred + + + disabled feature used + disabled feature used + + + bad char class syntax + bad char class syntax + + + bad lookahead syntax + bad lookahead syntax + + + bad repetition syntax + bad repetition syntax + + + invalid octal value + invalid octal value + + + missing left delim + missing left delim + + + unexpected end + unexpected end + + + met internal limit + met internal limit + + + invalid interval + invalid interval + + + invalid category + invalid category + + + + QSQLite2Driver + + Error opening database + Error opening database + + + Unable to begin transaction + Unable to begin transaction + + + Unable to commit transaction + Unable to commit transaction + + + Unable to rollback transaction + Unable to rollback transaction + + + + QSQLite2Result + + Unable to fetch results + Unable to fetch results + + + Unable to execute statement + Unable to execute statement + + + + QSQLiteDriver + + Error opening database + Error opening database + + + Error closing database + Error closing database + + + Unable to begin transaction + Unable to begin transaction + + + Unable to commit transaction + Unable to commit transaction + + + Unable to rollback transaction + Unable to rollback transaction + + + + QSQLiteResult + + Unable to fetch row + Unable to fetch row + + + Unable to execute statement + Unable to execute statement + + + Unable to reset statement + Unable to reset statement + + + Unable to bind parameters + Unable to bind parameters + + + Parameter count mismatch + Parameter count mismatch + + + No query + No query + + + + QScriptBreakpointsModel + + ID + ID + + + Location + Location + + + Condition + Condition + + + Ignore-count + Ignore-count + + + Single-shot + Single-shot + + + Hit-count + Hit-count + + + + QScriptBreakpointsWidget + + New + New + + + Delete + Delete + + + + QScriptDebugger + + Go to Line + Go to Line + + + Line: + Line: + + + Interrupt + Interrupt + + + Shift+F5 + Shift+F5 + + + Continue + Continue + + + F5 + F5 + + + Step Into + Step Into + + + F11 + F11 + + + Step Over + Step Over + + + F10 + F10 + + + Step Out + Step Out + + + Shift+F11 + Shift+F11 + + + Run to Cursor + Run to Cursor + + + Ctrl+F10 + Ctrl+F10 + + + Run to New Script + Run to New Script + + + Toggle Breakpoint + Toggle Breakpoint + + + F9 + F9 + + + Clear Debug Output + Clear Debug Output + + + Clear Error Log + Clear Error Log + + + Clear Console + Clear Console + + + &Find in Script... + &Find in Script... + + + Ctrl+F + Ctrl+F + + + Find &Next + Find &Next + + + F3 + F3 + + + Find &Previous + Find &Previous + + + Shift+F3 + Shift+F3 + + + Ctrl+G + Ctrl+G + + + Debug + Debug + + + + QScriptDebuggerCodeFinderWidget + + Close + Close + + + Previous + Previous + + + Next + Next + + + Case Sensitive + Case Sensitive + + + Whole words + Whole words + + + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;Search wrapped + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;Search wrapped + + + + QScriptDebuggerLocalsModel + + Name + Name + + + Value + Value + + + + QScriptDebuggerStackModel + + Level + Level + + + Name + Name + + + Location + Location + + + + QScriptEdit + + Toggle Breakpoint + Toggle Breakpoint + + + Disable Breakpoint + Disable Breakpoint + + + Enable Breakpoint + Enable Breakpoint + + + Breakpoint Condition: + Breakpoint Condition: + + + + QScriptEngineDebugger + + Loaded Scripts + Loaded Scripts + + + Breakpoints + Breakpoints + + + Stack + Stack + + + Locals + Locals + + + Console + Console + + + Debug Output + Debug Output + + + Error Log + Error Log + + + Search + Search + + + View + View + + + Qt Script Debugger + Qt Script Debugger + + + + QScriptNewBreakpointWidget + + Close + Close + + + + QScrollBar + + Scroll here + Scroll here + + + Left edge + Left edge + + + Top + Top + + + Right edge + Right edge + + + Bottom + Bottom + + + Page left + Page left + + + Page up + Page up + + + Page right + Page right + + + Page down + Page down + + + Scroll left + Scroll left + + + Scroll up + Scroll up + + + Scroll right + Scroll right + + + Scroll down + Scroll down + + + Line up + Line up + + + Position + Position + + + Line down + Line down + + + + QSharedMemory + + %1: create size is less then 0 + %1: create size is less then 0 + + + %1: unable to lock + %1: unable to lock + + + %1: unable to unlock + %1: unable to unlock + + + %1: permission denied + %1: permission denied + + + %1: already exists + %1: already exists + + + %1: doesn't exists + %1: doesn't exists + + + %1: out of resources + %1: out of resources + + + %1: unknown error %2 + %1: unknown error %2 + + + %1: key is empty + %1: key is empty + + + %1: ftok failed + %1: ftok failed + + + %1: unable to make key + %1: unable to make key + + + %1: doesn't exist + %1: doesn't exist + + + %1: UNIX key file doesn't exist + %1: UNIX key file doesn't exist + + + %1: system-imposed size restrictions + %1: system-imposed size restrictions + + + %1: not attached + %1: not attached + + + %1: invalid size + %1: invalid size + + + %1: key error + %1: key error + + + %1: size query failed + %1: size query failed + + + %1: unable to set key on lock + %1: unable to set key on lock + + + + QShortcut + + Space + Space + + + Esc + Esc + + + Tab + Tab + + + Backtab + Backtab + + + Backspace + Backspace + + + Return + Return + + + Enter + Enter + + + Ins + Ins + + + Del + Del + + + Pause + Pause + + + Print + Print + + + SysReq + SysReq + + + Home + Home + + + End + End + + + Left + Left + + + Up + Up + + + Right + Right + + + Down + Down + + + PgUp + PgUp + + + PgDown + PgDown + + + CapsLock + CapsLock + + + NumLock + NumLock + + + ScrollLock + ScrollLock + + + Menu + Menu + + + Help + Help + + + Back + Back + + + Forward + Forward + + + Stop + Stop + + + Refresh + Refresh + + + Volume Down + Volume Down + + + Volume Mute + Volume Mute + + + Volume Up + Volume Up + + + Bass Boost + Bass Boost + + + Bass Up + Bass Up + + + Bass Down + Bass Down + + + Treble Up + Treble Up + + + Treble Down + Treble Down + + + Media Play + Media Play + + + Media Stop + Media Stop + + + Media Previous + Media Previous + + + Media Next + Media Next + + + Media Record + Media Record + + + Favorites + Favorites + + + Search + Search + + + Standby + Standby + + + Open URL + Open URL + + + Launch Mail + Launch Mail + + + Launch Media + Launch Media + + + Launch (0) + Launch (0) + + + Launch (1) + Launch (1) + + + Launch (2) + Launch (2) + + + Launch (3) + Launch (3) + + + Launch (4) + Launch (4) + + + Launch (5) + Launch (5) + + + Launch (6) + Launch (6) + + + Launch (7) + Launch (7) + + + Launch (8) + Launch (8) + + + Launch (9) + Launch (9) + + + Launch (A) + Launch (A) + + + Launch (B) + Launch (B) + + + Launch (C) + Launch (C) + + + Launch (D) + Launch (D) + + + Launch (E) + Launch (E) + + + Launch (F) + Launch (F) + + + Monitor Brightness Up + Monitor Brightness Up + + + Monitor Brightness Down + Monitor Brightness Down + + + Keyboard Light On/Off + Keyboard Light On/Off + + + Keyboard Brightness Up + Keyboard Brightness Up + + + Keyboard Brightness Down + Keyboard Brightness Down + + + Power Off + Power Off + + + Wake Up + Wake Up + + + Eject + Eject + + + Screensaver + Screensaver + + + WWW + WWW + + + Sleep + Sleep + + + LightBulb + LightBulb + + + Shop + Shop + + + History + History + + + Add Favorite + Add Favorite + + + Hot Links + Hot Links + + + Adjust Brightness + Adjust Brightness + + + Finance + Finance + + + Community + Community + + + Audio Rewind + Audio Rewind + + + Back Forward + Back Forward + + + Application Left + Application Left + + + Application Right + Application Right + + + Book + Book + + + CD + CD + + + Calculator + Calculator + + + Clear + Clear + + + Clear Grab + Clear Grab + + + Close + Close + + + Copy + Copy + + + Cut + Cut + + + Display + Display + + + DOS + DOS + + + Documents + Documents + + + Spreadsheet + Spreadsheet + + + Browser + Browser + + + Game + Game + + + Go + Go + + + iTouch + iTouch + + + Logoff + Logoff + + + Market + Market + + + Meeting + Meeting + + + Keyboard Menu + Keyboard Menu + + + Menu PB + Menu PB + + + My Sites + My Sites + + + News + News + + + Home Office + Home Office + + + Option + Option + + + Paste + Paste + + + Phone + Phone + + + Reply + Reply + + + Reload + Reload + + + Rotate Windows + Rotate Windows + + + Rotation PB + Rotation PB + + + Rotation KB + Rotation KB + + + Save + Save + + + Send + Send + + + Spellchecker + Spellchecker + + + Split Screen + Split Screen + + + Support + Support + + + Task Panel + Task Panel + + + Terminal + Terminal + + + Tools + Tools + + + Travel + Travel + + + Video + Video + + + Word Processor + Word Processor + + + XFer + XFer + + + Zoom In + Zoom In + + + Zoom Out + Zoom Out + + + Away + Away + + + Messenger + Messenger + + + WebCam + WebCam + + + Mail Forward + Mail Forward + + + Pictures + Pictures + + + Music + Music + + + Battery + Battery + + + Bluetooth + Bluetooth + + + Wireless + Wireless + + + Ultra Wide Band + Ultra Wide Band + + + Audio Forward + Audio Forward + + + Audio Repeat + Audio Repeat + + + Audio Random Play + Audio Random Play + + + Subtitle + Subtitle + + + Audio Cycle Track + Audio Cycle Track + + + Time + Time + + + View + View + + + Top Menu + Top Menu + + + Suspend + Suspend + + + Hibernate + Hibernate + + + Print Screen + Print Screen + + + Page Up + Page Up + + + Page Down + Page Down + + + Caps Lock + Caps Lock + + + Num Lock + Num Lock + + + Number Lock + Number Lock + + + Scroll Lock + Scroll Lock + + + Insert + Insert + + + Delete + Delete + + + Escape + Escape + + + System Request + System Request + + + Select + Select + + + Yes + Yes + + + No + No + + + Context1 + Context1 + + + Context2 + Context2 + + + Context3 + Context3 + + + Context4 + Context4 + + + Call + Call + + + Hangup + Hangup + + + Flip + Flip + + + Ctrl + Ctrl + + + Shift + Shift + + + Alt + Alt + + + Meta + Meta + + + + + + + + + F%1 + F%1 + + + Home Page + Home Page + + + + QSlider + + Page left + Page left + + + Page up + Page up + + + Position + Position + + + Page right + Page right + + + Page down + Page down + + + + QSocks5SocketEngine + + Connection to proxy refused + Connection to proxy refused + + + Connection to proxy closed prematurely + Connection to proxy closed prematurely + + + Proxy host not found + Proxy host not found + + + Connection to proxy timed out + Connection to proxy timed out + + + Proxy authentication failed + Proxy authentication failed + + + Proxy authentication failed: %1 + Proxy authentication failed: %1 + + + SOCKS version 5 protocol error + SOCKS version 5 protocol error + + + General SOCKSv5 server failure + General SOCKSv5 server failure + + + Connection not allowed by SOCKSv5 server + Connection not allowed by SOCKSv5 server + + + TTL expired + TTL expired + + + SOCKSv5 command not supported + SOCKSv5 command not supported + + + Address type not supported + Address type not supported + + + Unknown SOCKSv5 proxy error code 0x%1 + Unknown SOCKSv5 proxy error code 0x%1 + + + Network operation timed out + Network operation timed out + + + + QSoftKeyManager + + Ok + Ok + + + Select + Select + + + Done + Done + + + Options + Options + + + Cancel + Cancel + + + Exit + Exit + + + + QSpinBox + + More + More + + + Less + Less + + + + QSql + + Delete + Delete + + + Delete this record? + Delete this record? + + + Yes + Yes + + + No + No + + + Insert + Insert + + + Update + Update + + + Save edits? + Save edits? + + + Cancel + Cancel + + + Confirm + Confirm + + + Cancel your edits? + Cancel your edits? + + + + QSslSocket + + Unable to write data: %1 + Unable to write data: %1 + + + Unable to decrypt data: %1 + Unable to decrypt data: %1 + + + Error while reading: %1 + Error while reading: %1 + + + Error during SSL handshake: %1 + Error during SSL handshake: %1 + + + Error creating SSL context (%1) + Error creating SSL context (%1) + + + Invalid or empty cipher list (%1) + Invalid or empty cipher list (%1) + + + Private key does not certify public key, %1 + Private key does not certify public key, %1 + + + Error creating SSL session, %1 + Error creating SSL session, %1 + + + Error creating SSL session: %1 + Error creating SSL session: %1 + + + Cannot provide a certificate with no key, %1 + Cannot provide a certificate with no key, %1 + + + Error loading local certificate, %1 + Error loading local certificate, %1 + + + Error loading private key, %1 + Error loading private key, %1 + + + No error + No error + + + The issuer certificate could not be found + The issuer certificate could not be found + + + The certificate signature could not be decrypted + The certificate signature could not be decrypted + + + The public key in the certificate could not be read + The public key in the certificate could not be read + + + The signature of the certificate is invalid + The signature of the certificate is invalid + + + The certificate is not yet valid + The certificate is not yet valid + + + The certificate has expired + The certificate has expired + + + The certificate's notBefore field contains an invalid time + The certificate's notBefore field contains an invalid time + + + The certificate's notAfter field contains an invalid time + The certificate's notAfter field contains an invalid time + + + The certificate is self-signed, and untrusted + The certificate is self-signed, and untrusted + + + The root certificate of the certificate chain is self-signed, and untrusted + The root certificate of the certificate chain is self-signed, and untrusted + + + The issuer certificate of a locally looked up certificate could not be found + The issuer certificate of a locally looked up certificate could not be found + + + No certificates could be verified + No certificates could be verified + + + One of the CA certificates is invalid + One of the CA certificates is invalid + + + The basicConstraints path length parameter has been exceeded + The basicConstraints path length parameter has been exceeded + + + The supplied certificate is unsuitable for this purpose + The supplied certificate is unsuitable for this purpose + + + The root CA certificate is not trusted for this purpose + The root CA certificate is not trusted for this purpose + + + The root CA certificate is marked to reject the specified purpose + The root CA certificate is marked to reject the specified purpose + + + The current candidate issuer certificate was rejected because its subject name did not match the issuer name of the current certificate + The current candidate issuer certificate was rejected because its subject name did not match the issuer name of the current certificate + + + The current candidate issuer certificate was rejected because its issuer name and serial number was present and did not match the authority key identifier of the current certificate + The current candidate issuer certificate was rejected because its issuer name and serial number was present and did not match the authority key identifier of the current certificate + + + The peer did not present any certificate + The peer did not present any certificate + + + The host name did not match any of the valid hosts for this certificate + The host name did not match any of the valid hosts for this certificate + + + Unknown error + Unknown error + + + + QStateMachine + + Missing initial state in compound state '%1' + Missing initial state in compound state '%1' + + + Missing default state in history state '%1' + Missing default state in history state '%1' + + + No common ancestor for targets and source of transition from state '%1' + No common ancestor for targets and source of transition from state '%1' + + + Unknown error + Unknown error + + + + QSystemSemaphore + + %1: does not exist + %1: does not exist + + + %1: out of resources + %1: out of resources + + + %1: permission denied + %1: permission denied + + + %1: already exists + %1: already exists + + + %1: unknown error %2 + %1: unknown error %2 + + + + QTDSDriver + + Unable to open connection + Unable to open connection + + + Unable to use database + Unable to use database + + + + QTabBar + + Scroll Left + Scroll Left + + + Scroll Right + Scroll Right + + + + QTcpServer + + Operation on socket is not supported + Operation on socket is not supported + + + + QTextControl + + &Undo + &Undo + + + &Redo + &Redo + + + Cu&t + Cu&t + + + &Copy + &Copy + + + Copy &Link Location + Copy &Link Location + + + &Paste + &Paste + + + Delete + Delete + + + Select All + Select All + + + + QToolButton + + Press + Press + + + Open + Open + + + + QUdpSocket + + This platform does not support IPv6 + This platform does not support IPv6 + + + + QUndoGroup + + Undo + Undo + + + Redo + Redo + + + + QUndoModel + + <empty> + <empty> + + + + QUndoStack + + Undo + Undo + + + Redo + Redo + + + + QUnicodeControlCharacterMenu + + LRM Left-to-right mark + LRM Left-to-right mark + + + RLM Right-to-left mark + RLM Right-to-left mark + + + ZWJ Zero width joiner + ZWJ Zero width joiner + + + ZWNJ Zero width non-joiner + ZWNJ Zero width non-joiner + + + ZWSP Zero width space + ZWSP Zero width space + + + LRE Start of left-to-right embedding + LRE Start of left-to-right embedding + + + RLE Start of right-to-left embedding + RLE Start of right-to-left embedding + + + LRO Start of left-to-right override + LRO Start of left-to-right override + + + RLO Start of right-to-left override + RLO Start of right-to-left override + + + PDF Pop directional formatting + PDF Pop directional formatting + + + Insert Unicode control character + Insert Unicode control character + + + + QWebFrame + + Request cancelled + Request cancelled + + + Request blocked + Request blocked + + + Cannot show URL + Cannot show URL + + + Frame load interrupted by policy change + Frame load interrupted by policy change + + + Cannot show mimetype + Cannot show mimetype + + + File does not exist + File does not exist + + + + QWebPage + + Submit + default label for Submit buttons in forms on web pages + Submit + + + Submit + Submit (input element) alt text for <input> elements with no alt, title, or value + Submit + + + Reset + default label for Reset buttons in forms on web pages + Reset + + + Choose File + title for file button used in HTML forms + Choose File + + + No file selected + text to display in file button used in HTML forms when no file is selected + No file selected + + + Open in New Window + Open in New Window context menu item + Open in New Window + + + Save Link... + Download Linked File context menu item + Save Link... + + + Copy Link + Copy Link context menu item + Copy Link + + + Open Image + Open Image in New Window context menu item + Open Image + + + Save Image + Download Image context menu item + Save Image + + + Copy Image + Copy Link context menu item + Copy Image + + + Open Frame + Open Frame in New Window context menu item + Open Frame + + + Copy + Copy context menu item + Copy + + + Go Back + Back context menu item + Go Back + + + Go Forward + Forward context menu item + Go Forward + + + Stop + Stop context menu item + Stop + + + Reload + Reload context menu item + Reload + + + Cut + Cut context menu item + Cut + + + Paste + Paste context menu item + Paste + + + No Guesses Found + No Guesses Found context menu item + No Guesses Found + + + Ignore + Ignore Spelling context menu item + Ignore + + + Add To Dictionary + Learn Spelling context menu item + Add To Dictionary + + + Search The Web + Search The Web context menu item + Search The Web + + + Look Up In Dictionary + Look Up in Dictionary context menu item + Look Up In Dictionary + + + Open Link + Open Link context menu item + Open Link + + + Ignore + Ignore Grammar context menu item + Ignore + + + Spelling + Spelling and Grammar context sub-menu item + Spelling + + + Show Spelling and Grammar + menu item title + Show Spelling and Grammar + + + Hide Spelling and Grammar + menu item title + Hide Spelling and Grammar + + + Check Spelling + Check spelling context menu item + Check Spelling + + + Check Spelling While Typing + Check spelling while typing context menu item + Check Spelling While Typing + + + Check Grammar With Spelling + Check grammar with spelling context menu item + Check Grammar With Spelling + + + Fonts + Font context sub-menu item + Fonts + + + Bold + Bold context menu item + Bold + + + Italic + Italic context menu item + Italic + + + Underline + Underline context menu item + Underline + + + Outline + Outline context menu item + Outline + + + Direction + Writing direction context sub-menu item + Direction + + + Text Direction + Text direction context sub-menu item + Text Direction + + + Default + Default writing direction context menu item + Default + + + Left to Right + Left to Right context menu item + Left to Right + + + Right to Left + Right to Left context menu item + Right to Left + + + Loading... + Media controller status message when the media is loading + Loading... + + + Live Broadcast + Media controller status message when watching a live broadcast + Live Broadcast + + + Audio Element + Media controller element + Audio Element + + + Video Element + Media controller element + Video Element + + + Mute Button + Media controller element + Mute Button + + + Unmute Button + Media controller element + Unmute Button + + + Play Button + Media controller element + Play Button + + + Pause Button + Media controller element + Pause Button + + + Slider + Media controller element + Slider + + + Slider Thumb + Media controller element + Slider Thumb + + + Rewind Button + Media controller element + Rewind Button + + + Return to Real-time Button + Media controller element + Return to Real-time Button + + + Elapsed Time + Media controller element + Elapsed Time + + + Remaining Time + Media controller element + Remaining Time + + + Status Display + Media controller element + Status Display + + + Fullscreen Button + Media controller element + Fullscreen Button + + + Seek Forward Button + Media controller element + Seek Forward Button + + + Seek Back Button + Media controller element + Seek Back Button + + + Audio element playback controls and status display + Media controller element + Audio element playback controls and status display + + + Video element playback controls and status display + Media controller element + Video element playback controls and status display + + + Mute audio tracks + Media controller element + Mute audio tracks + + + Unmute audio tracks + Media controller element + Unmute audio tracks + + + Begin playback + Media controller element + Begin playback + + + Pause playback + Media controller element + Pause playback + + + Movie time scrubber + Media controller element + Movie time scrubber + + + Movie time scrubber thumb + Media controller element + Movie time scrubber thumb + + + Rewind movie + Media controller element + Rewind movie + + + Return streaming movie to real-time + Media controller element + Return streaming movie to real-time + + + Current movie time + Media controller element + Current movie time + + + Remaining movie time + Media controller element + Remaining movie time + + + Current movie status + Media controller element + Current movie status + + + Play movie in full-screen mode + Media controller element + Play movie in full-screen mode + + + Seek quickly back + Media controller element + Seek quickly back + + + Seek quickly forward + Media controller element + Seek quickly forward + + + Indefinite time + Media time description + Indefinite time + + + %1 days %2 hours %3 minutes %4 seconds + Media time description + %1 days %2 hours %3 minutes %4 seconds + + + %1 hours %2 minutes %3 seconds + Media time description + %1 hours %2 minutes %3 seconds + + + %1 minutes %2 seconds + Media time description + %1 minutes %2 seconds + + + %1 seconds + Media time description + %1 seconds + + + Inspect + Inspect Element context menu item + Inspect + + + No recent searches + Label for only item in menu that appears when clicking on the search field image, when no searches have been performed + No recent searches + + + Recent searches + label for first item in the menu that appears when clicking on the search field image, used as embedded menu title + Recent searches + + + Clear recent searches + menu item in Recent Searches menu that empties menu's contents + Clear recent searches + + + Unknown + Unknown filesize FTP directory listing item + Unknown + + + Web Inspector - %2 + Web Inspector - %2 + + + %1 (%2x%3 pixels) + Title string for images + %1 (%2x%3 pixels) + + + Bad HTTP request + Bad HTTP request + + + This is a searchable index. Enter search keywords: + text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' + This is a searchable index. Enter search keywords: + + + Scroll here + Scroll here + + + Left edge + Left edge + + + Top + Top + + + Right edge + Right edge + + + Bottom + Bottom + + + Page left + Page left + + + Page up + Page up + + + Page right + Page right + + + Page down + Page down + + + Scroll left + Scroll left + + + Scroll up + Scroll up + + + Scroll right + Scroll right + + + Scroll down + Scroll down + + + %n file(s) + number of chosen file + + %n file(s) + %n file(s) + + + + JavaScript Alert - %1 + JavaScript Alert - %1 + + + JavaScript Confirm - %1 + JavaScript Confirm - %1 + + + JavaScript Prompt - %1 + JavaScript Prompt - %1 + + + JavaScript Problem - %1 + JavaScript Problem - %1 + + + The script on this page appears to have a problem. Do you want to stop the script? + The script on this page appears to have a problem. Do you want to stop the script? + + + Move the cursor to the next character + Move the cursor to the next character + + + Move the cursor to the previous character + Move the cursor to the previous character + + + Move the cursor to the next word + Move the cursor to the next word + + + Move the cursor to the previous word + Move the cursor to the previous word + + + Move the cursor to the next line + Move the cursor to the next line + + + Move the cursor to the previous line + Move the cursor to the previous line + + + Move the cursor to the start of the line + Move the cursor to the start of the line + + + Move the cursor to the end of the line + Move the cursor to the end of the line + + + Move the cursor to the start of the block + Move the cursor to the start of the block + + + Move the cursor to the end of the block + Move the cursor to the end of the block + + + Move the cursor to the start of the document + Move the cursor to the start of the document + + + Move the cursor to the end of the document + Move the cursor to the end of the document + + + Select all + Select all + + + Select to the next character + Select to the next character + + + Select to the previous character + Select to the previous character + + + Select to the next word + Select to the next word + + + Select to the previous word + Select to the previous word + + + Select to the next line + Select to the next line + + + Select to the previous line + Select to the previous line + + + Select to the start of the line + Select to the start of the line + + + Select to the end of the line + Select to the end of the line + + + Select to the start of the block + Select to the start of the block + + + Select to the end of the block + Select to the end of the block + + + Select to the start of the document + Select to the start of the document + + + Select to the end of the document + Select to the end of the document + + + Delete to the start of the word + Delete to the start of the word + + + Delete to the end of the word + Delete to the end of the word + + + Insert a new paragraph + Insert a new paragraph + + + Insert a new line + Insert a new line + + + Paste and Match Style + Paste and Match Style + + + Remove formatting + Remove formatting + + + Strikethrough + Strikethrough + + + Subscript + Subscript + + + Superscript + Superscript + + + Insert Bulleted List + Insert Bulleted List + + + Insert Numbered List + Insert Numbered List + + + Indent + Indent + + + Outdent + Outdent + + + Center + Center + + + Justify + Justify + + + Align Left + Align Left + + + Align Right + Align Right + + + + QWhatsThisAction + + What's This? + What's This? + + + + QWidget + + * + * + + + + QWizard + + Cancel + Cancel + + + Help + Help + + + < &Back + < &Back + + + &Finish + &Finish + + + &Help + &Help + + + Go Back + Go Back + + + Continue + Continue + + + Commit + Commit + + + Done + Done + + + &Next + &Next + + + &Next > + &Next > + + + + QWorkspace + + &Restore + &Restore + + + &Move + &Move + + + &Size + &Size + + + Mi&nimize + Mi&nimize + + + Ma&ximize + Ma&ximize + + + &Close + &Close + + + Stay on &Top + Stay on &Top + + + Minimize + Minimize + + + Restore Down + Restore Down + + + Close + Close + + + Sh&ade + Sh&ade + + + %1 - [%2] + %1 - [%2] + + + &Unshade + &Unshade + + + + QXml + + no error occurred + no error occurred + + + error triggered by consumer + error triggered by consumer + + + unexpected end of file + unexpected end of file + + + more than one document type definition + more than one document type definition + + + error occurred while parsing element + error occurred while parsing element + + + tag mismatch + tag mismatch + + + error occurred while parsing content + error occurred while parsing content + + + unexpected character + unexpected character + + + invalid name for processing instruction + invalid name for processing instruction + + + version expected while reading the XML declaration + version expected while reading the XML declaration + + + wrong value for standalone declaration + wrong value for standalone declaration + + + error occurred while parsing document type definition + error occurred while parsing document type definition + + + letter is expected + letter is expected + + + error occurred while parsing comment + error occurred while parsing comment + + + error occurred while parsing reference + error occurred while parsing reference + + + internal general entity reference not allowed in DTD + internal general entity reference not allowed in DTD + + + external parsed general entity reference not allowed in attribute value + external parsed general entity reference not allowed in attribute value + + + external parsed general entity reference not allowed in DTD + external parsed general entity reference not allowed in DTD + + + unparsed entity reference in wrong context + unparsed entity reference in wrong context + + + recursive entities + recursive entities + + + error in the text declaration of an external entity + error in the text declaration of an external entity + + + encoding declaration or standalone declaration expected while reading the XML declaration + encoding declaration or standalone declaration expected while reading the XML declaration + + + standalone declaration expected while reading the XML declaration + standalone declaration expected while reading the XML declaration + + + + QXmlPatternistCLI + + Warning in %1, at line %2, column %3: %4 + Warning in %1, at line %2, column %3: %4 + + + Warning in %1: %2 + Warning in %1: %2 + + + Unknown location + Unknown location + + + Error %1 in %2, at line %3, column %4: %5 + Error %1 in %2, at line %3, column %4: %5 + + + Error %1 in %2: %3 + Error %1 in %2: %3 + + + + QXmlStream + + Extra content at end of document. + Extra content at end of document. + + + Invalid entity value. + Invalid entity value. + + + Invalid XML character. + Invalid XML character. + + + Sequence ']]>' not allowed in content. + Sequence ']]>' not allowed in content. + + + Namespace prefix '%1' not declared + Namespace prefix '%1' not declared + + + Attribute redefined. + Attribute redefined. + + + Unexpected character '%1' in public id literal. + Unexpected character '%1' in public id literal. + + + Invalid XML version string. + Invalid XML version string. + + + Unsupported XML version. + Unsupported XML version. + + + %1 is an invalid encoding name. + %1 is an invalid encoding name. + + + Encoding %1 is unsupported + Encoding %1 is unsupported + + + Standalone accepts only yes or no. + Standalone accepts only yes or no. + + + Invalid attribute in XML declaration. + Invalid attribute in XML declaration. + + + Premature end of document. + Premature end of document. + + + Invalid document. + Invalid document. + + + Expected + Expected + + + , but got ' + , but got ' + + + Unexpected ' + Unexpected ' + + + Expected character data. + Expected character data. + + + Recursive entity detected. + Recursive entity detected. + + + Start tag expected. + Start tag expected. + + + XML declaration not at start of document. + XML declaration not at start of document. + + + NDATA in parameter entity declaration. + NDATA in parameter entity declaration. + + + %1 is an invalid processing instruction name. + %1 is an invalid processing instruction name. + + + Invalid processing instruction name. + Invalid processing instruction name. + + + Illegal namespace declaration. + Illegal namespace declaration. + + + Invalid XML name. + Invalid XML name. + + + Opening and ending tag mismatch. + Opening and ending tag mismatch. + + + Reference to unparsed entity '%1'. + Reference to unparsed entity '%1'. + + + Entity '%1' not declared. + Entity '%1' not declared. + + + Reference to external entity '%1' in attribute value. + Reference to external entity '%1' in attribute value. + + + Invalid character reference. + Invalid character reference. + + + Encountered incorrectly encoded content. + Encountered incorrectly encoded content. + + + The standalone pseudo attribute must appear after the encoding. + The standalone pseudo attribute must appear after the encoding. + + + %1 is an invalid PUBLIC identifier. + %1 is an invalid PUBLIC identifier. + + + + QtXmlPatterns + + At least one component must be present. + At least one component must be present. + + + %1 is not a valid value of type %2. + %1 is not a valid value of type %2. + + + When casting to %1 from %2, the source value cannot be %3. + When casting to %1 from %2, the source value cannot be %3. + + + Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values. + Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values. + + + The data of a processing instruction cannot contain the string %1 + The data of a processing instruction cannot contain the string %1 + + + %1 is an invalid %2 + %1 is an invalid %2 + + + %1 is not a valid XML 1.0 character. + %1 is not a valid XML 1.0 character. + + + %1 was called. + %1 was called. + + + In the replacement string, %1 must be followed by at least one digit when not escaped. + In the replacement string, %1 must be followed by at least one digit when not escaped. + + + In the replacement string, %1 can only be used to escape itself or %2, not %3 + In the replacement string, %1 can only be used to escape itself or %2, not %3 + + + %1 matches newline characters + %1 matches newline characters + + + Matches are case insensitive + Matches are case insensitive + + + %1 is an invalid regular expression pattern: %2 + %1 is an invalid regular expression pattern: %2 + + + It will not be possible to retrieve %1. + It will not be possible to retrieve %1. + + + The default collection is undefined + The default collection is undefined + + + %1 cannot be retrieved + %1 cannot be retrieved + + + The item %1 did not match the required type %2. + The item %1 did not match the required type %2. + + + %1 is an unknown schema type. + %1 is an unknown schema type. + + + A template with name %1 has already been declared. + A template with name %1 has already been declared. + + + Only one %1 declaration can occur in the query prolog. + Only one %1 declaration can occur in the query prolog. + + + The initialization of variable %1 depends on itself + The initialization of variable %1 depends on itself + + + The variable %1 is unused + The variable %1 is unused + + + Version %1 is not supported. The supported XQuery version is 1.0. + Version %1 is not supported. The supported XQuery version is 1.0. + + + No function with signature %1 is available + No function with signature %1 is available + + + It is not possible to redeclare prefix %1. + It is not possible to redeclare prefix %1. + + + Prefix %1 is already declared in the prolog. + Prefix %1 is already declared in the prolog. + + + The name of an option must have a prefix. There is no default namespace for options. + The name of an option must have a prefix. There is no default namespace for options. + + + The Schema Import feature is not supported, and therefore %1 declarations cannot occur. + The Schema Import feature is not supported, and therefore %1 declarations cannot occur. + + + The target namespace of a %1 cannot be empty. + The target namespace of a %1 cannot be empty. + + + The module import feature is not supported + The module import feature is not supported + + + The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2 + The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2 + + + A function already exists with the signature %1. + A function already exists with the signature %1. + + + No external functions are supported. All supported functions can be used directly, without first declaring them as external + No external functions are supported. All supported functions can be used directly, without first declaring them as external + + + The %1-axis is unsupported in XQuery + The %1-axis is unsupported in XQuery + + + The namespace URI cannot be the empty string when binding to a prefix, %1. + The namespace URI cannot be the empty string when binding to a prefix, %1. + + + %1 is an invalid namespace URI. + %1 is an invalid namespace URI. + + + It is not possible to bind to the prefix %1 + It is not possible to bind to the prefix %1 + + + Two namespace declaration attributes have the same name: %1. + Two namespace declaration attributes have the same name: %1. + + + The namespace URI must be a constant and cannot use enclosed expressions. + The namespace URI must be a constant and cannot use enclosed expressions. + + + %1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported. + %1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported. + + + empty + empty + + + zero or one + zero or one + + + exactly one + exactly one + + + one or more + one or more + + + zero or more + zero or more + + + The focus is undefined. + The focus is undefined. + + + An attribute by name %1 has already been created. + An attribute by name %1 has already been created. + + + Network timeout. + Network timeout. + + + Element %1 can't be serialized because it appears outside the document element. + Element %1 can't be serialized because it appears outside the document element. + + + Year %1 is invalid because it begins with %2. + Year %1 is invalid because it begins with %2. + + + Day %1 is outside the range %2..%3. + Day %1 is outside the range %2..%3. + + + Month %1 is outside the range %2..%3. + Month %1 is outside the range %2..%3. + + + Overflow: Can't represent date %1. + Overflow: Can't represent date %1. + + + Day %1 is invalid for month %2. + Day %1 is invalid for month %2. + + + Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; + Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; + + + Time %1:%2:%3.%4 is invalid. + Time %1:%2:%3.%4 is invalid. + + + Overflow: Date can't be represented. + Overflow: Date can't be represented. + + + At least one time component must appear after the %1-delimiter. + At least one time component must appear after the %1-delimiter. + + + Dividing a value of type %1 by %2 (not-a-number) is not allowed. + Dividing a value of type %1 by %2 (not-a-number) is not allowed. + + + Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed. + Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed. + + + Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed. + Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed. + + + A value of type %1 cannot have an Effective Boolean Value. + A value of type %1 cannot have an Effective Boolean Value. + + + Value %1 of type %2 exceeds maximum (%3). + Value %1 of type %2 exceeds maximum (%3). + + + Value %1 of type %2 is below minimum (%3). + Value %1 of type %2 is below minimum (%3). + + + A value of type %1 must contain an even number of digits. The value %2 does not. + A value of type %1 must contain an even number of digits. The value %2 does not. + + + %1 is not valid as a value of type %2. + %1 is not valid as a value of type %2. + + + Operator %1 cannot be used on type %2. + Operator %1 cannot be used on type %2. + + + Operator %1 cannot be used on atomic values of type %2 and %3. + Operator %1 cannot be used on atomic values of type %2 and %3. + + + The namespace URI in the name for a computed attribute cannot be %1. + The namespace URI in the name for a computed attribute cannot be %1. + + + The name for a computed attribute cannot have the namespace URI %1 with the local name %2. + The name for a computed attribute cannot have the namespace URI %1 with the local name %2. + + + Type error in cast, expected %1, received %2. + Type error in cast, expected %1, received %2. + + + When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed. + When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed. + + + A comment cannot contain %1 + A comment cannot contain %1 + + + A comment cannot end with a %1. + A comment cannot end with a %1. + + + An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place. + An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place. + + + A library module cannot be evaluated directly. It must be imported from a main module. + A library module cannot be evaluated directly. It must be imported from a main module. + + + No template by name %1 exists. + No template by name %1 exists. + + + A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type. + A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type. + + + A positional predicate must evaluate to a single numeric value. + A positional predicate must evaluate to a single numeric value. + + + The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, %2 is invalid. + The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, %2 is invalid. + + + %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. + %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. + + + The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. + The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. + + + No namespace binding exists for the prefix %1 + No namespace binding exists for the prefix %1 + + + No namespace binding exists for the prefix %1 in %2 + No namespace binding exists for the prefix %1 in %2 + + + The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration. + The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration. + + + The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + + + The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + + + If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same. + If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same. + + + %1 must be followed by %2 or %3, not at the end of the replacement string. + %1 must be followed by %2 or %3, not at the end of the replacement string. + + + %1 and %2 match the start and end of a line. + %1 and %2 match the start and end of a line. + + + Whitespace characters are removed, except when they appear in character classes + Whitespace characters are removed, except when they appear in character classes + + + %1 is an invalid flag for regular expressions. Valid flags are: + %1 is an invalid flag for regular expressions. Valid flags are: + + + If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified. + If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified. + + + The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization). + The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization). + + + A zone offset must be in the range %1..%2 inclusive. %3 is out of range. + A zone offset must be in the range %1..%2 inclusive. %3 is out of range. + + + Required cardinality is %1; got cardinality %2. + Required cardinality is %1; got cardinality %2. + + + The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2. + The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2. + + + The keyword %1 cannot occur with any other mode name. + The keyword %1 cannot occur with any other mode name. + + + No variable with name %1 exists + No variable with name %1 exists + + + The value of attribute %1 must be of type %2, which %3 isn't. + The value of attribute %1 must be of type %2, which %3 isn't. + + + The prefix %1 cannot be bound. By default, it is already bound to the namespace %2. + The prefix %1 cannot be bound. By default, it is already bound to the namespace %2. + + + A variable with name %1 has already been declared. + A variable with name %1 has already been declared. + + + No value is available for the external variable with name %1. + No value is available for the external variable with name %1. + + + A stylesheet function must have a prefixed name. + A stylesheet function must have a prefixed name. + + + The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. + The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. + + + An argument with name %1 has already been declared. Every argument name must be unique. + An argument with name %1 has already been declared. Every argument name must be unique. + + + When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. + When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. + + + In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching. + In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching. + + + In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching. + In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching. + + + In an XSL-T pattern, function %1 cannot have a third argument. + In an XSL-T pattern, function %1 cannot have a third argument. + + + In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. + In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. + + + In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can. + In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can. + + + %1 is an invalid template mode name. + %1 is an invalid template mode name. + + + The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. + The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. + + + The Schema Validation Feature is not supported. Hence, %1-expressions may not be used. + The Schema Validation Feature is not supported. Hence, %1-expressions may not be used. + + + None of the pragma expressions are supported. Therefore, a fallback expression must be present + None of the pragma expressions are supported. Therefore, a fallback expression must be present + + + Each name of a template parameter must be unique; %1 is duplicated. + Each name of a template parameter must be unique; %1 is duplicated. + + + No function with name %1 is available. + No function with name %1 is available. + + + %1 is not a valid numeric literal. + %1 is not a valid numeric literal. + + + W3C XML Schema identity constraint selector + W3C XML Schema identity constraint selector + + + W3C XML Schema identity constraint field + W3C XML Schema identity constraint field + + + A construct was encountered which is disallowed in the current language(%1). + A construct was encountered which is disallowed in the current language(%1). + + + Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared). + Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared). + + + Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared). + Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared). + + + An attribute with name %1 has already appeared on this element. + An attribute with name %1 has already appeared on this element. + + + A direct element constructor is not well-formed. %1 is ended with %2. + A direct element constructor is not well-formed. %1 is ended with %2. + + + The name %1 does not refer to any schema type. + The name %1 does not refer to any schema type. + + + %1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works. + %1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works. + + + %1 is not an atomic type. Casting is only possible to atomic types. + %1 is not an atomic type. Casting is only possible to atomic types. + + + %1 is not a valid name for a processing-instruction. + %1 is not a valid name for a processing-instruction. + + + The name of an extension expression must be in a namespace. + The name of an extension expression must be in a namespace. + + + Required type is %1, but %2 was found. + Required type is %1, but %2 was found. + + + Promoting %1 to %2 may cause loss of precision. + Promoting %1 to %2 may cause loss of precision. + + + It's not possible to add attributes after any other kind of node. + It's not possible to add attributes after any other kind of node. + + + Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported. + Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported. + + + Integer division (%1) by zero (%2) is undefined. + Integer division (%1) by zero (%2) is undefined. + + + Division (%1) by zero (%2) is undefined. + Division (%1) by zero (%2) is undefined. + + + Modulus division (%1) by zero (%2) is undefined. + Modulus division (%1) by zero (%2) is undefined. + + + %1 takes at most %n argument(s). %2 is therefore invalid. + + %1 takes at most %n argument(s). %2 is therefore invalid. + %1 takes at most %n argument(s). %2 is therefore invalid. + + + + %1 requires at least %n argument(s). %2 is therefore invalid. + + %1 requires at least %n argument(s). %2 is therefore invalid. + %1 requires at least %n argument(s). %2 is therefore invalid. + + + + The root node of the second argument to function %1 must be a document node. %2 is not a document node. + The root node of the second argument to function %1 must be a document node. %2 is not a document node. + + + The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) + The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) + + + A default namespace declaration must occur before function, variable, and option declarations. + A default namespace declaration must occur before function, variable, and option declarations. + + + Namespace declarations must occur before function, variable, and option declarations. + Namespace declarations must occur before function, variable, and option declarations. + + + Module imports must occur before function, variable, and option declarations. + Module imports must occur before function, variable, and option declarations. + + + %1 is not a whole number of minutes. + %1 is not a whole number of minutes. + + + Attribute %1 can't be serialized because it appears at the top level. + Attribute %1 can't be serialized because it appears at the top level. + + + %1 is an unsupported encoding. + %1 is an unsupported encoding. + + + %1 contains octets which are disallowed in the requested encoding %2. + %1 contains octets which are disallowed in the requested encoding %2. + + + The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character. + The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character. + + + Ambiguous rule match. + Ambiguous rule match. + + + In a namespace constructor, the value for a namespace cannot be an empty string. + In a namespace constructor, the value for a namespace cannot be an empty string. + + + The prefix must be a valid %1, which %2 is not. + The prefix must be a valid %1, which %2 is not. + + + The prefix %1 cannot be bound. + The prefix %1 cannot be bound. + + + Only the prefix %1 can be bound to %2 and vice versa. + Only the prefix %1 can be bound to %2 and vice versa. + + + The parameter %1 is required, but no corresponding %2 is supplied. + The parameter %1 is required, but no corresponding %2 is supplied. + + + The parameter %1 is passed, but no corresponding %2 exists. + The parameter %1 is passed, but no corresponding %2 exists. + + + The URI cannot have a fragment + The URI cannot have a fragment + + + Element %1 is not allowed at this location. + Element %1 is not allowed at this location. + + + Text nodes are not allowed at this location. + Text nodes are not allowed at this location. + + + Parse error: %1 + Parse error: %1 + + + The value of the XSL-T version attribute must be a value of type %1, which %2 isn't. + The value of the XSL-T version attribute must be a value of type %1, which %2 isn't. + + + Running an XSL-T 1.0 stylesheet with a 2.0 processor. + Running an XSL-T 1.0 stylesheet with a 2.0 processor. + + + Unknown XSL-T attribute %1. + Unknown XSL-T attribute %1. + + + Attribute %1 and %2 are mutually exclusive. + Attribute %1 and %2 are mutually exclusive. + + + In a simplified stylesheet module, attribute %1 must be present. + In a simplified stylesheet module, attribute %1 must be present. + + + If element %1 has no attribute %2, it cannot have attribute %3 or %4. + If element %1 has no attribute %2, it cannot have attribute %3 or %4. + + + Element %1 must have at least one of the attributes %2 or %3. + Element %1 must have at least one of the attributes %2 or %3. + + + At least one mode must be specified in the %1-attribute on element %2. + At least one mode must be specified in the %1-attribute on element %2. + + + Element %1 must come last. + Element %1 must come last. + + + At least one %1-element must occur before %2. + At least one %1-element must occur before %2. + + + Only one %1-element can appear. + Only one %1-element can appear. + + + At least one %1-element must occur inside %2. + At least one %1-element must occur inside %2. + + + When attribute %1 is present on %2, a sequence constructor cannot be used. + When attribute %1 is present on %2, a sequence constructor cannot be used. + + + Element %1 must have either a %2-attribute or a sequence constructor. + Element %1 must have either a %2-attribute or a sequence constructor. + + + When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor. + When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor. + + + Element %1 cannot have children. + Element %1 cannot have children. + + + Element %1 cannot have a sequence constructor. + Element %1 cannot have a sequence constructor. + + + The attribute %1 cannot appear on %2, when it is a child of %3. + The attribute %1 cannot appear on %2, when it is a child of %3. + + + A parameter in a function cannot be declared to be a tunnel. + A parameter in a function cannot be declared to be a tunnel. + + + This processor is not Schema-aware and therefore %1 cannot be used. + This processor is not Schema-aware and therefore %1 cannot be used. + + + Top level stylesheet elements must be in a non-null namespace, which %1 isn't. + Top level stylesheet elements must be in a non-null namespace, which %1 isn't. + + + The value for attribute %1 on element %2 must either be %3 or %4, not %5. + The value for attribute %1 on element %2 must either be %3 or %4, not %5. + + + Attribute %1 cannot have the value %2. + Attribute %1 cannot have the value %2. + + + The attribute %1 can only appear on the first %2 element. + The attribute %1 can only appear on the first %2 element. + + + At least one %1 element must appear as child of %2. + At least one %1 element must appear as child of %2. + + + %1 has inheritance loop in its base type %2. + %1 has inheritance loop in its base type %2. + + + Circular inheritance of base type %1. + Circular inheritance of base type %1. + + + Circular inheritance of union %1. + Circular inheritance of union %1. + + + %1 is not allowed to derive from %2 by restriction as the latter defines it as final. + %1 is not allowed to derive from %2 by restriction as the latter defines it as final. + + + %1 is not allowed to derive from %2 by extension as the latter defines it as final. + %1 is not allowed to derive from %2 by extension as the latter defines it as final. + + + Base type of simple type %1 cannot be complex type %2. + Base type of simple type %1 cannot be complex type %2. + + + Simple type %1 cannot have direct base type %2. + Simple type %1 cannot have direct base type %2. + + + Simple type %1 is not allowed to have base type %2. + Simple type %1 is not allowed to have base type %2. + + + Simple type %1 can only have simple atomic type as base type. + Simple type %1 can only have simple atomic type as base type. + + + Simple type %1 cannot derive from %2 as the latter defines restriction as final. + Simple type %1 cannot derive from %2 as the latter defines restriction as final. + + + Variety of item type of %1 must be either atomic or union. + Variety of item type of %1 must be either atomic or union. + + + Variety of member types of %1 must be atomic. + Variety of member types of %1 must be atomic. + + + %1 is not allowed to derive from %2 by list as the latter defines it as final. + %1 is not allowed to derive from %2 by list as the latter defines it as final. + + + Simple type %1 is only allowed to have %2 facet. + Simple type %1 is only allowed to have %2 facet. + + + Base type of simple type %1 must have variety of type list. + Base type of simple type %1 must have variety of type list. + + + Base type of simple type %1 has defined derivation by restriction as final. + Base type of simple type %1 has defined derivation by restriction as final. + + + Item type of base type does not match item type of %1. + Item type of base type does not match item type of %1. + + + Simple type %1 contains not allowed facet type %2. + Simple type %1 contains not allowed facet type %2. + + + %1 is not allowed to derive from %2 by union as the latter defines it as final. + %1 is not allowed to derive from %2 by union as the latter defines it as final. + + + %1 is not allowed to have any facets. + %1 is not allowed to have any facets. + + + Base type %1 of simple type %2 must have variety of union. + Base type %1 of simple type %2 must have variety of union. + + + Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute. + Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute. + + + Member type %1 cannot be derived from member type %2 of %3's base type %4. + Member type %1 cannot be derived from member type %2 of %3's base type %4. + + + Derivation method of %1 must be extension because the base type %2 is a simple type. + Derivation method of %1 must be extension because the base type %2 is a simple type. + + + Complex type %1 has duplicated element %2 in its content model. + Complex type %1 has duplicated element %2 in its content model. + + + Complex type %1 has non-deterministic content. + Complex type %1 has non-deterministic content. + + + Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3. + Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3. + + + Content model of complex type %1 is not a valid extension of content model of %2. + Content model of complex type %1 is not a valid extension of content model of %2. + + + Complex type %1 must have simple content. + Complex type %1 must have simple content. + + + Complex type %1 must have the same simple type as its base class %2. + Complex type %1 must have the same simple type as its base class %2. + + + Complex type %1 cannot be derived from base type %2%3. + Complex type %1 cannot be derived from base type %2%3. + + + Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3. + Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3. + + + Complex type %1 with simple content cannot be derived from complex base type %2. + Complex type %1 with simple content cannot be derived from complex base type %2. + + + Item type of simple type %1 cannot be a complex type. + Item type of simple type %1 cannot be a complex type. + + + Member type of simple type %1 cannot be a complex type. + Member type of simple type %1 cannot be a complex type. + + + %1 is not allowed to have a member type with the same name as itself. + %1 is not allowed to have a member type with the same name as itself. + + + %1 facet collides with %2 facet. + %1 facet collides with %2 facet. + + + %1 facet must have the same value as %2 facet of base type. + %1 facet must have the same value as %2 facet of base type. + + + %1 facet must be equal or greater than %2 facet of base type. + %1 facet must be equal or greater than %2 facet of base type. + + + %1 facet must be less than or equal to %2 facet of base type. + %1 facet must be less than or equal to %2 facet of base type. + + + %1 facet contains invalid regular expression + %1 facet contains invalid regular expression + + + Unknown notation %1 used in %2 facet. + Unknown notation %1 used in %2 facet. + + + %1 facet contains invalid value %2: %3. + %1 facet contains invalid value %2: %3. + + + %1 facet cannot be %2 or %3 if %4 facet of base type is %5. + %1 facet cannot be %2 or %3 if %4 facet of base type is %5. + + + %1 facet cannot be %2 if %3 facet of base type is %4. + %1 facet cannot be %2 if %3 facet of base type is %4. + + + %1 facet must be less than or equal to %2 facet. + %1 facet must be less than or equal to %2 facet. + + + %1 facet must be less than %2 facet of base type. + %1 facet must be less than %2 facet of base type. + + + %1 facet and %2 facet cannot appear together. + %1 facet and %2 facet cannot appear together. + + + %1 facet must be greater than %2 facet of base type. + %1 facet must be greater than %2 facet of base type. + + + %1 facet must be less than %2 facet. + %1 facet must be less than %2 facet. + + + %1 facet must be greater than or equal to %2 facet of base type. + %1 facet must be greater than or equal to %2 facet of base type. + + + Simple type contains not allowed facet %1. + Simple type contains not allowed facet %1. + + + %1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list. + %1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list. + + + Only %1 and %2 facets are allowed when derived by union. + Only %1 and %2 facets are allowed when derived by union. + + + %1 contains %2 facet with invalid data: %3. + %1 contains %2 facet with invalid data: %3. + + + Attribute group %1 contains attribute %2 twice. + Attribute group %1 contains attribute %2 twice. + + + Attribute group %1 contains two different attributes that both have types derived from %2. + Attribute group %1 contains two different attributes that both have types derived from %2. + + + Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3. + Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3. + + + Complex type %1 contains attribute %2 twice. + Complex type %1 contains attribute %2 twice. + + + Complex type %1 contains two different attributes that both have types derived from %2. + Complex type %1 contains two different attributes that both have types derived from %2. + + + Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3. + Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3. + + + Element %1 is not allowed to have a value constraint if its base type is complex. + Element %1 is not allowed to have a value constraint if its base type is complex. + + + Element %1 is not allowed to have a value constraint if its type is derived from %2. + Element %1 is not allowed to have a value constraint if its type is derived from %2. + + + Value constraint of element %1 is not of elements type: %2. + Value constraint of element %1 is not of elements type: %2. + + + Element %1 is not allowed to have substitution group affiliation as it is no global element. + Element %1 is not allowed to have substitution group affiliation as it is no global element. + + + Type of element %1 cannot be derived from type of substitution group affiliation. + Type of element %1 cannot be derived from type of substitution group affiliation. + + + Value constraint of attribute %1 is not of attributes type: %2. + Value constraint of attribute %1 is not of attributes type: %2. + + + Attribute %1 has value constraint but has type derived from %2. + Attribute %1 has value constraint but has type derived from %2. + + + %1 attribute in derived complex type must be %2 like in base type. + %1 attribute in derived complex type must be %2 like in base type. + + + Attribute %1 in derived complex type must have %2 value constraint like in base type. + Attribute %1 in derived complex type must have %2 value constraint like in base type. + + + Attribute %1 in derived complex type must have the same %2 value constraint like in base type. + Attribute %1 in derived complex type must have the same %2 value constraint like in base type. + + + Attribute %1 in derived complex type must have %2 value constraint. + Attribute %1 in derived complex type must have %2 value constraint. + + + processContent of base wildcard must be weaker than derived wildcard. + processContent of base wildcard must be weaker than derived wildcard. + + + Element %1 exists twice with different types. + Element %1 exists twice with different types. + + + Particle contains non-deterministic wildcards. + Particle contains non-deterministic wildcards. + + + Base attribute %1 is required but derived attribute is not. + Base attribute %1 is required but derived attribute is not. + + + Type of derived attribute %1 cannot be validly derived from type of base attribute. + Type of derived attribute %1 cannot be validly derived from type of base attribute. + + + Value constraint of derived attribute %1 does not match value constraint of base attribute. + Value constraint of derived attribute %1 does not match value constraint of base attribute. + + + Derived attribute %1 does not exist in the base definition. + Derived attribute %1 does not exist in the base definition. + + + Derived attribute %1 does not match the wildcard in the base definition. + Derived attribute %1 does not match the wildcard in the base definition. + + + Base attribute %1 is required but missing in derived definition. + Base attribute %1 is required but missing in derived definition. + + + Derived definition contains an %1 element that does not exists in the base definition + Derived definition contains an %1 element that does not exists in the base definition + + + Derived wildcard is not a subset of the base wildcard. + Derived wildcard is not a subset of the base wildcard. + + + %1 of derived wildcard is not a valid restriction of %2 of base wildcard + %1 of derived wildcard is not a valid restriction of %2 of base wildcard + + + Attribute %1 from base type is missing in derived type. + Attribute %1 from base type is missing in derived type. + + + Type of derived attribute %1 differs from type of base attribute. + Type of derived attribute %1 differs from type of base attribute. + + + Base definition contains an %1 element that is missing in the derived definition + Base definition contains an %1 element that is missing in the derived definition + + + %1 references unknown %2 or %3 element %4. + %1 references unknown %2 or %3 element %4. + + + %1 references identity constraint %2 that is no %3 or %4 element. + %1 references identity constraint %2 that is no %3 or %4 element. + + + %1 has a different number of fields from the identity constraint %2 that it references. + %1 has a different number of fields from the identity constraint %2 that it references. + + + Base type %1 of %2 element cannot be resolved. + Base type %1 of %2 element cannot be resolved. + + + Item type %1 of %2 element cannot be resolved. + Item type %1 of %2 element cannot be resolved. + + + Member type %1 of %2 element cannot be resolved. + Member type %1 of %2 element cannot be resolved. + + + Type %1 of %2 element cannot be resolved. + Type %1 of %2 element cannot be resolved. + + + Base type %1 of complex type cannot be resolved. + Base type %1 of complex type cannot be resolved. + + + %1 cannot have complex base type that has a %2. + %1 cannot have complex base type that has a %2. + + + Content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type. + Content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type. + + + Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model. + Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model. + + + Type of %1 element must be a simple type, %2 is not. + Type of %1 element must be a simple type, %2 is not. + + + Substitution group %1 of %2 element cannot be resolved. + Substitution group %1 of %2 element cannot be resolved. + + + Substitution group %1 has circular definition. + Substitution group %1 has circular definition. + + + Duplicated element names %1 in %2 element. + Duplicated element names %1 in %2 element. + + + Reference %1 of %2 element cannot be resolved. + Reference %1 of %2 element cannot be resolved. + + + Circular group reference for %1. + Circular group reference for %1. + + + %1 element is not allowed in this scope + %1 element is not allowed in this scope + + + %1 element cannot have %2 attribute with value other than %3. + %1 element cannot have %2 attribute with value other than %3. + + + %1 element cannot have %2 attribute with value other than %3 or %4. + %1 element cannot have %2 attribute with value other than %3 or %4. + + + %1 or %2 attribute of reference %3 does not match with the attribute declaration %4. + %1 or %2 attribute of reference %3 does not match with the attribute declaration %4. + + + Attribute group %1 has circular reference. + Attribute group %1 has circular reference. + + + %1 attribute in %2 must have %3 use like in base type %4. + %1 attribute in %2 must have %3 use like in base type %4. + + + Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2. + Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2. + + + %1 has attribute wildcard but its base type %2 has not. + %1 has attribute wildcard but its base type %2 has not. + + + Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible. + Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible. + + + Enumeration facet contains invalid content: {%1} is not a value of type %2. + Enumeration facet contains invalid content: {%1} is not a value of type %2. + + + Namespace prefix of qualified name %1 is not defined. + Namespace prefix of qualified name %1 is not defined. + + + %1 element %2 is not a valid restriction of the %3 element it redefines: %4. + %1 element %2 is not a valid restriction of the %3 element it redefines: %4. + + + Empty particle cannot be derived from non-empty particle. + Empty particle cannot be derived from non-empty particle. + + + Derived particle is missing element %1. + Derived particle is missing element %1. + + + Derived element %1 is missing value constraint as defined in base particle. + Derived element %1 is missing value constraint as defined in base particle. + + + Derived element %1 has weaker value constraint than base particle. + Derived element %1 has weaker value constraint than base particle. + + + Fixed value constraint of element %1 differs from value constraint in base particle. + Fixed value constraint of element %1 differs from value constraint in base particle. + + + Derived element %1 cannot be nillable as base element is not nillable. + Derived element %1 cannot be nillable as base element is not nillable. + + + Block constraints of derived element %1 must not be more weaker than in the base element. + Block constraints of derived element %1 must not be more weaker than in the base element. + + + Simple type of derived element %1 cannot be validly derived from base element. + Simple type of derived element %1 cannot be validly derived from base element. + + + Complex type of derived element %1 cannot be validly derived from base element. + Complex type of derived element %1 cannot be validly derived from base element. + + + Element %1 is missing in derived particle. + Element %1 is missing in derived particle. + + + Element %1 does not match namespace constraint of wildcard in base particle. + Element %1 does not match namespace constraint of wildcard in base particle. + + + Wildcard in derived particle is not a valid subset of wildcard in base particle. + Wildcard in derived particle is not a valid subset of wildcard in base particle. + + + processContent of wildcard in derived particle is weaker than wildcard in base particle. + processContent of wildcard in derived particle is weaker than wildcard in base particle. + + + Derived particle allows content that is not allowed in the base particle. + Derived particle allows content that is not allowed in the base particle. + + + Can not process unknown element %1, expected elements are: %2. + Can not process unknown element %1, expected elements are: %2. + + + Element %1 is not allowed in this scope, possible elements are: %2. + Element %1 is not allowed in this scope, possible elements are: %2. + + + Child element is missing in that scope, possible child elements are: %1. + Child element is missing in that scope, possible child elements are: %1. + + + Document is not a XML schema. + Document is not a XML schema. + + + %1 attribute of %2 element contains invalid content: {%3} is not a value of type %4. + %1 attribute of %2 element contains invalid content: {%3} is not a value of type %4. + + + %1 attribute of %2 element contains invalid content: {%3}. + %1 attribute of %2 element contains invalid content: {%3}. + + + Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema. + Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema. + + + Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema. + Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema. + + + %1 element is not allowed to have the same %2 attribute value as the target namespace %3. + %1 element is not allowed to have the same %2 attribute value as the target namespace %3. + + + %1 element without %2 attribute is not allowed inside schema without target namespace. + %1 element without %2 attribute is not allowed inside schema without target namespace. + + + %1 element is not allowed inside %2 element if %3 attribute is present. + %1 element is not allowed inside %2 element if %3 attribute is present. + + + %1 element has neither %2 attribute nor %3 child element. + %1 element has neither %2 attribute nor %3 child element. + + + %1 element with %2 child element must not have a %3 attribute. + %1 element with %2 child element must not have a %3 attribute. + + + %1 attribute of %2 element must be %3 or %4. + %1 attribute of %2 element must be %3 or %4. + + + %1 attribute of %2 element must have a value of %3. + %1 attribute of %2 element must have a value of %3. + + + %1 attribute of %2 element must have a value of %3 or %4. + %1 attribute of %2 element must have a value of %3 or %4. + + + %1 element must not have %2 and %3 attribute together. + %1 element must not have %2 and %3 attribute together. + + + Content of %1 attribute of %2 element must not be from namespace %3. + Content of %1 attribute of %2 element must not be from namespace %3. + + + %1 attribute of %2 element must not be %3. + %1 attribute of %2 element must not be %3. + + + %1 attribute of %2 element must have the value %3 because the %4 attribute is set. + %1 attribute of %2 element must have the value %3 because the %4 attribute is set. + + + Specifying use='prohibited' inside an attribute group has no effect. + Specifying use='prohibited' inside an attribute group has no effect. + + + %1 element must have either %2 or %3 attribute. + %1 element must have either %2 or %3 attribute. + + + %1 element must have either %2 attribute or %3 or %4 as child element. + %1 element must have either %2 attribute or %3 or %4 as child element. + + + %1 element requires either %2 or %3 attribute. + %1 element requires either %2 or %3 attribute. + + + Text or entity references not allowed inside %1 element + Text or entity references not allowed inside %1 element + + + %1 attribute of %2 element must contain %3, %4 or a list of URIs. + %1 attribute of %2 element must contain %3, %4 or a list of URIs. + + + %1 element is not allowed in this context. + %1 element is not allowed in this context. + + + %1 attribute of %2 element has larger value than %3 attribute. + %1 attribute of %2 element has larger value than %3 attribute. + + + Prefix of qualified name %1 is not defined. + Prefix of qualified name %1 is not defined. + + + %1 attribute of %2 element must either contain %3 or the other values. + %1 attribute of %2 element must either contain %3 or the other values. + + + Component with ID %1 has been defined previously. + Component with ID %1 has been defined previously. + + + Element %1 already defined. + Element %1 already defined. + + + Attribute %1 already defined. + Attribute %1 already defined. + + + Type %1 already defined. + Type %1 already defined. + + + Attribute group %1 already defined. + Attribute group %1 already defined. + + + Element group %1 already defined. + Element group %1 already defined. + + + Notation %1 already defined. + Notation %1 already defined. + + + Identity constraint %1 already defined. + Identity constraint %1 already defined. + + + Duplicated facets in simple type %1. + Duplicated facets in simple type %1. + + + %1 is not valid according to %2. + %1 is not valid according to %2. + + + String content does not match the length facet. + String content does not match the length facet. + + + String content does not match the minLength facet. + String content does not match the minLength facet. + + + String content does not match the maxLength facet. + String content does not match the maxLength facet. + + + String content does not match pattern facet. + String content does not match pattern facet. + + + String content is not listed in the enumeration facet. + String content is not listed in the enumeration facet. + + + Signed integer content does not match the maxInclusive facet. + Signed integer content does not match the maxInclusive facet. + + + Signed integer content does not match the maxExclusive facet. + Signed integer content does not match the maxExclusive facet. + + + Signed integer content does not match the minInclusive facet. + Signed integer content does not match the minInclusive facet. + + + Signed integer content does not match the minExclusive facet. + Signed integer content does not match the minExclusive facet. + + + Signed integer content is not listed in the enumeration facet. + Signed integer content is not listed in the enumeration facet. + + + Signed integer content does not match pattern facet. + Signed integer content does not match pattern facet. + + + Signed integer content does not match in the totalDigits facet. + Signed integer content does not match in the totalDigits facet. + + + Unsigned integer content does not match the maxInclusive facet. + Unsigned integer content does not match the maxInclusive facet. + + + Unsigned integer content does not match the maxExclusive facet. + Unsigned integer content does not match the maxExclusive facet. + + + Unsigned integer content does not match the minInclusive facet. + Unsigned integer content does not match the minInclusive facet. + + + Unsigned integer content does not match the minExclusive facet. + Unsigned integer content does not match the minExclusive facet. + + + Unsigned integer content is not listed in the enumeration facet. + Unsigned integer content is not listed in the enumeration facet. + + + Unsigned integer content does not match pattern facet. + Unsigned integer content does not match pattern facet. + + + Unsigned integer content does not match in the totalDigits facet. + Unsigned integer content does not match in the totalDigits facet. + + + Double content does not match the maxInclusive facet. + Double content does not match the maxInclusive facet. + + + Double content does not match the maxExclusive facet. + Double content does not match the maxExclusive facet. + + + Double content does not match the minInclusive facet. + Double content does not match the minInclusive facet. + + + Double content does not match the minExclusive facet. + Double content does not match the minExclusive facet. + + + Double content is not listed in the enumeration facet. + Double content is not listed in the enumeration facet. + + + Double content does not match pattern facet. + Double content does not match pattern facet. + + + Decimal content does not match in the fractionDigits facet. + Decimal content does not match in the fractionDigits facet. + + + Decimal content does not match in the totalDigits facet. + Decimal content does not match in the totalDigits facet. + + + Date time content does not match the maxInclusive facet. + Date time content does not match the maxInclusive facet. + + + Date time content does not match the maxExclusive facet. + Date time content does not match the maxExclusive facet. + + + Date time content does not match the minInclusive facet. + Date time content does not match the minInclusive facet. + + + Date time content does not match the minExclusive facet. + Date time content does not match the minExclusive facet. + + + Date time content is not listed in the enumeration facet. + Date time content is not listed in the enumeration facet. + + + Date time content does not match pattern facet. + Date time content does not match pattern facet. + + + Duration content does not match the maxInclusive facet. + Duration content does not match the maxInclusive facet. + + + Duration content does not match the maxExclusive facet. + Duration content does not match the maxExclusive facet. + + + Duration content does not match the minInclusive facet. + Duration content does not match the minInclusive facet. + + + Duration content does not match the minExclusive facet. + Duration content does not match the minExclusive facet. + + + Duration content is not listed in the enumeration facet. + Duration content is not listed in the enumeration facet. + + + Duration content does not match pattern facet. + Duration content does not match pattern facet. + + + Boolean content does not match pattern facet. + Boolean content does not match pattern facet. + + + Binary content does not match the length facet. + Binary content does not match the length facet. + + + Binary content does not match the minLength facet. + Binary content does not match the minLength facet. + + + Binary content does not match the maxLength facet. + Binary content does not match the maxLength facet. + + + Binary content is not listed in the enumeration facet. + Binary content is not listed in the enumeration facet. + + + Invalid QName content: %1. + Invalid QName content: %1. + + + QName content is not listed in the enumeration facet. + QName content is not listed in the enumeration facet. + + + QName content does not match pattern facet. + QName content does not match pattern facet. + + + Notation content is not listed in the enumeration facet. + Notation content is not listed in the enumeration facet. + + + List content does not match length facet. + List content does not match length facet. + + + List content does not match minLength facet. + List content does not match minLength facet. + + + List content does not match maxLength facet. + List content does not match maxLength facet. + + + List content is not listed in the enumeration facet. + List content is not listed in the enumeration facet. + + + List content does not match pattern facet. + List content does not match pattern facet. + + + Union content is not listed in the enumeration facet. + Union content is not listed in the enumeration facet. + + + Union content does not match pattern facet. + Union content does not match pattern facet. + + + Data of type %1 are not allowed to be empty. + Data of type %1 are not allowed to be empty. + + + Element %1 is missing child element. + Element %1 is missing child element. + + + There is one IDREF value with no corresponding ID: %1. + There is one IDREF value with no corresponding ID: %1. + + + Loaded schema file is invalid. + Loaded schema file is invalid. + + + %1 contains invalid data. + %1 contains invalid data. + + + xsi:schemaLocation namespace %1 has already appeared earlier in the instance document. + xsi:schemaLocation namespace %1 has already appeared earlier in the instance document. + + + xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute. + xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute. + + + No schema defined for validation. + No schema defined for validation. + + + No definition for element %1 available. + No definition for element %1 available. + + + Specified type %1 is not known to the schema. + Specified type %1 is not known to the schema. + + + Element %1 is not defined in this scope. + Element %1 is not defined in this scope. + + + Declaration for element %1 does not exist. + Declaration for element %1 does not exist. + + + Element %1 contains invalid content. + Element %1 contains invalid content. + + + Element %1 is declared as abstract. + Element %1 is declared as abstract. + + + Element %1 is not nillable. + Element %1 is not nillable. + + + Attribute %1 contains invalid data: %2 + Attribute %1 contains invalid data: %2 + + + Element contains content although it is nillable. + Element contains content although it is nillable. + + + Fixed value constraint not allowed if element is nillable. + Fixed value constraint not allowed if element is nillable. + + + Element %1 cannot contain other elements, as it has a fixed content. + Element %1 cannot contain other elements, as it has a fixed content. + + + Specified type %1 is not validly substitutable with element type %2. + Specified type %1 is not validly substitutable with element type %2. + + + Complex type %1 is not allowed to be abstract. + Complex type %1 is not allowed to be abstract. + + + Element %1 contains not allowed attributes. + Element %1 contains not allowed attributes. + + + Element %1 contains not allowed child element. + Element %1 contains not allowed child element. + + + Content of element %1 does not match its type definition: %2. + Content of element %1 does not match its type definition: %2. + + + Content of element %1 does not match defined value constraint. + Content of element %1 does not match defined value constraint. + + + Element %1 contains not allowed child content. + Element %1 contains not allowed child content. + + + Element %1 contains not allowed text content. + Element %1 contains not allowed text content. + + + Element %1 is missing required attribute %2. + Element %1 is missing required attribute %2. + + + Attribute %1 does not match the attribute wildcard. + Attribute %1 does not match the attribute wildcard. + + + Declaration for attribute %1 does not exist. + Declaration for attribute %1 does not exist. + + + Element %1 contains two attributes of type %2. + Element %1 contains two attributes of type %2. + + + Attribute %1 contains invalid content. + Attribute %1 contains invalid content. + + + Element %1 contains unknown attribute %2. + Element %1 contains unknown attribute %2. + + + Content of attribute %1 does not match its type definition: %2. + Content of attribute %1 does not match its type definition: %2. + + + Content of attribute %1 does not match defined value constraint. + Content of attribute %1 does not match defined value constraint. + + + Non-unique value found for constraint %1. + Non-unique value found for constraint %1. + + + Key constraint %1 contains absent fields. + Key constraint %1 contains absent fields. + + + Key constraint %1 contains references nillable element %2. + Key constraint %1 contains references nillable element %2. + + + No referenced value found for key reference %1. + No referenced value found for key reference %1. + + + More than one value found for field %1. + More than one value found for field %1. + + + Field %1 has no simple type. + Field %1 has no simple type. + + + ID value '%1' is not unique. + ID value '%1' is not unique. + + + '%1' attribute contains invalid QName content: %2. + '%1' attribute contains invalid QName content: %2. + + + diff --git a/config.profiles/symbian/translations/qt_zh_cn_symbian.ts b/config.profiles/symbian/translations/qt_zh_cn_symbian.ts new file mode 100644 index 0000000..b1b9941 --- /dev/null +++ b/config.profiles/symbian/translations/qt_zh_cn_symbian.ts @@ -0,0 +1,8517 @@ + + + + + + CloseButton + + Close Tab + 关闭标签页 + + + + FakeReply + + Fake error ! + 虚假错误! + + + Invalid URL + 无效URL + + + + Phonon:: + + Notifications + 通知 + + + Music + 音乐 + + + Video + 视频 + + + Communication + 通讯 + + + Games + 游戏 + + + Accessibility + 无障碍环境 + + + + Phonon::AudioOutput + + <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> + <html>音频播放设备<b>%1</b>不工作。<br/>无法返回到<b>%2</b>。</html> + + + <html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html> + <html>切换到刚刚可用且较为<br/>偏爱的音频播放设备<b>%1</b>。</html> + + + Revert back to device '%1' + 回复到设备"%1" + + + + Phonon::Gstreamer::Backend + + Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. + Some video features have been disabled. + 警告:看起来,您没有安装 gstreamer0.10-plugins-good 包。 + 一些视频特性已经被关闭。 + + + Warning: You do not seem to have the base GStreamer plugins installed. + All audio and video support has been disabled + 警告:看起来,您没有安装基础的 GStreamer 插件。 + 所有的音频和视频支持都已经被关闭。 + + + + Phonon::Gstreamer::MediaObject + + Cannot start playback. + +Check your GStreamer installation and make sure you +have libgstreamer-plugins-base installed. + + + + A required codec is missing. You need to install the following codec(s) to play this content: %0 + 缺少一个需要的解码器。您需要安装如下解码器来播放这个内容:%0 + + + Could not open media source. + 不能打开媒体源。 + + + Invalid source type. + 无效的源类型。 + + + Could not locate media source. + 不能定位媒体源。 + + + Could not open audio device. The device is already in use. + 不能打开音频设备。这个设备正在被使用。 + + + Could not decode media source. + 不能解码媒体源。 + + + + Phonon::MMF + + Audio Output + 音频输出 + + + The audio output device + 音频输出设备 + + + No error + 无错误 + + + Not found + 未找到 + + + Out of memory + 存储不足 + + + Not supported + 不支持 + + + Overflow + 溢出 + + + Underflow + 下溢 + + + Already exists + 已经存在 + + + Path not found + 未找到路径 + + + In use + 在使用中 + + + Not ready + 未就绪 + + + Access denied + 访问被拒绝 + + + Could not connect + 无法连接 + + + Disconnected + 已断开连接 + + + Permission denied + 权限被拒绝 + + + Insufficient bandwidth + 带宽不足 + + + Network unavailable + 网络不可用 + + + Network communication error + 网络通讯错误 + + + Streaming not supported + 不支持流 + + + Server alert + 服务器提示 + + + Invalid protocol + 无效协议 + + + Invalid URL + 无效URL + + + Multicast error + 组播错误 + + + Proxy server error + 代理服务器错误 + + + Proxy server not supported + 代理服务器不受支持 + + + Audio output error + 音频输出错误 + + + Video output error + 视频输出错误 + + + Decoder error + 解码器错误 + + + Audio or video components could not be played + 无法播放音频或视频组件 + + + DRM error + DRM错误 + + + Unknown error (%1) + 未知错误(%1) + + + + Phonon::MMF::AbstractMediaPlayer + + Not ready to play + 不准备播放 + + + Error opening file + 打开文件时出错 + + + Error opening URL + 打开URL时出错 + + + Setting volume failed + 设置卷失败 + + + Playback complete + 播放结束 + + + + Phonon::MMF::AudioEqualizer + + %1 Hz + %1赫兹 + + + + Phonon::MMF::AudioPlayer + + Getting position failed + 获取位置失败 + + + Opening clip failed + 打开片段失败 + + + + Phonon::MMF::EffectFactory + + Enabled + 已启用 + + + + Phonon::MMF::EnvironmentalReverb + + Decay HF ratio (%) + 高频衰减率(%) + + + Decay time (ms) + 衰减时间(毫秒) + + + Density (%) + 密度(%) + + + Diffusion (%) + 散射(%) + + + Reflections delay (ms) + 反映延迟(毫秒) + + + Reflections level (mB) + 反映级别(mB) + + + Reverb delay (ms) + 混响延迟(毫秒) + + + Reverb level (mB) + 混响级别(mB) + + + Room HF level + 高频室级别 + + + Room level (mB) + 室级别(mB) + + + + Phonon::MMF::MediaObject + + Error opening source: type not supported + 打开源时出错:类型不受支持 + + + Error opening source: media type could not be determined + 打开源时出错:无法判断多媒体类型 + + + + Phonon::MMF::StereoWidening + + Level (%) + 级别(%) + + + + Phonon::MMF::VideoPlayer + + Pause failed + 暂停失败 + + + Seek failed + 寻找失败 + + + Getting position failed + 获取位置失败 + + + Opening clip failed + 打开片段失败 + + + Buffering clip failed + 片段缓冲失败 + + + Video display error + 视频显示错误 + + + + Phonon::VolumeSlider + + Volume: %1% + 音量:%1% + + + Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1% + 请使用这个滑块调节音量。最左为%0,最右为%1% + + + Muted + 已静音 + + + + Q3Accel + + %1, %2 not defined + %1,%2未定义 + + + Ambiguous %1 not handled + 不明确的%1没有被处理 + + + + Q3DataTable + + True + + + + False + + + + Insert + 插入 + + + Update + 更新 + + + Delete + 删除 + + + + Q3FileDialog + + Copy or Move a File + 复制或者移动一个文件 + + + Read: %1 + 读取:%1 + + + Write: %1 + 写入:%1 + + + Cancel + 取消 + + + All Files (*) + 所有文件 (*) + + + Name + 名称 + + + Size + 大小 + + + Type + 类型 + + + Date + 日期 + + + Attributes + 属性 + + + &OK + 确定(&O) + + + Look &in: + 查找范围(&I): + + + File &name: + 文件名称(&N): + + + File &type: + 文件类型(&T): + + + Back + 后退 + + + One directory up + 向上一级 + + + Create New Folder + 创建新文件夹 + + + List View + 列表视图 + + + Detail View + 详细视图 + + + Preview File Info + 预览文件信息 + + + Preview File Contents + 预览文件内容 + + + Read-write + 读写 + + + Read-only + 只读 + + + Write-only + 只写 + + + Inaccessible + 不可访问的 + + + Symlink to File + 文件的系统链接 + + + Symlink to Directory + 目录的系统链接 + + + Symlink to Special + 特殊的系统链接 + + + File + 文件 + + + Dir + 目录 + + + Special + 特殊 + + + Open + 打开 + + + Save As + 另存为 + + + &Open + 打开(&O) + + + &Save + 保存(&S) + + + &Rename + 重命名(&R) + + + &Delete + 删除(&D) + + + R&eload + 重新载入(&E) + + + Sort by &Name + 按名称排列(&N) + + + Sort by &Size + 按大小排列(&S) + + + Sort by &Date + 按日期排列(&D) + + + &Unsorted + 未排列的(&U) + + + Sort + 排列 + + + Show &hidden files + 显示隐藏文件(&H) + + + the file + 文件 + + + the directory + 目录 + + + the symlink + 系统链接 + + + Delete %1 + 删除%1 + + + <qt>Are you sure you wish to delete %1 "%2"?</qt> + <qt>你确认你想删除%1,“%2”?</qt> + + + &Yes + 是(&Y) + + + &No + 否(&N) + + + New Folder 1 + 新建文件夹1 + + + New Folder + 新建文件夹 + + + New Folder %1 + 新建文件夹%1 + + + Find Directory + 查找目录 + + + Directories + 目录 + + + Directory: + 目录: + + + Error + 错误 + + + %1 +File not found. +Check path and filename. + 文件%1 +未找到。 +请检查路径和文件名。 + + + + All Files (*.*) + 所有文件 (*.*) + + + Open + 打开 + + + Select a Directory + 选择一个目录 + + + + Q3LocalFs + + Could not read directory +%1 + 不能读取目录 +%1 + + + Could not create directory +%1 + 不能创建目录 +%1 + + + Could not remove file or directory +%1 + 不能移除文件或者目录 +%1 + + + Could not rename +%1 +to +%2 + 不能把 +%1 +重命名为 +%2 + + + Could not open +%1 + 不能打开 +%1 + + + Could not write +%1 + 不能写入 +%1 + + + + Q3MainWindow + + Line up + 排列 + + + Customize... + 自定义... + + + + Q3NetworkProtocol + + Operation stopped by the user + 操作被用户停止 + + + + Q3ProgressDialog + + Cancel + 取消 + + + + Q3TabDialog + + OK + 确认 + + + Apply + 应用 + + + Help + 帮助 + + + Defaults + 默认 + + + Cancel + 取消 + + + + Q3TextEdit + + &Undo + 撤消(&U) + + + &Redo + 恢复(&R) + + + Cu&t + 剪切(&T) + + + &Copy + 复制(&C) + + + &Paste + 粘贴(&P) + + + Clear + 清空 + + + Select All + 选择全部 + + + + Q3TitleBar + + System + 系统 + + + Restore up + 向上恢复 + + + Minimize + 最小化 + + + Restore down + 向下恢复 + + + Maximize + 最大化 + + + Close + 关闭 + + + Contains commands to manipulate the window + 包含操作窗口的命令。 + + + Puts a minimized window back to normal + + + + Moves the window out of the way + 把窗口移到外面 + + + Puts a maximized window back to normal + 把一个最大化窗口恢复为普通状态 + + + Makes the window full screen + 窗口全屏化 + + + Closes the window + 关闭窗口 + + + Displays the name of the window and contains controls to manipulate it + 显示窗口名称并且包含维护它的控件 + + + + Q3ToolBar + + More... + 更多... + + + + Q3UrlOperator + + The protocol `%1' is not supported + 协议“%1”不被支持 + + + The protocol `%1' does not support listing directories + 协议“%1”不支持列出目录 + + + The protocol `%1' does not support creating new directories + 协议“%1”不支持创建新目录 + + + The protocol `%1' does not support removing files or directories + 协议“%1”不支持移除文件或者目录 + + + The protocol `%1' does not support renaming files or directories + 协议“%1”不支持重命名文件或者目录 + + + The protocol `%1' does not support getting files + 协议“%1”不支持获取文件 + + + The protocol `%1' does not support putting files + 协议“%1”不支持上传文件 + + + The protocol `%1' does not support copying or moving files or directories + 协议“%1”不支持复制或者移动文件或者目录 + + + (unknown) + (未知的) + + + + Q3Wizard + + &Cancel + 取消(&C) + + + < &Back + < 上一步(&B) + + + &Next > + 下一步(&N) > + + + &Finish + 完成(&F) + + + &Help + 帮助(&H) + + + + QAbstractSocket + + Host not found + 主机未找到 + + + Connection refused + 连接被拒绝 + + + Connection timed out + 连接超时 + + + Operation on socket is not supported + Socket操作不被支持 + + + Socket operation timed out + 套接字操作超时 + + + Socket is not connected + 套接字没有被连接 + + + Network unreachable + 网络不能访问 + + + + QAbstractSpinBox + + &Step up + 增加(&S) + + + Step &down + 减少(&D) + + + &Select All + 选择关部(&S) + + + + QAccessibleButton + + Press + 按下 + + + + QApplication + + QT_LAYOUT_DIRECTION + Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. + LTR + + + Executable '%1' requires Qt %2, found Qt %3. + 执行“%1”需要Qt %2,只找到了Qt %3。 + + + Incompatible Qt Library Error + 不兼容的Qt错误 + + + Activate + 激活 + + + Activates the program's main window + 激活这个程序的主窗口 + + + + QAxSelect + + Select ActiveX Control + 选择ActiveX控件 + + + OK + 确定 + + + &Cancel + 取消(&C) + + + COM &Object: + COM对象(&O): + + + + QCheckBox + + Uncheck + 取消选中 + + + Check + 选中 + + + Toggle + 切换 + + + + QColorDialog + + Hu&e: + 色调(&E): + + + &Sat: + 饱和度(&S): + + + &Val: + 亮度(&V): + + + &Red: + 红色(&R): + + + &Green: + 绿色(&G): + + + Bl&ue: + 蓝色(&U): + + + A&lpha channel: + Alpha通道(&A): + + + Select Color + 选择颜色 + + + &Basic colors + 基本颜色(&B) + + + &Custom colors + 自定义颜色(&C) + + + &Add to Custom Colors + 添加到自定义颜色(&A) + + + + QComboBox + + Open + 打开 + + + False + + + + True + + + + Close + 关闭 + + + + QCoreApplication + + %1: key is empty + QSystemSemaphore + %1:键是空的 + + + %1: unable to make key + QSystemSemaphore + %1:不能制造键 + + + %1: ftok failed + QSystemSemaphore + %1:ftok 失败 + + + %1: already exists + QSystemSemaphore + %1:已经存在 + + + %1: does not exist + QSystemSemaphore + %1:不存在 + + + %1: out of resources + QSystemSemaphore + %1:资源耗尽了 + + + %1: unknown error %2 + QSystemSemaphore + %1:未知错误 %2 + + + + QDB2Driver + + Unable to connect + 不能连接 + + + Unable to commit transaction + 不能提交事务 + + + Unable to rollback transaction + 不能回滚事务 + + + Unable to set autocommit + 不能设置自动提交 + + + + QDB2Result + + Unable to execute statement + 不能执行语句 + + + Unable to prepare statement + 不能准备语句 + + + Unable to bind variable + 不能帮定变量 + + + Unable to fetch record %1 + 不能获取记录%1 + + + Unable to fetch next + 不能获取下一个 + + + Unable to fetch first + 不能获取第一个 + + + + QDateTimeEdit + + AM + AM + + + am + am + + + PM + PM + + + pm + pm + + + + QDial + + QDial + QDial + + + SpeedoMeter + SpeedoMeter + + + SliderHandle + SliderHandle + + + + QDialog + + What's This? + 这是什么? + + + Done + 完成 + + + + QDialogButtonBox + + OK + 确定 + + + Save + 保存 + + + &Save + 保存(&S) + + + Open + 打开 + + + Cancel + 取消 + + + &Cancel + 取消(&C) + + + Close + 关闭 + + + &Close + 关闭(&C) + + + Apply + 应用 + + + Reset + 重置 + + + Help + 帮助 + + + Don't Save + 不保存 + + + Discard + 抛弃 + + + &Yes + 是(&Y) + + + Yes to &All + 全部是(&A) + + + &No + 否(&N) + + + N&o to All + 全部否(&O) + + + Save All + 保存全部 + + + Abort + 放弃 + + + Retry + 重试 + + + Ignore + 忽略 + + + Restore Defaults + 恢复默认 + + + Close without Saving + 不保存关闭 + + + &OK + 确定(&O) + + + + QDirModel + + Name + 名称 + + + Size + 大小 + + + Kind + Match OS X Finder + 类型 + + + Type + All other platforms + 类型 + + + Date Modified + 日期被修改 + + + + QDockWidget + + Close + 关闭 + + + Dock + 锚接 + + + Float + 浮动 + + + + QDoubleSpinBox + + More + 更多 + + + Less + 更少 + + + + QErrorMessage + + &Show this message again + 再次显示这个消息(&S) + + + &OK + 确定(&O) + + + Debug Message: + 调试消息: + + + Warning: + 警告: + + + Fatal Error: + 致命错误: + + + + QFile + + Destination file exists + 目标文件已存在 + + + Will not rename sequential file using block copy + 将不使用块复制重命名顺序文件 + + + Cannot remove source file + 无法删除源文件 + + + Cannot open %1 for input + 无法输入 %1 + + + Cannot open for output + 无法输出 + + + Failure to write block + 写块失败 + + + Cannot create %1 for output + 无法创建 %1 + + + + QFileDialog + + All Files (*) + 所有文件 (*) + + + Back + 后退 + + + List View + 列表视图 + + + Detail View + 详细视图 + + + File + 文件 + + + Open + 打开 + + + Save As + 另存为 + + + &Open + 打开(&O) + + + &Save + 保存(&S) + + + Recent Places + 最近的地方 + + + &Rename + 重命名(&R) + + + &Delete + 删除(&D) + + + Show &hidden files + 显示隐藏文件(&H) + + + New Folder + 新建文件夹 + + + Find Directory + 查找目录 + + + Directories + 目录 + + + All Files (*.*) + 所有文件 (*.*) + + + Directory: + 目录: + + + %1 already exists. +Do you want to replace it? + %1已经存在。 +你想要替换它么? + + + %1 +File not found. +Please verify the correct file name was given. + 文件%1 +没有找到。 +请核实已给定正确文件名。 + + + My Computer + 我的计算机 + + + Parent Directory + 父目录 + + + Files of type: + 文件类型: + + + %1 +Directory not found. +Please verify the correct directory name was given. + 目录%1 +没有找到。 +请核实已给定正确目录名。 + + + '%1' is write protected. +Do you want to delete it anyway? + “%1“是写保护的。 +你还是想删除它么? + + + Are sure you want to delete '%1'? + 你确认你想删除“%1“? + + + Could not delete directory. + 不能删除目录。 + + + Drive + 驱动器 + + + File Folder + Match Windows Explorer + 文件文件夹 + + + Folder + All other platforms + 文件夹 + + + Alias + Mac OS X Finder + 别名 + + + Shortcut + All other platforms + 快捷方式 + + + Unknown + 未知的 + + + Show + 显示 + + + Forward + 前进 + + + &New Folder + 新建文件夹(&N) + + + &Choose + 选择(&C) + + + Remove + 移除 + + + File &name: + 文件名称(&N): + + + Look in: + 查看: + + + Create New Folder + 创建新文件夹 + + + + QFileSystemModel + + %1 TB + %1 TB + + + %1 GB + %1 GB + + + %1 MB + %1 MB + + + %1 KB + %1千字节 + + + %1 bytes + %1字节 + + + Invalid filename + 无效文件名 + + + <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. + <b>名称“%1“不能被使用。</b><p>请使用另外一个包含更少字符或者不含有标点符号的名称。 + + + Name + 名称 + + + Size + 大小 + + + Kind + Match OS X Finder + 类型 + + + Type + All other platforms + 类型 + + + Date Modified + 日期被修改 + + + My Computer + 我的计算机 + + + Computer + 计算机 + + + %1 byte(s) + %1字节 + + + + QFontDatabase + + Normal + 普通 + + + Bold + 粗体 + + + Demi Bold + 半粗体 + + + Black + 黑体 + + + Demi + 半体 + + + Light + 轻体 + + + Italic + 意大利体 + + + Oblique + 斜体 + + + Any + 任意 + + + Latin + 拉丁文 + + + Greek + 希腊文 + + + Cyrillic + 西里尔文 + + + Armenian + 亚美尼亚文 + + + Hebrew + 希伯来文 + + + Arabic + 阿拉伯文 + + + Syriac + 叙利亚文 + + + Thaana + 马尔代夫文 + + + Devanagari + 梵文 + + + Bengali + 孟加拉文 + + + Gurmukhi + 旁遮普文 + + + Gujarati + 古吉拉特文 + + + Oriya + 奥里雅文 + + + Tamil + 泰米尔文 + + + Telugu + 泰卢固文 + + + Kannada + 埃纳德文 + + + Malayalam + 马拉亚拉姆文 + + + Sinhala + 僧伽罗文 + + + Thai + 泰国文 + + + Lao + 老挝文 + + + Tibetan + 藏文 + + + Myanmar + 缅甸文 + + + Georgian + 格鲁吉亚文 + + + Khmer + 谷美尔文 + + + Simplified Chinese + 简体中文 + + + Traditional Chinese + 繁体中文 + + + Japanese + 日文 + + + Korean + 韩文 + + + Vietnamese + 越南文 + + + Symbol + 符号 + + + Ogham + 欧甘文 + + + Runic + 古北欧文 + + + N'Ko + N'Ko + + + + QFontDialog + + &Font + 字体(&F) + + + Font st&yle + 字体风格(&Y) + + + &Size + 大小(&S) + + + Effects + 效果 + + + Stri&keout + 删除线(&K) + + + &Underline + 下划线(&U) + + + Sample + 实例 + + + Select Font + 选择字体 + + + Wr&iting System + 书写系统(&I) + + + + QFtp + + Host %1 found + 主机%1找到了 + + + Host found + 主机找到了 + + + Connected to host %1 + 连接到主机%1了 + + + Connected to host + 连接到主机了 + + + Connection to %1 closed + 到%1的连接关闭了 + + + Connection closed + 连接关闭了 + + + Host %1 not found + 主机%1没有找到 + + + Connection refused to host %1 + 连接被主机 %1 拒绝 + + + Connection timed out to host %1 + 主机%1连接超时 + + + Unknown error + 未知的错误 + + + Connecting to host failed: +%1 + 连接主机失败: +%1 + + + Login failed: +%1 + 登录失败: +%1 + + + Listing directory failed: +%1 + 列出目录失败: +%1 + + + Changing directory failed: +%1 + 改变目录失败: +%1 + + + Downloading file failed: +%1 + 下载文件失败: +%1 + + + Uploading file failed: +%1 + 上传文件失败: +%1 + + + Removing file failed: +%1 + 移除文件失败: +%1 + + + Creating directory failed: +%1 + 创建目录失败: +%1 + + + Removing directory failed: +%1 + 移除目录失败: +%1 + + + Not connected + 没有连接 + + + Connection refused for data connection + 因为数据连接而被拒绝连接 + + + + QHostInfo + + Unknown error + 未知的错误 + + + + QHostInfoAgent + + Host not found + 主机未找到 + + + Unknown address type + 未知的地址类型 + + + Unknown error + 未知的错误 + + + No host name given + 未给定主机名 + + + Invalid hostname + 无效主机名 + + + + QHttp + + Connection refused + 连接被拒绝 + + + Host %1 not found + 主机%1没有找到 + + + Wrong content length + 错误的内容长度 + + + HTTP request failed + HTTP请求失败 + + + Host %1 found + 主机%1找到了 + + + Host found + 主机找到了 + + + Connected to host %1 + 连接到%1主机了 + + + Connected to host + 连接到主机了 + + + Connection to %1 closed + 到%1的连接关闭了 + + + Connection closed + 连接关闭了 + + + Unknown error + 未知的错误 + + + Request aborted + 请求被放弃了 + + + No server set to connect to + 没有设置要连接的服务器 + + + Server closed connection unexpectedly + 服务器异常地关闭了连接 + + + Invalid HTTP response header + 无效的HTTP响应头 + + + Unknown authentication method + 未知鉴定方法 + + + Invalid HTTP chunked body + 无效的HTTP臃肿体 + + + Error writing response to device + 向设备中进行写回复时发生错误 + + + Proxy authentication required + 代理需要认证 + + + Authentication required + 需要认证 + + + Proxy requires authentication + 代理需要验证 + + + Host requires authentication + 主机需要验证 + + + Data corrupted + 数据错误 + + + SSL handshake failed + SSL 握手失败 + + + Unknown protocol specified + 所指定的协议是未知的 + + + Connection refused (or timed out) + 连接被拒绝(或者超时) + + + HTTPS connection requested but SSL support not compiled in + HTTPS 连接需要 SSL,但它没有被编译进来 + + + + QHttpSocketEngine + + Did not receive HTTP response from proxy + 未收到代理的HTTP响应 + + + Error parsing authentication request from proxy + 解析代理的认证请求出错 + + + Authentication required + 需要认证 + + + Proxy denied connection + 代理拒绝连接 + + + Error communicating with HTTP proxy + 和HTTP代理通讯时发生错误 + + + Proxy server not found + 未找到代理服务器 + + + Proxy connection refused + 代理连接被拒绝 + + + Proxy server connection timed out + 代理服务器连接超时 + + + Proxy connection closed prematurely + 代理连接过早关闭 + + + + QIBaseDriver + + Error opening database + 打开数据库错误 + + + Could not start transaction + 不能开始事务 + + + Unable to commit transaction + 不能提交事务 + + + Unable to rollback transaction + 不能回滚事务 + + + + QIBaseResult + + Unable to create BLOB + 不能创建BLOB + + + Unable to write BLOB + 不能写入BLOB + + + Unable to open BLOB + 不能打开BLOB + + + Unable to read BLOB + 不能读取BLOB + + + Could not find array + 不能找到数组 + + + Could not get array data + 不能得到数组数据 + + + Could not get query info + 不能得到查询信息 + + + Could not start transaction + 不能开始事务 + + + Unable to commit transaction + 不能提交事务 + + + Could not allocate statement + 不能分配语句 + + + Could not prepare statement + 不能准备语句 + + + Could not describe input statement + 不能描述输入语句 + + + Could not describe statement + 不能描述语句 + + + Unable to close statement + 不能关闭语句 + + + Unable to execute query + 不能执行查询 + + + Could not fetch next item + 不能获取下一项 + + + Could not get statement info + 不能得到语句信息 + + + + QIODevice + + Permission denied + 权限被拒绝 + + + Too many open files + 太多打开的文件 + + + No such file or directory + 没有这个文件或者目录 + + + No space left on device + 设备上没有空间了 + + + Unknown error + 未知的错误 + + + + QInputContext + + XIM + XIM + + + FEP + FEP + + + XIM input method + XIM输入法 + + + Windows input method + Windows输入法 + + + Mac OS X input method + Mac OS X输入法 + + + S60 FEP input method + S60 FEP输入法 + + + + QInputDialog + + Enter a value: + 输入一个值: + + + + QLibrary + + Could not mmap '%1': %2 + 不能映射”%1“:%2 + + + Plugin verification data mismatch in '%1' + “%1“中的插件验证数据不匹配 + + + Could not unmap '%1': %2 + 不能取消映射“%1“:%2 + + + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] + 插件“%1”使用了不兼容的Qt库。(%2.%3.%4) [%5] + + + The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" + 插件“%1“使用了不兼容的Qt库。期待的构建键是“%2“,得到的却是”%3“ + + + Unknown error + 未知的错误 + + + The shared library was not found. + 共享库没有被找到。 + + + The file '%1' is not a valid Qt plugin. + 文件“%1“不是有效的Qt插件。 + + + The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) + 插件“%1“使用了不兼容的Qt库。(不能混合使用库的调试版本和发布版本。) + + + Cannot load library %1: %2 + 无法加载库%1:%2 + + + Cannot unload library %1: %2 + 无法卸载库%1:%2 + + + Cannot resolve symbol "%1" in %2: %3 + 无法解析%2中的符号“%2”:%3 + + + + QLineEdit + + Select All + 选择全部 + + + &Undo + 撤消(&U) + + + &Redo + 恢复(&R) + + + Cu&t + 剪切(&T) + + + &Copy + 复制(&C) + + + &Paste + 粘贴(&P) + + + Delete + 删除 + + + + QLocalServer + + %1: Name error + %1: 名称错误 + + + %1: Permission denied + %1:权限被拒绝 + + + %1: Address in use + %1:地址正在被使用 + + + %1: Unknown error %2 + %1:未知错误 %2 + + + + QLocalSocket + + %1: Connection refused + %1:连接被拒绝 + + + %1: Remote closed + %1:远程已关闭 + + + %1: Invalid name + %1:无效名称 + + + %1: Socket access error + %1:套接字访问错误 + + + %1: Socket resource error + %1:套接字资源错误 + + + %1: Socket operation timed out + %1:套接字操作超时 + + + %1: Datagram too large + %1:数据报太大 + + + %1: Connection error + %1:连接错误 + + + %1: The socket operation is not supported + %1:套接字操作不被支持 + + + %1: Unknown error + %1:未知错误 + + + %1: Unknown error %2 + %1:未知错误 %2 + + + + QMYSQLDriver + + Unable to open database ' + 不能打开数据库 + + + Unable to connect + 不能连接 + + + Unable to begin transaction + 不能开始事务 + + + Unable to commit transaction + 不能提交事务 + + + Unable to rollback transaction + 不能回滚事务 + + + + QMYSQLResult + + Unable to fetch data + 不能获取数据 + + + Unable to execute query + 不能执行查询 + + + Unable to store result + 不能存储结果 + + + Unable to prepare statement + 不能准备语句 + + + Unable to reset statement + 不能重置语句 + + + Unable to bind value + 不能绑定值 + + + Unable to execute statement + 不能执行语句 + + + Unable to bind outvalues + 不能绑定外值 + + + Unable to store statement results + 不能存储语句结果 + + + Unable to execute next query + 不能执行下一个查询 + + + Unable to store next result + 不能存储下一个结果 + + + + QMdiArea + + (Untitled) + (未命名的) + + + + QMdiSubWindow + + %1 - [%2] + %1 - [%2] + + + Close + 关闭 + + + Minimize + 最小化 + + + Restore Down + 向下恢复 + + + &Restore + 恢复(&R) + + + &Move + 移动(&M) + + + &Size + 大小(&S) + + + Mi&nimize + 最小化(&N) + + + Ma&ximize + 最大化(&X) + + + Stay on &Top + 总在最前(&T) + + + &Close + 关闭(&C) + + + Maximize + 最大化 + + + Unshade + 取消遮蔽 + + + Shade + 遮蔽 + + + Restore + 恢复 + + + Help + 帮助 + + + Menu + 菜单 + + + - [%1] + - [%1] + + + + QMenu + + Close + 关闭 + + + Open + 打开 + + + Execute + 执行 + + + + QMenuBar + + Actions + 操作 + + + + QMessageBox + + OK + 确定 + + + <h3>About Qt</h3><p>This program uses Qt version %1.</p> + <h3>关于Qt</h3><p>此程序使用Qt版本%1。</p> + + + <p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p><p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://qt.nokia.com/">qt.nokia.com</a> for more information.</p> + <p>Qt是一个C++工具箱,用于跨平台应用程序开发。</p><p>Qt具有单一源跨可移植性,可跨越MS&nbsp;Windows、Mac&nbsp;OS&nbsp;X、Linux和所有主要的商业Unix类平台进行移植。Qt还适用于嵌入式设备,如Qt for Embedded Linux和Qt for Windows CE。</p><p>Qt有三种不同许可方式,以满足各种用户需求。</p><p>假如您要开发专利/商业软件,但不希望与第三方共享任何源代码,或者无法符合GNU LGPL版本2.1或GNU GPL版本3.0的条款,则按照我们的商业许可证协议授权的Qt非常适用。</p><p>假如您能够符合GNU LGPL版本2.1的条款和条件,则按照GNU LGPL版本2.1授权的Qt非常适合开发Qt应用程序(专有或开放源码)。</p><p>假如在开发Qt应用程序过程中,您希望这类应用程序能与遵循GNU GPL版本3.0的软件合用,或者您愿意符合GNU GPL版本3.0条款,则按照GNU通用公共许可证版本3.0授权的Qt非常适用。</p><p>请参阅<a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a>了解Qt授权概况。</p><p>版权所有 (C) 2010 诺基亚公司和/或附属公司。</p><p>Qt是一款诺基亚产品。请参阅<a href="http://qt.nokia.com/">qt.nokia.com</a>了解详情。</p> + + + About Qt + 关于Qt + + + Help + 帮助 + + + Show Details... + 显示细节…… + + + Hide Details... + 隐藏细节…… + + + + QMultiInputContext + + Select IM + 选择输入法 + + + + QMultiInputContextPlugin + + Multiple input method switcher + 多输入法切换器 + + + Multiple input method switcher that uses the context menu of the text widgets + 使用文本窗口部件上下文菜单的多输入法切换器 + + + + QNativeSocketEngine + + The remote host closed the connection + 远端主机关闭了这个连接 + + + Network operation timed out + 网络操作超时 + + + Out of resources + 资源耗尽了 + + + Unsupported socket operation + 不被支持的套接字操作 + + + Protocol type not supported + 协议类型不被支持 + + + Invalid socket descriptor + 无效的套接字描述符 + + + Network unreachable + 网络不能访问 + + + Permission denied + 权限被拒绝 + + + Connection timed out + 连接超时 + + + Connection refused + 连接被拒绝 + + + The bound address is already in use + 要启用的地址已经被使用 + + + The address is not available + 这个地址不可用 + + + The address is protected + 这个地址被保护了 + + + Unable to send a message + 不能发送一个消息 + + + Unable to receive a message + 不能接收一个消息 + + + Unable to write + 不能写入 + + + Network error + 网络错误 + + + Another socket is already listening on the same port + 另一个套接字已经正在监听同一端口 + + + Unable to initialize non-blocking socket + 不能初始化非阻塞套接字 + + + Unable to initialize broadcast socket + 不能初始化广播套接字 + + + Attempt to use IPv6 socket on a platform with no IPv6 support + 试图在不支持IPv6支持的平台上使用IPv6套接字 + + + Host unreachable + 主机不能访问 + + + Datagram was too large to send + 不能发送过大的数据报 + + + Operation on non-socket + 对非套接字操作 + + + Unknown error + 未知的错误 + + + The proxy type is invalid for this operation + 对于这个操作代理类型是无效的。 + + + + QNetworkAccessCacheBackend + + Error opening %1 + 打开%1发生错误 + + + + QNetworkAccessDebugPipeBackend + + Write error writing to %1: %2 + 写入%1时出错:%2 + + + + QNetworkAccessFileBackend + + Request for opening non-local file %1 + 正在打开非本地文件 %1 的请求 + + + Error opening %1: %2 + 打开 %1 错误:%2 + + + Write error writing to %1: %2 + 写入 %1 错误:%2 + + + Cannot open %1: Path is a directory + 无法打开 %1:路径是一个目录 + + + Read error reading from %1: %2 + 读取 %1 错误:%2 + + + + QNetworkAccessFtpBackend + + No suitable proxy found + 未找到合适的代理 + + + Cannot open %1: is a directory + 无法读取 %1:是一个目录 + + + Logging in to %1 failed: authentication required + 登入 %1 失败:需要验证 + + + Error while downloading %1: %2 + 下载 %1 时错误:%2 + + + Error while uploading %1: %2 + 上载 %1 时错误:%2 + + + + QNetworkAccessHttpBackend + + No suitable proxy found + 未找到合适的代理 + + + + QNetworkReply + + Error downloading %1 - server replied: %2 + 下载 %1 错误 - 服务器回复:%2 + + + Protocol "%1" is unknown + 协议“%1”是未知的 + + + + QNetworkReplyImpl + + Operation canceled + 操作被取消 + + + + QOCIDriver + + Unable to logon + 不能登录 + + + Unable to initialize + QOCIDriver + 不能初始化 + + + Unable to begin transaction + 不能开始事务 + + + Unable to commit transaction + 不能提交事务 + + + Unable to rollback transaction + 不能回滚事务 + + + + QOCIResult + + Unable to bind column for batch execute + 不能绑定批处理执行的列 + + + Unable to execute batch statement + 不能执行批处理语句 + + + Unable to goto next + 不能进入下一个 + + + Unable to alloc statement + 不能分配语句 + + + Unable to prepare statement + 不能准备语句 + + + Unable to get statement type + + + + Unable to bind value + 不能绑定值 + + + Unable to execute statement + 不能执行语句 + + + + QODBCDriver + + Unable to connect + 不能连接 + + + Unable to disable autocommit + 不能禁止自动提交 + + + Unable to commit transaction + 不能提交事务 + + + Unable to rollback transaction + 不能回滚事务 + + + Unable to enable autocommit + 不能打开自动提交 + + + Unable to connect - Driver doesn't support all functionality required + + + + + QODBCResult + + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration + QODBCResult::reset: 不能把“SQL_CURSOR_STATIC”设置为语句属性。请检查你的ODBC驱动程序设置。 + + + Unable to execute statement + 不能执行语句 + + + Unable to fetch next + 不能获取下一个 + + + Unable to prepare statement + 不能准备语句 + + + Unable to bind variable + 不能帮定变量 + + + Unable to fetch last + 不能获取最后一个 + + + Unable to fetch + 不能获取 + + + Unable to fetch first + 不能获取第一个 + + + Unable to fetch previous + 不能获取上一个 + + + + QObject + + Invalid hostname + 无效主机名 + + + Operation not supported on %1 + 在 %1 上不被支持的操作 + + + Invalid URI: %1 + 无效的 URI:%1 + + + Socket error on %1: %2 + %1 上的套接字错误:%2 + + + Remote host closed the connection prematurely on %1 + 远程主机过早地关闭了在 %1 上的这个连接 + + + No host name given + 未指定主机名 + + + + QPPDOptionsModel + + Name + 名称 + + + Value + + + + + QPSQLDriver + + Unable to connect + 不能连接 + + + Could not begin transaction + 不能开始事务 + + + Could not commit transaction + 不能提交事务 + + + Could not rollback transaction + 不能回滚事务 + + + Unable to subscribe + 不能订阅 + + + Unable to unsubscribe + 不能取消订阅 + + + + QPSQLResult + + Unable to create query + 不能创建查询 + + + Unable to prepare statement + 不能准备语句 + + + + QPageSetupWidget + + Centimeters (cm) + 厘米 (cm) + + + Millimeters (mm) + 毫米 (mm) + + + Inches (in) + 英寸 (in) + + + Points (pt) + 点 (pt) + + + Form + 窗体 + + + Paper + 纸张 + + + Page size: + 纸张大小: + + + Width: + 宽度: + + + Height: + 高度: + + + Paper source: + 纸张源: + + + Orientation + 方向 + + + Portrait + 纵向 + + + Landscape + 横向 + + + Reverse landscape + 反向横向 + + + Reverse portrait + 反向纵向 + + + Margins + 边距 + + + top margin + 上边距 + + + left margin + 左边距 + + + right margin + 右边距 + + + bottom margin + 下边距 + + + + QPluginLoader + + Unknown error + 未知的错误 + + + The plugin was not loaded. + 插件没有被载入。 + + + + QPrintDialog + + locally connected + 本地已经连接的 + + + Aliases: %1 + 别名:%1 + + + unknown + 未知的 + + + OK + 确定 + + + Print all + 打印全部 + + + Print range + 打印范围 + + + A0 (841 x 1189 mm) + A0 (841 x 1189 毫米) + + + A1 (594 x 841 mm) + A1 (594 x 841 毫米) + + + A2 (420 x 594 mm) + A2 (420 x 594 毫米) + + + A3 (297 x 420 mm) + A3 (297 x 420 毫米) + + + A5 (148 x 210 mm) + A5 (148 x 210 毫米) + + + A6 (105 x 148 mm) + A6 (105 x 148 毫米) + + + A7 (74 x 105 mm) + A7 (74 x 105 毫米) + + + A8 (52 x 74 mm) + A8 (52 x 74 毫米) + + + A9 (37 x 52 mm) + A9 (37 x 52 毫米) + + + B0 (1000 x 1414 mm) + B0 (1000 x 1414 毫米) + + + B1 (707 x 1000 mm) + B1 (707 x 1000 毫米) + + + B2 (500 x 707 mm) + B2 (500 x 707 毫米) + + + B3 (353 x 500 mm) + B3 (353 x 500 毫米) + + + B4 (250 x 353 mm) + B4 (250 x 353 毫米) + + + B6 (125 x 176 mm) + B6 (125 x 176 毫米) + + + B7 (88 x 125 mm) + B7 (88 x 125 毫米) + + + B8 (62 x 88 mm) + B8 (62 x 88 毫米) + + + B9 (44 x 62 mm) + B9 (44 x 62 毫米) + + + B10 (31 x 44 mm) + B10 (31 x 44 毫米) + + + C5E (163 x 229 mm) + C5E (163 x 229 毫米) + + + DLE (110 x 220 mm) + DLE (110 x 220 毫米) + + + Folio (210 x 330 mm) + Folio (210 x 330 毫米) + + + Ledger (432 x 279 mm) + Ledger (432 x 279 毫米) + + + Tabloid (279 x 432 mm) + Tabloid (279 x 432 毫米) + + + US Common #10 Envelope (105 x 241 mm) + 美国普通10号信封 (105 x 241 毫米) + + + A4 (210 x 297 mm, 8.26 x 11.7 inches) + A4 (210 x 297 毫米,8.26 x 11.7 英寸) + + + B5 (176 x 250 mm, 6.93 x 9.84 inches) + B5 (176 x 250 毫米,6.93 x 9.84 英寸) + + + Executive (7.5 x 10 inches, 191 x 254 mm) + Executive (7.5 x 10 英寸,191 x 254 毫米) + + + Legal (8.5 x 14 inches, 216 x 356 mm) + Legal (8.5 x 14 英寸,216 x 356 毫米) + + + Letter (8.5 x 11 inches, 216 x 279 mm) + Letter (8.5 x 11 英寸,216 x 279 毫米) + + + Print selection + 打印选择 + + + Print + 打印 + + + Print To File ... + 打印到文件…… + + + File %1 is not writable. +Please choose a different file name. + 文件%1不可写。 +请选择一个不同的文件名。 + + + %1 already exists. +Do you want to overwrite it? + %1已经存在。 +你想覆盖它么? + + + File exists + 文件存在 + + + <qt>Do you want to overwrite it?</qt> + <qt>你想覆盖它么?</qt> + + + %1 is a directory. +Please choose a different file name. + %1是目录。 +请选择一个不同的文件名。 + + + The 'From' value cannot be greater than the 'To' value. + “从”的数值不能大于“到”的数值。 + + + A0 + A0 + + + A1 + A1 + + + A2 + A2 + + + A3 + A3 + + + A4 + A4 + + + A5 + A5 + + + A6 + A6 + + + A7 + A7 + + + A8 + A8 + + + A9 + A9 + + + B0 + B0 + + + B1 + B1 + + + B2 + B2 + + + B3 + B3 + + + B4 + B4 + + + B5 + B5 + + + B6 + B6 + + + B7 + B7 + + + B8 + B8 + + + B9 + B9 + + + B10 + B10 + + + C5E + C5E + + + DLE + DLE + + + Executive + 决策文书 + + + Folio + 对开纸 + + + Ledger + 帐页 + + + Legal + 法律文书 + + + Letter + 信纸 + + + Tabloid + 小型报纸 + + + US Common #10 Envelope + 美国普通10号信封 + + + Custom + 自定义 + + + &Options >> + 选项(&O) >> + + + &Options << + 选项(&O) << + + + Print to File (PDF) + 打印到文件(PDF) + + + Print to File (Postscript) + 打印到文件(Postscript) + + + Local file + 本地文件 + + + Write %1 file + 写入 %1 文件 + + + &Print + 打印(&P) + + + + QPrintPreviewDialog + + %1% + %1% + + + Print Preview + 打印预览 + + + Next page + 下一页 + + + Previous page + 上一页 + + + First page + 第一页 + + + Last page + 最后一页 + + + Fit width + 适应宽度 + + + Fit page + 适应页面 + + + Zoom in + 放大 + + + Zoom out + 缩小 + + + Portrait + 纵向 + + + Landscape + 横向 + + + Show single page + 显示单页 + + + Show facing pages + 显示当前页 + + + Show overview of all pages + 显示所有页的概览 + + + Print + 打印 + + + Page setup + 打印设置 + + + Close + 关闭 + + + Export to PDF + 导出为PDF + + + Export to PostScript + 导出为PostScript + + + Page Setup + 页面设置 + + + + QPrintPropertiesWidget + + Form + 窗体 + + + Page + + + + Advanced + 高级 + + + + QPrintSettingsOutput + + Form + 窗体 + + + Copies + 拷贝 + + + Print range + 打印范围 + + + Print all + 打印全部 + + + Pages from + 页数从 + + + to + + + + Selection + 选择 + + + Output Settings + 输出设置 + + + Copies: + 备份: + + + Collate + 校对 + + + Reverse + 反向 + + + Options + 选项 + + + Color Mode + 彩色模式 + + + Color + 彩色 + + + Grayscale + 灰度 + + + Duplex Printing + 两部分打印 + + + None + + + + Long side + 长侧 + + + Short side + 短侧 + + + + QPrintWidget + + Form + 窗体 + + + Printer + 打印机 + + + &Name: + 名称(&N): + + + P&roperties + 属性(&R) + + + Location: + 位置: + + + Preview + 预览 + + + Type: + 类型: + + + Output &file: + 输出文件(&F): + + + ... + ... + + + + QProcess + + Could not open input redirection for reading + 无法打开用于读取的输入重定向 + + + Could not open output redirection for writing + 无法打开用于写入的输出重定向 + + + Resource error (fork failure): %1 + 资源错误(fork失败):%1 + + + Process operation timed out + 进程处理超时 + + + Error reading from process + 从进程中读取时发生错误 + + + Error writing to process + 向进程写入时发生错误 + + + Process crashed + 进程已崩溃 + + + No program defined + 未定义程序 + + + Process failed to start: %1 + 过程无法启动:%1 + + + + QProgressDialog + + Cancel + 撤消 + + + + QPushButton + + Open + 打开 + + + + QRadioButton + + Check + 选中 + + + + QRegExp + + no error occurred + 没有错误发生 + + + disabled feature used + 使用了失效的特效 + + + bad char class syntax + 错误的字符类语法 + + + bad lookahead syntax + 错误的预测语法 + + + bad repetition syntax + 错误的重复语法 + + + invalid octal value + 无效的八进制数值 + + + missing left delim + 找不到左分隔符 + + + unexpected end + 意外的终止 + + + met internal limit + 遇到内部限制 + + + invalid interval + 无效时间间隔 + + + invalid category + 无效类别 + + + + QSQLite2Driver + + Error opening database + 打开数据库时出错 + + + Unable to begin transaction + 不能开始事务 + + + Unable to commit transaction + 不能提交事务 + + + Unable to rollback transaction + 不能回滚事务 + + + + QSQLite2Result + + Unable to fetch results + 不能获取结果 + + + Unable to execute statement + 不能执行语句 + + + + QSQLiteDriver + + Error opening database + 打开数据库错误 + + + Error closing database + 关闭数据库错误 + + + Unable to begin transaction + 不能开始事务 + + + Unable to commit transaction + 不能提交事务 + + + Unable to rollback transaction + 不能回滚事务 + + + + QSQLiteResult + + Unable to fetch row + 不能获取行 + + + Unable to execute statement + 不能执行语句 + + + Unable to reset statement + 不能重置语句 + + + Unable to bind parameters + 不能绑定参数 + + + Parameter count mismatch + 参数数量不匹配 + + + No query + 没有查询 + + + + QScriptBreakpointsModel + + ID + ID + + + Location + 位置 + + + Condition + 条件 + + + Ignore-count + 忽略计数 + + + Single-shot + 单发 + + + Hit-count + 点击量 + + + + QScriptBreakpointsWidget + + New + 新建 + + + Delete + 删除 + + + + QScriptDebugger + + Go to Line + 转至行 + + + Line: + 行: + + + Interrupt + 中断 + + + Shift+F5 + Shift+F5 + + + Continue + 继续 + + + F5 + F5 + + + Step Into + 进入 + + + F11 + F11 + + + Step Over + 越过 + + + F10 + F10 + + + Step Out + 跳出 + + + Shift+F11 + Shift+F11 + + + Run to Cursor + 运行到光标 + + + Ctrl+F10 + Ctrl+F10 + + + Run to New Script + 运行到新脚本 + + + Toggle Breakpoint + 切换断点 + + + F9 + F9 + + + Clear Debug Output + 清除调试输出 + + + Clear Error Log + 清除错误日志 + + + Clear Console + 清除控制台 + + + &Find in Script... + 在脚本中查找(&F)... + + + Ctrl+F + Ctrl+F + + + Find &Next + 查找下一个(&N) + + + F3 + F3 + + + Find &Previous + 查找上一个(&P) + + + Shift+F3 + Shift+F3 + + + Ctrl+G + Ctrl+G + + + Debug + 调试 + + + + QScriptDebuggerCodeFinderWidget + + Close + 关闭 + + + Previous + 上一个 + + + Next + 下一个 + + + Case Sensitive + 区分大小写 + + + Whole words + 整个词 + + + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;Search wrapped + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;搜索已完成 + + + + QScriptDebuggerLocalsModel + + Name + 名称 + + + Value + + + + + QScriptDebuggerStackModel + + Level + 级别 + + + Name + 名称 + + + Location + 位置 + + + + QScriptEdit + + Toggle Breakpoint + 切换断点 + + + Disable Breakpoint + 禁用断点 + + + Enable Breakpoint + 启用断点 + + + Breakpoint Condition: + 断点条件: + + + + QScriptEngineDebugger + + Loaded Scripts + 已加载的脚本 + + + Breakpoints + 断点 + + + Stack + 堆栈 + + + Locals + 区域设置 + + + Console + 控制台 + + + Debug Output + 调试输出 + + + Error Log + 错误日志 + + + Search + 搜索 + + + View + 查看 + + + Qt Script Debugger + Qt脚本调试器 + + + + QScriptNewBreakpointWidget + + Close + 关闭 + + + + QScrollBar + + Scroll here + 滚动到这里 + + + Left edge + 左边缘 + + + Top + 顶部 + + + Right edge + 右边缘 + + + Bottom + 底部 + + + Page left + 左一页 + + + Page up + 上一页 + + + Page right + 右一页 + + + Page down + 下一页 + + + Scroll left + 向左滚动 + + + Scroll up + 向上滚动 + + + Scroll right + 向右滚动 + + + Scroll down + 向下滚动 + + + Line up + 向上排列 + + + Position + 位置 + + + Line down + 向下排列 + + + + QSharedMemory + + %1: create size is less then 0 + %1:创建的大小小于 0 + + + %1: unable to lock + %1:无法锁定 + + + %1: unable to unlock + %1:无法取消锁定 + + + %1: permission denied + %1:权限被拒绝 + + + %1: already exists + %1:已经存在 + + + %1: doesn't exists + %1:不存在 + + + %1: out of resources + %1:资源耗尽了 + + + %1: unknown error %2 + %1:未知错误 %2 + + + %1: key is empty + %1:键是空的 + + + %1: ftok failed + %1:ftok 失败 + + + %1: unable to make key + %1:不能制造键 + + + %1: doesn't exist + %1:不存在 + + + %1: UNIX key file doesn't exist + %1:UNIX密钥文件不存在 + + + %1: system-imposed size restrictions + %1:系统预设大小限制 + + + %1: not attached + %1:没有附加 + + + %1: invalid size + %1:无效大小 + + + %1: key error + %1: 键错误 + + + %1: size query failed + %1:大小查询失败 + + + %1: unable to set key on lock + %1:无法设置锁定的键 + + + + QShortcut + + Space + 空格 + + + Esc + Esc + + + Tab + Tab + + + Backtab + Backtab + + + Backspace + Backspace + + + Return + Return + + + Enter + Enter + + + Ins + Ins + + + Del + Del + + + Pause + Pause + + + Print + Print + + + SysReq + SysReq + + + Home + Home + + + End + End + + + Left + Left + + + Up + Up + + + Right + Right + + + Down + Down + + + PgUp + PgUp + + + PgDown + PgDown + + + CapsLock + CapsLock + + + NumLock + NumLock + + + ScrollLock + ScrollLock + + + Menu + Menu + + + Help + Help + + + Back + 后退 + + + Forward + 前进 + + + Stop + 停止 + + + Refresh + 刷新 + + + Volume Down + 调小音量 + + + Volume Mute + 静音 + + + Volume Up + 调大音量 + + + Bass Boost + 低音增强 + + + Bass Up + 调大低音 + + + Bass Down + 调小低音 + + + Treble Up + 调大高音 + + + Treble Down + 调小高音 + + + Media Play + 多媒体播放 + + + Media Stop + 多媒体停止 + + + Media Previous + 上一个多媒体 + + + Media Next + 下一个多媒体 + + + Media Record + 多媒体记录 + + + Favorites + 最喜爱的 + + + Search + 搜索 + + + Standby + 等待 + + + Open URL + 打开URL + + + Launch Mail + 启动邮件 + + + Launch Media + 启动多媒体 + + + Launch (0) + 启动 (0) + + + Launch (1) + 启动 (1) + + + Launch (2) + 启动 (2) + + + Launch (3) + 启动 (3) + + + Launch (4) + 启动 (4) + + + Launch (5) + 启动 (5) + + + Launch (6) + 启动 (6) + + + Launch (7) + 启动 (7) + + + Launch (8) + 启动 (8) + + + Launch (9) + 启动 (9) + + + Launch (A) + 启动 (A) + + + Launch (B) + 启动 (B) + + + Launch (C) + 启动 (C) + + + Launch (D) + 启动 (D) + + + Launch (E) + 启动 (E) + + + Launch (F) + 启动 (F) + + + Monitor Brightness Up + 提高监视器亮度 + + + Monitor Brightness Down + 降低监视器亮度 + + + Keyboard Light On/Off + 键盘灯打开/关闭 + + + Keyboard Brightness Up + 提高键盘亮度 + + + Keyboard Brightness Down + 降低键盘亮度 + + + Power Off + 关机 + + + Wake Up + 唤醒 + + + Eject + 弹出 + + + Screensaver + 屏幕保护程序 + + + WWW + WWW + + + Sleep + 睡眠 + + + LightBulb + 灯泡 + + + Shop + 商店 + + + History + 历史记录 + + + Add Favorite + 添加收藏夹 + + + Hot Links + 热点链接 + + + Adjust Brightness + 调节亮度 + + + Finance + 财务 + + + Community + 社区 + + + Audio Rewind + 音频倒带 + + + Back Forward + 后倒 + + + Application Left + 应用程序偏左 + + + Application Right + 应用程序偏右 + + + Book + 书籍 + + + CD + CD + + + Calculator + 计算器 + + + Clear + 清除 + + + Clear Grab + 清除抓取 + + + Close + 关闭 + + + Copy + 复制 + + + Cut + 剪切 + + + Display + 显示 + + + DOS + DOS + + + Documents + 文档 + + + Spreadsheet + 电子表格 + + + Browser + 浏览器 + + + Game + 游戏 + + + Go + 转至 + + + iTouch + iTouch + + + Logoff + 注销 + + + Market + 市场 + + + Meeting + 会议 + + + Keyboard Menu + 键盘功能表 + + + Menu PB + 功能表PB + + + My Sites + 我的站点 + + + News + 新闻 + + + Home Office + 家庭办公 + + + Option + 选项 + + + Paste + 粘贴 + + + Phone + 手机 + + + Reply + 回复 + + + Reload + 重新加载 + + + Rotate Windows + 旋转视窗 + + + Rotation PB + 旋转PB + + + Rotation KB + 旋转KB + + + Save + 储存 + + + Send + 发送 + + + Spellchecker + 拼写检查程序 + + + Split Screen + 分屏 + + + Support + 支持 + + + Task Panel + 任务面板 + + + Terminal + 终端 + + + Tools + 工具 + + + Travel + 旅行 + + + Video + 视频 + + + Word Processor + 字处理器 + + + XFer + XFer + + + Zoom In + 放大 + + + Zoom Out + 缩小 + + + Away + 远离 + + + Messenger + ## + + + WebCam + WebCam + + + Mail Forward + 电子邮件转发 + + + Pictures + 图片 + + + Music + 音乐 + + + Battery + 电池 + + + Bluetooth + 蓝牙 + + + Wireless + 无线 + + + Ultra Wide Band + 超宽带 + + + Audio Forward + 音频前进 + + + Audio Repeat + 音频重复 + + + Audio Random Play + 音频随机播放 + + + Subtitle + 小标题 + + + Audio Cycle Track + 音频循环轨道 + + + Time + 时间 + + + View + 查看 + + + Top Menu + 顶端功能表 + + + Suspend + 挂起 + + + Hibernate + 休眠 + + + Print Screen + Print Screen + + + Page Up + Page Up + + + Page Down + Page Down + + + Caps Lock + Caps Lock + + + Num Lock + Num Lock + + + Number Lock + Number Lock + + + Scroll Lock + Scroll Lock + + + Insert + Insert + + + Delete + Delete + + + Escape + Escape + + + System Request + System Request + + + Select + 选择 + + + Yes + + + + No + + + + Context1 + 上下文1 + + + Context2 + 上下文2 + + + Context3 + 上下文3 + + + Context4 + 上下文4 + + + Call + 呼叫 + + + Hangup + 挂起 + + + Flip + 翻转 + + + Ctrl + Ctrl + + + Shift + Shift + + + Alt + Alt + + + Meta + Meta + + + + + + + + + F%1 + F%1 + + + Home Page + 主页 + + + + QSlider + + Page left + 左一页 + + + Page up + 上一页 + + + Position + 位置 + + + Page right + 右一页 + + + Page down + 下一页 + + + + QSocks5SocketEngine + + Connection to proxy refused + 代理拒绝连接 + + + Connection to proxy closed prematurely + 代理连接过早关闭 + + + Proxy host not found + 代理主机未找到 + + + Connection to proxy timed out + 代理连接超时 + + + Proxy authentication failed + 代理认证失败 + + + Proxy authentication failed: %1 + 代理认证失败: %1 + + + SOCKS version 5 protocol error + SOCKS版本5协议错误 + + + General SOCKSv5 server failure + 常规服务器失败 + + + Connection not allowed by SOCKSv5 server + 连接不被SOCKSv5服务器允许 + + + TTL expired + TTL已过期 + + + SOCKSv5 command not supported + 不支持的SOCKSv5命令 + + + Address type not supported + 不支持的地址类型 + + + Unknown SOCKSv5 proxy error code 0x%1 + 未知SOCKSv5代理,错误代码 0x%1 + + + Network operation timed out + 网络操作超时 + + + + QSoftKeyManager + + Ok + 确定 + + + Select + 选择 + + + Done + 完成 + + + Options + 选项 + + + Cancel + 取消 + + + Exit + 退出 + + + + QSpinBox + + More + 更多 + + + Less + 更少 + + + + QSql + + Delete + 删除 + + + Delete this record? + 删除这条记录? + + + Yes + + + + No + + + + Insert + 插入 + + + Update + 更新 + + + Save edits? + 保存编辑? + + + Cancel + 取消 + + + Confirm + 确认 + + + Cancel your edits? + 取消您的编辑? + + + + QSslSocket + + Unable to write data: %1 + 不能写入数据:%1 + + + Unable to decrypt data: %1 + 无法解密数据:%1 + + + Error while reading: %1 + 读取时错误:%1 + + + Error during SSL handshake: %1 + SSL握手错误:%1 + + + Error creating SSL context (%1) + 创建SSL上下文错误(%1) + + + Invalid or empty cipher list (%1) + 无效或者空白的密码列表(%1) + + + Private key does not certify public key, %1 + 私钥不能证明公钥,%1 + + + Error creating SSL session, %1 + 创建SSL会话错误,%1 + + + Error creating SSL session: %1 + 创建SSL会话错误:%1 + + + Cannot provide a certificate with no key, %1 + 不能提供没有键的证书,%1 + + + Error loading local certificate, %1 + 不能载入本地证书,%1 + + + Error loading private key, %1 + 不能载入私有键,%1 + + + No error + 无错误 + + + The issuer certificate could not be found + 找不到发行人证书 + + + The certificate signature could not be decrypted + 证书签名无法解密 + + + The public key in the certificate could not be read + 无法读取证书中的公钥 + + + The signature of the certificate is invalid + 证书签名无效 + + + The certificate is not yet valid + 证书不再失效 + + + The certificate has expired + 证书已过期 + + + The certificate's notBefore field contains an invalid time + 证书的notBefore字段包含无效时间 + + + The certificate's notAfter field contains an invalid time + 证书的notAfter字段包含无效时间 + + + The certificate is self-signed, and untrusted + 证书为自签名,因而不受信任 + + + The root certificate of the certificate chain is self-signed, and untrusted + 证书链的根证书为自签名,因而不受信任 + + + The issuer certificate of a locally looked up certificate could not be found + 无法找到在本地查找的证书的发行人证书 + + + No certificates could be verified + 无证书可验证 + + + One of the CA certificates is invalid + CA证书之一无效 + + + The basicConstraints path length parameter has been exceeded + 已超过basicConstraints路径长度参数 + + + The supplied certificate is unsuitable for this purpose + 提供的证书不适合此用途 + + + The root CA certificate is not trusted for this purpose + 此用途不信任根CA证书 + + + The root CA certificate is marked to reject the specified purpose + 已将根CA证书标记为拒绝用于指定用途 + + + The current candidate issuer certificate was rejected because its subject name did not match the issuer name of the current certificate + 当前候选发行人证书被拒绝,因其持有人姓名与当前证书的发行人姓名不匹配 + + + The current candidate issuer certificate was rejected because its issuer name and serial number was present and did not match the authority key identifier of the current certificate + 当前候选发行人证书被拒绝,因其发行人姓名和序列号虽存在,但与当前证书的权威密钥标识符不匹配 + + + The peer did not present any certificate + 对方没有提供任何证书 + + + The host name did not match any of the valid hosts for this certificate + 主机名与此证书的任何有效主机都不匹配 + + + Unknown error + 未知错误 + + + + QStateMachine + + Missing initial state in compound state '%1' + 复合状态“%1”缺少初始状态 + + + Missing default state in history state '%1' + 历史状态“%1”缺少预设状态 + + + No common ancestor for targets and source of transition from state '%1' + 从状态"%1"过渡,但源和目标无共同父辈 + + + Unknown error + 未知错误 + + + + QSystemSemaphore + + %1: does not exist + %1:不存在 + + + %1: out of resources + %1:资源耗尽了 + + + %1: permission denied + %1:权限被拒绝 + + + %1: already exists + %1:已经存在 + + + %1: unknown error %2 + %1:未知错误 %2 + + + + QTDSDriver + + Unable to open connection + 不能打开连接 + + + Unable to use database + 不能使用数据库 + + + + QTabBar + + Scroll Left + 向左滚动 + + + Scroll Right + 向右滚动 + + + + QTcpServer + + Operation on socket is not supported + socket操作不被支持 + + + + QTextControl + + &Undo + 撤消(&U) + + + &Redo + 恢复(&R) + + + Cu&t + 剪切(&T) + + + &Copy + 复制(&C) + + + Copy &Link Location + 复制链接位置(&L) + + + &Paste + 粘贴(&P) + + + Delete + 删除 + + + Select All + 选择全部 + + + + QToolButton + + Press + 按下 + + + Open + 打开 + + + + QUdpSocket + + This platform does not support IPv6 + 这个平台不支持IPv6 + + + + QUndoGroup + + Undo + 撤销 + + + Redo + 恢复 + + + + QUndoModel + + <empty> + <空白> + + + + QUndoStack + + Undo + 撤销 + + + Redo + 恢复 + + + + QUnicodeControlCharacterMenu + + LRM Left-to-right mark + LRM 从左到右标记 + + + RLM Right-to-left mark + RLM 从右向左标记 + + + ZWJ Zero width joiner + ZWJ 零宽度连接器 + + + ZWNJ Zero width non-joiner + ZWNJ 零宽度非连接器 + + + ZWSP Zero width space + ZWSP 零宽度空格 + + + LRE Start of left-to-right embedding + LRE 开始从左到右嵌入 + + + RLE Start of right-to-left embedding + RLE 开始从右向左嵌入 + + + LRO Start of left-to-right override + LRO 开始从左向右覆盖 + + + RLO Start of right-to-left override + RLO 开始从右向左覆盖 + + + PDF Pop directional formatting + PDF 弹出方向格式 + + + Insert Unicode control character + 插入Unicode控制字符 + + + + QWebFrame + + Request cancelled + 请求被取消了 + + + Request blocked + 请求被阻塞了 + + + Cannot show URL + 无法显示 URL + + + Frame load interrupted by policy change + 策略变化导致帧加载中断 + + + Cannot show mimetype + 无法显示 MIMETYPE + + + File does not exist + 文件不存在 + + + + QWebPage + + Submit + default label for Submit buttons in forms on web pages + + + + Submit + Submit (input element) alt text for <input> elements with no alt, title, or value + + + + Reset + default label for Reset buttons in forms on web pages + 重置 + + + Choose File + title for file button used in HTML forms + 选择文件 + + + No file selected + text to display in file button used in HTML forms when no file is selected + 没有文件被选择 + + + Open in New Window + Open in New Window context menu item + 在新窗口中打开 + + + Save Link... + Download Linked File context menu item + 保存链接... + + + Copy Link + Copy Link context menu item + 复制链接 + + + Open Image + Open Image in New Window context menu item + 打开图片 + + + Save Image + Download Image context menu item + 保存图片 + + + Copy Image + Copy Link context menu item + 复制图片 + + + Open Frame + Open Frame in New Window context menu item + 打开框架 + + + Copy + Copy context menu item + 复制 + + + Go Back + Back context menu item + 后退 + + + Go Forward + Forward context menu item + 前进 + + + Stop + Stop context menu item + + + + Reload + Reload context menu item + 重新载入 + + + Cut + Cut context menu item + 剪切 + + + Paste + Paste context menu item + 粘贴 + + + No Guesses Found + No Guesses Found context menu item + 没有找到猜测 + + + Ignore + Ignore Spelling context menu item + 忽略 + + + Add To Dictionary + Learn Spelling context menu item + 添加到字典 + + + Search The Web + Search The Web context menu item + 搜索网页 + + + Look Up In Dictionary + Look Up in Dictionary context menu item + 在字典中查找 + + + Open Link + Open Link context menu item + 打开链接 + + + Ignore + Ignore Grammar context menu item + 忽略 + + + Spelling + Spelling and Grammar context sub-menu item + + + + Show Spelling and Grammar + menu item title + + + + Hide Spelling and Grammar + menu item title + 隐藏拼写和语法 + + + Check Spelling + Check spelling context menu item + 检查拼写 + + + Check Spelling While Typing + Check spelling while typing context menu item + 在输入时检查拼写 + + + Check Grammar With Spelling + Check grammar with spelling context menu item + 检查语法和拼写 + + + Fonts + Font context sub-menu item + 字体 + + + Bold + Bold context menu item + 粗体 + + + Italic + Italic context menu item + 意大利体 + + + Underline + Underline context menu item + + + + Outline + Outline context menu item + 轮廓 + + + Direction + Writing direction context sub-menu item + 方向 + + + Text Direction + Text direction context sub-menu item + + + + Default + Default writing direction context menu item + 默认 + + + Left to Right + Left to Right context menu item + 左到右 + + + Right to Left + Right to Left context menu item + 右到左 + + + Loading... + Media controller status message when the media is loading + 正在加载... + + + Live Broadcast + Media controller status message when watching a live broadcast + 手机广播 + + + Audio Element + Media controller element + 音频元素 + + + Video Element + Media controller element + 视频元素 + + + Mute Button + Media controller element + 静音按钮 + + + Unmute Button + Media controller element + 取消静音按钮 + + + Play Button + Media controller element + 播放按钮 + + + Pause Button + Media controller element + 暂停按钮 + + + Slider + Media controller element + 滑块 + + + Slider Thumb + Media controller element + 滑块微缩图像 + + + Rewind Button + Media controller element + 倒带按钮 + + + Return to Real-time Button + Media controller element + 返回到实时按钮 + + + Elapsed Time + Media controller element + 耗时 + + + Remaining Time + Media controller element + 剩余时间 + + + Status Display + Media controller element + 状态显示 + + + Fullscreen Button + Media controller element + 全屏按钮 + + + Seek Forward Button + Media controller element + 向前寻找按钮 + + + Seek Back Button + Media controller element + 向后寻找按钮 + + + Audio element playback controls and status display + Media controller element + 音频元素播放控件和状态显示 + + + Video element playback controls and status display + Media controller element + 视频元素播放控件和状态显示 + + + Mute audio tracks + Media controller element + 静音音轨 + + + Unmute audio tracks + Media controller element + 取消静音音轨 + + + Begin playback + Media controller element + 开始播放 + + + Pause playback + Media controller element + 暂停播放 + + + Movie time scrubber + Media controller element + 影片时间刷新器 + + + Movie time scrubber thumb + Media controller element + 影片时间刷新器微缩图像 + + + Rewind movie + Media controller element + 影片倒带 + + + Return streaming movie to real-time + Media controller element + 将流式影片返回到实时 + + + Current movie time + Media controller element + 当前影片时间 + + + Remaining movie time + Media controller element + 影片剩余时间 + + + Current movie status + Media controller element + 当前影片状态 + + + Play movie in full-screen mode + Media controller element + 以全屏模式播放影片 + + + Seek quickly back + Media controller element + 快速向后寻找 + + + Seek quickly forward + Media controller element + 快速向前寻找 + + + Indefinite time + Media time description + 不定时间 + + + %1 days %2 hours %3 minutes %4 seconds + Media time description + %1天%2小时%3分%4秒 + + + %1 hours %2 minutes %3 seconds + Media time description + %1小时%2分%3秒 + + + %1 minutes %2 seconds + Media time description + %1分%2秒 + + + %1 seconds + Media time description + %1秒 + + + Inspect + Inspect Element context menu item + 检查 + + + No recent searches + Label for only item in menu that appears when clicking on the search field image, when no searches have been performed + 没有最近的搜索 + + + Recent searches + label for first item in the menu that appears when clicking on the search field image, used as embedded menu title + 最近的搜索 + + + Clear recent searches + menu item in Recent Searches menu that empties menu's contents + 清除最近的搜索 + + + Unknown + Unknown filesize FTP directory listing item + + + + Web Inspector - %2 + + + + %1 (%2x%3 pixels) + Title string for images + %1 (%2x%3 像素) + + + Bad HTTP request + 错误的 HTTP 请求 + + + This is a searchable index. Enter search keywords: + text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' + + + + Scroll here + 滚动到这里 + + + Left edge + 左边缘 + + + Top + + + + Right edge + 右边缘 + + + Bottom + 底部 + + + Page left + 左一页 + + + Page up + 上一页 + + + Page right + 右一页 + + + Page down + 下一页 + + + Scroll left + 向左滚动 + + + Scroll up + 向上滚动 + + + Scroll right + 向右滚动 + + + Scroll down + 向下滚动 + + + %n file(s) + number of chosen file + + %n 个文件 + + + + JavaScript Alert - %1 + JavaScript警告 - %1 + + + JavaScript Confirm - %1 + JavaScript确认 - %1 + + + JavaScript Prompt - %1 + JavaScript提示 - %1 + + + JavaScript Problem - %1 + JavaScript问题 - %1 + + + The script on this page appears to have a problem. Do you want to stop the script? + 此页上的脚本似乎有问题。是否停止脚本? + + + Move the cursor to the next character + 移动光标到下一个字符 + + + Move the cursor to the previous character + 移动光标到上一个字符 + + + Move the cursor to the next word + 移动光标到下一个单词 + + + Move the cursor to the previous word + 移动光标到上一个单词 + + + Move the cursor to the next line + 移动光标到下一行 + + + Move the cursor to the previous line + 移动光标到上一行 + + + Move the cursor to the start of the line + 移动光标到行首 + + + Move the cursor to the end of the line + 移动光标到行尾 + + + Move the cursor to the start of the block + 移动光标到块首 + + + Move the cursor to the end of the block + 移动光标到块尾 + + + Move the cursor to the start of the document + 移动光标到文件开头 + + + Move the cursor to the end of the document + 移动光标到文件末尾 + + + Select all + 全选 + + + Select to the next character + + + + Select to the previous character + + + + Select to the next word + + + + Select to the previous word + + + + Select to the next line + + + + Select to the previous line + + + + Select to the start of the line + + + + Select to the end of the line + + + + Select to the start of the block + + + + Select to the end of the block + + + + Select to the start of the document + + + + Select to the end of the document + + + + Delete to the start of the word + 删除到单词首 + + + Delete to the end of the word + 删除到单词尾 + + + Insert a new paragraph + 插入新段落 + + + Insert a new line + 插入新行 + + + Paste and Match Style + 粘贴和匹配样式 + + + Remove formatting + 删除格式设置 + + + Strikethrough + 删除线 + + + Subscript + 下标 + + + Superscript + 上标 + + + Insert Bulleted List + 插入项目符号列表 + + + Insert Numbered List + 插入编号列表 + + + Indent + 缩进 + + + Outdent + 凸出 + + + Center + 中心 + + + Justify + 调整 + + + Align Left + 左对齐 + + + Align Right + 右对齐 + + + + QWhatsThisAction + + What's This? + + + + + QWidget + + * + + + + + QWizard + + Cancel + + + + Help + + + + < &Back + + + + &Finish + + + + &Help + + + + Go Back + + + + Continue + + + + Commit + + + + Done + + + + &Next + + + + &Next > + + + + + QWorkspace + + &Restore + + + + &Move + + + + &Size + + + + Mi&nimize + + + + Ma&ximize + + + + &Close + + + + Stay on &Top + + + + Minimize + + + + Restore Down + + + + Close + + + + Sh&ade + + + + %1 - [%2] + + + + &Unshade + + + + + QXml + + no error occurred + + + + error triggered by consumer + + + + unexpected end of file + + + + more than one document type definition + + + + error occurred while parsing element + + + + tag mismatch + + + + error occurred while parsing content + + + + unexpected character + + + + invalid name for processing instruction + + + + version expected while reading the XML declaration + + + + wrong value for standalone declaration + + + + error occurred while parsing document type definition + + + + letter is expected + + + + error occurred while parsing comment + + + + error occurred while parsing reference + + + + internal general entity reference not allowed in DTD + + + + external parsed general entity reference not allowed in attribute value + + + + external parsed general entity reference not allowed in DTD + + + + unparsed entity reference in wrong context + + + + recursive entities + + + + error in the text declaration of an external entity + + + + encoding declaration or standalone declaration expected while reading the XML declaration + + + + standalone declaration expected while reading the XML declaration + + + + + QXmlPatternistCLI + + Warning in %1, at line %2, column %3: %4 + %1中出现警告,位于%2行,%3列:%4 + + + Warning in %1: %2 + %1中出现警告:%2 + + + Unknown location + 未知位置 + + + Error %1 in %2, at line %3, column %4: %5 + %2中存在错误%1,位于%3行,%4列:%5 + + + Error %1 in %2: %3 + %2中存在错误%1:%3 + + + + QXmlStream + + Extra content at end of document. + + + + Invalid entity value. + + + + Invalid XML character. + + + + Sequence ']]>' not allowed in content. + + + + Namespace prefix '%1' not declared + + + + Attribute redefined. + + + + Unexpected character '%1' in public id literal. + + + + Invalid XML version string. + + + + Unsupported XML version. + + + + %1 is an invalid encoding name. + + + + Encoding %1 is unsupported + + + + Standalone accepts only yes or no. + + + + Invalid attribute in XML declaration. + + + + Premature end of document. + + + + Invalid document. + + + + Expected + + + + , but got ' + + + + Unexpected ' + + + + Expected character data. + + + + Recursive entity detected. + + + + Start tag expected. + + + + XML declaration not at start of document. + + + + NDATA in parameter entity declaration. + + + + %1 is an invalid processing instruction name. + + + + Invalid processing instruction name. + + + + Illegal namespace declaration. + + + + Invalid XML name. + + + + Opening and ending tag mismatch. + + + + Reference to unparsed entity '%1'. + + + + Entity '%1' not declared. + + + + Reference to external entity '%1' in attribute value. + + + + Invalid character reference. + + + + Encountered incorrectly encoded content. + + + + The standalone pseudo attribute must appear after the encoding. + + + + %1 is an invalid PUBLIC identifier. + + + + + QtXmlPatterns + + At least one component must be present. + 至少有一个组件被呈现。 + + + %1 is not a valid value of type %2. + %1 不是类型为 %2 的有效值。 + + + When casting to %1 from %2, the source value cannot be %3. + 当从 %2 抛出到 %1 时,源值不能是 %3。 + + + Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values. + 有效的布尔值(Effective Boolean Value)不能被用于计算一个包含两个或者更多原子值的序列。 + + + The data of a processing instruction cannot contain the string %1 + 处理指令的数据不能包含字符串 %1 + + + %1 is an invalid %2 + %1 是一个无效的 %2。 + + + %1 is not a valid XML 1.0 character. + %1 不是一个有效的 XML 1.0 字符。 + + + %1 was called. + %1 被调用了。 + + + In the replacement string, %1 must be followed by at least one digit when not escaped. + 在这个替换字符串中,%1 在没有被转义的时候必须被至少一个数字跟随。 + + + In the replacement string, %1 can only be used to escape itself or %2, not %3 + 在这个替换字符串中,%1 只能被用于转义它本身或者 %2,而不是 %3 + + + %1 matches newline characters + %1 匹配了换行符 + + + Matches are case insensitive + 匹配是大小写不敏感的 + + + %1 is an invalid regular expression pattern: %2 + %1 是正则表达式中的一个无效模式:%2 + + + It will not be possible to retrieve %1. + 将不能获取 %1。 + + + The default collection is undefined + 默认收集(collection)是未定义的 + + + %1 cannot be retrieved + 无法获取 %1 + + + The item %1 did not match the required type %2. + 项 %1 和所需的类型 %2 不匹配。 + + + %1 is an unknown schema type. + %1 是一个未知的方案类型。 + + + A template with name %1 has already been declared. + + + + Only one %1 declaration can occur in the query prolog. + 只有一个 %1 的声明可以出现在查询序言中。 + + + The initialization of variable %1 depends on itself + 变量 %1 的初始化依赖于它本身 + + + The variable %1 is unused + 变量 %1 没有被使用 + + + Version %1 is not supported. The supported XQuery version is 1.0. + 不支持版本 %1。被支持的 XQuery 版本是 1.0。 + + + No function with signature %1 is available + 没有签名为 %1 的可用函数。 + + + It is not possible to redeclare prefix %1. + 不能重复声明前缀 %1。 + + + Prefix %1 is already declared in the prolog. + 前缀 %1 在序言中已经声明过了。 + + + The name of an option must have a prefix. There is no default namespace for options. + 一个选项的名称必须带有前缀。对于选项没有默认命名空间。 + + + The Schema Import feature is not supported, and therefore %1 declarations cannot occur. + 不支持方案导入(Schema Import)特性,并且因此 %1 声明不能出现。 + + + The target namespace of a %1 cannot be empty. + %1 的目标命名空间不能为空。 + + + The module import feature is not supported + 不支持模块导入特性 + + + The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2 + 用户在一个库模块中定义的函数的命名空间必须和这个模块的命名空间一致。也就是说,它应该是 %1,而不是 %2 + + + A function already exists with the signature %1. + 一个带有签名 %1 的函数已经存在。 + + + No external functions are supported. All supported functions can be used directly, without first declaring them as external + 不支持外部函数。所有支持的函数必须可以被直接使用,不能把它们声明为外部的 + + + The %1-axis is unsupported in XQuery + 这个 %1 轴在 XQuery 中是不被支持的。 + + + The namespace URI cannot be the empty string when binding to a prefix, %1. + 当这个命名空间 URI 被绑定到一个前缀 %1 时,它不能是空字符串。 + + + %1 is an invalid namespace URI. + %1 是一个无效的命名空间 URI。 + + + It is not possible to bind to the prefix %1 + 无法绑定到这个前缀 %1。 + + + Two namespace declaration attributes have the same name: %1. + 两个命名空间声明属性使用了相同的名称:%1。 + + + The namespace URI must be a constant and cannot use enclosed expressions. + 命名空间 URI 必须是一个常量并且不能使用封闭的表达式。 + + + %1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported. + %1 不是范围内属性声明。注意方案导入特性是不被支持的。 + + + empty + 空白 + + + zero or one + 零或者一 + + + exactly one + 确切地一 + + + one or more + 一或者更多 + + + zero or more + 零或者更多 + + + The focus is undefined. + 焦点未定义。 + + + An attribute by name %1 has already been created. + 一个名称为 %1 的属性已经被创建。 + + + Network timeout. + 网络超时。 + + + Element %1 can't be serialized because it appears outside the document element. + 元素 %1 不能被串行化,因为它出现在文档元素之外。 + + + Year %1 is invalid because it begins with %2. + %1 年是无效的,因为应该从 %2 开始。 + + + Day %1 is outside the range %2..%3. + %1 日是在 %2...%3 范围之外的。 + + + Month %1 is outside the range %2..%3. + %1 月是在 %2...%3 范围之外的。 + + + Overflow: Can't represent date %1. + 溢出:无法呈现数据 %1。 + + + Day %1 is invalid for month %2. + %1 日对于 %2 月是无效的。 + + + Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; + 时间 24:%1:%2.%3 是无效的。小时是 24,但是分钟、秒和毫秒不全为 0; + + + Time %1:%2:%3.%4 is invalid. + 时间 %1:%2:%3.%4 是无效的。 + + + Overflow: Date can't be represented. + 溢出:数据无法被呈现。 + + + At least one time component must appear after the %1-delimiter. + 至少一个时间组件必须出现在这个 %1 界限之后。 + + + Dividing a value of type %1 by %2 (not-a-number) is not allowed. + 一个类型为 %1 的值除以 %2(不是一个数值)是不允许的。 + + + Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed. + 一个类型为 %1 的值除以 %2 或者 %3(正负零)是不允许的。 + + + Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed. + 一个类型为 %1 的值乘以 %2 或者 %3(正负无穷)是不允许的。 + + + A value of type %1 cannot have an Effective Boolean Value. + 一个类型为 %1 的值不能是一个有效的布尔值(Effective Boolean Value)。 + + + Value %1 of type %2 exceeds maximum (%3). + 类型为 %2 的值 %1 超过了最大值(%3)。 + + + Value %1 of type %2 is below minimum (%3). + 类型为 %2 的值 %1 超过了最小值(%3)。 + + + A value of type %1 must contain an even number of digits. The value %2 does not. + 类型为 %1 的值必须包含偶数个数字。值 %2 不是这样的。 + + + %1 is not valid as a value of type %2. + %1 不是类型为 %2 的有效值。 + + + Operator %1 cannot be used on type %2. + 操作符 %1 不能被用于类型 %2。 + + + Operator %1 cannot be used on atomic values of type %2 and %3. + 操作符 %1 不能被用于类型为 %2 和 %3 的原子值。 + + + The namespace URI in the name for a computed attribute cannot be %1. + 一个被计算的属性的名称中的命名空间 URI 不能是 %1。 + + + The name for a computed attribute cannot have the namespace URI %1 with the local name %2. + 一个被计算的属性的名称不能使用带有本地名称 %2 的命名空间 URI %1。 + + + Type error in cast, expected %1, received %2. + 抛出类型错误,期望的是 %1,收到的是 %2。 + + + When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed. + 当抛出到 %1 或者它的派生类时,源类型必须是同一类型,或者它必须是一个字符串类型。类型 %2 是不被允许的。 + + + A comment cannot contain %1 + 注释不能包含 %1 + + + A comment cannot end with a %1. + 注释不能以 %1 结尾。 + + + An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place. + 一个属性节点不能是一个文档节点的子节点。因此,这个属性 %1 所在位置是不合适的。 + + + A library module cannot be evaluated directly. It must be imported from a main module. + 一个库模块不能被直接评估。它必须从一个主模块中导入。 + + + No template by name %1 exists. + 没有名为 %1 的模板存在。 + + + A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type. + 类型为 %1 的值不能被判断。一个判断必须是数值类型或者一个有效的布尔值(Effective Boolean Value)类型。 + + + A positional predicate must evaluate to a single numeric value. + 一个定位判断必须评估一个单一数值。 + + + The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, %2 is invalid. + 一个处理指令中的目标名称不能是任何大小写混合的 %1。因此,%2 是无效的。 + + + %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. + %1 不是处理指令的有效目标名称。它必须是值 %2,例如 %3。 + + + The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. + 一个路径中的最后一步必须包含节点或者原子值。它不能是两者的一个组合。 + + + No namespace binding exists for the prefix %1 + 对于前缀 %1,没有存在绑定的命名空间。 + + + No namespace binding exists for the prefix %1 in %2 + 对于 %2 中的前缀 %1,没有存在绑定的命名空间。 + + + The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration. + %1 的第一个参数不能是类型 %2 的。它必须是数字类型的,xs:yearMonthDuration 或者 xs:dayTimeDuration。 + + + The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + %1 的第一个参数不能是类型 %2 的。它必须是类型 %3、%4 或者 %5 的。 + + + The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + %1 的第二个参数不能是类型 %2 的。它必须是类型 %3、%4 或者 %5 的。 + + + If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same. + 如果两个值都有区偏移(zone offset),它们必须拥有相同的区偏移。%1 和 %2 的区偏移是不同的。 + + + %1 must be followed by %2 or %3, not at the end of the replacement string. + %1 必须被 %2 或者 %3 跟随,不能在替换字符串的末尾。 + + + %1 and %2 match the start and end of a line. + %1 和 %2 匹配了一行的头和尾。 + + + Whitespace characters are removed, except when they appear in character classes + 空白字符被移除了,除非当它们出现在字符类中 + + + %1 is an invalid flag for regular expressions. Valid flags are: + %1 是正则表达式中的一个无效标记。有效标记为: + + + If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified. + 如果第一个参数是空序列或者零长度字符串(无命名空间),那么就不能指定前缀。前缀 %1 被指定了。 + + + The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization). + 不支持正规化(normalization)表单 %1。被支持的表单是 %2、%3、%4 和 %5,以及无,例如空字符串(无正规化)。 + + + A zone offset must be in the range %1..%2 inclusive. %3 is out of range. + 区偏移(zone offset)必须在 %1...%2 范围之内。%3 是在范围之外的。 + + + Required cardinality is %1; got cardinality %2. + 所需要的表间关系是 %1;得到的表间关系却是 %2。 + + + The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2. + 编码方式 %1 是无效的。它必须只包含拉丁字符,必须不包含空白符号,并且必须和正则表达式 %2 匹配。 + + + The keyword %1 cannot occur with any other mode name. + 任何其他模式名称不能出现关键字%1。 + + + No variable with name %1 exists + + + + The value of attribute %1 must be of type %2, which %3 isn't. + + + + The prefix %1 cannot be bound. By default, it is already bound to the namespace %2. + + + + A variable with name %1 has already been declared. + + + + No value is available for the external variable with name %1. + + + + A stylesheet function must have a prefixed name. + 样式表函数必须有一个前缀名。 + + + The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. + 命名空间 %1 是保留的;因此用户定义的函数不能使用它。请试试预定义的前缀 %2,它就是用于这种情况的。 + + + An argument with name %1 has already been declared. Every argument name must be unique. + + + + When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. + 当函数%1被用于样式匹配时,参数必须是变量参考或者字符串。 + + + In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching. + 在XSL-T样式中,函数%1的第一个参数必须是字符串,以便用于匹配。 + + + In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching. + 在XSL-T样式中,函数%1的第一个参数必须是文字或者变量参考,以便用于匹配。 + + + In an XSL-T pattern, function %1 cannot have a third argument. + 在XSL-T样式中,函数%1不能有第三个参数。 + + + In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. + 在XSL-T样式中,只用函数%1和%2可以用于匹配,%3不可以。 + + + In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can. + 在XSL-T仰视中,不能使用%1轴,只能使用%2轴或者%3轴。 + + + %1 is an invalid template mode name. + %1不是一个合法的模板模式名称。 + + + The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. + 一个在 for 表达式中绑定的变量的名称必须和这个定位变量不同。因此,这两个名称为 %1 的变量冲突。 + + + The Schema Validation Feature is not supported. Hence, %1-expressions may not be used. + 不支持方案验证特性(Schema Validation Feature)。因此,也许不能使用 %1 表达式。 + + + None of the pragma expressions are supported. Therefore, a fallback expression must be present + 不支持任何编译指示表达式(pragma expression)。因此,必须呈现一个回调表达式(fallback expression)。 + + + Each name of a template parameter must be unique; %1 is duplicated. + 每一个模板参数的名称都必须是唯一的;%2是重复的。 + + + No function with name %1 is available. + + + + %1 is not a valid numeric literal. + %1 不是一个有效的数字语义。 + + + W3C XML Schema identity constraint selector + + + + W3C XML Schema identity constraint field + + + + A construct was encountered which is disallowed in the current language(%1). + + + + Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared). + 命名空间 %1 只能和 %2 绑定(并且如果是这种情况,需要提前声明)。 + + + Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared). + 前缀 %1 只能和 %2 绑定(并且如果是这种情况,需要提前声明)。 + + + An attribute with name %1 has already appeared on this element. + + + + A direct element constructor is not well-formed. %1 is ended with %2. + 一个直接元素构造器没有很好地形成。%1 后面跟着 %2。 + + + The name %1 does not refer to any schema type. + 名称 %1 没有指向任何方案类型。 + + + %1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works. + %1 是一个复杂类型。无法抛出到复杂类型。因此,抛出到例如 %2 这样的原子类型是可以的。 + + + %1 is not an atomic type. Casting is only possible to atomic types. + %1 不是原子类型。只能抛出到原子类型。 + + + %1 is not a valid name for a processing-instruction. + %1不是一个处理指令的合法名称。 + + + The name of an extension expression must be in a namespace. + 一个扩展表达式的名称必须在一个命名空间中。 + + + Required type is %1, but %2 was found. + 需要的类型是 %1,但是找到的是 %2。 + + + Promoting %1 to %2 may cause loss of precision. + 把 %1 升级为 %2 会导致精度的损失。 + + + It's not possible to add attributes after any other kind of node. + 不能在任何其它类型节点后添加属性。 + + + Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported. + 只支持 Unicode 代码点校验(Unicode Codepoint Collation)(%1)。%2 是不被支持的。 + + + Integer division (%1) by zero (%2) is undefined. + 整数除法(%1)除零(%2)是未定义的。 + + + Division (%1) by zero (%2) is undefined. + 除法(%1)除零(%2)是未定义的。 + + + Modulus division (%1) by zero (%2) is undefined. + 求模除法(%1)除零(%2)是未定义的。 + + + %1 takes at most %n argument(s). %2 is therefore invalid. + + %1 最多可以有 %n 个参数。因此 %2 是无效的。 + + + + %1 requires at least %n argument(s). %2 is therefore invalid. + + %1 需要至少 %n 个参数。因此 %2 是无效的。 + + + + The root node of the second argument to function %1 must be a document node. %2 is not a document node. + 函数 %1 的第二个参数的根节点必须是一个文档节点。%2 不是一个文档节点。 + + + The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) + 用户定义函数的名字空间不能为空(试用为这种情况而存在的预定义前缀%1) + + + A default namespace declaration must occur before function, variable, and option declarations. + 默认命名空间声明必须出现在函数、变量和选项声明之前。 + + + Namespace declarations must occur before function, variable, and option declarations. + 命名空间声明必须出现在函数、变量和选项声明之前。 + + + Module imports must occur before function, variable, and option declarations. + 模块导入不能出现在函数、变量和选项声明之前。 + + + %1 is not a whole number of minutes. + %1 不是分钟的整数。 + + + Attribute %1 can't be serialized because it appears at the top level. + 属性 %1 不能被串行化,因为它出现在最顶层。 + + + %1 is an unsupported encoding. + %1 是不被支持的编码。 + + + %1 contains octets which are disallowed in the requested encoding %2. + %1包含了在请求编码%2中不允许的八进位值。 + + + The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character. + 在使用编码%3的%2中出现的代码点%1不是一个有效的XML字符。 + + + Ambiguous rule match. + 含糊规则匹配。 + + + In a namespace constructor, the value for a namespace cannot be an empty string. + + + + The prefix must be a valid %1, which %2 is not. + 前缀必须是有效的%1,而%2不是。 + + + The prefix %1 cannot be bound. + 前缀%1不能被绑定。 + + + Only the prefix %1 can be bound to %2 and vice versa. + 只有前缀%1可以绑定到%2,反之也一样 + + + The parameter %1 is required, but no corresponding %2 is supplied. + 需要参数%1,但是没有提供对应的%2。 + + + The parameter %1 is passed, but no corresponding %2 exists. + 参数%1已传递,但没有相应的%2存在。 + + + The URI cannot have a fragment + URI不能有片段 + + + Element %1 is not allowed at this location. + 元素%1不能在这个位置。 + + + Text nodes are not allowed at this location. + 文本节点不能在这个位置。 + + + Parse error: %1 + 解析错误:%1 + + + The value of the XSL-T version attribute must be a value of type %1, which %2 isn't. + XSL-T版本属性的值必须是%1类型的值,而%2不是。 + + + Running an XSL-T 1.0 stylesheet with a 2.0 processor. + 在XSL-T 2.0处理器中运行一个1.0的样式表。 + + + Unknown XSL-T attribute %1. + 未知的XSL-T属性%1。 + + + Attribute %1 and %2 are mutually exclusive. + 属性%1和%2彼此互斥。 + + + In a simplified stylesheet module, attribute %1 must be present. + 在一个简化样式表模块中,属性%1必须存在。 + + + If element %1 has no attribute %2, it cannot have attribute %3 or %4. + 如果元素%1没有属性%2,那么它也不能有属性%3或者%4。 + + + Element %1 must have at least one of the attributes %2 or %3. + 元素%1必须至少有属性%2或者%3其中一个。 + + + At least one mode must be specified in the %1-attribute on element %2. + 在元素%2的%1属性中至少要指定一个模式。 + + + Element %1 must come last. + 元素%1必须最后出现。 + + + At least one %1-element must occur before %2. + 至少一个元素%1要出现在%2之前。 + + + Only one %1-element can appear. + 只能出现一个元素%1。 + + + At least one %1-element must occur inside %2. + 至少一个元素%1要出现在%2之内。 + + + When attribute %1 is present on %2, a sequence constructor cannot be used. + 当属性%1出现在%2中时,不能使用顺序构造。 + + + Element %1 must have either a %2-attribute or a sequence constructor. + 元素%1必须有在一个%2属性或者顺序构造。 + + + When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor. + 当需要参数时,不能通过属性%1或者顺序构造提供默认值。 + + + Element %1 cannot have children. + 元素%1不能有子元素。 + + + Element %1 cannot have a sequence constructor. + 元素%1不能有顺序构造。 + + + The attribute %1 cannot appear on %2, when it is a child of %3. + 属性%1不能出现在%2中,因为它是%3的子元素。 + + + A parameter in a function cannot be declared to be a tunnel. + 函数内的参数不能被声明为通道(tunnel)。 + + + This processor is not Schema-aware and therefore %1 cannot be used. + 这个处理器不能感知Schema,因此%1不能被使用。 + + + Top level stylesheet elements must be in a non-null namespace, which %1 isn't. + 顶级样式表元素必须是在非空命名空间中的,而%1不是。 + + + The value for attribute %1 on element %2 must either be %3 or %4, not %5. + 元素%2中属性%1的值必须是%3或者%4,而不是%5。 + + + Attribute %1 cannot have the value %2. + 属性%1的值不能是%2。 + + + The attribute %1 can only appear on the first %2 element. + 属性%1只能出现在前%2个元素中。 + + + At least one %1 element must appear as child of %2. + %2必须至少又一个子元素%1。 + + + %1 has inheritance loop in its base type %2. + + + + Circular inheritance of base type %1. + + + + Circular inheritance of union %1. + + + + %1 is not allowed to derive from %2 by restriction as the latter defines it as final. + + + + %1 is not allowed to derive from %2 by extension as the latter defines it as final. + + + + Base type of simple type %1 cannot be complex type %2. + + + + Simple type %1 cannot have direct base type %2. + + + + Simple type %1 is not allowed to have base type %2. + + + + Simple type %1 can only have simple atomic type as base type. + + + + Simple type %1 cannot derive from %2 as the latter defines restriction as final. + + + + Variety of item type of %1 must be either atomic or union. + + + + Variety of member types of %1 must be atomic. + + + + %1 is not allowed to derive from %2 by list as the latter defines it as final. + + + + Simple type %1 is only allowed to have %2 facet. + + + + Base type of simple type %1 must have variety of type list. + + + + Base type of simple type %1 has defined derivation by restriction as final. + + + + Item type of base type does not match item type of %1. + + + + Simple type %1 contains not allowed facet type %2. + + + + %1 is not allowed to derive from %2 by union as the latter defines it as final. + + + + %1 is not allowed to have any facets. + + + + Base type %1 of simple type %2 must have variety of union. + + + + Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute. + + + + Member type %1 cannot be derived from member type %2 of %3's base type %4. + + + + Derivation method of %1 must be extension because the base type %2 is a simple type. + + + + Complex type %1 has duplicated element %2 in its content model. + + + + Complex type %1 has non-deterministic content. + + + + Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3. + + + + Content model of complex type %1 is not a valid extension of content model of %2. + + + + Complex type %1 must have simple content. + + + + Complex type %1 must have the same simple type as its base class %2. + + + + Complex type %1 cannot be derived from base type %2%3. + + + + Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3. + + + + Complex type %1 with simple content cannot be derived from complex base type %2. + + + + Item type of simple type %1 cannot be a complex type. + + + + Member type of simple type %1 cannot be a complex type. + + + + %1 is not allowed to have a member type with the same name as itself. + + + + %1 facet collides with %2 facet. + + + + %1 facet must have the same value as %2 facet of base type. + + + + %1 facet must be equal or greater than %2 facet of base type. + + + + %1 facet must be less than or equal to %2 facet of base type. + + + + %1 facet contains invalid regular expression + + + + Unknown notation %1 used in %2 facet. + + + + %1 facet contains invalid value %2: %3. + + + + %1 facet cannot be %2 or %3 if %4 facet of base type is %5. + + + + %1 facet cannot be %2 if %3 facet of base type is %4. + + + + %1 facet must be less than or equal to %2 facet. + + + + %1 facet must be less than %2 facet of base type. + + + + %1 facet and %2 facet cannot appear together. + + + + %1 facet must be greater than %2 facet of base type. + + + + %1 facet must be less than %2 facet. + + + + %1 facet must be greater than or equal to %2 facet of base type. + + + + Simple type contains not allowed facet %1. + + + + %1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list. + + + + Only %1 and %2 facets are allowed when derived by union. + + + + %1 contains %2 facet with invalid data: %3. + + + + Attribute group %1 contains attribute %2 twice. + + + + Attribute group %1 contains two different attributes that both have types derived from %2. + + + + Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3. + + + + Complex type %1 contains attribute %2 twice. + + + + Complex type %1 contains two different attributes that both have types derived from %2. + + + + Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3. + + + + Element %1 is not allowed to have a value constraint if its base type is complex. + + + + Element %1 is not allowed to have a value constraint if its type is derived from %2. + + + + Value constraint of element %1 is not of elements type: %2. + + + + Element %1 is not allowed to have substitution group affiliation as it is no global element. + + + + Type of element %1 cannot be derived from type of substitution group affiliation. + + + + Value constraint of attribute %1 is not of attributes type: %2. + + + + Attribute %1 has value constraint but has type derived from %2. + + + + %1 attribute in derived complex type must be %2 like in base type. + + + + Attribute %1 in derived complex type must have %2 value constraint like in base type. + + + + Attribute %1 in derived complex type must have the same %2 value constraint like in base type. + + + + Attribute %1 in derived complex type must have %2 value constraint. + + + + processContent of base wildcard must be weaker than derived wildcard. + + + + Element %1 exists twice with different types. + + + + Particle contains non-deterministic wildcards. + + + + Base attribute %1 is required but derived attribute is not. + + + + Type of derived attribute %1 cannot be validly derived from type of base attribute. + + + + Value constraint of derived attribute %1 does not match value constraint of base attribute. + + + + Derived attribute %1 does not exist in the base definition. + + + + Derived attribute %1 does not match the wildcard in the base definition. + + + + Base attribute %1 is required but missing in derived definition. + + + + Derived definition contains an %1 element that does not exists in the base definition + + + + Derived wildcard is not a subset of the base wildcard. + + + + %1 of derived wildcard is not a valid restriction of %2 of base wildcard + + + + Attribute %1 from base type is missing in derived type. + + + + Type of derived attribute %1 differs from type of base attribute. + + + + Base definition contains an %1 element that is missing in the derived definition + + + + %1 references unknown %2 or %3 element %4. + + + + %1 references identity constraint %2 that is no %3 or %4 element. + + + + %1 has a different number of fields from the identity constraint %2 that it references. + + + + Base type %1 of %2 element cannot be resolved. + + + + Item type %1 of %2 element cannot be resolved. + + + + Member type %1 of %2 element cannot be resolved. + + + + Type %1 of %2 element cannot be resolved. + + + + Base type %1 of complex type cannot be resolved. + + + + %1 cannot have complex base type that has a %2. + + + + Content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type. + + + + Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model. + + + + Type of %1 element must be a simple type, %2 is not. + + + + Substitution group %1 of %2 element cannot be resolved. + + + + Substitution group %1 has circular definition. + + + + Duplicated element names %1 in %2 element. + + + + Reference %1 of %2 element cannot be resolved. + + + + Circular group reference for %1. + + + + %1 element is not allowed in this scope + + + + %1 element cannot have %2 attribute with value other than %3. + + + + %1 element cannot have %2 attribute with value other than %3 or %4. + + + + %1 or %2 attribute of reference %3 does not match with the attribute declaration %4. + + + + Attribute group %1 has circular reference. + + + + %1 attribute in %2 must have %3 use like in base type %4. + + + + Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2. + + + + %1 has attribute wildcard but its base type %2 has not. + + + + Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible. + + + + Enumeration facet contains invalid content: {%1} is not a value of type %2. + + + + Namespace prefix of qualified name %1 is not defined. + + + + %1 element %2 is not a valid restriction of the %3 element it redefines: %4. + + + + Empty particle cannot be derived from non-empty particle. + + + + Derived particle is missing element %1. + + + + Derived element %1 is missing value constraint as defined in base particle. + + + + Derived element %1 has weaker value constraint than base particle. + + + + Fixed value constraint of element %1 differs from value constraint in base particle. + + + + Derived element %1 cannot be nillable as base element is not nillable. + + + + Block constraints of derived element %1 must not be more weaker than in the base element. + + + + Simple type of derived element %1 cannot be validly derived from base element. + + + + Complex type of derived element %1 cannot be validly derived from base element. + + + + Element %1 is missing in derived particle. + + + + Element %1 does not match namespace constraint of wildcard in base particle. + + + + Wildcard in derived particle is not a valid subset of wildcard in base particle. + + + + processContent of wildcard in derived particle is weaker than wildcard in base particle. + + + + Derived particle allows content that is not allowed in the base particle. + + + + Can not process unknown element %1, expected elements are: %2. + + + + Element %1 is not allowed in this scope, possible elements are: %2. + + + + Child element is missing in that scope, possible child elements are: %1. + + + + Document is not a XML schema. + + + + %1 attribute of %2 element contains invalid content: {%3} is not a value of type %4. + + + + %1 attribute of %2 element contains invalid content: {%3}. + + + + Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema. + + + + Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema. + + + + %1 element is not allowed to have the same %2 attribute value as the target namespace %3. + + + + %1 element without %2 attribute is not allowed inside schema without target namespace. + + + + %1 element is not allowed inside %2 element if %3 attribute is present. + + + + %1 element has neither %2 attribute nor %3 child element. + + + + %1 element with %2 child element must not have a %3 attribute. + + + + %1 attribute of %2 element must be %3 or %4. + + + + %1 attribute of %2 element must have a value of %3. + + + + %1 attribute of %2 element must have a value of %3 or %4. + + + + %1 element must not have %2 and %3 attribute together. + + + + Content of %1 attribute of %2 element must not be from namespace %3. + + + + %1 attribute of %2 element must not be %3. + + + + %1 attribute of %2 element must have the value %3 because the %4 attribute is set. + + + + Specifying use='prohibited' inside an attribute group has no effect. + + + + %1 element must have either %2 or %3 attribute. + + + + %1 element must have either %2 attribute or %3 or %4 as child element. + + + + %1 element requires either %2 or %3 attribute. + + + + Text or entity references not allowed inside %1 element + + + + %1 attribute of %2 element must contain %3, %4 or a list of URIs. + + + + %1 element is not allowed in this context. + + + + %1 attribute of %2 element has larger value than %3 attribute. + + + + Prefix of qualified name %1 is not defined. + + + + %1 attribute of %2 element must either contain %3 or the other values. + + + + Component with ID %1 has been defined previously. + + + + Element %1 already defined. + + + + Attribute %1 already defined. + + + + Type %1 already defined. + + + + Attribute group %1 already defined. + + + + Element group %1 already defined. + + + + Notation %1 already defined. + + + + Identity constraint %1 already defined. + + + + Duplicated facets in simple type %1. + + + + %1 is not valid according to %2. + + + + String content does not match the length facet. + + + + String content does not match the minLength facet. + + + + String content does not match the maxLength facet. + + + + String content does not match pattern facet. + + + + String content is not listed in the enumeration facet. + + + + Signed integer content does not match the maxInclusive facet. + + + + Signed integer content does not match the maxExclusive facet. + + + + Signed integer content does not match the minInclusive facet. + + + + Signed integer content does not match the minExclusive facet. + + + + Signed integer content is not listed in the enumeration facet. + + + + Signed integer content does not match pattern facet. + + + + Signed integer content does not match in the totalDigits facet. + + + + Unsigned integer content does not match the maxInclusive facet. + + + + Unsigned integer content does not match the maxExclusive facet. + + + + Unsigned integer content does not match the minInclusive facet. + + + + Unsigned integer content does not match the minExclusive facet. + + + + Unsigned integer content is not listed in the enumeration facet. + + + + Unsigned integer content does not match pattern facet. + + + + Unsigned integer content does not match in the totalDigits facet. + + + + Double content does not match the maxInclusive facet. + + + + Double content does not match the maxExclusive facet. + + + + Double content does not match the minInclusive facet. + + + + Double content does not match the minExclusive facet. + + + + Double content is not listed in the enumeration facet. + + + + Double content does not match pattern facet. + + + + Decimal content does not match in the fractionDigits facet. + + + + Decimal content does not match in the totalDigits facet. + + + + Date time content does not match the maxInclusive facet. + + + + Date time content does not match the maxExclusive facet. + + + + Date time content does not match the minInclusive facet. + + + + Date time content does not match the minExclusive facet. + + + + Date time content is not listed in the enumeration facet. + + + + Date time content does not match pattern facet. + + + + Duration content does not match the maxInclusive facet. + + + + Duration content does not match the maxExclusive facet. + + + + Duration content does not match the minInclusive facet. + + + + Duration content does not match the minExclusive facet. + + + + Duration content is not listed in the enumeration facet. + + + + Duration content does not match pattern facet. + + + + Boolean content does not match pattern facet. + + + + Binary content does not match the length facet. + + + + Binary content does not match the minLength facet. + + + + Binary content does not match the maxLength facet. + + + + Binary content is not listed in the enumeration facet. + + + + Invalid QName content: %1. + + + + QName content is not listed in the enumeration facet. + + + + QName content does not match pattern facet. + + + + Notation content is not listed in the enumeration facet. + + + + List content does not match length facet. + + + + List content does not match minLength facet. + + + + List content does not match maxLength facet. + + + + List content is not listed in the enumeration facet. + + + + List content does not match pattern facet. + + + + Union content is not listed in the enumeration facet. + + + + Union content does not match pattern facet. + + + + Data of type %1 are not allowed to be empty. + + + + Element %1 is missing child element. + + + + There is one IDREF value with no corresponding ID: %1. + + + + Loaded schema file is invalid. + + + + %1 contains invalid data. + + + + xsi:schemaLocation namespace %1 has already appeared earlier in the instance document. + + + + xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute. + + + + No schema defined for validation. + + + + No definition for element %1 available. + + + + Specified type %1 is not known to the schema. + + + + Element %1 is not defined in this scope. + + + + Declaration for element %1 does not exist. + + + + Element %1 contains invalid content. + + + + Element %1 is declared as abstract. + + + + Element %1 is not nillable. + + + + Attribute %1 contains invalid data: %2 + + + + Element contains content although it is nillable. + + + + Fixed value constraint not allowed if element is nillable. + + + + Element %1 cannot contain other elements, as it has a fixed content. + + + + Specified type %1 is not validly substitutable with element type %2. + + + + Complex type %1 is not allowed to be abstract. + + + + Element %1 contains not allowed attributes. + + + + Element %1 contains not allowed child element. + + + + Content of element %1 does not match its type definition: %2. + + + + Content of element %1 does not match defined value constraint. + + + + Element %1 contains not allowed child content. + + + + Element %1 contains not allowed text content. + + + + Element %1 is missing required attribute %2. + + + + Attribute %1 does not match the attribute wildcard. + + + + Declaration for attribute %1 does not exist. + + + + Element %1 contains two attributes of type %2. + + + + Attribute %1 contains invalid content. + + + + Element %1 contains unknown attribute %2. + + + + Content of attribute %1 does not match its type definition: %2. + + + + Content of attribute %1 does not match defined value constraint. + + + + Non-unique value found for constraint %1. + + + + Key constraint %1 contains absent fields. + + + + Key constraint %1 contains references nillable element %2. + + + + No referenced value found for key reference %1. + + + + More than one value found for field %1. + + + + Field %1 has no simple type. + + + + ID value '%1' is not unique. + + + + '%1' attribute contains invalid QName content: %2. + + + + diff --git a/config.profiles/symbian/translations/qt_zh_tw_symbian.ts b/config.profiles/symbian/translations/qt_zh_tw_symbian.ts new file mode 100644 index 0000000..3b1fb51 --- /dev/null +++ b/config.profiles/symbian/translations/qt_zh_tw_symbian.ts @@ -0,0 +1,8505 @@ + + + + + + CloseButton + + Close Tab + + + + + FakeReply + + Fake error ! + 假錯誤! + + + Invalid URL + URL無效 + + + + Phonon:: + + Notifications + + + + Music + + + + Video + + + + Communication + + + + Games + + + + Accessibility + + + + + Phonon::AudioOutput + + <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> + <html>音訊播放裝置<b>%1</b>無法運作。<br/>正在切換回<b>%2</b>。</html> + + + <html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html> + <html>正在切換到音訊播放裝置<b>%1</b>,<br/>該裝置剛變成可使用,而且優先順序較高。</html> + + + Revert back to device '%1' + 切換回裝置"%1" + + + + Phonon::Gstreamer::Backend + + Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. + Some video features have been disabled. + + + + Warning: You do not seem to have the base GStreamer plugins installed. + All audio and video support has been disabled + + + + + Phonon::Gstreamer::MediaObject + + Cannot start playback. + +Check your GStreamer installation and make sure you +have libgstreamer-plugins-base installed. + + + + A required codec is missing. You need to install the following codec(s) to play this content: %0 + + + + Could not open media source. + + + + Invalid source type. + + + + Could not locate media source. + + + + Could not open audio device. The device is already in use. + + + + Could not decode media source. + + + + + Phonon::MMF + + Audio Output + 音訊輸出 + + + The audio output device + 音訊輸出裝置 + + + No error + 沒有錯誤 + + + Not found + 找不到 + + + Out of memory + 記憶體不足 + + + Not supported + 不支援 + + + Overflow + 溢位 + + + Underflow + 降位 + + + Already exists + 已經存在 + + + Path not found + 找不到路徑 + + + In use + 使用中 + + + Not ready + 未就緒 + + + Access denied + 拒絕存取 + + + Could not connect + 無法連線 + + + Disconnected + 已中斷連線 + + + Permission denied + 權限不足 + + + Insufficient bandwidth + 頻寬不足 + + + Network unavailable + 網路無法使用 + + + Network communication error + 網路通訊錯誤 + + + Streaming not supported + 不支援串流 + + + Server alert + 伺服器警告 + + + Invalid protocol + 通訊協定無效 + + + Invalid URL + URL無效 + + + Multicast error + 多點傳送錯誤 + + + Proxy server error + Proxy伺服器錯誤 + + + Proxy server not supported + 不支援的Proxy伺服器 + + + Audio output error + 音訊輸出錯誤 + + + Video output error + 視訊輸出錯誤 + + + Decoder error + 解碼器錯誤 + + + Audio or video components could not be played + 音訊或視訊元件無法播放 + + + DRM error + DRM錯誤 + + + Unknown error (%1) + 不明錯誤(%1) + + + + Phonon::MMF::AbstractMediaPlayer + + Not ready to play + 尚未準備好播放 + + + Error opening file + 開啟檔案時發生錯誤 + + + Error opening URL + 開啟URL時發生錯誤 + + + Setting volume failed + 音量設定失敗 + + + Playback complete + 播放完成 + + + + Phonon::MMF::AudioEqualizer + + %1 Hz + %1 Hz + + + + Phonon::MMF::AudioPlayer + + Getting position failed + 取得位置失敗 + + + Opening clip failed + 開啟檔案失敗 + + + + Phonon::MMF::EffectFactory + + Enabled + 已啟用 + + + + Phonon::MMF::EnvironmentalReverb + + Decay HF ratio (%) + 衰減HF比率(%) + + + Decay time (ms) + 衰減時間(ms) + + + Density (%) + 密度(%) + + + Diffusion (%) + 擴散(%) + + + Reflections delay (ms) + 反射延遲(ms) + + + Reflections level (mB) + 反射電平(mB) + + + Reverb delay (ms) + 殘響延遲(ms) + + + Reverb level (mB) + 殘響電平(mB) + + + Room HF level + 空間HF電平 + + + Room level (mB) + 空間電平(mB) + + + + Phonon::MMF::MediaObject + + Error opening source: type not supported + 開啟來源時發生錯誤:不支援的類型 + + + Error opening source: media type could not be determined + 開啟來源時發生錯誤:無法判斷媒體類型 + + + + Phonon::MMF::StereoWidening + + Level (%) + 電平(%) + + + + Phonon::MMF::VideoPlayer + + Pause failed + 暫停失敗 + + + Seek failed + 搜尋失敗 + + + Getting position failed + 取得位置失敗 + + + Opening clip failed + 開啟檔案失敗 + + + Buffering clip failed + 檔案緩衝處理失敗 + + + Video display error + 視訊顯示錯誤 + + + + Phonon::VolumeSlider + + Volume: %1% + + + + Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1% + + + + Muted + 已靜音 + + + + Q3Accel + + %1, %2 not defined + + + + Ambiguous %1 not handled + + + + + Q3DataTable + + True + + + + False + + + + Insert + + + + Update + + + + Delete + + + + + Q3FileDialog + + Copy or Move a File + + + + Read: %1 + + + + Write: %1 + + + + Cancel + + + + All Files (*) + + + + Name + + + + Size + + + + Type + + + + Date + + + + Attributes + + + + &OK + + + + Look &in: + + + + File &name: + + + + File &type: + + + + Back + + + + One directory up + + + + Create New Folder + + + + List View + + + + Detail View + + + + Preview File Info + + + + Preview File Contents + + + + Read-write + + + + Read-only + + + + Write-only + + + + Inaccessible + + + + Symlink to File + + + + Symlink to Directory + + + + Symlink to Special + + + + File + + + + Dir + + + + Special + + + + Open + + + + Save As + + + + &Open + + + + &Save + + + + &Rename + + + + &Delete + + + + R&eload + + + + Sort by &Name + + + + Sort by &Size + + + + Sort by &Date + + + + &Unsorted + + + + Sort + + + + Show &hidden files + + + + the file + + + + the directory + + + + the symlink + + + + Delete %1 + + + + <qt>Are you sure you wish to delete %1 "%2"?</qt> + + + + &Yes + + + + &No + + + + New Folder 1 + + + + New Folder + 新資料夾 + + + New Folder %1 + 新資料夾 %1 + + + Find Directory + + + + Directories + + + + Directory: + + + + Error + + + + %1 +File not found. +Check path and filename. + + + + All Files (*.*) + + + + Open + + + + Select a Directory + + + + + Q3LocalFs + + Could not read directory +%1 + + + + Could not create directory +%1 + + + + Could not remove file or directory +%1 + + + + Could not rename +%1 +to +%2 + + + + Could not open +%1 + + + + Could not write +%1 + + + + + Q3MainWindow + + Line up + + + + Customize... + + + + + Q3NetworkProtocol + + Operation stopped by the user + + + + + Q3ProgressDialog + + Cancel + + + + + Q3TabDialog + + OK + + + + Apply + + + + Help + + + + Defaults + + + + Cancel + + + + + Q3TextEdit + + &Undo + + + + &Redo + + + + Cu&t + + + + &Copy + + + + &Paste + + + + Clear + + + + Select All + + + + + Q3TitleBar + + System + + + + Restore up + + + + Minimize + + + + Restore down + + + + Maximize + + + + Close + + + + Contains commands to manipulate the window + + + + Puts a minimized window back to normal + + + + Moves the window out of the way + + + + Puts a maximized window back to normal + + + + Makes the window full screen + + + + Closes the window + + + + Displays the name of the window and contains controls to manipulate it + + + + + Q3ToolBar + + More... + + + + + Q3UrlOperator + + The protocol `%1' is not supported + + + + The protocol `%1' does not support listing directories + + + + The protocol `%1' does not support creating new directories + + + + The protocol `%1' does not support removing files or directories + + + + The protocol `%1' does not support renaming files or directories + + + + The protocol `%1' does not support getting files + + + + The protocol `%1' does not support putting files + + + + The protocol `%1' does not support copying or moving files or directories + + + + (unknown) + + + + + Q3Wizard + + &Cancel + + + + < &Back + + + + &Next > + + + + &Finish + + + + &Help + + + + + QAbstractSocket + + Host not found + + + + Connection refused + + + + Connection timed out + + + + Operation on socket is not supported + + + + Socket operation timed out + + + + Socket is not connected + + + + Network unreachable + + + + + QAbstractSpinBox + + &Step up + + + + Step &down + + + + &Select All + + + + + QAccessibleButton + + Press + + + + + QApplication + + QT_LAYOUT_DIRECTION + Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. + + + + Executable '%1' requires Qt %2, found Qt %3. + + + + Incompatible Qt Library Error + + + + Activate + + + + Activates the program's main window + + + + + QAxSelect + + Select ActiveX Control + + + + OK + + + + &Cancel + + + + COM &Object: + + + + + QCheckBox + + Uncheck + + + + Check + + + + Toggle + + + + + QColorDialog + + Hu&e: + + + + &Sat: + + + + &Val: + + + + &Red: + + + + &Green: + + + + Bl&ue: + + + + A&lpha channel: + + + + Select Color + + + + &Basic colors + + + + &Custom colors + + + + &Add to Custom Colors + + + + + QComboBox + + Open + + + + False + + + + True + + + + Close + + + + + QCoreApplication + + %1: key is empty + QSystemSemaphore + + + + %1: unable to make key + QSystemSemaphore + + + + %1: ftok failed + QSystemSemaphore + + + + %1: already exists + QSystemSemaphore + + + + %1: does not exist + QSystemSemaphore + %1:不存在 + + + %1: out of resources + QSystemSemaphore + + + + %1: unknown error %2 + QSystemSemaphore + + + + + QDB2Driver + + Unable to connect + + + + Unable to commit transaction + + + + Unable to rollback transaction + + + + Unable to set autocommit + + + + + QDB2Result + + Unable to execute statement + + + + Unable to prepare statement + + + + Unable to bind variable + + + + Unable to fetch record %1 + + + + Unable to fetch next + + + + Unable to fetch first + + + + + QDateTimeEdit + + AM + + + + am + + + + PM + + + + pm + + + + + QDial + + QDial + + + + SpeedoMeter + + + + SliderHandle + + + + + QDialog + + What's This? + + + + Done + + + + + QDialogButtonBox + + OK + + + + Save + + + + &Save + + + + Open + + + + Cancel + + + + &Cancel + + + + Close + + + + &Close + + + + Apply + + + + Reset + + + + Help + + + + Don't Save + + + + Discard + + + + &Yes + + + + Yes to &All + + + + &No + + + + N&o to All + + + + Save All + + + + Abort + + + + Retry + + + + Ignore + + + + Restore Defaults + + + + Close without Saving + + + + &OK + + + + + QDirModel + + Name + + + + Size + + + + Kind + Match OS X Finder + + + + Type + All other platforms + + + + Date Modified + + + + + QDockWidget + + Close + + + + Dock + + + + Float + + + + + QDoubleSpinBox + + More + + + + Less + + + + + QErrorMessage + + &Show this message again + 再度顯示此訊息(&S) + + + &OK + + + + Debug Message: + + + + Warning: + 警告: + + + Fatal Error: + + + + + QFile + + Destination file exists + 目標檔已存在 + + + Will not rename sequential file using block copy + 使用區塊複製將不會重新命名循序檔 + + + Cannot remove source file + 無法移除來源檔 + + + Cannot open %1 for input + 無法開啟 %1 以輸入 + + + Cannot open for output + 無法開啟 %1 以輸出 + + + Failure to write block + 寫入區塊時失敗 + + + Cannot create %1 for output + 無法建立 %1 以輸出 + + + + QFileDialog + + All Files (*) + 所有檔案 (*) + + + Back + 返回 + + + List View + 列表檢視 + + + Detail View + 詳細檢視 + + + File + 檔案 + + + Open + 開啟 + + + Save As + 另存新檔 + + + &Open + 開啟(&O) + + + &Save + 儲存(&S) + + + Recent Places + 最近的地方 + + + &Rename + 重新命名(&R) + + + &Delete + 刪除(&D) + + + Show &hidden files + 顯示隱藏檔(&H) + + + New Folder + 新資料夾 + + + Find Directory + 尋找目錄 + + + Directories + 目錄 + + + All Files (*.*) + 所有檔案 (*.*) + + + Directory: + 目錄: + + + %1 already exists. +Do you want to replace it? + %1 已存在 +您要取代它嗎? + + + %1 +File not found. +Please verify the correct file name was given. + %1 +找不到檔案。 +請檢查檔名是否正確。 + + + My Computer + 我的電腦 + + + Parent Directory + 父目錄 + + + Files of type: + 檔案型態: + + + %1 +Directory not found. +Please verify the correct directory name was given. + %1 +找不到目錄。 +請檢查目錄名稱是否正確。 + + + '%1' is write protected. +Do you want to delete it anyway? + %1 有寫入保護。 +您確定要刪除它嗎? + + + Are sure you want to delete '%1'? + 您確定要刪除 %1 嗎? + + + Could not delete directory. + 無法刪除目錄。 + + + Drive + 磁碟 + + + File Folder + Match Windows Explorer + 檔案資料夾 + + + Folder + All other platforms + 資料夾 + + + Alias + Mac OS X Finder + 別名 + + + Shortcut + All other platforms + 捷徑 + + + Unknown + 未知 + + + Show + 顯示 + + + Forward + 往前 + + + &New Folder + 新增資料夾(&N) + + + &Choose + 選擇(&C) + + + Remove + 移除 + + + File &name: + 檔名(&N): + + + Look in: + 尋找於: + + + Create New Folder + 建立新資料夾 + + + + QFileSystemModel + + %1 TB + %1 TB + + + %1 GB + %1 GB + + + %1 MB + %1 MB + + + %1 KB + %1 KB + + + %1 bytes + %1 位元組 + + + Invalid filename + 不合法的檔名 + + + <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. + <b>無法使用名稱 "%1"。</b><p>請使用其它名稱,字元數少一點,或是不要有標點符號。 + + + Name + 名稱 + + + Size + 大小 + + + Kind + Match OS X Finder + 種類 + + + Type + All other platforms + 型態 + + + Date Modified + 變更日期 + + + My Computer + 我的電腦 + + + Computer + 電腦 + + + %1 byte(s) + %1位元組 + + + + QFontDatabase + + Normal + 正常 + + + Bold + 粗體 + + + Demi Bold + 半粗體 + + + Black + 黑體 + + + Demi + 半體 + + + Light + 輕體 + + + Italic + 斜體 + + + Oblique + 傾斜體 + + + Any + 任何 + + + Latin + 拉丁 + + + Greek + 希臘 + + + Cyrillic + 斯拉夫 + + + Armenian + 亞美尼亞 + + + Hebrew + 希伯來 + + + Arabic + 阿拉伯 + + + Syriac + 敘利亞 + + + Thaana + Thaana + + + Devanagari + Devanagari + + + Bengali + 孟加拉 + + + Gurmukhi + Gurmukhi + + + Gujarati + Gujarati + + + Oriya + Oriya + + + Tamil + 坦米爾 + + + Telugu + Telugu + + + Kannada + 坎達那 + + + Malayalam + 馬來語 + + + Sinhala + 錫蘭 + + + Thai + 泰語 + + + Lao + 寮國 + + + Tibetan + 西藏 + + + Myanmar + 緬甸 + + + Georgian + 喬治亞 + + + Khmer + 高棉 + + + Simplified Chinese + 簡體中文 + + + Traditional Chinese + 繁體中文 + + + Japanese + 日語 + + + Korean + 韓語 + + + Vietnamese + 越南 + + + Symbol + 符號 + + + Ogham + 歐甘 + + + Runic + 盧恩 + + + N'Ko + N'Ko + + + + QFontDialog + + &Font + 字型(&F) + + + Font st&yle + 字型樣式(&Y) + + + &Size + 大小(&S) + + + Effects + 效果 + + + Stri&keout + 刪除線(&K) + + + &Underline + 底線(&U) + + + Sample + 範例 + + + Select Font + 選擇字型 + + + Wr&iting System + 寫入系統(&I) + + + + QFtp + + Host %1 found + 找到主機 %1 + + + Host found + 找到主機 + + + Connected to host %1 + 已連接到主機 %1 + + + Connected to host + 已連線到主機 + + + Connection to %1 closed + 到 %1 的連線已關閉 + + + Connection closed + 連線已關閉 + + + Host %1 not found + 找不到主機 %1 + + + Connection refused to host %1 + 連線到主機 %1 被拒 + + + Connection timed out to host %1 + 連線到主機 %1 逾時 + + + Unknown error + 未知的錯誤 + + + Connecting to host failed: +%1 + 連線到主機失敗: +%1 + + + Login failed: +%1 + 登入失敗: +%1 + + + Listing directory failed: +%1 + 列出目錄時失敗: +%1 + + + Changing directory failed: +%1 + 變更目錄時失敗: +%1 + + + Downloading file failed: +%1 + 下載檔案時失敗: +%1 + + + Uploading file failed: +%1 + 上傳檔案時失敗: +%1 + + + Removing file failed: +%1 + 移除檔案時失敗: +%1 + + + Creating directory failed: +%1 + 建立目錄時失敗: +%1 + + + Removing directory failed: +%1 + 移除目錄時失敗: +%1 + + + Not connected + 未連線 + + + Connection refused for data connection + 資料連線被拒 + + + + QHostInfo + + Unknown error + 未知的錯誤 + + + + QHostInfoAgent + + Host not found + 找不到主機 + + + Unknown address type + 未知的位址型態 + + + Unknown error + 未知的錯誤 + + + No host name given + 未提供主機名稱 + + + Invalid hostname + 主機名稱無效 + + + + QHttp + + Connection refused + 連線被拒 + + + Host %1 not found + 找不到主機 %1 + + + Wrong content length + 錯誤的內容長度 + + + HTTP request failed + HTTP 要求失敗 + + + Host %1 found + 找到主機 %1 + + + Host found + 找到主機 + + + Connected to host %1 + 已連接到主機 %1 + + + Connected to host + 已連線到主機 + + + Connection to %1 closed + 到 %1 的連線已關閉 + + + Connection closed + 連線已關閉 + + + Unknown error + 未知的錯誤 + + + Request aborted + 要求中止 + + + No server set to connect to + 沒有設定要連線到哪個伺服器 + + + Server closed connection unexpectedly + 伺服器無預警關閉連線 + + + Invalid HTTP response header + 不合法的 HTTP 回覆標頭 + + + Unknown authentication method + 不明的驗證方法 + + + Invalid HTTP chunked body + 不合法的 HTTP 區塊主體 + + + Error writing response to device + 寫入回應到裝置時發生錯誤 + + + Proxy authentication required + 代理伺服器需要認證 + + + Authentication required + 需要認證 + + + Proxy requires authentication + 代理伺服器需要認證 + + + Host requires authentication + 主機需要認證 + + + Data corrupted + 資料已損毀 + + + SSL handshake failed + SSL 溝通失敗 + + + Unknown protocol specified + 指定了未知的協定 + + + Connection refused (or timed out) + 連線被拒(或連線逾時) + + + HTTPS connection requested but SSL support not compiled in + HTTPS 連線需要的 SSL 支援並未編譯進來 + + + + QHttpSocketEngine + + Did not receive HTTP response from proxy + 未從代理伺服器接收到 HTTP 回應 + + + Error parsing authentication request from proxy + 剖析從代理伺服器傳來的認證要求時發生錯誤 + + + Authentication required + 需要認證 + + + Proxy denied connection + 代理伺服器拒絕連線 + + + Error communicating with HTTP proxy + 與 HTTP 代理伺服器聯繫時發生錯誤 + + + Proxy server not found + 找不到代理伺服器 + + + Proxy connection refused + 代理伺服器連線被拒 + + + Proxy server connection timed out + 代理伺服器連線逾時 + + + Proxy connection closed prematurely + 代理伺服器連線已不正常關閉 + + + + QIBaseDriver + + Error opening database + 開啟資料庫發生錯誤 + + + Could not start transaction + 無法開始事務 + + + Unable to commit transaction + 無法提交事務 + + + Unable to rollback transaction + 無法反轉事務 + + + + QIBaseResult + + Unable to create BLOB + 無法建立 BLOB + + + Unable to write BLOB + 無法寫入 BLOB + + + Unable to open BLOB + 無法開啟 BLOB + + + Unable to read BLOB + 無法讀取 BLOB + + + Could not find array + 找不到陣列 + + + Could not get array data + 無法取得陣列資料 + + + Could not get query info + 無法取得查詢資訊 + + + Could not start transaction + 無法開始事務 + + + Unable to commit transaction + 無法提交事務 + + + Could not allocate statement + 無法配置敘述 + + + Could not prepare statement + 無法準備敘述 + + + Could not describe input statement + 無法描述輸入敘述 + + + Could not describe statement + 無法描述敘述 + + + Unable to close statement + 無法關閉敘述 + + + Unable to execute query + 無法執行查詢 + + + Could not fetch next item + 無法抓取下一個項目 + + + Could not get statement info + 無法取得敘述資訊 + + + + QIODevice + + Permission denied + 權限不足 + + + Too many open files + 開啟過多檔案 + + + No such file or directory + 找不到該檔案或目錄 + + + No space left on device + 裝置上已無空間 + + + Unknown error + 未知的錯誤 + + + + QInputContext + + XIM + XIM + + + FEP + FEP + + + XIM input method + XIM 輸入法 + + + Windows input method + Windows 輸入法 + + + Mac OS X input method + Mac OS X 輸入法 + + + S60 FEP input method + S60 FEP輸入法 + + + + QInputDialog + + Enter a value: + 請輸入值: + + + + QLibrary + + Could not mmap '%1': %2 + 無法 mmap '%1':%2 + + + Plugin verification data mismatch in '%1' + 在 %1 中的外掛程式確認資料不符合 + + + Could not unmap '%1': %2 + 無法 unmap '%1':%2 + + + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] + 外掛程式 %1 使用不相容的 Qt 函式庫(%2.%3.%4)【%5】 + + + The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" + 外掛程式 %1 使用不相容的 Qt 函式庫。預期建構鑰 %2,卻得到 %3 + + + Unknown error + 未知的錯誤 + + + The shared library was not found. + 找不到分享函式庫 + + + The file '%1' is not a valid Qt plugin. + 檔案 %1 不是合法的 Qt 外掛程式。 + + + The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) + 外掛程式 %1 使用不相容的 Qt 函式庫。(不能將除錯與釋出版的函式庫混在一起。) + + + Cannot load library %1: %2 + 無法載入函式庫 %1:%2 + + + Cannot unload library %1: %2 + 無法卸載函式庫 %1:%2 + + + Cannot resolve symbol "%1" in %2: %3 + 無法反解 %2 內的符號 %1:%3 + + + + QLineEdit + + Select All + 全部選擇 + + + &Undo + 復原(&U) + + + &Redo + 重做(&R) + + + Cu&t + 剪下(&T) + + + &Copy + 複製(&C) + + + &Paste + 貼上(&P) + + + Delete + 刪除 + + + + QLocalServer + + %1: Name error + %1:名稱錯誤 + + + %1: Permission denied + %1:存取被拒 + + + %1: Address in use + %1:位址使用中 + + + %1: Unknown error %2 + %1:未知的錯誤 %2 + + + + QLocalSocket + + %1: Connection refused + %1:連線被拒 + + + %1: Remote closed + %1:遠端已關閉 + + + %1: Invalid name + %1:不合法的名稱 + + + %1: Socket access error + %1:Socket 位址錯誤 + + + %1: Socket resource error + %1:Socket 資源錯誤 + + + %1: Socket operation timed out + %1:Socket 操作逾時 + + + %1: Datagram too large + %1:資料包過大 + + + %1: Connection error + %1:連線錯誤 + + + %1: The socket operation is not supported + %1:socket 操作未支援 + + + %1: Unknown error + %1:未知的錯誤 + + + %1: Unknown error %2 + %1:未知的錯誤 %2 + + + + QMYSQLDriver + + Unable to open database ' + 無法開啟資料庫 + + + Unable to connect + 無法連線 + + + Unable to begin transaction + 無法開始事務 + + + Unable to commit transaction + 無法提交事務 + + + Unable to rollback transaction + 無法反轉事務 + + + + QMYSQLResult + + Unable to fetch data + 無法抓取資料 + + + Unable to execute query + 無法執行查詢 + + + Unable to store result + 無法儲存結果 + + + Unable to prepare statement + 無法準備敘述 + + + Unable to reset statement + 無法重置敘述 + + + Unable to bind value + 無法結合數值 + + + Unable to execute statement + 無法執行敘述 + + + Unable to bind outvalues + 無法結合輸出值 + + + Unable to store statement results + 無法儲存敘述結果 + + + Unable to execute next query + 無法執行下一個查詢 + + + Unable to store next result + 無法儲存下一個結果 + + + + QMdiArea + + (Untitled) + (未命名) + + + + QMdiSubWindow + + %1 - [%2] + %1 - [%2] + + + Close + 關閉 + + + Minimize + 最小化 + + + Restore Down + 向下恢復 + + + &Restore + 回復(&R) + + + &Move + 移動(&M) + + + &Size + 大小(&S) + + + Mi&nimize + 最小化(&N) + + + Ma&ximize + 最大化(&X) + + + Stay on &Top + 留在頂端(&T) + + + &Close + 關閉(&C) + + + Maximize + 最大化 + + + Unshade + 取消遮蔽 + + + Shade + 遮蔽 + + + Restore + 回復 + + + Help + 說明 + + + Menu + 選單 + + + - [%1] + - [%1] + + + + QMenu + + Close + 關閉 + + + Open + 開啟 + + + Execute + 執行 + + + + QMenuBar + + Actions + 動作 + + + + QMessageBox + + OK + 確定 + + + <h3>About Qt</h3><p>This program uses Qt version %1.</p> + <h3>關於Qt</h3><p>本程式使用Qt %1版。</p> + + + <p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p><p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://qt.nokia.com/">qt.nokia.com</a> for more information.</p> + <p>Qt是一套應用於跨平台應用程式開發的C++工具集。</p><p>Qt提供橫跨MS&nbsp;Windows、Mac&nbsp;OS&nbsp;X、Linux及各主要商業Unix系統的單一來源移植能力。Qt也提供適用於嵌入式裝置的版本,例如Qt for Embedded Linux和Qt for Windows CE。</p><p>針對不同使用者的需求,Qt有三種不同授權方式。</p><p>商業授權合約下的Qt授權適用於專利/商業軟體的開發,在這種情況中,您可能不想與第三方分享任何原始碼或無法遵從GNU LGPL 2.1版或GNU GPL 3.0版的條款。</p><p>GNU LGPL 2.1版下的Qt授權適用於開發Qt應用程式(專利或開放原始碼),您必須遵從GNU LGPL 2.1版的條款與條件。</p><p>GNU GPL 3.0版下的Qt授權適用於開發Qt應用程式,在這種情況中,您希望將此應用程式搭配基於GNU GPL 3.0版開發的軟體一起使用,或您樂意遵從GNU GPL 3.0版的條款。</p><p>請參閱<a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a>,此頁面對於Qt授權會有概略的介紹。</p><p>Copyright (C) 2010 諾基亞公司及/或其子公司。</p><p>Qt是一項諾基亞產品。如需詳細資訊,請參閱<a href="http://qt.nokia.com/">qt.nokia.com</a>。</p> + + + About Qt + 關於 Qt + + + Help + 說明 + + + Show Details... + 顯示詳情... + + + Hide Details... + 隱藏詳情... + + + + QMultiInputContext + + Select IM + 選擇輸入法 + + + + QMultiInputContextPlugin + + Multiple input method switcher + 多重輸入法切換器 + + + Multiple input method switcher that uses the context menu of the text widgets + 使用文字元件中的內文選單的多重輸入法切換器 + + + + QNativeSocketEngine + + The remote host closed the connection + 遠端主機關閉了連線 + + + Network operation timed out + 網路操作逾時 + + + Out of resources + 資源不足 + + + Unsupported socket operation + 未支援的 socket 操作 + + + Protocol type not supported + 協定型態未支援 + + + Invalid socket descriptor + 不合法的 socket 描述子 + + + Network unreachable + 無法使用網路 + + + Permission denied + 權限不足 + + + Connection timed out + 連線逾時 + + + Connection refused + 連線被拒 + + + The bound address is already in use + 結合的位址已經在使用中 + + + The address is not available + 無法取得位址 + + + The address is protected + 此位址已被保護 + + + Unable to send a message + 無法送出訊息 + + + Unable to receive a message + 無法接收訊息 + + + Unable to write + 無法寫入 + + + Network error + 網路錯誤 + + + Another socket is already listening on the same port + 另一個 socket 已經在監聽同一個連接埠 + + + Unable to initialize non-blocking socket + 無法初始化非阻擋性 socket + + + Unable to initialize broadcast socket + 無法初始化廣播 socket + + + Attempt to use IPv6 socket on a platform with no IPv6 support + 試圖在沒有 IPv6 支援的平台上使用 IPv6 socket + + + Host unreachable + 無法連線到主機 + + + Datagram was too large to send + 資料過大無法送出 + + + Operation on non-socket + 對非 socket 操作 + + + Unknown error + 未知的錯誤 + + + The proxy type is invalid for this operation + 代理伺服器型態無法支援此操作 + + + + QNetworkAccessCacheBackend + + Error opening %1 + 開啟 %1 發生錯誤 + + + + QNetworkAccessDebugPipeBackend + + Write error writing to %1: %2 + 寫入%1時發生寫入錯誤:%2 + + + + QNetworkAccessFileBackend + + Request for opening non-local file %1 + 要求開啟非本地端檔案 %1 + + + Error opening %1: %2 + 開啟 %1 發生錯誤:%2 + + + Write error writing to %1: %2 + 寫入 %1 時發生錯誤:%2 + + + Cannot open %1: Path is a directory + 無法開啟 %1:此路徑是一個目錄 + + + Read error reading from %1: %2 + 從 %1 讀取錯誤:%2 + + + + QNetworkAccessFtpBackend + + No suitable proxy found + 找不到合適的代理伺服器 + + + Cannot open %1: is a directory + 無法開啟 %1:是一個目錄 + + + Logging in to %1 failed: authentication required + 登入 %1 失敗:需要認證 + + + Error while downloading %1: %2 + 下載 %1 時發生錯誤:%2 + + + Error while uploading %1: %2 + 上傳 %1 時發生錯誤:%2 + + + + QNetworkAccessHttpBackend + + No suitable proxy found + 找不到合適的代理伺服器 + + + + QNetworkReply + + Error downloading %1 - server replied: %2 + 下載 %1 時發生錯誤─伺服器回應:%2 + + + Protocol "%1" is unknown + 未知的協定 %1 + + + + QNetworkReplyImpl + + Operation canceled + 取消操作 + + + + QOCIDriver + + Unable to logon + 無法登入 + + + Unable to initialize + QOCIDriver + 無法初始化 + + + Unable to begin transaction + 無法開始事務 + + + Unable to commit transaction + 無法提交事務 + + + Unable to rollback transaction + 無法反轉事務 + + + + QOCIResult + + Unable to bind column for batch execute + 無法結合欄位以做批次執行 + + + Unable to execute batch statement + 無法執行批次敘述 + + + Unable to goto next + 無法跳到下一個 + + + Unable to alloc statement + 無法配置敘述 + + + Unable to prepare statement + 無法準備敘述 + + + Unable to get statement type + + + + Unable to bind value + 無法結合數值 + + + Unable to execute statement + 無法執行敘述 + + + + QODBCDriver + + Unable to connect + 無法連接 + + + Unable to disable autocommit + 無法關閉自動提交功能 + + + Unable to commit transaction + 無法提交事務 + + + Unable to rollback transaction + 無法反轉事務 + + + Unable to enable autocommit + 無法開啟自動提交功能 + + + Unable to connect - Driver doesn't support all functionality required + + + + + QODBCResult + + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration + QODBCResult::reset: 無法設定 SQL_CURSOR_STATIC 做為敘述屬性。請檢查您的 ODBC 驅動程式的設定 + + + Unable to execute statement + 無法執行敘述 + + + Unable to fetch next + 無法抓取下一筆 + + + Unable to prepare statement + 無法準備敘述 + + + Unable to bind variable + 無法結合變數 + + + Unable to fetch last + 無法抓取最後一筆 + + + Unable to fetch + 無法抓取 + + + Unable to fetch first + 無法抓取第一筆 + + + Unable to fetch previous + 無法抓取前一筆 + + + + QObject + + Invalid hostname + 主機名稱無效 + + + Operation not supported on %1 + 在 %1 上不支援此操作 + + + Invalid URI: %1 + 不合法的網址:%1 + + + Socket error on %1: %2 + %1 上發生 socket 錯誤:%2 + + + Remote host closed the connection prematurely on %1 + 於 %1 上遠端主機關閉了不正常的連線 + + + No host name given + 未指定主機 + + + + QPPDOptionsModel + + Name + 名稱 + + + Value + + + + + QPSQLDriver + + Unable to connect + 無法連線 + + + Could not begin transaction + 無法開始事務 + + + Could not commit transaction + 無法提交事務 + + + Could not rollback transaction + 無法反轉事務 + + + Unable to subscribe + 無法訂閱 + + + Unable to unsubscribe + 無法取消訂閱 + + + + QPSQLResult + + Unable to create query + 無法建立查詢 + + + Unable to prepare statement + 無法準備敘述 + + + + QPageSetupWidget + + Centimeters (cm) + 公分 + + + Millimeters (mm) + 公厘 + + + Inches (in) + 英吋 + + + Points (pt) + + + + Form + 表單 + + + Paper + 紙張 + + + Page size: + 紙張大小: + + + Width: + 寬度: + + + Height: + 高度: + + + Paper source: + 紙張來源: + + + Orientation + 方向 + + + Portrait + 縱向 + + + Landscape + 橫向 + + + Reverse landscape + 反序橫向 + + + Reverse portrait + 反序縱向 + + + Margins + 邊緣 + + + top margin + 上緣 + + + left margin + 左緣 + + + right margin + 右緣 + + + bottom margin + 下緣 + + + + QPluginLoader + + Unknown error + 未知的錯誤 + + + The plugin was not loaded. + 外掛程式未載入。 + + + + QPrintDialog + + locally connected + 本地連接 + + + Aliases: %1 + 別名:%1 + + + unknown + 未知 + + + OK + 確定 + + + Print all + 全部列印 + + + Print range + 列印範圍 + + + A0 (841 x 1189 mm) + A0 (841 x 1189 mm) + + + A1 (594 x 841 mm) + A1 (594 x 841 mm) + + + A2 (420 x 594 mm) + A2 (420 x 594 mm) + + + A3 (297 x 420 mm) + A3 (297 x 420 mm) + + + A5 (148 x 210 mm) + A5 (148 x 210 mm) + + + A6 (105 x 148 mm) + A6 (105 x 148 mm) + + + A7 (74 x 105 mm) + A7 (74 x 105 mm) + + + A8 (52 x 74 mm) + A8 (52 x 74 mm) + + + A9 (37 x 52 mm) + A9 (37 x 52 mm) + + + B0 (1000 x 1414 mm) + B0 (1000 x 1414 mm) + + + B1 (707 x 1000 mm) + B1 (707 x 1000 mm) + + + B2 (500 x 707 mm) + B2 (500 x 707 mm) + + + B3 (353 x 500 mm) + B3 (353 x 500 mm) + + + B4 (250 x 353 mm) + B4 (250 x 353 mm) + + + B6 (125 x 176 mm) + B6 (125 x 176 mm) + + + B7 (88 x 125 mm) + B7 (88 x 125 mm) + + + B8 (62 x 88 mm) + B8 (62 x 88 mm) + + + B9 (44 x 62 mm) + B9 (44 x 62 mm) + + + B10 (31 x 44 mm) + B10 (31 x 44 mm) + + + C5E (163 x 229 mm) + C5E (163 x 229 mm) + + + DLE (110 x 220 mm) + DLE (110 x 220 mm) + + + Folio (210 x 330 mm) + 對開 (210 x 330 mm) + + + Ledger (432 x 279 mm) + Ledger (432 x 279 mm) + + + Tabloid (279 x 432 mm) + Tabloid (279 x 432 mm) + + + US Common #10 Envelope (105 x 241 mm) + US 常用 10 號信封 (105x241 mm) + + + A4 (210 x 297 mm, 8.26 x 11.7 inches) + A4 (210 x 297 mm, 8.26 x 11.7 英吋) + + + B5 (176 x 250 mm, 6.93 x 9.84 inches) + B5 (176 x 250 mm, 6.93 x 9.84 英吋) + + + Executive (7.5 x 10 inches, 191 x 254 mm) + Executive (7.5 x 10 英吋, 191 x 254 mm) + + + Legal (8.5 x 14 inches, 216 x 356 mm) + Legal (8.5 x 14 英吋, 216 x 356 mm) + + + Letter (8.5 x 11 inches, 216 x 279 mm) + Letter (8.5 x 11 英吋, 216 x 279 mm) + + + Print selection + 列印選擇區 + + + Print + 列印 + + + Print To File ... + 列印到檔案... + + + File %1 is not writable. +Please choose a different file name. + 檔案 %1 無法寫入。 +請選擇其它檔名。 + + + %1 already exists. +Do you want to overwrite it? + %1 已存在。 +您要覆寫它嗎? + + + File exists + 檔案已存在 + + + <qt>Do you want to overwrite it?</qt> + <qt>您要覆寫它嗎?</qt> + + + %1 is a directory. +Please choose a different file name. + %1 是一個目錄。 +請選擇其他檔名。 + + + The 'From' value cannot be greater than the 'To' value. + 起始數值不能大於結束數值 + + + A0 + A0 + + + A1 + A1 + + + A2 + A2 + + + A3 + A3 + + + A4 + A4 + + + A5 + A5 + + + A6 + A6 + + + A7 + A7 + + + A8 + A8 + + + A9 + A9 + + + B0 + B0 + + + B1 + B1 + + + B2 + B2 + + + B3 + B3 + + + B4 + B4 + + + B5 + B5 + + + B6 + B6 + + + B7 + B7 + + + B8 + B8 + + + B9 + B9 + + + B10 + B10 + + + C5E + C5E + + + DLE + DLE + + + Executive + Executive + + + Folio + Folio + + + Ledger + Ledger + + + Legal + Legal + + + Letter + Letter + + + Tabloid + Tabloid + + + US Common #10 Envelope + US Common #10 Envelope + + + Custom + 自訂 + + + &Options >> + 操作 (&O) >> + + + &Options << + 操作 (&O) << + + + Print to File (PDF) + 列印到檔案(PDF) + + + Print to File (Postscript) + 列印到檔案(Postscript) + + + Local file + 本地端檔案 + + + Write %1 file + 寫入 %1 檔案 + + + &Print + 列印(&P) + + + + QPrintPreviewDialog + + %1% + %1% + + + Print Preview + 列印預覽 + + + Next page + 下一頁 + + + Previous page + 前一頁 + + + First page + 第一頁 + + + Last page + 最後一頁 + + + Fit width + 符合寬度 + + + Fit page + 符合頁面 + + + Zoom in + 放大 + + + Zoom out + 縮小 + + + Portrait + 縱向 + + + Landscape + 橫向 + + + Show single page + 顯示單一頁面 + + + Show facing pages + 顯示封面 + + + Show overview of all pages + 顯示所有頁面預覽 + + + Print + 列印 + + + Page setup + 列印設定 + + + Close + 關閉 + + + Export to PDF + 匯出到 PDF 檔 + + + Export to PostScript + 匯出到 PostScript 檔 + + + Page Setup + 頁面設定 + + + + QPrintPropertiesWidget + + Form + 表單 + + + Page + 頁面 + + + Advanced + 進階 + + + + QPrintSettingsOutput + + Form + 表單 + + + Copies + 份數 + + + Print range + 列印範圍 + + + Print all + 全部列印 + + + Pages from + 指定頁面:從 + + + to + + + + Selection + 選擇區 + + + Output Settings + 輸出設定 + + + Copies: + 份數: + + + Collate + 校對 + + + Reverse + 反向 + + + Options + 選項 + + + Color Mode + 顏色模式 + + + Color + 顏色 + + + Grayscale + 灰階 + + + Duplex Printing + 雙工列印 + + + None + + + + Long side + 長邊 + + + Short side + 短邊 + + + + QPrintWidget + + Form + 表單 + + + Printer + 印表機 + + + &Name: + 名稱(&N): + + + P&roperties + 屬性(&R) + + + Location: + 位置: + + + Preview + 預覽 + + + Type: + 型態: + + + Output &file: + 輸出檔案(&F): + + + ... + ... + + + + QProcess + + Could not open input redirection for reading + 無法開啟輸入導向以讀取 + + + Could not open output redirection for writing + 無法開啟輸出導向以寫入 + + + Resource error (fork failure): %1 + 資源錯誤(fork 失敗):%1 + + + Process operation timed out + 行程操作逾時 + + + Error reading from process + 從行程讀取時發生錯誤 + + + Error writing to process + 寫入行程時發生錯誤 + + + Process crashed + 行程已崩潰 + + + No program defined + 未定義程式 + + + Process failed to start: %1 + 處理序啟動失敗:%1 + + + + QProgressDialog + + Cancel + 取消 + + + + QPushButton + + Open + 開啟 + + + + QRadioButton + + Check + 勾選 + + + + QRegExp + + no error occurred + 沒有發生錯誤 + + + disabled feature used + 使用已關閉的功能 + + + bad char class syntax + 錯誤的字元類別語法 + + + bad lookahead syntax + 錯誤的 lookahead 語法 + + + bad repetition syntax + 錯誤的重覆語法 + + + invalid octal value + 不合法的八進位值 + + + missing left delim + 少了左方的區隔符 + + + unexpected end + 未預期遇到結尾 + + + met internal limit + 遇到內部限制 + + + invalid interval + 間隔無效 + + + invalid category + 類別無效 + + + + QSQLite2Driver + + Error opening database + 開啟資料庫時發生錯誤 + + + Unable to begin transaction + 無法開始事務 + + + Unable to commit transaction + 無法提交事務 + + + Unable to rollback transaction + 無法復原交易 + + + + QSQLite2Result + + Unable to fetch results + 無法抓取結果 + + + Unable to execute statement + 無法執行敘述 + + + + QSQLiteDriver + + Error opening database + 開啟資料庫發生錯誤 + + + Error closing database + 關閉資料庫發生錯誤 + + + Unable to begin transaction + 無法開始事務 + + + Unable to commit transaction + 無法提交事務 + + + Unable to rollback transaction + 無法反轉事務 + + + + QSQLiteResult + + Unable to fetch row + 無法抓取列 + + + Unable to execute statement + 無法執行敘述 + + + Unable to reset statement + 無法重置敘述 + + + Unable to bind parameters + 無法結合參數 + + + Parameter count mismatch + 參數數量不符合 + + + No query + 沒有查詢 + + + + QScriptBreakpointsModel + + ID + ID + + + Location + 位置 + + + Condition + 條件 + + + Ignore-count + 忽略次數 + + + Single-shot + 單次 + + + Hit-count + 叫用次數 + + + + QScriptBreakpointsWidget + + New + 新增 + + + Delete + 刪除 + + + + QScriptDebugger + + Go to Line + 跳至指定行 + + + Line: + 行: + + + Interrupt + 插斷 + + + Shift+F5 + Shift+F5 + + + Continue + 繼續 + + + F5 + F5 + + + Step Into + 逐步執行 + + + F11 + F11 + + + Step Over + 不進入函式 + + + F10 + F10 + + + Step Out + 跳出函式 + + + Shift+F11 + Shift+F11 + + + Run to Cursor + 執行至游標處 + + + Ctrl+F10 + Ctrl+F10 + + + Run to New Script + 執行至新指令碼 + + + Toggle Breakpoint + 切換中斷點 + + + F9 + F9 + + + Clear Debug Output + 清除偵錯輸出 + + + Clear Error Log + 清除錯誤記錄 + + + Clear Console + 清除主控台 + + + &Find in Script... + 在指令碼中尋找(&F)... + + + Ctrl+F + Ctrl+F + + + Find &Next + 尋找下一個(&N) + + + F3 + F3 + + + Find &Previous + 尋找上一個(&P) + + + Shift+F3 + Shift+F3 + + + Ctrl+G + Ctrl+G + + + Debug + 偵錯 + + + + QScriptDebuggerCodeFinderWidget + + Close + 關閉 + + + Previous + 上一個 + + + Next + 下一個 + + + Case Sensitive + 區分大小寫 + + + Whole words + 全字 + + + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;Search wrapped + <img src=":/qt/scripttools/debugging/images/wrap.png">&nbsp;搜尋已繞回 + + + + QScriptDebuggerLocalsModel + + Name + 名稱 + + + Value + + + + + QScriptDebuggerStackModel + + Level + 層級 + + + Name + 名稱 + + + Location + 位置 + + + + QScriptEdit + + Toggle Breakpoint + 切換中斷點 + + + Disable Breakpoint + 停用中斷點 + + + Enable Breakpoint + 啟用中斷點 + + + Breakpoint Condition: + 中斷點條件: + + + + QScriptEngineDebugger + + Loaded Scripts + 載入的指令碼 + + + Breakpoints + 中斷點 + + + Stack + 堆疊 + + + Locals + 區域變數 + + + Console + 主控台 + + + Debug Output + 偵錯輸出 + + + Error Log + 錯誤記錄 + + + Search + 搜尋 + + + View + 檢視 + + + Qt Script Debugger + Qt指令碼偵錯程式 + + + + QScriptNewBreakpointWidget + + Close + 關閉 + + + + QScrollBar + + Scroll here + 在此捲軸 + + + Left edge + 左邊緣 + + + Top + 頂端 + + + Right edge + 右邊緣 + + + Bottom + 底端 + + + Page left + 頁面左方 + + + Page up + 頁面上方 + + + Page right + 頁面右方 + + + Page down + 頁面下方 + + + Scroll left + 往左捲軸 + + + Scroll up + 往上捲軸 + + + Scroll right + 往右捲軸 + + + Scroll down + 往下捲軸 + + + Line up + 對上排列 + + + Position + 位置 + + + Line down + 對下排列 + + + + QSharedMemory + + %1: create size is less then 0 + %1:建立大小小於 0 + + + %1: unable to lock + %1:無法鎖定 + + + %1: unable to unlock + %1:無法解除鎖定 + + + %1: permission denied + %1:存取被拒 + + + %1: already exists + %1:已存在 + + + %1: doesn't exists + %1:不存在 + + + %1: out of resources + %1:資源不足 + + + %1: unknown error %2 + %1:未知的錯誤 %2 + + + %1: key is empty + %1:鍵值是空的 + + + %1: ftok failed + %1:ftok 失敗 + + + %1: unable to make key + %1:無法產生鍵值 + + + %1: doesn't exist + %1:不存在 + + + %1: UNIX key file doesn't exist + %1:UNIX金鑰檔不存在 + + + %1: system-imposed size restrictions + %1:系統大小限制 + + + %1: not attached + %1:未附加 + + + %1: invalid size + %1:不合法的大小 + + + %1: key error + %1:鍵值錯誤 + + + %1: size query failed + %1:大小查詢失敗 + + + %1: unable to set key on lock + %1:無法設定鍵值 + + + + QShortcut + + Space + 空白鍵 + + + Esc + Esc + + + Tab + Tab + + + Backtab + Backtab + + + Backspace + Backspace + + + Return + Return + + + Enter + Enter + + + Ins + Ins + + + Del + Del + + + Pause + Pause + + + Print + Print + + + SysReq + SysReq + + + Home + Home + + + End + End + + + Left + 左鍵 + + + Up + 上鍵 + + + Right + 右鍵 + + + Down + 下鍵 + + + PgUp + PgUp + + + PgDown + PgDown + + + CapsLock + 大寫鎖定 + + + NumLock + 數字鎖定 + + + ScrollLock + 捲軸鎖定 + + + Menu + 選單 + + + Help + 說明 + + + Back + 返回 + + + Forward + 往前 + + + Stop + 停止 + + + Refresh + 刷新 + + + Volume Down + 音量降低 + + + Volume Mute + 靜音 + + + Volume Up + 音量提高 + + + Bass Boost + 重低音 + + + Bass Up + Bass Up + + + Bass Down + Bass Down + + + Treble Up + Treble Up + + + Treble Down + Treble Down + + + Media Play + 媒體播放 + + + Media Stop + 媒體停止 + + + Media Previous + 媒體前一首 + + + Media Next + 媒體下一首 + + + Media Record + 媒體錄音 + + + Favorites + 我的最愛 + + + Search + 搜尋 + + + Standby + 待命 + + + Open URL + 開啟網址 + + + Launch Mail + 啟動郵件程式 + + + Launch Media + 啟動媒體程式 + + + Launch (0) + 啟動(0) + + + Launch (1) + 啟動(1) + + + Launch (2) + 啟動(2) + + + Launch (3) + 啟動(3) + + + Launch (4) + 啟動(4) + + + Launch (5) + 啟動(5) + + + Launch (6) + 啟動(6) + + + Launch (7) + 啟動(7) + + + Launch (8) + 啟動(8) + + + Launch (9) + 啟動(9) + + + Launch (A) + 啟動(A) + + + Launch (B) + 啟動(B) + + + Launch (C) + 啟動(C) + + + Launch (D) + 啟動(D) + + + Launch (E) + 啟動(E) + + + Launch (F) + 啟動(F) + + + Monitor Brightness Up + 螢幕亮度提高 + + + Monitor Brightness Down + 螢幕亮度降低 + + + Keyboard Light On/Off + 鍵盤燈光開/關 + + + Keyboard Brightness Up + 鍵盤亮度提高 + + + Keyboard Brightness Down + 鍵盤亮度降低 + + + Power Off + 關閉電源 + + + Wake Up + 喚醒 + + + Eject + 退出 + + + Screensaver + 螢幕保護 + + + WWW + WWW + + + Sleep + 睡眠 + + + LightBulb + 燈泡 + + + Shop + 商店 + + + History + 記錄 + + + Add Favorite + 加入我的最愛 + + + Hot Links + 熱門連結 + + + Adjust Brightness + 調整亮度 + + + Finance + 財務 + + + Community + 社群 + + + Audio Rewind + 音訊倒轉 + + + Back Forward + 上一個下一個 + + + Application Left + 應用程式靠左 + + + Application Right + 應用程式靠右 + + + Book + 書籍 + + + CD + CD + + + Calculator + 計算機 + + + Clear + 清除 + + + Clear Grab + 清除抓取內容 + + + Close + 關閉 + + + Copy + 複製 + + + Cut + 剪下 + + + Display + 顯示 + + + DOS + DOS + + + Documents + 文件 + + + Spreadsheet + 試算表 + + + Browser + 瀏覽器 + + + Game + 遊戲 + + + Go + + + + iTouch + iTouch + + + Logoff + 登出 + + + Market + 市場 + + + Meeting + 會議 + + + Keyboard Menu + 鍵盤功能表 + + + Menu PB + 功能表PB + + + My Sites + 我的網站 + + + News + 新聞 + + + Home Office + Home Office + + + Option + 選項 + + + Paste + 貼上 + + + Phone + 手機 + + + Reply + 回覆 + + + Reload + 重新載入 + + + Rotate Windows + 旋轉視窗 + + + Rotation PB + 循環PB + + + Rotation KB + 循環KB + + + Save + 儲存 + + + Send + 傳送 + + + Spellchecker + 拼字檢查 + + + Split Screen + 分割畫面 + + + Support + 支援 + + + Task Panel + 工作面板 + + + Terminal + 終端機 + + + Tools + 工具 + + + Travel + 旅行 + + + Video + 視訊 + + + Word Processor + 文字處理器 + + + XFer + XFer + + + Zoom In + 放大 + + + Zoom Out + 縮小 + + + Away + 離開 + + + Messenger + Messenger + + + WebCam + 網路攝影機 + + + Mail Forward + 郵件轉寄 + + + Pictures + 圖片 + + + Music + 音樂 + + + Battery + 電池 + + + Bluetooth + 藍牙 + + + Wireless + 無線 + + + Ultra Wide Band + 超寬頻 + + + Audio Forward + 音訊轉送 + + + Audio Repeat + 音訊重複 + + + Audio Random Play + 音訊機播放 + + + Subtitle + 副標題 + + + Audio Cycle Track + 音訊循環軌跡 + + + Time + 時間 + + + View + 檢視 + + + Top Menu + 上層功能表 + + + Suspend + 暫止 + + + Hibernate + 休眠 + + + Print Screen + 列印螢幕 + + + Page Up + 往上一頁 + + + Page Down + 往下一頁 + + + Caps Lock + 大寫鎖定 + + + Num Lock + 數字鎖定 + + + Number Lock + 數字鎖定 + + + Scroll Lock + 捲軸鎖定 + + + Insert + 插入 + + + Delete + 刪除 + + + Escape + Escape + + + System Request + 系統要求 SysRq + + + Select + 選擇 + + + Yes + + + + No + + + + Context1 + 內文1 + + + Context2 + 內文2 + + + Context3 + 內文3 + + + Context4 + 內文4 + + + Call + 呼叫 + + + Hangup + 掛斷 + + + Flip + 反轉 + + + Ctrl + Ctrl + + + Shift + Shift + + + Alt + Alt + + + Meta + Meta + + + + + + + + + F%1 + F%1 + + + Home Page + 首頁 + + + + QSlider + + Page left + 頁面左方 + + + Page up + 頁面上方 + + + Position + 位置 + + + Page right + 頁面右方 + + + Page down + 頁面下方 + + + + QSocks5SocketEngine + + Connection to proxy refused + 代理伺服器連線被拒 + + + Connection to proxy closed prematurely + 代理伺服器連線已不正常關閉 + + + Proxy host not found + 找不到代理伺服器 + + + Connection to proxy timed out + 代理伺服器連線逾時 + + + Proxy authentication failed + 代理伺服器認證失敗 + + + Proxy authentication failed: %1 + 代理伺服器認證失敗:%1 + + + SOCKS version 5 protocol error + SOCKS 5 的協定錯誤 + + + General SOCKSv5 server failure + 一般的 SOCKSv5 伺服器錯誤 + + + Connection not allowed by SOCKSv5 server + 連線未被 SOCKSv5 伺服器允許 + + + TTL expired + TTL 逾時 + + + SOCKSv5 command not supported + SOCKSv5 指令未被支援 + + + Address type not supported + 位址型態未被支援 + + + Unknown SOCKSv5 proxy error code 0x%1 + 未知的 SOCKSv5 代理伺服器錯誤代碼 0x%1 + + + Network operation timed out + 網路操作逾時 + + + + QSoftKeyManager + + Ok + 確定 + + + Select + 選取 + + + Done + 完成 + + + Options + 選項 + + + Cancel + 取消 + + + Exit + 退出 + + + + QSpinBox + + More + 更多 + + + Less + 較少 + + + + QSql + + Delete + 刪除 + + + Delete this record? + 要刪除這筆紀錄嗎? + + + Yes + + + + No + + + + Insert + 插入 + + + Update + 更新 + + + Save edits? + 要儲存編輯過的內容嗎? + + + Cancel + 取消 + + + Confirm + 確認 + + + Cancel your edits? + 要取消編輯嗎? + + + + QSslSocket + + Unable to write data: %1 + 無法寫入資料:%1 + + + Unable to decrypt data: %1 + 無法解密資料:%1 + + + Error while reading: %1 + 讀取時發生錯誤:%1 + + + Error during SSL handshake: %1 + SSL 同步時發生錯誤:%1 + + + Error creating SSL context (%1) + 建立 SSL 內文時發生錯誤(%1) + + + Invalid or empty cipher list (%1) + 不合法或空白的加密清單(%1) + + + Private key does not certify public key, %1 + 私密金鑰無法認證公開金鑰,%1 + + + Error creating SSL session, %1 + 建立 SSL 工作階段時發生錯誤:%1 + + + Error creating SSL session: %1 + 建立 SSL 工作階段時發生錯誤:%1 + + + Cannot provide a certificate with no key, %1 + 沒有金鑰無法提供憑證:%1 + + + Error loading local certificate, %1 + 載入本地憑證時發生錯誤:%1 + + + Error loading private key, %1 + 載入私鑰時發生錯誤:%1 + + + No error + 沒有錯誤 + + + The issuer certificate could not be found + 找不到發行者憑證 + + + The certificate signature could not be decrypted + 無法解密憑證簽名 + + + The public key in the certificate could not be read + 憑證中的公開金鑰無法讀取 + + + The signature of the certificate is invalid + 憑證的簽名無效 + + + The certificate is not yet valid + 憑證尚未生效 + + + The certificate has expired + 憑證已逾期 + + + The certificate's notBefore field contains an invalid time + 憑證的notBefore欄位包含無效的時間 + + + The certificate's notAfter field contains an invalid time + 憑證的notAfter欄位包含無效的時間 + + + The certificate is self-signed, and untrusted + 憑證是自我簽署的,而且不受信任 + + + The root certificate of the certificate chain is self-signed, and untrusted + 憑證鏈的根憑證是自我簽署的,而且不受信任 + + + The issuer certificate of a locally looked up certificate could not be found + 找不到本機查詢憑證的發行者憑證 + + + No certificates could be verified + 沒有可確認的憑證 + + + One of the CA certificates is invalid + CA憑證的其中之一無效 + + + The basicConstraints path length parameter has been exceeded + basicConstraints路徑長度參數已超出限制 + + + The supplied certificate is unsuitable for this purpose + 提供的憑證不適用於此目的 + + + The root CA certificate is not trusted for this purpose + 根CA憑證在此目的中不受信任 + + + The root CA certificate is marked to reject the specified purpose + 根CA憑證已註記拒絕該特定目的 + + + The current candidate issuer certificate was rejected because its subject name did not match the issuer name of the current certificate + 目前候選發行者的憑證已遭拒絕,因為其主旨名稱和目前憑證的發行者名稱不符 + + + The current candidate issuer certificate was rejected because its issuer name and serial number was present and did not match the authority key identifier of the current certificate + 目前候選發行者的憑證已遭拒絕,因為其發行者名稱及提出的序號和目前憑證的授權單位金鑰識別元不符 + + + The peer did not present any certificate + 對等節點未提出任何憑證 + + + The host name did not match any of the valid hosts for this certificate + 主機名稱不符合此憑證任何有效的主機 + + + Unknown error + 不明的錯誤 + + + + QStateMachine + + Missing initial state in compound state '%1' + 在複合狀態"%1"中遺失初始狀態 + + + Missing default state in history state '%1' + 在記錄狀態"%1"中遺失預設狀態 + + + No common ancestor for targets and source of transition from state '%1' + 從狀態"%1"的轉換中,目標和來源沒有共同的上階 + + + Unknown error + 不明的錯誤 + + + + QSystemSemaphore + + %1: does not exist + %1:不存在 + + + %1: out of resources + %1:資源不足 + + + %1: permission denied + %1:存取被拒 + + + %1: already exists + %1:已存在 + + + %1: unknown error %2 + %1:未知的錯誤 %2 + + + + QTDSDriver + + Unable to open connection + 無法開啟連線 + + + Unable to use database + 無法使用資料庫 + + + + QTabBar + + Scroll Left + 往左捲軸 + + + Scroll Right + 往右捲軸 + + + + QTcpServer + + Operation on socket is not supported + Socket 的操作未被支援 + + + + QTextControl + + &Undo + 復原(&U) + + + &Redo + 重做(&R) + + + Cu&t + 剪下(&T) + + + &Copy + 複製(&C) + + + Copy &Link Location + 複製連結位址(&L) + + + &Paste + 貼上(&P) + + + Delete + 刪除 + + + Select All + 全部選擇 + + + + QToolButton + + Press + 按下 + + + Open + 開啟 + + + + QUdpSocket + + This platform does not support IPv6 + 此平台不支援 IPv6 + + + + QUndoGroup + + Undo + 復原 + + + Redo + 重做 + + + + QUndoModel + + <empty> + <空白> + + + + QUndoStack + + Undo + 復原 + + + Redo + 重做 + + + + QUnicodeControlCharacterMenu + + LRM Left-to-right mark + LRM 左到右標記 + + + RLM Right-to-left mark + RLM 右到左標記 + + + ZWJ Zero width joiner + ZWJ 零寬度連接器 + + + ZWNJ Zero width non-joiner + ZWNJ 零寬度非連接器 + + + ZWSP Zero width space + ZWSP 零寬度空白 + + + LRE Start of left-to-right embedding + LRE 左到右嵌入起點 + + + RLE Start of right-to-left embedding + RLE 右到左嵌入起點 + + + LRO Start of left-to-right override + LRO 左到右覆寫起點 + + + RLO Start of right-to-left override + RLO 右到左覆寫起點 + + + PDF Pop directional formatting + PDF 彈出方向格式 + + + Insert Unicode control character + 插入萬國碼控制字元 + + + + QWebFrame + + Request cancelled + 請求已取消 + + + Request blocked + 請求已被阻擋 + + + Cannot show URL + 無法顯示網址 + + + Frame load interrupted by policy change + 框架載入因為原則變更而中斷 + + + Cannot show mimetype + 無法顯示 MIME 型態 + + + File does not exist + 檔案不存在 + + + + QWebPage + + Submit + default label for Submit buttons in forms on web pages + + + + Submit + Submit (input element) alt text for <input> elements with no alt, title, or value + + + + Reset + default label for Reset buttons in forms on web pages + 重置 + + + Choose File + title for file button used in HTML forms + 選擇檔案 + + + No file selected + text to display in file button used in HTML forms when no file is selected + 未選取任何檔案 + + + Open in New Window + Open in New Window context menu item + 在新視窗開啟 + + + Save Link... + Download Linked File context menu item + 儲存連結... + + + Copy Link + Copy Link context menu item + 複製連結 + + + Open Image + Open Image in New Window context menu item + 開啟影像 + + + Save Image + Download Image context menu item + 儲存影像 + + + Copy Image + Copy Link context menu item + 複製影像 + + + Open Frame + Open Frame in New Window context menu item + 開啟框架 + + + Copy + Copy context menu item + 複製 + + + Go Back + Back context menu item + 往回 + + + Go Forward + Forward context menu item + 往前 + + + Stop + Stop context menu item + + + + Reload + Reload context menu item + 重新載入 + + + Cut + Cut context menu item + 剪下 + + + Paste + Paste context menu item + 貼上 + + + No Guesses Found + No Guesses Found context menu item + 找不到可能的內容 + + + Ignore + Ignore Spelling context menu item + 忽略 + + + Add To Dictionary + Learn Spelling context menu item + 新增到字典 + + + Search The Web + Search The Web context menu item + 搜尋站台 + + + Look Up In Dictionary + Look Up in Dictionary context menu item + 在字典裡搜尋 + + + Open Link + Open Link context menu item + 開啟連結 + + + Ignore + Ignore Grammar context menu item + 忽略 + + + Spelling + Spelling and Grammar context sub-menu item + + + + Show Spelling and Grammar + menu item title + + + + Hide Spelling and Grammar + menu item title + 隱藏拼字與文法 + + + Check Spelling + Check spelling context menu item + 檢查拼字 + + + Check Spelling While Typing + Check spelling while typing context menu item + 打字時立即檢查拼字 + + + Check Grammar With Spelling + Check grammar with spelling context menu item + 檢查拼字與文法 + + + Fonts + Font context sub-menu item + 字型 + + + Bold + Bold context menu item + 粗體 + + + Italic + Italic context menu item + 斜體 + + + Underline + Underline context menu item + + + + Outline + Outline context menu item + 外框線 + + + Direction + Writing direction context sub-menu item + 方向 + + + Text Direction + Text direction context sub-menu item + + + + Default + Default writing direction context menu item + 預設 + + + Left to Right + Left to Right context menu item + 從左至右 + + + Right to Left + Right to Left context menu item + 從右至左 + + + Loading... + Media controller status message when the media is loading + 載入中... + + + Live Broadcast + Media controller status message when watching a live broadcast + 即時廣播 + + + Audio Element + Media controller element + 音訊元素 + + + Video Element + Media controller element + 視訊元素 + + + Mute Button + Media controller element + 靜音按鈕 + + + Unmute Button + Media controller element + 取消靜音按鈕 + + + Play Button + Media controller element + 播放按鈕 + + + Pause Button + Media controller element + 暫停按鈕 + + + Slider + Media controller element + 滑桿 + + + Slider Thumb + Media controller element + 滑桿縮圖 + + + Rewind Button + Media controller element + 倒轉按鈕 + + + Return to Real-time Button + Media controller element + 回復成即時按鈕 + + + Elapsed Time + Media controller element + 經過時間 + + + Remaining Time + Media controller element + 剩餘時間 + + + Status Display + Media controller element + 狀態顯示 + + + Fullscreen Button + Media controller element + 全螢幕按鈕 + + + Seek Forward Button + Media controller element + 往前搜尋按鈕 + + + Seek Back Button + Media controller element + 往回搜尋按鈕 + + + Audio element playback controls and status display + Media controller element + 音訊元素播放控制和狀態顯示 + + + Video element playback controls and status display + Media controller element + 視訊元素播放控制和狀態顯示 + + + Mute audio tracks + Media controller element + 音軌靜音 + + + Unmute audio tracks + Media controller element + 音軌取消靜音 + + + Begin playback + Media controller element + 開始播放 + + + Pause playback + Media controller element + 暫停播放 + + + Movie time scrubber + Media controller element + 影片時間清除器 + + + Movie time scrubber thumb + Media controller element + 影片時間清除器縮圖 + + + Rewind movie + Media controller element + 倒轉影片 + + + Return streaming movie to real-time + Media controller element + 串流影片回復成即時播放 + + + Current movie time + Media controller element + 目前的影片時間 + + + Remaining movie time + Media controller element + 剩餘的影片時間 + + + Current movie status + Media controller element + 目前的影片狀態 + + + Play movie in full-screen mode + Media controller element + 以全螢幕模式播放影片 + + + Seek quickly back + Media controller element + 快速往回搜尋 + + + Seek quickly forward + Media controller element + 快速往前搜尋 + + + Indefinite time + Media time description + 不限定時間 + + + %1 days %2 hours %3 minutes %4 seconds + Media time description + %1天%2小時%3分鐘%4秒鐘 + + + %1 hours %2 minutes %3 seconds + Media time description + %1小時%2分鐘%3秒鐘 + + + %1 minutes %2 seconds + Media time description + %1分鐘%2秒鐘 + + + %1 seconds + Media time description + %1秒鐘 + + + Inspect + Inspect Element context menu item + 查驗 + + + No recent searches + Label for only item in menu that appears when clicking on the search field image, when no searches have been performed + 沒有最近的搜尋 + + + Recent searches + label for first item in the menu that appears when clicking on the search field image, used as embedded menu title + 最近的搜尋 + + + Clear recent searches + menu item in Recent Searches menu that empties menu's contents + 清除最近的搜尋 + + + Unknown + Unknown filesize FTP directory listing item + + + + Web Inspector - %2 + + + + %1 (%2x%3 pixels) + Title string for images + %1(%2x%3 像素) + + + Bad HTTP request + 不良的 HTTP 請求 + + + This is a searchable index. Enter search keywords: + text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' + + + + Scroll here + 在此捲軸 + + + Left edge + 左邊緣 + + + Top + + + + Right edge + 右邊緣 + + + Bottom + 底端 + + + Page left + 頁面左方 + + + Page up + 頁面上方 + + + Page right + 頁面右方 + + + Page down + 頁面下方 + + + Scroll left + 往左捲軸 + + + Scroll up + 往上捲軸 + + + Scroll right + 往右捲軸 + + + Scroll down + 往下捲軸 + + + %n file(s) + number of chosen file + + %n 個檔案 + + + + JavaScript Alert - %1 + JavaScript 警告 ─ %1 + + + JavaScript Confirm - %1 + JavaScript 確認 ─ %1 + + + JavaScript Prompt - %1 + JavaScript 提示 ─ %1 + + + JavaScript Problem - %1 + JavaScript問題 - %1 + + + The script on this page appears to have a problem. Do you want to stop the script? + 此頁面上的指令碼似乎有問題。是否要停止指令碼? + + + Move the cursor to the next character + 移動游標到下一個字元 + + + Move the cursor to the previous character + 移動游標到前一個字元 + + + Move the cursor to the next word + 移動游標到下一個單字 + + + Move the cursor to the previous word + 移動游標到前一個單字 + + + Move the cursor to the next line + 移動游標到下一行 + + + Move the cursor to the previous line + 移動游標到前一行 + + + Move the cursor to the start of the line + 移動游標到這一行的起頭 + + + Move the cursor to the end of the line + 移動游標到這一行的結尾 + + + Move the cursor to the start of the block + 移動游標到這一個區塊的起頭 + + + Move the cursor to the end of the block + 移動游標到這一個區塊的結尾 + + + Move the cursor to the start of the document + 移動游標到這一個文件的起頭 + + + Move the cursor to the end of the document + 移動游標到這一個文件的結尾 + + + Select all + 全選 + + + Select to the next character + + + + Select to the previous character + + + + Select to the next word + + + + Select to the previous word + + + + Select to the next line + + + + Select to the previous line + + + + Select to the start of the line + + + + Select to the end of the line + + + + Select to the start of the block + + + + Select to the end of the block + + + + Select to the start of the document + + + + Select to the end of the document + + + + Delete to the start of the word + 刪除到此單字的起頭 + + + Delete to the end of the word + 刪除到此單字的結尾 + + + Insert a new paragraph + 插入新段落 + + + Insert a new line + 插入新行 + + + Paste and Match Style + 貼上並符合樣式 + + + Remove formatting + 移除格式設定 + + + Strikethrough + 刪除線 + + + Subscript + 下標 + + + Superscript + 上標 + + + Insert Bulleted List + 插入項目符號清單 + + + Insert Numbered List + 插入編號清單 + + + Indent + 縮排 + + + Outdent + 凸排 + + + Center + 置中 + + + Justify + 左右對齊 + + + Align Left + 靠左對齊 + + + Align Right + 靠右對齊 + + + + QWhatsThisAction + + What's This? + + + + + QWidget + + * + + + + + QWizard + + Cancel + + + + Help + + + + < &Back + + + + &Finish + + + + &Help + + + + Go Back + + + + Continue + + + + Commit + + + + Done + + + + &Next + + + + &Next > + + + + + QWorkspace + + &Restore + + + + &Move + + + + &Size + + + + Mi&nimize + + + + Ma&ximize + + + + &Close + + + + Stay on &Top + + + + Minimize + + + + Restore Down + + + + Close + + + + Sh&ade + + + + %1 - [%2] + + + + &Unshade + + + + + QXml + + no error occurred + + + + error triggered by consumer + + + + unexpected end of file + + + + more than one document type definition + + + + error occurred while parsing element + + + + tag mismatch + + + + error occurred while parsing content + + + + unexpected character + + + + invalid name for processing instruction + + + + version expected while reading the XML declaration + + + + wrong value for standalone declaration + + + + error occurred while parsing document type definition + + + + letter is expected + + + + error occurred while parsing comment + + + + error occurred while parsing reference + + + + internal general entity reference not allowed in DTD + + + + external parsed general entity reference not allowed in attribute value + + + + external parsed general entity reference not allowed in DTD + + + + unparsed entity reference in wrong context + + + + recursive entities + + + + error in the text declaration of an external entity + + + + encoding declaration or standalone declaration expected while reading the XML declaration + + + + standalone declaration expected while reading the XML declaration + + + + + QXmlPatternistCLI + + Warning in %1, at line %2, column %3: %4 + %1中的警告,位於行%2,欄%3:%4 + + + Warning in %1: %2 + %1中的警告:%2 + + + Unknown location + 不明的位置 + + + Error %1 in %2, at line %3, column %4: %5 + 在%2發生%1錯誤,位於行%3,欄%4:%5 + + + Error %1 in %2: %3 + 在%2發生%1錯誤:%3 + + + + QXmlStream + + Extra content at end of document. + + + + Invalid entity value. + + + + Invalid XML character. + + + + Sequence ']]>' not allowed in content. + + + + Namespace prefix '%1' not declared + + + + Attribute redefined. + + + + Unexpected character '%1' in public id literal. + + + + Invalid XML version string. + + + + Unsupported XML version. + + + + %1 is an invalid encoding name. + + + + Encoding %1 is unsupported + + + + Standalone accepts only yes or no. + + + + Invalid attribute in XML declaration. + + + + Premature end of document. + + + + Invalid document. + + + + Expected + + + + , but got ' + + + + Unexpected ' + + + + Expected character data. + + + + Recursive entity detected. + + + + Start tag expected. + + + + XML declaration not at start of document. + + + + NDATA in parameter entity declaration. + + + + %1 is an invalid processing instruction name. + + + + Invalid processing instruction name. + + + + Illegal namespace declaration. + + + + Invalid XML name. + + + + Opening and ending tag mismatch. + + + + Reference to unparsed entity '%1'. + + + + Entity '%1' not declared. + + + + Reference to external entity '%1' in attribute value. + + + + Invalid character reference. + + + + Encountered incorrectly encoded content. + + + + The standalone pseudo attribute must appear after the encoding. + + + + %1 is an invalid PUBLIC identifier. + + + + + QtXmlPatterns + + At least one component must be present. + 必須表達至少一個組件。 + + + %1 is not a valid value of type %2. + %1 不是合法的 %2 型態的值。 + + + When casting to %1 from %2, the source value cannot be %3. + 從 %2 轉換型態為 %1 的時候,來源數值不能是 %3。 + + + Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values. + 實際布林值(Effective Boolean)無法用在兩個或兩個以上的原數值(atomic value)的計算。 + + + The data of a processing instruction cannot contain the string %1 + 處理指令的資料不能包含字串 %1 + + + %1 is an invalid %2 + %1 是不合法的 %2 + + + %1 is not a valid XML 1.0 character. + %1 不是合法的 XML 1.0 字元。 + + + %1 was called. + %1 已被呼叫。 + + + In the replacement string, %1 must be followed by at least one digit when not escaped. + 在取代字串中,在未脫逸的情形下 %1 必須至少跟著一位數字。 + + + In the replacement string, %1 can only be used to escape itself or %2, not %3 + 在取代字串中,%1 只能用於自身或 %2 的脫逸,而非 %3。 + + + %1 matches newline characters + %1 符合了換行字元 + + + Matches are case insensitive + 比對為區分大小寫 + + + %1 is an invalid regular expression pattern: %2 + %1 是不合法的正規表示式樣式:%2 + + + It will not be possible to retrieve %1. + 無法取得 %1。 + + + The default collection is undefined + 預設的收藏未定義 + + + %1 cannot be retrieved + %1 無法取得 + + + The item %1 did not match the required type %2. + 項目 %1 未符合需要的型態 %2。 + + + %1 is an unknown schema type. + %1 是未知的機制型態。 + + + A template with name %1 has already been declared. + + + + Only one %1 declaration can occur in the query prolog. + 只有一個 %1 宣告可以在查詢中。 + + + The initialization of variable %1 depends on itself + 變數 %1 的初始化與自身相依。 + + + The variable %1 is unused + 變數 %1 未使用 + + + Version %1 is not supported. The supported XQuery version is 1.0. + 版本 %1 未支援。支援的 XQuery 版本為 1.0。 + + + No function with signature %1 is available + 沒有簽章為 %1 的函式可使用 + + + It is not possible to redeclare prefix %1. + 無法重宣告前置字串 %1。 + + + Prefix %1 is already declared in the prolog. + 前置字串 %1 已在 prolog 中宣告。 + + + The name of an option must have a prefix. There is no default namespace for options. + 選項名稱必須有前置字串。沒有選項的預設命名空間。 + + + The Schema Import feature is not supported, and therefore %1 declarations cannot occur. + 機制匯入功能未支援,因此有 %1 個宣告無法達成。 + + + The target namespace of a %1 cannot be empty. + %1 的目標命名空間不能是空的。 + + + The module import feature is not supported + 模組匯入功能未支援。 + + + The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2 + 在函式模組中的使用者定義函式的命名空間必須與模組的命名空間相同。也就是,應該為 %1 而不是 %2。 + + + A function already exists with the signature %1. + 已經有簽章為 %1 的函式存在。 + + + No external functions are supported. All supported functions can be used directly, without first declaring them as external + 未支援外部函式。所有支援的含式可以直接使用而不需要先宣告為外部函式。 + + + The %1-axis is unsupported in XQuery + XQuery 中未支援 %1 軸 + + + The namespace URI cannot be the empty string when binding to a prefix, %1. + 要與前置字串 %1 結合的命名空間網址不能是空字串。 + + + %1 is an invalid namespace URI. + %1 是不合法的命名空間網址。 + + + It is not possible to bind to the prefix %1 + 無法與前置字串 %1 結合。 + + + Two namespace declaration attributes have the same name: %1. + 有兩個命名空間宣告的屬性有相同的名稱:%1 + + + The namespace URI must be a constant and cannot use enclosed expressions. + 命名空間網址必須是常數,並且不能使用封閉敘述。 + + + %1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported. + %1 不是範圍內屬性宣告。注意機制匯入功能未支援。 + + + empty + 空白 + + + zero or one + 0 或 1 個 + + + exactly one + 剛好一個 + + + one or more + 一個以上 + + + zero or more + 0 個以上 + + + The focus is undefined. + 焦點未定義。 + + + An attribute by name %1 has already been created. + 名為 %1 的屬性已被建立。 + + + Network timeout. + 網路逾時。 + + + Element %1 can't be serialized because it appears outside the document element. + 元素 %1 無法序列化,因為似乎是在文件元素之外。 + + + Year %1 is invalid because it begins with %2. + 年份 %1 不合法,因為是從 %2 開始的。 + + + Day %1 is outside the range %2..%3. + 日期 %1 已超出 %2 到 %3 的範圍。 + + + Month %1 is outside the range %2..%3. + 月份 %1 已超出 %2 到 %3 的範圍。 + + + Overflow: Can't represent date %1. + 溢位:無法表示日期 %1。 + + + Day %1 is invalid for month %2. + 月份 %2 中沒有日期 %1。 + + + Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; + 時間 24:%1:%2.%3 不合法。小時為 24 則分、秒與毫秒都必須是 0。 + + + + Time %1:%2:%3.%4 is invalid. + 時間 %1:%2:%3.%4 不合法。 + + + Overflow: Date can't be represented. + 溢位:無法表示日期。 + + + At least one time component must appear after the %1-delimiter. + 在分隔符 %1 後必須至少有一個時間組件。 + + + Dividing a value of type %1 by %2 (not-a-number) is not allowed. + 將型態 %1 除以 %2(非數值)是不允許的。 + + + Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed. + 將型態 %1 除以 %2 或 %3(正或負零)是不允許的。 + + + Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed. + 將型態 %1 乘以 %2 或 %3(正或負無限大)是不允許的。 + + + A value of type %1 cannot have an Effective Boolean Value. + 型態 %1 不能有實際布林值。 + + + Value %1 of type %2 exceeds maximum (%3). + 型態 %2 的數值 %1 已超過最大值(%3)。 + + + Value %1 of type %2 is below minimum (%3). + 型態 %2 的數值 %1 已低過最小值(%3)。 + + + A value of type %1 must contain an even number of digits. The value %2 does not. + 型態 %1 的值必須包含偶數個數字。數值 %2 未符合此條件。 + + + %1 is not valid as a value of type %2. + %1 不是合法的 %2 型態的值。 + + + Operator %1 cannot be used on type %2. + 操作元 %1 不能用於型態 %2。 + + + Operator %1 cannot be used on atomic values of type %2 and %3. + 操作元 %1 不能用於型態 %2 與 %3 的原數值。 + + + The namespace URI in the name for a computed attribute cannot be %1. + 在已計算屬性的名稱的命名空間網址不能是 %1。 + + + The name for a computed attribute cannot have the namespace URI %1 with the local name %2. + 在已計算屬性的名稱不能同時有命名空間網址 %1 與本地端名稱 %2。 + + + Type error in cast, expected %1, received %2. + 轉換型態錯誤,應為 %1 但接收到 %2。 + + + When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed. + 轉換為型態 %1 或其衍生型態時,來源數值必須是相同型態,或者是字串。型態 %2 是不被允許的。 + + + A comment cannot contain %1 + 註解不能包含 %1 + + + A comment cannot end with a %1. + 註解不能以 %1 做結尾 + + + An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place. + 屬性點不能做為文件點的子節點。因此,屬性 %1 的位置不合適。 + + + A library module cannot be evaluated directly. It must be imported from a main module. + 不能直接計算函式模組。必須要從主模組匯入。 + + + No template by name %1 exists. + 沒有名為 %1 的樣本存在。 + + + A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type. + 型態 %1 的值不能是謂詞(predicate)。謂詞必須是數值型態,或是實際布林值。 + + + A positional predicate must evaluate to a single numeric value. + 位置謂詞必須能計算出單一的數值。 + + + The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, %2 is invalid. + 處理指令的目標名稱不能是任何大小寫組合的 %1。因此,%2 是不合法的值。 + + + %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. + %1 不是一個合法的處理指令的目標名稱。必須是 %2 的值,例如 %3。 + + + The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. + 路徑的最後一步必須是節點或原值,而不能在兩者之間。 + + + No namespace binding exists for the prefix %1 + 前置字串 %1 沒有結合命名空間 + + + No namespace binding exists for the prefix %1 in %2 + 在 %2 的前置字串 %1 沒有結合命名空間 + + + The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration. + 呼叫 %1 的第一個參數不能是 %2 型態。必須是數值型態,xs.yearMonthDuration 或 xs.dayTimeDuration。 + + + The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + 呼叫 %1 的第一個參數不能是 %2 型態。必須是 %3、%4 或 %5 型態。 + + + The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + 呼叫 %1 的第二個參數不能是 %2 型態。必須是 %3、%4 或 %5 型態。 + + + If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same. + 如果兩個值都有區域位移,則必須是相同的區域位移。%1 與 %2 並不相同。 + + + %1 must be followed by %2 or %3, not at the end of the replacement string. + %1 後面必須跟著 %2 或 %3,而非取代字串的結尾。 + + + %1 and %2 match the start and end of a line. + %1 與 %2 符合了一行的開始與結尾。 + + + Whitespace characters are removed, except when they appear in character classes + 空白字元已移除,除非它們出現在字元類別 + + + %1 is an invalid flag for regular expressions. Valid flags are: + %1 是正規表示式中不合法的旗標。合法的旗標有: + + + If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified. + 如果第一個參數是空序列,或是長度為 0 的字串(沒有命名空間),則無法指定前置字串。但是您指定了 %1。 + + + The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization). + 未支援常態化表單 %1。支援的表單有 %2、%3、%4、%5,以及無(也就是空字串,未常態化)。 + + + A zone offset must be in the range %1..%2 inclusive. %3 is out of range. + 區域位移必須是在 %1 到 %2 範圍之內。%3 已超出範圍。 + + + Required cardinality is %1; got cardinality %2. + 需要的基數為 %1;得到的是 %2。 + + + The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2. + 編碼 %1 不合法。必須只能包含拉丁字元,不含空白,並且要符合正規表示式 %2。 + + + The keyword %1 cannot occur with any other mode name. + 關鍵字 %1 不能與任何其它模式名稱一起存在。 + + + No variable with name %1 exists + + + + The value of attribute %1 must be of type %2, which %3 isn't. + + + + The prefix %1 cannot be bound. By default, it is already bound to the namespace %2. + + + + A variable with name %1 has already been declared. + + + + No value is available for the external variable with name %1. + + + + A stylesheet function must have a prefixed name. + 樣式表函式必須有前置名稱。 + + + The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. + 命名空間 %1 已被保留,因此使用者定義函式不能使用它。請試試預定義前置字串 %2。 + + + An argument with name %1 has already been declared. Every argument name must be unique. + + + + When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. + 當函式 %1 用於樣式比對時,參數必須是變數參考或字串。 + + + In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching. + 在 XSL-T 樣式內,函式 %1 的第一個參數必須是字串,以便用於比對。 + + + In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching. + 在 XSL-T 樣式內,函式 %1 的第一個參數必須是文字或變數參考,以便用於比對。 + + + In an XSL-T pattern, function %1 cannot have a third argument. + 在 XSL-T 樣式內,函式 %1 的不能有第三個參數。 + + + In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. + 在 XSL-T 樣式內,只有函式 %1,%2 可以用於比對。%3 不行。 + + + In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can. + 在 XSL-T 樣式內,不能用 %1 軸,只能用 %2 或 %3。 + + + %1 is an invalid template mode name. + %1 不是合法的樣本模式名稱。 + + + The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. + 與 for 敘述結合的變數名稱必須與位置變數不同。因此,有兩個名為 %1 的變數衝突了。 + + + The Schema Validation Feature is not supported. Hence, %1-expressions may not be used. + 未支援機制確認功能。%1 敘述無法使用。 + + + None of the pragma expressions are supported. Therefore, a fallback expression must be present + 未支援 pragma 敘述。因次,必須有預設的敘述。 + + + Each name of a template parameter must be unique; %1 is duplicated. + 每個樣本參數的名稱必須唯一;%1 已經被使用。 + + + No function with name %1 is available. + + + + %1 is not a valid numeric literal. + %1 不是合法的數值。 + + + W3C XML Schema identity constraint selector + + + + W3C XML Schema identity constraint field + + + + A construct was encountered which is disallowed in the current language(%1). + + + + Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared). + 命名空間 %1 只能與 %2 結合(也就是說,要預先定義)。 + + + Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared). + 前置字串 %1 只能與 %2 結合(也就是說,要預先定義)。 + + + An attribute with name %1 has already appeared on this element. + + + + A direct element constructor is not well-formed. %1 is ended with %2. + 直接元素建構器沒有完整產生。%1 以 %2 結束。 + + + The name %1 does not refer to any schema type. + 名稱 %1 未指向任何機制型態。 + + + %1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works. + %1 是複數型態,無法轉換成複數型態。然而,轉換為原型態,如 %2 是可行的。 + + + %1 is not an atomic type. Casting is only possible to atomic types. + %1 不是一個原型態。只能轉換為原型態。 + + + %1 is not a valid name for a processing-instruction. + %1 不是處理指令的合法名稱。 + + + The name of an extension expression must be in a namespace. + 延伸敘述的名稱必須在命名空間內。 + + + Required type is %1, but %2 was found. + 需要的型態為 %1,但找到 %2。 + + + Promoting %1 to %2 may cause loss of precision. + 將 %1 抬升為 %2 可能會失去精確度。 + + + It's not possible to add attributes after any other kind of node. + 不能在任何其它種類的節點後面加入屬性。 + + + Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported. + 只支援 Unicode Codepoint Collation(%1)。%2 未支援。; + + + Integer division (%1) by zero (%2) is undefined. + 整數除法 %1 除以零(%2)的行為未定義。 + + + Division (%1) by zero (%2) is undefined. + 除法 %1 除以零(%2)的行為未定義。 + + + Modulus division (%1) by zero (%2) is undefined. + 餘數除法 %1 除以零(%2)的行為未定義。 + + + %1 takes at most %n argument(s). %2 is therefore invalid. + + %1 最多只能有 %n 個參數,因此 %2 是不合法的。 + + + + %1 requires at least %n argument(s). %2 is therefore invalid. + + %1 至少需要 %n 個參數,因此 %2 是不合法的。 + + + + The root node of the second argument to function %1 must be a document node. %2 is not a document node. + 函式 %1 的第二個參數的根節點必須是文件節點。%2 不是文件節點。 + + + The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) + 使用者定義函式的命名空間不能為空白(請試著用預先定義的前置字串 %1) + + + A default namespace declaration must occur before function, variable, and option declarations. + 預設的命名空間宣告必須在函式、變數與選項宣告之前。 + + + Namespace declarations must occur before function, variable, and option declarations. + 命名空間宣告必須在函式、變數與選項宣告之前。 + + + Module imports must occur before function, variable, and option declarations. + 模組匯入必須在函式、變數與選項宣告之前。 + + + %1 is not a whole number of minutes. + %1 不是分鐘的數值。 + + + Attribute %1 can't be serialized because it appears at the top level. + 屬性元素 %1 無法序列化,因為似乎是在頂層。 + + + %1 is an unsupported encoding. + %1 是個未被支援的編碼。 + + + %1 contains octets which are disallowed in the requested encoding %2. + %1 包含了在要求的編碼 %2 內不允許的八進位值。 + + + The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character. + 在 %2 內的代碼點 %1(編碼 %3)是一個不合法的 XML 字元。 + + + Ambiguous rule match. + 不明確的規則符合。 + + + In a namespace constructor, the value for a namespace cannot be an empty string. + + + + The prefix must be a valid %1, which %2 is not. + 前置字串必須是合法的 %1,但 %2 不是。 + + + The prefix %1 cannot be bound. + 前置字串 %1 不能被結合。 + + + Only the prefix %1 can be bound to %2 and vice versa. + 只有前置字串 %1 能與 %2 結合。反之亦然。 + + + The parameter %1 is required, but no corresponding %2 is supplied. + 需要參數 %1,但是沒有提供相關的 %2。 + + + The parameter %1 is passed, but no corresponding %2 exists. + 參數 %1 已傳送,但找不到相關的 %2。 + + + The URI cannot have a fragment + URI 不能有片段。 + + + Element %1 is not allowed at this location. + 元素 %1 不能在此位置。 + + + Text nodes are not allowed at this location. + 文字節點不能在此位置。 + + + Parse error: %1 + 剖析錯誤:%1 + + + The value of the XSL-T version attribute must be a value of type %1, which %2 isn't. + XLS-T 版本屬性的值必須是型態 %1 的值,而 %2 不是。 + + + Running an XSL-T 1.0 stylesheet with a 2.0 processor. + 使用 2.0 處理器執行 XSL-T 1.0 樣式表中。 + + + Unknown XSL-T attribute %1. + 未知的 XSL-T 屬性 %1。 + + + Attribute %1 and %2 are mutually exclusive. + 屬性 %1 與 %2 彼此互斥。 + + + In a simplified stylesheet module, attribute %1 must be present. + 在簡化的樣式表模組中,屬性 %1 必須存在。 + + + If element %1 has no attribute %2, it cannot have attribute %3 or %4. + 若元素 %1 沒有屬性 %2,則也不能有屬性 %3 或 %4。 + + + Element %1 must have at least one of the attributes %2 or %3. + 元素 %1 必須至少有屬性 %2 或 %3 其中一個。 + + + At least one mode must be specified in the %1-attribute on element %2. + 在元素 %2 的 %1 屬性中至少要指定一個模式。 + + + Element %1 must come last. + 元素 %1 必須最後出現。 + + + At least one %1-element must occur before %2. + 至少一個元素 %1 要出現在 %2 之前。 + + + Only one %1-element can appear. + 只能出現一個元素 %1。 + + + At least one %1-element must occur inside %2. + 至少一個元素 %1 要出現在 %2 之內。 + + + When attribute %1 is present on %2, a sequence constructor cannot be used. + 當屬性 %1 出現在 %2 內時,不能使用序列建構子。 + + + Element %1 must have either a %2-attribute or a sequence constructor. + 元素 %1 必須至少有一個屬性 %2 或一個序列建構子。 + + + When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor. + 當需要參數時,不能透過屬性 %1 或序列建構子提供預設值。 + + + Element %1 cannot have children. + 元素 %1 不能有子元素。 + + + Element %1 cannot have a sequence constructor. + 元素 %1不能有序列建構子。 + + + The attribute %1 cannot appear on %2, when it is a child of %3. + 屬性 %1 不能出現在 %2,因為它是 %3 的子元素。 + + + A parameter in a function cannot be declared to be a tunnel. + 函式內的參數不能被宣告為通道(tunnel)。 + + + This processor is not Schema-aware and therefore %1 cannot be used. + 此處理器不是 Schema-aware,因此不能使用 %1。 + + + Top level stylesheet elements must be in a non-null namespace, which %1 isn't. + 頂層樣式表元素必須是非空白的命名空間,而 %1 不是。 + + + The value for attribute %1 on element %2 must either be %3 or %4, not %5. + 元素 %2 內屬性 %1 的值必須是 %3 或 %4,而不是 %5。 + + + Attribute %1 cannot have the value %2. + 屬性 %1 的值不能為 %2。 + + + The attribute %1 can only appear on the first %2 element. + 屬性 %1 只能出現在前 %2 個元素內。 + + + At least one %1 element must appear as child of %2. + %2 必須至少有一個子元素 %1。 + + + %1 has inheritance loop in its base type %2. + + + + Circular inheritance of base type %1. + + + + Circular inheritance of union %1. + + + + %1 is not allowed to derive from %2 by restriction as the latter defines it as final. + + + + %1 is not allowed to derive from %2 by extension as the latter defines it as final. + + + + Base type of simple type %1 cannot be complex type %2. + + + + Simple type %1 cannot have direct base type %2. + + + + Simple type %1 is not allowed to have base type %2. + + + + Simple type %1 can only have simple atomic type as base type. + + + + Simple type %1 cannot derive from %2 as the latter defines restriction as final. + + + + Variety of item type of %1 must be either atomic or union. + + + + Variety of member types of %1 must be atomic. + + + + %1 is not allowed to derive from %2 by list as the latter defines it as final. + + + + Simple type %1 is only allowed to have %2 facet. + + + + Base type of simple type %1 must have variety of type list. + + + + Base type of simple type %1 has defined derivation by restriction as final. + + + + Item type of base type does not match item type of %1. + + + + Simple type %1 contains not allowed facet type %2. + + + + %1 is not allowed to derive from %2 by union as the latter defines it as final. + + + + %1 is not allowed to have any facets. + + + + Base type %1 of simple type %2 must have variety of union. + + + + Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute. + + + + Member type %1 cannot be derived from member type %2 of %3's base type %4. + + + + Derivation method of %1 must be extension because the base type %2 is a simple type. + + + + Complex type %1 has duplicated element %2 in its content model. + + + + Complex type %1 has non-deterministic content. + + + + Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3. + + + + Content model of complex type %1 is not a valid extension of content model of %2. + + + + Complex type %1 must have simple content. + + + + Complex type %1 must have the same simple type as its base class %2. + + + + Complex type %1 cannot be derived from base type %2%3. + + + + Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3. + + + + Complex type %1 with simple content cannot be derived from complex base type %2. + + + + Item type of simple type %1 cannot be a complex type. + + + + Member type of simple type %1 cannot be a complex type. + + + + %1 is not allowed to have a member type with the same name as itself. + + + + %1 facet collides with %2 facet. + + + + %1 facet must have the same value as %2 facet of base type. + + + + %1 facet must be equal or greater than %2 facet of base type. + + + + %1 facet must be less than or equal to %2 facet of base type. + + + + %1 facet contains invalid regular expression + + + + Unknown notation %1 used in %2 facet. + + + + %1 facet contains invalid value %2: %3. + + + + %1 facet cannot be %2 or %3 if %4 facet of base type is %5. + + + + %1 facet cannot be %2 if %3 facet of base type is %4. + + + + %1 facet must be less than or equal to %2 facet. + + + + %1 facet must be less than %2 facet of base type. + + + + %1 facet and %2 facet cannot appear together. + + + + %1 facet must be greater than %2 facet of base type. + + + + %1 facet must be less than %2 facet. + + + + %1 facet must be greater than or equal to %2 facet of base type. + + + + Simple type contains not allowed facet %1. + + + + %1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list. + + + + Only %1 and %2 facets are allowed when derived by union. + + + + %1 contains %2 facet with invalid data: %3. + + + + Attribute group %1 contains attribute %2 twice. + + + + Attribute group %1 contains two different attributes that both have types derived from %2. + + + + Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3. + + + + Complex type %1 contains attribute %2 twice. + + + + Complex type %1 contains two different attributes that both have types derived from %2. + + + + Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3. + + + + Element %1 is not allowed to have a value constraint if its base type is complex. + + + + Element %1 is not allowed to have a value constraint if its type is derived from %2. + + + + Value constraint of element %1 is not of elements type: %2. + + + + Element %1 is not allowed to have substitution group affiliation as it is no global element. + + + + Type of element %1 cannot be derived from type of substitution group affiliation. + + + + Value constraint of attribute %1 is not of attributes type: %2. + + + + Attribute %1 has value constraint but has type derived from %2. + + + + %1 attribute in derived complex type must be %2 like in base type. + + + + Attribute %1 in derived complex type must have %2 value constraint like in base type. + + + + Attribute %1 in derived complex type must have the same %2 value constraint like in base type. + + + + Attribute %1 in derived complex type must have %2 value constraint. + + + + processContent of base wildcard must be weaker than derived wildcard. + + + + Element %1 exists twice with different types. + + + + Particle contains non-deterministic wildcards. + + + + Base attribute %1 is required but derived attribute is not. + + + + Type of derived attribute %1 cannot be validly derived from type of base attribute. + + + + Value constraint of derived attribute %1 does not match value constraint of base attribute. + + + + Derived attribute %1 does not exist in the base definition. + + + + Derived attribute %1 does not match the wildcard in the base definition. + + + + Base attribute %1 is required but missing in derived definition. + + + + Derived definition contains an %1 element that does not exists in the base definition + + + + Derived wildcard is not a subset of the base wildcard. + + + + %1 of derived wildcard is not a valid restriction of %2 of base wildcard + + + + Attribute %1 from base type is missing in derived type. + + + + Type of derived attribute %1 differs from type of base attribute. + + + + Base definition contains an %1 element that is missing in the derived definition + + + + %1 references unknown %2 or %3 element %4. + + + + %1 references identity constraint %2 that is no %3 or %4 element. + + + + %1 has a different number of fields from the identity constraint %2 that it references. + + + + Base type %1 of %2 element cannot be resolved. + + + + Item type %1 of %2 element cannot be resolved. + + + + Member type %1 of %2 element cannot be resolved. + + + + Type %1 of %2 element cannot be resolved. + + + + Base type %1 of complex type cannot be resolved. + + + + %1 cannot have complex base type that has a %2. + + + + Content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type. + + + + Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model. + + + + Type of %1 element must be a simple type, %2 is not. + + + + Substitution group %1 of %2 element cannot be resolved. + + + + Substitution group %1 has circular definition. + + + + Duplicated element names %1 in %2 element. + + + + Reference %1 of %2 element cannot be resolved. + + + + Circular group reference for %1. + + + + %1 element is not allowed in this scope + + + + %1 element cannot have %2 attribute with value other than %3. + + + + %1 element cannot have %2 attribute with value other than %3 or %4. + + + + %1 or %2 attribute of reference %3 does not match with the attribute declaration %4. + + + + Attribute group %1 has circular reference. + + + + %1 attribute in %2 must have %3 use like in base type %4. + + + + Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2. + + + + %1 has attribute wildcard but its base type %2 has not. + + + + Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible. + + + + Enumeration facet contains invalid content: {%1} is not a value of type %2. + + + + Namespace prefix of qualified name %1 is not defined. + + + + %1 element %2 is not a valid restriction of the %3 element it redefines: %4. + + + + Empty particle cannot be derived from non-empty particle. + + + + Derived particle is missing element %1. + + + + Derived element %1 is missing value constraint as defined in base particle. + + + + Derived element %1 has weaker value constraint than base particle. + + + + Fixed value constraint of element %1 differs from value constraint in base particle. + + + + Derived element %1 cannot be nillable as base element is not nillable. + + + + Block constraints of derived element %1 must not be more weaker than in the base element. + + + + Simple type of derived element %1 cannot be validly derived from base element. + + + + Complex type of derived element %1 cannot be validly derived from base element. + + + + Element %1 is missing in derived particle. + + + + Element %1 does not match namespace constraint of wildcard in base particle. + + + + Wildcard in derived particle is not a valid subset of wildcard in base particle. + + + + processContent of wildcard in derived particle is weaker than wildcard in base particle. + + + + Derived particle allows content that is not allowed in the base particle. + + + + Can not process unknown element %1, expected elements are: %2. + + + + Element %1 is not allowed in this scope, possible elements are: %2. + + + + Child element is missing in that scope, possible child elements are: %1. + + + + Document is not a XML schema. + + + + %1 attribute of %2 element contains invalid content: {%3} is not a value of type %4. + + + + %1 attribute of %2 element contains invalid content: {%3}. + + + + Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema. + + + + Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema. + + + + %1 element is not allowed to have the same %2 attribute value as the target namespace %3. + + + + %1 element without %2 attribute is not allowed inside schema without target namespace. + + + + %1 element is not allowed inside %2 element if %3 attribute is present. + + + + %1 element has neither %2 attribute nor %3 child element. + + + + %1 element with %2 child element must not have a %3 attribute. + + + + %1 attribute of %2 element must be %3 or %4. + + + + %1 attribute of %2 element must have a value of %3. + + + + %1 attribute of %2 element must have a value of %3 or %4. + + + + %1 element must not have %2 and %3 attribute together. + + + + Content of %1 attribute of %2 element must not be from namespace %3. + + + + %1 attribute of %2 element must not be %3. + + + + %1 attribute of %2 element must have the value %3 because the %4 attribute is set. + + + + Specifying use='prohibited' inside an attribute group has no effect. + + + + %1 element must have either %2 or %3 attribute. + + + + %1 element must have either %2 attribute or %3 or %4 as child element. + + + + %1 element requires either %2 or %3 attribute. + + + + Text or entity references not allowed inside %1 element + + + + %1 attribute of %2 element must contain %3, %4 or a list of URIs. + + + + %1 element is not allowed in this context. + + + + %1 attribute of %2 element has larger value than %3 attribute. + + + + Prefix of qualified name %1 is not defined. + + + + %1 attribute of %2 element must either contain %3 or the other values. + + + + Component with ID %1 has been defined previously. + + + + Element %1 already defined. + + + + Attribute %1 already defined. + + + + Type %1 already defined. + + + + Attribute group %1 already defined. + + + + Element group %1 already defined. + + + + Notation %1 already defined. + + + + Identity constraint %1 already defined. + + + + Duplicated facets in simple type %1. + + + + %1 is not valid according to %2. + + + + String content does not match the length facet. + + + + String content does not match the minLength facet. + + + + String content does not match the maxLength facet. + + + + String content does not match pattern facet. + + + + String content is not listed in the enumeration facet. + + + + Signed integer content does not match the maxInclusive facet. + + + + Signed integer content does not match the maxExclusive facet. + + + + Signed integer content does not match the minInclusive facet. + + + + Signed integer content does not match the minExclusive facet. + + + + Signed integer content is not listed in the enumeration facet. + + + + Signed integer content does not match pattern facet. + + + + Signed integer content does not match in the totalDigits facet. + + + + Unsigned integer content does not match the maxInclusive facet. + + + + Unsigned integer content does not match the maxExclusive facet. + + + + Unsigned integer content does not match the minInclusive facet. + + + + Unsigned integer content does not match the minExclusive facet. + + + + Unsigned integer content is not listed in the enumeration facet. + + + + Unsigned integer content does not match pattern facet. + + + + Unsigned integer content does not match in the totalDigits facet. + + + + Double content does not match the maxInclusive facet. + + + + Double content does not match the maxExclusive facet. + + + + Double content does not match the minInclusive facet. + + + + Double content does not match the minExclusive facet. + + + + Double content is not listed in the enumeration facet. + + + + Double content does not match pattern facet. + + + + Decimal content does not match in the fractionDigits facet. + + + + Decimal content does not match in the totalDigits facet. + + + + Date time content does not match the maxInclusive facet. + + + + Date time content does not match the maxExclusive facet. + + + + Date time content does not match the minInclusive facet. + + + + Date time content does not match the minExclusive facet. + + + + Date time content is not listed in the enumeration facet. + + + + Date time content does not match pattern facet. + + + + Duration content does not match the maxInclusive facet. + + + + Duration content does not match the maxExclusive facet. + + + + Duration content does not match the minInclusive facet. + + + + Duration content does not match the minExclusive facet. + + + + Duration content is not listed in the enumeration facet. + + + + Duration content does not match pattern facet. + + + + Boolean content does not match pattern facet. + + + + Binary content does not match the length facet. + + + + Binary content does not match the minLength facet. + + + + Binary content does not match the maxLength facet. + + + + Binary content is not listed in the enumeration facet. + + + + Invalid QName content: %1. + + + + QName content is not listed in the enumeration facet. + + + + QName content does not match pattern facet. + + + + Notation content is not listed in the enumeration facet. + + + + List content does not match length facet. + + + + List content does not match minLength facet. + + + + List content does not match maxLength facet. + + + + List content is not listed in the enumeration facet. + + + + List content does not match pattern facet. + + + + Union content is not listed in the enumeration facet. + + + + Union content does not match pattern facet. + + + + Data of type %1 are not allowed to be empty. + + + + Element %1 is missing child element. + + + + There is one IDREF value with no corresponding ID: %1. + + + + Loaded schema file is invalid. + + + + %1 contains invalid data. + + + + xsi:schemaLocation namespace %1 has already appeared earlier in the instance document. + + + + xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute. + + + + No schema defined for validation. + + + + No definition for element %1 available. + + + + Specified type %1 is not known to the schema. + + + + Element %1 is not defined in this scope. + + + + Declaration for element %1 does not exist. + + + + Element %1 contains invalid content. + + + + Element %1 is declared as abstract. + + + + Element %1 is not nillable. + + + + Attribute %1 contains invalid data: %2 + + + + Element contains content although it is nillable. + + + + Fixed value constraint not allowed if element is nillable. + + + + Element %1 cannot contain other elements, as it has a fixed content. + + + + Specified type %1 is not validly substitutable with element type %2. + + + + Complex type %1 is not allowed to be abstract. + + + + Element %1 contains not allowed attributes. + + + + Element %1 contains not allowed child element. + + + + Content of element %1 does not match its type definition: %2. + + + + Content of element %1 does not match defined value constraint. + + + + Element %1 contains not allowed child content. + + + + Element %1 contains not allowed text content. + + + + Element %1 is missing required attribute %2. + + + + Attribute %1 does not match the attribute wildcard. + + + + Declaration for attribute %1 does not exist. + + + + Element %1 contains two attributes of type %2. + + + + Attribute %1 contains invalid content. + + + + Element %1 contains unknown attribute %2. + + + + Content of attribute %1 does not match its type definition: %2. + + + + Content of attribute %1 does not match defined value constraint. + + + + Non-unique value found for constraint %1. + + + + Key constraint %1 contains absent fields. + + + + Key constraint %1 contains references nillable element %2. + + + + No referenced value found for key reference %1. + + + + More than one value found for field %1. + + + + Field %1 has no simple type. + + + + ID value '%1' is not unique. + + + + '%1' attribute contains invalid QName content: %2. + + + + diff --git a/config.profiles/symbian/translations_symbian/translations.pro b/config.profiles/symbian/translations_symbian/translations.pro new file mode 100644 index 0000000..f304c1b --- /dev/null +++ b/config.profiles/symbian/translations_symbian/translations.pro @@ -0,0 +1,16 @@ +TEMPLATE = subdirs + + +symbian: { +SYMBIANTRANSLATIONSFILES = qt +SYMBIANTRANSLATIONS = ur fa ar he fr pl ru zh_cn zh_tw cs da de es gl hu ja pt sk sl sv uk + +CONFIG = loc + +for( FILE, SYMBIANTRANSLATIONSFILES ) { + for( LANGID, SYMBIANTRANSLATIONS ) { + TRANSLATIONS += $${EPOCROOT}epoc32/include/platform/qt/translations/$${FILE}_$${LANGID}.ts + } +} + +} \ No newline at end of file -- cgit v0.12 From 8a3c4c8283e4762744a29262ce507713565c1c0c Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 22 Dec 2010 17:13:30 +0100 Subject: Fix crash in indeterminate progressbars on windows Note that this is a surgical fix for 4.7 only. In 4.8 we will add these checks at the top of the styling functions or in the widgets instead. Task-number:QTBUG-15227 Reviewed-by:gabi --- src/gui/styles/qcommonstyle.cpp | 5 +++-- src/gui/styles/qwindowsstyle.cpp | 4 +++- tests/auto/qstyle/tst_qstyle.cpp | 7 +++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 039a6da..1d7c838 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -1403,8 +1403,9 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, } break; case CE_ProgressBarGroove: - qDrawShadePanel(p, opt->rect, opt->palette, true, 1, - &opt->palette.brush(QPalette::Window)); + if (opt->rect.isValid()) + qDrawShadePanel(p, opt->rect, opt->palette, true, 1, + &opt->palette.brush(QPalette::Window)); break; case CE_ProgressBarLabel: if (const QStyleOptionProgressBar *pb = qstyleoption_cast(opt)) { diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 654be3c..32a6d8d 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -2397,8 +2397,10 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai #ifndef QT_NO_PROGRESSBAR case CE_ProgressBarContents: if (const QStyleOptionProgressBar *pb = qstyleoption_cast(opt)) { - QRect rect = pb->rect; + if (!rect.isValid()) + return; + bool vertical = false; bool inverted = false; diff --git a/tests/auto/qstyle/tst_qstyle.cpp b/tests/auto/qstyle/tst_qstyle.cpp index ba24225..9c754d2 100644 --- a/tests/auto/qstyle/tst_qstyle.cpp +++ b/tests/auto/qstyle/tst_qstyle.cpp @@ -413,6 +413,13 @@ void tst_QStyle::testWindowsStyle() QWindowsStyle wstyle; testAllFunctions(&wstyle); lineUpLayoutTest(&wstyle); + + // Tests drawing indeterminate progress with 0 size: QTBUG-15973 + QStyleOptionProgressBar pb; + pb.rect = QRect(0,0,-9,0); + QPixmap surface(QSize(200, 200)); + QPainter painter(&surface); + wstyle.drawControl(QStyle::CE_ProgressBar, &pb, &painter, 0); } void tst_QStyle::testWindowsXPStyle() -- cgit v0.12 From b461c315547b42293968219583187d83b2b25e0f Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 22 Dec 2010 09:23:48 +1000 Subject: Add additional QDeclarativeProperty autotests. --- .../tst_qdeclarativeproperty.cpp | 62 ++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp index 3cc71bb..41f2b19 100644 --- a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp +++ b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp @@ -167,6 +167,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty() QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); + QCOMPARE(prop.isSignalProperty(), false); QCOMPARE(prop.isValid(), false); QCOMPARE(prop.object(), (QObject *)0); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); @@ -263,6 +264,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object() QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); + QCOMPARE(prop.isSignalProperty(), false); QCOMPARE(prop.isValid(), false); QCOMPARE(prop.object(), (QObject *)0); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); @@ -309,6 +311,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object() QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), true); QCOMPARE(prop.isResettable(), false); + QCOMPARE(prop.isSignalProperty(), false); QCOMPARE(prop.isValid(), true); QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal); @@ -362,6 +365,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); + QCOMPARE(prop.isSignalProperty(), false); QCOMPARE(prop.isValid(), false); QCOMPARE(prop.object(), (QObject *)0); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); @@ -408,6 +412,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), true); QCOMPARE(prop.isResettable(), false); + QCOMPARE(prop.isSignalProperty(), false); QCOMPARE(prop.isValid(), true); QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal); @@ -456,6 +461,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); + QCOMPARE(prop.isSignalProperty(), true); QCOMPARE(prop.isValid(), true); QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); @@ -503,6 +509,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); + QCOMPARE(prop.isSignalProperty(), true); QCOMPARE(prop.isValid(), true); QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); @@ -555,6 +562,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_context() QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); + QCOMPARE(prop.isSignalProperty(), false); QCOMPARE(prop.isValid(), false); QCOMPARE(prop.object(), (QObject *)0); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); @@ -601,6 +609,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_context() QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), true); QCOMPARE(prop.isResettable(), false); + QCOMPARE(prop.isSignalProperty(), false); QCOMPARE(prop.isValid(), true); QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal); @@ -654,6 +663,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); + QCOMPARE(prop.isSignalProperty(), false); QCOMPARE(prop.isValid(), false); QCOMPARE(prop.object(), (QObject *)0); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); @@ -700,6 +710,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), true); QCOMPARE(prop.isResettable(), false); + QCOMPARE(prop.isSignalProperty(), false); QCOMPARE(prop.isValid(), true); QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal); @@ -748,6 +759,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); + QCOMPARE(prop.isSignalProperty(), true); QCOMPARE(prop.isValid(), true); QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); @@ -795,6 +807,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.isWritable(), false); QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); + QCOMPARE(prop.isSignalProperty(), true); QCOMPARE(prop.isValid(), true); QCOMPARE(prop.object(), qobject_cast(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); @@ -922,6 +935,17 @@ void tst_qdeclarativeproperty::read() QCOMPARE(p.read(), QVariant("myName")); } + // Value prop by name (static) + { + QObject o; + + QCOMPARE(QDeclarativeProperty::read(&o, "objectName"), QVariant(QString())); + + o.setObjectName("myName"); + + QCOMPARE(QDeclarativeProperty::read(&o, "objectName"), QVariant("myName")); + } + // Value-type prop { PropertyObject o; @@ -994,6 +1018,16 @@ void tst_qdeclarativeproperty::read() QCOMPARE(qvariant_cast(v)->property("a").toInt(), 10); QCOMPARE(qvariant_cast(v)->property("b").toInt(), 19); } + { // static + QDeclarativeComponent component(&engine, TEST_FILE("readSynthesizedObject.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QVariant v = QDeclarativeProperty::read(object, "test", &engine); + QVERIFY(v.userType() == QMetaType::QObjectStar); + QCOMPARE(qvariant_cast(v)->property("a").toInt(), 10); + QCOMPARE(qvariant_cast(v)->property("b").toInt(), 19); + } // Attached property { @@ -1026,6 +1060,15 @@ void tst_qdeclarativeproperty::read() QCOMPARE(p.read(), QVariant(10)); delete object; } + { // static + QDeclarativeComponent component(&engine); + component.setData("import Test 1.0 as Foo\nFoo.MyContainer { Foo.MyContainer.foo: 10 }", QUrl()); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(QDeclarativeProperty::read(object, "Foo.MyContainer.foo", qmlContext(object)), QVariant(10)); + delete object; + } } void tst_qdeclarativeproperty::write() @@ -1066,6 +1109,13 @@ void tst_qdeclarativeproperty::write() QCOMPARE(o.objectName(), QString("myName")); } + // Writable prop by name (static) + { + PropertyObject o; + QCOMPARE(QDeclarativeProperty::write(&o, QString("objectName"), QVariant(QString("myName"))), true); + QCOMPARE(o.objectName(), QString("myName")); + } + // Deleted object { PropertyObject *o = new PropertyObject; @@ -1138,6 +1188,18 @@ void tst_qdeclarativeproperty::write() QCOMPARE(p2.write(QUrl("main.qml")), true); QCOMPARE(o.url(), result); } + { // static + PropertyObject o; + + QCOMPARE(QDeclarativeProperty::write(&o, "url", QUrl("main.qml")), true); + QCOMPARE(o.url(), QUrl("main.qml")); + + QUrl result = engine.baseUrl().resolved(QUrl("main.qml")); + QVERIFY(result != QUrl("main.qml")); + + QCOMPARE(QDeclarativeProperty::write(&o, "url", QUrl("main.qml"), engine.rootContext()), true); + QCOMPARE(o.url(), result); + } // Attached property { -- cgit v0.12 From f360cc9b521e5e3e7d4b896627b3257365c6ad3c Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 22 Dec 2010 10:05:06 +1000 Subject: Improve QDeclarativeComponent test coverage. --- src/declarative/qml/qdeclarativecomponent.cpp | 11 ----------- src/declarative/qml/qdeclarativecomponent_p.h | 1 - .../qdeclarativecomponent/tst_qdeclarativecomponent.cpp | 15 +++++++++++++++ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index 77fc925..ecb3bc5 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -699,17 +699,6 @@ QObject *QDeclarativeComponent::create(QDeclarativeContext *context) return rv; } -QObject *QDeclarativeComponentPrivate::create(QDeclarativeContextData *context, - const QBitField &bindings) -{ - if (!context) - context = QDeclarativeContextData::get(engine->rootContext()); - - QObject *rv = beginCreate(context, bindings); - completeCreate(); - return rv; -} - /*! This method provides more advanced control over component instance creation. In general, programmers should use QDeclarativeComponent::create() to create a diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h index 7b30bad..daf1dcb 100644 --- a/src/declarative/qml/qdeclarativecomponent_p.h +++ b/src/declarative/qml/qdeclarativecomponent_p.h @@ -81,7 +81,6 @@ class Q_AUTOTEST_EXPORT QDeclarativeComponentPrivate : public QObjectPrivate, pu public: QDeclarativeComponentPrivate() : typeData(0), progress(0.), start(-1), count(-1), cc(0), engine(0), creationContext(0) {} - QObject *create(QDeclarativeContextData *, const QBitField &); QObject *beginCreate(QDeclarativeContextData *, const QBitField &); void completeCreate(); diff --git a/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp b/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp index 8a19b8b..60ce46d 100644 --- a/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp +++ b/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp @@ -57,6 +57,7 @@ public: tst_qdeclarativecomponent() { } private slots: + void null(); void loadEmptyUrl(); void qmlCreateObject(); @@ -64,6 +65,20 @@ private: QDeclarativeEngine engine; }; +void tst_qdeclarativecomponent::null() +{ + { + QDeclarativeComponent c; + QVERIFY(c.isNull()); + } + + { + QDeclarativeComponent c(&engine); + QVERIFY(c.isNull()); + } +} + + void tst_qdeclarativecomponent::loadEmptyUrl() { QDeclarativeComponent c(&engine); -- cgit v0.12 From 01fd44cd76f2da1dd1e39d7e5632b3274ca895a3 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 23 Dec 2010 10:20:23 +1000 Subject: Nested flickables would react alternately to flicks. The grab was not always kept by filtering Flickables, but would remain set next flick, resulting in toggling of flicking. Task-number: QTBUG-16177 Reviewed-by: Michael Brasser --- .../graphicsitems/qdeclarativeflickable.cpp | 6 +- .../data/flickable-nested.0.png | Bin 0 -> 1710 bytes .../data/flickable-nested.1.png | Bin 0 -> 1710 bytes .../data/flickable-nested.2.png | Bin 0 -> 1727 bytes .../data/flickable-nested.3.png | Bin 0 -> 1727 bytes .../data/flickable-nested.4.png | Bin 0 -> 1727 bytes .../data/flickable-nested.5.png | Bin 0 -> 1731 bytes .../data/flickable-nested.qml | 2159 ++++++++++++++++++++ .../qdeclarativeflickable/flickable-nested.qml | 50 + 9 files changed, 2213 insertions(+), 2 deletions(-) create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.0.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.1.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.2.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.3.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.4.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.5.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.qml create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeflickable/flickable-nested.qml diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index f1d92c5..f5da491 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -671,10 +671,12 @@ void QDeclarativeFlickable::setFlickableDirection(FlickableDirection direction) void QDeclarativeFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event) { + Q_Q(QDeclarativeFlickable); 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; + q->setKeepMouseGrab(stealMouse); pressed = true; timeline.clear(); hData.velocity = 0; @@ -769,6 +771,8 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent } stealMouse = stealX || stealY; + if (stealMouse) + q->setKeepMouseGrab(true); if (!lastPos.isNull()) { qreal elapsed = qreal(QDeclarativeItemPrivate::restart(lastPosTime)) / 1000.; @@ -848,8 +852,6 @@ 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); diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.0.png b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.0.png new file mode 100644 index 0000000..464d913 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.1.png b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.1.png new file mode 100644 index 0000000..464d913 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.2.png b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.2.png new file mode 100644 index 0000000..b16b9f0 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.3.png b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.3.png new file mode 100644 index 0000000..c3d2a6f Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.4.png b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.4.png new file mode 100644 index 0000000..d074e73 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.5.png b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.5.png new file mode 100644 index 0000000..0cac34c Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.5.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.qml b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.qml new file mode 100644 index 0000000..c418cc8 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/data/flickable-nested.qml @@ -0,0 +1,2159 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "flickable-nested.0.png" + } + Frame { + msec: 32 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 48 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 64 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 80 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 96 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 112 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 128 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 144 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 160 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 176 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 192 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 208 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 224 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 240 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 256 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 272 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 288 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 304 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 320 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 336 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 352 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 368 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 384 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 400 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 416 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 432 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 448 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 464 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 480 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 496 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 512 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 528 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 544 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 560 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 576 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 592 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 608 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 624 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 640 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 656 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 672 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 688 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 704 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 720 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 736 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 752 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 768 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 784 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 800 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 816 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 832 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 848 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 864 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 880 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 896 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 912 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 928 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 206; y: 205 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 944 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Frame { + msec: 960 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 206; y: 204 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 976 + image: "flickable-nested.1.png" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 206; y: 203 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 206; y: 202 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 992 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 205; y: 201 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 205; y: 199 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1008 + hash: "7523750f0fd21aff13e6ab379e87640d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 204; y: 197 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 202; y: 196 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1024 + hash: "bddf8ca2638c9a04f7029d6982152d11" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 198; y: 191 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 197; y: 189 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1040 + hash: "bc15f1b562879d5058d3b1336fb9074e" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 194; y: 185 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 194; y: 184 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1056 + hash: "3572c62d7d2b9b23a8d9d3e5037591dd" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 194; y: 182 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 194; y: 182 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1072 + hash: "ce9658887cca581a88e7db14b92d46f2" + } + Frame { + msec: 1088 + hash: "e1fe1a2e1669a200e20468b4aa98dd3d" + } + Frame { + msec: 1104 + hash: "b7582829bf01223e6641ce82f62047df" + } + Frame { + msec: 1120 + hash: "80bd41fe22fb84efb011acf50ec38574" + } + Frame { + msec: 1136 + hash: "04c8d6c3922ce9777ee27d8df59d4729" + } + Frame { + msec: 1152 + hash: "f84dba18e525f1c06548c0232a244b6d" + } + Frame { + msec: 1168 + hash: "26c74b95835e8e0da5aadc7c42cac81c" + } + Frame { + msec: 1184 + hash: "1b4fcb1f0bd83a683cfe0ac303be0033" + } + Frame { + msec: 1200 + hash: "1b4fcb1f0bd83a683cfe0ac303be0033" + } + Frame { + msec: 1216 + hash: "4df47f90656fff253883e3e2d33506dc" + } + Frame { + msec: 1232 + hash: "4df47f90656fff253883e3e2d33506dc" + } + Frame { + msec: 1248 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1264 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1280 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1296 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1312 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1328 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1344 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1360 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1376 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1392 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1408 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1424 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1440 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1456 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1472 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1488 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1504 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1520 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1536 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1552 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1568 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1584 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Frame { + msec: 1600 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 226; y: 218 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1616 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 225; y: 218 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1632 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 223; y: 217 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 222; y: 217 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1648 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 220; y: 216 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 218; y: 214 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1664 + hash: "7d0d94c4a7a9330f5bd17782ca484848" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 214; y: 212 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 212; y: 211 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1680 + hash: "54b41609ba43f710b08ba63f0b96df99" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 208; y: 208 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 207; y: 207 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1696 + hash: "8910b66b9eb1b2be80e36ed2824df1a0" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 205; y: 205 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 205; y: 205 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1712 + hash: "38df31933f34f961a9b7020ad0d469c2" + } + Frame { + msec: 1728 + hash: "7702a7f710991225d9f411e8f410b515" + } + Frame { + msec: 1744 + hash: "c90d402e68208ccfd2c7345a2bf650cd" + } + Frame { + msec: 1760 + hash: "2630ed37aaf37907d1ee48efb0239615" + } + Frame { + msec: 1776 + hash: "527725818699ce3425b5cb95a25610d5" + } + Frame { + msec: 1792 + hash: "7bd6e37853946a835973c3da213beddc" + } + Frame { + msec: 1808 + hash: "e3c5e113d992e5e50b6780185891edd7" + } + Frame { + msec: 1824 + hash: "e3c5e113d992e5e50b6780185891edd7" + } + Frame { + msec: 1840 + hash: "20ced2b9960931c4c0cbe8bcc1f9e52a" + } + Frame { + msec: 1856 + hash: "09710c8964c8b010a90c67f126acdefa" + } + Frame { + msec: 1872 + hash: "09710c8964c8b010a90c67f126acdefa" + } + Frame { + msec: 1888 + hash: "09710c8964c8b010a90c67f126acdefa" + } + Frame { + msec: 1904 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 1920 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 1936 + image: "flickable-nested.2.png" + } + Frame { + msec: 1952 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 1968 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 1984 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2000 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2016 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2032 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2048 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2064 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2080 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2096 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2112 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2128 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2144 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2160 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2176 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2192 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2208 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2224 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2240 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2256 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2272 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2288 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Frame { + msec: 2304 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 274; y: 218 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2320 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 273; y: 218 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 273; y: 217 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2336 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 272; y: 215 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 272; y: 213 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2352 + hash: "e80b03bd168ec62aba64cdf75dcd1d5f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 271; y: 210 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 270; y: 208 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2368 + hash: "79a132ab719ccdf48d367cca443cd835" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 269; y: 204 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 269; y: 202 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2384 + hash: "1f19e7d2c7494f5b603dee16e211d65d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 268; y: 196 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 268; y: 193 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2400 + hash: "64fd22407c77fac28d13035ce78c67b2" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 268; y: 186 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 266; y: 177 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2416 + hash: "f05a0f956b4964d4ebff056b63252297" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 265; y: 173 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 264; y: 167 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2432 + hash: "3de1e9a2b33e37b0fe3b799b68ec22d6" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 263; y: 164 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 263; y: 164 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2448 + hash: "71f115c60d4f20422e4ac3f319644c48" + } + Frame { + msec: 2464 + hash: "c3995ac89f0a4b3fb07401479538d338" + } + Frame { + msec: 2480 + hash: "950e83408adf55f4e7fc1c0c127caa89" + } + Frame { + msec: 2496 + hash: "5b335621a76a527d058708384c2e5635" + } + Frame { + msec: 2512 + hash: "a201ae31d5bb778bd44a49dd21951c1b" + } + Frame { + msec: 2528 + hash: "550e6708a8999d56d1f57c121228692f" + } + Frame { + msec: 2544 + hash: "d8eb4dd2b3cf50273cb7dfbb5bd658b9" + } + Frame { + msec: 2560 + hash: "aa1fd0a990e42175acc84de96b384e9d" + } + Frame { + msec: 2576 + hash: "0236fb15db30da5ec794444affee1169" + } + Frame { + msec: 2592 + hash: "a7445a70874a9767462e79e1dff88dbc" + } + Frame { + msec: 2608 + hash: "339ea6bd5b486ff85272e19e07669f0b" + } + Frame { + msec: 2624 + hash: "2b24d9d17c77cd0ac52989328dcf499b" + } + Frame { + msec: 2640 + hash: "2b24d9d17c77cd0ac52989328dcf499b" + } + Frame { + msec: 2656 + hash: "e2fcfe4f3e14e46404eb6955502180a1" + } + Frame { + msec: 2672 + hash: "5d0c9601b871690047f4df91723ccfb1" + } + Frame { + msec: 2688 + hash: "5d0c9601b871690047f4df91723ccfb1" + } + Frame { + msec: 2704 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2720 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2736 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2752 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2768 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2784 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2800 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2816 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2832 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2848 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2864 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2880 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2896 + image: "flickable-nested.3.png" + } + Frame { + msec: 2912 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2928 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2944 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Frame { + msec: 2960 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 268; y: 102 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2976 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 268; y: 103 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 268; y: 104 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2992 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 268; y: 105 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 269; y: 108 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3008 + hash: "5b5d7e880e9f4942f52a3cde738dc7fb" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 270; y: 111 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 270; y: 114 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3024 + hash: "2b24d9d17c77cd0ac52989328dcf499b" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 271; y: 119 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 272; y: 122 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3040 + hash: "550e6708a8999d56d1f57c121228692f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 273; y: 130 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 274; y: 138 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3056 + hash: "57f3c0a49cef2137e3cfa435396c099e" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 274; y: 142 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 274; y: 149 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3072 + hash: "0fffc659a270cc614d16ddf3fa2ab51d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 274; y: 153 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 274; y: 161 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3088 + hash: "a8d937c8379950299a6e3611ff313415" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 273; y: 165 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 272; y: 172 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3104 + hash: "46cfebbf821a08aa30055bfa8fffd137" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 271; y: 175 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 270; y: 180 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 270; y: 180 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3120 + hash: "20a32ee8ae2cf88a2cfdb2dd8552255a" + } + Frame { + msec: 3136 + hash: "20a32ee8ae2cf88a2cfdb2dd8552255a" + } + Frame { + msec: 3152 + hash: "20a32ee8ae2cf88a2cfdb2dd8552255a" + } + Frame { + msec: 3168 + hash: "20a32ee8ae2cf88a2cfdb2dd8552255a" + } + Frame { + msec: 3184 + hash: "20a32ee8ae2cf88a2cfdb2dd8552255a" + } + Frame { + msec: 3200 + hash: "20a32ee8ae2cf88a2cfdb2dd8552255a" + } + Frame { + msec: 3216 + hash: "20a32ee8ae2cf88a2cfdb2dd8552255a" + } + Frame { + msec: 3232 + hash: "20a32ee8ae2cf88a2cfdb2dd8552255a" + } + Frame { + msec: 3248 + hash: "20a32ee8ae2cf88a2cfdb2dd8552255a" + } + Frame { + msec: 3264 + hash: "20a32ee8ae2cf88a2cfdb2dd8552255a" + } + Frame { + msec: 3280 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3296 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3312 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3328 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3344 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3360 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3376 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3392 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3408 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3424 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3440 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3456 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3472 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3488 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3504 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3520 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3536 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3552 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3568 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 3584 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 352; y: 206 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3600 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 352; y: 205 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 352; y: 204 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3616 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 352; y: 201 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 352; y: 196 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3632 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 352; y: 193 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 352; y: 185 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3648 + hash: "eb718f97648438dae1440e2089434b0a" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 352; y: 176 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 352; y: 172 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3664 + hash: "e4a2b82752939f351ac46032f2d3333e" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 353; y: 163 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 354; y: 158 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3680 + hash: "ab1099a146433a5ec77b336673d0527c" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 356; y: 148 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 356; y: 142 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3696 + hash: "7e4ca5ba45d5de10d72ef5ab1171ead5" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 357; y: 130 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 357; y: 130 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3712 + hash: "417bb78fc4f255194a71193e388b752f" + } + Frame { + msec: 3728 + hash: "be63b1e57006d881a345db3ca66e7097" + } + Frame { + msec: 3744 + hash: "e1b96137c2cc0ef18e224a32f665de9d" + } + Frame { + msec: 3760 + hash: "6157ba3962fc7829e8693e2456fd6e8e" + } + Frame { + msec: 3776 + hash: "951ae231b7b18517f8d6504ce7f01b3d" + } + Frame { + msec: 3792 + hash: "57f60f9da1a204cc7eb930575de45ae4" + } + Frame { + msec: 3808 + hash: "008323603b48a55b589af7cbb2f1c8b0" + } + Frame { + msec: 3824 + hash: "b8447e994280cba5ccddc36e7ad3c927" + } + Frame { + msec: 3840 + hash: "98dfc2d6573e5cb7a56a893b8fecf422" + } + Frame { + msec: 3856 + image: "flickable-nested.4.png" + } + Frame { + msec: 3872 + hash: "09dabc3ef85dc857719e7d20111e6023" + } + Frame { + msec: 3888 + hash: "5864c4197fe3269c3f1ad05caf25832e" + } + Frame { + msec: 3904 + hash: "370a471a614d22d281d9987a5b6a42bf" + } + Frame { + msec: 3920 + hash: "36c74e2e325807c7c06e941581613f48" + } + Frame { + msec: 3936 + hash: "e1e2b69992294dc611e6eef7e259d4cd" + } + Frame { + msec: 3952 + hash: "e1e2b69992294dc611e6eef7e259d4cd" + } + Frame { + msec: 3968 + hash: "e1e2b69992294dc611e6eef7e259d4cd" + } + Frame { + msec: 3984 + hash: "36c74e2e325807c7c06e941581613f48" + } + Frame { + msec: 4000 + hash: "36c74e2e325807c7c06e941581613f48" + } + Frame { + msec: 4016 + hash: "bd8f39423d96fceaf577c7f792b61211" + } + Frame { + msec: 4032 + hash: "370a471a614d22d281d9987a5b6a42bf" + } + Frame { + msec: 4048 + hash: "c8fe4424d96460a2503632e3a54d4f6a" + } + Frame { + msec: 4064 + hash: "09dabc3ef85dc857719e7d20111e6023" + } + Frame { + msec: 4080 + hash: "22bff1406eba529d58320b8b19be76d9" + } + Frame { + msec: 4096 + hash: "478bc04322b93b75b5185d047c2898b7" + } + Frame { + msec: 4112 + hash: "98dfc2d6573e5cb7a56a893b8fecf422" + } + Frame { + msec: 4128 + hash: "03b96d3e148e86f1150b09696012d07c" + } + Frame { + msec: 4144 + hash: "735b24d2811beef969477c8b0f400d32" + } + Frame { + msec: 4160 + hash: "b8399d2a7a6de0b5f81e68e8f8825622" + } + Frame { + msec: 4176 + hash: "766a97e0881b623a0de93babfa841125" + } + Frame { + msec: 4192 + hash: "008323603b48a55b589af7cbb2f1c8b0" + } + Frame { + msec: 4208 + hash: "3da913235e4916b4691e3d089dc7b52f" + } + Frame { + msec: 4224 + hash: "3da913235e4916b4691e3d089dc7b52f" + } + Frame { + msec: 4240 + hash: "8c7f6ff7b3db65d7dd9ac4d18545f0d1" + } + Frame { + msec: 4256 + hash: "8c7f6ff7b3db65d7dd9ac4d18545f0d1" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 346; y: 95 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4272 + hash: "8c7f6ff7b3db65d7dd9ac4d18545f0d1" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 346; y: 98 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 346; y: 103 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4288 + hash: "951ae231b7b18517f8d6504ce7f01b3d" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 348; y: 110 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 348; y: 115 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4304 + hash: "364283bbbcedabc87689ec174ae29818" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 351; y: 124 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 353; y: 129 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4320 + hash: "6a8a59ba8cf0539704fc035d7d5def41" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 358; y: 141 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 361; y: 145 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4336 + hash: "d4626b39fbf24cc6a4e23ef33a570add" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 370; y: 163 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4352 + hash: "255604ac684a18e272dccfa9a81fa1bb" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 376; y: 172 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4368 + hash: "2696641e48ea2a0ccfc65057b283814f" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 377; y: 175 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 377; y: 175 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4384 + hash: "4ae011d8d81c57f9e2495d32a90fb5c0" + } + Frame { + msec: 4400 + hash: "c07f57059244b1164e698430b20aac8e" + } + Frame { + msec: 4416 + hash: "d39c21bc6fc079c76ea78d1a3fb0c974" + } + Frame { + msec: 4432 + hash: "f955985ee02fcb810ab8c5f4790f5c12" + } + Frame { + msec: 4448 + hash: "d06b83769bf0f0331e53c270f5dc294c" + } + Frame { + msec: 4464 + hash: "a49ef3866e3f71c26c57fcd616a6dc4c" + } + Frame { + msec: 4480 + hash: "086f4bb966b2076f51b1f615368afda5" + } + Frame { + msec: 4496 + hash: "898de0b200cb83c9724869dd2b74ed52" + } + Frame { + msec: 4512 + hash: "47833f93c5c55f57de5733950ba53714" + } + Frame { + msec: 4528 + hash: "0ced71db7e8c5b8ce8e195a7b821507d" + } + Frame { + msec: 4544 + hash: "84888b8748e297ed4e0525019865ea2b" + } + Frame { + msec: 4560 + hash: "0f62d1aaa0fec0dd90351258a3745869" + } + Frame { + msec: 4576 + hash: "e34a874942161ea830907f94040fc0a5" + } + Frame { + msec: 4592 + hash: "9031e4ad8ee57a8b826d6a6394f0feb9" + } + Frame { + msec: 4608 + hash: "9031e4ad8ee57a8b826d6a6394f0feb9" + } + Frame { + msec: 4624 + hash: "cc8a2477368001015b68c99db95ebaa1" + } + Frame { + msec: 4640 + hash: "01c0f4d5b155eb16ac364b24d5085bac" + } + Frame { + msec: 4656 + hash: "4c4f318b03e0da461bcecb61f43ef3cd" + } + Frame { + msec: 4672 + hash: "dffd22d719f18c943cd0c30afe272434" + } + Frame { + msec: 4688 + hash: "4f7ab0450512ae1319dad22a6e0400b7" + } + Frame { + msec: 4704 + hash: "ea29e23bdb49a30694640dfb078c796a" + } + Frame { + msec: 4720 + hash: "80739ed287906d0b55297be4b74a54cb" + } + Frame { + msec: 4736 + hash: "8d9117cf841c4b158f30b79ac8f2afb0" + } + Frame { + msec: 4752 + hash: "1850e9117160b2bd1865274092f9ec84" + } + Frame { + msec: 4768 + hash: "07945c8954860895f95f8e352c49e0a5" + } + Frame { + msec: 4784 + hash: "d0fa6087d2859446ff8f317c9d7dafe1" + } + Frame { + msec: 4800 + hash: "8ebba2084793d90a640ec2fb12dc0547" + } + Frame { + msec: 4816 + image: "flickable-nested.5.png" + } + Frame { + msec: 4832 + hash: "77d479675c36ecda0926061449f5a60b" + } + Frame { + msec: 4848 + hash: "77d479675c36ecda0926061449f5a60b" + } + Frame { + msec: 4864 + hash: "b968c1528ce7ecf80008fbd56f0ca9a9" + } + Frame { + msec: 4880 + hash: "b968c1528ce7ecf80008fbd56f0ca9a9" + } + Frame { + msec: 4896 + hash: "b968c1528ce7ecf80008fbd56f0ca9a9" + } + Frame { + msec: 4912 + hash: "b968c1528ce7ecf80008fbd56f0ca9a9" + } + Frame { + msec: 4928 + hash: "b968c1528ce7ecf80008fbd56f0ca9a9" + } + Frame { + msec: 4944 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 4960 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 4976 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 4992 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5008 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5024 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5040 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5056 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5072 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5088 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5104 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5120 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5136 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5152 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5168 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5184 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5200 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5216 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5232 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5248 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5264 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5280 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5296 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5312 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5328 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5344 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5360 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5376 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5392 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5408 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5424 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5440 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5456 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5472 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5488 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5504 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5520 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5536 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5552 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5568 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5584 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5600 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5616 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5632 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5648 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5664 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5680 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } + Frame { + msec: 5696 + hash: "38f29e86bd9bfe4df04c6411374f76ae" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeflickable/flickable-nested.qml b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/flickable-nested.qml new file mode 100644 index 0000000..9335b9e --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativeflickable/flickable-nested.qml @@ -0,0 +1,50 @@ +import QtQuick 1.0 + +Item { + width: 640 + height: 400 + + Flickable { + objectName: "flick 1" + anchors.fill: parent + contentWidth: width + 100 + contentHeight: height + 100 + + Rectangle { + width: 300 + height: 300 + color: "blue" + + Flickable { + objectName: "flick 2" + width: 300 + height: 300 + clip: true + contentWidth: 400 + contentHeight: 400 + + Rectangle { + width: 100 + height: 100 + anchors.centerIn: parent + color: "yellow" + + Flickable { + objectName: "flick 3" + anchors.fill: parent + clip: true + contentWidth: 150 + contentHeight: 150 + Rectangle { + x: 80 + y: 80 + width: 50 + height: 50 + color: "green" + } + } + } + } + } + } +} -- cgit v0.12 From 1699e8240b8073241f1aaddc12ded6065ef520b9 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 23 Dec 2010 11:02:04 +1000 Subject: Ensure PathView doesn't jump when starting to drag. Task-number: QTBUG-16133 Reviewed-by: Bea Lam --- .../graphicsitems/qdeclarativepathview.cpp | 4 +- .../data/test-pathview-2.0.png | Bin 1114 -> 1114 bytes .../data/test-pathview-2.1.png | Bin 1105 -> 1119 bytes .../data/test-pathview-2.2.png | Bin 1088 -> 1102 bytes .../data/test-pathview-2.3.png | Bin 1096 -> 1092 bytes .../data/test-pathview-2.4.png | Bin 1143 -> 1143 bytes .../data/test-pathview-2.5.png | Bin 1143 -> 1143 bytes .../qdeclarativepathview/data/test-pathview-2.qml | 366 +++++------ .../qdeclarativepathview/data/test-pathview.0.png | Bin 1169 -> 1169 bytes .../qdeclarativepathview/data/test-pathview.1.png | Bin 1182 -> 1172 bytes .../qdeclarativepathview/data/test-pathview.2.png | Bin 1211 -> 1201 bytes .../qdeclarativepathview/data/test-pathview.3.png | Bin 1184 -> 1164 bytes .../qdeclarativepathview/data/test-pathview.4.png | Bin 1152 -> 1226 bytes .../qdeclarativepathview/data/test-pathview.5.png | Bin 1141 -> 1192 bytes .../qdeclarativepathview/data/test-pathview.6.png | Bin 1189 -> 1188 bytes .../qdeclarativepathview/data/test-pathview.qml | 672 ++++++++++----------- .../qdeclarativepathview/test-pathview.qml | 2 + 17 files changed, 524 insertions(+), 520 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index 87ea214..a6f44b3 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -1133,8 +1133,10 @@ void QDeclarativePathViewPrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent QPointF pathPoint = pointNear(event->pos(), &newPc); if (!stealMouse) { QPointF delta = pathPoint - startPoint; - if (qAbs(delta.x()) > QApplication::startDragDistance() || qAbs(delta.y()) > QApplication::startDragDistance()) + if (qAbs(delta.x()) > QApplication::startDragDistance() || qAbs(delta.y()) > QApplication::startDragDistance()) { stealMouse = true; + startPc = newPc; + } } if (stealMouse) { diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.0.png b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.0.png index 699f83e..347e773 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.1.png b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.1.png index a742a6a..370ca80 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.2.png b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.2.png index 71abae2..97e3906 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.2.png and b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.3.png b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.3.png index a6e6b3e..5fa3c67 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.3.png and b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.4.png b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.4.png index 9f125c4..ce11c09 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.4.png and b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.5.png b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.5.png index 41d0cd5..d155742 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.5.png and b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.5.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.qml b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.qml index b75d140..304d5c7 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview-2.qml @@ -222,7 +222,7 @@ VisualTest { } Frame { msec: 752 - hash: "e21cac055208e47e267ac906c7c2ca9c" + hash: "d2dda5bec262721d653e88ec3eaeca57" } Mouse { type: 5 @@ -234,7 +234,7 @@ VisualTest { } Frame { msec: 768 - hash: "131e094a79edbeea9a1b981592e55abf" + hash: "d61d21ab4d83b8578494720d9bfe6fa8" } Mouse { type: 5 @@ -254,7 +254,7 @@ VisualTest { } Frame { msec: 784 - hash: "73faabf52bd2af8d8b9d28ce21e5e77b" + hash: "0a178235529d721529e8dc3b439a64c9" } Mouse { type: 5 @@ -266,7 +266,7 @@ VisualTest { } Frame { msec: 800 - hash: "359554a95362db1734f606cf677001fc" + hash: "c800609ffea814ba7cc2441790157245" } Mouse { type: 5 @@ -286,43 +286,43 @@ VisualTest { } Frame { msec: 816 - hash: "8ef4ecc5c5ba578f0279dc57a6c17ccd" + hash: "afcb452d41c6e895309bb921a1ad1d31" } Frame { msec: 832 - hash: "69c3d9d2700dd395b656b0b09fa63511" + hash: "02d8f91c33f62aaf366bcfd03d232269" } Frame { msec: 848 - hash: "2bbcc36d72c3e9a4b672a46f2aae5076" + hash: "1ba9bc8c2b941fd0ec82f211eb559682" } Frame { msec: 864 - hash: "125a5f0c8efdf97676edbe379660dcce" + hash: "ee8680df3c58a48f3fff4a8fc221e38c" } Frame { msec: 880 - hash: "4347a02227207fbf870b6aed76131619" + hash: "36c04a2bd58124877a332bb6a262a7e5" } Frame { msec: 896 - hash: "e08b494c818669bfc48273598574d22e" + hash: "e6ea836d68c54a8308e10f33d4eb8b98" } Frame { msec: 912 - hash: "186cb5465f45c0df8082ec8cad6ee8b1" + hash: "f2400819feb116ae3b327284bbb292ff" } Frame { msec: 928 - hash: "91d04d4469492c3bb2a1ed415dcd904c" + hash: "5d9a3458cb59ede36e7b51bac869785a" } Frame { msec: 944 - hash: "8cc8ef251d68af926a8f300b8666ecfd" + hash: "b859b690c633a9fec87941e7c89f5d19" } Frame { msec: 960 - hash: "42f64722245f8519386e75ce7e3c0cd9" + hash: "ef0b66e789a8e88389e16bfa36b9f6e2" } Frame { msec: 976 @@ -330,195 +330,195 @@ VisualTest { } Frame { msec: 992 - hash: "058311da9dcf73a4b4928038334b04b5" + hash: "493e3c7b0de4a7b4b46678fe4ce9a763" } Frame { msec: 1008 - hash: "ea662934ee0c3c8d4dbde3ad49448922" + hash: "b7056d635c69b8e5bf98872f4c07ed43" } Frame { msec: 1024 - hash: "01991a871819e7bdbf817580f720ead6" + hash: "68aa8bd6709e1b49cfefc4594c236c46" } Frame { msec: 1040 - hash: "69a7fe47ae589bcc2607cc42fcea7451" + hash: "4b28ebf737b8c4228771122d844b8166" } Frame { msec: 1056 - hash: "8240d087b767311e00b7dd4b8726246c" + hash: "b04155316770a1265e5dc431e1b9a9a1" } Frame { msec: 1072 - hash: "cc70c8e79d68f09e6db0dd43b99906b7" + hash: "d540453541aba394b0958cdc48f91d48" } Frame { msec: 1088 - hash: "2bfabef74bc6e1dbf72111838a0e7557" + hash: "b3e7cbc83c65ec61c768757798b17c58" } Frame { msec: 1104 - hash: "66616f01553364c5bd589b781e22163a" + hash: "b12b31d4959a697fcc8e54f1c846eef9" } Frame { msec: 1120 - hash: "58b9de84ebdaabee3917608f2af3bbdb" + hash: "77c3bbb94471cfbfd23cc3914d796dfc" } Frame { msec: 1136 - hash: "964d96b9b783efb1053501f8a6931248" + hash: "41975592e60f08a0296a8babe1da2df3" } Frame { msec: 1152 - hash: "055b77b921a2bac71b6780ab3179f19f" + hash: "0a5eea8a11b15ee8583f187f336f56c7" } Frame { msec: 1168 - hash: "074904f31b4f7cf0679f0bf7bba30af2" + hash: "bf9c02945fdee4b06353f8f7f4fca2a3" } Frame { msec: 1184 - hash: "f020a490b6800d5b4402ecb9a8bcd436" + hash: "157c92d133a39a2b1d20a551303d2f6f" } Frame { msec: 1200 - hash: "1615bdedf92f91f089e494d893840c4b" + hash: "213716cad9fa2179a17a512e8c03c8f5" } Frame { msec: 1216 - hash: "b6892f6a5db6d211f0d1bb2bbe5045bf" + hash: "0ec517c50e9e36fef4fb14318e298723" } Frame { msec: 1232 - hash: "5f0d903ba682923ac69454026a359ed9" + hash: "bab010fe0f5d3b57fd556a9b709c285e" } Frame { msec: 1248 - hash: "da5bae496a9ad28585151f4c75ee0c9f" + hash: "b6bdf2f21c4137d4b5f25e0fe728bba5" } Frame { msec: 1264 - hash: "68f553248f7ca116671782d1c357b552" + hash: "c091e46064c8096568224ed7e4c8dc4f" } Frame { msec: 1280 - hash: "5503df04dd7f4c88314f9d309a5b36b4" + hash: "c0a6ede96566533ab35384afa535530f" } Frame { msec: 1296 - hash: "cc48c1f58b553adcb27d60f176e2b910" + hash: "f61f5c7617700b9aad71206cfc9e402e" } Frame { msec: 1312 - hash: "661f546199d8753a7b6f6ccea5928c12" + hash: "c70c106d128051c06da3acdf817f5ffb" } Frame { msec: 1328 - hash: "0fd70052c100f77bddbad177d9e5573d" + hash: "624d7c7fb2f39225d51d1a548aa186ed" } Frame { msec: 1344 - hash: "488e0652c0ed82a014de63a64145c34c" + hash: "f052610f17a7484bf6cb2bd07aa91af6" } Frame { msec: 1360 - hash: "8b6bf2519080a6e4a61fe216f72dfa09" + hash: "44cd80041a1965c8c60fdffd9ae19395" } Frame { msec: 1376 - hash: "4dab1827f6ce9561297fce8e067df1bd" + hash: "7597f86b537fbd70260908c973f9db21" } Frame { msec: 1392 - hash: "b3f4c5cd728eaf2b791612a7fea64e7b" + hash: "30cd60db9aa2df2adc7d01091c905cb4" } Frame { msec: 1408 - hash: "3d01abd0b8a5a62d58a4c09546f212d8" + hash: "8da4613759e9bcb926a0c84556213eb5" } Frame { msec: 1424 - hash: "e76796498cf595c60d4b60cc0e320601" + hash: "1085fcc81f0aed8508817839ca748359" } Frame { msec: 1440 - hash: "1b31e96f2823e78a0c4029e7bc45b9f2" + hash: "b87f002bf6fb0684f0b3cf565507e066" } Frame { msec: 1456 - hash: "f75c182dc24f4fabe1034ee494dba2ad" + hash: "b60916a57aec6ebbd8b69be7c8d66e19" } Frame { msec: 1472 - hash: "646c12edadf350405709860381cfced6" + hash: "a28e1538d18ccb7485d0306b9f7b18a6" } Frame { msec: 1488 - hash: "b6719406da9f2484fe55e3c69184f86c" + hash: "832c857f2e05f2f82308cbf91f7bf401" } Frame { msec: 1504 - hash: "5456857d6d48d064df1cb3f35d8447b5" + hash: "ca3e50cd337a07ef07f063be28fa6dc2" } Frame { msec: 1520 - hash: "8d1809b568345e1532fb6d9428fc9729" + hash: "3ecf7faa733653ef20e4a26eb47d63d1" } Frame { msec: 1536 - hash: "5cffa76fe09a771a9f62a9f0392f0431" + hash: "f17a6be2e183f4c87e31004458e5052c" } Frame { msec: 1552 - hash: "8de59915e874ce829c691a19ac930f28" + hash: "bfa62672ee7fcd9c3a75b63198a4c2bf" } Frame { msec: 1568 - hash: "9027bbf8121f70d26530f70423ec05b7" + hash: "cdaafe7f622c18c2409ac539649de1cd" } Frame { msec: 1584 - hash: "d3d1d8b9f7b4eb74a8b7ae5cf19a8e20" + hash: "c957f5c58e0a9b315b51ac1012709493" } Frame { msec: 1600 - hash: "81ffcc0147e3124a3015deb7c0dbfd90" + hash: "925c55a8564f2318f9de4bd406cb5b13" } Frame { msec: 1616 - hash: "ca0c96e908f05c4ee1af1f80d7b432aa" + hash: "466208a8f6ecf45393be01a6dd7f2b0f" } Frame { msec: 1632 - hash: "2bdb6fbf942623856a6963c335794dd2" + hash: "35cff8c0f4b503ba4948966079484feb" } Frame { msec: 1648 - hash: "18ac264d9ea9b592b0738f1cf732f678" + hash: "47472faf5e9bf4b4e514abe55f1e0b72" } Frame { msec: 1664 - hash: "1ee9adbbae7b97dc050c82b8ed7b0aad" + hash: "b699165e354bcadfd0d914d9ecb3d2aa" } Frame { msec: 1680 - hash: "b502390c452883ade550d2761bb09d3d" + hash: "e255c047ce78f5677ccec8bd9737201a" } Frame { msec: 1696 - hash: "31a6f573fbb3f545ee051e2290938004" + hash: "bd4f08095a9c546a42c85e6df6eaf655" } Frame { msec: 1712 - hash: "3be9788228d9e540313e75671319c5b7" + hash: "ca65869f48b169260c3756d846a12f36" } Frame { msec: 1728 - hash: "23cbd718154f939d8270674e8f7607f0" + hash: "1921889beb8e61c8b959d4affa814465" } Frame { msec: 1744 - hash: "5f7f49b894b80ddd7cdc544a49ec24a2" + hash: "a9dda9ebaa97133c671917473721272c" } Mouse { type: 2 @@ -538,11 +538,11 @@ VisualTest { } Frame { msec: 1760 - hash: "2a1ddee3d3a0c2a4fffab3988e35e274" + hash: "cab96d2118b31d43e85dc902df2ed8ed" } Frame { msec: 1776 - hash: "2a1ddee3d3a0c2a4fffab3988e35e274" + hash: "cab96d2118b31d43e85dc902df2ed8ed" } Mouse { type: 5 @@ -562,7 +562,7 @@ VisualTest { } Frame { msec: 1792 - hash: "5594b9139480ba1c814509a049f9b6c5" + hash: "d21c8af68b314800b86922493db6553e" } Mouse { type: 5 @@ -574,7 +574,7 @@ VisualTest { } Frame { msec: 1808 - hash: "d8729deb404f5b821264743943adb288" + hash: "a80c0f6f679ba5f1354f8e16677c1125" } Mouse { type: 5 @@ -586,7 +586,7 @@ VisualTest { } Frame { msec: 1824 - hash: "6de642baf7698ec65d48ccf0a1e8e7db" + hash: "d8729deb404f5b821264743943adb288" } Mouse { type: 5 @@ -606,7 +606,7 @@ VisualTest { } Frame { msec: 1840 - hash: "f6732999861d1f638484a5aaa9cf0550" + hash: "87d41239eb7e170fa7a1ed523a9af942" } Mouse { type: 5 @@ -618,7 +618,7 @@ VisualTest { } Frame { msec: 1856 - hash: "7cd7c1679838f35556bd4ee4565b7a86" + hash: "1c185649e08a54a6949409ed7ee5dc60" } Mouse { type: 5 @@ -638,7 +638,7 @@ VisualTest { } Frame { msec: 1872 - hash: "4276a4d9350503603b0c9c98552697b3" + hash: "d82969ef0f4baf3c51e112e049cb1334" } Mouse { type: 5 @@ -650,7 +650,7 @@ VisualTest { } Frame { msec: 1888 - hash: "954a47627aee0a1128a78191bf32d984" + hash: "e746a3eb8527036b09afb9cdd3d15648" } Mouse { type: 5 @@ -662,7 +662,7 @@ VisualTest { } Frame { msec: 1904 - hash: "360a47795f7f9389f82f2f55fa1fe83f" + hash: "e1d6c01f6cd66a5bcdb08ca810a07282" } Mouse { type: 5 @@ -674,7 +674,7 @@ VisualTest { } Frame { msec: 1920 - hash: "19d4284791d0031342ba995bd17a7833" + hash: "fd0e9cf835131ee6cc5ecf67c6724d73" } Mouse { type: 5 @@ -706,7 +706,7 @@ VisualTest { } Frame { msec: 1952 - hash: "e9cd8fb810ecf39a90af039ead97aaf1" + hash: "69c17a9c18795b1d8ae63d36d76af626" } Mouse { type: 5 @@ -726,7 +726,7 @@ VisualTest { } Frame { msec: 1968 - hash: "42df1a0fbbe7cce5f2359d9e02696299" + hash: "c7ca4762498af158a2f2da6f5ae560ce" } Mouse { type: 5 @@ -738,7 +738,7 @@ VisualTest { } Frame { msec: 1984 - hash: "cc71434d6bd162386b80cb3b7e387116" + hash: "f500232133ec07a3b833b06425379484" } Mouse { type: 5 @@ -758,7 +758,7 @@ VisualTest { } Frame { msec: 2000 - hash: "a130b471b3903f3f1d77f2306da2b92e" + hash: "0a0cd0433e206dfc923ec0d3617e04a1" } Mouse { type: 5 @@ -770,7 +770,7 @@ VisualTest { } Frame { msec: 2016 - hash: "5bdb7472e325651e891c115953afdb39" + hash: "1754875ee6a5712ffb8ce1bbae6d4ed1" } Mouse { type: 5 @@ -782,7 +782,7 @@ VisualTest { } Frame { msec: 2032 - hash: "ab3a64b41c67a0b8a6c0830c0e0cb797" + hash: "1e743264f0a312bc0d0a023fbc6db832" } Mouse { type: 5 @@ -794,7 +794,7 @@ VisualTest { } Frame { msec: 2048 - hash: "8eb1f2c8c02c2acf4262e05000045649" + hash: "ab3a64b41c67a0b8a6c0830c0e0cb797" } Mouse { type: 5 @@ -806,7 +806,7 @@ VisualTest { } Frame { msec: 2064 - hash: "514220d357c4a26e4aaf9ed20d3f4f33" + hash: "d05f721f1d7d23d6e0cc67993bf1fa8f" } Mouse { type: 5 @@ -818,7 +818,7 @@ VisualTest { } Frame { msec: 2080 - hash: "e44526ef273048028d5989fc662eb7e6" + hash: "419c09739f855c53be3427a71aa3faf9" } Mouse { type: 5 @@ -838,7 +838,7 @@ VisualTest { } Frame { msec: 2096 - hash: "29ac091428a89cfcb4c52c08e0e10327" + hash: "f0ae80ed5965d7531d6a653c80eed444" } Mouse { type: 5 @@ -858,7 +858,7 @@ VisualTest { } Frame { msec: 2112 - hash: "82beb845af88fc9432dc104ff805a146" + hash: "1419fe55cc28ce9690846d4c03275fe7" } Mouse { type: 5 @@ -870,7 +870,7 @@ VisualTest { } Frame { msec: 2128 - hash: "371392f267b2c1f4e29963506180e246" + hash: "2e22df53697a599b0e44fb2a3986dcd0" } Mouse { type: 5 @@ -882,11 +882,11 @@ VisualTest { } Frame { msec: 2144 - hash: "1da06d036cc0a2d2de34eee37b6981c0" + hash: "96f763c555b523d9b7ed7a0a159db368" } Frame { msec: 2160 - hash: "1da06d036cc0a2d2de34eee37b6981c0" + hash: "96f763c555b523d9b7ed7a0a159db368" } Mouse { type: 5 @@ -898,31 +898,31 @@ VisualTest { } Frame { msec: 2176 - hash: "4980de22342d1085e205401090777d24" + hash: "20f9cf7787c8cfd4843289f5ab2012e7" } Frame { msec: 2192 - hash: "4980de22342d1085e205401090777d24" + hash: "20f9cf7787c8cfd4843289f5ab2012e7" } Frame { msec: 2208 - hash: "4980de22342d1085e205401090777d24" + hash: "20f9cf7787c8cfd4843289f5ab2012e7" } Frame { msec: 2224 - hash: "4980de22342d1085e205401090777d24" + hash: "20f9cf7787c8cfd4843289f5ab2012e7" } Frame { msec: 2240 - hash: "4980de22342d1085e205401090777d24" + hash: "20f9cf7787c8cfd4843289f5ab2012e7" } Frame { msec: 2256 - hash: "4980de22342d1085e205401090777d24" + hash: "20f9cf7787c8cfd4843289f5ab2012e7" } Frame { msec: 2272 - hash: "4980de22342d1085e205401090777d24" + hash: "20f9cf7787c8cfd4843289f5ab2012e7" } Mouse { type: 5 @@ -934,7 +934,7 @@ VisualTest { } Frame { msec: 2288 - hash: "e0a52543b976dc998615704c63b1f3e9" + hash: "1241895174f4d8e4386c3957e3d2e292" } Mouse { type: 5 @@ -946,7 +946,7 @@ VisualTest { } Frame { msec: 2304 - hash: "82beb845af88fc9432dc104ff805a146" + hash: "1419fe55cc28ce9690846d4c03275fe7" } Mouse { type: 5 @@ -958,7 +958,7 @@ VisualTest { } Frame { msec: 2320 - hash: "e44526ef273048028d5989fc662eb7e6" + hash: "419c09739f855c53be3427a71aa3faf9" } Mouse { type: 5 @@ -978,7 +978,7 @@ VisualTest { } Frame { msec: 2336 - hash: "8eb1f2c8c02c2acf4262e05000045649" + hash: "ab3a64b41c67a0b8a6c0830c0e0cb797" } Mouse { type: 5 @@ -990,7 +990,7 @@ VisualTest { } Frame { msec: 2352 - hash: "442958c3a705745204db96ff9902b7fc" + hash: "a130b471b3903f3f1d77f2306da2b92e" } Mouse { type: 5 @@ -1002,31 +1002,31 @@ VisualTest { } Frame { msec: 2368 - hash: "a130b471b3903f3f1d77f2306da2b92e" + hash: "0a0cd0433e206dfc923ec0d3617e04a1" } Frame { msec: 2384 - hash: "a130b471b3903f3f1d77f2306da2b92e" + hash: "0a0cd0433e206dfc923ec0d3617e04a1" } Frame { msec: 2400 - hash: "a130b471b3903f3f1d77f2306da2b92e" + hash: "0a0cd0433e206dfc923ec0d3617e04a1" } Frame { msec: 2416 - hash: "a130b471b3903f3f1d77f2306da2b92e" + hash: "0a0cd0433e206dfc923ec0d3617e04a1" } Frame { msec: 2432 - hash: "a130b471b3903f3f1d77f2306da2b92e" + hash: "0a0cd0433e206dfc923ec0d3617e04a1" } Frame { msec: 2448 - hash: "a130b471b3903f3f1d77f2306da2b92e" + hash: "0a0cd0433e206dfc923ec0d3617e04a1" } Frame { msec: 2464 - hash: "a130b471b3903f3f1d77f2306da2b92e" + hash: "0a0cd0433e206dfc923ec0d3617e04a1" } Mouse { type: 5 @@ -1046,7 +1046,7 @@ VisualTest { } Frame { msec: 2480 - hash: "374dc7c3ea0c93ac93a857a4620bc031" + hash: "47e86b008567366f37ac043ed8802d53" } Mouse { type: 5 @@ -1058,7 +1058,7 @@ VisualTest { } Frame { msec: 2496 - hash: "0b943f48b39053bfc906a4a47a37d68a" + hash: "92e1d5dbc85e777785cc68171a0a3fbf" } Mouse { type: 5 @@ -1070,7 +1070,7 @@ VisualTest { } Frame { msec: 2512 - hash: "099fbdf1560dd79b700914863406c904" + hash: "360a47795f7f9389f82f2f55fa1fe83f" } Mouse { type: 5 @@ -1090,7 +1090,7 @@ VisualTest { } Frame { msec: 2528 - hash: "3aa1614cc49504d19e979ebf190f2970" + hash: "acefb43050e140d689f1d377f50f5c83" } Mouse { type: 5 @@ -1102,7 +1102,7 @@ VisualTest { } Frame { msec: 2544 - hash: "837420c71a5010f25cccd05e5e9b3eec" + hash: "4bc43ae81aac757c872157ac9b41a2d9" } Mouse { type: 5 @@ -1114,7 +1114,7 @@ VisualTest { } Frame { msec: 2560 - hash: "871349fc09f418717231b8f8e20a7fff" + hash: "41421089f087c54ebcd9fa44e95bd96e" } Mouse { type: 5 @@ -1134,7 +1134,7 @@ VisualTest { } Frame { msec: 2576 - hash: "9b6022024aae22ec1f522fd00ed29e9b" + hash: "db0f09393b5c9284142f9eb3cb5952ce" } Mouse { type: 5 @@ -1154,79 +1154,79 @@ VisualTest { } Frame { msec: 2592 - hash: "8d9410909ae259388fa94b3a60342608" + hash: "9491689e51ec46bec07fb8b280daef80" } Frame { msec: 2608 - hash: "0ceb355351ac99458ba75776c11b3039" + hash: "44a30531642ada65c052afe30874d7ba" } Frame { msec: 2624 - hash: "61ca917ecc8ad4c35b7f2a3b828542bf" + hash: "6bf415b82e7cfa68b8321571ab619c3f" } Frame { msec: 2640 - hash: "fd5db933d1d8684b15eb5239d19d8919" + hash: "645e43948279d528020070125b71c33b" } Frame { msec: 2656 - hash: "13f466a82ee22cabf5cbd2463f55b46a" + hash: "495d14df729eede7e560f2e841bae142" } Frame { msec: 2672 - hash: "3b7f7880f5b568a0e45cd0e268822f3a" + hash: "fa3b12e9869bf4254c8cdf6e5b10bb2d" } Frame { msec: 2688 - hash: "cca22501c3b5a2ed4264ba060eeb1a6e" + hash: "482ce41c4b918a71b803c5f521ea494e" } Frame { msec: 2704 - hash: "efe5258ac5962d1d2bfa4286c1621830" + hash: "79d70563c7e139d9f9785565219133c7" } Frame { msec: 2720 - hash: "141998cff765a4e90836b871f229a1ca" + hash: "0dc70772aa50445c1cb7dbd8ee0092b0" } Frame { msec: 2736 - hash: "9d684675fa883d5488194effcb1d8d0a" + hash: "222d638b8fb896563028f029e6fb3c49" } Frame { msec: 2752 - hash: "fa87f781048f264ddf447441a714ee50" + hash: "20b8fc718d9329c9c8901fdfe14557a2" } Frame { msec: 2768 - hash: "61b4992b9c52222345c9ada3148d50f9" + hash: "e3972b3244e4a98c9ee4df2d4b623c12" } Frame { msec: 2784 - hash: "3e255a634d215746cb95f5d765335ea2" + hash: "e3a4b357c00d3d49e4a7d90f6f57054c" } Frame { msec: 2800 - hash: "d64a755e47a502244e7f14f2091f0ca6" + hash: "44ad81d2ad0d502b003e148412871a41" } Frame { msec: 2816 - hash: "582562992b0652f995b439897182e0f8" + hash: "47d757dab5c72cad08cb8026631d67e6" } Frame { msec: 2832 - hash: "2d69b1a274c262faf5ce9ed3191c7d22" + hash: "8522a3b6202b303a9e65a9e136423e27" } Frame { msec: 2848 - hash: "36c04a2bd58124877a332bb6a262a7e5" + hash: "70e3cd650472d0e95f4d6ca9e34a2ce1" } Frame { msec: 2864 - hash: "798711925da8f5034039dad86cc1fad1" + hash: "19a7825cd8c0eaa6f313ec77fff9ec1b" } Frame { msec: 2880 - hash: "31495157a10c3bb4dd70cfd857fd07e6" + hash: "579688ff6ec910570c0c0c60fdf44cf6" } Frame { msec: 2896 @@ -1234,207 +1234,207 @@ VisualTest { } Frame { msec: 2912 - hash: "b81330eb50dbd39f1abcdb8ff1553d08" + hash: "7ab8cf0d0b650e8f994a9beed8be29fb" } Frame { msec: 2928 - hash: "ececcb86b76e9cd2f57585bd87e16bef" + hash: "92e9be6d36844bb475b861ba9c4bc3ff" } Frame { msec: 2944 - hash: "2c37e2c24cf22a334cfcc6f2691ad9fb" + hash: "08b9cce3b2071b328054af6bcb6755c7" } Frame { msec: 2960 - hash: "ad0572020d273dbca046357aa0f8bf3b" + hash: "b505d2f41a6db06d4ca03f5340800aa6" } Frame { msec: 2976 - hash: "51a469e059a5e1a3675db731f55209d3" + hash: "f0267f59e247e24e4cf9c56f8931112b" } Frame { msec: 2992 - hash: "dca7d50a3faab1f049bece34bd16b8c4" + hash: "ddbc73e2df4da11d5122539a00c126de" } Frame { msec: 3008 - hash: "86dc86bafb01fa086caa3b22f9d393d9" + hash: "8dd67df95fae14079ed5b83c421a5b6e" } Frame { msec: 3024 - hash: "05754bd86070a6f01bf90ca2b964f695" + hash: "7b217f7c51087a07e8922b0286b2c1dc" } Frame { msec: 3040 - hash: "911ec290ba303f0cac258cbb893bbf78" + hash: "e464b5121f3204c64cafe2f5e31cf497" } Frame { msec: 3056 - hash: "f27f29249426f46b8fb508372bcbb32d" + hash: "7fc2018f8db17b65fd01b2ddfa44f66d" } Frame { msec: 3072 - hash: "2f452e2d519f33ee03db67ebd7f69e3b" + hash: "a5d1871511eac7224292b3552da466a8" } Frame { msec: 3088 - hash: "35cf7747a75ea3f727c2fe1dae6136c5" + hash: "2f0a55cf3cd30da77fbb73e749b729a3" } Frame { msec: 3104 - hash: "6773187693f52a8f2c0e358e379b4d21" + hash: "9aab649b6664c179878d0ead438dd751" } Frame { msec: 3120 - hash: "abca1f00f7ec60c8c80ba5345898e54b" + hash: "2ad733363d239d9a3ea1c31427a3b3fe" } Frame { msec: 3136 - hash: "9bee1da64534da97de349e1ee973cc9c" + hash: "e73b4fd7cb6285df9a77d666f25ab245" } Frame { msec: 3152 - hash: "087df06ca720918482f2e29653c7fbac" + hash: "53b05d8be52a74c3a24b88779d4927bf" } Frame { msec: 3168 - hash: "5b08911bf0975bd6615bf29294e4b1f5" + hash: "04fc6aac5f090960cd87eefb4273fb0f" } Frame { msec: 3184 - hash: "dead4bb3768b65418f68bae7dd0bf004" + hash: "294c842a71b5e4927146952ce865c8a2" } Frame { msec: 3200 - hash: "6bfe4c866936d8ae509650419ae12455" + hash: "ac6f7afb4a5e67e2edd8300e7dfdff13" } Frame { msec: 3216 - hash: "7428bdd9609a2594be08fdeac6ff1e17" + hash: "8a7ab6dc549b247f3b897e098d784dd8" } Frame { msec: 3232 - hash: "d02f9f693e0ae8c7034bf727064ec28a" + hash: "0a3144254f66a6b005b95a026496cd32" } Frame { msec: 3248 - hash: "b6284efd849547bbfefc22ec77d61062" + hash: "ca457a1c503a980687926e31ac16995b" } Frame { msec: 3264 - hash: "4b78b647be8e918e85edab0c23b6f882" + hash: "c17922ca04f5ce9916e2907a6c28bf8b" } Frame { msec: 3280 - hash: "c4a02c18ce3574d057e6a54b30efadb3" + hash: "b2a071734226b905f6c6f5652f645517" } Frame { msec: 3296 - hash: "d1d190010239d0b02a697d1c63c748ab" + hash: "1f41a314699151771d7d1ca672aaba8f" } Frame { msec: 3312 - hash: "b198689d11aa59d937297e6fcf675c93" + hash: "de94c2ad2e74036d975e8402dd8b06e9" } Frame { msec: 3328 - hash: "218f3371beea895aefd28aa874012dcc" + hash: "9cfe0627852cefe67fc0b44b31085b4a" } Frame { msec: 3344 - hash: "1135de1b9a4ebf1d2829546d3c3f3903" + hash: "de7ab5230efb63264f76fa1f1b61dcfa" } Frame { msec: 3360 - hash: "773a64cc7bb8e99a25078f348986e28f" + hash: "5ad22cf9e1c9a02cfc570beaac55bee0" } Frame { msec: 3376 - hash: "e8ce58aeb18b3f56ebd3d6f61ac94657" + hash: "9e6210d9e6bfda4fe0695b75d03435e2" } Frame { msec: 3392 - hash: "6de92679c32c7f3e9d9b6ba3a47e65eb" + hash: "d3989a9fb7e99d16032fa1842364f2ed" } Frame { msec: 3408 - hash: "339b37207af10ad986269e21ab37ff6d" + hash: "2f3e7040a4966e56858312f6534e9e77" } Frame { msec: 3424 - hash: "ac01f0708800fdfdacec67ac9e80602f" + hash: "16bb17f511519337be2e60d8b9f95149" } Frame { msec: 3440 - hash: "9de89a748b1e18eb6ed94875af6f26de" + hash: "819250fd9899a9457a9300f942f4d8bf" } Frame { msec: 3456 - hash: "d091e4a93c2beafb0ce4b6dff6d5b05f" + hash: "6639a15d4d23540ccf63c9bea0e1689e" } Frame { msec: 3472 - hash: "9532271085864d2fde3aa6e572599588" + hash: "14b553132a86e57577c416e6f6c53433" } Frame { msec: 3488 - hash: "d00804b42ab1c1f082a9f394ff4d666e" + hash: "f7a95239db44b66698d29f0daae826f1" } Frame { msec: 3504 - hash: "2c745f007353e6f8a7195470ba9492c2" + hash: "b5a6abb5294fb9b069ab8a075003cb61" } Frame { msec: 3520 - hash: "b4e952acb734ab1a608297fcb44fbe46" + hash: "391c1c43ce893aeefc42d164e6e8aaac" } Frame { msec: 3536 - hash: "75ceed3c2ddd557866145393fa50a12f" + hash: "271addef36d51d904bc1d68f65b66de3" } Frame { msec: 3552 - hash: "8b83b80554dd4a1266184092d380554c" + hash: "73a23e56edcd64ac6147aff27b785ebb" } Frame { msec: 3568 - hash: "973bddb1b2f9dbadd40c0de3ca7c3510" + hash: "bd43145ae22086348cb5e68765a42ac1" } Frame { msec: 3584 - hash: "5691b5bf54b50d4ff0a717873e001c00" + hash: "4b2706d1215f2b5b08ac87e40ba8c21b" } Frame { msec: 3600 - hash: "8b26b0aa8b06da031354c59d7fb41bf0" + hash: "6420fd46fd8068010d3caaa68eea457e" } Frame { msec: 3616 - hash: "45786c39a10b8e1cf399df98f3fb7ffb" + hash: "188499a79313d984ed1d710329b0237f" } Frame { msec: 3632 - hash: "c6d0be03e167c16566372cc992604dfb" + hash: "12da197320858ea4f8a1437b7ceac95a" } Frame { msec: 3648 - hash: "8d6e057550632d143faf996a62bbd1cd" + hash: "14bdec5663d1a81fa617d3b81e19f8b4" } Frame { msec: 3664 - hash: "7e3a321b95d5f62f0da2b10324b485b6" + hash: "3430047eca214a217aca0bd71814f4db" } Frame { msec: 3680 - hash: "e842f18dfd36947b2fa086a4d0bb2ec5" + hash: "974c431fe7030990389c7fc719655cfd" } Frame { msec: 3696 - hash: "a9359e143dae4113437a43cc00493479" + hash: "d38f3153b3cf39a278dc6948ff9ef71d" } Frame { msec: 3712 - hash: "2eca61c837cca9beb6d1834eafe8c538" + hash: "0c6eec50abcf4afc20311ffa1326d4e8" } Frame { msec: 3728 diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.0.png b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.0.png index af0e781..da688c7 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.0.png and b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.1.png b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.1.png index 6f1878f..618d238 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.1.png and b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.2.png b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.2.png index 97f09f7..0688ed1 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.2.png and b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.3.png b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.3.png index 878875a..ec6e330 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.3.png and b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.4.png b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.4.png index cdbe606..1692d17 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.4.png and b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.5.png b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.5.png index 7b78f7a..d70704d 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.5.png and b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.5.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.6.png b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.6.png index d7b5943..f8f37c6 100644 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.6.png and b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.6.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.qml b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.qml index bc900c6..3828e76 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativepathview/data/test-pathview.qml @@ -182,7 +182,7 @@ VisualTest { } Frame { msec: 592 - hash: "731c8547a72c64ac86aec87c0a9a12cb" + hash: "683d9f54c75f5b1ed082edb0b4559bc8" } Mouse { type: 5 @@ -202,7 +202,7 @@ VisualTest { } Frame { msec: 608 - hash: "d9d7dd7ea05499f028964fdd11af0fe6" + hash: "02e5238c0764f370d0f463cc3f477df7" } Mouse { type: 5 @@ -214,7 +214,7 @@ VisualTest { } Frame { msec: 624 - hash: "361879f350c448a484b71a9e7a42b87f" + hash: "02239cd84ce630a89b94dbcf469d9a70" } Mouse { type: 5 @@ -226,7 +226,7 @@ VisualTest { } Frame { msec: 640 - hash: "998da4b3e36ee3e17deb2b5a097661da" + hash: "6cdaa8ffc906ade671fe259711e76f24" } Mouse { type: 5 @@ -246,7 +246,7 @@ VisualTest { } Frame { msec: 656 - hash: "1b3f9758bd9842cc9545b494499f87c4" + hash: "db00a0d69efd43f69c83dafbf38a06a6" } Mouse { type: 5 @@ -258,7 +258,7 @@ VisualTest { } Frame { msec: 672 - hash: "7e87f7c233dad50549e4bdafe10bb48e" + hash: "76fdf4cb75376ec3a9e084d93765c5cb" } Mouse { type: 5 @@ -286,75 +286,75 @@ VisualTest { } Frame { msec: 688 - hash: "01ceb2fea81f2192ab11d7d6e1df879a" + hash: "b12e86c13e012c5992930b3e559c337c" } Frame { msec: 704 - hash: "9afa862248bd527e07374a5c2f2036a1" + hash: "4056e78a59e8f1e030f3e3a51c436b46" } Frame { msec: 720 - hash: "e06439495148bfbf059cfe2b5df22840" + hash: "c84781b7586943ef889b8911c23e91db" } Frame { msec: 736 - hash: "b206a28d6f3be8cba9595849328b27b8" + hash: "cd952ffa63dbcb772b666ce755c9a2f1" } Frame { msec: 752 - hash: "646e4529bf554dceee0140ec56a02d1c" + hash: "2a31778e3ab7c676ae82278948cef12a" } Frame { msec: 768 - hash: "31bdcf1f178d65e033e23dfbdcb9dc5f" + hash: "ef6319b262fc299b14b40d1521f9c9c3" } Frame { msec: 784 - hash: "b4e897356814ca2dddbc3644b1782f36" + hash: "05ccb24a2025df31188b413c8d837232" } Frame { msec: 800 - hash: "669e5d682aae8727640e0e0f4e855a60" + hash: "df31f9dba1a762397c0364d7e83052ef" } Frame { msec: 816 - hash: "892007b1a379c617412502499df92d01" + hash: "6eec07606ef320072ea23ceedb3f6b29" } Frame { msec: 832 - hash: "f4d66daa2d428aa712a73ded2de7a361" + hash: "e3502cb53c6e17373de3b718a8212f4d" } Frame { msec: 848 - hash: "0c21e69bed6dc2d6b7c23c20714aca67" + hash: "2e01e2e252ca9fb3e7107f04a3ba4031" } Frame { msec: 864 - hash: "189909bdbfeb1f02ad527fbc438d567d" + hash: "547a9f25404c2bf7737526faf67a459d" } Frame { msec: 880 - hash: "b2fcbc0657474e1b6d27e1f2f93be35b" + hash: "aa9c3122e3c2a7ed450a0afffbcf4e6a" } Frame { msec: 896 - hash: "4407d7ad1b6a40b2355145aee136ff15" + hash: "1535dea92038cf87395a616841fd9bf6" } Frame { msec: 912 - hash: "347ada687af0a97f0a862a1f3a1132be" + hash: "1535dea92038cf87395a616841fd9bf6" } Frame { msec: 928 - hash: "db6217ff0194c5a3f9ca9ea7e3b3dfd8" + hash: "1535dea92038cf87395a616841fd9bf6" } Frame { msec: 944 - hash: "8a94ca0ee93daaa1bdcdbfc8a80713c1" + hash: "1535dea92038cf87395a616841fd9bf6" } Frame { msec: 960 - hash: "ab24d0c8545518cbaff876976247be2c" + hash: "1535dea92038cf87395a616841fd9bf6" } Frame { msec: 976 @@ -450,7 +450,7 @@ VisualTest { } Frame { msec: 1216 - hash: "c612bb9906f18786ef7cc6f4e56de218" + hash: "aa9c3122e3c2a7ed450a0afffbcf4e6a" } Mouse { type: 5 @@ -470,7 +470,7 @@ VisualTest { } Frame { msec: 1232 - hash: "ffec210dd863ed32a780506f61b06056" + hash: "b889647c08af7db2e6582d9927cb1cf7" } Mouse { type: 5 @@ -490,7 +490,7 @@ VisualTest { } Frame { msec: 1248 - hash: "9613c658f267d19b84d6e7ef2a676fed" + hash: "ac97616fc3c54711bb067cc72c15d4c5" } Mouse { type: 5 @@ -510,7 +510,7 @@ VisualTest { } Frame { msec: 1264 - hash: "8c5dd8d0f9f434530b20e14a84af9f46" + hash: "b38c46d537e6e622c8a0ecae76dbe506" } Mouse { type: 5 @@ -530,7 +530,7 @@ VisualTest { } Frame { msec: 1280 - hash: "a956e8e9ca8958c387f8f5ce374cdec9" + hash: "6261f2f16bdd89142cfbf1de4ce64a32" } Mouse { type: 5 @@ -550,87 +550,87 @@ VisualTest { } Frame { msec: 1296 - hash: "712e865d894f179cfd9d86b08e60811a" + hash: "d4f8d57bae3d5bc888a4bbe2812b3fdf" } Frame { msec: 1312 - hash: "db5c1f2af2e72ff4edce83cb342b5263" + hash: "4e0a90dda433c1615ea367ec90917409" } Frame { msec: 1328 - hash: "834f0aa26c66234491468c1b27a2d329" + hash: "b20e244f27dae505568fcba25cccb5d8" } Frame { msec: 1344 - hash: "78a2a4b60db730a7367bc77e1dfc1a1b" + hash: "f31d264a002718787ea55a6312c7f9f2" } Frame { msec: 1360 - hash: "a8ff2277b5f7d515bc5a9af1f0e77197" + hash: "0abbf36b5e3f2db9288bde05825dc111" } Frame { msec: 1376 - hash: "e05d730624025000b831860f5b99e8ac" + hash: "64fc0f18174f5e8002cf79a908cc08df" } Frame { msec: 1392 - hash: "54aa124492ea742e4327f1d2b45ab620" + hash: "430d7719ebf3b5835af92683cff10e56" } Frame { msec: 1408 - hash: "bc700bee41ac384a2555723b010e9041" + hash: "411a8fe1ee3a0510574cbf6a69d23456" } Frame { msec: 1424 - hash: "26f66098c505cea4715a89b6a2232759" + hash: "47e431bf01575c44f7c1fa3e20409866" } Frame { msec: 1440 - hash: "00f3255a3ead315410d8c0d338779689" + hash: "d17b62a0b52b4a5220b29b55f764abc6" } Frame { msec: 1456 - hash: "154e7d86d7602ebba38a0d63b211894d" + hash: "9bd0d8dfbee424bd0ccf72703a7c51c2" } Frame { msec: 1472 - hash: "87cf2bff69ebd75af69d0a7c7f668b07" + hash: "8ef880c18ecd8adb66e7e0a2dceb61fc" } Frame { msec: 1488 - hash: "f221b870ecccb1669b6223e5431c31d1" + hash: "fcc1bc7f35342f595448ca2870478b50" } Frame { msec: 1504 - hash: "40a9d4c522d9fd831be2ca698ac10670" + hash: "cf360de1c6649e45beb974ddbe436ea9" } Frame { msec: 1520 - hash: "7ad47479d99fd4d9fde96fef242bdc20" + hash: "b2a6acf1fed92069fd2779b1fa236c95" } Frame { msec: 1536 - hash: "b91912801c790d849399306c693a4d33" + hash: "7128a442b6bb06038477d46ac3da5021" } Frame { msec: 1552 - hash: "e5c8d361abcbc15df0b0b82728cb5b84" + hash: "6a0ab3ccc3749b9a2b9a5b5851b0cf70" } Frame { msec: 1568 - hash: "3f2f82c925e93d4593581cdba16f361f" + hash: "18f6cdad215c55ea8335d06110715aa8" } Frame { msec: 1584 - hash: "7007fd0595c188a9a5b3ff31b0514aa5" + hash: "137420f4b1f51440c3aefd18dbdad71d" } Frame { msec: 1600 - hash: "118661091df765ae35c152c7fe818029" + hash: "faf898388f87948fbacd74589cb18af0" } Frame { msec: 1616 - hash: "0a8edd2a35f7921ced6e3aa7e571bc4b" + hash: "b818181b3fee6f5a35a0da6c0f8e240e" } Mouse { type: 2 @@ -650,7 +650,7 @@ VisualTest { } Frame { msec: 1632 - hash: "ef734ce4d7e1aee19a78b743c9923f90" + hash: "2e74cc22a4e5b20cc231bc08e15e662a" } Mouse { type: 5 @@ -670,7 +670,7 @@ VisualTest { } Frame { msec: 1648 - hash: "09a9925d5ec2fd03cfbf469bc22bf201" + hash: "27be226c985bb0143d1dca3e4be4b10a" } Mouse { type: 5 @@ -690,71 +690,71 @@ VisualTest { } Frame { msec: 1664 - hash: "6babcbf5582d5ed8f0cf52e233867055" + hash: "9384d46806b2a8091b6d16f7636d6ae4" } Frame { msec: 1680 - hash: "94dae9d52f3523e17f3f0e59ca24a069" + hash: "684a17820c3693d893f8199cd7c7076f" } Frame { msec: 1696 - hash: "0d417d25893a0454a729f5c23a2a6c28" + hash: "dc1facc91b6935983bbcd2eada452d4d" } Frame { msec: 1712 - hash: "afd1bbca1dcfea8d1f0a340d86b07fa8" + hash: "6bb08cc431a3ecca1a553ea10669bb0c" } Frame { msec: 1728 - hash: "97e98982742b94dba8b6cb59397bcb66" + hash: "1330640d4ca9ac69dd089cea34b7f61d" } Frame { msec: 1744 - hash: "a0ad8cbbd0daa0afd3831e8a071b9a0e" + hash: "95370207a55b56c41923937b40d5fe6b" } Frame { msec: 1760 - hash: "f71826bcd6ea91d2f64d627a390c379d" + hash: "c36b60f81e7de5c0e5a59655041adff2" } Frame { msec: 1776 - hash: "7699da01cf1ee9a7f404ab053241b530" + hash: "297abbc6b38a1909324fcee6d8b1d908" } Frame { msec: 1792 - hash: "6aba727ecc562d7b5555eae427e6978b" + hash: "0af89e3bab7c517f375897239ea35153" } Frame { msec: 1808 - hash: "ef9c6daa5b04b0be9159594e04524fba" + hash: "05109c3dfac7f65fe00e81d1a145f048" } Frame { msec: 1824 - hash: "6293ede5de83f3b01a3b4d8d87648089" + hash: "57e1e871cbbc627f2fb9bf5583c4f097" } Frame { msec: 1840 - hash: "c3b34d8592f88622cad0f9353d08e739" + hash: "5220aecdd1516d94f0698e79f17fee57" } Frame { msec: 1856 - hash: "880f3cb9d5dbe06cdf17e3a953d4562d" + hash: "f3d8c908e61e5d61bbeeb9c6b5e8a704" } Frame { msec: 1872 - hash: "ed381ce920863a5a6627f383a88ea2fe" + hash: "f27867aeb39ef64ebd50b5d79b69337e" } Frame { msec: 1888 - hash: "b5bc40b8c4abb6458aeb67eda73507b6" + hash: "b807b4e74a0f008df3f4534901debe38" } Frame { msec: 1904 - hash: "482cb61b7fac4b1654483f846b8b6717" + hash: "e19832a0a7fcd57efe46cb0102a8d418" } Frame { msec: 1920 - hash: "e1a4a16d2cf5132a9fbb0869ed6082d9" + hash: "f0dcfd9b22f385fedfde964774480f85" } Frame { msec: 1936 @@ -762,171 +762,171 @@ VisualTest { } Frame { msec: 1952 - hash: "f8874aaab1e65cf9b86d6b5174c3d2c8" + hash: "746c60e03c50dc2e28c62fe52a8dd9d2" } Frame { msec: 1968 - hash: "d8490adeaa793352b812e832f4cb079a" + hash: "27d6da44b605cb38552147fdf451ef45" } Frame { msec: 1984 - hash: "85fdb99926ba34a25fa964df11af9a5a" + hash: "c41d5491c417531ee86ac6ec8571c6a8" } Frame { msec: 2000 - hash: "ad137a75981c181838d97cbe313063ac" + hash: "ac57c578e7e2cbb57e982d6da5fb7268" } Frame { msec: 2016 - hash: "bfa5cecfc0058b56ca66aa816ea098dc" + hash: "db40e242fabf119f0e7187eeb96a34a5" } Frame { msec: 2032 - hash: "53fe3960c2f332eb099fedd8421fcc94" + hash: "0850d4b73a664ee0f1ed6d6e0615ea80" } Frame { msec: 2048 - hash: "61b99ff526560c1589d2fc8737af2af2" + hash: "ae6cb0bfda1cea70b3641251d0dc60c4" } Frame { msec: 2064 - hash: "f9dd63709bed985f5d691d27c0d32484" + hash: "67a28c2188aecfc5dcccedd257789dbc" } Frame { msec: 2080 - hash: "964c20ada9ad9e83edd9b429bf681b83" + hash: "4355f220c8a87ad981088fb23bb15f11" } Frame { msec: 2096 - hash: "997bc44a319c8ce8212387f7564c4005" + hash: "2081c1ffe35f20dd827b3d9f52be90b3" } Frame { msec: 2112 - hash: "892eda6e7446321483ffb1dbf44a0432" + hash: "ba13b0b4790aec7084b5553fe0b0d72b" } Frame { msec: 2128 - hash: "62068dca6da7227882b6c3bc147c6f24" + hash: "7f289e50f1bbd570b6bc2ca1998f8493" } Frame { msec: 2144 - hash: "2cd0c351c53234d4bbf4d2c74d313f59" + hash: "8bb3a37f416032d40cb5f919abb42e30" } Frame { msec: 2160 - hash: "cf812f971bb4f8ab3116cf2b14c325df" + hash: "bcc69f859b3bff759e0c732c7adc23f0" } Frame { msec: 2176 - hash: "be296bd9ab4c38d95e6d7d445d8c7f68" + hash: "d3e8aae08a2518c039d6bda80fc520a4" } Frame { msec: 2192 - hash: "536d0214c8c3f69ce8d4e1585128b2b8" + hash: "955212dc28a6f8fe59c658401284d3a3" } Frame { msec: 2208 - hash: "f71452a0a6ef80758800d67e601a162b" + hash: "8eebcff152288a4ab2a3e64fd7ba6f80" } Frame { msec: 2224 - hash: "e57c099beb70d0a4ca2cbc94a2c3887e" + hash: "85fe363271d480163fb7847a3501472f" } Frame { msec: 2240 - hash: "84cea22f64ff8b8838a7db0b19af1a4e" + hash: "23190380ddcc4e3afce2164a4743d179" } Frame { msec: 2256 - hash: "04aa0d5d089779977f569d0f849b97dd" + hash: "40ca7c3d24883a8d3457de934b247280" } Frame { msec: 2272 - hash: "85b52e125142d52d531132939930dd93" + hash: "299ed19fa4d213e0e9dd127e8799d5fc" } Frame { msec: 2288 - hash: "19bc7b318c21a6ce2be8ebde2e624fc3" + hash: "e39a067860fa7dcb4efba87aee58cc77" } Frame { msec: 2304 - hash: "9cc744249cb031f0400e87893c1642af" + hash: "a709045723c4a9a2e85295fcc360eea9" } Frame { msec: 2320 - hash: "a834706bbf573f37cf9f59c6c6cbbfa5" + hash: "029428301287e4c7cd2f8a1fa6a25381" } Frame { msec: 2336 - hash: "8db3eea9d47a162d8b0ee9cd18e194f3" + hash: "aef25177af3511dc99004a1e37f7f5d3" } Frame { msec: 2352 - hash: "29da9b8da8f572ace93250abb8626a90" + hash: "f9e11fd7023a72366dacaaf19b2eb81c" } Frame { msec: 2368 - hash: "179b74316d885f9ee41066b9c475b57f" + hash: "51f7c896d79c900a2b54a8c756228200" } Frame { msec: 2384 - hash: "35464509ef5a9919af46a30d40c3edc7" + hash: "28c18081813c801c6793873ec23e6c0c" } Frame { msec: 2400 - hash: "aadec42355d38d149421ef6c93783e69" + hash: "39df3050c4100e8a4f6e648b4aa16ba7" } Frame { msec: 2416 - hash: "cb8609791270e8e3c13da4579f85595f" + hash: "752cb6969fa8b76abf4bb229edb2c21f" } Frame { msec: 2432 - hash: "93e81e036a1bc30cc63ce703f8f43a34" + hash: "54d50f6c980cb04a1634622a29a6f0e9" } Frame { msec: 2448 - hash: "d08d18adf9ca92cd6597c2f51ae90383" + hash: "d510db233f025b026f896b760848cc07" } Frame { msec: 2464 - hash: "f54ec103787023647beaa4b992340385" + hash: "e5c8d361abcbc15df0b0b82728cb5b84" } Frame { msec: 2480 - hash: "61c9f72d78fce0b966a278abacc97ce6" + hash: "e5c8d361abcbc15df0b0b82728cb5b84" } Frame { msec: 2496 - hash: "5b0500ed0562b11280c3424412f74188" + hash: "e5c8d361abcbc15df0b0b82728cb5b84" } Frame { msec: 2512 - hash: "b8ee7bc1e94ce35bf946ee71fa03d72c" + hash: "e5c8d361abcbc15df0b0b82728cb5b84" } Frame { msec: 2528 - hash: "60ec6aceeaf82fc730c3df55b5c06f90" + hash: "e5c8d361abcbc15df0b0b82728cb5b84" } Frame { msec: 2544 - hash: "01cc732bad8b28483e79115c117ee26d" + hash: "e5c8d361abcbc15df0b0b82728cb5b84" } Frame { msec: 2560 - hash: "b39c8d373524ba679c8567d16e6c5fe0" + hash: "e5c8d361abcbc15df0b0b82728cb5b84" } Frame { msec: 2576 - hash: "2474476dfd021ff485c3a127bd22367e" + hash: "e5c8d361abcbc15df0b0b82728cb5b84" } Frame { msec: 2592 - hash: "1342a1a0f6bc02159de1be058cf2411b" + hash: "e5c8d361abcbc15df0b0b82728cb5b84" } Frame { msec: 2608 - hash: "a9721b64b9a5526335937245302249ae" + hash: "e5c8d361abcbc15df0b0b82728cb5b84" } Mouse { type: 2 @@ -938,15 +938,15 @@ VisualTest { } Frame { msec: 2624 - hash: "109dc503ee86e731f52d25908daf5d36" + hash: "e5c8d361abcbc15df0b0b82728cb5b84" } Frame { msec: 2640 - hash: "94998dbab6792c518ca1f37f060f1d4b" + hash: "e5c8d361abcbc15df0b0b82728cb5b84" } Frame { msec: 2656 - hash: "3146ba4e63fa74279939b8de935f067c" + hash: "e5c8d361abcbc15df0b0b82728cb5b84" } Mouse { type: 5 @@ -966,7 +966,7 @@ VisualTest { } Frame { msec: 2672 - hash: "1aaea4143076bf8ba8190d94fcc89e64" + hash: "f728208b0fc2f230313c86378cf7f419" } Mouse { type: 5 @@ -986,7 +986,7 @@ VisualTest { } Frame { msec: 2688 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Mouse { type: 5 @@ -1006,7 +1006,7 @@ VisualTest { } Frame { msec: 2704 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Mouse { type: 5 @@ -1026,7 +1026,7 @@ VisualTest { } Frame { msec: 2720 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Mouse { type: 5 @@ -1046,7 +1046,7 @@ VisualTest { } Frame { msec: 2736 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Mouse { type: 5 @@ -1066,39 +1066,39 @@ VisualTest { } Frame { msec: 2752 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 2768 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 2784 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 2800 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 2816 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 2832 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 2848 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 2864 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 2880 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 2896 @@ -1106,51 +1106,51 @@ VisualTest { } Frame { msec: 2912 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 2928 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 2944 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 2960 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 2976 - hash: "a0d8bb20189c3c65e5e72671788d9493" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 2992 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 3008 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 3024 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 3040 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 3056 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 3072 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 3088 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Mouse { type: 2 @@ -1162,23 +1162,23 @@ VisualTest { } Frame { msec: 3104 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 3120 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 3136 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 3152 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 3168 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Mouse { type: 5 @@ -1190,11 +1190,11 @@ VisualTest { } Frame { msec: 3184 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Frame { msec: 3200 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Mouse { type: 5 @@ -1214,7 +1214,7 @@ VisualTest { } Frame { msec: 3216 - hash: "1236a317e60f7ae3d3fb2fb521bad2a2" + hash: "f728208b0fc2f230313c86378cf7f419" } Mouse { type: 5 @@ -1234,7 +1234,7 @@ VisualTest { } Frame { msec: 3232 - hash: "1b604ea70459a768fb37a6333000174b" + hash: "7d43010a9951054df82571936a04cc50" } Mouse { type: 5 @@ -1254,7 +1254,7 @@ VisualTest { } Frame { msec: 3248 - hash: "25e0aabe364085a61b4572ef015dac2c" + hash: "ab1980970c82238d2c37d61db4fc5153" } Mouse { type: 5 @@ -1274,7 +1274,7 @@ VisualTest { } Frame { msec: 3264 - hash: "ee6fc5c1de08e6f13f23b26829d2cba2" + hash: "849ffa1fdd718a48e9570b88987f9203" } Mouse { type: 5 @@ -1294,7 +1294,7 @@ VisualTest { } Frame { msec: 3280 - hash: "b077c59359d047738d9ba739f591393b" + hash: "d497eff3c8879d30619630e7ffcbf5c9" } Mouse { type: 5 @@ -1314,7 +1314,7 @@ VisualTest { } Frame { msec: 3296 - hash: "2cc0b8d7bd088f2277f5e939c234114c" + hash: "b0679dfe2f631e41f5cc269bd16d742c" } Mouse { type: 5 @@ -1334,7 +1334,7 @@ VisualTest { } Frame { msec: 3312 - hash: "64703db84cd5bda3109546293783804d" + hash: "ab2d88a4cd58d0064c32660272ff1dbd" } Mouse { type: 5 @@ -1354,7 +1354,7 @@ VisualTest { } Frame { msec: 3328 - hash: "137cd88932ad1fdbfdbf1a80cccf7b3f" + hash: "ea3cff28ff3be273332b19a2b8acb95e" } Mouse { type: 5 @@ -1374,7 +1374,7 @@ VisualTest { } Frame { msec: 3344 - hash: "ff9011d861c64bcad214b52cb4245583" + hash: "458decd62af57d333a07459c89e62393" } Mouse { type: 5 @@ -1394,7 +1394,7 @@ VisualTest { } Frame { msec: 3360 - hash: "c3f0132e472d29ddee95c7349243d33e" + hash: "1347a26241ed98d4913e1cb6cda58286" } Mouse { type: 5 @@ -1414,87 +1414,87 @@ VisualTest { } Frame { msec: 3376 - hash: "42ae9c21dce6a7cd59de228dac775dd5" + hash: "2efe07858c0c4de7fd3e339d7a24d5f5" } Frame { msec: 3392 - hash: "3f8631caf6a98d83356b188d6f94e9a6" + hash: "3edbe6755710ce148341faeb6980707a" } Frame { msec: 3408 - hash: "b2788cd1939a6dd42f12d8fd1282a122" + hash: "0f53231de64ac5b0503e92ad10155dea" } Frame { msec: 3424 - hash: "0d1ab6e9f2780be0c392d20f4b3b9619" + hash: "f2be693c23ea0885d6e8180c3062ba76" } Frame { msec: 3440 - hash: "03fdd91b352798b1ff958c23c0bc5f35" + hash: "207003ce6908f9707e9193a6c82a40c0" } Frame { msec: 3456 - hash: "028fee3630fdb3cf862213c0466a56fe" + hash: "ba86efade16e8965f59f6257ae90d131" } Frame { msec: 3472 - hash: "3ab76009ca029723e5cf0bf9bc154102" + hash: "1fdaaa68c4ed484536c207a0eacf6e72" } Frame { msec: 3488 - hash: "866c59b7dd545364b70ddbf21a8ee874" + hash: "d1223c8254f9e7e37c4e09628f38bce2" } Frame { msec: 3504 - hash: "9b4ff972b1055db38900fc0c5007e7b0" + hash: "c822447614f47b5e15ffad967964a061" } Frame { msec: 3520 - hash: "cbe0073c84617e23f0679a08c1a78492" + hash: "5eb2e64f11847cc9360291e14e866611" } Frame { msec: 3536 - hash: "374a5e6070dd628ed031e80d44be1f3f" + hash: "545dcc2645b50d78c84c658880d0500c" } Frame { msec: 3552 - hash: "4d16c81f877585a82549cfc4f68c574d" + hash: "9d984e07b99137b3cb57dd4df16b8237" } Frame { msec: 3568 - hash: "64b2b4c374a730b138b3573095f45d2c" + hash: "da27085e7a3cccde7cc3db2d9c6cc2cd" } Frame { msec: 3584 - hash: "26c59f4131fdb01ac4771231341c75c3" + hash: "8d8c117ca102cb93e752904fe3aee7bc" } Frame { msec: 3600 - hash: "bf6a3fdb7c516ca9cfc09f1059cc8cdf" + hash: "bfb5ed7b65f36d80e3156560a0ec58b7" } Frame { msec: 3616 - hash: "1bfb86796087cd293c68205cce6ac294" + hash: "bbd5f2b95325fde3b8759f2ef713c6bd" } Frame { msec: 3632 - hash: "e0f76f8fc7bd7756a4e004655f97f782" + hash: "1c36be8deb2079ed81f1718c92e44803" } Frame { msec: 3648 - hash: "61d3aa5f827452482d8a4a903fe64acc" + hash: "5a424e7e66d87d278483c43070920d56" } Frame { msec: 3664 - hash: "c8e42d3a5df195eaa091e50fc9dcd51e" + hash: "ae28bc20e20e022e1ac9bc2ddac0e134" } Frame { msec: 3680 - hash: "bb684dccf4c0a74dc091fb78c1be4f2b" + hash: "1551c4aae06a258bdadc9ef356724871" } Frame { msec: 3696 - hash: "54341e5a76fb4657021c41e6e3f3d496" + hash: "526aec43f710e524d247f8a4b08c261c" } Mouse { type: 2 @@ -1514,7 +1514,7 @@ VisualTest { } Frame { msec: 3712 - hash: "435ee710e108df42f659250ad7dbdb5e" + hash: "b50ef7198c1831623ed2210e651ac618" } Mouse { type: 5 @@ -1526,7 +1526,7 @@ VisualTest { } Frame { msec: 3728 - hash: "0c7078ec0d4a1dea84e0fba06323c533" + hash: "913269856c18d4f478eed1aa1d5ae293" } Mouse { type: 5 @@ -1546,7 +1546,7 @@ VisualTest { } Frame { msec: 3744 - hash: "854103790c02ca86fa011ef1b0f2be0a" + hash: "2c6a32e167bef4c3de0ca97e5764f31b" } Mouse { type: 5 @@ -1566,7 +1566,7 @@ VisualTest { } Frame { msec: 3760 - hash: "1a5995196e5bb4d1464ca76191af72d5" + hash: "88386cf4d982c5ca4e3fbd3519d9bd9c" } Mouse { type: 5 @@ -1586,7 +1586,7 @@ VisualTest { } Frame { msec: 3776 - hash: "397bbd080cae99790621642fab6ded91" + hash: "ecf04273061af5f881925f3a33015fbb" } Mouse { type: 5 @@ -1606,7 +1606,7 @@ VisualTest { } Frame { msec: 3792 - hash: "66ecad306911060329dcf7695c358e87" + hash: "b09c45ea79cd818bac6fe35e4167d4bd" } Mouse { type: 5 @@ -1626,7 +1626,7 @@ VisualTest { } Frame { msec: 3808 - hash: "c06da5f40f3f59f576a1d540d0b3244f" + hash: "4a1dbbac65a3caac16b38c45be61003c" } Mouse { type: 5 @@ -1646,7 +1646,7 @@ VisualTest { } Frame { msec: 3824 - hash: "a88d97691539dce19af4c14baf610275" + hash: "f4a805fc5c12cc3b2a22ef01050bf3aa" } Mouse { type: 5 @@ -1666,7 +1666,7 @@ VisualTest { } Frame { msec: 3840 - hash: "a07dca2c0014609ca5241612550992f5" + hash: "aa7805e4d806c4c56ded804145c44464" } Mouse { type: 5 @@ -1706,7 +1706,7 @@ VisualTest { } Frame { msec: 3872 - hash: "e5a4e76dd607ba1bae97aaf184ee009a" + hash: "fd2eab6b3a65713f057da22a412512c7" } Mouse { type: 5 @@ -1726,7 +1726,7 @@ VisualTest { } Frame { msec: 3888 - hash: "bb1d2614e590562479fc8d301bc7402f" + hash: "0dda191a66162db6365c663979b0990d" } Mouse { type: 5 @@ -1746,7 +1746,7 @@ VisualTest { } Frame { msec: 3904 - hash: "5d9fd2238666d3ae04613f1bba0fab05" + hash: "72a57fe4fc34a19040890a9e2a11dae5" } Mouse { type: 5 @@ -1766,7 +1766,7 @@ VisualTest { } Frame { msec: 3920 - hash: "b12a944cb5e593afbb21a10453879b52" + hash: "fd18bd5f8f09c995f122b8b4ecb80279" } Mouse { type: 5 @@ -1786,7 +1786,7 @@ VisualTest { } Frame { msec: 3936 - hash: "2f04c990978627b86fb2ad04579db0db" + hash: "8d33b6fa9d6525902e5611cf8ed2fa1f" } Mouse { type: 5 @@ -1798,7 +1798,7 @@ VisualTest { } Frame { msec: 3952 - hash: "e7ddf142fc36174fcaaa70b9340ef7a8" + hash: "d73a8eba0c43f214946052481f3db98f" } Mouse { type: 5 @@ -1818,7 +1818,7 @@ VisualTest { } Frame { msec: 3968 - hash: "4fce53c6f5347fe03ecf17b07fabe3ac" + hash: "c2f101636963ff5c61be2ad83c6b7ceb" } Mouse { type: 5 @@ -1846,111 +1846,111 @@ VisualTest { } Frame { msec: 3984 - hash: "75a0ec2c0158c55a90147c3f4afaa19c" + hash: "54630f489303c7ec2e94b4c941bd310f" } Frame { msec: 4000 - hash: "e89e98b7c1f36b74c664c77e121dedcb" + hash: "357106c752b13bcca047d55a3c7cd486" } Frame { msec: 4016 - hash: "f4c1e52a7b97a25fba640be2a1430d2d" + hash: "b00b78122721ddcded2c7131cfe40d53" } Frame { msec: 4032 - hash: "be58ca8f63dac8373825231512f483ca" + hash: "7da9e4197cb9be292e561790af1caa27" } Frame { msec: 4048 - hash: "755b16d4be00cb52595d42775d6227ac" + hash: "076fefc33455667af954dcc5a06017d3" } Frame { msec: 4064 - hash: "c62f1ebbb1e4ae4ca22c060078d6240b" + hash: "76edfedd2b9edcc5770dcce87b022427" } Frame { msec: 4080 - hash: "5f1187e9530584f9eb81ce1ce8267da0" + hash: "12e6711077da076b737aef1aaa336d42" } Frame { msec: 4096 - hash: "5dc9921e9ddf15ee0457fcdc834544c5" + hash: "1e19329fb839a00faa3b95d13b7a9015" } Frame { msec: 4112 - hash: "efacedc2782435ef4e269e6956fb3547" + hash: "7469fb57ce0b7ea9a7cc6da14f6a245a" } Frame { msec: 4128 - hash: "5b356dd3082f6b0920bb41d332595ce1" + hash: "17e3aca0838e2ba75cc9b869bb969220" } Frame { msec: 4144 - hash: "5d8afcc1abd890beb2badf85bcf02897" + hash: "32ebb24cee3ba65f9242708538203553" } Frame { msec: 4160 - hash: "03c56ab4fea11cce19fcbb62dccb7683" + hash: "948429b8ded1f688cd7e27e0f056f40c" } Frame { msec: 4176 - hash: "236254ce32a8e06dc42f2fd3c9ac6c7c" + hash: "c6fc2e8519a31bc18eb924ca98cd24be" } Frame { msec: 4192 - hash: "4beb33da77bc2b41eb882a2a5cdeb539" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 4208 - hash: "b345470adead1ffb3af4d1091ffbd95c" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 4224 - hash: "c2677f1653b08952338a5c26a724ebe7" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 4240 - hash: "45b6633acf0ac28c5b5462920cf61282" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 4256 - hash: "26a9a6609ce8eee1f744c2bd43494f22" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 4272 - hash: "9373a8010a05d05cb5b3c2ec75359493" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 4288 - hash: "d0c561761825512a02a9e3640139cadc" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 4304 - hash: "d0c561761825512a02a9e3640139cadc" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 4320 - hash: "d0c561761825512a02a9e3640139cadc" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 4336 - hash: "d0c561761825512a02a9e3640139cadc" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 4352 - hash: "d0c561761825512a02a9e3640139cadc" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 4368 - hash: "d0c561761825512a02a9e3640139cadc" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 4384 - hash: "d0c561761825512a02a9e3640139cadc" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 4400 - hash: "d0c561761825512a02a9e3640139cadc" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Mouse { type: 2 @@ -1962,7 +1962,7 @@ VisualTest { } Frame { msec: 4416 - hash: "d0c561761825512a02a9e3640139cadc" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Mouse { type: 5 @@ -1974,7 +1974,7 @@ VisualTest { } Frame { msec: 4432 - hash: "d0c561761825512a02a9e3640139cadc" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Mouse { type: 5 @@ -1994,7 +1994,7 @@ VisualTest { } Frame { msec: 4448 - hash: "d0c561761825512a02a9e3640139cadc" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Mouse { type: 5 @@ -2014,7 +2014,7 @@ VisualTest { } Frame { msec: 4464 - hash: "0e7554f077e2d6d8c6cf9496b20ab009" + hash: "d8f9d016318e0bd38d4654b4850da952" } Mouse { type: 5 @@ -2034,7 +2034,7 @@ VisualTest { } Frame { msec: 4480 - hash: "d6e78f43c971abcc1d2aadb96e8b80b0" + hash: "13a2382e08ab10ecb40f9c24c682a797" } Mouse { type: 5 @@ -2054,7 +2054,7 @@ VisualTest { } Frame { msec: 4496 - hash: "10d8e0ee5bd432c639963c9cedd25b85" + hash: "cef145c5d105466f3913bb81bb2b58df" } Mouse { type: 5 @@ -2074,7 +2074,7 @@ VisualTest { } Frame { msec: 4512 - hash: "53e142d6b0112644d75df29f7865fbb4" + hash: "9bc0a21266bebbf8fc3509e5f92dd77f" } Mouse { type: 5 @@ -2086,7 +2086,7 @@ VisualTest { } Frame { msec: 4528 - hash: "9609807e6c2a27a8b9f1d5c878c3dadf" + hash: "e419dbe857667b014e4dd9b57b01bbe4" } Mouse { type: 5 @@ -2098,7 +2098,7 @@ VisualTest { } Frame { msec: 4544 - hash: "a0a1e5fd37e9d8033f182f4f2b20fd26" + hash: "411cb7a7f331161059faba4ae6549229" } Mouse { type: 5 @@ -2110,7 +2110,7 @@ VisualTest { } Frame { msec: 4560 - hash: "b40e553dc373e4018488d5421b9a8914" + hash: "b008d6b2b444881c36521595f6b31539" } Mouse { type: 5 @@ -2122,7 +2122,7 @@ VisualTest { } Frame { msec: 4576 - hash: "22e36512a0af86fac12c09f735dcb1f7" + hash: "77fcc3c74c3832ae6b80aec420cb06e0" } Mouse { type: 5 @@ -2142,59 +2142,59 @@ VisualTest { } Frame { msec: 4592 - hash: "70e9ad0f56e4c37f8684e38f614b889d" + hash: "41d1c54bc76caeae057fb1bdb3b93843" } Frame { msec: 4608 - hash: "0754126f5738e3dcec35fc1ef65fdec3" + hash: "03fdd91b352798b1ff958c23c0bc5f35" } Frame { msec: 4624 - hash: "b3d84ceeecc294d21bc09a3197195c20" + hash: "2098ea8b55b54ca8dd648fb285c43ebf" } Frame { msec: 4640 - hash: "ce00501e194b1056edf1ebd43b954a70" + hash: "9929c509654819fd04da4e4b5c8e22b4" } Frame { msec: 4656 - hash: "793f41ac2568530e6d630446216833dc" + hash: "c470d3a57c6b56f9f56b176823b27d53" } Frame { msec: 4672 - hash: "e8573de724b653439bde85c15e9555ab" + hash: "37474b3a23f90dafee6b9e0043a702fa" } Frame { msec: 4688 - hash: "bfb3f3645c7b2425b686ac23bcef82b8" + hash: "0fbb6a9fded011b010fa6f3a2819630c" } Frame { msec: 4704 - hash: "faa78596e208c2cf4593ea25e31fabde" + hash: "6c5a7dad864999548257e4bf0ddc3687" } Frame { msec: 4720 - hash: "f1b0931bffce37abfe5a6d635f1f8454" + hash: "339bc42e559c66d07f37af5e06feacef" } Frame { msec: 4736 - hash: "0975630a55bfd56eb3e39426c1c3f1e5" + hash: "513dc773dc93275e32fa9ac61e6dcb46" } Frame { msec: 4752 - hash: "98f1d79153a8009123abc94141375779" + hash: "b725c84435b1f387dc3f375280e39de6" } Frame { msec: 4768 - hash: "d864817f877a9eeb44c665518ea19687" + hash: "f3d04b513df286aacb9ebdb107d7a0b4" } Frame { msec: 4784 - hash: "79745c267d14e7790e1bb3a7e76f20b4" + hash: "c22839005ed0cb6b2fa9c958d17fd948" } Frame { msec: 4800 - hash: "ec038d4cec64b847711fa221f808bead" + hash: "2fb9a2d5d22a6d0ed567328ffaa512f0" } Frame { msec: 4816 @@ -2202,239 +2202,239 @@ VisualTest { } Frame { msec: 4832 - hash: "ef7b3f93abbf210f8f0d38a58380dc8f" + hash: "ba13b0b4790aec7084b5553fe0b0d72b" } Frame { msec: 4848 - hash: "f0eea63127df25f7f818596fc034fef8" + hash: "2bc983733d4004cc67a56d77e9f48e5d" } Frame { msec: 4864 - hash: "8000dee3ea54522a8193a7f9f2e86023" + hash: "0f729cbe41b155b6eef20a4be207b853" } Frame { msec: 4880 - hash: "111485ebaf93aae4f5e0a83da898bbac" + hash: "c2ca47a7d70ef827029b32c11a052b83" } Frame { msec: 4896 - hash: "4b2dee1fd88dcaeabc8235f6a0e5c090" + hash: "803aefca7f1cbd494d2d2f7e7eea9a3f" } Frame { msec: 4912 - hash: "5e560c777d0294dfa8f249232bfcf3a2" + hash: "2641683e1fa9ed418ac89631be7922f1" } Frame { msec: 4928 - hash: "d8b490092ca5ce3ef9b078f4768c382a" + hash: "3d9370305ca147625828f7ee3b34ca33" } Frame { msec: 4944 - hash: "28b2bbc3fd19786dd9c0ab718141c525" + hash: "5cdfdd22a0dc1ed78035ae4b5e2e26a7" } Frame { msec: 4960 - hash: "d1a61000ebc5a475c0223dde649c8054" + hash: "2af663981b43dbe699849eff4731829a" } Frame { msec: 4976 - hash: "d3e8aae08a2518c039d6bda80fc520a4" + hash: "b159d3a09666327bd2d860bf56920734" } Frame { msec: 4992 - hash: "9f3bd8654adb9af0457dd50ff71fcd43" + hash: "a1ed6f686f4cda9aa59bfd49deb8a075" } Frame { msec: 5008 - hash: "befe00fef613b7616e2dc668a5ed59c7" + hash: "c5f1862e7cbb1dcd6b303e58c525ab5c" } Frame { msec: 5024 - hash: "24e84e6998389aa119d7d9e0ac2206ac" + hash: "3cc5e5d87067978961eee6e7b33ada06" } Frame { msec: 5040 - hash: "2d3d2b66bf016c8e499f527dbf8923db" + hash: "74f3b0eae443bd9f171020fd973ca960" } Frame { msec: 5056 - hash: "52d24673729dbd53d3227675b7001b24" + hash: "432037812ab1a09e0d0b32dfaf0f876e" } Frame { msec: 5072 - hash: "4e5c807682d7b6b7839c047a7fb4ad93" + hash: "0eec7146b8df3b4892e89abd13b8bc9d" } Frame { msec: 5088 - hash: "319affea47c4a0b0e2c3db51b85430bc" + hash: "a01dc5f4b4307aa66068d21159dd64d5" } Frame { msec: 5104 - hash: "344962f0b88c7e8a33df71b4708fd1c0" + hash: "11eefdf5b1be8493a6ed9aaf519c7e17" } Frame { msec: 5120 - hash: "ac099ba8a5639b9c83b6f58f2b5bcf93" + hash: "55ed797b82f5bca2ac2b5954c44c041e" } Frame { msec: 5136 - hash: "2f8e57c93289dcdc758281531300e949" + hash: "498d4ca9faabf8b59e2359b60dc1aff2" } Frame { msec: 5152 - hash: "e4cc3bdf6068064bcfdd0014cc301e65" + hash: "78895368b141ab6d3a16f65f4389b2d5" } Frame { msec: 5168 - hash: "598c8a33e2bbf47b21df8b0636e0f0bc" + hash: "c73b27167bad79f3f3c5ebb64fa579c2" } Frame { msec: 5184 - hash: "6aea67c85370eee8447a22e2b9e8c44c" + hash: "fb05312d65155f0300f456d727698b80" } Frame { msec: 5200 - hash: "39e27a3376f4aba8510f7b0d90ca0e33" + hash: "6e974736a0ecea6a71c1a7052a14fa20" } Frame { msec: 5216 - hash: "0ff93a16a07af43bd5e22a2b00fd2588" + hash: "f5daf5bec03d3e56c877e9b2dc5701b6" } Frame { msec: 5232 - hash: "8b6004368b9b0a766f6b519820fe1ff6" + hash: "29793d2147563feb9ed0ebff18b303cd" } Frame { msec: 5248 - hash: "5d92c0a12ff138d1b2c75bd042be4ea2" + hash: "5b63dfa3cb7ac0847f2e63f9d2a0b2b6" } Frame { msec: 5264 - hash: "4386b0abe49106a0174154c726c301f6" + hash: "cf2f42dd9830d80f50df30e93a0b1ad2" } Frame { msec: 5280 - hash: "832da8d2a86caa3ca96f33d2cd49178e" + hash: "8abb0aa8951612338c3bb87c7a0d2509" } Frame { msec: 5296 - hash: "efee6ab1ba4a1112f2129aad12825667" + hash: "8abb0aa8951612338c3bb87c7a0d2509" } Frame { msec: 5312 - hash: "f20a7e67a4789c559b0b0a7656bd89b1" + hash: "8abb0aa8951612338c3bb87c7a0d2509" } Frame { msec: 5328 - hash: "350cc8c0085a8f79c9ea8880737a0b75" + hash: "8abb0aa8951612338c3bb87c7a0d2509" } Frame { msec: 5344 - hash: "b19715b4029ea489debf7c5a269aca98" + hash: "8abb0aa8951612338c3bb87c7a0d2509" } Frame { msec: 5360 - hash: "f383fcaf603af41650c5622bfaf136b3" + hash: "8abb0aa8951612338c3bb87c7a0d2509" } Frame { msec: 5376 - hash: "0c62a442367fc0bac5117da1327ed39a" + hash: "8abb0aa8951612338c3bb87c7a0d2509" } Frame { msec: 5392 - hash: "323ba45d158d983f359211f1a87b7ebd" + hash: "8abb0aa8951612338c3bb87c7a0d2509" } Frame { msec: 5408 - hash: "aeed1a31b8b77dac2c2858969ff2d86c" + hash: "8abb0aa8951612338c3bb87c7a0d2509" } Frame { msec: 5424 - hash: "27a9357730a97846ffeddd18492df04d" + hash: "8abb0aa8951612338c3bb87c7a0d2509" } Frame { msec: 5440 - hash: "42f78593e64585b33c8854e8ea92710e" + hash: "8abb0aa8951612338c3bb87c7a0d2509" } Frame { msec: 5456 - hash: "064f5cec99b9a351bebe2088019f46d1" + hash: "8abb0aa8951612338c3bb87c7a0d2509" } Frame { msec: 5472 - hash: "d3669826f94aa2afc1069ab967f677a3" + hash: "8abb0aa8951612338c3bb87c7a0d2509" } Frame { msec: 5488 - hash: "a118cf8892d29e6b70b4e65e42380c15" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5504 - hash: "f254260f01ff4697e9e3146cc106140d" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5520 - hash: "ec062b2bb87444115c2e8744b7f80bde" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5536 - hash: "4d45522a4e4253c810cac9cbf24c9b76" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5552 - hash: "532c3d3ead73836948a1036e8e69cadf" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5568 - hash: "4debea14aeac85ff4e64387938d8b010" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5584 - hash: "d8940cf6e39a1bd5e7216a83ce87a676" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5600 - hash: "fba6485f8a60a38ce2f3110137b1f2df" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5616 - hash: "8a8909b114332dd932b784a2640e9ff4" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5632 - hash: "fd901422400333c137240ef5f91928a3" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5648 - hash: "97b84a957515d5823e381fdd86d31fb8" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5664 - hash: "f3547ea694b88dd7d2fb8b04d6bf76a9" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5680 - hash: "9eb0da29d0c323b45e62d31bee97ce8c" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5696 - hash: "9d814096d27e9fbcffdf7e29866e0059" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5712 - hash: "6087185e1e8bf17545a7372be2990ab2" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5728 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5744 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5760 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5776 @@ -2442,126 +2442,126 @@ VisualTest { } Frame { msec: 5792 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5808 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5824 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5840 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5856 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5872 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5888 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5904 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5920 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5936 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5952 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5968 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 5984 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6000 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6016 - hash: "82e534c416dfe884e5abc2f91d902484" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6032 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6048 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6064 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6080 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6096 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6112 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6128 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6144 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6160 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6176 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6192 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6208 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6224 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6240 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6256 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } Frame { msec: 6272 - hash: "6839b467f32eaa79d4c1ce4905145350" + hash: "a29d4b3fa16829823e63bf83e7b62aff" } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativepathview/test-pathview.qml b/tests/auto/declarative/qmlvisual/qdeclarativepathview/test-pathview.qml index 4374b84..08499e7 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativepathview/test-pathview.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativepathview/test-pathview.qml @@ -35,6 +35,8 @@ Rectangle { id: photoPathView; model: rssModel; delegate: photoDelegate anchors.fill: parent; z: 1 anchors.topMargin:40 + highlightMoveDuration: 200 + flickDeceleration: 200 path: Path { startX: -50; startY: 40; -- cgit v0.12 From 34630042ded25177b49f8e54b41269db1be42935 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Thu, 23 Dec 2010 13:17:20 +1000 Subject: Try fixing build error on Windows --- .../declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro b/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro index 472cffb..efcea12 100644 --- a/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro +++ b/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro @@ -1,5 +1,5 @@ load(qttest_p4) -contains(QT_CONFIG,declarative): QT += declarative script gui +contains(QT_CONFIG,declarative): QT += declarative script gui network contains(QT_CONFIG,xmlpatterns) { QT += xmlpatterns DEFINES += QTEST_XMLPATTERNS -- cgit v0.12 From 16d08f97eaa7dd0469d7c9006546f86f1fd763f6 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 23 Dec 2010 13:13:36 +1000 Subject: Models which load incrementally via fetchMore() don't work. Call canFetchMore()/fetchMore() on setModel(), setRootIndex() and when the last item is created. Task-number: QTBUG-16039 Reviewed-by: Bea Lam --- .../graphicsitems/qdeclarativevisualitemmodel.cpp | 6 ++ .../qdeclarativelistview/incrementalmodel.cpp | 89 ++++++++++++++++++++++ .../qdeclarativelistview/incrementalmodel.h | 68 +++++++++++++++++ .../qdeclarativelistview/qdeclarativelistview.pro | 3 +- .../tst_qdeclarativelistview.cpp | 28 +++++++ 5 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 tests/auto/declarative/qdeclarativelistview/incrementalmodel.cpp create mode 100644 tests/auto/declarative/qdeclarativelistview/incrementalmodel.h diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index 4f5213a..bf9263b 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -773,6 +773,8 @@ void QDeclarativeVisualDataModel::setModel(const QVariant &model) QObject::connect(d->m_abstractItemModel, SIGNAL(modelReset()), this, SLOT(_q_modelReset())); QObject::connect(d->m_abstractItemModel, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged())); d->m_metaDataCacheable = true; + if (d->m_abstractItemModel->canFetchMore(d->m_root)) + d->m_abstractItemModel->fetchMore(d->m_root); return; } if ((d->m_visualItemModel = qvariant_cast(model))) { @@ -870,6 +872,8 @@ void QDeclarativeVisualDataModel::setRootIndex(const QVariant &root) if (d->m_root != modelIndex) { int oldCount = d->modelCount(); d->m_root = modelIndex; + if (d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(modelIndex)) + d->m_abstractItemModel->fetchMore(modelIndex); int newCount = d->modelCount(); if (d->m_delegate && oldCount) emit itemsRemoved(0, oldCount); @@ -1094,6 +1098,8 @@ QDeclarativeItem *QDeclarativeVisualDataModel::item(int index, const QByteArray d->m_delegateValidated = true; } } + if (d->modelCount()-1 == index && d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(d->m_root)) + d->m_abstractItemModel->fetchMore(d->m_root); return item; } diff --git a/tests/auto/declarative/qdeclarativelistview/incrementalmodel.cpp b/tests/auto/declarative/qdeclarativelistview/incrementalmodel.cpp new file mode 100644 index 0000000..b2c9df5 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelistview/incrementalmodel.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** 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 "incrementalmodel.h" +#include +#include + +IncrementalModel::IncrementalModel(QObject *parent) + : QAbstractListModel(parent), count(0) +{ + for (int i = 0; i < 100; ++i) + list.append("Item " + QString::number(i)); +} + +int IncrementalModel::rowCount(const QModelIndex & /* parent */) const +{ + return count; +} + +QVariant IncrementalModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (index.row() >= list.size() || index.row() < 0) + return QVariant(); + + if (role == Qt::DisplayRole) + return list.at(index.row()); + return QVariant(); +} + +bool IncrementalModel::canFetchMore(const QModelIndex & /* index */) const +{ + if (count < list.size()) + return true; + else + return false; +} + +void IncrementalModel::fetchMore(const QModelIndex & /* index */) +{ + int remainder = list.size() - count; + int itemsToFetch = qMin(5, remainder); + + beginInsertRows(QModelIndex(), count, count+itemsToFetch-1); + + count += itemsToFetch; + + endInsertRows(); +} diff --git a/tests/auto/declarative/qdeclarativelistview/incrementalmodel.h b/tests/auto/declarative/qdeclarativelistview/incrementalmodel.h new file mode 100644 index 0000000..b1f7407 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelistview/incrementalmodel.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef IncrementalModel_H +#define IncrementalModel_H + +#include +#include +#include + +class IncrementalModel : public QAbstractListModel +{ + Q_OBJECT + +public: + IncrementalModel(QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + +protected: + bool canFetchMore(const QModelIndex &parent) const; + void fetchMore(const QModelIndex &parent); + +private: + QStringList list; + int count; +}; + +#endif diff --git a/tests/auto/declarative/qdeclarativelistview/qdeclarativelistview.pro b/tests/auto/declarative/qdeclarativelistview/qdeclarativelistview.pro index 2c5a859..8c99f08 100644 --- a/tests/auto/declarative/qdeclarativelistview/qdeclarativelistview.pro +++ b/tests/auto/declarative/qdeclarativelistview/qdeclarativelistview.pro @@ -2,7 +2,8 @@ load(qttest_p4) contains(QT_CONFIG,declarative): QT += declarative macx:CONFIG -= app_bundle -SOURCES += tst_qdeclarativelistview.cpp +HEADERS += incrementalmodel.h +SOURCES += tst_qdeclarativelistview.cpp incrementalmodel.cpp symbian: { importFiles.sources = data diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index dba0cc4..e76cb15 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -51,6 +51,7 @@ #include #include #include "../../../shared/util.h" +#include "incrementalmodel.h" #ifdef Q_OS_SYMBIAN // In Symbian OS test data is located in applications private dir @@ -106,6 +107,7 @@ private slots: void resizeDelegate(); void QTBUG_16037(); void indexAt(); + void incrementalModel(); private: template void items(); @@ -1998,6 +2000,32 @@ void tst_QDeclarativeListView::indexAt() delete canvas; } +void tst_QDeclarativeListView::incrementalModel() +{ + QDeclarativeView *canvas = createView(); + + IncrementalModel model; + 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(), 20); + + listview->positionViewAtIndex(10, QDeclarativeListView::Beginning); + + QTRY_COMPARE(listview->count(), 25); + + delete canvas; +} + void tst_QDeclarativeListView::qListModelInterface_items() { items(); -- cgit v0.12 From 508d52477fe16f3b425e5d3ec65584e86ed939b3 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 23 Dec 2010 15:01:58 +1000 Subject: Improve docs on attached properties on view delegates. Clarify that the properties are attached to the root of the delegate, and must be accessed as such by child items. Task-number: QTBUG-16193 Reviewed-by: Bea Lam --- doc/src/snippets/declarative/gridview/gridview.qml | 26 ++++++++++++++++++++++ doc/src/snippets/declarative/listview/listview.qml | 14 ++++++++---- .../declarative/pathview/pathattributes.qml | 4 ++-- doc/src/snippets/declarative/pathview/pathview.qml | 14 ++++++++++-- .../graphicsitems/qdeclarativegridview.cpp | 9 ++++++++ .../graphicsitems/qdeclarativelistview.cpp | 7 ++++++ .../graphicsitems/qdeclarativepathview.cpp | 9 ++++++++ 7 files changed, 75 insertions(+), 8 deletions(-) diff --git a/doc/src/snippets/declarative/gridview/gridview.qml b/doc/src/snippets/declarative/gridview/gridview.qml index 73e58ec..87d70de 100644 --- a/doc/src/snippets/declarative/gridview/gridview.qml +++ b/doc/src/snippets/declarative/gridview/gridview.qml @@ -132,6 +132,32 @@ GridView { } //![highlightFollowsCurrentItem] +//![isCurrentItem] +GridView { + width: 300; height: 200 + cellWidth: 80; cellHeight: 80 + + Component { + id: contactsDelegate + Rectangle { + id: wrapper + width: 80 + height: 80 + color: GridView.isCurrentItem ? "black" : "red" + Text { + id: contactInfo + text: name + ": " + number + color: wrapper.GridView.isCurrentItem ? "red" : "black" + } + } + } + + model: ContactModel {} + delegate: contactsDelegate + focus: true +} +//![isCurrentItem] + } } diff --git a/doc/src/snippets/declarative/listview/listview.qml b/doc/src/snippets/declarative/listview/listview.qml index 8ba47a8..370429e 100644 --- a/doc/src/snippets/declarative/listview/listview.qml +++ b/doc/src/snippets/declarative/listview/listview.qml @@ -127,10 +127,16 @@ ListView { Component { id: contactsDelegate - Text { - id: contactInfo - text: name + ": " + number - color: contactInfo.ListView.isCurrentItem ? "red" : "black" + Rectangle { + id: wrapper + width: 180 + height: contactInfo.height + color: ListView.isCurrentItem ? "black" : "red" + Text { + id: contactInfo + text: name + ": " + number + color: wrapper.ListView.isCurrentItem ? "red" : "black" + } } } diff --git a/doc/src/snippets/declarative/pathview/pathattributes.qml b/doc/src/snippets/declarative/pathview/pathattributes.qml index d6dacdb..be933e0 100644 --- a/doc/src/snippets/declarative/pathview/pathattributes.qml +++ b/doc/src/snippets/declarative/pathview/pathattributes.qml @@ -52,8 +52,8 @@ Rectangle { scale: PathView.iconScale opacity: PathView.iconOpacity Column { - Image { anchors.horizontalCenter: name.horizontalCenter; width: 64; height: 64; source: icon } - Text { text: name; font.pointSize: 16} + Image { anchors.horizontalCenter: nameText.horizontalCenter; width: 64; height: 64; source: icon } + Text { id: nameText; text: name; font.pointSize: 16 } } } } diff --git a/doc/src/snippets/declarative/pathview/pathview.qml b/doc/src/snippets/declarative/pathview/pathview.qml index 93298c4..e5e90a4 100644 --- a/doc/src/snippets/declarative/pathview/pathview.qml +++ b/doc/src/snippets/declarative/pathview/pathview.qml @@ -48,8 +48,18 @@ Rectangle { Component { id: delegate Column { - Image { anchors.horizontalCenter: name.horizontalCenter; width: 64; height: 64; source: icon } - Text { text: name; font.pointSize: 16 } + id: wrapper + Image { + anchors.horizontalCenter: nameText.horizontalCenter + width: 64; height: 64 + source: icon + } + Text { + id: nameText + text: name + font.pointSize: 16 + color: wrapper.PathView.isCurrentItem ? "red" : "black" + } } } //! [1] diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 4a6a9dc..7ddf6a2 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1131,6 +1131,13 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m Delegates are instantiated as needed and may be destroyed at any time. State should \e never be stored in a delegate. + GridView attaches a number of properties to the root item of the delegate, for example + \c {GridView.isCurrentItem}. In the following example, the root delegate item can access + this attached property directly as \c GridView.isCurrentItem, while the child + \c contactInfo object must refer to this property as \c wrapper.GridView.isCurrentItem. + + \snippet doc/src/snippets/declarative/gridview/gridview.qml isCurrentItem + \note Views do not set the \l{Item::}{clip} property automatically. If the view is not clipped by another item or the screen, it will be necessary to set this property to true in order to clip the items that are partially or @@ -1167,6 +1174,8 @@ QDeclarativeGridView::~QDeclarativeGridView() This attached property holds the view that manages this delegate instance. It is attached to each instance of the delegate. + + \snippet doc/src/snippets/declarative/gridview/gridview.qml isCurrentItem */ /*! diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 86c8756..702442b 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -1416,6 +1416,13 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m Delegates are instantiated as needed and may be destroyed at any time. State should \e never be stored in a delegate. + ListView attaches a number of properties to the root item of the delegate, for example + \c {ListView.isCurrentItem}. In the following example, the root delegate item can access + this attached property directly as \c ListView.isCurrentItem, while the child + \c contactInfo object must refer to this property as \c wrapper.ListView.isCurrentItem. + + \snippet doc/src/snippets/declarative/listview/listview.qml isCurrentItem + \note Views do not enable \e clip automatically. If the view is not clipped by another item or the screen, it will be necessary to set \e {clip: true} in order to have the out of view items clipped diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index a6f44b3..e3987d0 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -393,6 +393,13 @@ void QDeclarativePathViewPrivate::regenerate() Delegates are instantiated as needed and may be destroyed at any time. State should \e never be stored in a delegate. + PathView attaches a number of properties to the root item of the delegate, for example + \c {PathView.isCurrentItem}. In the following example, the root delegate item can access + this attached property directly as \c PathView.isCurrentItem, while the child + \c nameText object must refer to this property as \c wrapper.PathView.isCurrentItem. + + \snippet doc/src/snippets/declarative/pathview/pathview.qml 1 + \bold Note that views do not enable \e clip automatically. If the view is not clipped by another item or the screen, it will be necessary to set \e {clip: true} in order to have the out of view items clipped @@ -452,6 +459,8 @@ QDeclarativePathView::~QDeclarativePathView() It is attached to each instance of the delegate. This property may be used to adjust the appearance of the current item. + + \snippet doc/src/snippets/declarative/pathview/pathview.qml 1 */ /*! -- cgit v0.12 From 93edc0680b8ca9cccefa31f8d2df08b0fc8f32f8 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 23 Dec 2010 15:21:32 +1000 Subject: More docs for FolderListModel --- .../qdeclarativefolderlistmodel.cpp | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp index 9c71004..7b05bc5 100644 --- a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp +++ b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp @@ -190,6 +190,12 @@ QVariant QDeclarativeFolderListModel::data(const QModelIndex &index, int role) c return rv; } +/*! + \qmlproperty int FolderListModel::count + + Returns the number of items in the current folder that match the + filter criteria. +*/ int QDeclarativeFolderListModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); @@ -225,6 +231,11 @@ void QDeclarativeFolderListModel::setFolder(const QUrl &folder) } } +/*! + \qmlproperty url FolderListModel::parentFolder + + Returns the URL of the parent of of the current \l folder. +*/ QUrl QDeclarativeFolderListModel::parentFolder() const { QString localFile = d->folder.toLocalFile(); @@ -286,6 +297,21 @@ void QDeclarativeFolderListModel::componentComplete() QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection); } +/*! + \qmlproperty enumeration FolderListModel::sortField + + The \a sortField property contains field to use for sorting. sortField + may be one of: + \list + \o Unsorted - no sorting is applied. The order is system default. + \o Name - sort by filename + \o Time - sort by time modified + \o Size - sort by file size + \o Type - sort by file type (extension) + \endlist + + \sa sortReversed +*/ QDeclarativeFolderListModel::SortField QDeclarativeFolderListModel::sortField() const { return d->sortField; @@ -299,6 +325,13 @@ void QDeclarativeFolderListModel::setSortField(SortField field) } } +/*! + \qmlproperty bool FolderListModel::sortReversed + + If set to true, reverses the sort order. The default is false. + + \sa sortField +*/ bool QDeclarativeFolderListModel::sortReversed() const { return d->sortReversed; -- cgit v0.12 From eb395badcba6eada75ad5e6a72b74f5204170ed9 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 23 Dec 2010 15:41:09 +1000 Subject: WorkerScript could starve image loading of CPU. We use idle priority for image loading and XmlListModel in order to keep the UI responsive, but WorkerScript used LowPriority which would significantly reduce CPU available for image loading. Task-number: QTBUG-16167 --- src/declarative/qml/qdeclarativeworkerscript.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp index 4b78020..9dc214f 100644 --- a/src/declarative/qml/qdeclarativeworkerscript.cpp +++ b/src/declarative/qml/qdeclarativeworkerscript.cpp @@ -458,7 +458,7 @@ QDeclarativeWorkerScriptEngine::QDeclarativeWorkerScriptEngine(QDeclarativeEngin { d->m_lock.lock(); connect(d, SIGNAL(stopThread()), this, SLOT(quit()), Qt::DirectConnection); - start(QThread::LowPriority); + start(QThread::IdlePriority); d->m_wait.wait(&d->m_lock); d->moveToThread(this); d->m_lock.unlock(); -- cgit v0.12 From 03f94089a16cf6b6a3b533ba1f90444eb18c29ab Mon Sep 17 00:00:00 2001 From: Charles Yin Date: Thu, 4 Nov 2010 15:38:57 +1000 Subject: Add Postgresql 8.x and 9 supports Change-Id: Ic740686ead768cc3e106703049d878549dfd3c6a Task-number:QTBUG-14206 Reviewed-by: Michael Goddard --- src/sql/drivers/psql/qsql_psql.cpp | 116 ++++++++++++++++++++++---------- src/sql/drivers/psql/qsql_psql.h | 6 +- tests/auto/qsqldatabase/tst_databases.h | 2 + 3 files changed, 88 insertions(+), 36 deletions(-) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index 2a4e595..bf9685f 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -54,7 +54,6 @@ #include #include - #include #include @@ -619,6 +618,50 @@ static void setDatestyle(PGconn* connection) PQclear(result); } +static QPSQLDriver::Protocol qMakePSQLVersion(int vMaj, int vMin) +{ + switch (vMaj) { + case 6: + return QPSQLDriver::Version6; + case 7: + { + switch (vMin) { + case 1: + return QPSQLDriver::Version71; + case 3: + return QPSQLDriver::Version73; + case 4: + return QPSQLDriver::Version74; + default: + return QPSQLDriver::Version7; + } + break; + } + case 8: + { + switch (vMin) { + case 1: + return QPSQLDriver::Version81; + case 2: + return QPSQLDriver::Version82; + case 3: + return QPSQLDriver::Version83; + case 4: + return QPSQLDriver::Version84; + default: + return QPSQLDriver::Version8; + } + break; + } + case 9: + return QPSQLDriver::Version9; + break; + default: + break; + } + return QPSQLDriver::VersionUnknown; +} + static QPSQLDriver::Protocol getPSQLVersion(PGconn* connection) { QPSQLDriver::Protocol serverVersion = QPSQLDriver::Version6; @@ -626,50 +669,44 @@ static QPSQLDriver::Protocol getPSQLVersion(PGconn* connection) int status = PQresultStatus(result); if (status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK) { QString val = QString::fromAscii(PQgetvalue(result, 0, 0)); + QRegExp rx(QLatin1String("(\\d+)\\.(\\d+)")); rx.setMinimal(true); // enforce non-greedy RegExp + if (rx.indexIn(val) != -1) { int vMaj = rx.cap(1).toInt(); int vMin = rx.cap(2).toInt(); - - switch (vMaj) { - case 7: - switch (vMin) { - case 0: - serverVersion = QPSQLDriver::Version7; - break; - case 1: - case 2: - serverVersion = QPSQLDriver::Version71; - break; - default: - serverVersion = QPSQLDriver::Version73; - break; - } - break; - case 8: - switch (vMin) { - case 0: - serverVersion = QPSQLDriver::Version8; - break; - case 1: - serverVersion = QPSQLDriver::Version81; - break; - case 2: - default: - serverVersion = QPSQLDriver::Version82; - break; - } - break; - default: - break; + serverVersion = qMakePSQLVersion(vMaj, vMin); +#ifdef PG_MAJORVERSION + if (rx.indexIn(QLatin1String(PG_MAJORVERSION)) != -1) { + vMaj = rx.cap(1).toInt(); + vMin = rx.cap(2).toInt(); + } + QPSQLDriver::Protocol clientVersion = qMakePSQLVersion(vMaj, vMin); + + if (serverVersion >= QPSQLDriver::Version9 && clientVersion < QPSQLDriver::Version9) { + //Client version before QPSQLDriver::Version9 only supports escape mode for bytea type, + //but bytea format is set to hex by default in PSQL 9 and above. So need to force the + //server use the old escape mode when connects to the new server with old client library. + result = PQexec(connection, "SET bytea_output=escape; "); + status = PQresultStatus(result); + } else if (serverVersion == QPSQLDriver::VersionUnknown) { + serverVersion = clientVersion; + if (serverVersion != QPSQLDriver::VersionUnknown) + qWarning("The server version of this PostgreSQL is unknown, falling back to the client version."); } +#endif } } PQclear(result); - if (serverVersion < QPSQLDriver::Version71) + //keep the old behavior unchanged + if (serverVersion == QPSQLDriver::VersionUnknown) + serverVersion = QPSQLDriver::Version6; + + if (serverVersion < QPSQLDriver::Version71) { qWarning("This version of PostgreSQL is not supported and may not work."); + } return serverVersion; } @@ -852,7 +889,10 @@ bool QPSQLDriver::commitTransaction() // This hack can dissapear once there is an API to query this sort of information. if (d->pro == QPSQLDriver::Version8 || d->pro == QPSQLDriver::Version81 || - d->pro == QPSQLDriver::Version82) { + d->pro == QPSQLDriver::Version82 || + d->pro == QPSQLDriver::Version83 || + d->pro == QPSQLDriver::Version84 || + d->pro == QPSQLDriver::Version9) { transaction_failed = qstrcmp(PQcmdStatus(res), "ROLLBACK") == 0; } @@ -963,6 +1003,9 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const case QPSQLDriver::Version8: case QPSQLDriver::Version81: case QPSQLDriver::Version82: + case QPSQLDriver::Version83: + case QPSQLDriver::Version84: + case QPSQLDriver::Version9: stmt = QLatin1String("SELECT pg_attribute.attname, pg_attribute.atttypid::int, " "pg_class.relname " "FROM pg_attribute, pg_class " @@ -1046,6 +1089,9 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const case QPSQLDriver::Version8: case QPSQLDriver::Version81: case QPSQLDriver::Version82: + case QPSQLDriver::Version83: + case QPSQLDriver::Version84: + case QPSQLDriver::Version9: stmt = QLatin1String("select pg_attribute.attname, pg_attribute.atttypid::int, " "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " "pg_attrdef.adsrc " diff --git a/src/sql/drivers/psql/qsql_psql.h b/src/sql/drivers/psql/qsql_psql.h index 22871ff..107da87 100644 --- a/src/sql/drivers/psql/qsql_psql.h +++ b/src/sql/drivers/psql/qsql_psql.h @@ -97,6 +97,7 @@ class Q_EXPORT_SQLDRIVER_PSQL QPSQLDriver : public QSqlDriver Q_OBJECT public: enum Protocol { + VersionUnknown = -1, Version6 = 6, Version7 = 7, Version71 = 8, @@ -104,7 +105,10 @@ public: Version74 = 10, Version8 = 11, Version81 = 12, - Version82 = 13 + Version82 = 13, + Version83 = 14, + Version84 = 15, + Version9 = 16, }; explicit QPSQLDriver(QObject *parent=0); diff --git a/tests/auto/qsqldatabase/tst_databases.h b/tests/auto/qsqldatabase/tst_databases.h index 80535df..82ee41a 100644 --- a/tests/auto/qsqldatabase/tst_databases.h +++ b/tests/auto/qsqldatabase/tst_databases.h @@ -235,6 +235,8 @@ public: // addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "postgres74-nokia.trolltech.com.au" ); // Version 7.4.19-1.el4_6.1 // addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql81.apac.nokia.com" ); // Version 8.1.11-1.el5_1.1 // addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql84.apac.nokia.com" ); // Version 8.4.1-2.1.i586 +// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql90.apac.nokia.com" ); // Version 9.0.0 + // addDb( "QDB2", "testdb", "troll", "trond", "silence.nokia.troll.no" ); // DB2 v9.1 on silence -- cgit v0.12 From 4d81f771f513a9911a4812b47c6479c85eff0628 Mon Sep 17 00:00:00 2001 From: Niklas Kurkisuo Date: Thu, 23 Dec 2010 14:48:10 +0100 Subject: Fix resource leak in QCLuceneStopAnalyzer::QCLuceneStopAnalyzer. CID 22164. Merge-request: 2534 Reviewed-by: Harald Fernengel --- tools/assistant/lib/fulltextsearch/qanalyzer.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/assistant/lib/fulltextsearch/qanalyzer.cpp b/tools/assistant/lib/fulltextsearch/qanalyzer.cpp index 835b72e..23a9f14 100644 --- a/tools/assistant/lib/fulltextsearch/qanalyzer.cpp +++ b/tools/assistant/lib/fulltextsearch/qanalyzer.cpp @@ -147,6 +147,12 @@ QCLuceneStopAnalyzer::QCLuceneStopAnalyzer(const QStringList &stopWords) tArray[stopWords.count()] = 0; d->analyzer = new lucene::analysis::StopAnalyzer(tArray); + + // free memory + for(int i = 0; i < stopWords.count(); ++i) { + delete [] tArray[i]; + } + delete [] tArray; } QStringList QCLuceneStopAnalyzer::englishStopWords() const -- cgit v0.12 From e18dfbc2f5cc99aca1ff7abbab5f9b3be2bfed73 Mon Sep 17 00:00:00 2001 From: Niklas Kurkisuo Date: Thu, 23 Dec 2010 14:48:12 +0100 Subject: Fix resource leak in QCLuceneStandardAnalyzer::QCLuceneStandardAnalyzer. CID 22165. Merge-request: 2534 Reviewed-by: Harald Fernengel --- tools/assistant/lib/fulltextsearch/qanalyzer.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/assistant/lib/fulltextsearch/qanalyzer.cpp b/tools/assistant/lib/fulltextsearch/qanalyzer.cpp index 23a9f14..db2f06c 100644 --- a/tools/assistant/lib/fulltextsearch/qanalyzer.cpp +++ b/tools/assistant/lib/fulltextsearch/qanalyzer.cpp @@ -96,6 +96,12 @@ QCLuceneStandardAnalyzer::QCLuceneStandardAnalyzer(const QStringList &stopWords) tArray[stopWords.count()] = 0; d->analyzer = new lucene::analysis::standard::StandardAnalyzer(tArray); + + // free memory + for(int i = 0; i < stopWords.count(); ++i) { + delete [] tArray[i]; + } + delete [] tArray; } -- cgit v0.12 From d2f87812095d658bceea9287543a7f3d52e18944 Mon Sep 17 00:00:00 2001 From: Juuso Pakarinen Date: Thu, 23 Dec 2010 14:48:13 +0100 Subject: Fix for coding conventions. Merge-request: 2534 Reviewed-by: Harald Fernengel --- tools/assistant/lib/fulltextsearch/qanalyzer.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tools/assistant/lib/fulltextsearch/qanalyzer.cpp b/tools/assistant/lib/fulltextsearch/qanalyzer.cpp index db2f06c..c974fa6 100644 --- a/tools/assistant/lib/fulltextsearch/qanalyzer.cpp +++ b/tools/assistant/lib/fulltextsearch/qanalyzer.cpp @@ -97,10 +97,9 @@ QCLuceneStandardAnalyzer::QCLuceneStandardAnalyzer(const QStringList &stopWords) d->analyzer = new lucene::analysis::standard::StandardAnalyzer(tArray); - // free memory - for(int i = 0; i < stopWords.count(); ++i) { + for (int i = 0; i < stopWords.count(); ++i) delete [] tArray[i]; - } + delete [] tArray; } @@ -154,10 +153,9 @@ QCLuceneStopAnalyzer::QCLuceneStopAnalyzer(const QStringList &stopWords) d->analyzer = new lucene::analysis::StopAnalyzer(tArray); - // free memory - for(int i = 0; i < stopWords.count(); ++i) { + for (int i = 0; i < stopWords.count(); ++i) delete [] tArray[i]; - } + delete [] tArray; } -- cgit v0.12 From 1c5a9b8d80b9dfe26b2d669e081d9a461c181222 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Thu, 23 Dec 2010 14:49:52 +0100 Subject: Whitespace change Since I can't touch merge requests, this is a separate commit to fix whitespace errors in code. --- tools/assistant/lib/fulltextsearch/qanalyzer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/assistant/lib/fulltextsearch/qanalyzer.cpp b/tools/assistant/lib/fulltextsearch/qanalyzer.cpp index c974fa6..56eae69 100644 --- a/tools/assistant/lib/fulltextsearch/qanalyzer.cpp +++ b/tools/assistant/lib/fulltextsearch/qanalyzer.cpp @@ -99,7 +99,7 @@ QCLuceneStandardAnalyzer::QCLuceneStandardAnalyzer(const QStringList &stopWords) for (int i = 0; i < stopWords.count(); ++i) delete [] tArray[i]; - + delete [] tArray; } @@ -155,7 +155,7 @@ QCLuceneStopAnalyzer::QCLuceneStopAnalyzer(const QStringList &stopWords) for (int i = 0; i < stopWords.count(); ++i) delete [] tArray[i]; - + delete [] tArray; } -- cgit v0.12 From 15f6124da9c2cf70e74a1e0e6f89c27d17ec9d29 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 23 Dec 2010 15:53:43 +0200 Subject: Fix fullscreen/Maximized dialog misplacement in Symbian Task-number: QTBUG-16277 Reviewed-by: Sami Merila --- src/gui/dialogs/qdialog.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp index 16ea045..bcf952c 100644 --- a/src/gui/dialogs/qdialog.cpp +++ b/src/gui/dialogs/qdialog.cpp @@ -899,9 +899,21 @@ bool QDialog::symbianAdjustedPosition() { #if defined(Q_WS_S60) QPoint p; - const bool doS60Positioning = !(isFullScreen()||isMaximized()); - if (doS60Positioning) { - QPoint oldPos = pos(); + QPoint oldPos = pos(); + if (isFullScreen()) { + p.setX(0); + p.setY(0); + } else if (isMaximized()) { + TRect statusPaneRect = TRect(); + if (S60->screenHeightInPixels > S60->screenWidthInPixels) { + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStatusPane, statusPaneRect); + } else { + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStaconTop, statusPaneRect); + } + + p.setX(0); + p.setY(statusPaneRect.Height()); + } else { // naive way to deduce screen orientation if (S60->screenHeightInPixels > S60->screenWidthInPixels) { int cbaHeight; @@ -937,10 +949,10 @@ bool QDialog::symbianAdjustedPosition() p.setX(qMax(0,S60->screenWidthInPixels - width())); } } - if (oldPos != p || p.y() < 0) - move(p); } - return doS60Positioning; + if (oldPos != p || p.y() < 0) + move(p); + return true; #else // TODO - check positioning requirement for Symbian, non-s60 return false; -- cgit v0.12 From c168138195b623afc523ddd647dcfb690106c845 Mon Sep 17 00:00:00 2001 From: axis Date: Thu, 23 Dec 2010 15:07:21 +0100 Subject: Fixed several compile and deployment issues in the mmf phonon plugin. RevBy: Trust me Conflicts: src/plugins/phonon/mmf/mmf.pro src/s60installs/s60installs.pro --- src/plugins/phonon/mmf/mmf.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/phonon/mmf/mmf.pro b/src/plugins/phonon/mmf/mmf.pro index e546d83..9dccc4f 100644 --- a/src/plugins/phonon/mmf/mmf.pro +++ b/src/plugins/phonon/mmf/mmf.pro @@ -128,7 +128,7 @@ symbian { is_using_gnupoc { LIBS += -laudioequalizereffect -lbassboosteffect -ldistanceattenuationeffect -ldopplerbase -leffectbase -lenvironmentalreverbeffect -llistenerdopplereffect -llistenerlocationeffect -llistenerorientationeffect -llocationbase -lloudnesseffect -lorientationbase -lsourcedopplereffect -lsourcelocationeffect -lsourceorientationeffect -lstereowideningeffect } else { - LIBS += -lAudioEqualizerEffect -lBassBoostEffect -lDistanceAttenuationEffect -lDopplerBase -lEffectBase -lEnvironmentalReverbEffect -lListenerDopplerEffect -lListenerLocationEffect -lListenerOrientationEffect -lLocationBase -lLoudnessEffect -lOrientationBase -lSourceDopplerEffect -lSourceLocationEffect -lSourceOrientationEffect -lStereoWideningEffect + LIBS += -lAudioEqualizerEffect -lBassBoostEffect -lDistanceAttenuationEffect -lDopplerbase -lEffectBase -lEnvironmentalReverbEffect -lListenerDopplerEffect -lListenerLocationEffect -lListenerOrientationEffect -lLocationBase -lLoudnessEffect -lOrientationBase -lSourceDopplerEffect -lSourceLocationEffect -lSourceOrientationEffect -lStereoWideningEffect } # This is needed for having the .qtplugin file properly created on Symbian. -- cgit v0.12 From 76c1492a51746730c1b51539b87f8d8c810f44ff Mon Sep 17 00:00:00 2001 From: axis Date: Thu, 23 Dec 2010 15:52:38 +0100 Subject: Fixed a bug in elf2e32_qtwrapper regarding spaces in def files. It would not parse the line correctly if a space was missing between the "@" and the ordinal number. RevBy: Trust me --- bin/elf2e32_qtwrapper.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/elf2e32_qtwrapper.pl b/bin/elf2e32_qtwrapper.pl index d91be14..a90877e 100755 --- a/bin/elf2e32_qtwrapper.pl +++ b/bin/elf2e32_qtwrapper.pl @@ -146,7 +146,7 @@ while (1) { $origDefLine = <$origDefFile>; if (defined($origDefLine)) { $origDefLine =~ s/[\n\r]//; - if ($origDefLine =~ /([a-z0-9_]+) +\@ ([0-9]+) (.*)/i) { + if ($origDefLine =~ /([a-z0-9_]+) +\@ *([0-9]+) (.*)/i) { $origSym = $1; $origOrdinal = $2; $origExtraData = $3; @@ -161,7 +161,7 @@ while (1) { if ($savedNewDefFileLine) { # This happens if the new def file was missing an entry. $newDefLine = $savedNewDefFileLine; - $newDefLine =~ /([a-z0-9_]+) +\@ ([0-9]+) (.*)/i or die("$0: Shouldn't happen"); + $newDefLine =~ /([a-z0-9_]+) +\@ *([0-9]+) (.*)/i or die("$0: Shouldn't happen"); $newSym = $1; $newOrdinal = $2; $newExtraData = $3; @@ -171,7 +171,7 @@ while (1) { $newDefLine = <$newDefFile>; if (defined($newDefLine)) { $newDefLine =~ s/[\n\r]//; - if ($newDefLine =~ /([a-z0-9_]+) +\@ ([0-9]+) (.*)/i) { + if ($newDefLine =~ /([a-z0-9_]+) +\@ *([0-9]+) (.*)/i) { $newSym = $1; $newOrdinal = $2; $newExtraData = $3; -- cgit v0.12 From ef96a142f790152524248b4dd0f24e3126ef871e Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Wed, 29 Dec 2010 19:15:03 +0200 Subject: Clear WSERV content when a native child receives an "expose" Native child windows on Symbian can cause composition artifacts on S^3 because they own a visible RWindow instance, but the RWindow technically has no content because child windows paint their content to their parent's backing store. In the event that a native child widget completely obscures a top level, the composition engine does not understand that the child is "empty" and should clear the UI surface to let the top level "shine through". The result is that articacts can remain on the UI surface after a transition from a WSERV drawing app to a Qt (EGL rendering) app. To fix this issue, we call CWindowGc::Clear() when the native child widget receives an "expose" event. This clears the UI surface content and ensures the top level is visible even though it is technically below another RWindow. Task-number: QTMOBILITY-484 Reviewed-by: Jani Hautakangas --- src/gui/kernel/qapplication_s60.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 181fcc7..691c02a 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1071,6 +1071,14 @@ void QSymbianControl::Draw(const TRect& controlRect) const Q_ASSERT(topExtra); if (!topExtra->inExpose) { topExtra->inExpose = true; + if (!qwidget->isWindow()) { + // If we get here, then it means we have a native child window + // Since no content should ever be painted to these windows, we + // erase them with a transparent brush when they get an expose. + CWindowGc &gc = SystemGc(); + gc.SetBrushColor(TRgb(0, 0, 0, 0)); + gc.Clear(controlRect); + } QRect exposeRect = qt_TRect2QRect(controlRect); qwidget->d_func()->syncBackingStore(exposeRect); topExtra->inExpose = false; -- cgit v0.12 From a31d271bdd4594ea455736a0000cd3493b0efc93 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 30 Dec 2010 10:36:06 +1000 Subject: tst_qmessagebox: simulate key events more robustly Don't use QTimer::singleShot because it provides no method of cancelling the event when failures occur. Always verify that the simulated key event is consumed as expected. --- tests/auto/qmessagebox/tst_qmessagebox.cpp | 103 ++++++++++++++++++++--------- 1 file changed, 71 insertions(+), 32 deletions(-) diff --git a/tests/auto/qmessagebox/tst_qmessagebox.cpp b/tests/auto/qmessagebox/tst_qmessagebox.cpp index f6ee764..a39d458 100644 --- a/tests/auto/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/qmessagebox/tst_qmessagebox.cpp @@ -107,7 +107,7 @@ class tst_QMessageBox : public QObject public: tst_QMessageBox(); int exec(QMessageBox *msgBox, int key = -1); - int sendReturn(); + void sendKeySoon(); public slots: void sendKey(); @@ -136,8 +136,12 @@ private slots: void setInformativeText(); void iconPixmap(); + void init(); + void initTestCase(); + private: int keyToSend; + QTimer keySendTimer; }; tst_QMessageBox::tst_QMessageBox() : keyToSend(-1) @@ -152,22 +156,16 @@ int tst_QMessageBox::exec(QMessageBox *msgBox, int key) QTimer::singleShot(1000, msgBox, SLOT(close())); } else { keyToSend = key; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); } return msgBox->exec(); } -int tst_QMessageBox::sendReturn() -{ - keyToSend = Qt::Key_Return; - QTimer::singleShot(1000, this, SLOT(sendKey())); - return 0; -} - void tst_QMessageBox::sendKey() { if (keyToSend == -2) { QApplication::activeModalWidget()->close(); + keyToSend = -1; return; } if (keyToSend == -1) @@ -177,6 +175,24 @@ void tst_QMessageBox::sendKey() keyToSend = -1; } +void tst_QMessageBox::sendKeySoon() +{ + keySendTimer.start(); +} + +void tst_QMessageBox::init() +{ + // if there is any pending key send from the last test, cancel it. + keySendTimer.stop(); +} + +void tst_QMessageBox::initTestCase() +{ + keySendTimer.setInterval(1000); + keySendTimer.setSingleShot(true); + QVERIFY(QObject::connect(&keySendTimer, SIGNAL(timeout()), this, SLOT(sendKey()))); +} + void tst_QMessageBox::sanityTest() { QMessageBox msgBox; @@ -317,32 +333,36 @@ void tst_QMessageBox::statics() for (int i = 0; i < 4; i++) { keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); QMessageBox::StandardButton sb = (*statics[i])(0, "caption", "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help | QMessageBox::Cancel, QMessageBox::NoButton); QCOMPARE(sb, QMessageBox::Cancel); + QCOMPARE(keyToSend, -1); keyToSend = -2; // close() - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); sb = (*statics[i])(0, "caption", "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help | QMessageBox::Cancel, QMessageBox::NoButton); QCOMPARE(sb, QMessageBox::Cancel); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); sb = (*statics[i])(0, "caption", "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help, QMessageBox::Yes); QCOMPARE(sb, QMessageBox::Yes); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); sb = (*statics[i])(0, "caption", "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help, QMessageBox::No); QCOMPARE(sb, QMessageBox::No); + QCOMPARE(keyToSend, -1); } } @@ -361,16 +381,18 @@ void tst_QMessageBox::shortcut() void tst_QMessageBox::about() { keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); QMessageBox::about(0, "Caption", "This is an auto test"); + QCOMPARE(keyToSend, -1); #if !defined(Q_OS_WINCE) keyToSend = Qt::Key_Enter; #else keyToSend = Qt::Key_Escape; #endif - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); QMessageBox::aboutQt(0, "Caption"); + QCOMPARE(keyToSend, -1); } // Old message box enums @@ -392,7 +414,7 @@ void tst_QMessageBox::staticSourceCompat() // source compat tests for < 4.2 keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes, QMessageBox::No); int expectedButton = int(QMessageBox::Yes); #if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) @@ -403,43 +425,51 @@ void tst_QMessageBox::staticSourceCompat() expectedButton = int(QMessageBox::No); #endif QCOMPARE(ret, expectedButton); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No); QCOMPARE(ret, int(QMessageBox::Yes)); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes, QMessageBox::No | QMessageBox::Default); QCOMPARE(ret, int(QMessageBox::No)); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape); QCOMPARE(ret, int(QMessageBox::Yes)); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Escape, QMessageBox::No | QMessageBox::Default); QCOMPARE(ret, int(QMessageBox::No)); + QCOMPARE(keyToSend, -1); // the button text versions keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 1); QCOMPARE(ret, 1); + QCOMPARE(keyToSend, -1); if (0) { // dont run these tests since the dialog wont close! keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 1); QCOMPARE(ret, -1); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 0, 1); QCOMPARE(ret, 1); + QCOMPARE(keyToSend, -1); } } @@ -472,7 +502,7 @@ void tst_QMessageBox::staticBinaryCompat() // binary compat tests for < 4.2 keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", Old_Yes, Old_No, 0); int expectedButton = int(Old_Yes); #if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) @@ -483,33 +513,39 @@ void tst_QMessageBox::staticBinaryCompat() expectedButton = int(Old_No); #endif QCOMPARE(ret, expectedButton); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", Old_Yes | Old_Escape, Old_No, 0); QCOMPARE(ret, int(Old_Yes)); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", Old_Yes | Old_Default, Old_No, 0); QCOMPARE(ret, int(Old_Yes)); + QCOMPARE(keyToSend, -1); #if 0 keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", Old_Yes, Old_No | Old_Default, 0); QCOMPARE(ret, -1); + QCOMPARE(keyToSend, -1); #endif keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", Old_Yes | Old_Escape, Old_No | Old_Default, 0); QCOMPARE(ret, Old_Yes); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", Old_Yes | Old_Default, Old_No | Old_Escape, 0); QCOMPARE(ret, Old_No); + QCOMPARE(keyToSend, -1); } @@ -688,22 +724,25 @@ void tst_QMessageBox::detailsButtonText() void tst_QMessageBox::incorrectDefaultButton() { keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); //Do not crash here QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); QMessageBox::question( 0, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save ); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); QMessageBox::question( 0, "", "I've been hit!",QFlag(QMessageBox::Ok | QMessageBox::Cancel),QMessageBox::Save ); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); //do not crash here -> call old function of QMessageBox in this case QMessageBox::question( 0, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Ok); + QCOMPARE(keyToSend, -1); } void tst_QMessageBox::updateSize() -- cgit v0.12 From 6981c17455f949fd4fccbaf1bd42ab48f95d4212 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 30 Dec 2010 10:46:05 +1000 Subject: tst_qmessagebox: make the failure message better for detailsButtonText --- tests/auto/qmessagebox/tst_qmessagebox.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/auto/qmessagebox/tst_qmessagebox.cpp b/tests/auto/qmessagebox/tst_qmessagebox.cpp index a39d458..9e497fa 100644 --- a/tests/auto/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/qmessagebox/tst_qmessagebox.cpp @@ -714,8 +714,7 @@ void tst_QMessageBox::detailsButtonText() foreach(btn, list) { if (btn && (btn->inherits("QPushButton"))) { if (btn->text() != QMessageBox::tr("OK") && btn->text() != QMessageBox::tr("Show Details...")) { - qDebug() << btn->text(); - QFAIL("Incorrect messagebox button text!"); + QFAIL(qPrintable(QString("Unexpected messagebox button text: %1").arg(btn->text()))); } } } -- cgit v0.12 From 89866e1112bba004847573c5494aa3b6ec75049f Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 30 Dec 2010 15:25:38 +1000 Subject: tst_qmessagebox: fix `about' test on mac QMessageBox::about and aboutQt are modeless on Mac (only). This means that if we simulate key events, we need to explicitly run the event loop until they are consumed. Prior to a31d271bdd4594ea455736a0000cd3493b0efc93, this buggy test was causing detailsButtonText to fail. --- tests/auto/qmessagebox/tst_qmessagebox.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/auto/qmessagebox/tst_qmessagebox.cpp b/tests/auto/qmessagebox/tst_qmessagebox.cpp index 9e497fa..4bc1a28 100644 --- a/tests/auto/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/qmessagebox/tst_qmessagebox.cpp @@ -55,6 +55,8 @@ #include #endif +#include "../../shared/util.h" + //TESTED_CLASS= //TESTED_FILES= @@ -383,7 +385,13 @@ void tst_QMessageBox::about() keyToSend = Qt::Key_Escape; sendKeySoon(); QMessageBox::about(0, "Caption", "This is an auto test"); + // On Mac, about and aboutQt are not modal, so we need to + // explicitly run the event loop +#ifdef Q_WS_MAC + QTRY_COMPARE(keyToSend, -1); +#else QCOMPARE(keyToSend, -1); +#endif #if !defined(Q_OS_WINCE) keyToSend = Qt::Key_Enter; @@ -392,7 +400,11 @@ void tst_QMessageBox::about() #endif sendKeySoon(); QMessageBox::aboutQt(0, "Caption"); +#ifdef Q_WS_MAC + QTRY_COMPARE(keyToSend, -1); +#else QCOMPARE(keyToSend, -1); +#endif } // Old message box enums -- cgit v0.12 From 8365b863419ad68f7dde7b7595e1b943ad9670ca Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Fri, 31 Dec 2010 08:20:39 +1000 Subject: Fixed networkselftest failing to resolve hostname The logic here was the opposite from what was intended. Note that this bug was hidden under normal circumstances when running the entire testcase. It only appeared when one of the following was true: (1) httpProxy or socks5Proxy was run on its own, or (2) the dnsResolution test failed. --- tests/auto/networkselftest/tst_networkselftest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/networkselftest/tst_networkselftest.cpp b/tests/auto/networkselftest/tst_networkselftest.cpp index 752e368..5e9c50e 100644 --- a/tests/auto/networkselftest/tst_networkselftest.cpp +++ b/tests/auto/networkselftest/tst_networkselftest.cpp @@ -337,7 +337,7 @@ QHostAddress tst_NetworkSelfTest::serverIpAddress() // need resolving QHostInfo resolved = QHostInfo::fromName(QtNetworkSettings::serverName()); if(resolved.error() != QHostInfo::NoError || - !resolved.addresses().isEmpty()) { + resolved.addresses().isEmpty()) { qWarning("QHostInfo::fromName failed (%d).", resolved.error()); return QHostAddress(QHostAddress::Null); } -- cgit v0.12