summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/io/qfile.cpp7
-rw-r--r--src/corelib/io/qfilesystemwatcher_symbian.cpp10
-rw-r--r--src/corelib/io/qfilesystemwatcher_symbian_p.h18
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp75
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h3
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp239
-rw-r--r--src/corelib/plugin/qfactoryloader_p.h1
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h2
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp77
-rw-r--r--src/s60installs/bwins/QtCoreu.def5
-rw-r--r--src/s60installs/eabi/QtCoreu.def2
11 files changed, 311 insertions, 128 deletions
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index 06c403a..d08574d 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -1332,6 +1332,13 @@ bool QFile::open(const RFile &f, OpenMode mode, FileHandleFlags handleFlags)
This function is not supported on Windows CE.
+ On Symbian, this function returns -1 if the file was opened normally,
+ as Symbian OS native file handles do not fit in an int, and are
+ incompatible with C library functions that the handle would be used for.
+ If the file was opened using the overloads that take an open C library
+ file handle / file descriptor, then this function returns that same
+ handle.
+
\sa QSocketNotifier
*/
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/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
index 8ef9726..ad51b4b 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_p.h
+++ b/src/gui/inputmethod/qcoefepinputcontext_p.h
@@ -136,6 +136,7 @@ private:
private Q_SLOTS:
void ensureInputCapabilitiesChanged();
void translateInputWidget();
+ void ensureWidgetVisibility();
// From MCoeFepAwareTextEditor
public:
@@ -208,6 +209,7 @@ private:
int m_splitViewResizeBy;
Qt::WindowStates m_splitViewPreviousWindowStates;
QRectF m_transformation;
+ QGraphicsItem *m_splitViewPreviousFocusItem; //can't use QPointer<> since QGraphicsItem is not a QObject.
CAknCcpuSupport *m_ccpu;
QAction *m_copyAction;
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index 3546079..bacf07a 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -382,6 +382,7 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_hasTempPreeditString(false),
m_splitViewResizeBy(0),
m_splitViewPreviousWindowStates(Qt::WindowNoState),
+ m_splitViewPreviousFocusItem(0),
m_ccpu(0)
{
m_fepState->SetObjectProvider(this);
@@ -451,6 +452,11 @@ void QCoeFepInputContext::reset()
if (m_cachedPreeditString.isEmpty() && !(currentHints & Qt::ImhNoPredictiveText))
m_cachedPreeditString = m_preeditString;
commitCurrentString(true);
+
+ // QGraphicsScene calls reset() when changing focus item. Unfortunately, the new focus item is
+ // set right after resetting the input context. Therefore, asynchronously call ensureWidgetVisibility().
+ if (S60->splitViewLastWidget)
+ QMetaObject::invokeMethod(this,"ensureWidgetVisibility", Qt::QueuedConnection);
}
void QCoeFepInputContext::ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType)
@@ -793,9 +799,8 @@ void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget)
{
QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget);
- if (!gv) {
+ if (!gv)
return;
- }
QSymbianControl *symControl = static_cast<QSymbianControl*>(gv->effectiveWinId());
symControl->CancelLongTapTimer();
@@ -810,11 +815,13 @@ void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget)
if (!alwaysResize) {
if (gv->scene() && S60->partial_keyboardAutoTranslation) {
if (gv->scene()->focusItem()) {
+ QGraphicsItem *focusItem =
+ m_splitViewPreviousFocusItem ? m_splitViewPreviousFocusItem : gv->scene()->focusItem();
// Check if the widget contains cursorPositionChanged signal and disconnect from it.
QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
- int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
+ int index = focusItem->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
if (index != -1)
- disconnect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
+ disconnect(focusItem->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
}
QGraphicsItem *rootItem = 0;
@@ -882,6 +889,11 @@ bool QCoeFepInputContext::isPartialKeyboardSupported()
return (S60->partial_keyboard || !QApplication::testAttribute(Qt::AA_S60DisablePartialScreenInputMode));
}
+void QCoeFepInputContext::ensureWidgetVisibility()
+{
+ ensureFocusWidgetVisible(S60->splitViewLastWidget);
+}
+
// Ensure that the input widget is visible in the splitview rect.
void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget)
@@ -913,17 +925,22 @@ void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget)
// states getting changed.
if (!moveWithinVisibleArea) {
- // Check if the widget contains cursorPositionChanged signal and connect to it.
- QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
- if (gv->scene() && gv->scene()->focusItem() && S60->partial_keyboardAutoTranslation) {
- int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
- if (index != -1)
- connect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
- }
S60->splitViewLastWidget = widget;
m_splitViewPreviousWindowStates = windowToMove->windowState();
}
+ // Check if the widget contains cursorPositionChanged signal and connect to it.
+ if (gv->scene() && gv->scene()->focusItem() && S60->partial_keyboardAutoTranslation) {
+ QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
+ if (m_splitViewPreviousFocusItem && m_splitViewPreviousFocusItem != gv->scene()->focusItem())
+ disconnect(m_splitViewPreviousFocusItem->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
+ int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
+ if (index != -1) {
+ connect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
+ m_splitViewPreviousFocusItem = gv->scene()->focusItem();
+ }
+ }
+
int windowTop = widget->window()->pos().y();
const bool userResize = widget->testAttribute(Qt::WA_Resized);
@@ -1266,10 +1283,15 @@ void QCoeFepInputContext::translateInputWidget()
m_transformation = (rootItem->transform().isTranslating()) ? QRectF(0,0, gv->width(), rootItem->transform().dy()) : QRectF();
- // Adjust cursor bounding rect to be lower, so that view translates if the cursor gets near
- // the splitview border.
- QRect cursorRect = cursorP.boundingRect().adjusted(0, cursor.height(), 0, cursor.height());
- if (splitViewRect.contains(cursorRect))
+ // Adjust cursor bounding rect towards navigation direction,
+ // so that view translates if the cursor gets near the splitview border.
+ QRect cursorRect = (cursorP.boundingRect().top() < 0) ?
+ cursorP.boundingRect().adjusted(0, -cursor.height(), 0, -cursor.height()) :
+ cursorP.boundingRect().adjusted(0, cursor.height(), 0, cursor.height());
+
+ // If the current cursor position and upcoming cursor positions are visible in the splitview
+ // area, do not move the view.
+ if (splitViewRect.contains(cursorRect) && splitViewRect.contains(cursorP.boundingRect()))
return;
// New Y position should be ideally just above the keyboard.
@@ -1281,22 +1303,29 @@ void QCoeFepInputContext::translateInputWidget()
const qreal itemHeight = path.boundingRect().height();
// Limit the maximum translation so that underlaying window content is not exposed.
- qreal maxY = gv->sceneRect().bottom() - splitViewRect.bottom();
- maxY = m_transformation.height() ? (qMin(itemHeight, maxY) + m_transformation.height()) : maxY;
- if (maxY < 0)
- maxY = 0;
+ qreal availableSpace = gv->sceneRect().bottom() - splitViewRect.bottom();
+ availableSpace = m_transformation.height() ?
+ (qMin(itemHeight, availableSpace) + m_transformation.height()) :
+ availableSpace;
// Translation should happen row-by-row, but initially it needs to ensure that cursor is visible.
const qreal translation = m_transformation.height() ?
cursor.height() : (cursorRect.bottom() - vkbRect.top());
- qreal dy = -(qMin(maxY, translation));
+ qreal dy = 0.0;
+ if (availableSpace > 0)
+ dy = -(qMin(availableSpace, translation));
+ else
+ dy = -(translation);
- // Correct the translation direction, if the cursor rect would be moved outside of application area.
- if ((cursorRect.bottom() + dy) < 0)
+ // Correct the translation direction, if the cursor rect would be moved above application area.
+ if ((cursorP.boundingRect().bottom() + dy) < 0)
dy *= -1;
- // Do not allow transform above screen top, nor beyond scenerect
- if (m_transformation.height() + dy > 0 || gv->sceneRect().bottom() + m_transformation.height() < 0) {
+ // Do not allow transform above screen top, nor beyond scenerect. Also, if there is no available
+ // space anymore, skip translation.
+ if ((m_transformation.height() + dy) > 0
+ || (gv->sceneRect().bottom() + m_transformation.height()) < 0
+ || !availableSpace) {
// If we already have some transformation, remove it.
if (m_transformation.height() < 0 || gv->sceneRect().bottom() + m_transformation.height() < 0) {
rootItem->resetTransform();
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