diff options
-rw-r--r-- | src/corelib/global/qglobal.h | 31 | ||||
-rw-r--r-- | src/corelib/tools/qalgorithms.h | 17 | ||||
-rw-r--r-- | src/corelib/tools/qshareddata.h | 14 | ||||
-rw-r--r-- | src/corelib/tools/qsharedpointer_impl.h | 19 | ||||
-rw-r--r-- | src/gui/text/qtextdocumentlayout.cpp | 19 | ||||
-rw-r--r-- | tests/auto/headers/tst_headers.cpp | 84 | ||||
-rw-r--r-- | tests/auto/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp | 20 | ||||
-rw-r--r-- | tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 32 | ||||
-rw-r--r-- | tests/auto/qtextdocument/tst_qtextdocument.cpp | 39 |
9 files changed, 206 insertions, 69 deletions
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 5a2c329..92fe649 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1906,6 +1906,14 @@ public: \ static inline const char *name() { return #TYPE; } \ } +template <typename T> +inline void qSwap(T &value1, T &value2) +{ + const T t = value1; + value1 = value2; + value2 = t; +} + /* Specialize a shared type with: @@ -1915,33 +1923,12 @@ public: \ types must declare a 'bool isDetached(void) const;' member for this to work. */ -#if defined Q_CC_MSVC && _MSC_VER < 1300 -template <typename T> -inline void qSwap_helper(T &value1, T &value2, T*) -{ - T t = value1; - value1 = value2; - value2 = t; -} #define Q_DECLARE_SHARED(TYPE) \ template <> inline bool qIsDetached<TYPE>(TYPE &t) { return t.isDetached(); } \ -template <> inline void qSwap_helper<TYPE>(TYPE &value1, TYPE &value2, TYPE*) \ -{ \ - const TYPE::DataPtr t = value1.data_ptr(); \ - value1.data_ptr() = value2.data_ptr(); \ - value2.data_ptr() = t; \ -} -#else -#define Q_DECLARE_SHARED(TYPE) \ -template <> inline bool qIsDetached<TYPE>(TYPE &t) { return t.isDetached(); } \ -template <typename T> inline void qSwap(T &, T &); \ template <> inline void qSwap<TYPE>(TYPE &value1, TYPE &value2) \ { \ - const TYPE::DataPtr t = value1.data_ptr(); \ - value1.data_ptr() = value2.data_ptr(); \ - value2.data_ptr() = t; \ + qSwap<TYPE::DataPtr>(value1.data_ptr(), value2.data_ptr()); \ } -#endif /* QTypeInfo primitive specializations diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h index 6f623d9..3e5c3cc 100644 --- a/src/corelib/tools/qalgorithms.h +++ b/src/corelib/tools/qalgorithms.h @@ -141,23 +141,6 @@ inline void qCount(const Container &container, const T &value, Size &n) qCount(container.constBegin(), container.constEnd(), value, n); } - -#if defined Q_CC_MSVC && _MSC_VER < 1300 -template <typename T> -inline void qSwap(T &value1, T &value2) -{ - qSwap_helper<T>(value1, value2, (T *)0); -} -#else -template <typename T> -inline void qSwap(T &value1, T &value2) -{ - T t = value1; - value1 = value2; - value2 = t; -} -#endif - #ifdef qdoc template <typename T> LessThan qLess() diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h index e13e37c..dde6e88 100644 --- a/src/corelib/tools/qshareddata.h +++ b/src/corelib/tools/qshareddata.h @@ -111,6 +111,9 @@ public: inline bool operator!() const { return !d; } + inline void swap(QSharedDataPointer &other) + { qSwap(d, other.d); } + protected: T *clone(); @@ -186,6 +189,9 @@ public: inline bool operator!() const { return !d; } + inline void swap(QExplicitlySharedDataPointer &other) + { qSwap(d, other.d); } + protected: T *clone(); @@ -235,6 +241,14 @@ template <class T> Q_INLINE_TEMPLATE QExplicitlySharedDataPointer<T>::QExplicitlySharedDataPointer(T *adata) : d(adata) { if (d) d->ref.ref(); } +template <class T> +Q_INLINE_TEMPLATE void qSwap(QSharedDataPointer<T> &p1, QSharedDataPointer<T> &p2) +{ p1.swap(p2); } + +template <class T> +Q_INLINE_TEMPLATE void qSwap(QExplicitlySharedDataPointer<T> &p1, QExplicitlySharedDataPointer<T> &p2) +{ p1.swap(p2); } + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index cbeb79f..1136aa9 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -171,8 +171,8 @@ namespace QtSharedPointer { inline ExternalRefCountData() { - QBasicAtomicInt proto = Q_BASIC_ATOMIC_INITIALIZER(1); - weakref = strongref = proto; + strongref = 1; + weakref = 1; } inline ExternalRefCountData(Qt::Initialization) { } virtual inline ~ExternalRefCountData() { Q_ASSERT(!weakref); Q_ASSERT(strongref <= 0); } @@ -385,6 +385,12 @@ namespace QtSharedPointer { delete this->value; } + inline void internalSwap(ExternalRefCount &other) + { + qSwap(d, other.d); + qSwap(this->value, other.value); + } + #if defined(Q_NO_TEMPLATE_FRIENDS) public: #else @@ -465,6 +471,9 @@ public: inline QSharedPointer<T> &operator=(const QWeakPointer<X> &other) { internalSet(other.d, other.value); return *this; } + inline void swap(QSharedPointer &other) + { internalSwap(other); } + template <class X> QSharedPointer<X> staticCast() const { @@ -682,6 +691,12 @@ Q_INLINE_TEMPLATE QWeakPointer<T> QSharedPointer<T>::toWeakRef() const return QWeakPointer<T>(*this); } +template <class T> +inline void qSwap(QSharedPointer<T> &p1, QSharedPointer<T> &p2) +{ + p1.swap(p2); +} + namespace QtSharedPointer { // helper functions: template <class X, class T> diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index e26961f..a795c1f 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -2601,13 +2601,13 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi // float has been added in the meantime, redo layoutStruct->pendingFloats.clear(); - if (haveWordOrAnyWrapMode) { - option.setWrapMode(QTextOption::WrapAnywhere); - tl->setTextOption(option); - } - line.setLineWidth((right-left).toReal()); if (QFixed::fromReal(line.naturalTextWidth()) > right-left) { + if (haveWordOrAnyWrapMode) { + option.setWrapMode(QTextOption::WrapAnywhere); + tl->setTextOption(option); + } + layoutStruct->pendingFloats.clear(); // lines min width more than what we have layoutStruct->y = findY(layoutStruct->y, layoutStruct, QFixed::fromReal(line.naturalTextWidth())); @@ -2619,12 +2619,13 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi else right -= text_indent; line.setLineWidth(qMax<qreal>(line.naturalTextWidth(), (right-left).toReal())); - } - if (haveWordOrAnyWrapMode) { - option.setWrapMode(QTextOption::WordWrap); - tl->setTextOption(option); + if (haveWordOrAnyWrapMode) { + option.setWrapMode(QTextOption::WordWrap); + tl->setTextOption(option); + } } + } QFixed lineHeight = QFixed::fromReal(line.height()); diff --git a/tests/auto/headers/tst_headers.cpp b/tests/auto/headers/tst_headers.cpp index 51e3a55..f5a11f4 100644 --- a/tests/auto/headers/tst_headers.cpp +++ b/tests/auto/headers/tst_headers.cpp @@ -50,7 +50,7 @@ public: private slots: void initTestCase(); - void licenseCheck_data() { allHeadersData(); } + void licenseCheck_data() { allSourceFilesData(); } void licenseCheck(); void privateSlots_data() { allHeadersData(); } @@ -60,11 +60,19 @@ private slots: void macros(); private: + static QStringList getFiles(const QString &path, + const QStringList dirFilters, + const QRegExp &exclude); + static QStringList getHeaders(const QString &path); + static QStringList getSourceFiles(const QString &path); + + void allSourceFilesData(); void allHeadersData(); QStringList headers; const QRegExp copyrightPattern; const QRegExp licensePattern; const QRegExp moduleTest; + QString qtSrcDir; }; tst_Headers::tst_Headers() : @@ -74,29 +82,41 @@ tst_Headers::tst_Headers() : { } -QStringList getHeaders(const QString &path) +QStringList tst_Headers::getFiles(const QString &path, + const QStringList dirFilters, + const QRegExp &excludeReg) { - QStringList headers; - - QDir dir(path); - QStringList dirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + const QDir dir(path); + const QStringList dirs(dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)); + QStringList result; foreach (QString subdir, dirs) - headers += getHeaders(path + "/" + subdir); + result += getFiles(path + "/" + subdir, dirFilters, excludeReg); - QStringList entries = dir.entryList(QStringList("*.h"), QDir::Files); - QRegExp reg("^(?!ui_)"); - entries = entries.filter(reg); + QStringList entries = dir.entryList(dirFilters, QDir::Files); + entries = entries.filter(excludeReg); foreach (QString entry, entries) - headers += path + "/" + entry; + result += path + "/" + entry; - return headers; + return result; +} + +QStringList tst_Headers::getHeaders(const QString &path) +{ + return getFiles(path, QStringList("*.h"), QRegExp("^(?!ui_)")); +} + +QStringList tst_Headers::getSourceFiles(const QString &path) +{ + return getFiles(path, QStringList("*.cpp"), QRegExp("^(?!(moc_|qrc_))")); } void tst_Headers::initTestCase() { - QString qtSrcDir = QString::fromLocal8Bit(qgetenv("QTSRCDIR").isEmpty() - ? qgetenv("QTDIR") : qgetenv("QTSRCDIR")); + qtSrcDir = QString::fromLocal8Bit(qgetenv("QTSRCDIR").isEmpty() + ? qgetenv("QTDIR") + : qgetenv("QTSRCDIR")); + headers = getHeaders(qtSrcDir + "/src"); #ifndef Q_OS_WINCE @@ -108,6 +128,30 @@ void tst_Headers::initTestCase() QVERIFY(licensePattern.isValid()); } +void tst_Headers::allSourceFilesData() +{ + QTest::addColumn<QString>("sourceFile"); + + const QStringList sourceFiles(getSourceFiles(qtSrcDir)); + + foreach (QString sourceFile, sourceFiles) { + if (sourceFile.contains("/3rdparty/") + || sourceFile.contains("/config.tests/") + || sourceFile.contains("/snippets/") + || sourceFile.contains("linguist/lupdate/testdata") + || sourceFile.contains("/fulltextsearch/")) + continue; + + // This test is crude, but if a file contains this string, we skip it. + QFile file(sourceFile); + QVERIFY(file.open(QIODevice::ReadOnly)); + if (file.readAll().contains("This file was generated by")) + continue; + + QTest::newRow(qPrintable(sourceFile)) << sourceFile; + } +} + void tst_Headers::allHeadersData() { QTest::addColumn<QString>("header"); @@ -125,12 +169,14 @@ void tst_Headers::allHeadersData() void tst_Headers::licenseCheck() { - QFETCH(QString, header); + QFETCH(QString, sourceFile); - if (header.endsWith("/qgifhandler.h") || header.endsWith("/qconfig.h")) + if (sourceFile.endsWith("/qgifhandler.h") + || sourceFile.endsWith("/qconfig.h") + || sourceFile.endsWith("/qconfig.cpp")) return; - QFile f(header); + QFile f(sourceFile); QVERIFY(f.open(QIODevice::ReadOnly)); QByteArray data = f.readAll(); QStringList content = QString::fromLocal8Bit(data.replace('\r',"")).split("\n"); @@ -138,8 +184,8 @@ void tst_Headers::licenseCheck() if (content.first().contains("generated")) content.takeFirst(); - QVERIFY(licensePattern.exactMatch(content.at(7)) || - licensePattern.exactMatch(content.at(4))); + QVERIFY(licensePattern.exactMatch(content.value(7)) || + licensePattern.exactMatch(content.value(4))); QString licenseType = licensePattern.cap(1); int i = 0; diff --git a/tests/auto/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp b/tests/auto/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp index 4cdeb5c..97e57f1 100644 --- a/tests/auto/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp +++ b/tests/auto/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp @@ -61,6 +61,7 @@ private Q_SLOTS: void clone() const; void data() const; void reset() const; + void swap() const; }; class MyClass : public QSharedData @@ -233,6 +234,25 @@ void tst_QExplicitlySharedDataPointer::reset() const } } +void tst_QExplicitlySharedDataPointer::swap() const +{ + QExplicitlySharedDataPointer<MyClass> p1(0), p2(new MyClass()); + QVERIFY(!p1.data()); + QVERIFY(p2.data()); + + p1.swap(p2); + QVERIFY(p1.data()); + QVERIFY(!p2.data()); + + p1.swap(p2); + QVERIFY(!p1.data()); + QVERIFY(p2.data()); + + qSwap(p1, p2); + QVERIFY(p1.data()); + QVERIFY(!p2.data()); +} + QTEST_MAIN(tst_QExplicitlySharedDataPointer) #include "tst_qexplicitlyshareddatapointer.moc" diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 58e5401..ab75c91 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -62,6 +62,7 @@ class tst_QSharedPointer: public QObject private slots: void basics_data(); void basics(); + void swap(); void forwardDeclaration1(); void forwardDeclaration2(); void memoryManagement(); @@ -263,6 +264,37 @@ void tst_QSharedPointer::basics() // aData is deleted here } +void tst_QSharedPointer::swap() +{ + QSharedPointer<int> p1, p2(new int(42)), control = p2; + QVERIFY(p1 != control); + QVERIFY(p1.isNull()); + QVERIFY(p2 == control); + QVERIFY(!p2.isNull()); + QVERIFY(*p2 == 42); + + p1.swap(p2); + QVERIFY(p1 == control); + QVERIFY(!p1.isNull()); + QVERIFY(p2 != control); + QVERIFY(p2.isNull()); + QVERIFY(*p1 == 42); + + p1.swap(p2); + QVERIFY(p1 != control); + QVERIFY(p1.isNull()); + QVERIFY(p2 == control); + QVERIFY(!p2.isNull()); + QVERIFY(*p2 == 42); + + qSwap(p1, p2); + QVERIFY(p1 == control); + QVERIFY(!p1.isNull()); + QVERIFY(p2 != control); + QVERIFY(p2.isNull()); + QVERIFY(*p1 == 42); +} + class ForwardDeclared; ForwardDeclared *forwardPointer(); void externalForwardDeclaration(); diff --git a/tests/auto/qtextdocument/tst_qtextdocument.cpp b/tests/auto/qtextdocument/tst_qtextdocument.cpp index 72f3ea8..4643df0 100644 --- a/tests/auto/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/qtextdocument/tst_qtextdocument.cpp @@ -55,8 +55,13 @@ #include <qtextlist.h> #include <qtextcodec.h> #include <qurl.h> +#include <qpainter.h> +#include <qfontmetrics.h> +#include <qimage.h> +#include <qtextlayout.h> #include "common.h" + QT_FORWARD_DECLARE_CLASS(QTextDocument) //TESTED_CLASS= @@ -93,6 +98,8 @@ private slots: void noundo_isModified3(); void mightBeRichText(); + void task240325(); + void toHtml_data(); void toHtml(); void toHtml2(); @@ -532,6 +539,38 @@ void tst_QTextDocument::noundo_basicIsModifiedChecks() QCOMPARE(spy.count(), 0); } +void tst_QTextDocument::task240325() +{ + doc->setHtml("<html><img width=\"100\" height=\"100\" align=\"right\"/>Foobar Foobar Foobar Foobar</html>"); + + QImage img(1000, 7000, QImage::Format_ARGB32_Premultiplied); + QPainter p(&img); + QFontMetrics fm(p.font()); + + // Set page size to contain image and one "Foobar" + doc->setPageSize(QSize(100 + fm.width("Foobar")*2, 1000)); + + // Force layout + doc->drawContents(&p); + + QCOMPARE(doc->blockCount(), 1); + for (QTextBlock block = doc->begin() ; block!=doc->end() ; block = block.next()) { + QTextLayout *layout = block.layout(); + QCOMPARE(layout->lineCount(), 4); + for (int lineIdx=0;lineIdx<layout->lineCount();++lineIdx) { + QTextLine line = layout->lineAt(lineIdx); + + QString text = block.text().mid(line.textStart(), line.textLength()).trimmed(); + + // Remove start token + if (lineIdx == 0) + text = text.mid(1); + + QCOMPARE(text, QString::fromLatin1("Foobar")); + } + } +} + void tst_QTextDocument::noundo_moreIsModified() { doc->setUndoRedoEnabled(false); |