Add QLocale::toUpper/Lower
authorLars Knoll <lars.knoll@nokia.com>
Fri, 19 Aug 2011 10:17:06 +0000 (12:17 +0200)
committerQt by Nokia <qt-info@nokia.com>
Wed, 31 Aug 2011 11:12:43 +0000 (13:12 +0200)
The toUpper/Lower() methods in QString should not
be locale dependent, as this can lead to rather
hard to find bugs in at least a turkish locale.

Rather have explicit, locale dependend case conversions
available in QLocale.

Reviewed-by: Denis Dzyubenko
(cherry picked from commit da0e1e101bb4c44c25b6523357fa81ad1b2d6539)

Change-Id: I1cc3f341bef17ad573a736dc94c9c5d514ace54e
Reviewed-on: http://codereview.qt.nokia.com/3259
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
src/corelib/tools/qlocale.cpp
src/corelib/tools/qlocale.h
src/corelib/tools/qstring.cpp
tests/auto/qstring/tst_qstring.cpp

index 4648ca1..36c4ae7 100644 (file)
@@ -88,6 +88,8 @@ Q_GLOBAL_STATIC(QLocalePrivate, globalLocalePrivate)
 
 #ifdef QT_USE_ICU
 extern bool qt_initIcu(const QString &localeName);
+extern bool qt_u_strToUpper(const QString &str, QString *out, const QLocale &locale);
+extern bool qt_u_strToLower(const QString &str, QString *out, const QLocale &locale);
 #endif
 
 /******************************************************************************
@@ -2170,6 +2172,42 @@ Qt::LayoutDirection QLocale::textDirection() const
     return Qt::LeftToRight;
 }
 
+/*!
+  \since 4.8
+
+  Returns an uppercase copy of \a str.
+*/
+QString QLocale::toUpper(const QString &str) const
+{
+#ifdef QT_USE_ICU
+    {
+        QString result;
+        if (qt_u_strToUpper(str, &result, *this))
+            return result;
+        // else fall through and use Qt's toUpper
+    }
+#endif
+    return str.toUpper();
+}
+
+/*!
+  \since 4.8
+
+  Returns a lowercase copy of \a str.
+*/
+QString QLocale::toLower(const QString &str) const
+{
+#ifdef QT_USE_ICU
+    {
+        QString result;
+        if (qt_u_strToLower(str, &result, *this))
+            return result;
+        // else fall through and use Qt's toUpper
+    }
+#endif
+    return str.toLower();
+}
+
 
 /*!
     \since 4.5
index 8a5d526..55dd55b 100644 (file)
@@ -724,6 +724,9 @@ public:
 
     Qt::LayoutDirection textDirection() const;
 
+    QString toUpper(const QString &str) const;
+    QString toLower(const QString &str) const;
+
     QString currencySymbol(CurrencySymbolFormat = CurrencySymbol) const;
     QString toCurrencyString(qlonglong, const QString &symbol = QString()) const;
     QString toCurrencyString(qulonglong, const QString &symbol = QString()) const;
index 9ce5eea..78b1b59 100644 (file)
@@ -105,8 +105,6 @@ QTextCodec *QString::codecForCStrings;
 #ifdef QT_USE_ICU
 // qlocale_icu.cpp
 extern bool qt_ucol_strcoll(const QChar *source, int sourceLength, const QChar *target, int targetLength, int *result);
-extern bool qt_u_strToUpper(const QString &str, QString *out, const QLocale &locale);
-extern bool qt_u_strToLower(const QString &str, QString *out, const QLocale &locale);
 #endif
 
 
@@ -4878,7 +4876,10 @@ QString QString::rightJustified(int width, QChar fill, bool truncate) const
 
     \snippet doc/src/snippets/qstring/main.cpp 75
 
-    \sa toUpper()
+    The case conversion will always happen in the 'C' locale. For locale dependent
+    case folding use QLocale::toLower()
+
+    \sa toUpper(), QLocale::toLower()
 */
 
 QString QString::toLower() const
@@ -4889,15 +4890,6 @@ QString QString::toLower() const
     if (!d->size)
         return *this;
 
-#ifdef QT_USE_ICU
-    {
-        QString result;
-        if (qt_u_strToLower(*this, &result, QLocale()))
-            return result;
-        // else fall through and use Qt's toUpper
-    }
-#endif
-
     const ushort *e = d->data() + d->size;
 
     // this avoids one out of bounds check in the loop
@@ -4978,7 +4970,10 @@ QString QString::toCaseFolded() const
 
     \snippet doc/src/snippets/qstring/main.cpp 81
 
-    \sa toLower()
+    The case conversion will always happen in the 'C' locale. For locale dependent
+    case folding use QLocale::toUpper()
+
+    \sa toLower(), QLocale::toLower()
 */
 
 QString QString::toUpper() const
@@ -4989,15 +4984,6 @@ QString QString::toUpper() const
     if (!d->size)
         return *this;
 
-#ifdef QT_USE_ICU
-    {
-        QString result;
-        if (qt_u_strToUpper(*this, &result, QLocale()))
-            return result;
-        // else fall through and use Qt's toUpper
-    }
-#endif
-
     const ushort *e = d->data() + d->size;
 
     // this avoids one out of bounds check in the loop
index f7a725c..cf68bda 100644 (file)
@@ -5086,24 +5086,28 @@ void tst_QString::toUpperLower_icu()
 
     QLocale::setDefault(QLocale(QLocale::Turkish, QLocale::Turkey));
 
+    QCOMPARE(s.toUpper(), QString::fromLatin1("I"));
+    QCOMPARE(s.toLower(), QString::fromLatin1("i"));
+
     // turkish locale has a capital I with a dot (U+0130, utf8 c4b0)
+    QLocale l;
 
-    QCOMPARE(s.toUpper(), QString::fromUtf8("\xc4\xb0"));
-    QCOMPARE(QString::fromUtf8("\xc4\xb0").toLower(), s);
+    QCOMPARE(l.toUpper(s), QString::fromUtf8("\xc4\xb0"));
+    QCOMPARE(l.toLower(QString::fromUtf8("\xc4\xb0")), s);
 
     // nothing should happen here
-    QCOMPARE(s.toLower(), s);
-    QCOMPARE(QString::fromLatin1("I").toUpper(), QString::fromLatin1("I"));
+    QCOMPARE(l.toLower(s), s);
+    QCOMPARE(l.toUpper(QString::fromLatin1("I")), QString::fromLatin1("I"));
 
     // U+0131, utf8 c4b1 is the lower-case i without a dot
     QString sup = QString::fromUtf8("\xc4\xb1");
 
-    QCOMPARE(sup.toUpper(), QString::fromLatin1("I"));
-    QCOMPARE(QString::fromLatin1("I").toLower(), sup);
+    QCOMPARE(l.toUpper(sup), QString::fromLatin1("I"));
+    QCOMPARE(l.toLower(QString::fromLatin1("I")), sup);
 
     // nothing should happen here
-    QCOMPARE(sup.toLower(), sup);
-    QCOMPARE(QString::fromLatin1("i").toLower(), QString::fromLatin1("i"));
+    QCOMPARE(l.toLower(sup), sup);
+    QCOMPARE(l.toLower(QString::fromLatin1("i")), QString::fromLatin1("i"));
 
     // the cleanup function will restore the default locale
 }