From e4c60e6b8d111c6214d8ee47b8c2bb8b9f8fcfe2 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 21 Apr 2010 14:56:40 +0200 Subject: Support updating system locale data on Symbian Subscribing to the locale change notification to be able to update the system locale whenever the user changes the current system locale. Task-number: QTBUG-4870 Reviewed-by: Thomas Zander Reviewed-by: Jason Barron --- mkspecs/common/symbian/symbian.conf | 2 +- src/corelib/kernel/qcoreapplication.cpp | 13 ++++++ src/corelib/kernel/qcoreapplication_p.h | 7 ++++ src/corelib/kernel/qeventdispatcher_symbian.cpp | 2 + src/corelib/kernel/qeventdispatcher_symbian_p.h | 1 + src/corelib/tools/qlocale.cpp | 12 ++++++ src/corelib/tools/qlocale_p.h | 18 +++++++++ src/corelib/tools/qlocale_symbian.cpp | 53 +++++++++++++++++++++++-- src/gui/kernel/qapplication.cpp | 4 ++ 9 files changed, 107 insertions(+), 5 deletions(-) diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 0bd0bf2..89034ca 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -66,7 +66,7 @@ QMAKE_LINK_OBJECT_MAX = QMAKE_LINK_OBJECT_SCRIPT= QMAKE_LIBS = -llibc -llibm -leuser -llibdl -QMAKE_LIBS_CORE = $$QMAKE_LIBS -lefsrv -lhal +QMAKE_LIBS_CORE = $$QMAKE_LIBS -lefsrv -lhal -lbafl QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE -lfbscli -lbitgdi -lgdi -lws32 -lapgrfx -lcone -leikcore -lmediaclientaudio -leikcoctl -leiksrv -lapparc -lcentralrepository QMAKE_LIBS_NETWORK = QMAKE_LIBS_EGL = -llibEGL diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index bf2e2e4..f44fe99 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -63,6 +63,7 @@ #include #include #include +#include #ifdef Q_OS_SYMBIAN # include @@ -521,6 +522,9 @@ QCoreApplication::QCoreApplication(int &argc, char **argv) QFactoryLoader::refreshAll(); #endif +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) + d_func()->symbianInit(); +#endif } // ### move to QCoreApplicationPrivate constructor? @@ -597,6 +601,15 @@ void QCoreApplication::init() qt_startup_hook(); } +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) +void QCoreApplicationPrivate::symbianInit() +{ + if (!environmentChangeNotifier) + environmentChangeNotifier.reset(new QEnvironmentChangeNotifier); +} +#endif + + /*! Destroys the QCoreApplication object. */ diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 77188d3..e066137 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -65,6 +65,9 @@ QT_BEGIN_NAMESPACE typedef QList QTranslatorList; +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) +class QEnvironmentChangeNotifier; +#endif class QAbstractEventDispatcher; class Q_CORE_EXPORT QCoreApplicationPrivate : public QObjectPrivate @@ -113,6 +116,10 @@ public: bool aboutToQuitEmitted; QString cachedApplicationDirPath; QString cachedApplicationFilePath; +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) + QScopedPointer environmentChangeNotifier; + void symbianInit(); +#endif static bool isTranslatorInstalled(QTranslator *translator); diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index a6d486e..687a6d9 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -1105,3 +1105,5 @@ void CQtActiveScheduler::Error(TInt aError) const } QT_END_NAMESPACE + +#include "moc_qeventdispatcher_symbian_p.cpp" diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h index 05758ca..bc42753 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian_p.h +++ b/src/corelib/kernel/qeventdispatcher_symbian_p.h @@ -221,6 +221,7 @@ public: // from CActiveScheduler class Q_CORE_EXPORT QEventDispatcherSymbian : public QAbstractEventDispatcher { + Q_OBJECT Q_DECLARE_PRIVATE(QAbstractEventDispatcher) public: diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index c3f6783..20c2e27 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -129,6 +129,11 @@ inline bool isascii(int c) } #endif +#if defined(Q_OS_SYMBIAN) +void qt_symbianUpdateSystemPrivate(); +void qt_symbianInitSystemLocale(); +#endif + /****************************************************************************** ** Helpers for accessing Qt locale database */ @@ -1407,6 +1412,9 @@ static const QSystemLocale *systemLocale() { if (_systemLocale) return _systemLocale; +#if defined(Q_OS_SYMBIAN) + qt_symbianInitSystemLocale(); +#endif return QSystemLocale_globalSystemLocale(); } @@ -1417,6 +1425,10 @@ void QLocalePrivate::updateSystemPrivate() system_lp = globalLocalePrivate(); *system_lp = *sys_locale->fallbackLocale().d(); +#if defined(Q_OS_SYMBIAN) + qt_symbianUpdateSystemPrivate(); +#endif + QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant()); if (!res.isNull()) system_lp->m_language_id = res.toInt(); diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h index ecf79e9..6205745 100644 --- a/src/corelib/tools/qlocale_p.h +++ b/src/corelib/tools/qlocale_p.h @@ -58,6 +58,10 @@ #include "qlocale.h" +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) +class CEnvironmentChangeNotifier; +#endif + QT_BEGIN_NAMESPACE struct Q_CORE_EXPORT QLocalePrivate @@ -201,6 +205,20 @@ inline char QLocalePrivate::digitToCLocale(const QChar &in) const return 0; } +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) +class QEnvironmentChangeNotifier +{ +public: + QEnvironmentChangeNotifier(); + ~QEnvironmentChangeNotifier(); + + static TInt localeChanged(TAny *data); + +private: + CEnvironmentChangeNotifier *iChangeNotifier; +}; +#endif + QT_END_NAMESPACE #endif // QLOCALE_P_H diff --git a/src/corelib/tools/qlocale_symbian.cpp b/src/corelib/tools/qlocale_symbian.cpp index 01f56cc..6e36dcd 100644 --- a/src/corelib/tools/qlocale_symbian.cpp +++ b/src/corelib/tools/qlocale_symbian.cpp @@ -46,8 +46,14 @@ #include #include +#include +#include +#include +#include #include "private/qcore_symbian_p.h" - +#include "private/qcoreapplication_p.h" +#include "private/qlocale_p.h" +#include QT_BEGIN_NAMESPACE @@ -771,13 +777,18 @@ static QLocale::MeasurementSystem symbianMeasurementSystem() return QLocale::MetricSystem; } -QLocale QSystemLocale::fallbackLocale() const +void qt_symbianUpdateSystemPrivate() { // load system data before query calls + _s60Locale.LoadSystemSettings(); +} + +void qt_symbianInitSystemLocale() +{ static QBasicAtomicInt initDone = Q_BASIC_ATOMIC_INITIALIZER(0); + if (initDone == 2) + return; if (initDone.testAndSetRelaxed(0, 1)) { - _s60Locale.LoadSystemSettings(); - // Initialize platform version dependent function pointers ptrTimeFormatL = reinterpret_cast (qt_resolveS60PluginFunc(S60Plugin_TimeFormatL)); @@ -801,7 +812,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); @@ -884,4 +898,35 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const return QVariant(); } +#if !defined(QT_NO_SYSTEMLOCALE) +QEnvironmentChangeNotifier::QEnvironmentChangeNotifier() +{ + // Create the change notifier and install the callback function + const TCallBack callback(&QEnvironmentChangeNotifier::localeChanged, this); + QT_TRAP_THROWING(iChangeNotifier = CEnvironmentChangeNotifier::NewL(CActive::EPriorityStandard, callback)); + iChangeNotifier->Start(); +} + +TInt QEnvironmentChangeNotifier::localeChanged(TAny *data) +{ + QEnvironmentChangeNotifier *that = reinterpret_cast(data); + + TInt flag = that->iChangeNotifier->Change(); + if (flag & EChangesLocale) { + static bool first = true; + if (!first) { // skip the first notification on app startup + QT_TRYCATCH_LEAVING(QLocalePrivate::updateSystemPrivate()); + QT_TRYCATCH_LEAVING(QCoreApplication::postEvent(qApp, new QEvent(QEvent::LocaleChange))); + } + first = false; + } + return KErrNone; +} + +QEnvironmentChangeNotifier::~QEnvironmentChangeNotifier() +{ + delete iChangeNotifier; +} +#endif + QT_END_NAMESPACE diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index ec635d4..bc58c76 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -788,6 +788,10 @@ void QApplicationPrivate::construct( qt_gui_eval_init(application_type); #endif +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) + symbianInit(); +#endif + #ifndef QT_NO_LIBRARY if(load_testability) { QLibrary testLib(QLatin1String("qttestability")); -- cgit v0.12