From e0d752884e2e0923540373315198d27557c4364c Mon Sep 17 00:00:00 2001
From: dka <darpan.k-a@nokia.com>
Date: Mon, 12 Oct 2009 16:25:23 +0300
Subject: [PATCH] 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.

Modified-by: axis
Modified-by: Denis Dzyubenko

Reviewed-by: Denis Dzyubenko
Reviewed-by: axis
---
 src/corelib/kernel/qcoreapplication.cpp |   11 ++++
 src/corelib/kernel/qcoreapplication.h   |    4 ++
 src/corelib/kernel/qcoreapplication_p.h |    4 ++
 src/corelib/tools/qlocale_p.h           |    3 +
 src/corelib/tools/qlocale_symbian.cpp   |   82 +++++++++++++++++++++++++++++++
 5 files changed, 104 insertions(+), 0 deletions(-)

diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 8a55bad..0f3a59d 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,14 @@ int QCoreApplication::loopLevel()
     \sa Q_OBJECT, QObject::tr(), QObject::trUtf8()
 */
 
+#if defined(Q_OS_SYMBIAN)
+void QCoreApplicationPrivate::_q_symbianUpdateLocale()
+{
+    QLocalePrivate::symbianUpdateLocale();
+}
+
+#endif
+
 QT_END_NAMESPACE
+
+#include "moc_qcoreapplication.cpp"
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index 097b8b4..8bdf11b 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_symbianUpdateLocale())
+#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..cca99f3 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_symbianUpdateLocale();
+#endif
 };
 
 QT_END_NAMESPACE
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 0123a6e..b0a9570 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -133,6 +133,9 @@ public:
     inline char digitToCLocale(const QChar &c) const;
 
     static void updateSystemPrivate();
+#if defined(Q_OS_SYMBIAN)
+    static void symbianUpdateLocale();
+#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 1660e95..aad2501 100644
--- a/src/corelib/tools/qlocale_symbian.cpp
+++ b/src/corelib/tools/qlocale_symbian.cpp
@@ -46,11 +46,88 @@
 #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"
 
 
 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(0)
+{
+}
+
+
+CLocaleChangeNotifier::~CLocaleChangeNotifier()
+{
+    Cancel();
+    changeNotifier.Close();
+}
+
+void CLocaleChangeNotifier::ConstructL()
+{
+    changeNotifier.Create();
+    CActiveScheduler::Add(this);
+    SetActive();
+}
+
+void CLocaleChangeNotifier::DoCancel()
+{
+    changeNotifier.LogonCancel();
+}
+
+void CLocaleChangeNotifier::RunL()
+{
+    SetActive();
+    changeNotifier.Logon(iStatus);
+    if (iStatus.Int() == EChangesLocale) {
+        QT_TRYCATCH_LEAVING(QLocalePrivate::updateSystemPrivate());
+    }
+}
+
+static void qt_cleanupLocaleNotifier()
+{
+    delete qt_changeNotifier;
+    qt_changeNotifier = NULL;
+}
+
+void QLocalePrivate::symbianUpdateLocale()
+{
+    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);
 
@@ -778,6 +855,11 @@ QLocale QSystemLocale::fallbackLocale() const
     if (initDone.testAndSetRelaxed(0, 1)) {
         _s60Locale.LoadSystemSettings();
 
+        if (!qt_changeNotifier) {
+            QMetaObject::invokeMethod(qApp, SLOT(_q_symbianUpdateLocale()), Qt::AutoConnection);
+            QLocalePrivate::updateSystemPrivate();
+        }
+
         // Initialize platform version dependent function pointers
         ptrTimeFormatL = reinterpret_cast<FormatFunc>
             (qt_resolveS60PluginFunc(S60Plugin_TimeFormatL));
-- 
1.6.2.1.307.g91408

