summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2010-05-18 04:09:47 (GMT)
committerAndrew den Exter <andrew.den-exter@nokia.com>2010-05-18 04:09:47 (GMT)
commit183afaf48fdaeeacde009cd3f497152f89d8e0af (patch)
treee6fcc88a20e8af694c7c5020b2050c76add26de7 /src/corelib
parentcb03c8cad2a40272c9cc8d0998246fb74a49e671 (diff)
parent379b4dc81177b95c15de30c5925efca1136e4041 (diff)
downloadQt-183afaf48fdaeeacde009cd3f497152f89d8e0af.zip
Qt-183afaf48fdaeeacde009cd3f497152f89d8e0af.tar.gz
Qt-183afaf48fdaeeacde009cd3f497152f89d8e0af.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt into 4.7
Conflicts: configure.exe src/imports/multimedia/qdeclarativeaudio.cpp src/imports/multimedia/qdeclarativeaudio_p.h src/multimedia/mediaservices/mediaservices.pro src/plugins/mediaservices/mediaservices.pro src/plugins/mediaservices/symbian/mediaplayer/s60audioplayersession.h src/plugins/mediaservices/symbian/mediaplayer/s60videoplayersession.h src/s60installs/s60installs.pro src/src.pro
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/animation/qabstractanimation.cpp3
-rw-r--r--src/corelib/io/qfilesystemwatcher_symbian.cpp63
-rw-r--r--src/corelib/io/qfilesystemwatcher_symbian_p.h6
-rw-r--r--src/corelib/io/qiodevice.cpp3
-rw-r--r--src/corelib/io/qurl.cpp6
-rw-r--r--src/corelib/kernel/qabstractitemmodel.cpp56
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp13
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h7
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp2
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian_p.h1
-rw-r--r--src/corelib/tools/qchar.cpp31
-rw-r--r--src/corelib/tools/qchar.h9
-rw-r--r--src/corelib/tools/qdatetime.cpp44
-rw-r--r--src/corelib/tools/qdatetime.h1
-rw-r--r--src/corelib/tools/qlocale.cpp12
-rw-r--r--src/corelib/tools/qlocale_p.h18
-rw-r--r--src/corelib/tools/qlocale_symbian.cpp53
-rw-r--r--src/corelib/tools/qmap.h20
18 files changed, 289 insertions, 59 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index 01570ad..04342e7 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -369,6 +369,9 @@ void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState)
if (state == newState)
return;
+ if (loopCount == 0)
+ return;
+
QAbstractAnimation::State oldState = state;
int oldCurrentTime = currentTime;
int oldCurrentLoop = currentLoop;
diff --git a/src/corelib/io/qfilesystemwatcher_symbian.cpp b/src/corelib/io/qfilesystemwatcher_symbian.cpp
index 69daae7..6136742 100644
--- a/src/corelib/io/qfilesystemwatcher_symbian.cpp
+++ b/src/corelib/io/qfilesystemwatcher_symbian.cpp
@@ -106,7 +106,7 @@ void QNotifyChangeEvent::DoCancel()
}
QSymbianFileSystemWatcherEngine::QSymbianFileSystemWatcherEngine() :
- errorCode(KErrNone), watcherStarted(false)
+ watcherStarted(false)
{
moveToThread(this);
}
@@ -122,11 +122,7 @@ QStringList QSymbianFileSystemWatcherEngine::addPaths(const QStringList &paths,
QMutexLocker locker(&mutex);
QStringList p = paths;
- if (!startWatcher()) {
- qWarning("Could not start QSymbianFileSystemWatcherEngine thread");
-
- return p;
- }
+ startWatcher();
QMutableListIterator<QString> it(p);
while (it.hasNext()) {
@@ -150,18 +146,17 @@ QStringList QSymbianFileSystemWatcherEngine::addPaths(const QStringList &paths,
filePath += QChar(L'/');
}
- currentEvent = NULL;
+ currentAddEvent = NULL;
QMetaObject::invokeMethod(this,
"addNativeListener",
Qt::QueuedConnection,
Q_ARG(QString, filePath));
syncCondition.wait(&mutex);
+ if (currentAddEvent) {
+ currentAddEvent->isDir = isDir;
- if (currentEvent) {
- currentEvent->isDir = isDir;
-
- activeObjectToPath.insert(currentEvent, path);
+ activeObjectToPath.insert(currentAddEvent, path);
it.remove();
if (isDir)
@@ -185,10 +180,10 @@ QStringList QSymbianFileSystemWatcherEngine::removePaths(const QStringList &path
while (it.hasNext()) {
QString path = it.next();
- currentEvent = activeObjectToPath.key(path);
- if (!currentEvent)
+ currentRemoveEvent = activeObjectToPath.key(path);
+ if (!currentRemoveEvent)
continue;
- activeObjectToPath.remove(currentEvent);
+ activeObjectToPath.remove(currentRemoveEvent);
QMetaObject::invokeMethod(this,
"removeNativeListener",
@@ -202,9 +197,6 @@ QStringList QSymbianFileSystemWatcherEngine::removePaths(const QStringList &path
directories->removeAll(path);
}
- if (activeObjectToPath.size() == 0)
- stop();
-
return p;
}
@@ -228,44 +220,31 @@ void QSymbianFileSystemWatcherEngine::stop()
}
// This method must be called inside mutex
-bool QSymbianFileSystemWatcherEngine::startWatcher()
+void QSymbianFileSystemWatcherEngine::startWatcher()
{
- bool retval = true;
-
if (!watcherStarted) {
setStackSize(0x5000);
start();
syncCondition.wait(&mutex);
-
- if (errorCode != KErrNone) {
- retval = false;
- } else {
- watcherStarted = true;
- }
+ watcherStarted = true;
}
- return retval;
}
void QSymbianFileSystemWatcherEngine::run()
{
- // Initialize file session
-
mutex.lock();
syncCondition.wakeOne();
mutex.unlock();
- if (errorCode == KErrNone) {
- exec();
+ exec();
- foreach(QNotifyChangeEvent *e, activeObjectToPath.keys()) {
- e->Cancel();
- delete e;
- }
-
- activeObjectToPath.clear();
- watcherStarted = false;
+ foreach(QNotifyChangeEvent *e, activeObjectToPath.keys()) {
+ e->Cancel();
+ delete e;
}
+
+ activeObjectToPath.clear();
}
void QSymbianFileSystemWatcherEngine::addNativeListener(const QString &directoryPath)
@@ -273,16 +252,16 @@ void QSymbianFileSystemWatcherEngine::addNativeListener(const QString &directory
QMutexLocker locker(&mutex);
QString nativeDir(QDir::toNativeSeparators(directoryPath));
TPtrC ptr(qt_QString2TPtrC(nativeDir));
- currentEvent = new QNotifyChangeEvent(qt_s60GetRFs(), ptr, this, directoryPath.endsWith(QChar(L'/'), Qt::CaseSensitive));
+ currentAddEvent = new QNotifyChangeEvent(qt_s60GetRFs(), ptr, this, directoryPath.endsWith(QChar(L'/'), Qt::CaseSensitive));
syncCondition.wakeOne();
}
void QSymbianFileSystemWatcherEngine::removeNativeListener()
{
QMutexLocker locker(&mutex);
- currentEvent->Cancel();
- delete currentEvent;
- currentEvent = NULL;
+ currentRemoveEvent->Cancel();
+ delete currentRemoveEvent;
+ currentRemoveEvent = NULL;
syncCondition.wakeOne();
}
diff --git a/src/corelib/io/qfilesystemwatcher_symbian_p.h b/src/corelib/io/qfilesystemwatcher_symbian_p.h
index 7e3f045..e687a4a 100644
--- a/src/corelib/io/qfilesystemwatcher_symbian_p.h
+++ b/src/corelib/io/qfilesystemwatcher_symbian_p.h
@@ -113,14 +113,14 @@ private:
friend class QNotifyChangeEvent;
void emitPathChanged(QNotifyChangeEvent *e);
- bool startWatcher();
+ void startWatcher();
QHash<QNotifyChangeEvent*, QString> activeObjectToPath;
QMutex mutex;
QWaitCondition syncCondition;
- int errorCode;
bool watcherStarted;
- QNotifyChangeEvent *currentEvent;
+ QNotifyChangeEvent *currentAddEvent;
+ QNotifyChangeEvent *currentRemoveEvent;
};
#endif // QT_NO_FILESYSTEMWATCHER
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index bb11d6b..223df9b 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -810,6 +810,9 @@ qint64 QIODevice::read(char *data, qint64 maxSize)
}
}
+ if (!maxSize)
+ return readSoFar;
+
if ((d->openMode & Unbuffered) == 0 && maxSize < QIODEVICE_BUFFERSIZE) {
// In buffered mode, we try to fill up the QIODevice buffer before
// we do anything else.
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 4e580dd..d4b8b5f 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -5557,6 +5557,12 @@ QUrl QUrl::resolved(const QUrl &relative) const
removeDotsFromPath(&t.d->encodedPath);
t.d->path.clear();
+#if defined(QURL_DEBUG)
+ qDebug("QUrl(\"%s\").resolved(\"%s\") = \"%s\"",
+ toEncoded().constData(),
+ relative.toEncoded().constData(),
+ t.toEncoded().constData());
+#endif
return t;
}
diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp
index b0503be..3660a3c 100644
--- a/src/corelib/kernel/qabstractitemmodel.cpp
+++ b/src/corelib/kernel/qabstractitemmodel.cpp
@@ -2530,6 +2530,62 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
condition is true, in which case you should abort your move
operation.
+ \table 80%
+ \row
+ \o \inlineimage modelview-move-rows-1.png Moving rows to another parent
+ \o Specify the first and last row numbers for the span of rows in
+ the source parent you want to move in the model. Also specify
+ the row in the destination parent to move the span to.
+
+ For example, as shown in the diagram, we move three rows from
+ row 2 to 4 in the source, so \a sourceFirst is 2 and \a sourceLast is 4.
+ We move those items to above row 2 in the destination, so \a destinationRow is 2.
+
+ \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 6
+
+ This moves the three rows rows 2, 3, and 4 in the source to become 2, 3 and 4 in
+ the destination. Other affected siblings are displaced accordingly.
+ \row
+ \o \inlineimage modelview-move-rows-2.png Moving rows to append to another parent
+ \o To append rows to another parent, move them to after the last row.
+
+ For example, as shown in the diagram, we move three rows to a
+ collection of 6 existing rows (ending in row 5), so \a destinationStart is 6:
+
+ \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 7
+
+ This moves the target rows to the end of the target parent as 6, 7 and 8.
+ \row
+ \o \inlineimage modelview-move-rows-3.png Moving rows in the same parent up
+ \o To move rows within the same parent, specify the row to move them to.
+
+ For example, as shown in the diagram, we move one item from row 2 to row 0,
+ so \a sourceFirst and \a sourceLast are 2 and \a destinationChild is 0.
+
+ \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 8
+
+ Note that other rows may be displaced accordingly. Note also that when moving
+ items within the same parent you should not attempt invalid or no-op moves. In
+ the above example, item 2 is at row 2 before the move, so it can not be moved
+ to row 2 (where it is already) or row 3 (no-op as row 3 means above row 3, where
+ it is already)
+
+ \row
+ \o \inlineimage modelview-move-rows-4.png Moving rows in the same parent down
+ \o To move rows within the same parent, specify the row to move them to.
+
+ For example, as shown in the diagram, we move one item from row 2 to row 4,
+ so \a sourceFirst and \a sourceLast are 2 and \a destinationChild is 4.
+
+ \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 9
+
+ Note that other rows may be displaced accordingly.
+ \endtable
+
+ \note This function emits the rowsAboutToBeInserted() signal which
+ connected views (or proxies) must handle before the data is inserted.
+ Otherwise, the views may end up in an invalid state.
+
\sa endMoveRows()
\since 4.6
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 609e6b3..4e6e6b9 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -63,6 +63,7 @@
#include <qvarlengtharray.h>
#include <private/qfactoryloader_p.h>
#include <private/qfunctions_p.h>
+#include <private/qlocale_p.h>
#ifdef Q_OS_SYMBIAN
# include <exception>
@@ -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<QTranslator*> 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<QEnvironmentChangeNotifier> 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/qchar.cpp b/src/corelib/tools/qchar.cpp
index 67ea00d..2f09b0e 100644
--- a/src/corelib/tools/qchar.cpp
+++ b/src/corelib/tools/qchar.cpp
@@ -653,14 +653,41 @@ bool QChar::isSymbol() const
\fn bool QChar::isHighSurrogate() const
Returns true if the QChar is the high part of a utf16 surrogate
- (ie. if its code point is between 0xd800 and 0xdbff).
+ (ie. if its code point is between 0xd800 and 0xdbff, inclusive).
*/
/*!
\fn bool QChar::isLowSurrogate() const
Returns true if the QChar is the low part of a utf16 surrogate
- (ie. if its code point is between 0xdc00 and 0xdfff).
+ (ie. if its code point is between 0xdc00 and 0xdfff, inclusive).
+*/
+
+/*!
+ \fn static bool QChar::isHighSurrogate(uint ucs4)
+ \since 4.7
+
+ Returns true if the UCS-4-encoded character specified by \a ucs4
+ is the high part of a utf16 surrogate
+ (ie. if its code point is between 0xd800 and 0xdbff, inclusive).
+*/
+
+/*!
+ \fn static bool QChar::isLowSurrogate(uint ucs4)
+ \since 4.7
+
+ Returns true if the UCS-4-encoded character specified by \a ucs4
+ is the high part of a utf16 surrogate
+ (ie. if its code point is between 0xdc00 and 0xdfff, inclusive).
+*/
+
+/*!
+ \fn static bool QChar::requiresSurrogates(uint ucs4)
+ \since 4.7
+
+ Returns true if the UCS-4-encoded character specified by \a ucs4
+ can be splited to the high and low parts of a utf16 surrogate
+ (ie. if its code point is greater than or equals to 0x10000).
*/
/*!
diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h
index 1432c7f..205f911 100644
--- a/src/corelib/tools/qchar.h
+++ b/src/corelib/tools/qchar.h
@@ -285,6 +285,15 @@ public:
inline void setCell(uchar cell);
inline void setRow(uchar row);
+ static inline bool isHighSurrogate(uint ucs4) {
+ return ((ucs4 & 0xfffffc00) == 0xd800);
+ }
+ static inline bool isLowSurrogate(uint ucs4) {
+ return ((ucs4 & 0xfffffc00) == 0xdc00);
+ }
+ static inline bool requiresSurrogates(uint ucs4) {
+ return (ucs4 >= 0x10000);
+ }
static inline uint surrogateToUcs4(ushort high, ushort low) {
return (uint(high)<<10) + low - 0x35fdc00;
}
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 9afcd80..9f5d8c6 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -1705,7 +1705,7 @@ int QTime::secsTo(const QTime &t) const
Note that the time will wrap if it passes midnight. See addSecs()
for an example.
- \sa addSecs(), msecsTo()
+ \sa addSecs(), msecsTo(), QDateTime::addMSecs()
*/
QTime QTime::addMSecs(int ms) const
@@ -1734,7 +1734,7 @@ QTime QTime::addMSecs(int ms) const
seconds in a day, the result is always between -86400000 and
86400000 ms.
- \sa secsTo(), addMSecs()
+ \sa secsTo(), addMSecs(), QDateTime::msecsTo()
*/
int QTime::msecsTo(const QTime &t) const
@@ -2042,10 +2042,11 @@ int QTime::elapsed() const
later.
You can increment (or decrement) a datetime by a given number of
- seconds using addSecs(), or days using addDays(). Similarly you can
- use addMonths() and addYears(). The daysTo() function returns the
- number of days between two datetimes, and secsTo() returns the
- number of seconds between two datetimes.
+ milliseconds using addMSecs(), seconds using addSecs(), or days
+ using addDays(). Similarly you can use addMonths() and addYears().
+ The daysTo() function returns the number of days between two datetimes,
+ secsTo() returns the number of seconds between two datetimes, and
+ msecsTo() returns the number of milliseconds between two datetimes.
QDateTime can store datetimes as \l{Qt::LocalTime}{local time} or
as \l{Qt::UTC}{UTC}. QDateTime::currentDateTime() returns a
@@ -2719,7 +2720,7 @@ QDateTime QDateTime::addSecs(int s) const
later than the datetime of this object (or earlier if \a msecs is
negative).
- \sa addSecs(), secsTo(), addDays(), addMonths(), addYears()
+ \sa addSecs(), msecsTo(), addDays(), addMonths(), addYears()
*/
QDateTime QDateTime::addMSecs(qint64 msecs) const
{
@@ -2731,7 +2732,7 @@ QDateTime QDateTime::addMSecs(qint64 msecs) const
datetime. If the \a other datetime is earlier than this datetime,
the value returned is negative.
- \sa addDays(), secsTo()
+ \sa addDays(), secsTo(), msecsTo()
*/
int QDateTime::daysTo(const QDateTime &other) const
@@ -2766,6 +2767,33 @@ int QDateTime::secsTo(const QDateTime &other) const
}
/*!
+ Returns the number of milliseconds from this datetime to the \a other
+ datetime. If the \a other datetime is earlier than this datetime,
+ the value returned is negative.
+
+ Before performing the comparison, the two datetimes are converted
+ to Qt::UTC to ensure that the result is correct if one of the two
+ datetimes has daylight saving time (DST) and the other doesn't.
+
+ \sa addMSecs(), daysTo(), QTime::msecsTo()
+*/
+
+qint64 QDateTime::msecsTo(const QDateTime &other) const
+{
+ QDate selfDate;
+ QDate otherDate;
+ QTime selfTime;
+ QTime otherTime;
+
+ d->getUTC(selfDate, selfTime);
+ other.d->getUTC(otherDate, otherTime);
+
+ return (static_cast<qint64>(selfDate.daysTo(otherDate)) * static_cast<qint64>(MSECS_PER_DAY))
+ + static_cast<qint64>(selfTime.msecsTo(otherTime));
+}
+
+
+/*!
\fn QDateTime QDateTime::toTimeSpec(Qt::TimeSpec specification) const
Returns a copy of this datetime configured to use the given time
diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h
index f445f1c..2466aeb 100644
--- a/src/corelib/tools/qdatetime.h
+++ b/src/corelib/tools/qdatetime.h
@@ -251,6 +251,7 @@ public:
inline QDateTime toUTC() const { return toTimeSpec(Qt::UTC); }
int daysTo(const QDateTime &) const;
int secsTo(const QDateTime &) const;
+ qint64 msecsTo(const QDateTime &) const;
bool operator==(const QDateTime &other) const;
inline bool operator!=(const QDateTime &other) const { return !(*this == other); }
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 <QThread>
#include <e32std.h>
+#include <e32const.h>
+#include <e32base.h>
+#include <e32property.h>
+#include <bacntf.h>
#include "private/qcore_symbian_p.h"
-
+#include "private/qcoreapplication_p.h"
+#include "private/qlocale_p.h"
+#include <qdebug.h>
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<FormatFunc>
(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<QEnvironmentChangeNotifier *>(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/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index df0ae46..5696ba6 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -125,6 +125,10 @@ template <class Key, class T>
struct QMapNode {
Key key;
T value;
+
+private:
+ // never access these members through this structure.
+ // see below
QMapData::Node *backward;
QMapData::Node *forward[1];
};
@@ -134,6 +138,22 @@ struct QMapPayloadNode
{
Key key;
T value;
+
+private:
+ // QMap::e is a pointer to QMapData::Node, which matches the member
+ // below. However, the memory allocation node in QMapData::node_create
+ // allocates sizeof(QMapPayloNode) and incorrectly calculates the offset
+ // of 'backward' below. If the alignment of QMapPayloadNode is larger
+ // than the alignment of a pointer, the 'backward' member is aligned to
+ // the end of this structure, not to 'value' above, and will occupy the
+ // tail-padding area.
+ //
+ // e.g., on a 32-bit archictecture with Key = int and
+ // sizeof(T) = alignof(T) = 8
+ // 0 4 8 12 16 20 24 byte
+ // | key | PAD | value |backward| PAD | correct layout
+ // | key | PAD | value | |backward| how it's actually used
+ // |<----- value of QMap::payload() = 20 ----->|
QMapData::Node *backward;
};