summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@nokia.com>2011-10-25 14:56:51 +0200
committerLiang Qi <liang.qi@nokia.com>2011-10-25 14:56:51 +0200
commitbd0258ed73ecee28fba4c21027b2c2afd1b6af39 (patch)
tree136e780c13e0019382a315758d20e8ea43cf1c2d /src
parentcb4eb590d4af9978a0d60402f3c4ab99b6f4ede4 (diff)
parentec6543371108bbe24fb8d98eb1ff057c641a0e9d (diff)
Merge remote-tracking branch 'origin/4.7' into qt-4.8-from-4.7
Conflicts: src/corelib/kernel/qeventdispatcher_symbian.cpp src/declarative/qml/qdeclarativetypeloader.cpp src/imports/gestures/gestures.pro src/imports/particles/particles.pro src/opengl/qgl.cpp src/opengl/qgl_p.h src/s60installs/bwins/QtGuiu.def src/s60installs/eabi/QtGuiu.def tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro tests/auto/declarative/qdeclarativewebview/qdeclarativewebview.pro tests/auto/qaudioinput/qaudioinput.pro tests/auto/qaudiooutput/qaudiooutput.pro tests/auto/qchar/qchar.pro tests/auto/qclipboard/test/test.pro tests/auto/qsound/qsound.pro
Diffstat (limited to 'src')
-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
28 files changed, 447 insertions, 102 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index b216075e9d..fca2feb937 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 d2554229e2..dfc90e8ee5 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 a7d593a6b2..0a749109bf 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 44d6a1a7f4..7638b2b688 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 1d4db40386..74ebda2ec0 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 d40833ac45..273a2c73be 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 c2f00865ef..21413ce3b1 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 319e76ce98..d2ae9cc790 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 82197dcf03..0d8119fb5f 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 56b663689e..c0dce3e909 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 5cdf785ccd..f86274f91d 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 ad51b4b265..90d47f9fbe 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 8f13c53898..ed7411f642 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 35a9559254..3605472aae 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 15488490d1..3334056ad1 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 0756d6ca6a..c4cb19cee4 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 7d198ce14b..954d7fbd9f 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 44764a91a2..0f63979726 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 ad872bae3f..2768cc9c97 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 90b50e4659..894d164c72 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 d7a6275af5..51a9a918f9 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 dbbb07cf57..f5fe73926d 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 423fa08a1f..6d95713214 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 4de5122a86..0b963503c5 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 de349a759d..945bbafc54 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 b8e5c22a09..94c63fc2d8 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 335b94f3f1..92bfb25974 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 3606f9cb98..83e1851973 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