summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
authorEl Mehdi Fekari <mfekari@rim.com>2013-03-15 18:03:36 (GMT)
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-03-20 09:10:46 (GMT)
commit0e1862cf317ae08ff80dc967491e69ea84599f13 (patch)
tree115410d0a7e08e3ec4287f86fb6b59e822c39638 /src/corelib/tools
parent1d2234498cde6821014fcec7f2b321ad76724cce (diff)
downloadQt-0e1862cf317ae08ff80dc967491e69ea84599f13.zip
Qt-0e1862cf317ae08ff80dc967491e69ea84599f13.tar.gz
Qt-0e1862cf317ae08ff80dc967491e69ea84599f13.tar.bz2
Inital port of QSystemLocale on BlackBerry 10
Backport of: a0c4a712263dbacd2c8d95da64e00bd213d05cbf Change-Id: I4253067b42a8aa93325d48eeaa3a9937be2d2b75 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com> Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qlocale_blackberry.cpp313
-rw-r--r--src/corelib/tools/qlocale_blackberry.h105
-rw-r--r--src/corelib/tools/qlocale_p.h23
-rw-r--r--src/corelib/tools/qlocale_unix.cpp84
-rw-r--r--src/corelib/tools/tools.pri4
5 files changed, 422 insertions, 107 deletions
diff --git a/src/corelib/tools/qlocale_blackberry.cpp b/src/corelib/tools/qlocale_blackberry.cpp
new file mode 100644
index 0000000..09b81ca
--- /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(QLatin1String("AP"), Qt::CaseInsensitive)) {
+ format.replace(QLatin1String("AP"), QLatin1String(""), Qt::CaseInsensitive);
+ format.replace(QLatin1String("h"), QLatin1String("H"), Qt::CaseSensitive);
+ }
+
+ } else {
+
+ if (!format.contains(QLatin1String("AP"), Qt::CaseInsensitive)) {
+ format.contains(QLatin1String("HH"), Qt::CaseSensitive) ?
+ format.replace(QLatin1String("HH"), QLatin1String("hh"), Qt::CaseSensitive) :
+ format.replace(QLatin1String("H"), QLatin1String("h"), Qt::CaseSensitive);
+
+ formatType == QLocale::LongFormat ? format.append(QLatin1String(" AP t")) : format.append(QLatin1String(" AP"));
+ }
+ }
+
+ return format;
+}
+
+Q_GLOBAL_STATIC(QBBSystemLocaleData, bbSysLocaleData)
+
+QLocale QSystemLocale::fallbackLocale() 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 0000000..3a5bc20
--- /dev/null
+++ b/src/corelib/tools/qlocale_blackberry.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** 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_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+#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
+
+QT_END_HEADER
+
+#endif // QLOCALE_BLACKBERRY_H
+
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 780055e..1756972 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
-
#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
class CEnvironmentChangeNotifier;
#endif
@@ -275,25 +271,6 @@ private:
};
#endif
-#if defined(Q_OS_BLACKBERRY)
-class QBBLocaleData: public QObject
-{
- Q_OBJECT
-public:
- QBBLocaleData();
- virtual ~QBBLocaleData();
- void readPPSLocale();
-
-public Q_SLOTS:
- void updateMeasurementSystem();
-
-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 b9d228e..3fa903d 100644
--- a/src/corelib/tools/qlocale_unix.cpp
+++ b/src/corelib/tools/qlocale_unix.cpp
@@ -46,82 +46,8 @@
#include "qstringlist.h"
#include "qvariant.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;
-
-QBBLocaleData::QBBLocaleData()
- :ppsNotifier(0)
- ,ppsFd(-1)
-{
- readPPSLocale();
-}
-
-QBBLocaleData::~QBBLocaleData()
-{
- if (ppsFd != -1)
- qt_safe_close(ppsFd);
-}
-
-void QBBLocaleData::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 QBBLocaleData::readPPSLocale()
-{
- errno = 0;
- ppsFd = qt_safe_open(ppsServicePath, O_RDONLY);
- if (ppsFd == -1) {
- qWarning("Failed to open Locale pps, errno=%d", errno);
- return;
- }
-
- updateMeasurementSystem();
- if (QCoreApplication::instance()) {
- ppsNotifier = new QSocketNotifier(ppsFd, QSocketNotifier::Read, this);
- QObject::connect(ppsNotifier, SIGNAL(activated(int)), this, SLOT(updateMeasurementSystem()));
- }
-}
-#endif
-
static QByteArray getSystemLocale()
{
#if defined(Q_OS_QNX)
@@ -188,10 +114,6 @@ struct QSystemLocaleData
Q_GLOBAL_STATIC(QSystemLocaleData, qSystemLocaleData)
#endif
-#if defined(Q_OS_BLACKBERRY)
- Q_GLOBAL_STATIC(QBBLocaleData, qbbLocaleData)
-#endif
-
#ifndef QT_NO_SYSTEMLOCALE
QLocale QSystemLocale::fallbackLocale() const
{
@@ -208,9 +130,6 @@ QLocale QSystemLocale::fallbackLocale() const
QVariant QSystemLocale::query(QueryType type, QVariant in) const
{
QSystemLocaleData *d = qSystemLocaleData();
-#if defined(Q_OS_BLACKBERRY)
- QBBLocaleData *bbd = qbbLocaleData();
-#endif
const QLocale &lc_numeric = d->lc_numeric;
const QLocale &lc_time = d->lc_time;
const QLocale &lc_monetary = d->lc_monetary;
@@ -290,9 +209,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 bbd->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 3dfce4b..1a7153a 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -88,6 +88,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:symbian:SOURCES += tools/qelapsedtimer_symbian.cpp tools/qlocale_symbian.cpp
else:unix:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp
else:win32:SOURCES += tools/qelapsedtimer_win.cpp tools/qlocale_win.cpp