diff options
author | Sami Merila <sami.merila@nokia.com> | 2011-09-28 12:49:27 (GMT) |
---|---|---|
committer | Sami Merila <sami.merila@nokia.com> | 2011-09-28 12:49:27 (GMT) |
commit | 8f872c92e44ada010afea6f828f109dc2f4feb51 (patch) | |
tree | fe0d64e2036291096cdbee93e163b3bfc22290a7 | |
parent | ed9e0cae2e99d16a311727873ff349b45bd61d13 (diff) | |
parent | a01fe35b0a9d63e5d51389213a866a81830f0f9e (diff) | |
download | Qt-8f872c92e44ada010afea6f828f109dc2f4feb51.zip Qt-8f872c92e44ada010afea6f828f109dc2f4feb51.tar.gz Qt-8f872c92e44ada010afea6f828f109dc2f4feb51.tar.bz2 |
Merge branch 'master' of scm.dev.nokia.troll.no:qt/qt-symbian-team
-rw-r--r-- | src/corelib/io/qfilesystemwatcher_symbian.cpp | 10 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemwatcher_symbian_p.h | 18 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 75 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication_p.h | 3 | ||||
-rw-r--r-- | src/corelib/plugin/qfactoryloader.cpp | 239 | ||||
-rw-r--r-- | src/corelib/plugin/qfactoryloader_p.h | 1 | ||||
-rw-r--r-- | src/s60installs/bwins/QtCoreu.def | 5 | ||||
-rw-r--r-- | src/s60installs/eabi/QtCoreu.def | 2 |
8 files changed, 249 insertions, 104 deletions
diff --git a/src/corelib/io/qfilesystemwatcher_symbian.cpp b/src/corelib/io/qfilesystemwatcher_symbian.cpp index 63cc4f1..fa857c6 100644 --- a/src/corelib/io/qfilesystemwatcher_symbian.cpp +++ b/src/corelib/io/qfilesystemwatcher_symbian.cpp @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE QNotifyChangeEvent::QNotifyChangeEvent(RFs &fs, const TDesC &file, - QSymbianFileSystemWatcherEngine *e, bool aIsDir, + QSymbianFileSystemWatcherInterface *e, bool aIsDir, TInt aPriority) : CActive(aPriority), isDir(aIsDir), @@ -96,9 +96,9 @@ void QNotifyChangeEvent::RunL() if (!failureCount) { int err; - QT_TRYCATCH_ERROR(err, engine->emitPathChanged(this)); + QT_TRYCATCH_ERROR(err, engine->handlePathChanged(this)); if (err != KErrNone) - qWarning("QNotifyChangeEvent::RunL() - emitPathChanged threw exception (Converted error code: %d)", err); + qWarning("QNotifyChangeEvent::RunL() - handlePathChanged threw exception (Converted error code: %d)", err); } } } @@ -203,7 +203,7 @@ QStringList QSymbianFileSystemWatcherEngine::removePaths(const QStringList &path return p; } -void QSymbianFileSystemWatcherEngine::emitPathChanged(QNotifyChangeEvent *e) +void QSymbianFileSystemWatcherEngine::handlePathChanged(QNotifyChangeEvent *e) { QMutexLocker locker(&mutex); @@ -255,7 +255,7 @@ void QSymbianFileSystemWatcherEngine::addNativeListener(const QString &directory QMutexLocker locker(&mutex); QString nativeDir(QDir::toNativeSeparators(directoryPath)); TPtrC ptr(qt_QString2TPtrC(nativeDir)); - currentAddEvent = new QNotifyChangeEvent(qt_s60GetRFs(), ptr, this, directoryPath.endsWith(QChar(L'/'), Qt::CaseSensitive)); + currentAddEvent = q_check_ptr(new QNotifyChangeEvent(qt_s60GetRFs(), ptr, this, directoryPath.endsWith(QChar(L'/')))); syncCondition.wakeOne(); } diff --git a/src/corelib/io/qfilesystemwatcher_symbian_p.h b/src/corelib/io/qfilesystemwatcher_symbian_p.h index 0b317a0..842df80 100644 --- a/src/corelib/io/qfilesystemwatcher_symbian_p.h +++ b/src/corelib/io/qfilesystemwatcher_symbian_p.h @@ -66,29 +66,35 @@ QT_BEGIN_NAMESPACE -class QSymbianFileSystemWatcherEngine; +class QSymbianFileSystemWatcherInterface; class QNotifyChangeEvent : public CActive { public: - QNotifyChangeEvent(RFs &fsSession, const TDesC &file, QSymbianFileSystemWatcherEngine *engine, + QNotifyChangeEvent(RFs &fsSession, const TDesC &file, QSymbianFileSystemWatcherInterface *engine, bool aIsDir, TInt aPriority = EPriorityStandard); ~QNotifyChangeEvent(); bool isDir; + TPath watchedPath; private: void RunL(); void DoCancel(); RFs &fsSession; - TPath watchedPath; - QSymbianFileSystemWatcherEngine *engine; + QSymbianFileSystemWatcherInterface *engine; int failureCount; }; -class QSymbianFileSystemWatcherEngine : public QFileSystemWatcherEngine +class QSymbianFileSystemWatcherInterface +{ +public: + virtual void handlePathChanged(QNotifyChangeEvent *e) = 0; +}; + +class QSymbianFileSystemWatcherEngine : public QFileSystemWatcherEngine, public QSymbianFileSystemWatcherInterface { Q_OBJECT @@ -111,7 +117,7 @@ public Q_SLOTS: private: friend class QNotifyChangeEvent; - void emitPathChanged(QNotifyChangeEvent *e); + void handlePathChanged(QNotifyChangeEvent *e); void startWatcher(); diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index c4a9e40..2eb68f7 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -2329,6 +2329,33 @@ QString QCoreApplication::applicationVersion() #ifndef QT_NO_LIBRARY +#if defined(Q_OS_SYMBIAN) +void qt_symbian_installLibraryPaths(QString installPathPlugins, QStringList& libPaths) +{ + // Add existing path on all drives for relative PluginsPath in Symbian + QString tempPath = installPathPlugins; + if (tempPath.at(tempPath.length() - 1) != QDir::separator()) { + tempPath += QDir::separator(); + } + RFs& fs = qt_s60GetRFs(); + TPtrC tempPathPtr(reinterpret_cast<const TText*> (tempPath.constData())); + // Symbian searches should start from Y:. Fix start drive otherwise TFindFile starts from the session drive + _LIT(KStartDir, "Y:"); + TFileName dirPath(KStartDir); + dirPath.Append(tempPathPtr); + TFindFile finder(fs); + TInt err = finder.FindByDir(tempPathPtr, dirPath); + while (err == KErrNone) { + QString foundDir(reinterpret_cast<const QChar *>(finder.File().Ptr()), + finder.File().Length()); + foundDir = QDir(foundDir).canonicalPath(); + if (!libPaths.contains(foundDir)) + libPaths.append(foundDir); + err = finder.Find(); + } +} +#endif + Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive)) /*! @@ -2361,24 +2388,8 @@ QStringList QCoreApplication::libraryPaths() QStringList *app_libpaths = coreappdata()->app_libpaths = new QStringList; QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath); #if defined(Q_OS_SYMBIAN) - // Add existing path on all drives for relative PluginsPath in Symbian if (installPathPlugins.at(1) != QChar(QLatin1Char(':'))) { - QString tempPath = installPathPlugins; - if (tempPath.at(tempPath.length() - 1) != QDir::separator()) { - tempPath += QDir::separator(); - } - RFs& fs = qt_s60GetRFs(); - TPtrC tempPathPtr(reinterpret_cast<const TText*> (tempPath.constData())); - TFindFile finder(fs); - TInt err = finder.FindByDir(tempPathPtr, tempPathPtr); - while (err == KErrNone) { - QString foundDir(reinterpret_cast<const QChar *>(finder.File().Ptr()), - finder.File().Length()); - foundDir = QDir(foundDir).canonicalPath(); - if (!app_libpaths->contains(foundDir)) - app_libpaths->append(foundDir); - err = finder.Find(); - } + qt_symbian_installLibraryPaths(installPathPlugins, *app_libpaths); } #else if (QFile::exists(installPathPlugins)) { @@ -2493,6 +2504,36 @@ void QCoreApplication::removeLibraryPath(const QString &path) QFactoryLoader::refreshAll(); } +#if defined(Q_OS_SYMBIAN) +void QCoreApplicationPrivate::rebuildInstallLibraryPaths() +{ + // check there is not a single fixed install path + QString nativeInstallPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath); + if (nativeInstallPathPlugins.at(1) == QChar(QLatin1Char(':'))) + return; + QString installPathPlugins = QDir::cleanPath(nativeInstallPathPlugins); + // look for the install path at the drive roots + installPathPlugins.prepend(QChar(QLatin1Char(':'))); + + QMutexLocker locker(libraryPathMutex()); + QStringList &app_libpaths = *coreappdata()->app_libpaths; + // Build a new library path, copying non-installPath components, and replacing existing install path with new + QStringList newPaths; + bool installPathFound = false; + foreach (QString path, app_libpaths) { + if (path.mid(1).compare(installPathPlugins, Qt::CaseInsensitive) == 0) { + // skip existing install paths, insert new install path when we find the first + if (!installPathFound) + qt_symbian_installLibraryPaths(nativeInstallPathPlugins, newPaths); + installPathFound = true; + } else { + newPaths.append(path); + } + } + app_libpaths = newPaths; +} +#endif + #endif //QT_NO_LIBRARY /*! diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index c6c6489..6f75da3 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -126,6 +126,9 @@ public: void symbianInit(); # endif static CApaCommandLine* symbianCommandLine(); +#ifndef QT_NO_LIBRARY + static void rebuildInstallLibraryPaths(); +#endif #endif static bool isTranslatorInstalled(QTranslator *translator); diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index c8831e5..24b4be0 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -50,8 +50,13 @@ #include "qmutex.h" #include "qplugin.h" #include "qpluginloader.h" +#include "qlibraryinfo.h" #include "private/qobject_p.h" #include "private/qcoreapplication_p.h" +#ifdef Q_OS_SYMBIAN +#include "private/qcore_symbian_p.h" +#include "private/qfilesystemwatcher_symbian_p.h" +#endif QT_BEGIN_NAMESPACE @@ -59,6 +64,23 @@ Q_GLOBAL_STATIC(QList<QFactoryLoader *>, qt_factory_loaders) Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_factoryloader_mutex, (QMutex::Recursive)) +#ifdef Q_OS_SYMBIAN +class QSymbianSystemPluginWatcher : public QSymbianFileSystemWatcherInterface +{ +public: + QSymbianSystemPluginWatcher(); + ~QSymbianSystemPluginWatcher(); + + void watchForUpdates(); + void handlePathChanged(QNotifyChangeEvent *e); + + QList<QNotifyChangeEvent*> watchers; + TDriveList drives; +}; + +Q_GLOBAL_STATIC(QSymbianSystemPluginWatcher, qt_symbian_system_plugin_watcher) +#endif + class QFactoryLoaderPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QFactoryLoader) @@ -98,102 +120,117 @@ QFactoryLoader::QFactoryLoader(const char *iid, QMutexLocker locker(qt_factoryloader_mutex()); update(); qt_factory_loaders()->append(this); +#ifdef Q_OS_SYMBIAN + // kick off Symbian plugin watcher for updates + qt_symbian_system_plugin_watcher(); +#endif } - -void QFactoryLoader::update() +void QFactoryLoader::updateDir(const QString &pluginDir, QSettings& settings) { -#ifdef QT_SHARED Q_D(QFactoryLoader); - QStringList paths = QCoreApplication::libraryPaths(); - QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); - for (int i = 0; i < paths.count(); ++i) { - const QString &pluginDir = paths.at(i); - // Already loaded, skip it... - if (d->loadedPaths.contains(pluginDir)) - continue; - d->loadedPaths << pluginDir; + QString path = pluginDir + d->suffix; + if (!QDir(path).exists(QLatin1String("."))) + return; - QString path = pluginDir + d->suffix; - if (!QDir(path).exists(QLatin1String("."))) - continue; + QStringList plugins = QDir(path).entryList(QDir::Files); + QLibraryPrivate *library = 0; + for (int j = 0; j < plugins.count(); ++j) { + QString fileName = QDir::cleanPath(path + QLatin1Char('/') + plugins.at(j)); - QStringList plugins = QDir(path).entryList(QDir::Files); - QLibraryPrivate *library = 0; - for (int j = 0; j < plugins.count(); ++j) { - QString fileName = QDir::cleanPath(path + QLatin1Char('/') + plugins.at(j)); + if (qt_debug_component()) { + qDebug() << "QFactoryLoader::QFactoryLoader() looking at" << fileName; + } + library = QLibraryPrivate::findOrCreate(QFileInfo(fileName).canonicalFilePath()); + if (!library->isPlugin(&settings)) { if (qt_debug_component()) { - qDebug() << "QFactoryLoader::QFactoryLoader() looking at" << fileName; + qDebug() << library->errorString; + qDebug() << " not a plugin"; } - library = QLibraryPrivate::findOrCreate(QFileInfo(fileName).canonicalFilePath()); - if (!library->isPlugin(&settings)) { + library->release(); + continue; + } + QString regkey = QString::fromLatin1("Qt Factory Cache %1.%2/%3:/%4") + .arg((QT_VERSION & 0xff0000) >> 16) + .arg((QT_VERSION & 0xff00) >> 8) + .arg(QLatin1String(d->iid)) + .arg(fileName); + QStringList reg, keys; + reg = settings.value(regkey).toStringList(); + if (reg.count() && library->lastModified == reg[0]) { + keys = reg; + keys.removeFirst(); + } else { + if (!library->loadPlugin()) { if (qt_debug_component()) { qDebug() << library->errorString; - qDebug() << " not a plugin"; + qDebug() << " could not load"; } library->release(); continue; } - QString regkey = QString::fromLatin1("Qt Factory Cache %1.%2/%3:/%4") - .arg((QT_VERSION & 0xff0000) >> 16) - .arg((QT_VERSION & 0xff00) >> 8) - .arg(QLatin1String(d->iid)) - .arg(fileName); - QStringList reg, keys; - reg = settings.value(regkey).toStringList(); - if (reg.count() && library->lastModified == reg[0]) { - keys = reg; - keys.removeFirst(); - } else { - if (!library->loadPlugin()) { - if (qt_debug_component()) { - qDebug() << library->errorString; - qDebug() << " could not load"; - } - library->release(); - continue; - } - QObject *instance = library->instance(); - if (!instance) { - library->release(); - // ignore plugins that have a valid signature but cannot be loaded. - continue; - } - QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instance); - if (instance && factory && instance->qt_metacast(d->iid)) - keys = factory->keys(); - if (keys.isEmpty()) - library->unload(); - reg.clear(); - reg << library->lastModified; - reg += keys; - settings.setValue(regkey, reg); - } - if (qt_debug_component()) { - qDebug() << "keys" << keys; - } - - if (keys.isEmpty()) { + QObject *instance = library->instance(); + if (!instance) { library->release(); + // ignore plugins that have a valid signature but cannot be loaded. continue; } - d->libraryList += library; - for (int k = 0; k < keys.count(); ++k) { - // first come first serve, unless the first - // library was built with a future Qt version, - // whereas the new one has a Qt version that fits - // better - QString key = keys.at(k); - if (!d->cs) - key = key.toLower(); - QLibraryPrivate *previous = d->keyMap.value(key); - if (!previous || (previous->qt_version > QT_VERSION && library->qt_version <= QT_VERSION)) { - d->keyMap[key] = library; - d->keyList += keys.at(k); - } + QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instance); + if (instance && factory && instance->qt_metacast(d->iid)) + keys = factory->keys(); + if (keys.isEmpty()) + library->unload(); + reg.clear(); + reg << library->lastModified; + reg += keys; + settings.setValue(regkey, reg); + } + if (qt_debug_component()) { + qDebug() << "keys" << keys; + } + + if (keys.isEmpty()) { + library->release(); + continue; + } + + int keysUsed = 0; + for (int k = 0; k < keys.count(); ++k) { + // first come first serve, unless the first + // library was built with a future Qt version, + // whereas the new one has a Qt version that fits + // better + QString key = keys.at(k); + if (!d->cs) + key = key.toLower(); + QLibraryPrivate *previous = d->keyMap.value(key); + if (!previous || (previous->qt_version > QT_VERSION && library->qt_version <= QT_VERSION)) { + d->keyMap[key] = library; + d->keyList += keys.at(k); + keysUsed++; } } + if (keysUsed) + d->libraryList += library; + else + library->release(); + } +} + +void QFactoryLoader::update() +{ +#ifdef QT_SHARED + Q_D(QFactoryLoader); + QStringList paths = QCoreApplication::libraryPaths(); + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + for (int i = 0; i < paths.count(); ++i) { + const QString &pluginDir = paths.at(i); + // Already loaded, skip it... + if (d->loadedPaths.contains(pluginDir)) + continue; + d->loadedPaths << pluginDir; + updateDir(pluginDir, settings); } #else Q_D(QFactoryLoader); @@ -264,6 +301,56 @@ void QFactoryLoader::refreshAll() } } +#ifdef Q_OS_SYMBIAN +QSymbianSystemPluginWatcher::QSymbianSystemPluginWatcher() +{ + qt_s60GetRFs().DriveList(drives); + watchForUpdates(); +} + +QSymbianSystemPluginWatcher::~QSymbianSystemPluginWatcher() +{ + qDeleteAll(watchers); +} + +void QSymbianSystemPluginWatcher::watchForUpdates() +{ + QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath); + if (installPathPlugins.at(1) == QChar(QLatin1Char(':'))) + return; + + installPathPlugins.prepend(QLatin1String("?:")); + installPathPlugins = QDir::toNativeSeparators(installPathPlugins); + RFs& fs = qt_s60GetRFs(); + for (int i=0; i<KMaxDrives; i++) { + int attr = drives[i]; + if ((attr & KDriveAttLocal) && !(attr & KDriveAttRom)) { + // start new watcher + TChar driveLetter; + fs.DriveToChar(i, driveLetter); + installPathPlugins[0] = driveLetter; + TPtrC ptr(qt_QString2TPtrC(installPathPlugins)); + QNotifyChangeEvent *event = q_check_ptr(new QNotifyChangeEvent(fs, ptr, this, true)); + watchers.push_back(event); + } + } +} + +void QSymbianSystemPluginWatcher::handlePathChanged(QNotifyChangeEvent *e) +{ + QCoreApplicationPrivate::rebuildInstallLibraryPaths(); + QMutexLocker locker(qt_factoryloader_mutex()); + QString dirName(QDir::cleanPath(qt_TDesC2QString(e->watchedPath))); + QList<QFactoryLoader *> *loaders = qt_factory_loaders(); + for (QList<QFactoryLoader *>::const_iterator it = loaders->constBegin(); + it != loaders->constEnd(); ++it) { + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + (*it)->updateDir(dirName, settings); + } +} + +#endif + QT_END_NAMESPACE #endif // QT_NO_LIBRARY diff --git a/src/corelib/plugin/qfactoryloader_p.h b/src/corelib/plugin/qfactoryloader_p.h index e90ebf6..8548ab2 100644 --- a/src/corelib/plugin/qfactoryloader_p.h +++ b/src/corelib/plugin/qfactoryloader_p.h @@ -82,6 +82,7 @@ public: #endif void update(); + void updateDir(const QString &pluginDir, QSettings& settings); static void refreshAll(); }; diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def index be09295..3437502 100644 --- a/src/s60installs/bwins/QtCoreu.def +++ b/src/s60installs/bwins/QtCoreu.def @@ -4879,4 +4879,9 @@ EXPORTS ?languageId@QLocalePrivate@@QBEGXZ @ 4878 NONAME ; unsigned short QLocalePrivate::languageId(void) const ?started@QFutureWatcherBase@@IAEXXZ @ 4879 NONAME ; void QFutureWatcherBase::started(void) ?staticMetaObjectExtraData@QAbstractState@@0UQMetaObjectExtraData@@B @ 4880 NONAME ; struct QMetaObjectExtraData const QAbstractState::staticMetaObjectExtraData + ?rebuildInstallLibraryPaths@QCoreApplicationPrivate@@SAXXZ @ 4881 NONAME ; void QCoreApplicationPrivate::rebuildInstallLibraryPaths(void) + ?connectNotify@QFutureWatcherBase@@MAEXPBD@Z @ 4882 NONAME ; void QFutureWatcherBase::connectNotify(char const *) + ?event@QFutureWatcherBase@@UAE_NPAVQEvent@@@Z @ 4883 NONAME ; bool QFutureWatcherBase::event(class QEvent *) + ?updateDir@QFactoryLoader@@QAEXABVQString@@AAVQSettings@@@Z @ 4884 NONAME ; void QFactoryLoader::updateDir(class QString const &, class QSettings &) + ?disconnectNotify@QFutureWatcherBase@@MAEXPBD@Z @ 4885 NONAME ; void QFutureWatcherBase::disconnectNotify(char const *) diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index cf42b67..1fabdb2 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -4162,4 +4162,6 @@ EXPORTS inflateReset2 @ 4161 NONAME inflateUndermine @ 4162 NONAME zlibCompileFlags @ 4163 NONAME + _ZN14QFactoryLoader9updateDirERK7QStringR9QSettings @ 4164 NONAME + _ZN23QCoreApplicationPrivate26rebuildInstallLibraryPathsEv @ 4165 NONAME |