diff options
author | Lars Knoll <lars.knoll@digia.com> | 2014-08-27 12:57:14 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@digia.com> | 2014-09-10 21:11:11 +0200 |
commit | c17563eca879845deef542173f5fb479c9aa2d0e (patch) | |
tree | b967050c3502458043998288292d6da952252649 /src/corelib/tools/qcollator_macx.cpp | |
parent | 6316a681f3f3dde46d5ab5c915f31a2098b463bb (diff) |
Fix several issues in QCollator
Refactor the code and move more things into the cross platform
code path.
Make sure the flags survive changing the locale of QCollator.
Use the correct locale on Windows, WinRT and OS X. We now
pass all QCollator autotests on these platforms.
Task-number: QTBUG-40778
Change-Id: Ic2d3334b5018c323a35a3ea8fc1d7ab5f99b4e62
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/tools/qcollator_macx.cpp')
-rw-r--r-- | src/corelib/tools/qcollator_macx.cpp | 92 |
1 files changed, 30 insertions, 62 deletions
diff --git a/src/corelib/tools/qcollator_macx.cpp b/src/corelib/tools/qcollator_macx.cpp index 877510489a..52fb059a9e 100644 --- a/src/corelib/tools/qcollator_macx.cpp +++ b/src/corelib/tools/qcollator_macx.cpp @@ -55,85 +55,50 @@ void QCollatorPrivate::init() { cleanup(); LocaleRef localeRef; - int rc = LocaleRefFromLocaleString(locale.name().toLocal8Bit(), &localeRef); + int rc = LocaleRefFromLocaleString(locale.bcp47Name().toLocal8Bit(), &localeRef); if (rc != 0) qWarning() << "couldn't initialize the locale"; + UInt32 options = 0; + + if (caseSensitivity == Qt::CaseInsensitive) + options |= kUCCollateCaseInsensitiveMask; + if (numericMode) + options |= kUCCollateDigitsAsNumberMask; + if (ignorePunctuation) + options |= kUCCollatePunctuationSignificantMask; + OSStatus status = UCCreateCollator( localeRef, 0, - collator.options, - &collator.collator + options, + &collator ); if (status != 0) qWarning() << "Couldn't initialize the collator"; -} - -void QCollatorPrivate::cleanup() -{ - UCDisposeCollator(&collator.collator); - collator.collator = 0; -} - -void QCollator::setCaseSensitivity(Qt::CaseSensitivity cs) -{ - detach(); - - if (cs == Qt::CaseSensitive) - d->collator.options &= ~kUCCollateCaseInsensitiveMask; - else - d->collator.options |= kUCCollateCaseInsensitiveMask; - d->init(); -} - -Qt::CaseSensitivity QCollator::caseSensitivity() const -{ - return !(d->collator.options & kUCCollateCaseInsensitiveMask) ? Qt::CaseInsensitive : Qt::CaseSensitive; -} -void QCollator::setNumericMode(bool on) -{ - detach(); - - if (on) - d->collator.options |= kUCCollateDigitsAsNumberMask; - else - d->collator.options &= ~kUCCollateDigitsAsNumberMask; - - d->init(); -} - -bool QCollator::numericMode() const -{ - return bool(d->collator.options & kUCCollateDigitsAsNumberMask); -} - -void QCollator::setIgnorePunctuation(bool on) -{ - detach(); - - if (on) - d->collator.options |= kUCCollatePunctuationSignificantMask; - else - d->collator.options &= ~kUCCollatePunctuationSignificantMask; - - d->init(); + dirty = false; } -bool QCollator::ignorePunctuation() const +void QCollatorPrivate::cleanup() { - return bool(d->collator.options & kUCCollatePunctuationSignificantMask); + if (collator) + UCDisposeCollator(&collator); + collator = 0; } int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const { + if (d->dirty) + d->init(); + SInt32 result; Boolean equivalent; - UCCompareText(d->collator.collator, - reinterpret_cast<const UniChar *>(s1), len1, - reinterpret_cast<const UniChar *>(s2), len2, - &equivalent, - &result); + UCCompareText(d->collator, + reinterpret_cast<const UniChar *>(s1), len1, + reinterpret_cast<const UniChar *>(s2), len2, + &equivalent, + &result); if (equivalent) return 0; return result < 0 ? -1 : 1; @@ -150,15 +115,18 @@ int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const QCollatorSortKey QCollator::sortKey(const QString &string) const { + if (d->dirty) + d->init(); + //Documentation recommends having it 5 times as big as the input QVector<UCCollationValue> ret(string.size() * 5); ItemCount actualSize; - int status = UCGetCollationKey(d->collator.collator, reinterpret_cast<const UniChar *>(string.constData()), string.count(), + int status = UCGetCollationKey(d->collator, reinterpret_cast<const UniChar *>(string.constData()), string.count(), ret.size(), &actualSize, ret.data()); ret.resize(actualSize+1); if (status == kUCOutputBufferTooSmall) { - UCGetCollationKey(d->collator.collator, reinterpret_cast<const UniChar *>(string.constData()), string.count(), + UCGetCollationKey(d->collator, reinterpret_cast<const UniChar *>(string.constData()), string.count(), ret.size(), &actualSize, ret.data()); } ret[actualSize] = 0; |