summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qlocale.cpp86
-rw-r--r--src/corelib/tools/qlocale.h8
-rw-r--r--src/corelib/tools/qlocale_p.h2
-rw-r--r--tests/auto/qlocale/tst_qlocale.cpp16
-rwxr-xr-xutil/local_database/cldr2qlocalexml.py12
-rwxr-xr-xutil/local_database/qlocalexml2cpp.py18
6 files changed, 138 insertions, 4 deletions
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 985889c401..10ad0cc54d 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -59,6 +59,7 @@ QT_END_NAMESPACE
#include "qdatetime.h"
#include "qstringlist.h"
#include "qvariant.h"
+#include "qstringbuilder.h"
#if defined(Q_WS_WIN)
# include "qt_windows.h"
# include <time.h>
@@ -1313,6 +1314,33 @@ static QString macFormatCurrency(const QVariant &in)
return QCFString::toQString(result);
}
+static QVariant macQuotationSymbol(QSystemLocale::QueryType type, const QVariant &in)
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+ if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_6)
+ return QVariant();
+
+ QCFType<CFLocaleRef> locale = CFLocaleCopyCurrent();
+ switch (type) {
+ case QSystemLocale::QuotationBegin:
+ if (in.toInt() == QLocale::StandardQuotation)
+ return QCFString::toQString(static_cast<CFStringRef>(CFLocaleGetValue(locale, kCFLocaleQuotationBeginDelimiterKey)));
+ else
+ return QCFString::toQString(static_cast<CFStringRef>(CFLocaleGetValue(locale, kCFLocaleAlternateQuotationBeginDelimiterKey)));
+ break;
+ case QSystemLocale::QuotationEnd:
+ if (in.toInt() == QLocale::StandardQuotation)
+ return QCFString::toQString(static_cast<CFStringRef>(CFLocaleGetValue(locale, kCFLocaleQuotationEndDelimiterKey)));
+ else
+ return QCFString::toQString(static_cast<CFStringRef>(CFLocaleGetValue(locale, kCFLocaleAlternateQuotationEndDelimiterKey)));
+ break;
+ default:
+ break;
+ }
+#endif
+ return QVariant();
+}
+
static void getMacPreferredLanguageAndCountry(QString *language, QString *country)
{
QCFType<CFArrayRef> languages = (CFArrayRef)CFPreferencesCopyValue(
@@ -1400,6 +1428,10 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
return QVariant(macCurrencySymbol(QLocale::CurrencySymbolFormat(in.toUInt())));
case FormatCurrency:
return macFormatCurrency(in);
+ case QuotationBegin:
+ case QuotationEnd: {
+ return macQuotationSymbol(type,in);
+ }
default:
break;
}
@@ -1541,6 +1573,8 @@ Q_GLOBAL_STATIC(QLocalePrivate, globalLocalePrivate)
\value PMText a string that represents the system PM designator associated with a 12-hour clock.
\value CurrencySymbol a string that represents a currency in a format QLocale::CurrencyFormat.
\value FormatCurrency a localized string representation of a number with a currency symbol.
+ \value QuotationBegin a QString specifying the start of a quotation. the in variant contains a QLocale::QuotationStyle
+ \value QuotationEnd a QString specifying the end of a quotation. the in variant contains a QLocale::QuotationStyle
*/
/*!
@@ -2328,6 +2362,21 @@ QDataStream &operator>>(QDataStream &ds, QLocale &l)
locale specified; otherwise returns false.
*/
+/*!
+ \enum QLocale::QuotationStyle
+
+ This enum defines a set of possible styles for locale specific quotation.
+
+ \value StandardQuotation If this option is set, the standard quotation marks
+ will be used to quote strings.
+ \value AlternateQuotation If this option is set, the alternate quotation marks
+ will be used to quote strings.
+
+ \since 4.8
+
+ \sa quoteString()
+*/
+
static const int locale_data_size = sizeof(locale_data)/sizeof(QLocalePrivate) - 1;
static const QLocalePrivate *dataPointerHelper(quint16 index)
@@ -2491,6 +2540,43 @@ QLocale::NumberOptions QLocale::numberOptions() const
}
/*!
+ \since 4.8
+
+ Returns \a str quoted according to the current locale.
+
+ If \a AlternateQuotation is used for \a QuoatationStyle
+ but the locale does not provide an alternate quotation,
+ we will fallback to the parent locale.
+*/
+QString QLocale::quoteString(const QString &str, QuotationStyle qs) const
+{
+
+ return quoteString(&str, qs);
+}
+
+/*!
+ \since 4.8
+
+ \overload
+*/
+QString QLocale::quoteString(const QStringRef &str, QuotationStyle qs) const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d() == systemPrivate()) {
+ QVariant quotationBegin = systemLocale()->query(QSystemLocale::QuotationBegin, QVariant(qs));
+ QVariant quotationEnd = systemLocale()->query(QSystemLocale::QuotationEnd, QVariant(qs));
+ if (!quotationBegin.isNull() && !quotationEnd.isNull())
+ return quotationBegin.toString() % str % quotationEnd.toString();
+ }
+#endif
+
+ if (qs == StandardQuotation)
+ return QChar(d()->m_quotation_start) % str % QChar(d()->m_quotation_end);
+ else
+ return QChar(d()->m_alternate_quotation_start) % str % QChar(d()->m_alternate_quotation_end);
+}
+
+/*!
\nonreentrant
Sets the global default locale to \a locale. These
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index 225ae9cd53..924cb7bc64 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -97,7 +97,9 @@ public:
PMText, // QString
FirstDayOfWeek, // Qt::DayOfWeek
CurrencySymbol, // QString in: format
- FormatCurrency // QString in: qlonglong, qulonglong or double
+ FormatCurrency, // QString in: qlonglong, qulonglong or double
+ QuotationBegin, // QString in: StandardQuotation or AlternateQuotation
+ QuotationEnd // QString in: StandardQuotation or AlternateQuotation
};
virtual QVariant query(QueryType type, QVariant in) const;
virtual QLocale fallbackLocale() const;
@@ -707,6 +709,10 @@ public:
void setNumberOptions(NumberOptions options);
NumberOptions numberOptions() const;
+ enum QuotationStyle { StandardQuotation, AlternateQuotation };
+ QString quoteString(const QString &str, QuotationStyle qs = StandardQuotation) const;
+ QString quoteString(const QStringRef &str, QuotationStyle qs = StandardQuotation) const;
+
//private: // this should be private, but can't be
struct Data {
quint16 index;
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 283f722f91..1d286ab4bc 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -164,6 +164,8 @@ public:
quint16 m_decimal, m_group, m_list, m_percent,
m_zero, m_minus, m_plus, m_exponential;
+ quint16 m_quotation_start, m_quotation_end;
+ quint16 m_alternate_quotation_start, m_alternate_quotation_end;
quint16 m_short_date_format_idx, m_short_date_format_size;
quint16 m_long_date_format_idx, m_long_date_format_size;
diff --git a/tests/auto/qlocale/tst_qlocale.cpp b/tests/auto/qlocale/tst_qlocale.cpp
index 3217e5efc6..250aac98d6 100644
--- a/tests/auto/qlocale/tst_qlocale.cpp
+++ b/tests/auto/qlocale/tst_qlocale.cpp
@@ -141,6 +141,7 @@ private slots:
void ampm();
void currency();
+ void quoteString();
private:
QString m_decimal, m_thousand, m_sdate, m_ldate, m_time;
@@ -1122,6 +1123,8 @@ void tst_QLocale::macDefaultLocale()
QCOMPARE(locale.dayName(7), QString("Sunday"));
QCOMPARE(locale.monthName(1), QString("January"));
QCOMPARE(locale.monthName(12), QString("December"));
+ QCOMPARE(locale.quoteString("string"), QString::fromUtf8("\xe2\x80\x9c" "string" "\xe2\x80\x9d"));
+ QCOMPARE(locale.quoteString("string", QLocale::AlternateQuotation), QString::fromUtf8("\xe2\x80\x98" "string" "\xe2\x80\x99"));
}
@@ -2153,5 +2156,18 @@ void tst_QLocale::currency()
QCOMPARE(de_DE.toCurrencyString(double(-1234.56)), QString::fromUtf8("-1234,56\xc2\xa0\xe2\x82\xac"));
}
+void tst_QLocale::quoteString()
+{
+ const QString someText("text");
+ const QLocale c(QLocale::C);
+ QCOMPARE(c.quoteString(someText), QString::fromUtf8("\x22" "text" "\x22"));
+ QCOMPARE(c.quoteString(someText, QLocale::AlternateQuotation), QString::fromUtf8("\x27" "text" "\x27"));
+
+ const QLocale de_CH("de_CH");
+ QCOMPARE(de_CH.quoteString(someText), QString::fromUtf8("\xc2\xab" "text" "\xc2\xbb"));
+ QCOMPARE(de_CH.quoteString(someText, QLocale::AlternateQuotation), QString::fromUtf8("\xe2\x80\xb9" "text" "\xe2\x80\xba"));
+
+}
+
QTEST_APPLESS_MAIN(tst_QLocale)
#include "tst_qlocale.moc"
diff --git a/util/local_database/cldr2qlocalexml.py b/util/local_database/cldr2qlocalexml.py
index b873565c3e..0bc166408a 100755
--- a/util/local_database/cldr2qlocalexml.py
+++ b/util/local_database/cldr2qlocalexml.py
@@ -199,6 +199,10 @@ def generateLocaleInfo(path):
result['minus'] = get_number_in_system(path, "numbers/symbols/minusSign", numbering_system)
result['plus'] = get_number_in_system(path, "numbers/symbols/plusSign", numbering_system)
result['exp'] = get_number_in_system(path, "numbers/symbols/exponential", numbering_system).lower()
+ result['quotationStart'] = findEntry(path, "delimiters/quotationStart")
+ result['quotationEnd'] = findEntry(path, "delimiters/quotationEnd")
+ result['alternateQuotationStart'] = findEntry(path, "delimiters/alternateQuotationStart")
+ result['alternateQuotationEnd'] = findEntry(path, "delimiters/alternateQuotationEnd")
result['am'] = findEntry(path, "dates/calendars/calendar[gregorian]/dayPeriods/dayPeriodContext[format]/dayPeriodWidth[wide]/dayPeriod[am]", draft)
result['pm'] = findEntry(path, "dates/calendars/calendar[gregorian]/dayPeriods/dayPeriodContext[format]/dayPeriodWidth[wide]/dayPeriod[pm]", draft)
result['longDateFormat'] = convert_date(findEntry(path, "dates/calendars/calendar[gregorian]/dateFormats/dateFormatLength[full]/dateFormat/pattern"))
@@ -600,6 +604,10 @@ print \
<minus>45</minus>\n\
<plus>43</plus>\n\
<exp>101</exp>\n\
+ <quotationStart>\"</quotationStart>\n\
+ <quotationEnd>\"</quotationEnd>\n\
+ <alternateQuotationStart>\'</alternateQuotationStart>\n\
+ <alternateQuotationEnd>\'</alternateQuotationEnd>\n\
<am>AM</am>\n\
<pm>PM</pm>\n\
<firstDayOfWeek>mon</firstDayOfWeek>\n\
@@ -644,6 +652,10 @@ for key in locale_keys:
print " <minus>" + ordStr(l['minus']) + "</minus>"
print " <plus>" + ordStr(l['plus']) + "</plus>"
print " <exp>" + fixOrdStrExp(l['exp']) + "</exp>"
+ print " <quotationStart>" + l['quotationStart'].encode('utf-8') + "</quotationStart>"
+ print " <quotationEnd>" + l['quotationEnd'].encode('utf-8') + "</quotationEnd>"
+ print " <alternateQuotationStart>" + l['alternateQuotationStart'].encode('utf-8') + "</alternateQuotationStart>"
+ print " <alternateQuotationEnd>" + l['alternateQuotationEnd'].encode('utf-8') + "</alternateQuotationEnd>"
print " <am>" + l['am'].encode('utf-8') + "</am>"
print " <pm>" + l['pm'].encode('utf-8') + "</pm>"
print " <firstDayOfWeek>" + l['firstDayOfWeek'].encode('utf-8') + "</firstDayOfWeek>"
diff --git a/util/local_database/qlocalexml2cpp.py b/util/local_database/qlocalexml2cpp.py
index 2f998f3f37..6b8fdb9808 100755
--- a/util/local_database/qlocalexml2cpp.py
+++ b/util/local_database/qlocalexml2cpp.py
@@ -195,6 +195,10 @@ def convertToQtDayOfWeek(firstDay):
qtDayOfWeek = {"mon":1, "tue":2, "wed":3, "thu":4, "fri":5, "sat":6, "sun":7}
return qtDayOfWeek[firstDay]
+def assertSingleChar(string):
+ assert len(string) == 1, "This string is not allowed to be longer than 1 character"
+ return string
+
class Locale:
def __init__(self, elt):
self.language = eltText(firstChildElt(elt, "language"))
@@ -207,6 +211,10 @@ class Locale:
self.minus = int(eltText(firstChildElt(elt, "minus")))
self.plus = int(eltText(firstChildElt(elt, "plus")))
self.exp = int(eltText(firstChildElt(elt, "exp")))
+ self.quotationStart = ord(assertSingleChar(eltText(firstChildElt(elt, "quotationStart"))))
+ self.quotationEnd = ord(assertSingleChar(eltText(firstChildElt(elt, "quotationEnd"))))
+ self.alternateQuotationStart = ord(assertSingleChar(eltText(firstChildElt(elt, "alternateQuotationStart"))))
+ self.alternateQuotationEnd = ord(assertSingleChar(eltText(firstChildElt(elt, "alternateQuotationEnd"))))
self.am = eltText(firstChildElt(elt, "am"))
self.pm = eltText(firstChildElt(elt, "pm"))
self.firstDayOfWeek = convertToQtDayOfWeek(eltText(firstChildElt(elt, "firstDayOfWeek")))
@@ -433,7 +441,7 @@ def main():
# Locale data
data_temp_file.write("static const QLocalePrivate locale_data[] = {\n")
- data_temp_file.write("// lang terr dec group list prcnt zero minus plus exp sDtFmt lDtFmt sTmFmt lTmFmt ssMonth slMonth sMonth lMonth sDays lDays am,len pm,len\n")
+ data_temp_file.write("// lang terr dec group list prcnt zero minus plus exp quotStart quotEnd altQuotStart altQuotEnd sDtFmt lDtFmt sTmFmt lTmFmt ssMonth slMonth sMonth lMonth sDays lDays am,len pm,len\n")
locale_keys = locale_map.keys()
compareLocaleKeys.default_map = default_map
@@ -443,7 +451,7 @@ def main():
for key in locale_keys:
l = locale_map[key]
- data_temp_file.write(" { %6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s, {%s}, %s,%s,%s,%s,%6d,%6d,%6d }, // %s/%s\n" \
+ data_temp_file.write(" { %6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s, {%s}, %s,%s,%s,%s,%6d,%6d,%6d }, // %s/%s\n" \
% (key[0], key[1],
l.decimal,
l.group,
@@ -453,6 +461,10 @@ def main():
l.minus,
l.plus,
l.exp,
+ l.quotationStart,
+ l.quotationEnd,
+ l.alternateQuotationStart,
+ l.alternateQuotationEnd,
date_format_data.append(l.shortDateFormat),
date_format_data.append(l.longDateFormat),
time_format_data.append(l.shortTimeFormat),
@@ -481,7 +493,7 @@ def main():
l.firstDayOfWeek,
l.language,
l.country))
- data_temp_file.write(" { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, {0,0,0}, 0,0, 0,0, 0,0, 0,0, 0, 0, 0 } // trailing 0s\n")
+ data_temp_file.write(" { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, {0,0,0}, 0,0, 0,0, 0,0, 0,0, 0, 0, 0 } // trailing 0s\n")
data_temp_file.write("};\n")
data_temp_file.write("\n")