From 37a8926fd8aa1971a4d0a8b04facf63c631b9367 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 11 Aug 2009 10:26:31 +0200 Subject: fix warnings for the qreal == float case Reviewed-by: mauricek --- src/gui/graphicsview/qgraphicsscene_p.h | 4 ++-- src/gui/styles/qstylehelper.cpp | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index a4bbdd2..7415591 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -267,9 +267,9 @@ static inline void _q_adjustRect(QRectF *rect) { Q_ASSERT(rect); if (!rect->width()) - rect->adjust(-0.00001, 0, 0.00001, 0); + rect->adjust(qreal(-0.00001), 0, qreal(0.00001), 0); if (!rect->height()) - rect->adjust(0, -0.00001, 0, 0.00001); + rect->adjust(0, qreal(-0.00001), 0, qreal(0.00001)); } static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item) diff --git a/src/gui/styles/qstylehelper.cpp b/src/gui/styles/qstylehelper.cpp index 4877ec4..402c4d1 100644 --- a/src/gui/styles/qstylehelper.cpp +++ b/src/gui/styles/qstylehelper.cpp @@ -250,8 +250,8 @@ void drawDial(const QStyleOptionSlider *option, QPainter *painter) QRadialGradient shadowGradient(shadowRect.center().x(), shadowRect.center().y(), shadowRect.width()/2.0, shadowRect.center().x(), shadowRect.center().y()); - shadowGradient.setColorAt(0.91, QColor(0, 0, 0, 40)); - shadowGradient.setColorAt(1.0, Qt::transparent); + shadowGradient.setColorAt(qreal(0.91), QColor(0, 0, 0, 40)); + shadowGradient.setColorAt(qreal(1.0), Qt::transparent); p->setBrush(shadowGradient); p->setPen(Qt::NoPen); p->translate(shadowSize, shadowSize); @@ -263,8 +263,8 @@ void drawDial(const QStyleOptionSlider *option, QPainter *painter) br.width()*1.3, br.center().x(), br.center().y() - br.height()/2); gradient.setColorAt(0, buttonColor.lighter(110)); - gradient.setColorAt(0.5, buttonColor); - gradient.setColorAt(0.501, buttonColor.darker(102)); + gradient.setColorAt(qreal(0.5), buttonColor); + gradient.setColorAt(qreal(0.501), buttonColor.darker(102)); gradient.setColorAt(1, buttonColor.darker(115)); p->setBrush(gradient); } else { @@ -290,21 +290,21 @@ void drawDial(const QStyleOptionSlider *option, QPainter *painter) END_STYLE_PIXMAPCACHE - QPointF dp = calcRadialPos(option, 0.70); + QPointF dp = calcRadialPos(option, qreal(0.70)); buttonColor = buttonColor.lighter(104); - buttonColor.setAlphaF(0.8); - const qreal ds = r/7.0; + buttonColor.setAlphaF(qreal(0.8)); + const qreal ds = r/qreal(7.0); QRectF dialRect(dp.x() - ds, dp.y() - ds, 2*ds, 2*ds); QRadialGradient dialGradient(dialRect.center().x() + dialRect.width()/2, dialRect.center().y() + dialRect.width(), dialRect.width()*2, dialRect.center().x(), dialRect.center().y()); dialGradient.setColorAt(1, buttonColor.darker(140)); - dialGradient.setColorAt(0.4, buttonColor.darker(120)); + dialGradient.setColorAt(qreal(0.4), buttonColor.darker(120)); dialGradient.setColorAt(0, buttonColor.darker(110)); if (penSize > 3.0) { painter->setPen(QPen(QColor(0, 0, 0, 25), penSize)); - painter->drawLine(calcRadialPos(option, 0.90), calcRadialPos(option, 0.96)); + painter->drawLine(calcRadialPos(option, qreal(0.90)), calcRadialPos(option, qreal(0.96))); } painter->setBrush(dialGradient); -- cgit v0.12 From d45b0ee01402c2474652f6afd2cd1e8564d8071c Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 11 Aug 2009 16:03:03 +0200 Subject: QPoint comparision operators use qFuzzyIsNull instead of qFuzzyCompare qFuzzyCompare doesn't support 0 as parameter. So this function is pretty useless for QPoint, where coordinates can be zero. Reviewed-by: Harald Fernengel --- src/corelib/tools/qpoint.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qpoint.h b/src/corelib/tools/qpoint.h index df35eaa..8d653b0 100644 --- a/src/corelib/tools/qpoint.h +++ b/src/corelib/tools/qpoint.h @@ -302,12 +302,12 @@ inline QPointF &QPointF::operator*=(qreal c) inline bool operator==(const QPointF &p1, const QPointF &p2) { - return qFuzzyCompare(p1.xp, p2.xp) && qFuzzyCompare(p1.yp, p2.yp); + return qFuzzyIsNull(p1.xp - p2.xp) && qFuzzyIsNull(p1.yp - p2.yp); } inline bool operator!=(const QPointF &p1, const QPointF &p2) { - return !qFuzzyCompare(p1.xp, p2.xp) || !qFuzzyCompare(p1.yp, p2.yp); + return !qFuzzyIsNull(p1.xp - p2.xp) || !qFuzzyIsNull(p1.yp - p2.yp); } inline const QPointF operator+(const QPointF &p1, const QPointF &p2) -- cgit v0.12 From ee7d7a4f3016e8ca94bde5c2328676e31bf4eba2 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 11 Aug 2009 11:53:41 +0200 Subject: fix QTextFormat::doubleProperty where qreal is float This function was too strict. It returned 0 if the property wasn't of type QVariant::Double. Now it tests for QMetaType::Float too. Reviewed-by: kh1 Reviewed-by: mauricek --- src/gui/text/qtextformat.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index a3dd83e..fd0c17f 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -875,7 +875,8 @@ int QTextFormat::intProperty(int propertyId) const /*! Returns the value of the property specified by \a propertyId. If the - property isn't of QVariant::Double type, 0 is returned instead. + property isn't of QVariant::Double or QMetaType::Float type, 0 is + returned instead. \sa setProperty() boolProperty() intProperty() stringProperty() colorProperty() lengthProperty() lengthVectorProperty() Property */ @@ -884,9 +885,9 @@ qreal QTextFormat::doubleProperty(int propertyId) const if (!d) return 0.; const QVariant prop = d->property(propertyId); - if (prop.type() != QVariant::Double) + if (prop.type() != QVariant::Double && prop.type() != QMetaType::Float) return 0.; - return prop.toDouble(); // #### + return qVariantValue(prop); } /*! -- cgit v0.12 From 204c771ab5c0ef62c76ead594bfeacc3627ab108 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 11 Aug 2009 17:56:43 +0200 Subject: fix tst_QPixmapCache::clear for Windows CE This test used too much memory for Windows CE <= 5. Reviewed-by: thartman --- tests/auto/qpixmapcache/tst_qpixmapcache.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp index e71bd5d..7866df8 100644 --- a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp +++ b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp @@ -392,14 +392,19 @@ void tst_QPixmapCache::clear() QPixmap p1(10, 10); p1.fill(Qt::red); - for (int i = 0; i < 20000; ++i) +#ifdef Q_OS_WINCE + const int numberOfKeys = 10000; +#else + const int numberOfKeys = 20000; +#endif + for (int i = 0; i < numberOfKeys; ++i) QVERIFY(QPixmapCache::find("x" + QString::number(i)) == 0); - for (int j = 0; j < 20000; ++j) + for (int j = 0; j < numberOfKeys; ++j) QPixmapCache::insert(QString::number(j), p1); int num = 0; - for (int k = 0; k < 20000; ++k) { + for (int k = 0; k < numberOfKeys; ++k) { if (QPixmapCache::find(QString::number(k), p1)) ++num; } @@ -407,7 +412,7 @@ void tst_QPixmapCache::clear() QPixmapCache::clear(); - for (int k = 0; k < 20000; ++k) + for (int k = 0; k < numberOfKeys; ++k) QVERIFY(QPixmapCache::find(QString::number(k)) == 0); //The int part of the API @@ -415,12 +420,12 @@ void tst_QPixmapCache::clear() p2.fill(Qt::red); QList keys; - for (int k = 0; k < 20000; ++k) + for (int k = 0; k < numberOfKeys; ++k) keys.append(QPixmapCache::insert(p2)); QPixmapCache::clear(); - for (int k = 0; k < 20000; ++k) { + for (int k = 0; k < numberOfKeys; ++k) { QVERIFY(QPixmapCache::find(keys.at(k), &p1) == 0); QCOMPARE(getPrivate(keys[k])->isValid, false); } -- cgit v0.12 From eb4efda5c8a9a32c38945e26f68217b170b87ffb Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:14 +0200 Subject: QFSFileEngine::mkdir fix on Windows This function now returns early if a non-directory is met in the path. Something like /foo/bar/&&/ will bail out early. Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 7c75525..11d1ca6 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -958,9 +958,13 @@ bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) con if (slash) { QString chunk = dirName.left(slash); bool existed = false; - if (!isDirPath(chunk, &existed) && !existed) { - if (!mkDir(chunk)) + if (!isDirPath(chunk, &existed)) { + if (!existed) { + if (!mkDir(chunk)) + return false; + } else { return false; + } } } } -- cgit v0.12 From d703c131bae6fb89672a55e1bcd735e2514e75ac Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:16 +0200 Subject: don't set FileType flag when link's target doesn't exists Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 11d1ca6..25fbae8 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -896,7 +896,7 @@ static inline bool rmDir(const QString &path) static inline bool isDirPath(const QString &dirPath, bool *existed) { QString path = dirPath; - if (path.length() == 2 &&path.at(1) == QLatin1Char(':')) + if (path.length() == 2 && path.at(1) == QLatin1Char(':')) path += QLatin1Char('\\'); DWORD fileAttrib = ::GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16()); @@ -1523,9 +1523,10 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil ret |= LinkType; QString l = readLink(d->filePath); if (!l.isEmpty()) { - if (isDirPath(l, 0)) + bool existed = false; + if (isDirPath(l, &existed) && existed) ret |= DirectoryType; - else + else if (existed) ret |= FileType; } } else if (d->doStat()) { -- cgit v0.12 From c9fb4ac3483c492f32e4f42987935478d4e89eb8 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:18 +0200 Subject: micro-optimization in QFSFileEngine::mkdir Merge-request: 1176 Reviewed-by: Joerg Bornemann --- 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 c0b6820..075aa7c 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -414,15 +414,15 @@ bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) con if ((st.st_mode & S_IFMT) != S_IFDIR) return false; } else if (QT_MKDIR(chunk, 0777) != 0) { - return false; + return false; } } } return true; } #if defined(Q_OS_DARWIN) // Mac X doesn't support trailing /'s - if (dirName[dirName.length() - 1] == QLatin1Char('/')) - dirName = dirName.left(dirName.length() - 1); + if (dirName.endsWith(QLatin1Char('/'))) + dirName.chop(1); #endif return (QT_MKDIR(QFile::encodeName(dirName), 0777) == 0); } -- cgit v0.12 From bcbaeff0332e30f020f031b99efcc69d9707f962 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:20 +0200 Subject: replace QFile::exists() by QT_STAT() respectively which is a bit faster since it doesn't creates new file engine instance Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_unix.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 075aa7c..cde5272 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -76,10 +76,14 @@ static QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QString & if ((flags & QIODevice::ReadOnly) && !(flags & QIODevice::Truncate)) { mode = "rb"; if (flags & QIODevice::WriteOnly) { - if (!fileName.isEmpty() &&QFile::exists(fileName)) - mode = "rb+"; - else + QT_STATBUF statBuf; + if (!fileName.isEmpty() + && QT_STAT(QFile::encodeName(fileName), &statBuf) == 0 + && (statBuf.st_mode & S_IFMT) == S_IFREG) { + mode += "+"; + } else { mode = "wb+"; + } } } else if (flags & QIODevice::WriteOnly) { mode = "wb"; -- cgit v0.12 From 0e193b51c995395c92f8b1d0b67a782314772c6c Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:23 +0200 Subject: avoid needless const_cast-s tried_stat, could_stat, need_lstat, and is_link are members marked as mutable; prefer mutable over const_cast Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_unix.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index cde5272..029d422 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -524,18 +524,19 @@ QFileInfoList QFSFileEngine::drives() bool QFSFileEnginePrivate::doStat() const { - if (tried_stat == 0) { - QFSFileEnginePrivate *that = const_cast(this); + if (!tried_stat) { + tried_stat = true; + could_stat = false; + if (fh && nativeFilePath.isEmpty()) { // ### actually covers two cases: d->fh and when the file is not open - that->could_stat = (QT_FSTAT(fileno(fh), &st) == 0); + 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 - that->could_stat = (QT_STAT(nativeFilePath.constData(), &st) == 0); + could_stat = (QT_STAT(nativeFilePath.constData(), &st) == 0); } else { - that->could_stat = (QT_FSTAT(fd, &st) == 0); + could_stat = (QT_FSTAT(fd, &st) == 0); } - that->tried_stat = 1; } return could_stat; } @@ -543,10 +544,10 @@ bool QFSFileEnginePrivate::doStat() const bool QFSFileEnginePrivate::isSymlink() const { if (need_lstat) { - QFSFileEnginePrivate *that = const_cast(this); - that->need_lstat = false; + need_lstat = false; + QT_STATBUF st; // don't clobber our main one - that->is_link = (QT_LSTAT(nativeFilePath.constData(), &st) == 0) ? S_ISLNK(st.st_mode) : false; + is_link = (QT_LSTAT(nativeFilePath.constData(), &st) == 0) ? S_ISLNK(st.st_mode) : false; } return is_link; } -- cgit v0.12 From 7fe0dfb80efd67886a33fe8b37e9714175925688 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:25 +0200 Subject: avoid crash when testing HiddenFlag and BaseName is empty Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_unix.cpp | 3 ++- tests/auto/qfileinfo/tst_qfileinfo.cpp | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 029d422..4d451e6 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -656,7 +656,8 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const ret |= LocalDiskFlag; if (exists) ret |= ExistsFlag; - if (fileName(BaseName)[0] == QLatin1Char('.') + QString baseName = fileName(BaseName); + if ((baseName.size() > 0 && baseName.at(0) == QLatin1Char('.')) #if !defined(QWS) && defined(Q_OS_MAC) || _q_isMacHidden(d->filePath) #endif diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index a87e306..e2800e5 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -974,6 +974,9 @@ void tst_QFileInfo::isHidden_data() foreach (const QFileInfo& info, QDir::drives()) { QTest::newRow(qPrintable("drive." + info.path())) << info.path() << false; } +#if !defined(Q_OS_WIN) + QTest::newRow("/bin/") << QString::fromLatin1("/bin/") << false; +#endif #ifdef Q_OS_MAC QTest::newRow("mac_etc") << QString::fromLatin1("/etc") << true; QTest::newRow("mac_private_etc") << QString::fromLatin1("/private/etc") << false; -- cgit v0.12 From f36fb8b2b63b3734cc2bd66b329ca4fef1204845 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:27 +0200 Subject: '.' and '..' must not be hidden _unix code always sets HiddenFlag for special dirs which is wrong; also there is some inconsistence under win: * FindFirstFile sets FILE_ATTRIBUTE_HIDDEN flag for ".." of hidden dir *even* if parent dir is not hidden; * GetFileAttributes sets FILE_ATTRIBUTE_HIDDEN flag for ".." *only* if parent dir is hidden. so, _win part sets HiddenFlag wrong too; finally, we never test parent dir's flags; futhermore hidden special dirs (dotAndDotDot) makes dir iterator's filtering a bit more complex Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_unix.cpp | 18 +++++++++++------- src/corelib/io/qfsfileengine_win.cpp | 7 ++++--- tests/auto/qfileinfo/tst_qfileinfo.cpp | 13 +++++++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 4d451e6..ff10a44 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -656,15 +656,19 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const ret |= LocalDiskFlag; if (exists) ret |= ExistsFlag; - QString baseName = fileName(BaseName); - if ((baseName.size() > 0 && baseName.at(0) == QLatin1Char('.')) + if (d->filePath == QLatin1String("/")) { + ret |= RootFlag; + } else { + QString baseName = fileName(BaseName); + if ((baseName.size() > 1 + && baseName.at(0) == QLatin1Char('.') && baseName.at(1) != QLatin1Char('.')) #if !defined(QWS) && defined(Q_OS_MAC) - || _q_isMacHidden(d->filePath) + || _q_isMacHidden(d->filePath) #endif - ) - ret |= HiddenFlag; - if (d->filePath == QLatin1String("/")) - ret |= RootFlag; + ) { + ret |= HiddenFlag; + } + } } return ret; } diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 25fbae8..c2b993b 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1542,12 +1542,13 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil if (type & FlagsMask) { if(d->doStat()) { ret |= QAbstractFileEngine::FileFlags(ExistsFlag | LocalDiskFlag); - if (d->fileAttrib & FILE_ATTRIBUTE_HIDDEN) - ret |= HiddenFlag; if (d->filePath == QLatin1String("/") || (d->filePath.at(0).isLetter() && d->filePath.mid(1,d->filePath.length()) == QLatin1String(":/")) || isUncRoot(d->filePath)) { ret |= RootFlag; - ret &= ~HiddenFlag; + } else if (d->fileAttrib & FILE_ATTRIBUTE_HIDDEN) { + QString baseName = fileName(BaseName); + if (baseName != QLatin1String(".") && baseName != QLatin1String("..")) + ret |= HiddenFlag; } } } diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index e2800e5..fa2bd6e 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -974,9 +974,22 @@ void tst_QFileInfo::isHidden_data() foreach (const QFileInfo& info, QDir::drives()) { QTest::newRow(qPrintable("drive." + info.path())) << info.path() << false; } + +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + QTest::newRow("C:/RECYCLER") << QString::fromLatin1("C:/RECYCLER") << true; + QTest::newRow("C:/RECYCLER/.") << QString::fromLatin1("C:/RECYCLER/.") << false; + QTest::newRow("C:/RECYCLER/..") << QString::fromLatin1("C:/RECYCLER/..") << false; +#endif +#if defined(Q_OS_UNIX) + QTest::newRow("~/.qt") << QDir::homePath() + QString("/.qt") << true; + QTest::newRow("~/.qt/.") << QDir::homePath() + QString("/.qt/.") << false; + QTest::newRow("~/.qt/..") << QDir::homePath() + QString("/.qt/..") << false; +#endif + #if !defined(Q_OS_WIN) QTest::newRow("/bin/") << QString::fromLatin1("/bin/") << false; #endif + #ifdef Q_OS_MAC QTest::newRow("mac_etc") << QString::fromLatin1("/etc") << true; QTest::newRow("mac_private_etc") << QString::fromLatin1("/private/etc") << false; -- cgit v0.12 From 53576b4d3c3e7325d01efba6c4da80299492f2db Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:30 +0200 Subject: QFSFileEngine must set LocalDiskFlag regardless file exists or not LocalDiskFlag actually means "Local File Engine" and can be effectively used for testing file path for target storage type (local/network/virtual and so on) Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 5 +++-- tests/auto/qfileinfo/tst_qfileinfo.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index c2b993b..52fe44e 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1540,8 +1540,9 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil } } if (type & FlagsMask) { - if(d->doStat()) { - ret |= QAbstractFileEngine::FileFlags(ExistsFlag | LocalDiskFlag); + ret |= LocalDiskFlag; + if (d->doStat()) { + ret |= ExistsFlag; if (d->filePath == QLatin1String("/") || (d->filePath.at(0).isLetter() && d->filePath.mid(1,d->filePath.length()) == QLatin1String(":/")) || isUncRoot(d->filePath)) { ret |= RootFlag; diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index fa2bd6e..306ca49 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -147,6 +147,9 @@ private slots: void isBundle_data(); void isBundle(); + void isLocalFs_data(); + void isLocalFs(); + void refresh(); #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) @@ -1024,6 +1027,29 @@ void tst_QFileInfo::isBundle() QCOMPARE(fi.isBundle(), isBundle); } +void tst_QFileInfo::isLocalFs_data() +{ + QTest::addColumn("path"); + QTest::addColumn("isLocalFs"); + + QTest::newRow("local root") << QString::fromLatin1("/") << true; + QTest::newRow("local non-existent file") << QString::fromLatin1("/abrakadabra.boo") << true; + + QTest::newRow("qresource root") << QString::fromLatin1(":/") << false; +} + +void tst_QFileInfo::isLocalFs() +{ + QFETCH(QString, path); + QFETCH(bool, isLocalFs); + + QFileInfo info(path); + QFileInfoPrivate *privateInfo = getPrivate(info); + QVERIFY(privateInfo->data->fileEngine); + QCOMPARE(bool(privateInfo->data->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag) + & QAbstractFileEngine::LocalDiskFlag), isLocalFs); +} + void tst_QFileInfo::refresh() { #if defined(Q_OS_WINCE) -- cgit v0.12 From 7fe142cfcf27632a455ce193fa57c131afea61cc Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:33 +0200 Subject: move dubbed code into static funtion Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 52fe44e..2c9b977 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -337,6 +337,13 @@ static bool uncShareExists(const QString &server) return false; } +static bool isDriveRoot(const QString &path) +{ + return (path.length() == 3 + && path.at(0).isLetter() && path.at(1) == QLatin1Char(':') + && path.at(2) == QLatin1Char('/')); +} + static QString nativeAbsoluteFilePathCore(const QString &path) { QString ret; @@ -1217,8 +1224,8 @@ bool QFSFileEnginePrivate::doStat() const could_stat = fileAttrib != INVALID_FILE_ATTRIBUTES; if (!could_stat) { #if !defined(Q_OS_WINCE) - if (!fname.isEmpty() && fname.at(0).isLetter() && fname.mid(1, fname.length()) == QLatin1String(":/")) { - // an empty drive ?? + if (isDriveRoot(fname)) { + // a valid drive ?? DWORD drivesBitmask = ::GetLogicalDrives(); int drivebit = 1 << (fname.at(0).toUpper().unicode() - QLatin1Char('A').unicode()); if (drivesBitmask & drivebit) { @@ -1543,8 +1550,7 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil ret |= LocalDiskFlag; if (d->doStat()) { ret |= ExistsFlag; - if (d->filePath == QLatin1String("/") || (d->filePath.at(0).isLetter() && d->filePath.mid(1,d->filePath.length()) == QLatin1String(":/")) - || isUncRoot(d->filePath)) { + if (d->filePath == QLatin1String("/") || isDriveRoot(d->filePath) || isUncRoot(d->filePath)) { ret |= RootFlag; } else if (d->fileAttrib & FILE_ATTRIBUTE_HIDDEN) { QString baseName = fileName(BaseName); -- cgit v0.12 From 2c36b1ec645991535ca974dc9e0d5ce812f0708a Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:35 +0200 Subject: don't mix calculated and forced permission bits this commit just moves closing bracket to the function end Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 2c9b977..a512bd6 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1481,25 +1481,25 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const //### 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 defualt ... should it ? - ret |= QAbstractFileEngine::ReadOtherPerm | QAbstractFileEngine::ReadGroupPerm + ret |= QAbstractFileEngine::ReadOtherPerm | QAbstractFileEngine::ReadGroupPerm | QAbstractFileEngine::ReadOwnerPerm | QAbstractFileEngine::ReadUserPerm | QAbstractFileEngine::WriteUserPerm | QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm; - } - if (doStat()) { - if (ret & (QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm | - QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm)) { - if (fileAttrib & FILE_ATTRIBUTE_READONLY) - ret &= ~(QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm | - QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm); - } + if (doStat()) { + if (ret & (QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm | + QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm)) { + if (fileAttrib & FILE_ATTRIBUTE_READONLY) + ret &= ~(QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm | + QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm); + } - QString ext = filePath.right(4).toLower(); - if (ext == QLatin1String(".exe") || ext == QLatin1String(".com") || ext == QLatin1String(".bat") || - ext == QLatin1String(".pif") || ext == QLatin1String(".cmd") || (fileAttrib & FILE_ATTRIBUTE_DIRECTORY)) - ret |= QAbstractFileEngine::ExeOwnerPerm | QAbstractFileEngine::ExeGroupPerm | - QAbstractFileEngine::ExeOtherPerm | QAbstractFileEngine::ExeUserPerm; + QString ext = filePath.right(4).toLower(); + if (ext == QLatin1String(".exe") || ext == QLatin1String(".com") || ext == QLatin1String(".bat") || + ext == QLatin1String(".pif") || ext == QLatin1String(".cmd") || (fileAttrib & FILE_ATTRIBUTE_DIRECTORY)) + ret |= QAbstractFileEngine::ExeOwnerPerm | QAbstractFileEngine::ExeGroupPerm | + QAbstractFileEngine::ExeOtherPerm | QAbstractFileEngine::ExeUserPerm; + } } return ret; } -- cgit v0.12 From 1ff4c70e181e79456690a23a3af97cfef52c9f5e Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:37 +0200 Subject: don't mix link's target's permissions with link's Exe*Perm bits Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index a512bd6..9e341b9 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1494,7 +1494,8 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm); } - QString ext = filePath.right(4).toLower(); + QString fname = filePath.endsWith(QLatin1String(".lnk")) ? readLink(filePath) : filePath; + QString ext = fname.right(4).toLower(); if (ext == QLatin1String(".exe") || ext == QLatin1String(".com") || ext == QLatin1String(".bat") || ext == QLatin1String(".pif") || ext == QLatin1String(".cmd") || (fileAttrib & FILE_ATTRIBUTE_DIRECTORY)) ret |= QAbstractFileEngine::ExeOwnerPerm | QAbstractFileEngine::ExeGroupPerm | -- cgit v0.12 From a7e9efcb96a93f23636e8bc98bb89b705a82cbf4 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:39 +0200 Subject: optimize longFileName() a bit isUncPath() is always called with native separator-ed paths, so we can avoid needless comparisons; don't declare isUncPath() under CE since it never used Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 9e341b9..a6c2c17 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -295,13 +295,14 @@ static bool isUncRoot(const QString &server) return localPath.isEmpty(); } +#if !defined(Q_OS_WINCE) static bool isUncPath(const QString &path) { - // Starts with // or \\, but not \\. or //. - return (path.startsWith(QLatin1String("//")) - || path.startsWith(QLatin1String("\\\\"))) - && (path.size() > 2 && path.at(2) != QLatin1Char('.')); + // Starts with \\, but not \\. + return (path.startsWith(QLatin1String("\\\\")) + && path.size() > 2 && path.at(2) != QLatin1Char('.')); } +#endif static bool isRelativePath(const QString &path) { @@ -398,7 +399,7 @@ QString QFSFileEnginePrivate::longFileName(const QString &path) #if !defined(Q_OS_WINCE) QString prefix = QLatin1String("\\\\?\\"); if (isUncPath(absPath)) { - prefix = QLatin1String("\\\\?\\UNC\\"); + prefix.append(QLatin1String("UNC\\")); // "\\\\?\\UNC\\" absPath.remove(0, 2); } return prefix + absPath; -- cgit v0.12 From 085d1cb57d240e5335517ccd08da699d4faeed6a Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:42 +0200 Subject: minor optimizations -in most cases GetFullPathName returns string with at least path.size() chars; -". " isn't valid path; ". " isn't valid path too...should we to pay more? Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index a6c2c17..3a5e9f4 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -349,7 +349,7 @@ static QString nativeAbsoluteFilePathCore(const QString &path) { QString ret; #if !defined(Q_OS_WINCE) - QVarLengthArray buf(MAX_PATH); + 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()) { @@ -375,15 +375,8 @@ static QString nativeAbsoluteFilePath(const QString &path) // (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. - int i = path.size() - 1; - while (i >= 0 && path.at(i) == QLatin1Char(' ')) --i; - int extraws = path.size() - 1 - i; - if (extraws >= 0) { - while (extraws) { - absPath.append(QLatin1Char(' ')); - --extraws; - } - } + if (!path.isEmpty() && path.at(path.size() - 1) == QLatin1Char(' ')) + absPath.append(QLatin1Char(' ')); return absPath; } -- cgit v0.12 From 7c46245633a1edfbdc1ff770a28a7d5e7a5739bf Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:44 +0200 Subject: optimize inlines in QFSFileEngine un-inline isDirPath() since it too large for this (reduce size of QtCore binary in a few kilobytes) Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_unix.cpp | 6 +++--- src/corelib/io/qfsfileengine_win.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index ff10a44..50ed46d 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE Returns the stdlib open string corresponding to a QIODevice::OpenMode. */ -static QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QString &fileName = QString()) +static inline QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QString &fileName) { QByteArray mode; if ((flags & QIODevice::ReadOnly) && !(flags & QIODevice::Truncate)) { @@ -109,7 +109,7 @@ static QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QString & Returns the stdio open flags corresponding to a QIODevice::OpenMode. */ -static int openModeToOpenFlags(QIODevice::OpenMode mode) +static inline int openModeToOpenFlags(QIODevice::OpenMode mode) { int oflags = QT_OPEN_RDONLY; #ifdef QT_LARGEFILE_SUPPORT @@ -138,7 +138,7 @@ static int openModeToOpenFlags(QIODevice::OpenMode mode) Sets the file descriptor to close on exec. That is, the file descriptor is not inherited by child processes. */ -static bool setCloseOnExec(int fd) +static inline bool setCloseOnExec(int fd) { return fd != -1 && fcntl(fd, F_SETFD, FD_CLOEXEC) != -1; } diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 3a5e9f4..e669752 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -296,7 +296,7 @@ static bool isUncRoot(const QString &server) } #if !defined(Q_OS_WINCE) -static bool isUncPath(const QString &path) +static inline bool isUncPath(const QString &path) { // Starts with \\, but not \\. return (path.startsWith(QLatin1String("\\\\")) @@ -304,7 +304,7 @@ static bool isUncPath(const QString &path) } #endif -static bool isRelativePath(const QString &path) +static inline bool isRelativePath(const QString &path) { return !(path.startsWith(QLatin1Char('/')) || (path.length() >= 2 @@ -338,7 +338,7 @@ static bool uncShareExists(const QString &server) return false; } -static bool isDriveRoot(const QString &path) +static inline bool isDriveRoot(const QString &path) { return (path.length() == 3 && path.at(0).isLetter() && path.at(1) == QLatin1Char(':') @@ -894,7 +894,7 @@ static inline bool rmDir(const QString &path) return ::RemoveDirectory((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16()); } -static inline bool isDirPath(const QString &dirPath, bool *existed) +static bool isDirPath(const QString &dirPath, bool *existed) { QString path = dirPath; if (path.length() == 2 && path.at(1) == QLatin1Char(':')) -- cgit v0.12 From 96a578afeaf2ee08db3eeea0f0250e8b08bcf9b6 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:46 +0200 Subject: merge nativeAbsoluteFilePath and nativeAbsoluteFilePathCore Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_win.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index e669752..edf65d2 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -345,9 +345,9 @@ static inline bool isDriveRoot(const QString &path) && path.at(2) == QLatin1Char('/')); } -static QString nativeAbsoluteFilePathCore(const QString &path) +static QString nativeAbsoluteFilePath(const QString &path) { - QString ret; + QString absPath; #if !defined(Q_OS_WINCE) QVarLengthArray buf(qMax(MAX_PATH, path.size() + 1)); wchar_t *fileName = 0; @@ -357,19 +357,13 @@ static QString nativeAbsoluteFilePathCore(const QString &path) retLen = GetFullPathName((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName); } if (retLen != 0) - ret = QString::fromWCharArray(buf.data(), retLen); + absPath = QString::fromWCharArray(buf.data(), retLen); #else if (path.startsWith(QLatin1Char('/')) || path.startsWith(QLatin1Char('\\'))) - ret = QDir::toNativeSeparators(path); + absPath = QDir::toNativeSeparators(path); else - ret = QDir::toNativeSeparators(QDir::cleanPath(qfsPrivateCurrentDir + QLatin1Char('/') + path)); + absPath = QDir::toNativeSeparators(QDir::cleanPath(qfsPrivateCurrentDir + QLatin1Char('/') + path)); #endif - return ret; -} - -static QString nativeAbsoluteFilePath(const QString &path) -{ - QString absPath = nativeAbsoluteFilePathCore(path); // 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, -- cgit v0.12 From 1693931ac92a6a7d98eb28acda371f2d7c9c6dc2 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 11 Aug 2009 18:11:48 +0200 Subject: code clean-up and style fixes remove unused includes; tabs -> whitespaces; clean extra whitespaces Merge-request: 1176 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfsfileengine_iterator.cpp | 1 - src/corelib/io/qfsfileengine_iterator_p.h | 2 +- src/corelib/io/qfsfileengine_iterator_unix.cpp | 2 +- src/corelib/io/qfsfileengine_iterator_win.cpp | 12 +++----- src/corelib/io/qfsfileengine_unix.cpp | 4 +-- src/corelib/io/qfsfileengine_win.cpp | 41 +++++++++++--------------- 6 files changed, 25 insertions(+), 37 deletions(-) diff --git a/src/corelib/io/qfsfileengine_iterator.cpp b/src/corelib/io/qfsfileengine_iterator.cpp index 35b388f..52fc80d 100644 --- a/src/corelib/io/qfsfileengine_iterator.cpp +++ b/src/corelib/io/qfsfileengine_iterator.cpp @@ -79,4 +79,3 @@ QFileInfo QFSFileEngineIterator::currentFileInfo() const QT_END_NAMESPACE #endif // QT_NO_FSFILEENGINE - diff --git a/src/corelib/io/qfsfileengine_iterator_p.h b/src/corelib/io/qfsfileengine_iterator_p.h index 7829fff..342ef8d 100644 --- a/src/corelib/io/qfsfileengine_iterator_p.h +++ b/src/corelib/io/qfsfileengine_iterator_p.h @@ -89,4 +89,4 @@ QT_END_NAMESPACE #endif // QT_NO_FSFILEENGINE -#endif +#endif // QFSFILEENGINE_ITERATOR_P_H diff --git a/src/corelib/io/qfsfileengine_iterator_unix.cpp b/src/corelib/io/qfsfileengine_iterator_unix.cpp index a6c965c..107a500 100644 --- a/src/corelib/io/qfsfileengine_iterator_unix.cpp +++ b/src/corelib/io/qfsfileengine_iterator_unix.cpp @@ -56,7 +56,7 @@ public: #if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) , mt_file(0) #endif - { } + {} DIR *dir; dirent *dirEntry; diff --git a/src/corelib/io/qfsfileengine_iterator_win.cpp b/src/corelib/io/qfsfileengine_iterator_win.cpp index dd4ddf3..3d9c20e 100644 --- a/src/corelib/io/qfsfileengine_iterator_win.cpp +++ b/src/corelib/io/qfsfileengine_iterator_win.cpp @@ -39,14 +39,11 @@ ** ****************************************************************************/ -#include "qdebug.h" #include "qfsfileengine_iterator_p.h" #include "qfsfileengine_p.h" #include "qplatformdefs.h" #include -#include -#include QT_BEGIN_NAMESPACE @@ -56,7 +53,7 @@ public: inline QFSFileEngineIteratorPlatformSpecificData() : uncShareIndex(-1), findFileHandle(INVALID_HANDLE_VALUE), done(false), uncFallback(false) - { } + {} QFSFileEngineIterator *it; @@ -68,7 +65,6 @@ public: bool done; bool uncFallback; - void advance(); void saveCurrentFileName(); }; @@ -116,10 +112,10 @@ 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 @@ -151,7 +147,7 @@ bool QFSFileEngineIterator::hasNext() const platform->done = true; } } else { - platform->done = true; + platform->done = true; } } diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 50ed46d..7d91764 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -582,7 +582,7 @@ 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 & QAbstractFileEngine::FileFlag(QAbstractFileEngine::Refresh)) { + if (type & Refresh) { d->tried_stat = 0; d->need_lstat = 1; } @@ -777,7 +777,7 @@ QString QFSFileEngine::fileName(FileName file) const s[len] = '\0'; ret += QFile::decodeName(QByteArray(s)); #if defined(__GLIBC__) && !defined(PATH_MAX) - ::free(s); + ::free(s); #endif if (!ret.startsWith(QLatin1Char('/'))) { diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index edf65d2..0cddee3 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -47,10 +47,6 @@ #include "qfile.h" #include "qdir.h" -#include "qtemporaryfile.h" -#ifndef QT_NO_REGEXP -# include "qregexp.h" -#endif #include "private/qmutexpool_p.h" #include "qvarlengtharray.h" #include "qdatetime.h" @@ -125,7 +121,7 @@ static TRUSTEE_W currentUserTrusteeW; typedef BOOL (WINAPI *PtrOpenProcessToken)(HANDLE, DWORD, PHANDLE ); static PtrOpenProcessToken ptrOpenProcessToken = 0; -typedef BOOL (WINAPI *PtrGetUserProfileDirectoryW)( HANDLE, LPWSTR, LPDWORD); +typedef BOOL (WINAPI *PtrGetUserProfileDirectoryW)(HANDLE, LPWSTR, LPDWORD); static PtrGetUserProfileDirectoryW ptrGetUserProfileDirectoryW = 0; typedef BOOL (WINAPI *PtrSetFilePointerEx)(HANDLE, LARGE_INTEGER, PLARGE_INTEGER, DWORD); static PtrSetFilePointerEx ptrSetFilePointerEx = 0; @@ -266,7 +262,7 @@ bool QFSFileEnginePrivate::uncListSharesOnServer(const QString &server, QStringL 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; + p = BufPtr; for (i = 1; i <= er; ++i) { if (list && p->shi1_type == 0) list->append(QString::fromWCharArray(p->shi1_netname)); @@ -276,7 +272,6 @@ bool QFSFileEnginePrivate::uncListSharesOnServer(const QString &server, QStringL ptrNetApiBufferFree(BufPtr); } while (res==ERROR_MORE_DATA); return res == ERROR_SUCCESS; - } return false; } @@ -306,10 +301,11 @@ static inline bool isUncPath(const QString &path) 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('/'))))); // drive, e.g. a: + || (path.at(0) == QLatin1Char('/') && path.at(1) == QLatin1Char('/'))))); } static QString fixIfRelativeUncPath(const QString &path) @@ -328,12 +324,8 @@ 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)) { - if (parts.count() >= 2) - return shares.contains(parts.at(1), Qt::CaseInsensitive); - else - return true; - } + if (QFSFileEnginePrivate::uncListSharesOnServer(QLatin1String("\\\\") + parts.at(0), &shares)) + return parts.count() >= 2 ? shares.contains(parts.at(1), Qt::CaseInsensitive) : true; } return false; } @@ -400,8 +392,8 @@ QString QFSFileEnginePrivate::longFileName(const QString &path) */ void QFSFileEnginePrivate::nativeInitFileName() { - QString path = longFileName(QDir::toNativeSeparators(fixIfRelativeUncPath(filePath))); - nativeFilePath = QByteArray((const char *)path.utf16(), path.size() * 2 + 1); + QString path = longFileName(QDir::toNativeSeparators(fixIfRelativeUncPath(filePath))); + nativeFilePath = QByteArray((const char *)path.utf16(), path.size() * 2 + 1); } /* @@ -423,8 +415,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE }; // WriteOnly can create files, ReadOnly cannot. - DWORD creationDisp = (openMode & QIODevice::WriteOnly) - ? OPEN_ALWAYS : OPEN_EXISTING; + DWORD creationDisp = (openMode & QIODevice::WriteOnly) ? OPEN_ALWAYS : OPEN_EXISTING; // Create the file handle. fileHandle = CreateFile((const wchar_t*)nativeFilePath.constData(), @@ -1145,10 +1136,10 @@ QFileInfoList QFSFileEngine::drives() char driveName[] = "A:/"; while(driveBits) { - if(driveBits & 1) - ret.append(QString::fromLatin1(driveName)); - driveName[0]++; - driveBits = driveBits >> 1; + if(driveBits & 1) + ret.append(QString::fromLatin1(driveName)); + driveName[0]++; + driveBits = driveBits >> 1; } return ret; #else @@ -1501,7 +1492,7 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil Q_D(const QFSFileEngine); QAbstractFileEngine::FileFlags ret = 0; // Force a stat, so that we're guaranteed to get up-to-date results - if (type & QAbstractFileEngine::FileFlag(QAbstractFileEngine::Refresh)) { + if (type & Refresh) { d->tried_stat = 0; } @@ -1647,10 +1638,11 @@ QString QFSFileEngine::fileName(FileName file) const 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('/'))))); // drive, e.g. a: + || (d->filePath.at(0) == QLatin1Char('/') && d->filePath.at(1) == QLatin1Char('/'))))); } uint QFSFileEngine::ownerId(FileOwner /*own*/) const @@ -1966,4 +1958,5 @@ void QFSFileEnginePrivate::mapHandleClose() } } #endif + QT_END_NAMESPACE -- cgit v0.12 From e0059d1d01a7c1d76ed86cccf8253d0ebd18f575 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 6 Apr 2009 18:28:13 +0200 Subject: Handle multi-length strings in the low-level formatting code Patch originally from Oswald on Jira QT-10, with few a modifications. If a string contains multiple variants sorted by decreasing length, separated by \x9c, it will try to paint the longest variant which fits into the bounding box. Reviewed-by: Oswald Buddenhagen Task-Number: QT-10 --- src/gui/painting/qpainter.cpp | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 8192fb7..c3fc14b 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -7486,12 +7486,14 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, int *underlinePositions = underlinePositionStack; QFontMetricsF fm(fnt); - QString text = str; + int offset = 0; +start_lenghtVariant: + bool hasMoreLenghtVariants = false; // compatible behaviour to the old implementation. Replace // tabs by spaces - QChar *chr = text.data(); - const QChar *end = chr + str.length(); + QChar *chr = text.data() + offset; + QChar *end = text.data() + text.length(); bool has_tab = false; while (chr != end) { if (*chr == QLatin1Char('\r') || (singleline && *chr == QLatin1Char('\n'))) { @@ -7502,12 +7504,17 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, ++maxUnderlines; } else if (*chr == QLatin1Char('\t')) { has_tab = true; + } else if (*chr == QChar(ushort(0x9c))) { + // string with multiple length variants + end = chr; + hasMoreLenghtVariants = true; + break; } ++chr; } if (has_tab) { if (!expandtabs) { - chr = text.data(); + chr = text.data() + offset; while (chr != end) { if (*chr == QLatin1Char('\t')) *chr = QLatin1Char(' '); @@ -7518,12 +7525,13 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, } } + QChar *cout = end; if (hidemnmemonic || showmnemonic) { if (maxUnderlines > 32) underlinePositions = new int[maxUnderlines]; - QChar *cout = text.data(); + cout = text.data() + offset; QChar *cin = cout; - int l = str.length(); + int l = end - cout; while (l) { if (*cin == QLatin1Char('&')) { ++cin; @@ -7538,9 +7546,6 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, ++cin; --l; } - int newlen = cout - text.unicode(); - if (newlen != text.length()) - text.resize(newlen); } // no need to do extra work for underlines if we don't paint @@ -7551,13 +7556,12 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, qreal height = 0; qreal width = 0; - QStackTextEngine engine(text, fnt); + QString finalText = text.mid(offset, cout - (text.data() + offset)); + QStackTextEngine engine(finalText, fnt); if (option) { engine.option = *option; } - - engine.option.setTextDirection(layout_direction); if (tf & Qt::AlignJustify) engine.option.setAlignment(Qt::AlignJustify); @@ -7573,7 +7577,7 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, textLayout.setCacheEnabled(true); textLayout.engine()->underlinePositions = underlinePositions; - if (text.isEmpty()) { + if (finalText.isEmpty()) { height = fm.height(); width = 0; tf |= Qt::TextDontPrint; @@ -7638,6 +7642,10 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, } } QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height); + if (hasMoreLenghtVariants && !r.contains(bounds)) { + offset = end - text.data() + 1; + goto start_lenghtVariant; + } if (brect) *brect = bounds; -- cgit v0.12 From c225767b9b50336432e39cd589637df4fe721d62 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 11 May 2009 12:45:51 +0200 Subject: Add the Qt::TextLongestVariant flag so QFontMetrics::size returns the size of the biggest string In case the strings contains multiple strings separated by \x9c Reviewed-by: Oswald Buddenhagen Task-number: QT-10 --- doc/src/classes/qnamespace.qdoc | 1 + src/corelib/global/qnamespace.h | 3 ++- src/gui/painting/qpainter.cpp | 3 ++- src/gui/text/qfontmetrics.cpp | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/src/classes/qnamespace.qdoc b/doc/src/classes/qnamespace.qdoc index 18ecd7b..5872d04 100644 --- a/doc/src/classes/qnamespace.qdoc +++ b/doc/src/classes/qnamespace.qdoc @@ -490,6 +490,7 @@ \omitvalue WordBreak \omitvalue TextForceLeftToRight \omitvalue TextForceRightToLeft + \omitvalue TextLongestVariant Always use the longest variant when computing the size of a multi-variant string You can use as many modifier flags as you want, except that Qt::TextSingleLine and Qt::TextWordWrap cannot be combined. diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index f172d77..4024fce 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -233,7 +233,8 @@ public: TextHideMnemonic = 0x8000, TextJustificationForced = 0x10000, TextForceLeftToRight = 0x20000, - TextForceRightToLeft = 0x40000 + TextForceRightToLeft = 0x40000, + TextLongestVariant = 0x80000 #if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN) ,SingleLine = TextSingleLine, diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index c3fc14b..4d9b43a 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -7642,7 +7642,8 @@ start_lenghtVariant: } } QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height); - if (hasMoreLenghtVariants && !r.contains(bounds)) { + + if (hasMoreLenghtVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) { offset = end - text.data() + 1; goto start_lenghtVariant; } diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 012c0f6..47d3864 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -798,7 +798,7 @@ QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &te */ QSize QFontMetrics::size(int flags, const QString &text, int tabStops, int *tabArray) const { - return boundingRect(QRect(0,0,0,0), flags, text, tabStops, tabArray).size(); + return boundingRect(QRect(0,0,0,0), flags | Qt::TextLongestVariant, text, tabStops, tabArray).size(); } /*! -- cgit v0.12 From caebd2676dda37fb7ab11c3b994fd341f88b0de0 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 11 May 2009 12:46:58 +0200 Subject: Make QFontMetrics::elidedText aware of multi-length strings Reviewed-by: Oswald Buddenhagen Task-number: QT-10 --- src/gui/text/qfontmetrics.cpp | 17 ++++++++++++++-- tests/auto/qfontmetrics/tst_qfontmetrics.cpp | 30 +++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 47d3864..5c5320f 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -859,8 +859,21 @@ QRect QFontMetrics::tightBoundingRect(const QString &text) const language. */ -QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags) const -{ +QString QFontMetrics::elidedText(const QString &_text, Qt::TextElideMode mode, int width, int flags) const +{ + QString text = _text; + if (!(flags & Qt::TextLongestVariant)) { + int posA = 0; + int posB = text.indexOf(QLatin1Char('\x9c')); + while (posB >= 0) { + QString portion = text.mid(posA, posB - posA); + if (size(flags, portion).width() <= width) + return portion; + posA = posB + 1; + posB = text.indexOf(QLatin1Char('\x9c'), posA); + } + text = text.mid(posA); + } QStackTextEngine engine(text, QFont(d)); return engine.elidedText(mode, width, flags); } diff --git a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp index 5658055..cae1126 100644 --- a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp @@ -71,6 +71,7 @@ private slots: void elidedText(); void veryNarrowElidedText(); void averageCharWidth(); + void elidedMultiLenght(); }; tst_QFontMetrics::tst_QFontMetrics() @@ -168,7 +169,8 @@ void tst_QFontMetrics::elidedText_data() QTest::addColumn("font"); QTest::addColumn("text"); - QTest::newRow("helvetica hello") << QFont("helvetica",10) << QString("hello"); + QTest::newRow("helvetica hello") << QFont("helvetica",10) << QString("hello") ; + QTest::newRow("helvetica hello &Bye") << QFont("helvetica",10) << QString("hello&Bye") ; } @@ -178,9 +180,9 @@ void tst_QFontMetrics::elidedText() QFETCH(QString, text); QFontMetrics fm(font); int w = fm.width(text); - QString newtext = fm.elidedText(text,Qt::ElideRight,w); + QString newtext = fm.elidedText(text,Qt::ElideRight,w, 0); QCOMPARE(text,newtext); // should not elide - newtext = fm.elidedText(text,Qt::ElideRight,w-1); + newtext = fm.elidedText(text,Qt::ElideRight,w-1, 0); QVERIFY(text != newtext); // should elide } @@ -201,5 +203,27 @@ void tst_QFontMetrics::averageCharWidth() QVERIFY(fmf.averageCharWidth() != 0); } +void tst_QFontMetrics::elidedMultiLenght() +{ + QString text1 = "Long Text 1\x9cShorter\x9csmall"; + QString text1_long = "Long Text 1"; + QString text1_short = "Shorter"; + QString text1_small = "small"; + QFontMetrics fm = QFontMetrics(QFont()); + int width_long = fm.width(text1_long); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, 8000), text1_long); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_long), text1_long); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_long - 1), text1_short); + int width_short = fm.width(text1_short); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_short), text1_short); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_short - 1), text1_small); + + QChar ellipsisChar(0x2026); + QString text1_el = QString::fromLatin1("sm") + ellipsisChar; + int width_small = fm.width(text1_el); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_small + 1), text1_el); + +} + QTEST_MAIN(tst_QFontMetrics) #include "tst_qfontmetrics.moc" -- cgit v0.12 From 60ca03709c7e9845b997520dab70ac1ac76787dd Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 20 Apr 2009 12:51:57 +0200 Subject: Change QFontMetrics::width to return the width of the longest variant if the string is a multi-length one Task-number: QT-10 Reviewed-by: Oswald Buddenhagen --- src/gui/text/qfontmetrics.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 5c5320f..4229d5b 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -528,12 +528,14 @@ int QFontMetrics::rightBearing(QChar ch) const */ int QFontMetrics::width(const QString &text, int len) const { + int pos = text.indexOf(QLatin1Char('\x9c')); + QString txt = (pos == -1) ? text : text.left(pos); if (len < 0) - len = text.length(); + len = txt.length(); if (len == 0) return 0; - QTextEngine layout(text, d); + QTextEngine layout(txt, d); layout.ignoreBidi = true; return qRound(layout.width(0, len)); } -- cgit v0.12 From 5c4c47facfcb75b0277872a0fac813ab41700e5e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 11 Aug 2009 19:12:07 +0200 Subject: Optimize qt_format_text test operations: try not to detach Reviewed-by: Oswald Buddenhagen --- src/gui/painting/qpainter.cpp | 68 ++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 4d9b43a..cd4ea86 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -7480,10 +7480,9 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, if (!painter) tf |= Qt::TextDontPrint; - int maxUnderlines = 0; + uint maxUnderlines = 0; int numUnderlines = 0; - int underlinePositionStack[32]; - int *underlinePositions = underlinePositionStack; + QVarLengthArray underlinePositions(1); QFontMetricsF fm(fnt); QString text = str; @@ -7492,54 +7491,46 @@ start_lenghtVariant: bool hasMoreLenghtVariants = false; // compatible behaviour to the old implementation. Replace // tabs by spaces - QChar *chr = text.data() + offset; - QChar *end = text.data() + text.length(); bool has_tab = false; - while (chr != end) { - if (*chr == QLatin1Char('\r') || (singleline && *chr == QLatin1Char('\n'))) { - *chr = QLatin1Char(' '); - } else if (*chr == QLatin1Char('\n')) { - *chr = QChar::LineSeparator; - } else if (*chr == QLatin1Char('&')) { + int old_offset = offset; + for (; offset < text.length(); offset++) { + QChar chr = text.at(offset); + if (chr == QLatin1Char('\r') || (singleline && chr == QLatin1Char('\n'))) { + text[offset] = QLatin1Char(' '); + } else if (chr == QLatin1Char('\n')) { + chr = QChar::LineSeparator; + } else if (chr == QLatin1Char('&')) { ++maxUnderlines; - } else if (*chr == QLatin1Char('\t')) { + } else if (chr == QLatin1Char('\t')) { + if (!expandtabs) { + text[offset] = QLatin1Char(' '); + } else if (!tabarraylen && !tabstops) { + tabstops = qRound(fm.width(QLatin1Char('x'))*8); + } has_tab = true; - } else if (*chr == QChar(ushort(0x9c))) { + } else if (chr == QChar(ushort(0x9c))) { // string with multiple length variants - end = chr; hasMoreLenghtVariants = true; break; } - ++chr; - } - if (has_tab) { - if (!expandtabs) { - chr = text.data() + offset; - while (chr != end) { - if (*chr == QLatin1Char('\t')) - *chr = QLatin1Char(' '); - ++chr; - } - } else if (!tabarraylen && !tabstops) { - tabstops = qRound(fm.width(QLatin1Char('x'))*8); - } } - QChar *cout = end; - if (hidemnmemonic || showmnemonic) { - if (maxUnderlines > 32) - underlinePositions = new int[maxUnderlines]; - cout = text.data() + offset; + int length = offset - old_offset; + if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) { + underlinePositions.resize(maxUnderlines + 1); + + QChar *cout = text.data() + old_offset; QChar *cin = cout; - int l = end - cout; + int l = length; while (l) { if (*cin == QLatin1Char('&')) { ++cin; + --length; --l; if (!l) break; if (*cin != QLatin1Char('&') && !hidemnmemonic) - underlinePositions[numUnderlines++] = cout - text.unicode(); + underlinePositions[numUnderlines++] = cout - text.data() - old_offset; } *cout = *cin; ++cout; @@ -7556,7 +7547,7 @@ start_lenghtVariant: qreal height = 0; qreal width = 0; - QString finalText = text.mid(offset, cout - (text.data() + offset)); + QString finalText = text.mid(old_offset, length); QStackTextEngine engine(finalText, fnt); if (option) { engine.option = *option; @@ -7575,7 +7566,7 @@ start_lenghtVariant: engine.forceJustification = true; QTextLayout textLayout(&engine); textLayout.setCacheEnabled(true); - textLayout.engine()->underlinePositions = underlinePositions; + textLayout.engine()->underlinePositions = underlinePositions.data(); if (finalText.isEmpty()) { height = fm.height(); @@ -7644,7 +7635,7 @@ start_lenghtVariant: QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height); if (hasMoreLenghtVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) { - offset = end - text.data() + 1; + offset++; goto start_lenghtVariant; } if (brect) @@ -7673,9 +7664,6 @@ start_lenghtVariant: painter->restore(); } } - - if (underlinePositions != underlinePositionStack) - delete [] underlinePositions; } /*! -- cgit v0.12