summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEl Mehdi Fekari <mfekari@rim.com>2013-03-08 16:08:23 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-03-14 19:49:38 +0100
commita0c4a712263dbacd2c8d95da64e00bd213d05cbf (patch)
treeaa7e4ee78ff8421615f0906a747a95e07ca00d62
parentb32a6384b3786e5e496810121429e2860fc41da1 (diff)
Inital port of QSystemLocale on BlackBerry 10
Change-Id: Ic177e2867d9fa3dbaec221766964ac28656a2662 Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
-rw-r--r--src/corelib/tools/qlocale_blackberry.cpp313
-rw-r--r--src/corelib/tools/qlocale_blackberry.h99
-rw-r--r--src/corelib/tools/qlocale_p.h26
-rw-r--r--src/corelib/tools/qlocale_unix.cpp101
-rw-r--r--src/corelib/tools/tools.pri4
5 files changed, 416 insertions, 127 deletions
diff --git a/src/corelib/tools/qlocale_blackberry.cpp b/src/corelib/tools/qlocale_blackberry.cpp
new file mode 100644
index 0000000000..01576dd732
--- /dev/null
+++ b/src/corelib/tools/qlocale_blackberry.cpp
@@ -0,0 +1,313 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlocale_blackberry.h"
+#include "qlocale_p.h"
+
+#include "qdatetime.h"
+
+#include "qcoreapplication.h"
+#include "private/qcore_unix_p.h"
+
+#include <errno.h>
+#include <sys/pps.h>
+#include <unistd.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_SYSTEMLOCALE
+
+static const char ppsUomPath[] = "/pps/services/locale/uom";
+static const char ppsRegionLocalePath[] = "/pps/services/locale/settings";
+static const char ppsLanguageLocalePath[] = "/pps/services/confstr/_CS_LOCALE";
+static const char ppsHourFormatPath[] = "/pps/system/settings";
+
+static const size_t ppsBufferSize = 256;
+
+QBBSystemLocaleData::QBBSystemLocaleData()
+ : languageNotifier(0)
+ , regionNotifier(0)
+ , measurementNotifier(0)
+ , hourNotifier(0)
+ , languageFd(-1)
+ , regionFd(-1)
+ , measurementFd(-1)
+ , hourFd(-1)
+{
+ // we cannot call this directly, because by the time this constructor is
+ // called, the event dispatcher has not yet been created, causing the
+ // subsequent call to QSocketNotifier constructor to fail.
+ QMetaObject::invokeMethod(this, "installSocketNotifiers", Qt::QueuedConnection);
+
+ readLangageLocale();
+ readRegionLocale();
+ readMeasurementSystem();
+ readHourFormat();
+}
+
+QBBSystemLocaleData::~QBBSystemLocaleData()
+{
+ if (measurementFd != -1)
+ qt_safe_close(measurementFd);
+
+ if (languageFd != -1)
+ qt_safe_close(languageFd);
+
+ if (regionFd != -1)
+ qt_safe_close(regionFd);
+
+ if (hourFd != -1)
+ qt_safe_close(hourFd);
+}
+
+uint QBBSystemLocaleData::measurementSystem()
+{
+ return m_measurementSystem;
+}
+
+QVariant QBBSystemLocaleData::timeFormat(QLocale::FormatType formatType)
+{
+ return getCorrectFormat(regionLocale().timeFormat(formatType), formatType);
+}
+
+QVariant QBBSystemLocaleData::dateTimeFormat(QLocale::FormatType formatType)
+{
+ return getCorrectFormat(regionLocale().dateTimeFormat(formatType), formatType);
+}
+
+QLocale QBBSystemLocaleData::languageLocale()
+{
+ if (!lc_langage.isEmpty())
+ return QLocale(QLatin1String(lc_langage));
+
+ return QLocale::c();
+}
+
+QLocale QBBSystemLocaleData::regionLocale()
+{
+ if (!lc_region.isEmpty())
+ return QLocale(QLatin1String(lc_region));
+
+ return QLocale::c();
+}
+
+void QBBSystemLocaleData::installSocketNotifiers()
+{
+ Q_ASSERT(!languageNotifier || !regionNotifier || !measurementNotifier || !hourNotifier);
+ Q_ASSERT(QCoreApplication::instance());
+
+ languageNotifier = new QSocketNotifier(languageFd, QSocketNotifier::Read, this);
+ QObject::connect(languageNotifier, SIGNAL(activated(int)), this, SLOT(readLangageLocale()));
+
+ regionNotifier = new QSocketNotifier(regionFd, QSocketNotifier::Read, this);
+ QObject::connect(regionNotifier, SIGNAL(activated(int)), this, SLOT(readRegionLocale()));
+
+ measurementNotifier = new QSocketNotifier(measurementFd, QSocketNotifier::Read, this);
+ QObject::connect(measurementNotifier, SIGNAL(activated(int)), this, SLOT(readMeasurementSystem()));
+
+ hourNotifier = new QSocketNotifier(hourFd, QSocketNotifier::Read, this);
+ QObject::connect(hourNotifier, SIGNAL(activated(int)), this, SLOT(readHourFormat()));
+}
+
+void QBBSystemLocaleData::readLangageLocale()
+{
+ lc_langage = readPpsValue(ppsLanguageLocalePath, "_CS_LOCALE", &languageFd);
+}
+
+void QBBSystemLocaleData::readRegionLocale()
+{
+ lc_region = readPpsValue(ppsRegionLocalePath, "region", &regionFd);
+}
+
+void QBBSystemLocaleData::readMeasurementSystem()
+{
+ QByteArray measurement = readPpsValue(ppsUomPath, "uom", &measurementFd);
+ m_measurementSystem = (qstrcmp(measurement, "imperial") == 0) ? QLocale::ImperialSystem : QLocale::MetricSystem;
+}
+
+void QBBSystemLocaleData::readHourFormat()
+{
+ QByteArray hourFormat = readPpsValue(ppsHourFormatPath, "hourFormat", &hourFd);
+ is24HourFormat = (qstrcmp(hourFormat, "24") == 0);
+}
+
+QByteArray QBBSystemLocaleData::readPpsValue(const char *ppsPath, const char *ppsObject, int *ppsFd)
+{
+ QByteArray result;
+ if (!ppsPath || !ppsObject)
+ return result;
+
+ *ppsFd = qt_safe_open(ppsPath, O_RDONLY);
+ if (*ppsFd == -1) {
+ qWarning("Failed to open Locale pps, errno=%d", errno);
+ return result;
+ }
+
+ char buffer[ppsBufferSize];
+
+ int bytes = qt_safe_read(*ppsFd, buffer, ppsBufferSize - 1);
+ if (bytes == -1) {
+ qWarning("Failed to read Locale pps, errno=%d", errno);
+ return result;
+ }
+ // ensure data is null terminated
+ buffer[bytes] = '\0';
+
+ pps_decoder_t ppsDecoder;
+ pps_decoder_initialize(&ppsDecoder, 0);
+ if (pps_decoder_parse_pps_str(&ppsDecoder, buffer) == PPS_DECODER_OK) {
+ pps_decoder_push(&ppsDecoder, 0);
+ const char *ppsBuff;
+ if (pps_decoder_get_string(&ppsDecoder, ppsObject, &ppsBuff) == PPS_DECODER_OK) {
+ result = ppsBuff;
+ } else {
+ int val;
+ if (pps_decoder_get_int(&ppsDecoder, ppsObject, &val) == PPS_DECODER_OK)
+ result = QByteArray::number(val);
+ }
+ }
+
+ pps_decoder_cleanup(&ppsDecoder);
+
+ return result;
+}
+
+QString QBBSystemLocaleData::getCorrectFormat(const QString &baseFormat, QLocale::FormatType formatType)
+{
+ QString format = baseFormat;
+ if (is24HourFormat) {
+ if (format.contains(QStringLiteral("AP"), Qt::CaseInsensitive)) {
+ format.replace(QStringLiteral("AP"), QStringLiteral(""), Qt::CaseInsensitive);
+ format.replace(QStringLiteral("h"), QStringLiteral("H"), Qt::CaseSensitive);
+ }
+
+ } else {
+
+ if (!format.contains(QStringLiteral("AP"), Qt::CaseInsensitive)) {
+ format.contains(QStringLiteral("HH"), Qt::CaseSensitive) ?
+ format.replace(QStringLiteral("HH"), QStringLiteral("hh"), Qt::CaseSensitive) :
+ format.replace(QStringLiteral("H"), QStringLiteral("h"), Qt::CaseSensitive);
+
+ formatType == QLocale::LongFormat ? format.append(QStringLiteral(" AP t")) : format.append(QStringLiteral(" AP"));
+ }
+ }
+
+ return format;
+}
+
+Q_GLOBAL_STATIC(QBBSystemLocaleData, bbSysLocaleData)
+
+QLocale QSystemLocale::fallbackUiLocale() const
+{
+ return bbSysLocaleData()->languageLocale();
+}
+
+QVariant QSystemLocale::query(QueryType type, QVariant in) const
+{
+ QBBSystemLocaleData *d = bbSysLocaleData();
+
+ QReadLocker locker(&d->lock);
+
+ const QLocale &lc_language = d->languageLocale();
+ const QLocale &lc_region = d->regionLocale();
+
+ switch (type) {
+ case DecimalPoint:
+ return lc_region.decimalPoint();
+ case GroupSeparator:
+ return lc_region.groupSeparator();
+ case NegativeSign:
+ return lc_region.negativeSign();
+ case PositiveSign:
+ return lc_region.positiveSign();
+ case DateFormatLong:
+ return lc_region.dateFormat(QLocale::LongFormat);
+ case DateFormatShort:
+ return lc_region.dateFormat(QLocale::ShortFormat);
+ case TimeFormatLong:
+ return d->timeFormat(QLocale::LongFormat);
+ case TimeFormatShort:
+ return d->timeFormat(QLocale::ShortFormat);
+ case DateTimeFormatLong:
+ return d->dateTimeFormat(QLocale::LongFormat);
+ case DateTimeFormatShort:
+ return d->dateTimeFormat(QLocale::ShortFormat);
+ case DayNameLong:
+ return lc_language.dayName(in.toInt(), QLocale::LongFormat);
+ case DayNameShort:
+ return lc_language.dayName(in.toInt(), QLocale::ShortFormat);
+ case MonthNameLong:
+ return lc_language.monthName(in.toInt(), QLocale::LongFormat);
+ case MonthNameShort:
+ return lc_language.monthName(in.toInt(), QLocale::ShortFormat);
+ case DateToStringLong:
+ return lc_region.toString(in.toDate(), QLocale::LongFormat);
+ case DateToStringShort:
+ return lc_region.toString(in.toDate(), QLocale::ShortFormat);
+ case TimeToStringLong:
+ return lc_region.toString(in.toTime(), QLocale::LongFormat);
+ case TimeToStringShort:
+ return lc_region.toString(in.toTime(), QLocale::ShortFormat);
+ case DateTimeToStringShort:
+ return lc_region.toString(in.toDateTime(), d->dateTimeFormat(QLocale::ShortFormat).toString());
+ case DateTimeToStringLong:
+ return lc_region.toString(in.toDateTime(), d->dateTimeFormat(QLocale::LongFormat).toString());
+ case MeasurementSystem:
+ return d->measurementSystem();
+ case ZeroDigit:
+ return lc_region.zeroDigit();
+ case CountryId:
+ return lc_region.country();
+ case LanguageId:
+ return lc_language.language();
+ case AMText:
+ return lc_language.amText();
+ case PMText:
+ return lc_language.pmText();
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qlocale_blackberry.h b/src/corelib/tools/qlocale_blackberry.h
new file mode 100644
index 0000000000..8e9560d6c1
--- /dev/null
+++ b/src/corelib/tools/qlocale_blackberry.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLOCALE_BLACKBERRY_H
+#define QLOCALE_BLACKBERRY_H
+
+#include "qsocketnotifier.h"
+#include "qreadwritelock.h"
+#include "qlocale.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_SYSTEMLOCALE
+
+class QBBSystemLocaleData : public QObject
+{
+ Q_OBJECT
+
+public:
+ QBBSystemLocaleData();
+ virtual ~QBBSystemLocaleData();
+ uint measurementSystem();
+ QVariant timeFormat(QLocale::FormatType);
+ QVariant dateTimeFormat(QLocale::FormatType);
+ QLocale languageLocale();
+ QLocale regionLocale();
+
+ QReadWriteLock lock;
+
+public Q_SLOTS:
+ void installSocketNotifiers();
+ void readLangageLocale();
+ void readRegionLocale();
+ void readMeasurementSystem();
+ void readHourFormat();
+
+private:
+ QByteArray readPpsValue(const char* ppsPath, const char* ppsObject, int* ppsFd);
+ QString getCorrectFormat(const QString &baseFormat, QLocale::FormatType typeFormat);
+
+ QByteArray lc_langage;
+ QByteArray lc_region;
+ uint m_measurementSystem;
+ bool is24HourFormat;
+
+ QSocketNotifier *languageNotifier;
+ QSocketNotifier *regionNotifier;
+ QSocketNotifier *measurementNotifier;
+ QSocketNotifier *hourNotifier;
+
+ int languageFd;
+ int regionFd;
+ int measurementFd;
+ int hourFd;
+};
+#endif // QT_NO_SYSTEMLOCALE
+
+QT_END_NAMESPACE
+
+#endif // QLOCALE_BLACKBERRY_H
+
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 3c3d7c7054..ff44dcc163 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -59,10 +59,6 @@
#include "qlocale.h"
-#if defined(Q_OS_BLACKBERRY)
-#include "qsocketnotifier.h"
-#endif
-
QT_BEGIN_NAMESPACE
#ifndef QT_NO_SYSTEMLOCALE
@@ -377,28 +373,6 @@ inline char QLocalePrivate::digitToCLocale(QChar in) const
return 0;
}
-#if defined(Q_OS_BLACKBERRY)
-class QQNXLocaleData: public QObject
-{
- Q_OBJECT
-public:
- QQNXLocaleData();
- virtual ~QQNXLocaleData();
-
-public Q_SLOTS:
- void updateMeasurementSystem();
- void installSocketNotifier();
-
-private:
- void initialize();
-
-public:
- uint ppsMeasurement;
- QSocketNotifier *ppsNotifier;
- int ppsFd;
-};
-#endif
-
QString qt_readEscapedFormatString(const QString &format, int *idx);
bool qt_splitLocaleName(const QString &name, QString &lang, QString &script, QString &cntry);
int qt_repeatCount(const QString &s, int i);
diff --git a/src/corelib/tools/qlocale_unix.cpp b/src/corelib/tools/qlocale_unix.cpp
index fb9e3f1a8b..4e443cd79b 100644
--- a/src/corelib/tools/qlocale_unix.cpp
+++ b/src/corelib/tools/qlocale_unix.cpp
@@ -47,99 +47,8 @@
#include "qvariant.h"
#include "qreadwritelock.h"
-#if defined(Q_OS_BLACKBERRY)
-#include <QtCore/private/qcore_unix_p.h>
-#include <QCoreApplication>
-
-#include <unistd.h>
-#include <errno.h>
-#include <sys/pps.h>
-#endif
-
QT_BEGIN_NAMESPACE
-#if defined(Q_OS_BLACKBERRY)
-static const char ppsServicePath[] = "/pps/services/locale/uom";
-static const size_t ppsBufferSize = 256;
-
-QQNXLocaleData::QQNXLocaleData()
- :ppsNotifier(0)
- ,ppsFd(-1)
-{
- initialize();
-
- // we cannot call this directly, because by the time this constructor is
- // called, the event dispatcher has not yet been created, causing the
- // subsequent call to QSocketNotifier constructor to fail.
- QMetaObject::invokeMethod(this, "installSocketNotifier", Qt::QueuedConnection);
-}
-
-QQNXLocaleData::~QQNXLocaleData()
-{
- if (ppsFd != -1)
- qt_safe_close(ppsFd);
-}
-
-void QQNXLocaleData::updateMeasurementSystem()
-{
- char buffer[ppsBufferSize];
-
- errno = 0;
- int bytes = qt_safe_read(ppsFd, buffer, ppsBufferSize - 1);
- if (bytes == -1) {
- qWarning("Failed to read Locale pps, errno=%d", errno);
- return;
- }
- // ensure data is null terminated
- buffer[bytes] = '\0';
-
- pps_decoder_t ppsDecoder;
- pps_decoder_initialize(&ppsDecoder, 0);
- if (pps_decoder_parse_pps_str(&ppsDecoder, buffer) == PPS_DECODER_OK) {
- pps_decoder_push(&ppsDecoder, 0);
- const char *measurementBuff;
- if (pps_decoder_get_string(&ppsDecoder, "uom", &measurementBuff) == PPS_DECODER_OK) {
- if (qstrcmp(measurementBuff, "imperial") == 0) {
- pps_decoder_cleanup(&ppsDecoder);
- ppsMeasurement = QLocale::ImperialSystem;
- return;
- }
- }
- }
-
- pps_decoder_cleanup(&ppsDecoder);
- ppsMeasurement = QLocale::MetricSystem;
-}
-
-void QQNXLocaleData::initialize()
-{
- errno = 0;
- ppsFd = qt_safe_open(ppsServicePath, O_RDONLY);
- if (ppsFd == -1) {
- qWarning("Failed to open Locale pps, errno=%d", errno);
- return;
- }
-
- updateMeasurementSystem();
-}
-
-void QQNXLocaleData::installSocketNotifier()
-{
- if (!QCoreApplication::instance() || ppsFd == -1) {
- qWarning("QQNXLocaleData: Failed to create socket notifier, locale updates may not work.");
- return;
- }
-
- if (ppsNotifier) {
- qWarning("QQNXLocaleData: socket notifier already created.");
- return;
- }
-
- ppsNotifier = new QSocketNotifier(ppsFd, QSocketNotifier::Read, this);
- QObject::connect(ppsNotifier, SIGNAL(activated(int)), this, SLOT(updateMeasurementSystem()));
-}
-#endif
-
#ifndef QT_NO_SYSTEMLOCALE
struct QSystemLocaleData
{
@@ -194,11 +103,7 @@ void QSystemLocaleData::readEnvironment()
lc_messages = QLocale(QString::fromLatin1(lc_messages_var));
}
-
Q_GLOBAL_STATIC(QSystemLocaleData, qSystemLocaleData)
-#if defined(Q_OS_BLACKBERRY)
- Q_GLOBAL_STATIC(QQNXLocaleData, qqnxLocaleData)
-#endif
#endif
@@ -230,9 +135,6 @@ QLocale QSystemLocale::fallbackUiLocale() const
QVariant QSystemLocale::query(QueryType type, QVariant in) const
{
QSystemLocaleData *d = qSystemLocaleData();
-#if defined(Q_OS_BLACKBERRY)
- QQNXLocaleData *qnxd = qqnxLocaleData();
-#endif
if (type == LocaleChanged) {
d->readEnvironment();
@@ -320,9 +222,6 @@ QVariant QSystemLocale::query(QueryType type, QVariant in) const
return QLocale::MetricSystem;
if (meas_locale.compare(QLatin1String("Other"), Qt::CaseInsensitive) == 0)
return QLocale::MetricSystem;
-#if defined(Q_OS_BLACKBERRY)
- return qnxd->ppsMeasurement;
-#endif
return QVariant((int)QLocale(meas_locale).measurementSystem());
}
case UILanguages: {
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index c6e12c59eb..bb152987e6 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -106,6 +106,10 @@ SOURCES += \
SOURCES += tools/qelapsedtimer_mac.cpp
OBJECTIVE_SOURCES += tools/qlocale_mac.mm
}
+else:blackberry {
+ SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_blackberry.cpp
+ HEADERS += tools/qlocale_blackberry.h
+}
else:unix:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp
else:win32:SOURCES += tools/qelapsedtimer_win.cpp tools/qlocale_win.cpp
else:integrity:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp