summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2011-10-26 07:52:38 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2011-10-26 07:52:38 (GMT)
commit65f5b6b4bb21c8d7062bbb950a5b4b53153d288f (patch)
tree93cfa1ae8fe232031db7b5ee9d7de262e04a93bd
parent9ff6bc28d5977bde97e8429328028e46572be445 (diff)
parentbd0258ed73ecee28fba4c21027b2c2afd1b6af39 (diff)
downloadQt-65f5b6b4bb21c8d7062bbb950a5b4b53153d288f.zip
Qt-65f5b6b4bb21c8d7062bbb950a5b4b53153d288f.tar.gz
Qt-65f5b6b4bb21c8d7062bbb950a5b4b53153d288f.tar.bz2
Merge branch 'qt-4.8-from-4.7' of scm.dev.nokia.troll.no:qt/qt-integration into master-integration
* 'qt-4.8-from-4.7' of scm.dev.nokia.troll.no:qt/qt-integration: Doc: Fix example code Regression caused by 2be143ebb5246bb2f9b674bb09d23df5b2b6c504 Accepting predicted text using hardware keyboard replaces unwanted part Fixes: the png_handle_cHRM crash bug in bundled libpng 1.5.4 Workaround to VideoCore III scissor bug. Fix to QGLWidget crash Update def files Fix crash on exit when overriding signal handlers in states. Typo fix Add new signals to indicate GPU resource usage. symbian - search drives for translation files symbian - search drives for translation files Cannot flick to the end of a horizontal list view width LayoutMirroring Backport more imports directory caching changes. Symbian - fix deleteLater not working from RunL Fix more test DEPLOYMENT statements for Symbian Fix deployment for declarative tests, examples on Symbian Fix StrictlyEnforceRange with snapOneItem/Row and header behavior, pt 2 Backport imports directory caching performance optimization
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp26
-rw-r--r--src/corelib/kernel/qtranslator.cpp40
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp33
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp14
-rw-r--r--src/declarative/qml/qdeclarativedirparser.cpp40
-rw-r--r--src/declarative/qml/qdeclarativedirparser_p.h6
-rw-r--r--src/declarative/qml/qdeclarativeimport.cpp112
-rw-r--r--src/declarative/qml/qdeclarativeimport_p.h2
-rw-r--r--src/declarative/qml/qdeclarativetypeloader.cpp94
-rw-r--r--src/declarative/qml/qdeclarativetypeloader_p.h9
-rw-r--r--src/declarative/util/qdeclarativepropertychanges.cpp5
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h1
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp37
-rw-r--r--src/gui/kernel/qapplication.cpp28
-rw-r--r--src/gui/kernel/qapplication.h4
-rw-r--r--src/gui/kernel/qapplication_p.h3
-rw-r--r--src/gui/kernel/qapplication_s60.cpp24
-rw-r--r--src/imports/folderlistmodel/folderlistmodel.pro4
-rw-r--r--src/imports/gestures/gestures.pro4
-rw-r--r--src/imports/particles/particles.pro4
-rw-r--r--src/imports/shaders/shaders.pro2
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp2
-rw-r--r--src/opengl/qgl.cpp8
-rw-r--r--src/opengl/qgl_egl.cpp11
-rw-r--r--src/opengl/qgl_p.h3
-rw-r--r--src/opengl/qgl_symbian.cpp18
-rw-r--r--src/s60installs/bwins/QtGuiu.def8
-rw-r--r--src/s60installs/eabi/QtGuiu.def7
-rw-r--r--tests/auto/declarative/qdeclarativepincharea/qdeclarativepincharea.pro2
-rw-r--r--tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash3.qml27
-rw-r--r--tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp17
-rw-r--r--tests/auto/qclipboard/test/test.pro6
-rw-r--r--tests/auto/qfileinfo/qfileinfo.pro2
-rw-r--r--tests/auto/qlocalsocket/test/test.pro2
34 files changed, 497 insertions, 108 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index b216075..fca2feb 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian.cpp
+++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp
@@ -60,6 +60,24 @@ QT_BEGIN_NAMESPACE
#define WAKE_UP_PRIORITY CActive::EPriorityStandard
#define TIMER_PRIORITY CActive::EPriorityHigh
+class Incrementer {
+ int &variable;
+public:
+ inline Incrementer(int &variable) : variable(variable)
+ { ++variable; }
+ inline ~Incrementer()
+ { --variable; }
+};
+
+class Decrementer {
+ int &variable;
+public:
+ inline Decrementer(int &variable) : variable(variable)
+ { --variable; }
+ inline ~Decrementer()
+ { ++variable; }
+};
+
static inline int qt_pipe_write(int socket, const char *data, qint64 len)
{
return ::write(socket, data, len);
@@ -951,6 +969,8 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla
#endif
while (1) {
+ //native active object callbacks are logically part of the event loop, so inc nesting level
+ Incrementer inc(d->threadData->loopLevel);
if (block) {
// This is where Qt will spend most of its time.
CActiveScheduler::Current()->WaitForAnyRequest();
@@ -1045,6 +1065,7 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla
void QEventDispatcherSymbian::timerFired(int timerId)
{
+ Q_D(QAbstractEventDispatcher);
QHash<int, SymbianTimerInfoPtr>::iterator i = m_timerList.find(timerId);
if (i == m_timerList.end()) {
// The timer has been deleted. Ignore this event.
@@ -1063,6 +1084,8 @@ void QEventDispatcherSymbian::timerFired(int timerId)
m_insideTimerEvent = true;
QTimerEvent event(timerInfo->timerId);
+ //undo the added nesting level around RunIfReady, since Qt's event system also nests
+ Decrementer dec(d->threadData->loopLevel);
QCoreApplication::sendEvent(timerInfo->receiver, &event);
m_insideTimerEvent = oldInsideTimerEventValue;
@@ -1073,6 +1096,7 @@ void QEventDispatcherSymbian::timerFired(int timerId)
void QEventDispatcherSymbian::wakeUpWasCalled()
{
+ Q_D(QAbstractEventDispatcher);
// The reactivation should happen in RunL, right before the call to this function.
// This is because m_wakeUpDone is the "signal" that the object can be completed
// once more.
@@ -1082,6 +1106,8 @@ void QEventDispatcherSymbian::wakeUpWasCalled()
// the sendPostedEvents was done, but before the object was ready to be completed
// again. This could deadlock the application if there are no other posted events.
m_wakeUpDone.fetchAndStoreOrdered(0);
+ //undo the added nesting level around RunIfReady, since Qt's event system also nests
+ Decrementer dec(d->threadData->loopLevel);
sendPostedEvents();
}
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index d255422..dfc90e8 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -51,6 +51,7 @@
#include "qcoreapplication.h"
#include "qcoreapplication_p.h"
#include "qdatastream.h"
+#include "qdir.h"
#include "qfile.h"
#include "qmap.h"
#include "qalgorithms.h"
@@ -63,6 +64,10 @@
#include "private/qcore_unix_p.h"
#endif
+#ifdef Q_OS_SYMBIAN
+#include "private/qcore_symbian_p.h"
+#endif
+
// most of the headers below are already included in qplatformdefs.h
// also this lacks Large File support but that's probably irrelevant
#if defined(QT_USE_MMAP)
@@ -405,11 +410,24 @@ bool QTranslator::load(const QString & filename, const QString & directory,
QString prefix;
if (QFileInfo(filename).isRelative()) {
+#ifdef Q_OS_SYMBIAN
+ if (directory.isEmpty())
+ prefix = QCoreApplication::applicationDirPath();
+ else
+ prefix = QFileInfo(directory).absoluteFilePath(); //TFindFile doesn't like dirty paths
+ if (prefix.length() > 2 && prefix.at(1) == QLatin1Char(':') && prefix.at(0).isLetter())
+ prefix[0] = QLatin1Char('Y');
+#else
prefix = directory;
- if (prefix.length() && !prefix.endsWith(QLatin1Char('/')))
- prefix += QLatin1Char('/');
+#endif
+ if (prefix.length() && !prefix.endsWith(QLatin1Char('/')))
+ prefix += QLatin1Char('/');
}
+#ifdef Q_OS_SYMBIAN
+ QString nativePrefix = QDir::toNativeSeparators(prefix);
+#endif
+
QString fname = filename;
QString realname;
QString delims;
@@ -418,6 +436,24 @@ bool QTranslator::load(const QString & filename, const QString & directory,
for (;;) {
QFileInfo fi;
+#ifdef Q_OS_SYMBIAN
+ //search for translations on other drives, e.g. Qt may be in Z, while app is in C
+ //note this uses symbian search rules, i.e. y:->a:, followed by z:
+ TFindFile finder(qt_s60GetRFs());
+ QString fname2 = fname + (suffix.isNull() ? QString::fromLatin1(".qm") : suffix);
+ TInt err = finder.FindByDir(
+ qt_QString2TPtrC(fname2),
+ qt_QString2TPtrC(nativePrefix));
+ if (err != KErrNone)
+ err = finder.FindByDir(qt_QString2TPtrC(fname), qt_QString2TPtrC(nativePrefix));
+ if (err == KErrNone) {
+ fi.setFile(qt_TDesC2QString(finder.File()));
+ realname = fi.canonicalFilePath();
+ if (fi.isReadable() && fi.isFile())
+ break;
+ }
+#endif
+
realname = prefix + fname + (suffix.isNull() ? QString::fromLatin1(".qm") : suffix);
fi.setFile(realname);
if (fi.isReadable() && fi.isFile())
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index a7d593a..0a74910 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -1083,25 +1083,29 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
tempPosition -= bias;
}
FxGridItem *topItem = snapItemAt(tempPosition+highlightStart);
+ if (!topItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ topItem = currentItem;
+ }
FxGridItem *bottomItem = snapItemAt(tempPosition+highlightEnd);
+ if (!bottomItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ bottomItem = currentItem;
+ }
qreal pos;
- if (topItem && bottomItem && strictHighlightRange) {
- qreal topPos = qMin(topItem->rowPos() - highlightStart, -maxExtent);
- qreal bottomPos = qMax(bottomItem->rowPos() - highlightEnd, -minExtent);
- pos = qAbs(data.move + topPos) < qAbs(data.move + bottomPos) ? topPos : bottomPos;
- } else if (topItem) {
- qreal headerPos = 0;
- if (header)
- headerPos = isRightToLeftTopToBottom() ? header->rowPos() + cellWidth - headerSize() : header->rowPos();
- if (topItem->index == 0 && header && tempPosition+highlightStart < headerPos+headerSize()/2 && !strictHighlightRange) {
- pos = isRightToLeftTopToBottom() ? - headerPos + highlightStart - size() : headerPos - highlightStart;
+ bool isInBounds = -position() > maxExtent && -position() <= minExtent;
+ if (topItem && (isInBounds || strictHighlightRange)) {
+ if (topItem->index == 0 && header && tempPosition+highlightStart < header->rowPos()+headerSize()/2 && !strictHighlightRange) {
+ pos = isRightToLeftTopToBottom() ? - header->rowPos() + highlightStart - size() : header->rowPos() - highlightStart;
} else {
if (isRightToLeftTopToBottom())
pos = qMax(qMin(-topItem->rowPos() + highlightStart - size(), -maxExtent), -minExtent);
else
pos = qMax(qMin(topItem->rowPos() - highlightStart, -maxExtent), -minExtent);
}
- } else if (bottomItem) {
+ } else if (bottomItem && isInBounds) {
if (isRightToLeftTopToBottom())
pos = qMax(qMin(-bottomItem->rowPos() + highlightEnd - size(), -maxExtent), -minExtent);
else
@@ -2247,9 +2251,10 @@ qreal QDeclarativeGridView::minXExtent() const
qreal extent = -d->startPosition();
qreal highlightStart;
qreal highlightEnd;
- qreal endPositionFirstItem;
+ qreal endPositionFirstItem = 0;
if (d->isRightToLeftTopToBottom()) {
- endPositionFirstItem = d->rowPosAt(d->model->count()-1);
+ if (d->model && d->model->count())
+ endPositionFirstItem = d->rowPosAt(d->model->count()-1);
highlightStart = d->highlightRangeStartValid
? d->highlightRangeStart - (d->lastPosition()-endPositionFirstItem)
: d->size() - (d->lastPosition()-endPositionFirstItem);
@@ -2264,7 +2269,7 @@ qreal QDeclarativeGridView::minXExtent() const
extent += d->header->item->width();
}
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
- extent += highlightStart;
+ extent += d->isRightToLeftTopToBottom() ? -highlightStart : highlightStart;
extent = qMax(extent, -(endPositionFirstItem - highlightEnd));
}
return extent;
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index 44d6a1a..7638b2b 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -1326,10 +1326,20 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
tempPosition -= bias;
}
FxListItem *topItem = snapItemAt(tempPosition+highlightStart);
+ if (!topItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ topItem = currentItem;
+ }
FxListItem *bottomItem = snapItemAt(tempPosition+highlightEnd);
+ if (!bottomItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ bottomItem = currentItem;
+ }
qreal pos;
bool isInBounds = -position() > maxExtent && -position() <= minExtent;
- if (topItem && isInBounds) {
+ if (topItem && (isInBounds || strictHighlightRange)) {
if (topItem->index == 0 && header && tempPosition+highlightStart < header->position()+header->size()/2 && !strictHighlightRange) {
pos = isRightToLeft() ? - header->position() + highlightStart - size() : header->position() - highlightStart;
} else {
@@ -2754,7 +2764,7 @@ qreal QDeclarativeListView::minXExtent() const
d->minExtent += d->header->size();
}
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
- d->minExtent += highlightStart;
+ d->minExtent += d->isRightToLeft() ? -highlightStart : highlightStart;
d->minExtent = qMax(d->minExtent, -(endPositionFirstItem - highlightEnd + 1));
}
d->minExtentDirty = false;
diff --git a/src/declarative/qml/qdeclarativedirparser.cpp b/src/declarative/qml/qdeclarativedirparser.cpp
index 1d4db40..74ebda2 100644
--- a/src/declarative/qml/qdeclarativedirparser.cpp
+++ b/src/declarative/qml/qdeclarativedirparser.cpp
@@ -41,8 +41,10 @@
#include "private/qdeclarativedirparser_p.h"
#include "qdeclarativeerror.h"
+#include <private/qdeclarativeglobal_p.h>
#include <QtCore/QTextStream>
+#include <QtCore/QFile>
#include <QtCore/QtDebug>
QT_BEGIN_NAMESPACE
@@ -66,6 +68,16 @@ void QDeclarativeDirParser::setUrl(const QUrl &url)
_url = url;
}
+QString QDeclarativeDirParser::fileSource() const
+{
+ return _filePathSouce;
+}
+
+void QDeclarativeDirParser::setFileSource(const QString &filePath)
+{
+ _filePathSouce = filePath;
+}
+
QString QDeclarativeDirParser::source() const
{
return _source;
@@ -92,6 +104,23 @@ bool QDeclarativeDirParser::parse()
_plugins.clear();
_components.clear();
+ if (_source.isEmpty() && !_filePathSouce.isEmpty()) {
+ QFile file(_filePathSouce);
+ if (!QDeclarative_isFileCaseCorrect(_filePathSouce)) {
+ QDeclarativeError error;
+ error.setDescription(QString::fromUtf8("cannot load module \"$$URI$$\": File name case mismatch for \"%1\"").arg(_filePathSouce));
+ _errors.prepend(error);
+ return false;
+ } else if (file.open(QFile::ReadOnly)) {
+ _source = QString::fromUtf8(file.readAll());
+ } else {
+ QDeclarativeError error;
+ error.setDescription(QString::fromUtf8("module \"$$URI$$\" definition \"%1\" not readable").arg(_filePathSouce));
+ _errors.prepend(error);
+ return false;
+ }
+ }
+
QTextStream stream(&_source);
int lineNumber = 0;
@@ -224,9 +253,16 @@ bool QDeclarativeDirParser::hasError() const
return false;
}
-QList<QDeclarativeError> QDeclarativeDirParser::errors() const
+QList<QDeclarativeError> QDeclarativeDirParser::errors(const QString &uri) const
{
- return _errors;
+ QList<QDeclarativeError> errors = _errors;
+ for (int i = 0; i < errors.size(); ++i) {
+ QDeclarativeError &e = errors[i];
+ QString description = e.description();
+ description.replace(QLatin1String("$$URI$$"), uri);
+ e.setDescription(description);
+ }
+ return errors;
}
QList<QDeclarativeDirParser::Plugin> QDeclarativeDirParser::plugins() const
diff --git a/src/declarative/qml/qdeclarativedirparser_p.h b/src/declarative/qml/qdeclarativedirparser_p.h
index d40833a..273a2c7 100644
--- a/src/declarative/qml/qdeclarativedirparser_p.h
+++ b/src/declarative/qml/qdeclarativedirparser_p.h
@@ -73,11 +73,14 @@ public:
QString source() const;
void setSource(const QString &source);
+ QString fileSource() const;
+ void setFileSource(const QString &filePath);
+
bool isParsed() const;
bool parse();
bool hasError() const;
- QList<QDeclarativeError> errors() const;
+ QList<QDeclarativeError> errors(const QString &uri) const;
struct Plugin
{
@@ -129,6 +132,7 @@ private:
QList<QDeclarativeError> _errors;
QUrl _url;
QString _source;
+ QString _filePathSouce;
QList<Component> _components;
QList<Plugin> _plugins;
#ifdef QT_CREATOR
diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp
index c2f0086..21413ce 100644
--- a/src/declarative/qml/qdeclarativeimport.cpp
+++ b/src/declarative/qml/qdeclarativeimport.cpp
@@ -80,16 +80,16 @@ public:
QList<QDeclarativeDirComponents> qmlDirComponents;
- bool find_helper(int i, const QByteArray& type, int *vmajor, int *vminor,
+ bool find_helper(QDeclarativeTypeLoader *typeLoader, int i, const QByteArray& type, int *vmajor, int *vminor,
QDeclarativeType** type_return, QUrl* url_return,
QUrl *base = 0, bool *typeRecursionDetected = 0);
- bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
+ bool find(QDeclarativeTypeLoader *typeLoader, const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
QUrl* url_return, QUrl *base = 0, QString *errorString = 0);
};
class QDeclarativeImportsPrivate {
public:
- QDeclarativeImportsPrivate();
+ QDeclarativeImportsPrivate(QDeclarativeTypeLoader *loader);
~QDeclarativeImportsPrivate();
bool importExtension(const QString &absoluteFilePath, const QString &uri,
@@ -112,6 +112,7 @@ public:
QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded;
QDeclarativeImportedNamespace unqualifiedset;
QHash<QString,QDeclarativeImportedNamespace* > set;
+ QDeclarativeTypeLoader *typeLoader;
};
/*!
@@ -135,9 +136,12 @@ QDeclarativeImports::operator =(const QDeclarativeImports &copy)
return *this;
}
-QDeclarativeImports::QDeclarativeImports()
-: d(new QDeclarativeImportsPrivate)
-{
+QDeclarativeImports::QDeclarativeImports()
+ : d(new QDeclarativeImportsPrivate(0)){
+}
+
+QDeclarativeImports::QDeclarativeImports(QDeclarativeTypeLoader *typeLoader)
+ : d(new QDeclarativeImportsPrivate(typeLoader)){
}
QDeclarativeImports::~QDeclarativeImports()
@@ -269,10 +273,11 @@ bool QDeclarativeImports::resolveType(QDeclarativeImportedNamespace* ns, const Q
QDeclarativeType** type_return, QUrl* url_return,
int *vmaj, int *vmin) const
{
- return ns->find(type,vmaj,vmin,type_return,url_return);
+ Q_ASSERT(d->typeLoader);
+ return ns->find(d->typeLoader,type,vmaj,vmin,type_return,url_return);
}
-bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, int *vmajor, int *vminor,
+bool QDeclarativeImportedNamespace::find_helper(QDeclarativeTypeLoader *typeLoader, int i, const QByteArray& type, int *vmajor, int *vminor,
QDeclarativeType** type_return, QUrl* url_return,
QUrl *base, bool *typeRecursionDetected)
{
@@ -292,7 +297,6 @@ bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, i
return true;
}
- QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml"));
QDeclarativeDirComponents qmldircomponents = qmlDirComponents.at(i);
bool typeWasDeclaredInQmldir = false;
@@ -304,6 +308,7 @@ bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, i
// importing version -1 means import ALL versions
if ((vmaj == -1) || (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion))) {
+ QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml"));
QUrl candidate = url.resolved(QUrl(c.fileName));
if (c.internal && base) {
if (base->resolved(QUrl(c.fileName)) != candidate)
@@ -324,8 +329,9 @@ bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, i
if (!typeWasDeclaredInQmldir && !isLibrary.at(i)) {
// XXX search non-files too! (eg. zip files, see QT-524)
- QFileInfo f(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url));
- if (f.exists()) {
+ QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml"));
+ QString file = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);
+ if (!typeLoader->absoluteFilePath(file).isEmpty()) {
if (base && *base == url) { // no recursion
if (typeRecursionDetected)
*typeRecursionDetected = true;
@@ -339,9 +345,8 @@ bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, i
return false;
}
-QDeclarativeImportsPrivate::QDeclarativeImportsPrivate()
-: ref(1)
-{
+QDeclarativeImportsPrivate::QDeclarativeImportsPrivate(QDeclarativeTypeLoader *loader)
+ : ref(1), typeLoader(loader){
}
QDeclarativeImportsPrivate::~QDeclarativeImportsPrivate()
@@ -354,33 +359,22 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath
QDeclarativeImportDatabase *database,
QDeclarativeDirComponents* components, QString *errorString)
{
- QFile file(absoluteFilePath);
- QString filecontent;
- if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("cannot load module \"%1\": File name case mismatch for \"%2\"").arg(uri).arg(absoluteFilePath);
- return false;
- } else if (file.open(QFile::ReadOnly)) {
- filecontent = QString::fromUtf8(file.readAll());
- if (qmlImportTrace())
- qDebug().nospace() << "QDeclarativeImports(" << qPrintable(base.toString()) << "::importExtension: "
- << "loaded " << absoluteFilePath;
- } else {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath);
+ Q_ASSERT(typeLoader);
+ const QDeclarativeDirParser *qmldirParser = typeLoader->qmlDirParser(absoluteFilePath);
+ if (qmldirParser->hasError()) {
+ if (errorString) {
+ const QList<QDeclarativeError> qmldirErrors = qmldirParser->errors(uri);
+ for (int i = 0; i < qmldirErrors.size(); ++i)
+ *errorString += qmldirErrors.at(i).description();
+ }
return false;
}
- QDir dir = QFileInfo(file).dir();
-
- QDeclarativeDirParser qmldirParser;
- qmldirParser.setSource(filecontent);
- qmldirParser.parse();
if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) {
qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath);
-
- foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) {
+ QDir dir = QFileInfo(absoluteFilePath).dir();
+ foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser->plugins()) {
QString resolvedFilePath = database->resolvePlugin(dir, plugin.path, plugin.name);
#if defined(QT_LIBINFIX) && defined(Q_OS_SYMBIAN)
@@ -405,7 +399,7 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath
}
if (components)
- *components = qmldirParser.components();
+ *components = qmldirParser->components();
return true;
}
@@ -446,6 +440,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
QDeclarativeScriptParser::Import::Type importType,
QDeclarativeImportDatabase *database, QString *errorString)
{
+ Q_ASSERT(typeLoader);
QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork;
QString uri = uri_arg;
QDeclarativeImportedNamespace *s;
@@ -463,20 +458,20 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
url.replace(QLatin1Char('.'), QLatin1Char('/'));
bool found = false;
QString dir;
-
+ QString qmldir;
// step 1: search for extension with fully encoded version number
if (vmaj >= 0 && vmin >= 0) {
foreach (const QString &p, database->fileImportPath) {
dir = p+QLatin1Char('/')+url;
+ qmldir = dir+QString(QLatin1String(".%1.%2")).arg(vmaj).arg(vmin)+QLatin1String("/qmldir");
- QFileInfo fi(dir+QString(QLatin1String(".%1.%2")).arg(vmaj).arg(vmin)+QLatin1String("/qmldir"));
- const QString absoluteFilePath = fi.absoluteFilePath();
-
- if (fi.isFile()) {
+ QString absoluteFilePath = typeLoader->absoluteFilePath(qmldir);
+ if (!absoluteFilePath.isEmpty()) {
found = true;
- url = QUrl::fromLocalFile(fi.absolutePath()).toString();
+ QString absolutePath = absoluteFilePath.left(absoluteFilePath.lastIndexOf(QLatin1Char('/')));
+ url = QUrl::fromLocalFile(absolutePath).toString();
uri = resolvedUri(dir, database);
if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
return false;
@@ -488,14 +483,14 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
if (vmaj >= 0 && vmin >= 0) {
foreach (const QString &p, database->fileImportPath) {
dir = p+QLatin1Char('/')+url;
+ qmldir = dir+QString(QLatin1String(".%1")).arg(vmaj)+QLatin1String("/qmldir");
- QFileInfo fi(dir+QString(QLatin1String(".%1")).arg(vmaj)+QLatin1String("/qmldir"));
- const QString absoluteFilePath = fi.absoluteFilePath();
-
- if (fi.isFile()) {
+ QString absoluteFilePath = typeLoader->absoluteFilePath(qmldir);
+ if (!absoluteFilePath.isEmpty()) {
found = true;
- url = QUrl::fromLocalFile(fi.absolutePath()).toString();
+ QString absolutePath = absoluteFilePath.left(absoluteFilePath.lastIndexOf(QLatin1Char('/')));
+ url = QUrl::fromLocalFile(absolutePath).toString();
uri = resolvedUri(dir, database);
if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
return false;
@@ -508,14 +503,14 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
foreach (const QString &p, database->fileImportPath) {
dir = p+QLatin1Char('/')+url;
+ qmldir = dir+QLatin1String("/qmldir");
- QFileInfo fi(dir+QLatin1String("/qmldir"));
- const QString absoluteFilePath = fi.absoluteFilePath();
-
- if (fi.isFile()) {
+ QString absoluteFilePath = typeLoader->absoluteFilePath(qmldir);
+ if (!absoluteFilePath.isEmpty()) {
found = true;
- url = QUrl::fromLocalFile(fi.absolutePath()).toString();
+ QString absolutePath = absoluteFilePath.left(absoluteFilePath.lastIndexOf(QLatin1Char('/')));
+ url = QUrl::fromLocalFile(absolutePath).toString();
uri = resolvedUri(dir, database);
if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
return false;
@@ -553,7 +548,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
uri = resolvedUri(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri))), database);
if (uri.endsWith(QLatin1Char('/')))
uri.chop(1);
- if (QFile::exists(localFileOrQrc)) {
+ if (!typeLoader->absoluteFilePath(localFileOrQrc).isEmpty()) {
if (!importExtension(localFileOrQrc,uri,database,&qmldircomponents,errorString))
return false;
}
@@ -616,6 +611,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
QUrl* url_return, QString *errorString)
{
+ Q_ASSERT(typeLoader);
QDeclarativeImportedNamespace *s = 0;
int slash = type.indexOf('/');
if (slash >= 0) {
@@ -637,7 +633,7 @@ bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int *
}
QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower)
if (s) {
- if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errorString))
+ if (s->find(typeLoader, unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errorString))
return true;
if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) {
// qualified, and only 1 url
@@ -654,16 +650,16 @@ QDeclarativeImportedNamespace *QDeclarativeImportsPrivate::findNamespace(const Q
return set.value(type);
}
-bool QDeclarativeImportedNamespace::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
+bool QDeclarativeImportedNamespace::find(QDeclarativeTypeLoader *typeLoader, const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
QUrl* url_return, QUrl *base, QString *errorString)
{
bool typeRecursionDetected = false;
for (int i=0; i<urls.count(); ++i) {
- if (find_helper(i, type, vmajor, vminor, type_return, url_return, base, &typeRecursionDetected)) {
+ if (find_helper(typeLoader, i, type, vmajor, vminor, type_return, url_return, base, &typeRecursionDetected)) {
if (qmlCheckTypes()) {
// check for type clashes
for (int j = i+1; j<urls.count(); ++j) {
- if (find_helper(j, type, vmajor, vminor, 0, 0, base)) {
+ if (find_helper(typeLoader, j, type, vmajor, vminor, 0, 0, base)) {
if (errorString) {
QString u1 = urls.at(i);
QString u2 = urls.at(j);
@@ -1042,7 +1038,7 @@ bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QSt
if (!engineInitialized || !typesRegistered) {
if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
if (errorString)
- *errorString = tr("File name case mismatch for \"%2\"").arg(absoluteFilePath);
+ *errorString = tr("File name case mismatch for \"%1\"").arg(absoluteFilePath);
return false;
}
QPluginLoader loader(absoluteFilePath);
diff --git a/src/declarative/qml/qdeclarativeimport_p.h b/src/declarative/qml/qdeclarativeimport_p.h
index 319e76c..d2ae9cc 100644
--- a/src/declarative/qml/qdeclarativeimport_p.h
+++ b/src/declarative/qml/qdeclarativeimport_p.h
@@ -68,11 +68,13 @@ class QDir;
class QDeclarativeImportedNamespace;
class QDeclarativeImportsPrivate;
class QDeclarativeImportDatabase;
+class QDeclarativeTypeLoader;
class QDeclarativeImports
{
public:
QDeclarativeImports();
+ QDeclarativeImports(QDeclarativeTypeLoader *);
QDeclarativeImports(const QDeclarativeImports &);
~QDeclarativeImports();
QDeclarativeImports &operator=(const QDeclarativeImports &);
diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp
index 82197dc..0d8119f 100644
--- a/src/declarative/qml/qdeclarativetypeloader.cpp
+++ b/src/declarative/qml/qdeclarativetypeloader.cpp
@@ -50,10 +50,37 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtCore/qdebug.h>
#include <QtCore/qdir.h>
+#include <QtCore/qdiriterator.h>
#include <QtCore/qfile.h>
QT_BEGIN_NAMESPACE
+/*
+Returns the set of QML files in path (qmldir, *.qml, *.js). The caller
+is responsible for deleting the returned data.
+*/
+static QSet<QString> *qmlFilesInDirectory(const QString &path)
+{
+ QDirIterator dir(path, QDir::Files);
+ if (!dir.hasNext())
+ return 0;
+ QSet<QString> *files = new QSet<QString>;
+ while (dir.hasNext()) {
+ dir.next();
+ QString fileName = dir.fileName();
+ if (fileName == QLatin1String("qmldir")
+ || fileName.endsWith(QLatin1String(".qml"))
+ || fileName.endsWith(QLatin1String(".js"))) {
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_DARWIN) || defined(Q_OS_SYMBIAN)
+ fileName = fileName.toLower();
+#endif
+ files->insert(fileName);
+ }
+ }
+ return files;
+}
+
+
/*!
\class QDeclarativeDataBlob
\brief The QDeclarativeDataBlob encapsulates a data request that can be issued to a QDeclarativeDataLoader.
@@ -727,6 +754,67 @@ QDeclarativeQmldirData *QDeclarativeTypeLoader::getQmldir(const QUrl &url)
}
/*!
+Returns the absolute filename of path via a directory cache for files named
+"qmldir", "*.qml", "*.js"
+Returns a empty string if the path does not exist.
+*/
+QString QDeclarativeTypeLoader::absoluteFilePath(const QString &path)
+{
+ if (path.isEmpty())
+ return QString();
+ if (path.at(0) == QLatin1Char(':')) {
+ // qrc resource
+ QFileInfo fileInfo(path);
+ return fileInfo.isFile() ? fileInfo.absoluteFilePath() : QString();
+ }
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_DARWIN) || defined(Q_OS_SYMBIAN)
+ QString lowPath(path.toLower());
+#else
+ QString lowPath(path);
+#endif
+ int lastSlash = lowPath.lastIndexOf(QLatin1Char('/'));
+ QString dirPath = lowPath.left(lastSlash);
+
+ StringSet *fileSet = 0;
+ QHash<QString,StringSet*>::const_iterator it = m_importDirCache.find(dirPath);
+ if (it == m_importDirCache.end()) {
+ StringSet *files = qmlFilesInDirectory(path.left(lastSlash));
+ m_importDirCache.insert(dirPath, files);
+ fileSet = files;
+ } else {
+ fileSet = *it;
+ }
+ if (!fileSet)
+ return QString();
+
+ QString absoluteFilePath = fileSet->contains(QString(lowPath.constData()+lastSlash+1, lowPath.length()-lastSlash-1)) ? path : QString();
+ if (absoluteFilePath.length() > 2 && absoluteFilePath.at(0) != QLatin1Char('/') && absoluteFilePath.at(1) != QLatin1Char(':'))
+ absoluteFilePath = QFileInfo(absoluteFilePath).absoluteFilePath();
+
+ return absoluteFilePath;
+}
+
+/*!
+Return a QDeclarativeDirParser for absoluteFilePath. The QDeclarativeDirParser may be cached.
+*/
+const QDeclarativeDirParser *QDeclarativeTypeLoader::qmlDirParser(const QString &absoluteFilePath)
+{
+ QDeclarativeDirParser *qmldirParser;
+ QHash<QString,QDeclarativeDirParser*>::const_iterator it = m_importQmlDirCache.find(absoluteFilePath);
+ if (it == m_importQmlDirCache.end()) {
+ qmldirParser = new QDeclarativeDirParser;
+ qmldirParser->setFileSource(absoluteFilePath);
+ qmldirParser->setUrl(QUrl::fromLocalFile(absoluteFilePath));
+ qmldirParser->parse();
+ m_importQmlDirCache.insert(absoluteFilePath, qmldirParser);
+ } else {
+ qmldirParser = *it;
+ }
+
+ return qmldirParser;
+}
+
+/*
Clears cached information about loaded files, including any type data, scripts
and qmldir information.
*/
@@ -738,16 +826,20 @@ void QDeclarativeTypeLoader::clearCache()
(*iter)->release();
for (QmldirCache::Iterator iter = m_qmldirCache.begin(); iter != m_qmldirCache.end(); ++iter)
(*iter)->release();
+ qDeleteAll(m_importDirCache);
+ qDeleteAll(m_importQmlDirCache);
m_typeCache.clear();
m_scriptCache.clear();
m_qmldirCache.clear();
+ m_importDirCache.clear();
+ m_importQmlDirCache.clear();
}
QDeclarativeTypeData::QDeclarativeTypeData(const QUrl &url, QDeclarativeTypeLoader::Options options,
QDeclarativeTypeLoader *manager)
-: QDeclarativeDataBlob(url, QmlFile), m_options(options), m_typesResolved(false),
+: QDeclarativeDataBlob(url, QmlFile), m_options(options), m_imports(manager), m_typesResolved(false),
m_compiledData(0), m_typeLoader(manager)
{
}
diff --git a/src/declarative/qml/qdeclarativetypeloader_p.h b/src/declarative/qml/qdeclarativetypeloader_p.h
index 56b6636..c0dce3e 100644
--- a/src/declarative/qml/qdeclarativetypeloader_p.h
+++ b/src/declarative/qml/qdeclarativetypeloader_p.h
@@ -198,14 +198,23 @@ public:
QDeclarativeScriptData *getScript(const QUrl &);
QDeclarativeQmldirData *getQmldir(const QUrl &);
+
+ QString absoluteFilePath(const QString &path);
+ const QDeclarativeDirParser *qmlDirParser(const QString &absoluteFilePath);
+
private:
typedef QHash<QUrl, QDeclarativeTypeData *> TypeCache;
typedef QHash<QUrl, QDeclarativeScriptData *> ScriptCache;
typedef QHash<QUrl, QDeclarativeQmldirData *> QmldirCache;
+ typedef QSet<QString> StringSet;
+ typedef QHash<QString, StringSet*> ImportDirCache;
+ typedef QHash<QString, QDeclarativeDirParser*> ImportQmlDirCache;
TypeCache m_typeCache;
ScriptCache m_scriptCache;
QmldirCache m_qmldirCache;
+ ImportDirCache m_importDirCache;
+ ImportQmlDirCache m_importQmlDirCache;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeTypeLoader::Options)
diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp
index 5cdf785..f86274f 100644
--- a/src/declarative/util/qdeclarativepropertychanges.cpp
+++ b/src/declarative/util/qdeclarativepropertychanges.cpp
@@ -171,7 +171,8 @@ public:
reverseExpression = rewindExpression;
}
- /*virtual void copyOriginals(QDeclarativeActionEvent *other)
+ virtual bool needsCopy() { return true; }
+ virtual void copyOriginals(QDeclarativeActionEvent *other)
{
QDeclarativeReplaceSignalHandler *rsh = static_cast<QDeclarativeReplaceSignalHandler*>(other);
saveCurrentValues();
@@ -182,7 +183,7 @@ public:
ownedExpression = rsh->ownedExpression;
rsh->ownedExpression = 0;
}
- }*/
+ }
virtual void rewind() {
ownedExpression = QDeclarativePropertyPrivate::setSignalExpression(property, rewindExpression);
diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
index ad51b4b..90d47f9 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_p.h
+++ b/src/gui/inputmethod/qcoefepinputcontext_p.h
@@ -205,6 +205,7 @@ private:
QBasicTimer m_tempPreeditStringTimeout;
bool m_hasTempPreeditString;
QString m_cachedPreeditString;
+ int m_cachedCursorAndAnchorPosition;
int m_splitViewResizeBy;
Qt::WindowStates m_splitViewPreviousWindowStates;
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index 8f13c53..ed7411f 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -380,6 +380,7 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_formatRetriever(0),
m_pointerHandler(0),
m_hasTempPreeditString(false),
+ m_cachedCursorAndAnchorPosition(-1),
m_splitViewResizeBy(0),
m_splitViewPreviousWindowStates(Qt::WindowNoState),
m_splitViewPreviousFocusItem(0),
@@ -448,9 +449,18 @@ void QCoeFepInputContext::reset()
}
// Store a copy of preedit text, if prediction is active and input context is reseted.
// This is to ensure that we can replace preedit string after losing focus to FEP manager's
- // internal sub-windows.
- if (m_cachedPreeditString.isEmpty() && !(currentHints & Qt::ImhNoPredictiveText))
+ // internal sub-windows. Additionally, store the cursor position if there is no selected text.
+ // This allows input context to replace preedit strings if they are not at the end of current
+ // text.
+ if (m_cachedPreeditString.isEmpty() && !(currentHints & Qt::ImhNoPredictiveText)) {
m_cachedPreeditString = m_preeditString;
+ if (focusWidget() && !m_cachedPreeditString.isEmpty()) {
+ int cursor = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
+ int anchor = focusWidget()->inputMethodQuery(Qt::ImAnchorPosition).toInt();
+ if (cursor == anchor)
+ m_cachedCursorAndAnchorPosition = cursor;
+ }
+ }
commitCurrentString(true);
// QGraphicsScene calls reset() when changing focus item. Unfortunately, the new focus item is
@@ -491,6 +501,7 @@ void QCoeFepInputContext::setFocusWidget(QWidget *w)
void QCoeFepInputContext::widgetDestroyed(QWidget *w)
{
m_cachedPreeditString.clear();
+ m_cachedCursorAndAnchorPosition = -1;
// Make sure that the input capabilities of whatever new widget got focused are queried.
CCoeControl *ctrl = w->effectiveWinId();
@@ -1350,6 +1361,7 @@ void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText,
return;
m_cachedPreeditString.clear();
+ m_cachedCursorAndAnchorPosition = -1;
commitTemporaryPreeditString();
@@ -1408,8 +1420,16 @@ void QCoeFepInputContext::UpdateFepInlineTextL(const TDesC& aNewInlineText,
QString newPreeditString = qt_TDesC2QString(aNewInlineText);
QInputMethodEvent event(newPreeditString, attributes);
if (!m_cachedPreeditString.isEmpty()) {
- event.setCommitString(QLatin1String(""), -m_cachedPreeditString.length(), m_cachedPreeditString.length());
+ int cursorPos = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
+ // Predicted word is either replaced from the end of the word (normal case),
+ // or from stored location, if the predicted word is either in the beginning of,
+ // or in the middle of already committed word.
+ int diff = cursorPos - m_cachedCursorAndAnchorPosition;
+ int replaceLocation = (diff != m_cachedPreeditString.length()) ? diff : m_cachedPreeditString.length();
+
+ event.setCommitString(QLatin1String(""), -replaceLocation, m_cachedPreeditString.length());
m_cachedPreeditString.clear();
+ m_cachedCursorAndAnchorPosition = -1;
} else if (newPreeditString.isEmpty() && m_preeditString.isEmpty()) {
// In Symbian world this means "erase last character".
event.setCommitString(QLatin1String(""), -1, 1);
@@ -1507,6 +1527,10 @@ void QCoeFepInputContext::SetCursorSelectionForFepL(const TCursorSelection& aCur
int pos = aCursorSelection.iAnchorPos;
int length = aCursorSelection.iCursorPos - pos;
+ if (m_cachedCursorAndAnchorPosition != -1) {
+ pos = m_cachedCursorAndAnchorPosition;
+ length = 0;
+ }
QList<QInputMethodEvent::Attribute> attributes;
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos, length, QVariant());
@@ -1524,6 +1548,13 @@ void QCoeFepInputContext::GetCursorSelectionForFep(TCursorSelection& aCursorSele
int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt() + m_preeditString.size();
int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt() + m_preeditString.size();
+
+ // If the position is stored, use that value, so that word replacement from proposed word
+ // lists are added to the correct position.
+ if (m_cachedCursorAndAnchorPosition != -1) {
+ cursor = m_cachedCursorAndAnchorPosition;
+ anchor = m_cachedCursorAndAnchorPosition;
+ }
QString text = w->inputMethodQuery(Qt::ImSurroundingText).value<QString>();
int combinedSize = text.size() + m_preeditString.size();
if (combinedSize < anchor || combinedSize < cursor) {
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 35a9559..3605472 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -3426,7 +3426,35 @@ QString QApplication::sessionKey() const
}
#endif
+/*!
+ \since 4.7.4
+ \fn void QApplication::aboutToReleaseGpuResources()
+
+ This signal is emitted when application is about to release all
+ GPU resources associated to contexts owned by application.
+
+ The signal is particularly useful if your application has allocated
+ GPU resources directly apart from Qt and needs to do some last-second
+ cleanup.
+
+ \warning This signal is only emitted on Symbian.
+
+ \sa aboutToUseGpuResources()
+*/
+/*!
+ \since 4.7.4
+ \fn void QApplication::aboutToUseGpuResources()
+
+ This signal is emitted when application is about to use GPU resources.
+
+ The signal is particularly useful if your application needs to know
+ when GPU resources are be available.
+
+ \warning This signal is only emitted on Symbian.
+
+ \sa aboutToFreeGpuResources()
+*/
/*!
\since 4.2
diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h
index 1548849..3334056 100644
--- a/src/gui/kernel/qapplication.h
+++ b/src/gui/kernel/qapplication.h
@@ -305,6 +305,10 @@ Q_SIGNALS:
void commitDataRequest(QSessionManager &sessionManager);
void saveStateRequest(QSessionManager &sessionManager);
#endif
+#ifdef Q_OS_SYMBIAN
+ void aboutToReleaseGpuResources();
+ void aboutToUseGpuResources();
+#endif
public:
QString styleSheet() const;
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index 0756d6c..c4cb19c 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -564,6 +564,9 @@ public:
void symbianHandleLiteModeStartup();
void _q_aboutToQuit();
+
+ void emitAboutToReleaseGpuResources();
+ void emitAboutToUseGpuResources();
#endif
#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
void sendSyntheticEnterLeave(QWidget *widget);
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 7d198ce..954d7fb 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -235,6 +235,9 @@ void QS60Data::controlVisibilityChanged(CCoeControl *control, bool visible)
if (QTLWExtra *topData = qt_widget_private(window)->maybeTopData()) {
QWidgetBackingStoreTracker &backingStore = topData->backingStore;
if (visible) {
+ QApplicationPrivate *d = QApplicationPrivate::instance();
+ d->emitAboutToUseGpuResources();
+
if (backingStore.data()) {
backingStore.registerWidget(widget);
} else {
@@ -244,6 +247,9 @@ void QS60Data::controlVisibilityChanged(CCoeControl *control, bool visible)
widget->repaint();
}
} else {
+ QApplicationPrivate *d = QApplicationPrivate::instance();
+ d->emitAboutToReleaseGpuResources();
+
// In certain special scenarios we may get an ENotVisible event
// without a previous EPartiallyVisible. The backingstore must
// still be destroyed, hence the registerWidget() call below.
@@ -2795,6 +2801,24 @@ void QApplicationPrivate::_q_aboutToQuit()
#endif
}
+void QApplicationPrivate::emitAboutToReleaseGpuResources()
+{
+#ifdef Q_SYMBIAN_SUPPORTS_SURFACES
+ Q_Q(QApplication);
+ QPointer<QApplication> guard(q);
+ emit q->aboutToReleaseGpuResources();
+#endif
+}
+
+void QApplicationPrivate::emitAboutToUseGpuResources()
+{
+#ifdef Q_SYMBIAN_SUPPORTS_SURFACES
+ Q_Q(QApplication);
+ QPointer<QApplication> guard(q);
+ emit q->aboutToUseGpuResources();
+#endif
+}
+
QS60ThreadLocalData::QS60ThreadLocalData()
{
CCoeEnv *env = CCoeEnv::Static();
diff --git a/src/imports/folderlistmodel/folderlistmodel.pro b/src/imports/folderlistmodel/folderlistmodel.pro
index 44764a9..0f63979 100644
--- a/src/imports/folderlistmodel/folderlistmodel.pro
+++ b/src/imports/folderlistmodel/folderlistmodel.pro
@@ -19,8 +19,8 @@ symbian:{
isEmpty(DESTDIR):importFiles.files = qmlfolderlistmodelplugin$${QT_LIBINFIX}.dll qmldir
else:importFiles.files = $$DESTDIR/qmlfolderlistmodelplugin$${QT_LIBINFIX}.dll qmldir
importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH
-
- DEPLOYMENT = importFiles
+
+ DEPLOYMENT += importFiles
}
INSTALLS += target qmldir
diff --git a/src/imports/gestures/gestures.pro b/src/imports/gestures/gestures.pro
index ad872ba..2768cc9 100644
--- a/src/imports/gestures/gestures.pro
+++ b/src/imports/gestures/gestures.pro
@@ -19,8 +19,8 @@ symbian:{
isEmpty(DESTDIR):importFiles.files = qmlgesturesplugin$${QT_LIBINFIX}.dll qmldir
else:importFiles.files = $$DESTDIR/qmlgesturesplugin$${QT_LIBINFIX}.dll qmldir
importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH
-
- DEPLOYMENT = importFiles
+
+ DEPLOYMENT += importFiles
}
INSTALLS += target qmldir
diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro
index 90b50e4..894d164 100644
--- a/src/imports/particles/particles.pro
+++ b/src/imports/particles/particles.pro
@@ -23,8 +23,8 @@ symbian:{
isEmpty(DESTDIR):importFiles.files = qmlparticlesplugin$${QT_LIBINFIX}.dll qmldir
else:importFiles.files = $$DESTDIR/qmlparticlesplugin$${QT_LIBINFIX}.dll qmldir
importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH
-
- DEPLOYMENT = importFiles
+
+ DEPLOYMENT += importFiles
}
INSTALLS += target qmldir
diff --git a/src/imports/shaders/shaders.pro b/src/imports/shaders/shaders.pro
index d7a6275..51a9a91 100644
--- a/src/imports/shaders/shaders.pro
+++ b/src/imports/shaders/shaders.pro
@@ -32,7 +32,7 @@ symbian:{
isEmpty(DESTDIR):importFiles.sources = qmlparticlesplugin$${QT_LIBINFIX}.dll qmldir
else:importFiles.sources = $$DESTDIR/qmlparticlesplugin$${QT_LIBINFIX}.dll qmldir
importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH
- DEPLOYMENT = importFiles
+ DEPLOYMENT += importFiles
}
INSTALLS += target qmldir
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index dbbb07c..f5fe739 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -2268,6 +2268,8 @@ void QGL2PaintEngineExPrivate::updateClipScissorTest()
currentScissorBounds = bounds;
if (bounds == QRect(0, 0, width, height)) {
+ if (ctx->d_func()->workaround_brokenScissor)
+ clearClip(0);
glDisable(GL_SCISSOR_TEST);
} else {
glEnable(GL_SCISSOR_TEST);
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 423fa08..6d95713 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1743,6 +1743,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
workaround_brokenTextureFromPixmap = false;
workaround_brokenTextureFromPixmap_init = false;
+ workaround_brokenScissor = false;
workaround_brokenAlphaTexSubImage = false;
workaround_brokenAlphaTexSubImage_init = false;
@@ -4381,7 +4382,7 @@ bool QGLWidget::event(QEvent *e)
// if we've reparented a window that has the current context
// bound, we need to rebind that context to the new window id
if (d->glcx == QGLContext::currentContext())
- makeCurrent();
+ makeCurrent(); // Shouldn't happen but keep it here just for sure
if (testAttribute(Qt::WA_TranslucentBackground))
setContext(new QGLContext(d->glcx->requestedFormat(), this));
@@ -4389,8 +4390,11 @@ bool QGLWidget::event(QEvent *e)
// A re-parent is likely to destroy the Symbian window and re-create it. It is important
// that we free the EGL surface _before_ the winID changes - otherwise we can leak.
- if (e->type() == QEvent::ParentAboutToChange)
+ if (e->type() == QEvent::ParentAboutToChange) {
+ if (d->glcx == QGLContext::currentContext())
+ d->glcx->doneCurrent();
d->glcx->d_func()->destroyEglSurfaceForDevice();
+ }
if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) {
// The window may have been re-created during re-parent or state change - if so, the EGL
diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp
index 4de5122..0b96350 100644
--- a/src/opengl/qgl_egl.cpp
+++ b/src/opengl/qgl_egl.cpp
@@ -194,7 +194,9 @@ void QGLContext::makeCurrent()
if (!d->workaroundsCached) {
d->workaroundsCached = true;
const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
- if (renderer && (strstr(renderer, "SGX") || strstr(renderer, "MBX"))) {
+ if (!renderer)
+ return;
+ if ((strstr(renderer, "SGX") || strstr(renderer, "MBX"))) {
// PowerVR MBX/SGX chips needs to clear all buffers when starting to render
// a new frame, otherwise there will be a performance penalty to pay for
// each frame.
@@ -231,6 +233,13 @@ void QGLContext::makeCurrent()
d->workaround_brokenFBOReadBack = true;
}
}
+ } else if (strstr(renderer, "VideoCore III")) {
+ // Some versions of VideoCore III drivers seem to pollute and use
+ // stencil buffer when using glScissors even if stencil test is disabled.
+ // Workaround is to clear stencil buffer before disabling scissoring.
+
+ // qDebug() << "Found VideoCore III driver, enabling brokenDisableScissorTest";
+ d->workaround_brokenScissor = true;
}
}
}
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index de349a7..945bbaf 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -179,6 +179,7 @@ public:
#endif
#if defined(Q_OS_SYMBIAN)
, eglSurfaceWindowId(0)
+ , surfaceSizeInitialized(false)
#endif
{
isGLWidget = 1;
@@ -224,6 +225,7 @@ public:
#ifdef Q_OS_SYMBIAN
void recreateEglSurface();
WId eglSurfaceWindowId;
+ bool surfaceSizeInitialized : 1;
#endif
};
@@ -426,6 +428,7 @@ public:
uint workaround_brokenTextureFromPixmap : 1;
uint workaround_brokenTextureFromPixmap_init : 1;
+ uint workaround_brokenScissor : 1;
uint workaround_brokenAlphaTexSubImage : 1;
uint workaround_brokenAlphaTexSubImage_init : 1;
diff --git a/src/opengl/qgl_symbian.cpp b/src/opengl/qgl_symbian.cpp
index b8e5c22..94c63fc 100644
--- a/src/opengl/qgl_symbian.cpp
+++ b/src/opengl/qgl_symbian.cpp
@@ -259,7 +259,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // almost same as
return true;
}
-void QGLWidget::resizeEvent(QResizeEvent *)
+void QGLWidget::resizeEvent(QResizeEvent *e)
{
Q_D(QGLWidget);
if (!isValid())
@@ -270,17 +270,18 @@ void QGLWidget::resizeEvent(QResizeEvent *)
if (this == qt_gl_share_widget())
return;
- if (QGLContext::currentContext())
- doneCurrent();
-
- // Symbian needs to recreate the surface on resize.
- d->recreateEglSurface();
+ if (!d->surfaceSizeInitialized || e->oldSize() != e->size()) {
+ // On Symbian we need to recreate the surface on resize.
+ d->recreateEglSurface();
+ d->surfaceSizeInitialized = true;
+ }
makeCurrent();
+
if (!d->glcx->initialized())
glInit();
+
resizeGL(width(), height());
- //handle overlay
}
const QGLContext* QGLWidget::overlayContext() const
@@ -363,6 +364,9 @@ void QGLWidgetPrivate::recreateEglSurface()
WId currentId = q->winId();
if (glcx->d_func()->eglSurface != EGL_NO_SURFACE) {
+ if (glcx == QGLContext::currentContext())
+ glcx->doneCurrent();
+
eglDestroySurface(glcx->d_func()->eglContext->display(),
glcx->d_func()->eglSurface);
}
diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def
index 335b94f..92bfb25 100644
--- a/src/s60installs/bwins/QtGuiu.def
+++ b/src/s60installs/bwins/QtGuiu.def
@@ -13113,6 +13113,7 @@ EXPORTS
?hasBCM2727@QSymbianGraphicsSystemEx@@SA_NXZ @ 13112 NONAME ; bool QSymbianGraphicsSystemEx::hasBCM2727(void)
?constImageRef@QVolatileImage@@QBEABVQImage@@XZ @ 13113 NONAME ; class QImage const & QVolatileImage::constImageRef(void) const
?toVolatileImage@QPixmapData@@UBE?AVQVolatileImage@@XZ @ 13114 NONAME ; class QVolatileImage QPixmapData::toVolatileImage(void) const
+<<<<<<< HEAD
?qt_s60_setPartialScreenAutomaticTranslation@@YAX_N@Z @ 13115 NONAME ; void qt_s60_setPartialScreenAutomaticTranslation(bool)
png_access_version_number @ 13116 NONAME
png_benign_error @ 13117 NONAME
@@ -13986,4 +13987,11 @@ EXPORTS
?resetFontEngineCache@QTextEngine@@QAEXXZ @ 13985 NONAME ; void QTextEngine::resetFontEngineCache(void)
?symbianHandleLiteModeStartup@QApplicationPrivate@@QAEXXZ @ 13986 NONAME ; void QApplicationPrivate::symbianHandleLiteModeStartup(void)
?_q_cleanupWinIds@QWidgetPrivate@@QAEXXZ @ 13987 NONAME ; void QWidgetPrivate::_q_cleanupWinIds(void)
+=======
+ ?qt_s60_setPartialScreenAutomaticTranslation@@YAX_N@Z @ 13115 NONAME ; void qt_s60_setPartialScreenAutomaticTranslation(bool)
+ ?aboutToUseGpuResources@QApplication@@IAEXXZ @ 13116 NONAME ; void QApplication::aboutToUseGpuResources(void)
+ ?aboutToReleaseGpuResources@QApplication@@IAEXXZ @ 13117 NONAME ; void QApplication::aboutToReleaseGpuResources(void)
+ ?emitAboutToUseGpuResources@QApplicationPrivate@@QAEXXZ @ 13118 NONAME ; void QApplicationPrivate::emitAboutToUseGpuResources(void)
+ ?emitAboutToReleaseGpuResources@QApplicationPrivate@@QAEXXZ @ 13119 NONAME ; void QApplicationPrivate::emitAboutToReleaseGpuResources(void)
+>>>>>>> origin/4.7
diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def
index 3606f9c..83e1851 100644
--- a/src/s60installs/eabi/QtGuiu.def
+++ b/src/s60installs/eabi/QtGuiu.def
@@ -12198,6 +12198,7 @@ EXPORTS
_ZNK11QPixmapData15toVolatileImageEv @ 12197 NONAME
_ZNK14QVolatileImage13constImageRefEv @ 12198 NONAME
_Z43qt_s60_setPartialScreenAutomaticTranslationb @ 12199 NONAME
+<<<<<<< HEAD
_Z18qt_addBitmapToPathffPKhiiiP12QPainterPath @ 12200 NONAME
_Z22qt_fontdata_from_indexi @ 12201 NONAME
_Z27qt_isExtendedRadialGradientRK6QBrush @ 12202 NONAME
@@ -12799,4 +12800,10 @@ EXPORTS
_ZN11QTextEngine20resetFontEngineCacheEv @ 12798 NONAME
_ZN14QWidgetPrivate16_q_cleanupWinIdsEv @ 12799 NONAME
_ZN19QApplicationPrivate28symbianHandleLiteModeStartupEv @ 12800 NONAME
+=======
+ _ZN12QApplication22aboutToUseGpuResourcesEv @ 12200 NONAME
+ _ZN12QApplication26aboutToReleaseGpuResourcesEv @ 12201 NONAME
+ _ZN19QApplicationPrivate26emitAboutToUseGpuResourcesEv @ 12202 NONAME
+ _ZN19QApplicationPrivate30emitAboutToReleaseGpuResourcesEv @ 12203 NONAME
+>>>>>>> origin/4.7
diff --git a/tests/auto/declarative/qdeclarativepincharea/qdeclarativepincharea.pro b/tests/auto/declarative/qdeclarativepincharea/qdeclarativepincharea.pro
index 2c13644..3bdb3fc 100644
--- a/tests/auto/declarative/qdeclarativepincharea/qdeclarativepincharea.pro
+++ b/tests/auto/declarative/qdeclarativepincharea/qdeclarativepincharea.pro
@@ -7,7 +7,7 @@ SOURCES += tst_qdeclarativepincharea.cpp
symbian: {
importFiles.sources = data
importFiles.path = .
- DEPLOYMENT = importFiles
+ DEPLOYMENT += importFiles
} else {
DEFINES += SRCDIR=\\\"$$PWD\\\"
}
diff --git a/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash3.qml b/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash3.qml
new file mode 100644
index 0000000..ed1f22f
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash3.qml
@@ -0,0 +1,27 @@
+import QtQuick 1.0
+
+Rectangle {
+ id: myRect
+ width: 400
+ height: 400
+
+ onHeightChanged: console.log("base state")
+
+ states: [
+ State {
+ name: "state1"
+ PropertyChanges {
+ target: myRect
+ onHeightChanged: console.log("state1")
+ color: "green"
+ }
+ },
+ State {
+ name: "state2";
+ PropertyChanges {
+ target: myRect
+ onHeightChanged: console.log("state2")
+ color: "red"
+ }
+ }]
+}
diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp
index 9fafa7d..e90e6fb 100644
--- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp
+++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp
@@ -113,6 +113,7 @@ private slots:
void signalOverride();
void signalOverrideCrash();
void signalOverrideCrash2();
+ void signalOverrideCrash3();
void parentChange();
void parentChangeErrors();
void anchorChanges();
@@ -520,6 +521,22 @@ void tst_qdeclarativestates::signalOverrideCrash2()
delete rect;
}
+void tst_qdeclarativestates::signalOverrideCrash3()
+{
+ QDeclarativeEngine engine;
+
+ QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverrideCrash3.qml");
+ QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QDeclarativeItemPrivate::get(rect)->setState("state1");
+ QDeclarativeItemPrivate::get(rect)->setState("");
+ QDeclarativeItemPrivate::get(rect)->setState("state2");
+ QDeclarativeItemPrivate::get(rect)->setState("");
+
+ delete rect;
+}
+
void tst_qdeclarativestates::parentChange()
{
QDeclarativeEngine engine;
diff --git a/tests/auto/qclipboard/test/test.pro b/tests/auto/qclipboard/test/test.pro
index 12c6b6c..2e8f6db 100644
--- a/tests/auto/qclipboard/test/test.pro
+++ b/tests/auto/qclipboard/test/test.pro
@@ -15,7 +15,7 @@ wince*|symbian: {
copier.path = copier
paster.files = ../paster/paster.exe
paster.path = paster
-
+
symbian: {
LIBS += -lbafl -lestor -letext
@@ -27,6 +27,6 @@ wince*|symbian: {
reg_resource.files += $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/paster_reg.rsc
reg_resource.path = $$REG_RESOURCE_IMPORT_DIR
}
-
+
DEPLOYMENT += copier paster rsc reg_resource
-} \ No newline at end of file
+}
diff --git a/tests/auto/qfileinfo/qfileinfo.pro b/tests/auto/qfileinfo/qfileinfo.pro
index b35b1e0..7a2cf9c 100644
--- a/tests/auto/qfileinfo/qfileinfo.pro
+++ b/tests/auto/qfileinfo/qfileinfo.pro
@@ -19,7 +19,7 @@ symbian {
TARGET.CAPABILITY=AllFiles
LIBS *= -lefsrv
INCLUDEPATH *= $$MW_LAYER_SYSTEMINCLUDE # Needed for e32svr.h in S^3 envs
- }
+}
# support for running test from shadow build directory
wince* {
diff --git a/tests/auto/qlocalsocket/test/test.pro b/tests/auto/qlocalsocket/test/test.pro
index b2755b5..7d85cba 100644
--- a/tests/auto/qlocalsocket/test/test.pro
+++ b/tests/auto/qlocalsocket/test/test.pro
@@ -44,7 +44,7 @@ wince*|symbian {
scriptFiles.path = lackey/scripts
DEPLOYMENT += additionalFiles scriptFiles
QT += script # for easy deployment of QtScript
-
+
requires(contains(QT_CONFIG,script))
}