summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authordka <darpan.k-a@nokia.com>2009-10-12 13:25:23 (GMT)
committerDenis Dzyubenko <denis.dzyubenko@nokia.com>2009-12-15 09:36:33 (GMT)
commit44f7c1e097582a704a06ccbbf516536b88ddcd3a (patch)
tree1444e29341ecd5d02d78ee66bd056f432680fed0 /src
parent1f4a4cca0067b1d4a9784f00e41c3fc1aca1f712 (diff)
downloadQt-44f7c1e097582a704a06ccbbf516536b88ddcd3a.zip
Qt-44f7c1e097582a704a06ccbbf516536b88ddcd3a.tar.gz
Qt-44f7c1e097582a704a06ccbbf516536b88ddcd3a.tar.bz2
Changes to support locale change event for symbian platform
Subscribing to the locale change notification to be able to update the system locale whenever the user changes the current system locale. Also changed the initialization of the system locale to make construction of the QLocale object as lightweight as possible. So now the default contructor just creates a QLocale and QSystemLocale objects, but doesn't try to fill the cache in the latter with data from the system and postpones it until it is actually requested (most applications create QLocale objects on the stack and might not even use the data from the system locale, so we don't need to initialize system locale right away). Modified-by: axis Modified-by: Denis Dzyubenko Reviewed-by: Denis Dzyubenko Reviewed-by: axis
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qcore_symbian_p.h3
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp10
-rw-r--r--src/corelib/kernel/qcoreapplication.h4
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h4
-rw-r--r--src/corelib/tools/qlocale.cpp43
-rw-r--r--src/corelib/tools/qlocale_p.h5
-rw-r--r--src/corelib/tools/qlocale_symbian.cpp121
-rw-r--r--src/plugins/s60/src/qlocale_3_1.cpp8
8 files changed, 181 insertions, 17 deletions
diff --git a/src/corelib/kernel/qcore_symbian_p.h b/src/corelib/kernel/qcore_symbian_p.h
index f86bfd3..2ef48b5 100644
--- a/src/corelib/kernel/qcore_symbian_p.h
+++ b/src/corelib/kernel/qcore_symbian_p.h
@@ -139,7 +139,8 @@ enum S60PluginFuncOrdinals
S60Plugin_GetLongDateFormatSpec = 3,
S60Plugin_GetShortDateFormatSpec = 4,
S60Plugin_LocalizedDirectoryName = 5,
- S60Plugin_GetSystemDrive = 6
+ S60Plugin_GetSystemDrive = 6,
+ S60Plugin_RefreshLocaleInfo = 7
};
Q_CORE_EXPORT TLibraryFunction qt_resolveS60PluginFunc(int ordinal);
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 8a55bad..93df45d 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -69,6 +69,7 @@
# include <f32file.h>
# include "qeventdispatcher_symbian_p.h"
# include "private/qcore_symbian_p.h"
+# include "private/qlocale_p.h"
#elif defined(Q_OS_UNIX)
# if !defined(QT_NO_GLIB)
# include "qeventdispatcher_glib_p.h"
@@ -2601,4 +2602,13 @@ int QCoreApplication::loopLevel()
\sa Q_OBJECT, QObject::tr(), QObject::trUtf8()
*/
+#if defined(Q_OS_SYMBIAN)
+void QCoreApplicationPrivate::_q_symbianRegisterLocaleNotifier()
+{
+ QLocalePrivate::symbianRegisterLocaleNotifier();
+}
+#endif
+
QT_END_NAMESPACE
+
+#include "moc_qcoreapplication.cpp"
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index 097b8b4..152a775 100644
--- a/src/corelib/kernel/qcoreapplication.h
+++ b/src/corelib/kernel/qcoreapplication.h
@@ -196,6 +196,10 @@ private:
static QCoreApplication *self;
+#if defined(Q_OS_SYMBIAN)
+ Q_PRIVATE_SLOT(d_func(), void _q_symbianRegisterLocaleNotifier())
+#endif
+
Q_DISABLE_COPY(QCoreApplication)
friend class QEventDispatcherUNIXPrivate;
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index bf43f88..39e50c4 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -122,6 +122,10 @@ public:
static uint attribs;
static inline bool testAttribute(uint flag) { return attribs & (1 << flag); }
+
+#if defined(Q_OS_SYMBIAN)
+ void _q_symbianRegisterLocaleNotifier();
+#endif
};
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 4a66b92..22114c2 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -129,6 +129,10 @@ inline bool isascii(int c)
}
#endif
+#if defined(Q_OS_SYMBIAN)
+void symbianUpdateSystemPrivate();
+#endif
+
/******************************************************************************
** Helpers for accessing Qt locale database
*/
@@ -1388,7 +1392,8 @@ QSystemLocale::QSystemLocale()
/*! \internal */
QSystemLocale::QSystemLocale(bool)
-{ }
+{
+}
/*!
Deletes the object.
@@ -1407,16 +1412,29 @@ static const QSystemLocale *systemLocale()
{
if (_systemLocale)
return _systemLocale;
+#if defined(Q_OS_SYMBIAN)
+ symbianInitSystemLocale();
+#endif
return QSystemLocale_globalSystemLocale();
}
-void QLocalePrivate::updateSystemPrivate()
+void QLocalePrivate::updateSystemPrivate(bool initialize)
{
const QSystemLocale *sys_locale = systemLocale();
if (!system_lp)
system_lp = globalLocalePrivate();
*system_lp = *sys_locale->fallbackLocale().d();
+ system_lp->m_language_id = 0;
+#if defined(Q_OS_SYMBIAN)
+ RDebug::Print(_L("updateSystemPrivate"));
+#endif
+ if (!initialize)
+ return;
+
+#if defined(Q_OS_SYMBIAN)
+ symbianUpdateSystemPrivate();
+#endif
QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant());
if (!res.isNull())
system_lp->m_language_id = res.toInt();
@@ -1446,12 +1464,12 @@ void QLocalePrivate::updateSystemPrivate()
}
#endif
-static const QLocalePrivate *systemPrivate()
+static const QLocalePrivate *systemPrivate(bool initialize = true)
{
#ifndef QT_NO_SYSTEMLOCALE
// copy over the information from the fallback locale and modify
if (!system_lp || system_lp->m_language_id == 0)
- QLocalePrivate::updateSystemPrivate();
+ QLocalePrivate::updateSystemPrivate(initialize);
return system_lp;
#else
@@ -1459,10 +1477,10 @@ static const QLocalePrivate *systemPrivate()
#endif
}
-static const QLocalePrivate *defaultPrivate()
+static const QLocalePrivate *defaultPrivate(bool initialize = true)
{
if (!default_lp)
- default_lp = systemPrivate();
+ default_lp = systemPrivate(initialize);
return default_lp;
}
@@ -2169,7 +2187,7 @@ QLocale::QLocale()
: v(0)
{
p.numberOptions = default_number_options;
- p.index = localePrivateIndex(defaultPrivate());
+ p.index = localePrivateIndex(defaultPrivate(false));
}
/*!
@@ -2199,7 +2217,7 @@ QLocale::QLocale(Language language, Country country)
// If not found, should default to system
if (d->languageId() == QLocale::C && language != QLocale::C) {
p.numberOptions = default_number_options;
- p.index = localePrivateIndex(defaultPrivate());
+ p.index = localePrivateIndex(defaultPrivate(false));
} else {
p.numberOptions = 0;
p.index = localePrivateIndex(d);
@@ -2283,6 +2301,7 @@ void QLocale::setDefault(const QLocale &locale)
*/
QLocale::Language QLocale::language() const
{
+ systemPrivate(); // make sure inline data is initialized from the system.
return Language(d()->languageId());
}
@@ -2293,6 +2312,7 @@ QLocale::Language QLocale::language() const
*/
QLocale::Country QLocale::country() const
{
+ systemPrivate(); // make sure inline data is initialized from the system.
return Country(d()->countryId());
}
@@ -3021,6 +3041,7 @@ QDateTime QLocale::toDateTime(const QString &string, const QString &format) cons
*/
QChar QLocale::decimalPoint() const
{
+ systemPrivate(); // make sure inline data is initialized from the system.
return d()->decimal();
}
@@ -3031,6 +3052,7 @@ QChar QLocale::decimalPoint() const
*/
QChar QLocale::groupSeparator() const
{
+ systemPrivate(); // make sure inline data is initialized from the system.
return d()->group();
}
@@ -3041,6 +3063,7 @@ QChar QLocale::groupSeparator() const
*/
QChar QLocale::percent() const
{
+ systemPrivate(); // make sure inline data is initialized from the system.
return d()->percent();
}
@@ -3051,6 +3074,7 @@ QChar QLocale::percent() const
*/
QChar QLocale::zeroDigit() const
{
+ systemPrivate(); // make sure inline data is initialized from the system.
return d()->zero();
}
@@ -3061,6 +3085,7 @@ QChar QLocale::zeroDigit() const
*/
QChar QLocale::negativeSign() const
{
+ systemPrivate(); // make sure inline data is initialized from the system.
return d()->minus();
}
@@ -3071,6 +3096,7 @@ QChar QLocale::negativeSign() const
*/
QChar QLocale::positiveSign() const
{
+ systemPrivate(); // make sure inline data is initialized from the system.
return d()->plus();
}
@@ -3081,6 +3107,7 @@ QChar QLocale::positiveSign() const
*/
QChar QLocale::exponential() const
{
+ systemPrivate(); // make sure inline data is initialized from the system.
return d()->exponential();
}
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 0123a6e..63e9e0f 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -132,7 +132,10 @@ public:
CharBuff *result) const;
inline char digitToCLocale(const QChar &c) const;
- static void updateSystemPrivate();
+ static void updateSystemPrivate(bool initialize = true);
+#if defined(Q_OS_SYMBIAN)
+ static void symbianRegisterLocaleNotifier();
+#endif
enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode };
bool validateChars(const QString &str, NumberMode numMode, QByteArray *buff, int decDigits = -1) const;
diff --git a/src/corelib/tools/qlocale_symbian.cpp b/src/corelib/tools/qlocale_symbian.cpp
index 1273d06..c4ad67c 100644
--- a/src/corelib/tools/qlocale_symbian.cpp
+++ b/src/corelib/tools/qlocale_symbian.cpp
@@ -46,11 +46,95 @@
#include <QThread>
#include <e32std.h>
+#include <e32const.h>
+#include <e32base.h>
#include "private/qcore_symbian_p.h"
-
+#include "private/qcoreapplication_p.h"
+#include "qlocale_p.h"
+#include "qdebug.h"
QT_BEGIN_NAMESPACE
+class CLocaleChangeNotifier : public CActive
+{
+public:
+ static CLocaleChangeNotifier *NewL();
+ ~CLocaleChangeNotifier();
+
+private:
+ CLocaleChangeNotifier();
+ void ConstructL();
+ void RunL();
+ void DoCancel();
+
+private:
+ RChangeNotifier changeNotifier;
+};
+
+static CLocaleChangeNotifier *qt_changeNotifier = NULL;
+
+CLocaleChangeNotifier *CLocaleChangeNotifier::NewL()
+{
+ CLocaleChangeNotifier *self = new (ELeave) CLocaleChangeNotifier();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+}
+
+CLocaleChangeNotifier::CLocaleChangeNotifier()
+ : CActive(CActive::EPriorityStandard)
+{
+}
+
+
+CLocaleChangeNotifier::~CLocaleChangeNotifier()
+{
+ Cancel();
+ changeNotifier.Close();
+}
+
+void CLocaleChangeNotifier::ConstructL()
+{
+ changeNotifier.Create();
+ CActiveScheduler::Add(this);
+ SetActive();
+}
+
+void CLocaleChangeNotifier::DoCancel()
+{
+ changeNotifier.LogonCancel();
+}
+
+void CLocaleChangeNotifier::RunL()
+{
+ SetActive();
+ if (changeNotifier.Logon(iStatus) == KErrNone) {
+ if (iStatus.Int() == EChangesLocale) {
+ RDebug::Print(_L("notifier:locale changed"));
+ QT_TRYCATCH_LEAVING(QLocalePrivate::updateSystemPrivate());
+ } else {
+ RDebug::Print(_L("notifier:something else changed"));
+ }
+ } else {
+ RDebug::Print(_L("notifier:logon failed"));
+ }
+}
+
+static void qt_cleanupLocaleNotifier()
+{
+ delete qt_changeNotifier;
+ qt_changeNotifier = NULL;
+}
+
+void QLocalePrivate::symbianRegisterLocaleNotifier()
+{
+ if (!qt_changeNotifier) {
+ QT_TRAP_THROWING(qt_changeNotifier = CLocaleChangeNotifier::NewL());
+ qAddPostRoutine(qt_cleanupLocaleNotifier);
+ }
+}
+
// Located in qlocale.cpp
extern void getLangAndCountry(const QString &name, QLocale::Language &lang, QLocale::Country &cntry);
@@ -65,6 +149,7 @@ static FormatFunc ptrTimeFormatL = NULL;
static FormatSpecFunc ptrGetTimeFormatSpec = NULL;
static FormatSpecFunc ptrGetLongDateFormatSpec = NULL;
static FormatSpecFunc ptrGetShortDateFormatSpec = NULL;
+static FormatSpecFunc ptrRefreshLocaleInfo = NULL;
// Default functions if functions cannot be resolved
static void defaultTimeFormatL(TTime&, TDes& des, const TDesC&, const TLocale&)
@@ -214,6 +299,8 @@ static const char *jp_locale_dep[] = {
*/
static QString s60ToQtFormat(const QString &sys_fmt)
{
+ RDebug::Print(_L("Time Format \"%S\""), &timeFormat);
+
TLocale *locale = _s60Locale.GetLocale();
QString result;
@@ -679,6 +766,8 @@ static QString symbianDateFormat(bool short_format)
dateFormat.Set(ptrGetLongDateFormatSpec(_s60Locale));
}
+ RDebug::Print(_L("symDateFormat: \"%S\""), &dateFormat);
+
return s60ToQtFormat(qt_TDesC2QString(dateFormat));
}
@@ -688,6 +777,8 @@ static QString symbianDateFormat(bool short_format)
*/
static QString symbianTimeFormat()
{
+ TPtrC timeFormat = ptrGetTimeFormatSpec(_s60Locale);
+ RDebug::Print(_L("symTimeFormat: \"%S\""), &timeFormat);
return s60ToQtFormat(qt_TDesC2QString(ptrGetTimeFormatSpec(_s60Locale)));
}
@@ -771,22 +862,35 @@ static QLocale::MeasurementSystem symbianMeasurementSystem()
return QLocale::MetricSystem;
}
-QLocale QSystemLocale::fallbackLocale() const
+void symbianUpdateSystemPrivate()
{
+ RDebug::Print(_L("symbianUpdateSystemPrivate"));
// load system data before query calls
+ _s60Locale.LoadSystemSettings();
+ if (ptrRefreshLocaleInfo)
+ ptrRefreshLocaleInfo();
+}
+
+void symbianInitSystemLocale()
+{
+ RDebug::Print(_L("symbianInitSystemLocale"));
static QBasicAtomicInt initDone = Q_BASIC_ATOMIC_INITIALIZER(0);
if (initDone.testAndSetRelaxed(0, 1)) {
- _s60Locale.LoadSystemSettings();
+ if (!qt_changeNotifier) {
+ QMetaObject::invokeMethod(qApp, SLOT(_q_symbianRegisterLocaleNotifier()), Qt::AutoConnection);
+ }
// Initialize platform version dependent function pointers
ptrTimeFormatL = reinterpret_cast<FormatFunc>
- (qt_resolveS60PluginFunc(S60Plugin_TimeFormatL));
+ (qt_resolveS60PluginFunc(S60Plugin_TimeFormatL));
ptrGetTimeFormatSpec = reinterpret_cast<FormatSpecFunc>
- (qt_resolveS60PluginFunc(S60Plugin_GetTimeFormatSpec));
+ (qt_resolveS60PluginFunc(S60Plugin_GetTimeFormatSpec));
ptrGetLongDateFormatSpec = reinterpret_cast<FormatSpecFunc>
- (qt_resolveS60PluginFunc(S60Plugin_GetLongDateFormatSpec));
+ (qt_resolveS60PluginFunc(S60Plugin_GetLongDateFormatSpec));
ptrGetShortDateFormatSpec = reinterpret_cast<FormatSpecFunc>
- (qt_resolveS60PluginFunc(S60Plugin_GetShortDateFormatSpec));
+ (qt_resolveS60PluginFunc(S60Plugin_GetShortDateFormatSpec));
+ ptrRefreshLocaleInfo = reinterpret_cast<FormatSpecFunc>
+ (qt_resolveS60PluginFunc(S60Plugin_RefreshLocaleInfo));
if (!ptrTimeFormatL)
ptrTimeFormatL = &defaultTimeFormatL;
if (!ptrGetTimeFormatSpec)
@@ -801,7 +905,10 @@ QLocale QSystemLocale::fallbackLocale() const
}
while(initDone != 2)
QThread::yieldCurrentThread();
+}
+QLocale QSystemLocale::fallbackLocale() const
+{
TLanguage lang = User::Language();
QString locale = QLatin1String(qt_symbianLocaleName(lang));
return QLocale(locale);
diff --git a/src/plugins/s60/src/qlocale_3_1.cpp b/src/plugins/s60/src/qlocale_3_1.cpp
index beeee7f..d597861 100644
--- a/src/plugins/s60/src/qlocale_3_1.cpp
+++ b/src/plugins/s60/src/qlocale_3_1.cpp
@@ -50,6 +50,7 @@ _LIT(KLocaleIndependent, "%F");
static TBuf<10> dateFormat;
static TBuf<10> timeFormat;
+#define _DEBUG
static void initialiseDateFormat()
{
if(dateFormat.Length())
@@ -146,3 +147,10 @@ EXPORT_C TPtrC defaultGetShortDateFormatSpec(TExtendedLocale&)
initialiseDateFormat();
return TPtrC(dateFormat);
}
+
+EXPORT_C void refreshLocaleInfo()
+{
+ // clear the buffers, so next time we re-read data from the system.
+ dateFormat.Zero();
+ timeFormat.Zero();
+}