From 055d68ce72a9cfbaffa5ac85314aff215e7a74c6 Mon Sep 17 00:00:00 2001 From: Aapo Haapanen Date: Thu, 22 Sep 2011 15:50:50 +0300 Subject: fix for QTBUG-18050: QXmlQuery crash --- src/xmlpatterns/api/qxmlquery.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/xmlpatterns/api/qxmlquery.cpp b/src/xmlpatterns/api/qxmlquery.cpp index e69fe50..4690a8d 100644 --- a/src/xmlpatterns/api/qxmlquery.cpp +++ b/src/xmlpatterns/api/qxmlquery.cpp @@ -988,7 +988,12 @@ bool setFocusHelper(QXmlQuery *const queryInstance, const QXmlItem focusItem(focusResult.next()); if(focusItem.isNull() || focusResult.hasError()) + { + /* The previous focus must be cleared in error situations. + * Otherwise the query may be left in an inconsistent state. */ + queryInstance->setFocus(QXmlItem()); return false; + } else { queryInstance->setFocus(focusItem); -- cgit v0.12 From 4d07fc585b7cb8784deaf98afa432082f36fc981 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Fri, 23 Sep 2011 10:51:53 +0300 Subject: The cursor can get offscreen in splitscreen landscape mode When input context is making the translation, it doesn't check if the translation is happening to the correct direction (i.e. upwards or downwards). As a fix, check if the cursor is still visible after making the translation. If it isn't apply the translation to the other direction. Task-number: QTBUG-21543 Reviewed-by: Miikka Heikkinen --- src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 9025221..b830d50 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -1277,7 +1277,11 @@ void QCoeFepInputContext::translateInputWidget() // Translation should happen row-by-row, but initially it needs to ensure that cursor is visible. const qreal translation = m_transformation.height() ? cursor.height() : (cursorRect.bottom() - vkbRect.top()); - const qreal dy = -(qMin(maxY, translation)); + qreal dy = -(qMin(maxY, translation)); + + // Correct the translation direction, if the cursor rect would be moved outside of application area. + if ((cursorRect.bottom() + dy) < 0) + dy *= -1; // Do not allow transform above screen top, nor beyond scenerect if (m_transformation.height() + dy > 0 || gv->sceneRect().bottom() + m_transformation.height() < 0) { -- cgit v0.12 From 00a3147f66688b71069989bbac406a00f6e8cf83 Mon Sep 17 00:00:00 2001 From: Aapo Haapanen Date: Thu, 22 Sep 2011 15:50:50 +0300 Subject: Fix for QTBUG-18050: QXmlQuery crash If QXmlQuery has a previous focus and an invalid xml is given in setFocus, the old focus must be cleared. Otherwise the query may be left in an inconsistent state. Task-number: QTBUG-18050 Reviewed-by: Miikka Heikkinen --- src/xmlpatterns/api/qxmlquery.cpp | 5 +++++ tests/auto/qxmlquery/tst_qxmlquery.cpp | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/xmlpatterns/api/qxmlquery.cpp b/src/xmlpatterns/api/qxmlquery.cpp index e69fe50..e5e901d 100644 --- a/src/xmlpatterns/api/qxmlquery.cpp +++ b/src/xmlpatterns/api/qxmlquery.cpp @@ -988,7 +988,12 @@ bool setFocusHelper(QXmlQuery *const queryInstance, const QXmlItem focusItem(focusResult.next()); if(focusItem.isNull() || focusResult.hasError()) + { + /* The previous focus must be cleared in error situations. + * Otherwise the query may be left in an inconsistent state. */ + queryInstance->setFocus(QXmlItem()); return false; + } else { queryInstance->setFocus(focusItem); diff --git a/tests/auto/qxmlquery/tst_qxmlquery.cpp b/tests/auto/qxmlquery/tst_qxmlquery.cpp index e443720..51bb88e 100644 --- a/tests/auto/qxmlquery/tst_qxmlquery.cpp +++ b/tests/auto/qxmlquery/tst_qxmlquery.cpp @@ -167,6 +167,7 @@ private Q_SLOTS: void setFocusQString() const; void setFocusQStringFailure() const; void setFocusQStringSignature() const; + void setFocusQStringFailureAfterSucces() const; void recompilationWithEvaluateToResultFailing() const; void secondEvaluationWithEvaluateToResultFailing() const; void recompilationWithEvaluateToReceiver() const; @@ -1976,6 +1977,25 @@ void tst_QXmlQuery::setFocusQStringSignature() const static_cast(query.setFocus(QString())); } +void tst_QXmlQuery::setFocusQStringFailureAfterSucces() const +{ + /* Test for QTBUG-18050. First call setFocus with a valid string, + * and then with an invalid string. evaluateTo should not crash. */ + QXmlQuery query; + MessageSilencer silencer; + query.setMessageHandler(&silencer); + + QVERIFY(query.setFocus(QLatin1String("valid-input"))); + QVERIFY(!query.setFocus(QLatin1String("invalid-input"))); + + query.setQuery("/query"); + + QString output; + /* Last setFocus was with an invalid string, so evaluateTo should return + * false */ + QVERIFY(!query.evaluateTo(&output)); +} + void tst_QXmlQuery::setFocusQIODeviceTriggerWarnings() const { /* A null pointer. */ -- cgit v0.12 From a0e677ef0468fdf2d8f04e1b64312a3d9881be5f Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 23 Sep 2011 12:01:08 +0100 Subject: symbian - Document behaviour of QDir::rootPath / homePath The root path was intentionally changed to reflect the real drive root, while home path continues to reflect the user data directory. Task-Number: QTBUG-21527 Reviewed-By: Miikka Heikkinen --- src/corelib/io/qdir.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 4ba8e06..48b9358 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1872,7 +1872,10 @@ QString QDir::currentPath() Under non-Windows operating systems the \c HOME environment variable is used if it exists, otherwise the path returned by the - rootPath(). On Symbian always the same as the path returned by the rootPath(). + rootPath(). + + On Symbian this typically returns "c:/data", + i.e. the same as native PathInfo::PhoneMemoryRootPath(). \sa home(), currentPath(), rootPath(), tempPath() */ @@ -1936,9 +1939,8 @@ QString QDir::tempPath() /*! Returns the absolute path of the root directory. - For Unix operating systems this returns "/". For Windows file - systems this normally returns "c:/". On Symbian this typically returns - "c:/data", i.e. the same as native PathInfo::PhoneMemoryRootPath(). + For Unix operating systems this returns "/". For Windows and Symbian file + systems this normally returns "c:/". I.E. the root of the system drive. \sa root(), drives(), currentPath(), homePath(), tempPath() */ -- cgit v0.12 From 930461946ce14051e56a3d7f49e2cd24742b8777 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 23 Sep 2011 15:53:59 +0100 Subject: Symbian - perform some FS initialisation previously done by open c When using Qt 4.6 and 4.7, the working directory is set to the same drive the application is installed on by the open c library. The default working directory in symbian is always the private directory on the system drive, but we told people to rely on the open c behaviour. Open C also creates the private path on both the system and installation drives when the application is started. This behaviour is also replicated now in Qt 4.8 for backward compatibility of apps that may rely on it. Similar code to create the private path on the installation drive in QCoreApplication::applicationDirPath() has been removed, as the new code in this patch is always executed first. Task-Number: QTBUG-21527 Reviewed-By: mread --- src/corelib/kernel/qcore_symbian_p.cpp | 19 +++++++++++++++++++ src/corelib/kernel/qcoreapplication.cpp | 6 ------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/corelib/kernel/qcore_symbian_p.cpp b/src/corelib/kernel/qcore_symbian_p.cpp index 04acfb0..57ae2af 100644 --- a/src/corelib/kernel/qcore_symbian_p.cpp +++ b/src/corelib/kernel/qcore_symbian_p.cpp @@ -45,6 +45,7 @@ #include "qcore_symbian_p.h" #include #include +#include "qdebug.h" QT_BEGIN_NAMESPACE @@ -115,6 +116,24 @@ public: QS60RFsSession() { qt_symbian_throwIfError(iFs.Connect()); qt_symbian_throwIfError(iFs.ShareProtected()); + //BC with 4.7: create private path on system drive + TInt sysdrive = iFs.GetSystemDrive(); + TInt err = iFs.CreatePrivatePath(sysdrive); + if (err != KErrNone && err != KErrAlreadyExists) + qWarning("Failed to create private path on system drive."); + //BC with 4.7: set working directory to same drive as application + TFileName pfn = RProcess().FileName(); + TInt drive; + if (pfn.Length() > 0 && iFs.CharToDrive(pfn[0], drive) == KErrNone) { + // for system drive or rom based apps, leave the path on system drive + if (drive != sysdrive && drive != EDriveZ) { + err = iFs.CreatePrivatePath(drive); + if (err == KErrNone || err == KErrAlreadyExists) + iFs.SetSessionToPrivate(drive); + else + qWarning("Failed to create private path on application drive."); + } + } } ~QS60RFsSession() { diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 752bbaa..c4a9e40 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1991,12 +1991,6 @@ QString QCoreApplication::applicationDirPath() appPath = qt_TDesC2QString(privatePath); appPath.prepend(QLatin1Char(':')).prepend(qDriveChar); - // Create the appPath if it doesn't exist. Non-existing appPath will cause - // Platform Security violations later on if the app doesn't have AllFiles capability. - err = fs.CreatePrivatePath(drive); - if (err != KErrNone) - qWarning("QCoreApplication::applicationDirPath: Failed to create private path."); - d->cachedApplicationDirPath = QFileInfo(appPath).path(); } #else -- cgit v0.12 From 8d9e63130767858287331d7e19d732919d620607 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 26 Sep 2011 10:46:53 +0300 Subject: Fix plugin implicit loading when calling QPluginLoader::instance(). QPluginLoader::instance() didn't increase loading refcount if another QPluginLoader had already loaded the plugin. This meant that if the another QPluginLoader subsequently unloaded the plugin, the instance would be destroyed even if the second loader still wanted to use it. Also improved the tst_QPluginLoader::deleteinstanceOnUnload() test case to test more combinations of deletion order and explicit/implicit loading. Task-number: QT-5259 Reviewed-by: Sami Merila --- src/corelib/plugin/qpluginloader.cpp | 2 +- tests/auto/qpluginloader/tst_qpluginloader.cpp | 29 ++++++++++++++++++-------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index bbb64e4..9f9ea1a 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -198,7 +198,7 @@ QPluginLoader::~QPluginLoader() */ QObject *QPluginLoader::instance() { - if (!isLoaded() && !load()) + if (!load()) return 0; if (!d->inst && d->instance) d->inst = d->instance(); diff --git a/tests/auto/qpluginloader/tst_qpluginloader.cpp b/tests/auto/qpluginloader/tst_qpluginloader.cpp index d2d92a5..152d1f4 100644 --- a/tests/auto/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/qpluginloader/tst_qpluginloader.cpp @@ -272,10 +272,10 @@ void tst_QPluginLoader::loadHints() void tst_QPluginLoader::deleteinstanceOnUnload() { - for (int pass = 0; pass < 2; ++pass) { + for (int pass = 0; pass < 4; ++pass) { QPluginLoader loader1; loader1.setFileName( sys_qualifiedLibraryName("theplugin")); //a plugin - if (pass == 0) + if (pass < 2) loader1.load(); // not recommended, instance() should do the job. PluginInterface *instance1 = qobject_cast(loader1.instance()); QVERIFY(instance1); @@ -283,21 +283,32 @@ void tst_QPluginLoader::deleteinstanceOnUnload() QPluginLoader loader2; loader2.setFileName( sys_qualifiedLibraryName("theplugin")); //a plugin - if (pass == 0) + if (pass < 2) loader2.load(); // not recommended, instance() should do the job. PluginInterface *instance2 = qobject_cast(loader2.instance()); QCOMPARE(instance2->pluginName(), QLatin1String("Plugin ok")); QSignalSpy spy1(loader1.instance(), SIGNAL(destroyed())); QSignalSpy spy2(loader2.instance(), SIGNAL(destroyed())); - if (pass == 0) { - QCOMPARE(loader2.unload(), false); // refcount not reached 0, not really unloaded - QCOMPARE(spy1.count(), 0); - QCOMPARE(spy2.count(), 0); - } + + // refcount not reached 0, not really unloaded + if (pass % 2) + QCOMPARE(loader1.unload(), false); + else + QCOMPARE(loader2.unload(), false); + + QCOMPARE(spy1.count(), 0); + QCOMPARE(spy2.count(), 0); + QCOMPARE(instance1->pluginName(), QLatin1String("Plugin ok")); QCOMPARE(instance2->pluginName(), QLatin1String("Plugin ok")); - QVERIFY(loader1.unload()); // refcount reached 0, did really unload + + // refcount reached 0, did really unload + if (pass % 2) + QVERIFY(loader2.unload()); + else + QVERIFY(loader1.unload()); + QCOMPARE(spy1.count(), 1); QCOMPARE(spy2.count(), 1); } -- cgit v0.12 From aa73a64e7997af3a029be32753c248a21e6961fb Mon Sep 17 00:00:00 2001 From: "Jarkko T. Toivonen" Date: Mon, 26 Sep 2011 12:51:48 +0300 Subject: Lower case as default in password entry in Symbian port. The text case "Abc" is removed from the permitted cases because passwords are rarely sentences but random characters. Task-number: QTBUG-10312 Reviewed-by: Shane Kearns --- src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 56338b2..87c4045 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -755,6 +755,9 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints) } else if (hints & ImhNoAutoUppercase) { m_fepState->SetDefaultCase(EAknEditorLowerCase); m_fepState->SetCurrentCase(EAknEditorLowerCase); + } else if (hints & ImhHiddenText) { + m_fepState->SetDefaultCase(EAknEditorLowerCase); + m_fepState->SetCurrentCase(EAknEditorLowerCase); } else { m_fepState->SetDefaultCase(EAknEditorTextCase); m_fepState->SetCurrentCase(EAknEditorTextCase); @@ -766,6 +769,10 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints) if (hints & ImhLowercaseOnly) { flags |= EAknEditorLowerCase; } + if (hints & ImhHiddenText) { + flags = EAknEditorAllCaseModes; + flags &= ~EAknEditorTextCase; + } if (flags == 0) { flags = EAknEditorAllCaseModes; if (hints & ImhNoAutoUppercase) { -- cgit v0.12 From 26341f6060434b6cbc08d98df34c2d2aee56a70c Mon Sep 17 00:00:00 2001 From: Juha Kukkonen Date: Mon, 26 Sep 2011 08:25:50 +0300 Subject: Fix QXmlQuery autotest failure. Changed XQuery functions fn:doc() and fn:doc-available() to work with URLs without scheme when accessing files. Task-number: QT-4962 Reviewed-by: Honglei Zhang --- src/xmlpatterns/functions/qsequencegeneratingfns.cpp | 20 ++++++++++++++++++-- .../qabstractxmlnodemodel/qabstractxmlnodemodel.pro | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/xmlpatterns/functions/qsequencegeneratingfns.cpp b/src/xmlpatterns/functions/qsequencegeneratingfns.cpp index 6215f3d..3f3dbbb 100644 --- a/src/xmlpatterns/functions/qsequencegeneratingfns.cpp +++ b/src/xmlpatterns/functions/qsequencegeneratingfns.cpp @@ -41,6 +41,7 @@ #include #include +#include #include "qanyuri_p.h" #include "qboolean_p.h" @@ -207,6 +208,21 @@ Item::Iterator::Ptr IdrefFN::evaluateSequence(const DynamicContext::Ptr &context return CommonValues::emptyIterator; /* TODO Haven't implemented further. */ } +/*! + * Attemps to resolve scheme if URL does not have scheme defined. + */ +static QUrl resolveScheme(const QUrl &url) +{ + // On Windows and Symbian the drive letter is detected as the scheme. + if (url.scheme().isEmpty() || (url.scheme().length() == 1)) { + QString filename = url.toString(); + QFileInfo file(filename); + if (file.exists()) + return QUrl::fromLocalFile(filename); + } + return url; +} + Item DocFN::evaluateSingleton(const DynamicContext::Ptr &context) const { const Item itemURI(m_operands.first()->evaluateSingleton(context)); @@ -219,7 +235,7 @@ Item DocFN::evaluateSingleton(const DynamicContext::Ptr &context) const * as part of a workaround for solaris-cc-64. DocFN::typeCheck() is in qsequencefns.cpp * as part of that workaround. */ const QUrl mayRela(AnyURI::toQUrl(itemURI.stringValue(), context, this)); - const QUrl uri(context->resolveURI(mayRela, staticBaseURI())); + const QUrl uri(resolveScheme(context->resolveURI(mayRela, staticBaseURI()))); Q_ASSERT(uri.isValid()); Q_ASSERT(!uri.isRelative()); @@ -251,7 +267,7 @@ bool DocAvailableFN::evaluateEBV(const DynamicContext::Ptr &context) const /* These two lines are duplicated in DocFN::evaluateSingleton(), as part * of a workaround for solaris-cc-64. */ const QUrl mayRela(AnyURI::toQUrl(itemURI.stringValue(), context, this)); - const QUrl uri(context->resolveURI(mayRela, staticBaseURI())); + const QUrl uri(resolveScheme(context->resolveURI(mayRela, staticBaseURI()))); Q_ASSERT(!uri.isRelative()); return context->resourceLoader()->isDocumentAvailable(uri); diff --git a/tests/auto/qabstractxmlnodemodel/qabstractxmlnodemodel.pro b/tests/auto/qabstractxmlnodemodel/qabstractxmlnodemodel.pro index b8f509d..90a99c0 100644 --- a/tests/auto/qabstractxmlnodemodel/qabstractxmlnodemodel.pro +++ b/tests/auto/qabstractxmlnodemodel/qabstractxmlnodemodel.pro @@ -6,7 +6,7 @@ HEADERS += TestNodeModel.h LoadingModel.h include (../xmlpatterns.pri) -wince*: { +wince*|symbian: { addFiles.files = tree.xml addFiles.path = . -- cgit v0.12 From 5f161591b6ae25524b129bf4a41d6438f0a4d402 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 28 Sep 2011 10:08:55 +0300 Subject: Fix QTextBrowser autotest to use "file" scheme in URLs. A security fix to QUrl that causes it to no longer interpret URLs without scheme as local files broke QTextBrowser test case. Added the necessary "file" schemes to URLs used in the test. Also added a mention about necessity of using "file" scheme to QTextBrowser documentation. Task-number: QT-5286 Reviewed-by: Sami Merila --- src/gui/widgets/qtextbrowser.cpp | 3 ++- tests/auto/qtextbrowser/tst_qtextbrowser.cpp | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/gui/widgets/qtextbrowser.cpp b/src/gui/widgets/qtextbrowser.cpp index cd8fa11..e786c5c 100644 --- a/src/gui/widgets/qtextbrowser.cpp +++ b/src/gui/widgets/qtextbrowser.cpp @@ -619,7 +619,8 @@ void QTextBrowserPrivate::restoreHistoryEntry(const HistoryEntry entry) If you want to load documents stored in the Qt resource system use \c{qrc} as the scheme in the URL to load. For example, for the document resource path \c{:/docs/index.html} use \c{qrc:/docs/index.html} as - the URL with setSource(). + the URL with setSource(). To access local files, use \c{file} as the + scheme in the URL. \sa QTextEdit, QTextDocument */ diff --git a/tests/auto/qtextbrowser/tst_qtextbrowser.cpp b/tests/auto/qtextbrowser/tst_qtextbrowser.cpp index f36b335..4489daa 100644 --- a/tests/auto/qtextbrowser/tst_qtextbrowser.cpp +++ b/tests/auto/qtextbrowser/tst_qtextbrowser.cpp @@ -146,7 +146,7 @@ void tst_QTextBrowser::cleanup() void tst_QTextBrowser::noReloadOnAnchorJump() { - QUrl url("anchor.html"); + QUrl url("file:anchor.html"); browser->htmlLoadAttempts = 0; browser->setSource(url); @@ -162,7 +162,7 @@ void tst_QTextBrowser::noReloadOnAnchorJump() void tst_QTextBrowser::bgColorOnSourceChange() { - browser->setSource(QUrl("pagewithbg.html")); + browser->setSource(QUrl("file:pagewithbg.html")); QVERIFY(browser->document()->rootFrame()->frameFormat().hasProperty(QTextFormat::BackgroundBrush)); QVERIFY(browser->document()->rootFrame()->frameFormat().background().color() == Qt::blue); @@ -179,7 +179,7 @@ void tst_QTextBrowser::forwardButton() QVERIFY(browser->historyTitle(0).isEmpty()); QVERIFY(browser->historyTitle(1).isEmpty()); - browser->setSource(QUrl("pagewithbg.html")); + browser->setSource(QUrl("file:pagewithbg.html")); QVERIFY(!forwardEmissions.isEmpty()); QVariant val = forwardEmissions.takeLast()[0]; @@ -192,7 +192,7 @@ void tst_QTextBrowser::forwardButton() QVERIFY(val.toBool() == false); QVERIFY(browser->historyTitle(-1).isEmpty()); - QCOMPARE(browser->historyUrl(0), QUrl("pagewithbg.html")); + QCOMPARE(browser->historyUrl(0), QUrl("file:pagewithbg.html")); QCOMPARE(browser->documentTitle(), QString("Page With BG")); QCOMPARE(browser->historyTitle(0), QString("Page With BG")); QVERIFY(browser->historyTitle(1).isEmpty()); @@ -244,7 +244,7 @@ void tst_QTextBrowser::forwardButton() void tst_QTextBrowser::viewportPositionInHistory() { - browser->setSource(QUrl("bigpage.html")); + browser->setSource(QUrl("file:bigpage.html")); browser->scrollToAnchor("bottom"); QVERIFY(browser->verticalScrollBar()->value() > 0); @@ -283,7 +283,7 @@ void tst_QTextBrowser::relativeLinks() void tst_QTextBrowser::anchors() { - browser->setSource(QUrl("bigpage.html")); + browser->setSource(QUrl("file:bigpage.html")); browser->setSource(QUrl("#bottom")); QVERIFY(browser->verticalScrollBar()->value() > 0); @@ -306,7 +306,7 @@ void tst_QTextBrowser::forwardBackwardAvailable() QVERIFY(!browser->isBackwardAvailable()); QVERIFY(!browser->isForwardAvailable()); - browser->setSource(QUrl("anchor.html")); + browser->setSource(QUrl("file:anchor.html")); QVERIFY(!browser->isBackwardAvailable()); QVERIFY(!browser->isForwardAvailable()); QCOMPARE(backwardSpy.count(), 1); @@ -406,7 +406,7 @@ void tst_QTextBrowser::clearHistory() backwardSpy.clear(); forwardSpy.clear(); - browser->setSource(QUrl("anchor.html")); + browser->setSource(QUrl("file:anchor.html")); QVERIFY(!browser->isBackwardAvailable()); QVERIFY(!browser->isForwardAvailable()); QCOMPARE(backwardSpy.count(), 1); @@ -447,7 +447,7 @@ void tst_QTextBrowser::clearHistory() void tst_QTextBrowser::sourceInsideLoadResource() { - QUrl url("pagewithimage.html"); + QUrl url("file:pagewithimage.html"); browser->setSource(url); QCOMPARE(browser->lastResource.toString(), QUrl::fromLocalFile(QDir::current().filePath("foobar.png")).toString()); QEXPECT_FAIL("", "This is currently not supported", Continue); @@ -532,7 +532,7 @@ void tst_QTextBrowser::adjacentAnchors() void tst_QTextBrowser::loadResourceOnRelativeLocalFiles() { - browser->setSource(QUrl("subdir/index.html")); + browser->setSource(QUrl("file:subdir/index.html")); QVERIFY(!browser->toPlainText().isEmpty()); QVariant v = browser->loadResource(QTextDocument::HtmlResource, QUrl("../anchor.html")); QVERIFY(v.isValid()); @@ -543,7 +543,7 @@ void tst_QTextBrowser::loadResourceOnRelativeLocalFiles() void tst_QTextBrowser::focusIndicator() { HackBrowser *browser = new HackBrowser; - browser->setSource(QUrl("firstpage.html")); + browser->setSource(QUrl("file:firstpage.html")); QVERIFY(!browser->textCursor().hasSelection()); browser->focusTheNextChild(); @@ -595,7 +595,7 @@ void tst_QTextBrowser::focusIndicator() void tst_QTextBrowser::focusHistory() { HackBrowser *browser = new HackBrowser; - browser->setSource(QUrl("firstpage.html")); + browser->setSource(QUrl("file:firstpage.html")); QVERIFY(!browser->textCursor().hasSelection()); browser->focusTheNextChild(); -- cgit v0.12 From eef7c0674d667e1a932a58944a80a0046d08445a Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 28 Sep 2011 10:23:28 +0300 Subject: Fix building against older Symbian^3 environments R_AVKON_DISCREET_POPUP_TEXT_COPIED is missing from some older Symbian^3 environments, so define it explicitly. Also do not attempt to show the popup unless running against newer versions. Reviewed-by: Sami Merila --- src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index e7084ac..3546079 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -94,6 +94,11 @@ #define QT_EPSUidAknFep 0x100056de #define QT_EAknFepTouchInputActive 0x00000004 +// For compatibility with older Symbian^3 environments, which do not have this define yet. +#ifndef R_AVKON_DISCREET_POPUP_TEXT_COPIED +#define R_AVKON_DISCREET_POPUP_TEXT_COPIED 0x8cc0227 +#endif + _LIT(KAvkonResourceFile, "z:\\resource\\avkon.rsc" ); QT_BEGIN_NAMESPACE @@ -1624,11 +1629,13 @@ void QCoeFepInputContext::copyOrCutTextToClipboard(const char *operation) if (cursor != anchor) { if (ccpuInvokeSlot(w, focusObject, operation)) { - TRAP_IGNORE( - CAknDiscreetPopup::ShowGlobalPopupL( - R_AVKON_DISCREET_POPUP_TEXT_COPIED, - KAvkonResourceFile); - ) + if (QSysInfo::symbianVersion() > QSysInfo::SV_SF_3) { + TRAP_IGNORE( + CAknDiscreetPopup::ShowGlobalPopupL( + R_AVKON_DISCREET_POPUP_TEXT_COPIED, + KAvkonResourceFile); + ) + } } } } -- cgit v0.12 From 827ba304d068eed1c0bd1dacbfbbe82115f43bd2 Mon Sep 17 00:00:00 2001 From: mread Date: Tue, 27 Sep 2011 17:08:07 +0100 Subject: Making QNotifyChangeEvent, Symbian file watcher, more widely usable QNotifyChangeEvent was being used by QSymbianFileSystemWatcherEngine, but it also helps in the implementation of new plugin watching for QTBUG-20098. So it has been generalised to work with an interface and any class that implements that interface. The Qt file system watchers could not be used in QTBUG-20098, as they will not watch for currently non-existing directories. Task-number: QTBUG-20098 Reviewed-by: Shane Kearns --- src/corelib/io/qfilesystemwatcher_symbian.cpp | 10 +++++----- src/corelib/io/qfilesystemwatcher_symbian_p.h | 18 ++++++++++++------ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_symbian.cpp b/src/corelib/io/qfilesystemwatcher_symbian.cpp index 63cc4f1..fa857c6 100644 --- a/src/corelib/io/qfilesystemwatcher_symbian.cpp +++ b/src/corelib/io/qfilesystemwatcher_symbian.cpp @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE QNotifyChangeEvent::QNotifyChangeEvent(RFs &fs, const TDesC &file, - QSymbianFileSystemWatcherEngine *e, bool aIsDir, + QSymbianFileSystemWatcherInterface *e, bool aIsDir, TInt aPriority) : CActive(aPriority), isDir(aIsDir), @@ -96,9 +96,9 @@ void QNotifyChangeEvent::RunL() if (!failureCount) { int err; - QT_TRYCATCH_ERROR(err, engine->emitPathChanged(this)); + QT_TRYCATCH_ERROR(err, engine->handlePathChanged(this)); if (err != KErrNone) - qWarning("QNotifyChangeEvent::RunL() - emitPathChanged threw exception (Converted error code: %d)", err); + qWarning("QNotifyChangeEvent::RunL() - handlePathChanged threw exception (Converted error code: %d)", err); } } } @@ -203,7 +203,7 @@ QStringList QSymbianFileSystemWatcherEngine::removePaths(const QStringList &path return p; } -void QSymbianFileSystemWatcherEngine::emitPathChanged(QNotifyChangeEvent *e) +void QSymbianFileSystemWatcherEngine::handlePathChanged(QNotifyChangeEvent *e) { QMutexLocker locker(&mutex); @@ -255,7 +255,7 @@ void QSymbianFileSystemWatcherEngine::addNativeListener(const QString &directory QMutexLocker locker(&mutex); QString nativeDir(QDir::toNativeSeparators(directoryPath)); TPtrC ptr(qt_QString2TPtrC(nativeDir)); - currentAddEvent = new QNotifyChangeEvent(qt_s60GetRFs(), ptr, this, directoryPath.endsWith(QChar(L'/'), Qt::CaseSensitive)); + currentAddEvent = q_check_ptr(new QNotifyChangeEvent(qt_s60GetRFs(), ptr, this, directoryPath.endsWith(QChar(L'/')))); syncCondition.wakeOne(); } diff --git a/src/corelib/io/qfilesystemwatcher_symbian_p.h b/src/corelib/io/qfilesystemwatcher_symbian_p.h index 0b317a0..842df80 100644 --- a/src/corelib/io/qfilesystemwatcher_symbian_p.h +++ b/src/corelib/io/qfilesystemwatcher_symbian_p.h @@ -66,29 +66,35 @@ QT_BEGIN_NAMESPACE -class QSymbianFileSystemWatcherEngine; +class QSymbianFileSystemWatcherInterface; class QNotifyChangeEvent : public CActive { public: - QNotifyChangeEvent(RFs &fsSession, const TDesC &file, QSymbianFileSystemWatcherEngine *engine, + QNotifyChangeEvent(RFs &fsSession, const TDesC &file, QSymbianFileSystemWatcherInterface *engine, bool aIsDir, TInt aPriority = EPriorityStandard); ~QNotifyChangeEvent(); bool isDir; + TPath watchedPath; private: void RunL(); void DoCancel(); RFs &fsSession; - TPath watchedPath; - QSymbianFileSystemWatcherEngine *engine; + QSymbianFileSystemWatcherInterface *engine; int failureCount; }; -class QSymbianFileSystemWatcherEngine : public QFileSystemWatcherEngine +class QSymbianFileSystemWatcherInterface +{ +public: + virtual void handlePathChanged(QNotifyChangeEvent *e) = 0; +}; + +class QSymbianFileSystemWatcherEngine : public QFileSystemWatcherEngine, public QSymbianFileSystemWatcherInterface { Q_OBJECT @@ -111,7 +117,7 @@ public Q_SLOTS: private: friend class QNotifyChangeEvent; - void emitPathChanged(QNotifyChangeEvent *e); + void handlePathChanged(QNotifyChangeEvent *e); void startWatcher(); -- cgit v0.12 From 820b50807b18f3a08c250566482cdab33e0a5be4 Mon Sep 17 00:00:00 2001 From: mread Date: Wed, 28 Sep 2011 11:01:44 +0100 Subject: Added Symbian private API to update libraryPaths Library paths on Symbian can change as memory cards are inserted or removed. Potentially there is a \resource\qt\plugins on a card which should be added to the library path. Since some Symbian Qt applications are expected to be very long running, they would not see an updated library path without this abililty to update the path. The update algorithm strips out existing instances of \resource\qt\plugins, places new ones where the first \resource\qt\plugins was, and leaves the rest of the library path unchanged. Task-number: QTBUG-20098 Reviewed-by: Shane Kearns --- src/corelib/kernel/qcoreapplication.cpp | 75 +++++++++++++++++++++++++-------- src/corelib/kernel/qcoreapplication_p.h | 3 ++ 2 files changed, 61 insertions(+), 17 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index c4a9e40..2eb68f7 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -2329,6 +2329,33 @@ QString QCoreApplication::applicationVersion() #ifndef QT_NO_LIBRARY +#if defined(Q_OS_SYMBIAN) +void qt_symbian_installLibraryPaths(QString installPathPlugins, QStringList& libPaths) +{ + // Add existing path on all drives for relative PluginsPath in Symbian + QString tempPath = installPathPlugins; + if (tempPath.at(tempPath.length() - 1) != QDir::separator()) { + tempPath += QDir::separator(); + } + RFs& fs = qt_s60GetRFs(); + TPtrC tempPathPtr(reinterpret_cast (tempPath.constData())); + // Symbian searches should start from Y:. Fix start drive otherwise TFindFile starts from the session drive + _LIT(KStartDir, "Y:"); + TFileName dirPath(KStartDir); + dirPath.Append(tempPathPtr); + TFindFile finder(fs); + TInt err = finder.FindByDir(tempPathPtr, dirPath); + while (err == KErrNone) { + QString foundDir(reinterpret_cast(finder.File().Ptr()), + finder.File().Length()); + foundDir = QDir(foundDir).canonicalPath(); + if (!libPaths.contains(foundDir)) + libPaths.append(foundDir); + err = finder.Find(); + } +} +#endif + Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive)) /*! @@ -2361,24 +2388,8 @@ QStringList QCoreApplication::libraryPaths() QStringList *app_libpaths = coreappdata()->app_libpaths = new QStringList; QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath); #if defined(Q_OS_SYMBIAN) - // Add existing path on all drives for relative PluginsPath in Symbian if (installPathPlugins.at(1) != QChar(QLatin1Char(':'))) { - QString tempPath = installPathPlugins; - if (tempPath.at(tempPath.length() - 1) != QDir::separator()) { - tempPath += QDir::separator(); - } - RFs& fs = qt_s60GetRFs(); - TPtrC tempPathPtr(reinterpret_cast (tempPath.constData())); - TFindFile finder(fs); - TInt err = finder.FindByDir(tempPathPtr, tempPathPtr); - while (err == KErrNone) { - QString foundDir(reinterpret_cast(finder.File().Ptr()), - finder.File().Length()); - foundDir = QDir(foundDir).canonicalPath(); - if (!app_libpaths->contains(foundDir)) - app_libpaths->append(foundDir); - err = finder.Find(); - } + qt_symbian_installLibraryPaths(installPathPlugins, *app_libpaths); } #else if (QFile::exists(installPathPlugins)) { @@ -2493,6 +2504,36 @@ void QCoreApplication::removeLibraryPath(const QString &path) QFactoryLoader::refreshAll(); } +#if defined(Q_OS_SYMBIAN) +void QCoreApplicationPrivate::rebuildInstallLibraryPaths() +{ + // check there is not a single fixed install path + QString nativeInstallPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath); + if (nativeInstallPathPlugins.at(1) == QChar(QLatin1Char(':'))) + return; + QString installPathPlugins = QDir::cleanPath(nativeInstallPathPlugins); + // look for the install path at the drive roots + installPathPlugins.prepend(QChar(QLatin1Char(':'))); + + QMutexLocker locker(libraryPathMutex()); + QStringList &app_libpaths = *coreappdata()->app_libpaths; + // Build a new library path, copying non-installPath components, and replacing existing install path with new + QStringList newPaths; + bool installPathFound = false; + foreach (QString path, app_libpaths) { + if (path.mid(1).compare(installPathPlugins, Qt::CaseInsensitive) == 0) { + // skip existing install paths, insert new install path when we find the first + if (!installPathFound) + qt_symbian_installLibraryPaths(nativeInstallPathPlugins, newPaths); + installPathFound = true; + } else { + newPaths.append(path); + } + } + app_libpaths = newPaths; +} +#endif + #endif //QT_NO_LIBRARY /*! diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index c6c6489..6f75da3 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -126,6 +126,9 @@ public: void symbianInit(); # endif static CApaCommandLine* symbianCommandLine(); +#ifndef QT_NO_LIBRARY + static void rebuildInstallLibraryPaths(); +#endif #endif static bool isTranslatorInstalled(QTranslator *translator); -- cgit v0.12 From 9ae99f01d3bdeedc254c44f99fe49d1fb5633261 Mon Sep 17 00:00:00 2001 From: mread Date: Wed, 28 Sep 2011 11:05:02 +0100 Subject: New plugin detection for Symbian Symbian can have very long running apps, which expect to pick up new plugins without a restart. This change makes the plugin factory, which is used for many internal plugin types, detect plugin changes and update its list of plugins. This uses the QNotifyChangeEvent class to watch for plugin directory changes, including when they do not already exist, including on removable drives with no media currently present. When a change is detected, it triggers a rebuild of the plugin library paths, then rescans for plugins only on the drive that changed. An alternative implementation could have made use of watching software installer P&S keys for notification of change. However these are not triggered by memory card insertion or removal, so file system watchers are used. Task-number: QTBUG-20098 Reviewed-by: Shane Kearns --- src/corelib/plugin/qfactoryloader.cpp | 239 +++++++++++++++++++++++----------- src/corelib/plugin/qfactoryloader_p.h | 1 + 2 files changed, 164 insertions(+), 76 deletions(-) diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index c8831e5..24b4be0 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -50,8 +50,13 @@ #include "qmutex.h" #include "qplugin.h" #include "qpluginloader.h" +#include "qlibraryinfo.h" #include "private/qobject_p.h" #include "private/qcoreapplication_p.h" +#ifdef Q_OS_SYMBIAN +#include "private/qcore_symbian_p.h" +#include "private/qfilesystemwatcher_symbian_p.h" +#endif QT_BEGIN_NAMESPACE @@ -59,6 +64,23 @@ Q_GLOBAL_STATIC(QList, qt_factory_loaders) Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_factoryloader_mutex, (QMutex::Recursive)) +#ifdef Q_OS_SYMBIAN +class QSymbianSystemPluginWatcher : public QSymbianFileSystemWatcherInterface +{ +public: + QSymbianSystemPluginWatcher(); + ~QSymbianSystemPluginWatcher(); + + void watchForUpdates(); + void handlePathChanged(QNotifyChangeEvent *e); + + QList watchers; + TDriveList drives; +}; + +Q_GLOBAL_STATIC(QSymbianSystemPluginWatcher, qt_symbian_system_plugin_watcher) +#endif + class QFactoryLoaderPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QFactoryLoader) @@ -98,102 +120,117 @@ QFactoryLoader::QFactoryLoader(const char *iid, QMutexLocker locker(qt_factoryloader_mutex()); update(); qt_factory_loaders()->append(this); +#ifdef Q_OS_SYMBIAN + // kick off Symbian plugin watcher for updates + qt_symbian_system_plugin_watcher(); +#endif } - -void QFactoryLoader::update() +void QFactoryLoader::updateDir(const QString &pluginDir, QSettings& settings) { -#ifdef QT_SHARED Q_D(QFactoryLoader); - QStringList paths = QCoreApplication::libraryPaths(); - QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); - for (int i = 0; i < paths.count(); ++i) { - const QString &pluginDir = paths.at(i); - // Already loaded, skip it... - if (d->loadedPaths.contains(pluginDir)) - continue; - d->loadedPaths << pluginDir; + QString path = pluginDir + d->suffix; + if (!QDir(path).exists(QLatin1String("."))) + return; - QString path = pluginDir + d->suffix; - if (!QDir(path).exists(QLatin1String("."))) - continue; + QStringList plugins = QDir(path).entryList(QDir::Files); + QLibraryPrivate *library = 0; + for (int j = 0; j < plugins.count(); ++j) { + QString fileName = QDir::cleanPath(path + QLatin1Char('/') + plugins.at(j)); - QStringList plugins = QDir(path).entryList(QDir::Files); - QLibraryPrivate *library = 0; - for (int j = 0; j < plugins.count(); ++j) { - QString fileName = QDir::cleanPath(path + QLatin1Char('/') + plugins.at(j)); + if (qt_debug_component()) { + qDebug() << "QFactoryLoader::QFactoryLoader() looking at" << fileName; + } + library = QLibraryPrivate::findOrCreate(QFileInfo(fileName).canonicalFilePath()); + if (!library->isPlugin(&settings)) { if (qt_debug_component()) { - qDebug() << "QFactoryLoader::QFactoryLoader() looking at" << fileName; + qDebug() << library->errorString; + qDebug() << " not a plugin"; } - library = QLibraryPrivate::findOrCreate(QFileInfo(fileName).canonicalFilePath()); - if (!library->isPlugin(&settings)) { + library->release(); + continue; + } + QString regkey = QString::fromLatin1("Qt Factory Cache %1.%2/%3:/%4") + .arg((QT_VERSION & 0xff0000) >> 16) + .arg((QT_VERSION & 0xff00) >> 8) + .arg(QLatin1String(d->iid)) + .arg(fileName); + QStringList reg, keys; + reg = settings.value(regkey).toStringList(); + if (reg.count() && library->lastModified == reg[0]) { + keys = reg; + keys.removeFirst(); + } else { + if (!library->loadPlugin()) { if (qt_debug_component()) { qDebug() << library->errorString; - qDebug() << " not a plugin"; + qDebug() << " could not load"; } library->release(); continue; } - QString regkey = QString::fromLatin1("Qt Factory Cache %1.%2/%3:/%4") - .arg((QT_VERSION & 0xff0000) >> 16) - .arg((QT_VERSION & 0xff00) >> 8) - .arg(QLatin1String(d->iid)) - .arg(fileName); - QStringList reg, keys; - reg = settings.value(regkey).toStringList(); - if (reg.count() && library->lastModified == reg[0]) { - keys = reg; - keys.removeFirst(); - } else { - if (!library->loadPlugin()) { - if (qt_debug_component()) { - qDebug() << library->errorString; - qDebug() << " could not load"; - } - library->release(); - continue; - } - QObject *instance = library->instance(); - if (!instance) { - library->release(); - // ignore plugins that have a valid signature but cannot be loaded. - continue; - } - QFactoryInterface *factory = qobject_cast(instance); - if (instance && factory && instance->qt_metacast(d->iid)) - keys = factory->keys(); - if (keys.isEmpty()) - library->unload(); - reg.clear(); - reg << library->lastModified; - reg += keys; - settings.setValue(regkey, reg); - } - if (qt_debug_component()) { - qDebug() << "keys" << keys; - } - - if (keys.isEmpty()) { + QObject *instance = library->instance(); + if (!instance) { library->release(); + // ignore plugins that have a valid signature but cannot be loaded. continue; } - d->libraryList += library; - for (int k = 0; k < keys.count(); ++k) { - // first come first serve, unless the first - // library was built with a future Qt version, - // whereas the new one has a Qt version that fits - // better - QString key = keys.at(k); - if (!d->cs) - key = key.toLower(); - QLibraryPrivate *previous = d->keyMap.value(key); - if (!previous || (previous->qt_version > QT_VERSION && library->qt_version <= QT_VERSION)) { - d->keyMap[key] = library; - d->keyList += keys.at(k); - } + QFactoryInterface *factory = qobject_cast(instance); + if (instance && factory && instance->qt_metacast(d->iid)) + keys = factory->keys(); + if (keys.isEmpty()) + library->unload(); + reg.clear(); + reg << library->lastModified; + reg += keys; + settings.setValue(regkey, reg); + } + if (qt_debug_component()) { + qDebug() << "keys" << keys; + } + + if (keys.isEmpty()) { + library->release(); + continue; + } + + int keysUsed = 0; + for (int k = 0; k < keys.count(); ++k) { + // first come first serve, unless the first + // library was built with a future Qt version, + // whereas the new one has a Qt version that fits + // better + QString key = keys.at(k); + if (!d->cs) + key = key.toLower(); + QLibraryPrivate *previous = d->keyMap.value(key); + if (!previous || (previous->qt_version > QT_VERSION && library->qt_version <= QT_VERSION)) { + d->keyMap[key] = library; + d->keyList += keys.at(k); + keysUsed++; } } + if (keysUsed) + d->libraryList += library; + else + library->release(); + } +} + +void QFactoryLoader::update() +{ +#ifdef QT_SHARED + Q_D(QFactoryLoader); + QStringList paths = QCoreApplication::libraryPaths(); + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + for (int i = 0; i < paths.count(); ++i) { + const QString &pluginDir = paths.at(i); + // Already loaded, skip it... + if (d->loadedPaths.contains(pluginDir)) + continue; + d->loadedPaths << pluginDir; + updateDir(pluginDir, settings); } #else Q_D(QFactoryLoader); @@ -264,6 +301,56 @@ void QFactoryLoader::refreshAll() } } +#ifdef Q_OS_SYMBIAN +QSymbianSystemPluginWatcher::QSymbianSystemPluginWatcher() +{ + qt_s60GetRFs().DriveList(drives); + watchForUpdates(); +} + +QSymbianSystemPluginWatcher::~QSymbianSystemPluginWatcher() +{ + qDeleteAll(watchers); +} + +void QSymbianSystemPluginWatcher::watchForUpdates() +{ + QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath); + if (installPathPlugins.at(1) == QChar(QLatin1Char(':'))) + return; + + installPathPlugins.prepend(QLatin1String("?:")); + installPathPlugins = QDir::toNativeSeparators(installPathPlugins); + RFs& fs = qt_s60GetRFs(); + for (int i=0; iwatchedPath))); + QList *loaders = qt_factory_loaders(); + for (QList::const_iterator it = loaders->constBegin(); + it != loaders->constEnd(); ++it) { + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + (*it)->updateDir(dirName, settings); + } +} + +#endif + QT_END_NAMESPACE #endif // QT_NO_LIBRARY diff --git a/src/corelib/plugin/qfactoryloader_p.h b/src/corelib/plugin/qfactoryloader_p.h index e90ebf6..8548ab2 100644 --- a/src/corelib/plugin/qfactoryloader_p.h +++ b/src/corelib/plugin/qfactoryloader_p.h @@ -82,6 +82,7 @@ public: #endif void update(); + void updateDir(const QString &pluginDir, QSettings& settings); static void refreshAll(); }; -- cgit v0.12 From a01fe35b0a9d63e5d51389213a866a81830f0f9e Mon Sep 17 00:00:00 2001 From: mread Date: Wed, 28 Sep 2011 13:32:20 +0100 Subject: Added new private exports to DEF files This change lists new private exports in the Symbian def files for: - QCoreApplicationPrivate::rebuildInstallLibraryPaths - QFactoryLoader::updateDir There are also some QFutureWatcherBase exports added to the winscw DEF file which appear to have not been added before. Task-number: QTBUG-20098 Reviewed-by: Shane Kearns --- src/s60installs/bwins/QtCoreu.def | 5 +++++ src/s60installs/eabi/QtCoreu.def | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def index be09295..3437502 100644 --- a/src/s60installs/bwins/QtCoreu.def +++ b/src/s60installs/bwins/QtCoreu.def @@ -4879,4 +4879,9 @@ EXPORTS ?languageId@QLocalePrivate@@QBEGXZ @ 4878 NONAME ; unsigned short QLocalePrivate::languageId(void) const ?started@QFutureWatcherBase@@IAEXXZ @ 4879 NONAME ; void QFutureWatcherBase::started(void) ?staticMetaObjectExtraData@QAbstractState@@0UQMetaObjectExtraData@@B @ 4880 NONAME ; struct QMetaObjectExtraData const QAbstractState::staticMetaObjectExtraData + ?rebuildInstallLibraryPaths@QCoreApplicationPrivate@@SAXXZ @ 4881 NONAME ; void QCoreApplicationPrivate::rebuildInstallLibraryPaths(void) + ?connectNotify@QFutureWatcherBase@@MAEXPBD@Z @ 4882 NONAME ; void QFutureWatcherBase::connectNotify(char const *) + ?event@QFutureWatcherBase@@UAE_NPAVQEvent@@@Z @ 4883 NONAME ; bool QFutureWatcherBase::event(class QEvent *) + ?updateDir@QFactoryLoader@@QAEXABVQString@@AAVQSettings@@@Z @ 4884 NONAME ; void QFactoryLoader::updateDir(class QString const &, class QSettings &) + ?disconnectNotify@QFutureWatcherBase@@MAEXPBD@Z @ 4885 NONAME ; void QFutureWatcherBase::disconnectNotify(char const *) diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index cf42b67..1fabdb2 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -4162,4 +4162,6 @@ EXPORTS inflateReset2 @ 4161 NONAME inflateUndermine @ 4162 NONAME zlibCompileFlags @ 4163 NONAME + _ZN14QFactoryLoader9updateDirERK7QStringR9QSettings @ 4164 NONAME + _ZN23QCoreApplicationPrivate26rebuildInstallLibraryPathsEv @ 4165 NONAME -- cgit v0.12 From ed9e0cae2e99d16a311727873ff349b45bd61d13 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Wed, 28 Sep 2011 15:48:36 +0300 Subject: New focusitem is not connected to the translate slot in splitview If user changes focus from one item to a new one while the splitview keyboard is open, the newly focused item is not connected to the translate() slot. Thus, the item will not be kept "automatically" visible above the keyboard when cursor position changes. QCoeFepInputContext now holds a pointer to the last focus item and disconnects the previous focus item from slot when new focus item is set. Ensuring the visibility of the focus item needs to be done asynchronously after reset() has been called from graphics scene, to ensure that new focus item has been set. The translation rules have been tweaked to support translation to both directions (up|down). Previous implementation worked properly only for upwards translation (new cursor position was assumed to be lower than the existing one). Task-number: QTBUG-21611 Reviewed-by: Miikka Heikkinen --- src/gui/inputmethod/qcoefepinputcontext_p.h | 2 + src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 77 +++++++++++++++++-------- 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h index 8ef9726..ad51b4b 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_p.h +++ b/src/gui/inputmethod/qcoefepinputcontext_p.h @@ -136,6 +136,7 @@ private: private Q_SLOTS: void ensureInputCapabilitiesChanged(); void translateInputWidget(); + void ensureWidgetVisibility(); // From MCoeFepAwareTextEditor public: @@ -208,6 +209,7 @@ private: int m_splitViewResizeBy; Qt::WindowStates m_splitViewPreviousWindowStates; QRectF m_transformation; + QGraphicsItem *m_splitViewPreviousFocusItem; //can't use QPointer<> since QGraphicsItem is not a QObject. CAknCcpuSupport *m_ccpu; QAction *m_copyAction; diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 3546079..bacf07a 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -382,6 +382,7 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent) m_hasTempPreeditString(false), m_splitViewResizeBy(0), m_splitViewPreviousWindowStates(Qt::WindowNoState), + m_splitViewPreviousFocusItem(0), m_ccpu(0) { m_fepState->SetObjectProvider(this); @@ -451,6 +452,11 @@ void QCoeFepInputContext::reset() if (m_cachedPreeditString.isEmpty() && !(currentHints & Qt::ImhNoPredictiveText)) m_cachedPreeditString = m_preeditString; commitCurrentString(true); + + // QGraphicsScene calls reset() when changing focus item. Unfortunately, the new focus item is + // set right after resetting the input context. Therefore, asynchronously call ensureWidgetVisibility(). + if (S60->splitViewLastWidget) + QMetaObject::invokeMethod(this,"ensureWidgetVisibility", Qt::QueuedConnection); } void QCoeFepInputContext::ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType) @@ -793,9 +799,8 @@ void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget) { QGraphicsView *gv = qobject_cast(S60->splitViewLastWidget); - if (!gv) { + if (!gv) return; - } QSymbianControl *symControl = static_cast(gv->effectiveWinId()); symControl->CancelLongTapTimer(); @@ -810,11 +815,13 @@ void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget) if (!alwaysResize) { if (gv->scene() && S60->partial_keyboardAutoTranslation) { if (gv->scene()->focusItem()) { + QGraphicsItem *focusItem = + m_splitViewPreviousFocusItem ? m_splitViewPreviousFocusItem : gv->scene()->focusItem(); // Check if the widget contains cursorPositionChanged signal and disconnect from it. QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged())); - int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1)); + int index = focusItem->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1)); if (index != -1) - disconnect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget())); + disconnect(focusItem->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget())); } QGraphicsItem *rootItem = 0; @@ -882,6 +889,11 @@ bool QCoeFepInputContext::isPartialKeyboardSupported() return (S60->partial_keyboard || !QApplication::testAttribute(Qt::AA_S60DisablePartialScreenInputMode)); } +void QCoeFepInputContext::ensureWidgetVisibility() +{ + ensureFocusWidgetVisible(S60->splitViewLastWidget); +} + // Ensure that the input widget is visible in the splitview rect. void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget) @@ -913,17 +925,22 @@ void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget) // states getting changed. if (!moveWithinVisibleArea) { - // Check if the widget contains cursorPositionChanged signal and connect to it. - QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged())); - if (gv->scene() && gv->scene()->focusItem() && S60->partial_keyboardAutoTranslation) { - int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1)); - if (index != -1) - connect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget())); - } S60->splitViewLastWidget = widget; m_splitViewPreviousWindowStates = windowToMove->windowState(); } + // Check if the widget contains cursorPositionChanged signal and connect to it. + if (gv->scene() && gv->scene()->focusItem() && S60->partial_keyboardAutoTranslation) { + QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged())); + if (m_splitViewPreviousFocusItem && m_splitViewPreviousFocusItem != gv->scene()->focusItem()) + disconnect(m_splitViewPreviousFocusItem->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget())); + int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1)); + if (index != -1) { + connect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget())); + m_splitViewPreviousFocusItem = gv->scene()->focusItem(); + } + } + int windowTop = widget->window()->pos().y(); const bool userResize = widget->testAttribute(Qt::WA_Resized); @@ -1266,10 +1283,15 @@ void QCoeFepInputContext::translateInputWidget() m_transformation = (rootItem->transform().isTranslating()) ? QRectF(0,0, gv->width(), rootItem->transform().dy()) : QRectF(); - // Adjust cursor bounding rect to be lower, so that view translates if the cursor gets near - // the splitview border. - QRect cursorRect = cursorP.boundingRect().adjusted(0, cursor.height(), 0, cursor.height()); - if (splitViewRect.contains(cursorRect)) + // Adjust cursor bounding rect towards navigation direction, + // so that view translates if the cursor gets near the splitview border. + QRect cursorRect = (cursorP.boundingRect().top() < 0) ? + cursorP.boundingRect().adjusted(0, -cursor.height(), 0, -cursor.height()) : + cursorP.boundingRect().adjusted(0, cursor.height(), 0, cursor.height()); + + // If the current cursor position and upcoming cursor positions are visible in the splitview + // area, do not move the view. + if (splitViewRect.contains(cursorRect) && splitViewRect.contains(cursorP.boundingRect())) return; // New Y position should be ideally just above the keyboard. @@ -1281,22 +1303,29 @@ void QCoeFepInputContext::translateInputWidget() const qreal itemHeight = path.boundingRect().height(); // Limit the maximum translation so that underlaying window content is not exposed. - qreal maxY = gv->sceneRect().bottom() - splitViewRect.bottom(); - maxY = m_transformation.height() ? (qMin(itemHeight, maxY) + m_transformation.height()) : maxY; - if (maxY < 0) - maxY = 0; + qreal availableSpace = gv->sceneRect().bottom() - splitViewRect.bottom(); + availableSpace = m_transformation.height() ? + (qMin(itemHeight, availableSpace) + m_transformation.height()) : + availableSpace; // Translation should happen row-by-row, but initially it needs to ensure that cursor is visible. const qreal translation = m_transformation.height() ? cursor.height() : (cursorRect.bottom() - vkbRect.top()); - qreal dy = -(qMin(maxY, translation)); + qreal dy = 0.0; + if (availableSpace > 0) + dy = -(qMin(availableSpace, translation)); + else + dy = -(translation); - // Correct the translation direction, if the cursor rect would be moved outside of application area. - if ((cursorRect.bottom() + dy) < 0) + // Correct the translation direction, if the cursor rect would be moved above application area. + if ((cursorP.boundingRect().bottom() + dy) < 0) dy *= -1; - // Do not allow transform above screen top, nor beyond scenerect - if (m_transformation.height() + dy > 0 || gv->sceneRect().bottom() + m_transformation.height() < 0) { + // Do not allow transform above screen top, nor beyond scenerect. Also, if there is no available + // space anymore, skip translation. + if ((m_transformation.height() + dy) > 0 + || (gv->sceneRect().bottom() + m_transformation.height()) < 0 + || !availableSpace) { // If we already have some transformation, remove it. if (m_transformation.height() < 0 || gv->sceneRect().bottom() + m_transformation.height() < 0) { rootItem->resetTransform(); -- cgit v0.12 From 783f1de86112745eb4fca3bb0a8d75a4197a70c9 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 28 Sep 2011 11:39:53 +0100 Subject: symbian - document behaviour of QFile::handle() --- src/corelib/io/qfile.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 06c403a..d08574d 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -1332,6 +1332,13 @@ bool QFile::open(const RFile &f, OpenMode mode, FileHandleFlags handleFlags) This function is not supported on Windows CE. + On Symbian, this function returns -1 if the file was opened normally, + as Symbian OS native file handles do not fit in an int, and are + incompatible with C library functions that the handle would be used for. + If the file was opened using the overloads that take an open C library + file handle / file descriptor, then this function returns that same + handle. + \sa QSocketNotifier */ -- cgit v0.12 From c4699f8940d4bb0ecd462f323c6acc3619b15b1c Mon Sep 17 00:00:00 2001 From: mread Date: Thu, 29 Sep 2011 14:54:27 +0100 Subject: QTBUG-9113 - reinstating tst_qobjectrace tests for Symbian on Qt 4.8 tst_qobjectrace had some of its tests disabled for Symbian builds because they were not working with Symbian's event dispatcher. Retesting with Qt 4.8, which has a new event dispatcher, shows that they are now working. The tests are re-enabled again. They ran successfully on E7, N8 and emulator many times without crashing. Task-number: QTBUG-9113 Reviewed-by: Shane Kearns --- tests/auto/qobjectrace/tst_qobjectrace.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/auto/qobjectrace/tst_qobjectrace.cpp b/tests/auto/qobjectrace/tst_qobjectrace.cpp index 1f52aec..f9ec6ce 100644 --- a/tests/auto/qobjectrace/tst_qobjectrace.cpp +++ b/tests/auto/qobjectrace/tst_qobjectrace.cpp @@ -139,11 +139,6 @@ private slots: void tst_QObjectRace::moveToThreadRace() { -#if defined(Q_OS_SYMBIAN) - // ### FIXME: task 257411 - remove xfail once this is fixed - QEXPECT_FAIL("", "Symbian event dispatcher can't handle this kind of race, see task: 257411", Abort); - QVERIFY(false); -#endif RaceObject *object = new RaceObject; enum { ThreadCount = 6 }; @@ -229,13 +224,6 @@ public: void tst_QObjectRace::destroyRace() { -#if defined(Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86) - // ### FIXME: task 257411 - remove xfail once this is fixed. - // Oddly enough, this seems to work properly in HW, if given enough time and memory. - QEXPECT_FAIL("", "Symbian event dispatcher can't handle this kind of race on emulator, see task: 257411", Abort); - QVERIFY(false); -#endif - enum { ThreadCount = 10, ObjectCountPerThread = 733, ObjectCount = ThreadCount * ObjectCountPerThread }; -- cgit v0.12 From 6570a4612ebf128a140c0ed66ac83bfaf9670b44 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 30 Sep 2011 12:52:17 +0300 Subject: Do not crash in copy() of pixmaps without an underlying bitmap If CFbsBitmap::Create() fails for some reason (e.g. due to lack of memory), we may end up with a QVolatileImage for which the underlying bitmap pointer is null, resulting in the QImage wrapper being null too. The copyFrom() function was not checking for this situation and started to copy data blindly to the null QImage's bits(), which is a null pointer. This is now fixed so no copying occurs in such a scenario. Task-number: QTTH-1446 Reviewed-by: Sami Merila --- src/gui/image/qvolatileimage.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/gui/image/qvolatileimage.cpp b/src/gui/image/qvolatileimage.cpp index 9734c82..350d70f 100644 --- a/src/gui/image/qvolatileimage.cpp +++ b/src/gui/image/qvolatileimage.cpp @@ -248,12 +248,14 @@ void QVolatileImage::copyFrom(QVolatileImage *source, const QRect &rect) const uchar *sptr = srcImgRef.constBits() + r.y() * srcbpl; beginDataAccess(); QImage &dstImgRef(imageRef()); - int dstbpl = dstImgRef.bytesPerLine(); - uchar *dptr = dstImgRef.bits(); - for (int y = 0; y < r.height(); ++y) { - qMemCopy(dptr, sptr + r.x() * srcbpp, r.width() * srcbpp); - sptr += srcbpl; - dptr += dstbpl; + if (!dstImgRef.isNull()) { + int dstbpl = dstImgRef.bytesPerLine(); + uchar *dptr = dstImgRef.bits(); + for (int y = 0; y < r.height(); ++y) { + qMemCopy(dptr, sptr + r.x() * srcbpp, r.width() * srcbpp); + sptr += srcbpl; + dptr += dstbpl; + } } endDataAccess(); source->endDataAccess(true); -- cgit v0.12 From b4fb55db3939219e976d53c32b42bf28acaa41b1 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 30 Sep 2011 14:01:37 +0300 Subject: Symbian: Parse ts filenames case-insensitively for localize_deployment A lot of platform applications have all-lowercase translation files due to file naming policies. This makes no difference for runtime translation, so removed unnecessary case sensitivity when parsing ts filenames for localization deployment. Task-number: QT-5305 Reviewed-by: Sami Merila --- mkspecs/common/symbian/symbian.conf | 13 ++++---- mkspecs/features/symbian/localize_deployment.prf | 38 ++++++++++++------------ qmake/generators/symbian/symbiancommon.cpp | 1 + 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 61a6228..c50dc77 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -151,11 +151,11 @@ SYMBIAN_SUPPORTED_LANGUAGES = \ mr mo mn nb pl pt pa ro ru sr \ si sk sl so es sw sv tl ta te \ th bo ti tr tk uk ur vi cy zu \ - nn eu zh gl fa st en_US fr_BE \ - pt_BR en_CA fr_CA el_CY tr_CY \ - en_TW en_HK en_CN en_JP en_TH \ - sv_FI zh_HK es_419 en_ZA fr_CH \ - de_CH it_CH zh_TW + nn eu zh gl fa st en_us fr_be \ + pt_br en_ca fr_ca el_cy tr_cy \ + en_tw en_hk en_cn en_jp en_th \ + sv_fi zh_hk es_419 en_za fr_ch \ + de_ch it_ch zh_tw # These directories must match what configure uses for QT_INSTALL_PLUGINS and QT_INSTALL_IMPORTS QT_PLUGINS_BASE_DIR = /resource/qt$${QT_LIBINFIX}/plugins @@ -251,7 +251,8 @@ defineTest(matchSymbianLanguages) { # Cannot parse .ts file for language here, so detect it from filename. # Allow two and three character language and country codes. for(translation, TRANSLATIONS) { - language = $$replace(translation, "^(.*/)?[^/]+_(([^_]{2,3}_)?[^_]{2,3})\\.ts$", \\2) + low_translation = $$lower($$translation) + language = $$replace(low_translation, "^(.*/)?[^/]+_(([^_]{2,3}_)?[^_]{2,3})\\.ts$", \\2) !contains(HANDLED_LANGUAGES, $$language) { HANDLED_LANGUAGES += $$language # Make sure translation path is absolute or shadow builds will not work diff --git a/mkspecs/features/symbian/localize_deployment.prf b/mkspecs/features/symbian/localize_deployment.prf index 185c713..3e7f585 100644 --- a/mkspecs/features/symbian/localize_deployment.prf +++ b/mkspecs/features/symbian/localize_deployment.prf @@ -76,26 +76,26 @@ SYMBIAN_LANG.cy = 97 #Welsh SYMBIAN_LANG.zu = 98 #Zulu # Regional dialects -SYMBIAN_LANG.en_US = 10 #American English -SYMBIAN_LANG.fr_BE = 21 #Belgian French -SYMBIAN_LANG.pt_BR = 76 #Brazilian Portuguese -SYMBIAN_LANG.en_CA = 46 #Canadian English -SYMBIAN_LANG.fr_CA = 51 #Canadian French -SYMBIAN_LANG.el_CY = 55 #Cyprus Greek -SYMBIAN_LANG.tr_CY = 91 #Cyprus Turkish -SYMBIAN_LANG.en_TW = 157 #English as appropriate for use in Taiwan -SYMBIAN_LANG.en_HK = 158 #English as appropriate for use in Hong Kong -SYMBIAN_LANG.en_CN = 159 #English as appropriate for use in the Peoples Republic of China -SYMBIAN_LANG.en_JP = 160 #English as appropriate for use in Japan -SYMBIAN_LANG.en_TH = 161 #English as appropriate for use in Thailand -SYMBIAN_LANG.sv_FI = 85 #Finland Swedish -SYMBIAN_LANG.zh_HK = 30 #HongKong Chinese +SYMBIAN_LANG.en_us = 10 #American English +SYMBIAN_LANG.fr_be = 21 #Belgian French +SYMBIAN_LANG.pt_br = 76 #Brazilian Portuguese +SYMBIAN_LANG.en_ca = 46 #Canadian English +SYMBIAN_LANG.fr_ca = 51 #Canadian French +SYMBIAN_LANG.el_cy = 55 #Cyprus Greek +SYMBIAN_LANG.tr_cy = 91 #Cyprus Turkish +SYMBIAN_LANG.en_tw = 157 #English as appropriate for use in Taiwan +SYMBIAN_LANG.en_hk = 158 #English as appropriate for use in Hong Kong +SYMBIAN_LANG.en_cn = 159 #English as appropriate for use in the Peoples Republic of China +SYMBIAN_LANG.en_jp = 160 #English as appropriate for use in Japan +SYMBIAN_LANG.en_th = 161 #English as appropriate for use in Thailand +SYMBIAN_LANG.sv_fi = 85 #Finland Swedish +SYMBIAN_LANG.zh_hk = 30 #HongKong Chinese SYMBIAN_LANG.es_419 = 83 #Latin American Spanish -SYMBIAN_LANG.en_ZA = 48 #South African English -SYMBIAN_LANG.fr_CH = 11 #Swiss French -SYMBIAN_LANG.de_CH = 12 #Swiss German -SYMBIAN_LANG.it_CH = 61 #Swiss Italian -SYMBIAN_LANG.zh_TW = 29 #Taiwan Chinese +SYMBIAN_LANG.en_za = 48 #South African English +SYMBIAN_LANG.fr_ch = 11 #Swiss French +SYMBIAN_LANG.de_ch = 12 #Swiss German +SYMBIAN_LANG.it_ch = 61 #Swiss Italian +SYMBIAN_LANG.zh_tw = 29 #Taiwan Chinese isEmpty(SYMBIAN_MATCHED_LANGUAGES) { matchSymbianLanguages() diff --git a/qmake/generators/symbian/symbiancommon.cpp b/qmake/generators/symbian/symbiancommon.cpp index 2c4373a..8db82d6 100644 --- a/qmake/generators/symbian/symbiancommon.cpp +++ b/qmake/generators/symbian/symbiancommon.cpp @@ -850,6 +850,7 @@ void SymbianCommonGenerator::parseTsFiles(SymbianLocalizationList *symbianLocali foreach (QString file, symbianTsFiles) { QRegExp matcher(matchStr); + matcher.setCaseSensitivity(Qt::CaseInsensitive); if (matcher.exactMatch(file) && parseTsContent(file, &loc)) break; } -- cgit v0.12 From c9ff25ec9ca7a9c00e4aea7b7ff23e34064a2a1f Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 22 Sep 2011 15:57:31 +0100 Subject: runonphone - Implement CODA autodetection If runonphone is executed without specifying the debug agent, then it will attempt to autodetect it by sending a CODA ping to the USB port. If there is a reply within 1 second, then CODA mode is used. If not, then TRK mode is used. TRK drops unrecognised messages, so the CODA ping is ignored and initialisation starts normally when the TRK ping is sent. Autodetect can be skipped by using the --coda or --trk arguments on the command line to force use of a specific debug agent. Reviewed-By: mread --- tools/runonphone/codasignalhandler.cpp | 10 ++++--- tools/runonphone/main.cpp | 31 ++++++++++++++++++---- .../symbianutils/symbiandevicemanager.cpp | 3 +++ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/tools/runonphone/codasignalhandler.cpp b/tools/runonphone/codasignalhandler.cpp index 2de6fbc..1df7834 100644 --- a/tools/runonphone/codasignalhandler.cpp +++ b/tools/runonphone/codasignalhandler.cpp @@ -188,10 +188,15 @@ int CodaSignalHandler::run() connect(this, SIGNAL(done()), this, SLOT(finished())); d->codaDevice->sendSerialPing(false); - if (d->timeout > 0) - QTimer::singleShot(d->timeout, this, SLOT(timeout())); + QTimer timer; + if (d->timeout > 0) { + connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); + timer.setSingleShot(true); + timer.start(d->timeout); + } d->eventLoop = new QEventLoop(); d->eventLoop->exec(); + timer.stop(); int result = d->result; reportMessage(tr("Done.")); @@ -199,7 +204,6 @@ int CodaSignalHandler::run() disconnect(d->codaDevice.data(), 0, this, 0); SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(d->codaDevice); - QCoreApplication::quit(); return result; } diff --git a/tools/runonphone/main.cpp b/tools/runonphone/main.cpp index 39fa983..6dd53fc 100644 --- a/tools/runonphone/main.cpp +++ b/tools/runonphone/main.cpp @@ -70,7 +70,8 @@ void printUsage(QTextStream& outstream, QString exeName) << "-T, --tempfile specify temporary sis file name" << endl << "--nocrashlog Don't capture call stack if test crashes" << endl << "--crashlogpath Path to save crash logs (default=working dir)" << endl - << "--coda Use CODA instead of TRK (default agent)" << endl + << "--coda Use CODA instead of detecting the debug agent" << endl + << "--trk Use TRK instead of detecting the debug agent" << endl << endl << "USB COM ports can usually be autodetected, use -p or -f to force a specific port." << endl << "TRK is the default debugging agent, use --coda option when using CODA instead of TRK." << endl @@ -99,7 +100,7 @@ int main(int argc, char *argv[]) int loglevel=1; int timeout=0; bool crashlog = true; - bool coda = false; + enum {AgentUnknown, AgentCoda, AgentTRK} debugAgent = AgentUnknown; QString crashlogpath; QListIterator it(args); it.next(); //skip name of program @@ -154,7 +155,9 @@ int main(int argc, char *argv[]) } } else if (arg == "--coda") - coda = true; + debugAgent = AgentCoda; + else if (arg == "--trk") + debugAgent = AgentTRK; else if (arg == "--tempfile" || arg == "-T") { CHECK_PARAMETER_EXISTS dstName = it.next(); @@ -225,7 +228,24 @@ int main(int argc, char *argv[]) QFileInfo info(exeFile); QFileInfo uploadInfo(uploadLocalFile); - if (coda) { + if (debugAgent == AgentUnknown) { + outstream << "detecting debug agent..." << endl; + CodaSignalHandler codaDetector; + //auto detect agent + codaDetector.setSerialPortName(serialPortName); + codaDetector.setLogLevel(loglevel); + codaDetector.setActionType(ActionPingOnly); + codaDetector.setTimeout(1000); + if (!codaDetector.run()) { + debugAgent = AgentCoda; + outstream << " - Coda is found" << endl; + } else { + debugAgent = AgentTRK; + outstream << " - Coda is not found, defaulting to TRK" << endl; + } + } + + if (debugAgent == AgentCoda) { codaHandler.setSerialPortName(serialPortName); codaHandler.setLogLevel(loglevel); @@ -257,7 +277,8 @@ int main(int argc, char *argv[]) return codaHandler.run(); } else { - launcher.reset(new trk::Launcher(trk::Launcher::ActionPingOnly)); + launcher.reset(new trk::Launcher(trk::Launcher::ActionPingOnly, + SymbianUtils::SymbianDeviceManager::instance()->acquireDevice(serialPortName))); QStringList srcNames, dstNames; if (!sisFile.isEmpty()) { launcher->addStartupActions(trk::Launcher::ActionCopyInstall); diff --git a/tools/runonphone/symbianutils/symbiandevicemanager.cpp b/tools/runonphone/symbianutils/symbiandevicemanager.cpp index e8d0b5e..0b7f581 100644 --- a/tools/runonphone/symbianutils/symbiandevicemanager.cpp +++ b/tools/runonphone/symbianutils/symbiandevicemanager.cpp @@ -183,6 +183,9 @@ SymbianDevice::TrkDevicePtr SymbianDevice::acquireDevice() << "acquired: " << m_data->deviceAcquired << " open: " << isOpen(); if (isNull() || m_data->deviceAcquired) return TrkDevicePtr(); + //if port was opened for coda (but is not acquired) then close it first. + if (m_data->codaDevice) + m_data->codaDevice->device()->close(); if (m_data->device.isNull()) { m_data->device = TrkDevicePtr(new trk::TrkDevice); m_data->device->setPort(m_data->portName); -- cgit v0.12 From 8610ee14b8636641651a8ba6040cca16c4141ed6 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 3 Oct 2011 16:27:34 +0100 Subject: QNAM - fix poor performance of HEAD request with authentication QHttpNetworkReply was waiting for a body to be sent for 401 and 407 responses, whereas with a HTTP HEAD request, there will be no body. This delayed the authentication signal until after the http channel is closed by the server after a timeout. For example with the server used for autotesting, the authentication signal is delayed 15 seconds. When the server has a very long timeout, the authentication signal may not be emitted at all. Task-Number: QT-5304 Reviewed-By: Martin Petersson --- src/network/access/qhttpnetworkreply.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 1a02200..6173b39 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -891,7 +891,7 @@ bool QHttpNetworkReplyPrivate::expectContent() || statusCode == 204 || statusCode == 304) return false; if (request.operation() == QHttpNetworkRequest::Head) - return !shouldEmitSignals(); + return false; // no body expected for HEAD request qint64 expectedContentLength = contentLength(); if (expectedContentLength == 0) return false; -- cgit v0.12 From 3dfaa160e19c3563d0c229fbdb951d314adc918c Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 3 Oct 2011 16:29:43 +0100 Subject: Create auto test for http HEAD request This is in order to have a regression test for QT-5304. However the test is also checking basic functionality of head requests too. Task-Number: QT-5304 Reviewed-By: Martin Petersson --- tests/auto/qnetworkreply/.gitattributes | 1 + tests/auto/qnetworkreply/index.html | 3 ++ tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 61 ++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 tests/auto/qnetworkreply/index.html diff --git a/tests/auto/qnetworkreply/.gitattributes b/tests/auto/qnetworkreply/.gitattributes index 80252cf..7fa30e3 100644 --- a/tests/auto/qnetworkreply/.gitattributes +++ b/tests/auto/qnetworkreply/.gitattributes @@ -1,3 +1,4 @@ rfc3252.txt -crlf bigfile -crlf resource -crlf +index.html -crlf diff --git a/tests/auto/qnetworkreply/index.html b/tests/auto/qnetworkreply/index.html new file mode 100644 index 0000000..135db79 --- /dev/null +++ b/tests/auto/qnetworkreply/index.html @@ -0,0 +1,3 @@ +

Welcome to qt-test-server

+fluke +

This is a network test server. It serves as a cacheing ftp and http proxy, transparent http/socks5 proxy, imap, ftp and http server, plus more.

diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 70287a9..3d1e35e 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -197,6 +197,8 @@ private Q_SLOTS: void getFromHttp(); void getErrors_data(); void getErrors(); + void headFromHttp_data(); + void headFromHttp(); void putToFile_data(); void putToFile(); void putToFtp_data(); @@ -1610,6 +1612,65 @@ void tst_QNetworkReply::getFromHttp() QCOMPARE(reply->readAll(), reference.readAll()); } +void tst_QNetworkReply::headFromHttp_data() +{ + QTest::addColumn("referenceSize"); + QTest::addColumn("url"); + QTest::addColumn("contentType"); + QTest::addColumn("proxy"); + + qint64 rfcsize = QFileInfo(SRCDIR "/rfc3252.txt").size(); + qint64 bigfilesize = QFileInfo(SRCDIR "/bigfile").size(); + qint64 indexsize = QFileInfo(SRCDIR "/index.html").size(); + + //testing proxies, mainly for the 407 response from http proxy + for (int i = 0; i < proxies.count(); ++i) { + QTest::newRow("rfc" + proxies.at(i).tag) << rfcsize << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt") << "text/plain" << proxies.at(i).proxy; + QTest::newRow("bigfile" + proxies.at(i).tag) << bigfilesize << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile") << "text/plain" << proxies.at(i).proxy; + QTest::newRow("index" + proxies.at(i).tag) << indexsize << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/") << "text/html" << proxies.at(i).proxy; + QTest::newRow("with-authentication" + proxies.at(i).tag) << rfcsize << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt") << "text/plain" << proxies.at(i).proxy; + QTest::newRow("cgi" + proxies.at(i).tag) << (qint64)-1 << QUrl("http://qt-test-server/qtest/cgi-bin/httpcachetest_expires500.cgi") << "text/html" << proxies.at(i).proxy; + } +} + +void tst_QNetworkReply::headFromHttp() +{ + QFETCH(qint64, referenceSize); + QFETCH(QUrl, url); + QFETCH(QString, contentType); + QFETCH(QNetworkProxy, proxy); + + QNetworkRequest request(url); + QNetworkReplyPtr reply; + + QElapsedTimer time; + time.start(); + + manager.setProxy(proxy); + connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); + connect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); + + RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::HeadOperation, request, reply)); + + manager.disconnect(SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); + manager.disconnect(SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); + + QVERIFY(time.elapsed() < 8000); //check authentication didn't wait for the server to timeout the http connection (15s on qt test server) + + QCOMPARE(reply->url(), request.url()); + QCOMPARE(reply->error(), QNetworkReply::NoError); + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + // only compare when the header is set. + if (reply->header(QNetworkRequest::ContentLengthHeader).isValid() && referenceSize >= 0) + QCOMPARE(reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(), referenceSize); + if (reply->header(QNetworkRequest::ContentTypeHeader).isValid()) + QCOMPARE(reply->header(QNetworkRequest::ContentTypeHeader).toString(), contentType); +} + void tst_QNetworkReply::getErrors_data() { QTest::addColumn("url"); -- cgit v0.12 From 6b716b286095a6810aa8318b68c5df32f06bc710 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 4 Oct 2011 15:16:00 +0300 Subject: Symbian: Fix native dialog with splitscreen VKB focus loss issue If a native input dialog that utilized splitscreen VKB was opened while focus was on QML TextEdit element, the focus would not be restored to QML TextEdit element after native dialog was closed. This happened because the KSplitViewCloseEvent came after FocusChanged, as the focus changes are ignored while splitview VKB is open. Task-number: QTBUG-21733 Reviewed-by: Sami Merila --- src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 3 +++ src/gui/kernel/qapplication_s60.cpp | 9 ++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index bacf07a..0f9f0db 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -898,6 +898,9 @@ void QCoeFepInputContext::ensureWidgetVisibility() void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget) { + if (!widget) + return; + // Native side opening and closing its virtual keyboard when it changes the keyboard layout, // has an adverse impact on long tap timer. Cancel the timer when splitview opens to avoid this. QSymbianControl *symControl = static_cast(widget->effectiveWinId()); diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 80bcdf0..03da630 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1493,12 +1493,15 @@ void QSymbianControl::handleClientAreaChange() } } -bool QSymbianControl::isSplitViewWidget(QWidget *widget) { +bool QSymbianControl::isSplitViewWidget(QWidget *widget) +{ bool returnValue = true; - //Ignore events sent to non-active windows, not visible widgets and not parents of input widget. + // Ignore events sent to non-active windows, not visible widgets and not parents of input widget + // and non-Qt dialogs. if (!qwidget->isActiveWindow() || !qwidget->isVisible() - || !qwidget->isAncestorOf(widget)) { + || !qwidget->isAncestorOf(widget) + || CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) { returnValue = false; } -- cgit v0.12 From 06e3ef571d9acd53d8277fbaac357c170a6db22c Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Wed, 5 Oct 2011 14:08:42 +0300 Subject: Remove one local variable from QCoeFepInputContext Remove hasText variable as it is not used anywhere. Reviewed-by: Miikka Heikkinen --- src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 0f9f0db..f18d32c 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -1644,8 +1644,6 @@ void QCoeFepInputContext::changeCBA(bool showCopyAndOrPaste) void QCoeFepInputContext::copyOrCutTextToClipboard(const char *operation) { - bool hasText = false; - QWidget *w = focusWidget(); QObject *focusObject = 0; if (!w) { -- cgit v0.12 From 0520b1ce10dc2358d663ee08b53b7de9ce41bb23 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Wed, 5 Oct 2011 14:14:50 +0300 Subject: Ignore CcpuCan calls if input context is being destroyed If input context is being destroyed while its ability to paste/copy/cut is inquired from native side, just return false. This makes application exit somewhat faster. Reviewed-by: Miikka Heikkinen --- src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index f18d32c..ff74afe 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -1744,6 +1744,8 @@ TBool QCoeFepInputContext::CcpuIsFocused() const TBool QCoeFepInputContext::CcpuCanCut() const { bool retval = false; + if (m_inDestruction) + return retval; QWidget *w = focusWidget(); if (!w) w = m_lastFocusedEditor; @@ -1775,6 +1777,9 @@ void QCoeFepInputContext::CcpuCopyL() TBool QCoeFepInputContext::CcpuCanPaste() const { bool canPaste = false; + if (m_inDestruction) + return canPaste; + QString textToPaste = QApplication::clipboard()->text(); if (!textToPaste.isEmpty()) { QWidget *w = focusWidget(); -- cgit v0.12 From 2a6298bcf29104a4258992c7357a031f4ca9cc7f Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Wed, 5 Oct 2011 15:06:31 +0300 Subject: Copy and Cut are not available for some QML editors Copy and Cut actions do not appear in fullscreen VKB menu when a QML TextEdit or TextInput element is focused and has selected text. This happens because input method queries for cursor and anchor position in QCoeFepInputContext::CcpuCanCut() return zero in this case. It is probably related to focus changes when the options menu pops up. When menu pops up from native keyboard, window containing the QML elements is set as non-active, therefore it loses focus widget, which in turn causes queries about cursor and anchor positions to return zero. As a workaround, when there is no microfocus available, ask the "selectedText" property directly from QML elements. Task-number: QTBUG-21568 Reviewed-by: Miikka Heikkinen --- src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 28 +++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index ff74afe..8f13c53 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -1747,14 +1747,30 @@ TBool QCoeFepInputContext::CcpuCanCut() const if (m_inDestruction) return retval; QWidget *w = focusWidget(); - if (!w) + QObject *focusObject = 0; + if (!w) { w = m_lastFocusedEditor; - else - w = getQWidgetFromQGraphicsView(w); + focusObject = m_lastFocusedObject; + } else { + w = getQWidgetFromQGraphicsView(w, &focusObject); + } if (w) { - int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt(); - int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt(); - retval = cursor != anchor; + QRect microFocus = w->inputMethodQuery(Qt::ImMicroFocus).toRect(); + if (microFocus.isNull()) { + // For some reason, the editor does not have microfocus. Most probably, + // it is due to using native fullscreen editing mode with QML apps. + // Try accessing "selectedText" directly. + QObject *invokeTarget = w; + if (focusObject) + invokeTarget = focusObject; + + QString selectedText = invokeTarget->property("selectedText").toString(); + retval = !selectedText.isNull(); + } else { + int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt(); + int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt(); + retval = cursor != anchor; + } } return retval; } -- cgit v0.12 From 6e1b00087902866cd4c0e3057690d045356869f0 Mon Sep 17 00:00:00 2001 From: mread Date: Wed, 5 Oct 2011 16:40:26 +0100 Subject: Converting accidental use of doubles to qreal in declarative Declarative had a number of places where double operations were used instead of qreal, due to the use of double literals. These are now constructed as qreal literals so that qreal operations are used. This makes no difference where qreal is double. But on Symbian, qreal is float, and this give a performance boost for floating point intensive code. Task-number: QTBUG-4894 Reviewed-by: Martin Jones --- .../graphicsitems/qdeclarativeflipable.cpp | 4 +-- .../graphicsitems/qdeclarativegridview.cpp | 6 ++-- .../graphicsitems/qdeclarativelistview.cpp | 6 ++-- .../graphicsitems/qdeclarativepathview.cpp | 28 +++++++-------- src/declarative/util/qdeclarativeanimation.cpp | 2 +- .../util/qdeclarativesmoothedanimation.cpp | 42 +++++++++++----------- .../util/qdeclarativespringanimation.cpp | 8 ++--- .../util/qdeclarativestateoperations.cpp | 2 +- src/declarative/util/qdeclarativexmllistmodel.cpp | 2 +- 9 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflipable.cpp b/src/declarative/graphicsitems/qdeclarativeflipable.cpp index 70fc702..4dcf17c 100644 --- a/src/declarative/graphicsitems/qdeclarativeflipable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflipable.cpp @@ -228,9 +228,9 @@ void QDeclarativeFlipablePrivate::updateSceneTransformFromParent() if (current == QDeclarativeFlipable::Back && back) setBackTransform(); if (front) - front->setOpacity((current==QDeclarativeFlipable::Front)?1.:0.); + front->setOpacity((current==QDeclarativeFlipable::Front)?qreal(1.):qreal(0.)); if (back) - back->setOpacity((current==QDeclarativeFlipable::Back)?1.:0.); + back->setOpacity((current==QDeclarativeFlipable::Back)?qreal(1.):qreal(0.)); emit q->sideChanged(); } } diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 023737d..a7d593a 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1212,10 +1212,10 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m } qreal accel = deceleration; qreal v2 = v * v; - qreal overshootDist = 0.0; - if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarativeGridView::SnapOneRow) { + qreal overshootDist = qreal(0.0); + if ((maxDistance > qreal(0.0) && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarativeGridView::SnapOneRow) { // + rowSize()/4 to encourage moving at least one item in the flick direction - qreal dist = v2 / (accel * 2.0) + rowSize()/4; + qreal dist = v2 / (accel * qreal(2.0)) + rowSize()/4; dist = qMin(dist, maxDistance); if (v > 0) dist = -dist; diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 6a91e5f..44d6a1a 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -1457,14 +1457,14 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m // the initial flick - estimate boundary qreal accel = deceleration; qreal v2 = v * v; - overshootDist = 0.0; + overshootDist = qreal(0.0); // + averageSize/4 to encourage moving at least one item in the flick direction - qreal dist = v2 / (accel * 2.0) + averageSize/4; + qreal dist = v2 / (accel * qreal(2.0)) + averageSize/4; if (maxDistance > 0) dist = qMin(dist, maxDistance); if (v > 0) dist = -dist; - if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarativeListView::SnapOneItem) { + if ((maxDistance > qreal(0.0) && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarativeListView::SnapOneItem) { if (snapMode != QDeclarativeListView::SnapOneItem) { qreal distTemp = isRightToLeft() ? -dist : dist; data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + distTemp) + highlightStart; diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index 94f128d..ecd8982 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -246,7 +246,7 @@ void QDeclarativePathViewPrivate::updateHighlight() } else { qreal target = currentIndex; - offsetAdj = 0.0; + offsetAdj = qreal(0.0); tl.reset(moveHighlight); moveHighlight.setValue(highlightPosition); @@ -255,14 +255,14 @@ void QDeclarativePathViewPrivate::updateHighlight() if (target - highlightPosition > modelCount/2) { highlightUp = false; qreal distance = modelCount - target + highlightPosition; - tl.move(moveHighlight, 0.0, QEasingCurve(QEasingCurve::InQuad), int(duration * highlightPosition / distance)); - tl.set(moveHighlight, modelCount-0.01); + tl.move(moveHighlight, qreal(0.0), QEasingCurve(QEasingCurve::InQuad), int(duration * highlightPosition / distance)); + tl.set(moveHighlight, modelCount-qreal(0.01)); tl.move(moveHighlight, target, QEasingCurve(QEasingCurve::OutQuad), int(duration * (modelCount-target) / distance)); } else if (target - highlightPosition <= -modelCount/2) { highlightUp = true; qreal distance = modelCount - highlightPosition + target; - tl.move(moveHighlight, modelCount-0.01, QEasingCurve(QEasingCurve::InQuad), int(duration * (modelCount-highlightPosition) / distance)); - tl.set(moveHighlight, 0.0); + tl.move(moveHighlight, modelCount-qreal(0.01), QEasingCurve(QEasingCurve::InQuad), int(duration * (modelCount-highlightPosition) / distance)); + tl.set(moveHighlight, qreal(0.0)); tl.move(moveHighlight, target, QEasingCurve(QEasingCurve::OutQuad), int(duration * target / distance)); } else { highlightUp = highlightPosition - target < 0; @@ -287,18 +287,18 @@ void QDeclarativePathViewPrivate::setHighlightPosition(qreal pos) qreal relativeHighlight = qmlMod(pos + offset, range) / range; if (!highlightUp && relativeHighlight > end * mappedRange) { - qreal diff = 1.0 - relativeHighlight; + qreal diff = qreal(1.0) - relativeHighlight; setOffset(offset + diff * range); } else if (highlightUp && relativeHighlight >= (end - start) * mappedRange) { qreal diff = relativeHighlight - (end - start) * mappedRange; - setOffset(offset - diff * range - 0.00001); + setOffset(offset - diff * range - qreal(0.00001)); } highlightPosition = pos; qreal pathPos = positionOfIndex(pos); updateItem(highlightItem, pathPos); if (QDeclarativePathViewAttached *att = attached(highlightItem)) - att->setOnPath(pathPos != -1.0); + att->setOnPath(pathPos != qreal(-1.0)); } } @@ -1200,7 +1200,7 @@ void QDeclarativePathViewPrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEve qreal elapsed = qreal(lastElapsed + QDeclarativeItemPrivate::elapsed(lastPosTime)) / 1000.; qreal velocity = elapsed > 0. ? lastDist / elapsed : 0; - if (model && modelCount && qAbs(velocity) > 1.) { + if (model && modelCount && qAbs(velocity) > qreal(1.)) { qreal count = pathItems == -1 ? modelCount : pathItems; if (qAbs(velocity) > count * 2) // limit velocity velocity = (velocity > 0 ? count : -count) * 2; @@ -1208,7 +1208,7 @@ void QDeclarativePathViewPrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEve qreal v2 = velocity*velocity; qreal accel = deceleration/10; // + 0.25 to encourage moving at least one item in the flick direction - qreal dist = qMin(qreal(modelCount-1), qreal(v2 / (accel * 2.0) + 0.25)); + qreal dist = qMin(qreal(modelCount-1), qreal(v2 / (accel * qreal(2.0)) + qreal(0.25))); if (haveHighlightRange && highlightRangeMode == QDeclarativePathView::StrictlyEnforceRange) { // round to nearest item. if (velocity > 0.) @@ -1217,13 +1217,13 @@ void QDeclarativePathViewPrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEve dist = qRound(dist - offset) + offset; // Calculate accel required to stop on item boundary if (dist <= 0.) { - dist = 0.; - accel = 0.; + dist = qreal(0.); + accel = qreal(0.); } else { accel = v2 / (2.0f * qAbs(dist)); } } - offsetAdj = 0.0; + offsetAdj = qreal(0.0); moveOffset.setValue(offset); tl.accel(moveOffset, velocity, accel, dist); tl.callback(QDeclarativeTimeLineCallback(&moveOffset, fixOffsetCallback, this)); @@ -1588,7 +1588,7 @@ void QDeclarativePathView::createdItem(int index, QDeclarativeItem *item) att->setOnPath(false); } item->setParentItem(this); - d->updateItem(item, index < d->firstIndex ? 0.0 : 1.0); + d->updateItem(item, index < d->firstIndex ? qreal(0.0) : qreal(1.0)); } } diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index ce21bcd..455c4f6 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -2719,7 +2719,7 @@ void QDeclarativeParentAnimation::transition(QDeclarativeStateActions &actions, } if (scale != 0) - rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI; + rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/qreal(M_PI); else { qmlInfo(this) << QDeclarativeParentAnimation::tr("Unable to preserve appearance under scale of 0"); ok = false; diff --git a/src/declarative/util/qdeclarativesmoothedanimation.cpp b/src/declarative/util/qdeclarativesmoothedanimation.cpp index b77db89..e905d0a 100644 --- a/src/declarative/util/qdeclarativesmoothedanimation.cpp +++ b/src/declarative/util/qdeclarativesmoothedanimation.cpp @@ -51,7 +51,7 @@ #include -#include +#include #define DELAY_STOP_TIMER_INTERVAL 32 @@ -98,20 +98,20 @@ bool QSmoothedAnimation::recalc() s = to - initialValue; vi = initialVelocity; - s = (invert? -1.0: 1.0) * s; + s = (invert? qreal(-1.0): qreal(1.0)) * s; if (userDuration > 0 && velocity > 0) { tf = s / velocity; - if (tf > (userDuration / 1000.)) tf = (userDuration / 1000.); + if (tf > (userDuration / qreal(1000.))) tf = (userDuration / qreal(1000.)); } else if (userDuration > 0) { - tf = userDuration / 1000.; + tf = userDuration / qreal(1000.); } else if (velocity > 0) { tf = s / velocity; } else { return false; } - finalDuration = ceil(tf * 1000.0); + finalDuration = ceil(tf * qreal(1000.0)); if (maximumEasingTime == 0) { a = 0; @@ -121,33 +121,33 @@ bool QSmoothedAnimation::recalc() vp = velocity; sp = 0; sd = s; - } else if (maximumEasingTime != -1 && tf > (maximumEasingTime / 1000.)) { - qreal met = maximumEasingTime / 1000.; + } else if (maximumEasingTime != -1 && tf > (maximumEasingTime / qreal(1000.))) { + qreal met = maximumEasingTime / qreal(1000.); td = tf - met; qreal c1 = td; qreal c2 = (tf - td) * vi - tf * velocity; - qreal c3 = -0.5 * (tf - td) * vi * vi; + qreal c3 = qreal(-0.5) * (tf - td) * vi * vi; - qreal vp1 = (-c2 + sqrt(c2 * c2 - 4 * c1 * c3)) / (2. * c1); + qreal vp1 = (-c2 + qSqrt(c2 * c2 - 4 * c1 * c3)) / (qreal(2.) * c1); vp = vp1; a = vp / met; d = a; tp = (vp - vi) / a; - sp = vi * tp + 0.5 * a * tp * tp; + sp = vi * tp + qreal(0.5) * a * tp * tp; sd = sp + (td - tp) * vp; } else { - qreal c1 = 0.25 * tf * tf; - qreal c2 = 0.5 * vi * tf - s; - qreal c3 = -0.25 * vi * vi; + qreal c1 = qreal(0.25) * tf * tf; + qreal c2 = qreal(0.5) * vi * tf - s; + qreal c3 = qreal(-0.25) * vi * vi; - qreal a1 = (-c2 + sqrt(c2 * c2 - 4 * c1 * c3)) / (2. * c1); + qreal a1 = (-c2 + qSqrt(c2 * c2 - 4 * c1 * c3)) / (qreal(2.) * c1); - qreal tp1 = 0.5 * tf - 0.5 * vi / a1; + qreal tp1 = qreal(0.5) * tf - qreal(0.5) * vi / a1; qreal vp1 = a1 * tp1 + vi; - qreal sp1 = 0.5 * a1 * tp1 * tp1 + vi * tp1; + qreal sp1 = qreal(0.5) * a1 * tp1 * tp1 + vi * tp1; a = a1; d = a1; @@ -165,7 +165,7 @@ qreal QSmoothedAnimation::easeFollow(qreal time_seconds) qreal value; if (time_seconds < tp) { trackVelocity = vi + time_seconds * a; - value = 0.5 * a * time_seconds * time_seconds + vi * time_seconds; + value = qreal(0.5) * a * time_seconds * time_seconds + vi * time_seconds; } else if (time_seconds < td) { time_seconds -= tp; trackVelocity = vp; @@ -173,7 +173,7 @@ qreal QSmoothedAnimation::easeFollow(qreal time_seconds) } else if (time_seconds < tf) { time_seconds -= td; trackVelocity = vp - time_seconds * a; - value = sd - 0.5 * d * time_seconds * time_seconds + vp * time_seconds; + value = sd - qreal(0.5) * d * time_seconds * time_seconds + vp * time_seconds; } else { trackVelocity = 0; value = s; @@ -186,10 +186,10 @@ qreal QSmoothedAnimation::easeFollow(qreal time_seconds) void QSmoothedAnimation::updateCurrentTime(int t) { - qreal time_seconds = qreal(t - lastTime) / 1000.; + qreal time_seconds = qreal(t - lastTime) / qreal(1000.); qreal value = easeFollow(time_seconds); - value *= (invert? -1.0: 1.0); + value *= (invert? qreal(-1.0): qreal(1.0)); QDeclarativePropertyPrivate::write(target, initialValue + value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); @@ -213,7 +213,7 @@ void QSmoothedAnimation::init() return; } - bool hasReversed = trackVelocity != 0. && + bool hasReversed = trackVelocity != qreal(0.) && ((!invert) == ((initialValue - to) > 0)); if (hasReversed) { diff --git a/src/declarative/util/qdeclarativespringanimation.cpp b/src/declarative/util/qdeclarativespringanimation.cpp index 2c6058c..0b453ee 100644 --- a/src/declarative/util/qdeclarativespringanimation.cpp +++ b/src/declarative/util/qdeclarativespringanimation.cpp @@ -161,17 +161,17 @@ bool QDeclarativeSpringAnimationPrivate::animate(const QDeclarativeProperty &pro animation.velocity = animation.velocity + (spring * diff - damping * animation.velocity) / mass; else animation.velocity = animation.velocity + spring * diff - damping * animation.velocity; - if (maxVelocity > 0.) { + if (maxVelocity > qreal(0.)) { // limit velocity if (animation.velocity > maxVelocity) animation.velocity = maxVelocity; else if (animation.velocity < -maxVelocity) animation.velocity = -maxVelocity; } - animation.currentValue += animation.velocity * 16.0 / 1000.0; + animation.currentValue += animation.velocity * qreal(16.0) / qreal(1000.0); if (haveModulus) { animation.currentValue = fmod(animation.currentValue, modulus); - if (animation.currentValue < 0.0) + if (animation.currentValue < qreal(0.0)) animation.currentValue += modulus; } } @@ -195,7 +195,7 @@ bool QDeclarativeSpringAnimationPrivate::animate(const QDeclarativeProperty &pro animation.currentValue = fmod(animation.currentValue, modulus); } else { animation.currentValue -= moveBy; - if (haveModulus && animation.currentValue < 0.0) + if (haveModulus && animation.currentValue < qreal(0.0)) animation.currentValue = fmod(animation.currentValue, modulus) + modulus; } if (lastTime - animation.start >= animation.duration) { diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index c260684..8f613b0 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -123,7 +123,7 @@ void QDeclarativeParentChangePrivate::doChange(QDeclarativeItem *targetParent, Q } if (scale != 0) - rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI; + rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/qreal(M_PI); else { qmlInfo(q) << QDeclarativeParentChange::tr("Unable to preserve appearance under scale of 0"); ok = false; diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 658dcad..980568e 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -530,7 +530,7 @@ public: void notifyQueryStarted(bool remoteSource) { Q_Q(QDeclarativeXmlListModel); - progress = remoteSource ? 0.0 : 1.0; + progress = remoteSource ? qreal(0.0) : qreal(1.0); status = QDeclarativeXmlListModel::Loading; errorString.clear(); emit q->progressChanged(progress); -- cgit v0.12 From bf69c7e0af67ec877da4fee244386e538fa1c01d Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 6 Oct 2011 13:46:30 +0100 Subject: Fix incorrect QFileInfo permissions on windows Requesting the write permission marked the read permission as known without having retrieved it. A subsequent request for read permission would return false. Task-Number: QTBUG-20714 Reviewed-By: mread --- src/corelib/io/qfilesystemengine_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 031d64b..3296bab 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -692,7 +692,7 @@ bool QFileSystemEngine::fillPermissions(const QFileSystemEntry &entry, QFileSyst if (what & QFileSystemMetaData::UserWritePermission) { if (::_waccess((wchar_t*)entry.nativeFilePath().utf16(), W_OK) == 0) data.entryFlags |= QFileSystemMetaData::UserWritePermission; - data.knownFlagsMask |= QFileSystemMetaData::UserReadPermission; + data.knownFlagsMask |= QFileSystemMetaData::UserWritePermission; } } -- cgit v0.12 From 51ed77637a6001f66805e8091ce8616d8f2530db Mon Sep 17 00:00:00 2001 From: mread Date: Thu, 6 Oct 2011 15:07:29 +0100 Subject: Removing accidental use of double instead of qreal from QLine QLine contained a number of places where conversions and calculations were done as double where qreal should have been used instead. This is caused by the use of raw floating point literals. The fix is to construct the literals as qreal. The angle conversions are simplified to reduce the risk of a growing loss of precision from this change. On Symbian, where qreal is float, this gives a 5-10% performance improvement to the affected functions, as tested by a new benchmark test. The auto tests pass, these contain precision tests which indicates that there is no significant loss of precision with this change. On Windows, where qreal is double, this has no significant effect on performance. Task-number: QTBUG-4894 Reviewed-by: Shane Kearns --- src/corelib/tools/qline.cpp | 21 ++-- tests/benchmarks/corelib/tools/qline/main.cpp | 157 +++++++++++++++++++++++++ tests/benchmarks/corelib/tools/qline/qline.pro | 12 ++ tests/benchmarks/corelib/tools/tools.pro | 1 + 4 files changed, 183 insertions(+), 8 deletions(-) create mode 100644 tests/benchmarks/corelib/tools/qline/main.cpp create mode 100644 tests/benchmarks/corelib/tools/qline/qline.pro diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp index 0f67652..9c7c243 100644 --- a/src/corelib/tools/qline.cpp +++ b/src/corelib/tools/qline.cpp @@ -302,10 +302,15 @@ QDataStream &operator>>(QDataStream &stream, QLine &line) #endif // QT_NO_DATASTREAM +inline static qreal q_deg2rad(qreal x) +{ + return x * qreal(0.01745329251994329576923690768489); /* pi/180 */ +} -#ifndef M_2PI -#define M_2PI 6.28318530717958647692528676655900576 -#endif +inline static qreal q_rad2deg(qreal x) +{ + return x * qreal(57.295779513082320876798154814105); /* 180/pi */ +} /*! \class QLineF @@ -575,7 +580,7 @@ qreal QLineF::angle() const const qreal dx = pt2.x() - pt1.x(); const qreal dy = pt2.y() - pt1.y(); - const qreal theta = qAtan2(-dy, dx) * 360.0 / M_2PI; + const qreal theta = q_rad2deg(qAtan2(-dy, dx)); const qreal theta_normalized = theta < 0 ? theta + 360 : theta; @@ -599,7 +604,7 @@ qreal QLineF::angle() const */ void QLineF::setAngle(qreal angle) { - const qreal angleR = angle * M_2PI / 360.0; + const qreal angleR = q_deg2rad(angle); const qreal l = length(); const qreal dx = qCos(angleR) * l; @@ -621,7 +626,7 @@ void QLineF::setAngle(qreal angle) */ QLineF QLineF::fromPolar(qreal length, qreal angle) { - const qreal angleR = angle * M_2PI / 360.0; + const qreal angleR = q_deg2rad(angle); return QLineF(0, 0, qCos(angleR) * length, -qSin(angleR) * length); } @@ -815,8 +820,8 @@ qreal QLineF::angle(const QLineF &l) const qreal cos_line = (dx()*l.dx() + dy()*l.dy()) / (length()*l.length()); qreal rad = 0; // only accept cos_line in the range [-1,1], if it is outside, use 0 (we return 0 rather than PI for those cases) - if (cos_line >= -1.0 && cos_line <= 1.0) rad = qAcos( cos_line ); - return rad * 360 / M_2PI; + if (cos_line >= qreal(-1.0) && cos_line <= qreal(1.0)) rad = qAcos( cos_line ); + return q_rad2deg(rad); } diff --git a/tests/benchmarks/corelib/tools/qline/main.cpp b/tests/benchmarks/corelib/tools/qline/main.cpp new file mode 100644 index 0000000..d7f93ba --- /dev/null +++ b/tests/benchmarks/corelib/tools/qline/main.cpp @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +// This file contains benchmarks for QLineF functions. + +#include +#include +#include + +class tst_qline : public QObject +{ + Q_OBJECT +private slots: + void fromPolar(); + void intersect_data(); + void intersect(); + void length(); + void setLength(); + void angle(); + void setAngle(); + void angleTo(); + void unitVector(); + void normalVector(); + void angle2(); +}; + +void tst_qline::fromPolar() +{ + QBENCHMARK { + QLineF::fromPolar(10, 2); + } +} + +void tst_qline::intersect_data() +{ + QTest::addColumn("l1"); + QTest::addColumn("l2"); + QTest::newRow("cross") << QLineF(-1,-1,1,1) << QLineF(-1,1,1,-1); + QTest::newRow("miss") << QLineF(1,1,2,2) << QLineF(1,11,2,12); +} + +void tst_qline::intersect() +{ + QFETCH(QLineF, l1); + QFETCH(QLineF, l2); + QPointF intersection; + QBENCHMARK { + l1.intersect(l2, &intersection); + } +} + +void tst_qline::length() +{ + QLineF line(1,2,3,4); + QBENCHMARK { + line.length(); + } +} + +void tst_qline::setLength() +{ + QLineF line(1,2,3,4); + QBENCHMARK { + line.setLength(5); + } +} + +void tst_qline::angle() +{ + QLineF line(1,2,3,4); + QBENCHMARK { + line.angle(); + } +} + +void tst_qline::setAngle() +{ + QLineF line(1,2,3,4); + QBENCHMARK { + line.setAngle(1); + } +} + +void tst_qline::angleTo() +{ + QLineF line1(1,2,3,4); + QLineF line2(8,7,6,5); + QBENCHMARK { + line1.angleTo(line2); + } +} + +void tst_qline::unitVector() +{ + QLineF line(1,2,3,4); + QBENCHMARK { + line.unitVector(); + } +} + +void tst_qline::normalVector() +{ + QLineF line(1,2,3,4); + QBENCHMARK { + line.normalVector(); + } +} + +void tst_qline::angle2() +{ + QLineF line1(1,2,3,4); + QLineF line2(8,7,6,5); + QBENCHMARK { + line1.angle(line2); + } +} + +QTEST_MAIN(tst_qline) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qline/qline.pro b/tests/benchmarks/corelib/tools/qline/qline.pro new file mode 100644 index 0000000..ae6bf5e --- /dev/null +++ b/tests/benchmarks/corelib/tools/qline/qline.pro @@ -0,0 +1,12 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_bench_qline +DEPENDPATH += . +INCLUDEPATH += . + +QT -= gui + +CONFIG += release + +# Input +SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/tools.pro b/tests/benchmarks/corelib/tools/tools.pro index 44e8973..83a9411 100644 --- a/tests/benchmarks/corelib/tools/tools.pro +++ b/tests/benchmarks/corelib/tools/tools.pro @@ -3,6 +3,7 @@ SUBDIRS = \ containers-associative \ containers-sequential \ qbytearray \ + qline \ qlist \ qrect \ qregexp \ -- cgit v0.12 From 7e662f3727e7c3dd3c41c29ed49bc41d2b66c744 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 6 Oct 2011 15:40:34 +0100 Subject: Fix construction races in QtNetwork When two threads construct a QNetworkAccessManager at exactly the same time on an SMP system, there are construction races for some Q_GLOBAL_STATIC data. This is normal and expected - the losing thread deletes its instance as part of the Q_GLOBAL_STATIC macro. However, for two of the classes, destruction of the loser had side effects. For QNetworkConfigurationMangerPrivate, there was a crash because of uninitialised variable on the losing side. For QNetworkAccessBackendFactoryData, a guard mechanism intended to prevent the data being reconstructed by destructors of other global static classes was being set by the loser. To fix this, the bool is changed to a QAtomicInt. In the normal case, it will have value 0->1 on startup and 1->0 on shutdown. In the race case, it will have values 0->1->2->1 on startup and 1->0 on shutdown. Task-Number: QTBUG-20343 Reviewed-By: mread --- src/network/access/qnetworkaccessbackend.cpp | 15 ++++++++++----- src/network/bearer/qnetworkconfigmanager_p.cpp | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index 2fae7d6..88c45d1 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -57,20 +57,25 @@ QT_BEGIN_NAMESPACE -static bool factoryDataShutdown = false; class QNetworkAccessBackendFactoryData: public QList { public: - QNetworkAccessBackendFactoryData() : mutex(QMutex::Recursive) { } + QNetworkAccessBackendFactoryData() : mutex(QMutex::Recursive) + { + valid.ref(); + } ~QNetworkAccessBackendFactoryData() { QMutexLocker locker(&mutex); // why do we need to lock? - factoryDataShutdown = true; + valid.deref(); } QMutex mutex; + //this is used to avoid (re)constructing factory data from destructors of other global classes + static QAtomicInt valid; }; Q_GLOBAL_STATIC(QNetworkAccessBackendFactoryData, factoryData) +QAtomicInt QNetworkAccessBackendFactoryData::valid; QNetworkAccessBackendFactory::QNetworkAccessBackendFactory() { @@ -80,7 +85,7 @@ QNetworkAccessBackendFactory::QNetworkAccessBackendFactory() QNetworkAccessBackendFactory::~QNetworkAccessBackendFactory() { - if (!factoryDataShutdown) { + if (QNetworkAccessBackendFactoryData::valid) { QMutexLocker locker(&factoryData()->mutex); factoryData()->removeAll(this); } @@ -89,7 +94,7 @@ QNetworkAccessBackendFactory::~QNetworkAccessBackendFactory() QNetworkAccessBackend *QNetworkAccessManagerPrivate::findBackend(QNetworkAccessManager::Operation op, const QNetworkRequest &request) { - if (!factoryDataShutdown) { + if (QNetworkAccessBackendFactoryData::valid) { QMutexLocker locker(&factoryData()->mutex); QNetworkAccessBackendFactoryData::ConstIterator it = factoryData()->constBegin(), end = factoryData()->constEnd(); diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index 18e29af..96a534d 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -60,7 +60,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, #endif QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate() - : QObject(), pollTimer(0), mutex(QMutex::Recursive), forcedPolling(0), firstUpdate(true) + : QObject(), pollTimer(0), bearerThread(0), mutex(QMutex::Recursive), forcedPolling(0), firstUpdate(true) { qRegisterMetaType("QNetworkConfiguration"); qRegisterMetaType("QNetworkConfigurationPrivatePointer"); -- cgit v0.12 From 22d475e1ef32875c4933b2bb4c2830cb1bdd3266 Mon Sep 17 00:00:00 2001 From: Juha Kukkonen Date: Mon, 10 Oct 2011 08:36:14 +0300 Subject: Fix XML schema validation failure. Checking constraining facets for double failed if enumeration restriction had values INF or NaN. There were two issues that caused validation to fail: - wrong conversion function was used when constraining facets for double are checked, which caused values to be in lower case - case when both restriction and default value are NaN was not handled correctly Task-number: QTBUG-21375 Reviewed-by: Honglei Zhang --- src/xmlpatterns/schema/qxsdtypechecker.cpp | 11 ++++++- .../files/schema-with-restrictions.xsd | 37 ++++++++++++++++++++++ .../tst_xmlpatternsvalidator.cpp | 5 +++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/auto/xmlpatternsvalidator/files/schema-with-restrictions.xsd diff --git a/src/xmlpatterns/schema/qxsdtypechecker.cpp b/src/xmlpatterns/schema/qxsdtypechecker.cpp index fb47448..e5709ae 100644 --- a/src/xmlpatterns/schema/qxsdtypechecker.cpp +++ b/src/xmlpatterns/schema/qxsdtypechecker.cpp @@ -57,6 +57,7 @@ #include "qxsdschemahelper_p.h" #include "qxsdschemamerger_p.h" #include "qxsdstatemachine_p.h" +#include "qabstractfloat_p.h" #include "qxsdschemadebugger_p.h" @@ -697,7 +698,8 @@ bool XsdTypeChecker::checkConstrainingFacetsDouble(double value, const QString & } if (facets.contains(XsdFacet::Enumeration)) { const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); - const DerivedString::Ptr valueStr = DerivedString::fromLexical(m_namePool, QString::number(value)); + const Numeric::Ptr valuePtr = Double::fromValue(value); + const DerivedString::Ptr valueStr = DerivedString::fromLexical(m_namePool, valuePtr->stringValue()); const AtomicValue::List multiValue = facet->multiValue(); bool found = false; @@ -706,6 +708,13 @@ bool XsdTypeChecker::checkConstrainingFacetsDouble(double value, const QString & found = true; break; } + + // Handle case when both facet and value are NaN separately as equals for NaN returns always false. + const Numeric::Ptr facetValue = ValueFactory::fromLexical(multiValue.at(j)->as >()->stringValue(), BuiltinTypes::xsDouble, m_context, m_reflection); + if (facetValue->isNaN() && valuePtr->isNaN()) { + found = true; + break; + } } if (!found) { diff --git a/tests/auto/xmlpatternsvalidator/files/schema-with-restrictions.xsd b/tests/auto/xmlpatternsvalidator/files/schema-with-restrictions.xsd new file mode 100644 index 0000000..532efcb --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/files/schema-with-restrictions.xsd @@ -0,0 +1,37 @@ + + + + + Test for QTBUG-21375: xmlpatternsvalidator does not allow for non-numeric literals in xsd:double attributes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp b/tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp index 817ea1a..60c1fe8 100644 --- a/tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp +++ b/tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp @@ -222,6 +222,11 @@ void tst_XmlPatternsValidator::xsdSupport_data() const << (QStringList() << QLatin1String("files/dateTime-with-microseconds.xml") << QLatin1String("files/dateTime-with-microseconds.xsd")) << QString(); + + QTest::newRow("QTBUG-21375 A schema with a xs:double based simple type with non-numeric restrictions") + << 0 + << (QStringList() << QLatin1String("files/schema-with-restrictions.xsd")) + << QString(); } QTEST_MAIN(tst_XmlPatternsValidator) -- cgit v0.12 From 9224d59d11464cc24e8768cc395cd9f86b1700ad Mon Sep 17 00:00:00 2001 From: Eero Hyyti Date: Mon, 10 Oct 2011 14:12:52 +0300 Subject: Doc updates to installation, platform notes and symbian introduction. --- doc/src/getting-started/installation.qdoc | 64 ++------- doc/src/platforms/platform-notes.qdoc | 198 +++++++++++++++++----------- doc/src/platforms/symbian-introduction.qdoc | 8 +- 3 files changed, 133 insertions(+), 137 deletions(-) diff --git a/doc/src/getting-started/installation.qdoc b/doc/src/getting-started/installation.qdoc index bec9ee4..c166794 100644 --- a/doc/src/getting-started/installation.qdoc +++ b/doc/src/getting-started/installation.qdoc @@ -504,75 +504,27 @@ in the \l{Qt for Windows CE Requirements} document. \tableofcontents -Qt for the Symbian platform has some requirements that are given in more detail -in the \l{Qt for the Symbian platform Requirements} document. - - -\section1 Step 1: Install Qt - - Download the \c {Qt libraries 4.x for Windows} package (for \c minGW or \c {VS 2008}) - from the \l {http://qt.nokia.com/downloads#qt-lib}{downloads} page. - - Run the downloaded package and follow the instructions. - - \note Qt must be installed on the same drive as the Symbian SDK you are - using, and the install path must not contain any spaces. - -\section1 Step 2: Install Qt into a device - - To run Qt applications on a device, \c{qt_installer.sis} found - in the Qt installation directory must be first installed into the device. - \c{Qt_installer.sis} contains Qt libraries and Open C libraries all in one - convenient package. - Begin installation by connecting your device via USB cable to a computer that - has the \l{http://www.nokia.com/pcsuite}{Nokia PC Suite} installed. - On the device, select "PC Suite mode". In Windows Explorer right click - on the \c{qt_installer.sis} file, select "Install with Nokia Application - Installer" and follow the instructions. - -\section1 Running Qt demos - - We've included a subset of the Qt demos in this package for you - to try out. An excellent starting point is the "fluidlauncher" - demo. - - To run the demo on a real device, install \c{fluidlauncher.sis} - found in the Qt installation directory to a device that already has Qt installed. - After installation, you can find fluidlauncher in the applications folder of the device. - - To run the demos and examples on the emulator, you need to build them first. - Open the "Qt for the Symbian platform Command Prompt" from the Start menu and type: - - \snippet doc/src/snippets/code/doc_src_installation.qdoc 25 - - To run the demos on the emulator simply navigate to the directory of the demo - you want to see and run: - - \snippet doc/src/snippets/code/doc_src_installation.qdoc 27 - - For more information about building and running Qt programs on the -Symbian platform, - see \l{The Symbian platform - Introduction to Qt}. - -\bold{We hope you will enjoy using Qt.} - + Qt for Symbian binary packages (SIS files) are available from the \l + {http://qt.nokia.com/downloads}{Qt SDK}. */ /*! \page install-Symbian.html -\title Installing Qt for the Symbian platform +\title Installing Qt for the Symbian Platform \ingroup installation \ingroup qtsymbian \brief How to install Qt for the Symbian platform. \previouspage Installation \tableofcontents + \l {http://qt.nokia.com/downloads}{Qt SDK} provides all the necessary tools + and libraries for developing Qt applications. However, if you want to build + Qt itself for Symbian, follow the instructions below. + Qt for the Symbian platform has some requirements that are given in more detail in the \l{Qt for the Symbian platform Requirements} document. This document describes how to install and configure Qt for -the Symbian platform from scratch. If you are using pre-built binaries, follow -the instructions given in the \l{Installing Qt for the Symbian platform from a -Binary Package} document. +the Symbian platform from scratch. \section1 Step 1: Set Up the Development Environment diff --git a/doc/src/platforms/platform-notes.qdoc b/doc/src/platforms/platform-notes.qdoc index d33a7a9..fbb66b1 100644 --- a/doc/src/platforms/platform-notes.qdoc +++ b/doc/src/platforms/platform-notes.qdoc @@ -622,7 +622,10 @@ \ingroup platform-specific \brief Information about the state of support for the Symbian platform. - This page documents the current notes for the Symbian port. + This page describes implementation details regarding the Qt for Symbian port. To get + started with application development for Symbian devices, read the \l + {http://doc.qt.nokia.com/qtcreator/creator-developing-symbian.html} + {Connecting Symbian Devices} document. \section1 Source Compatibility @@ -635,10 +638,10 @@ As with every supported platform, Qt strives to maintain application behavior and binary compatibility throughout the lifetime of the Qt 4.x - major version and on the Symbian devices that support Qt. Symbian support in - Qt SDK and Ovi Store were introduced with Qt 4.6. Each Qt release contains - bug fixes that might change the API behavior and thereby affect application - compatibility. + major version and on the \l {Supported Devices}{Symbian devices that support Qt}. + Symbian support in Qt SDK and Ovi Store were introduced with Qt 4.6. Each Qt + release contains bug fixes that might change the API behavior and thereby + affect application compatibility. In addition, Symbian devices have different input methods, such as different keyboard styles or touch input, screen sizes, memory, and CPU and GPU @@ -648,73 +651,93 @@ Generally, an earlier target (such as S60 5th Edition) is supported on a larger number of devices than a later target (such as Symbian Belle). + \target Supported Devices \section1 Supported Devices + + The \l {http://developer.qt.nokia.com/wiki/support_for_Symbian}{Support for Symbian} document + details the Qt support on different Symbian devices. - \l {http://www.developer.nokia.com/Community/Wiki/Nokia_Smart_Installer_for_Symbian#Supported_Devices}{Nokia Smart Installer for Symbian} - documentation lists supported devices. + The \l {http://www.developer.nokia.com/Community/Wiki/Nokia_Smart_Installer_for_Symbian#Supported_Devices} + {Nokia Smart Installer for Symbian} document lists how Qt is supported on + different Symbian devices through Smart Installer. Qt versions are supported by Symbian devices as follows: \list \o Qt 4.6 is supported by S60 3rd Edition feature pack 1 and newer devices through \l {http://www.developer.nokia.com/Community/Wiki/Nokia_Smart_Installer_for_Symbian}{Smart Installer}. - \o Qt 4.7.3 is supported by S60 5th Edition and newer devices. + \o Qt 4.7.3 is supported by S60 5th Edition and newer devices + through \l {http://www.developer.nokia.com/Community/Wiki/Nokia_Smart_Installer_for_Symbian}{Smart Installer}. \endlist Symbian devices have a pre-installed Qt support as follows: \list - \o Symbian Anna: Qt 4.7.3 in C: drive. + \o Symbian Anna: Qt 4.7.3 in C: drive. Note that Qt 4.7.4 is supported in Symbian Anna + through \l {http://www.developer.nokia.com/Community/Wiki/Nokia_Smart_Installer_for_Symbian}{Smart Installer}. \o Symbian Belle: Qt 4.7.4 in device firmware (ROM). \endlist - \section1 Supported Functionality - - The following technologies and classes are not currently supported: - - \table - \header \o Technology - \o Note - \row \o QtConcurrent - \o Planned for future release. - \row \o QtDBus - \o No current plans to support this feature. - \row \o Printing support - \o No current plans to support this feature. - \row \o Qt3Support - \o No current plans to support this feature. - \endtable + \section1 Functionality Support + The following technologies and classes are not supported: + \list + \o QtConcurrent + \o QtDBus + \o \l {http://doc.qt.nokia.com/4.8/printing.html}{Printing support} + \o Qt3Support + \endlist + The following technologies have limited support: \table - \header \o Technology + \header \o Module \o Note \row \o QtSql \o The only supported driver is SQLite. \row \o QtMultimedia - \o For support details see \l {Multimedia and Phonon Support} section. + \o For support details see \l {Multimedia Support} section. + \row \o QtGui + \o QtGui's widgets are deprecated (i.e. they are available but not + recommended to use) in the Symbian port. It is recommended to use \l + {http://doc.qt.nokia.com/qt-components-symbian-1.1/symbian-components-functional.html} + {Qt Quick Components for Symbian} instead, because they provide + better look and feel on Symbian devices. + + Moreover, the following classes of QtGui \bold {should not + be used} in a Symbian application: + + \list + \o QFileDialog with the \c DontUseNativeDialog option + \o QColorDialog with the \c DontUseNativeDialog option + \o QFontDialog + \o QWizard + \o QCalendarWidget + \o QDateTimeEdit + \o QMdiArea + \o QDockWidget + \o QMdiSubWindow + \o QPrintPreviewWidget + \endlist + + QScrollArea: The scrolling and focus handling of QScrollArea's all + scrollable widgets, for example QListView, differs from native Avkon + list widgets' one. Native Avkon scrollable components support + touch-gesture-based scrolling by dragging and flicking the UI + component but this functionality is not implemented in Qt widgets. + Scrolling by dragging and flicking works also in Qt Quick Components + that implements the \l + {http://www.developer.nokia.com/Resources/Library/Symbian_Design_Guidelines/} + {Symbian design guidelines}. + \endtable - - It is not recommended to use the following Qt widgets: - \list - \o QFileDialog with the \c DontUseNativeDialog option - \o QColorDialog with the \c DontUseNativeDialog option - \o QFontDialog - \o QWizard - \o QCalendarWidget - \o QDateTimeEdit - \o QMdiArea - \o QMdiSubWindow - \o QDockWidget - \o QPrintPreviewWidget - \endlist \section1 Compiler Notes - - \section2 GCCE (Symbian) - - GCCE cannot be used to compile Qt libaries for the Symbian platform, but GCCE is supported - when compiling Qt applications for the Symbian platform. + + For the application development the necessary compiler toolchain is included in \l + {http://qt.nokia.com/downloads}{Qt SDK}. For instructions compiling Qt + itself see the \l + {http://doc.qt.nokia.com/stable/install-symbian.html} + {Installing Qt for the Symbian platform} document. \section1 Known Issues @@ -730,11 +753,14 @@ \section1 Required Capabilities - The Qt libraries are typically signed with \c{All -TCB} capabilites, but + The Qt libraries are typically signed with \c{All -TCB} capabilites but that does not mean your Qt application needs to be signed with the same capabilities to function properly. The capabilities your application needs - to function properly depends on which parts of Qt you use, here is an - overview: + to function properly depends on which parts of Qt you use. + In a Qt application Symbian capabilities are defined in the + \l {http://doc.qt.nokia.com/4.8/qmake-variable-reference.html#target-capability} + {TARGET.CAPABILITY} qmake variable in the project file. + Here is an overview for which capabilities may be needed when using different modules: \table \header \o Module @@ -751,9 +777,9 @@ \o \c ReadUserData is required to include all the phone's SSL certificates in the system's default CA certificate list (for example those added by the user or stored in the SIM card), without this capability only the CA certs built into the phone are used. - \row \o QtMultiMedia + \row \o QtMultimedia \o \c UserEnvironment if QAudioInput is used. - \row \o QtWebkit + \row \o QtWebKit \o \c NetworkServices is automatically added for this module if no capabilities are explicitly specified. \endtable @@ -764,30 +790,41 @@ For more information see the documentation of the individual Qt classes. If a class does not mention Symbian capabilities, it requires none. - \target Multimedia and Phonon Support - \section1 Multimedia and Phonon Support + \target Multimedia Support + \section1 Multimedia Support - Qt provides a high-level API for multimedia functionality with - (\l{http://doc.qt.nokia.com/qtmobility/multimedia.html}). + Qt Mobility provides a high-level API for multimedia functionality with + \l{http://doc.qt.nokia.com/qtmobility/multimedia.html}{QtMultimediaKit}. + In addition, Qt provides the low-level \l {QtMultimedia}{QtMultimedia} + module that is internally used by the QtMultimediaKit. For more information + on developing multimedia applications for Symbian devices, see + \l {http://www.developer.nokia.com/info/sw.nokia.com/id/4abf12e7-72d8-45ef-b1a2-46184abe18ba/Guide_for_Qt_Multimedia_Developers.html} + {Guide for Qt Multimedia Developers}. - Qt also provides a backend for Qt's Phonon module, which supports video and - sound playback through Symbian's Multimedia Framework, MMF. Note that Phonon - support is not being extended, and that Qt's multimedia module will - take over for Phonon at a later stage. + Moreover, there is a third multimedia-related module called Phonon. Qt + provides two backends for the Phonon module in Symbian: \i MMF and \i Helix. - In this release the support is experimental. Video playback may show - artifacts when the video is moved or resized (for instance during - orientation flips). This problem is present on S60 5th Edition and earlier - versions, and on Symbian^3 systems. + Note that Phonon is a legacy module and the QtMultimediaKit module is + replacing Phonon in Qt 5. Although Phonon is supported in Symbian for + backwards compatibility and there is no plan to remove Phonon from Symbian + any new applications should use QtMultimediaKit in Symbian using Qt 4.7 + bundle. The QtMultimediaKit feature set is comparable to that in Phonon. - The audio and video formats that Phonon supports depends on what support + The following applies to Phonon: + \list + \o MMF Phonon backend supports video and sound playback through Symbian's + Multimedia Framework, MMF. Phonon's video playback may show artifacts when + the video is moved or resized (for instance, during device orientation + changes from portrait to landscape and vice versa). This problem is present + on S60 5th Edition and earlier versions, as well as in Symbian Anna devices. + \o The audio and video formats that Phonon supports depends on what support the platform provides for MMF. The emulator is known to have limited codec support. - - In addition, there exists a backend for the Helix framework. However, since + \o In addition, there exists a backend for the Helix framework. However, since it is not shipped with Qt, its availability depends on the Symbian platform in use. If the MFF plugin fails to load, the Helix plugin, if present on the device, will be loaded instead. + \endlist \section1 Hardware Accelerated Rendering @@ -806,17 +843,18 @@ \o Popups \endlist - \section1 QtOpenGL Support in Symbian + \section1 OpenGL Support in Symbian Qt 4.7 introduces the \l {QtOpenGL} module. QtOpenGL is supported on devices which support OpenGL ES 2.0. Symbian platforms prior - to Symbian^3 are not supported. + to Symbian Anna (and Symbian^3) are not supported. \l QGLWidget usage as a \l QGraphicsView viewport is not recommended on Symbian. The OpenVG graphics system is not able to manage OpenGL graphics resources. Also, a QGLWidget object is not able to release its GPU resources when the application goes to the background. If OpenGL functionality is - needed, OpenGL graphics system usage is recommended. If an application + needed, \l { http://doc.qt.nokia.com/4.7-snapshot/qapplication.html#setGraphicsSystem} + {OpenGL graphics system} usage is recommended. If an application decides to use QGLWidget, then it is the application's responsibility to destroy and release QGLWidget and related OpenGL resources when the application goes to the background. Otherwise, the \l{Graphics Out Of Memory monitor} @@ -827,7 +865,7 @@ QGLShader, and \l QGLShaderProgram are direct GPU resources and it is the application's responsibility to manage them. - \section1 UI Performance in devices prior to Symbian^3 + \section1 UI Performance in S60 3rd and 5th Edition Devices Qt uses the QPainter class to perform low-level painting on widgets and other paint devices. QPainter provides functions to draw complex shapes, @@ -835,11 +873,18 @@ transformations and Porter-Duff composition. If the underlying graphics architecture does not support all of these operations then Qt uses the raster graphics system for rendering. - - Most of the Symbian devices prior to Symbian^3 use a non-ScreenPlay - graphics architecture which does not have native support for all functions - provided by QPainter. In non-ScreenPlay devices Qt uses the raster - graphics system by default which has a performance penalty when compared + + In Symbian Anna (and Symbian^3) Qt uses hardware accelerated graphics as explained above. + This is enabled by \l + {http://library.developer.nokia.com/index.jsp?topic=/GUID-E35887BB-7E58-438C-AA27-97B2CDE7E069/GUID-D93978BE-11A3-5CE3-B110-1DEAA5AD566C.html} + {ScreenPlay Graphics Architecture} in these devices. + + Most of the Symbian S60 3rd and 5th Edition devices have a + graphics architecture that does not have native support for all functions + provided by QPainter. In these \l + {http://library.developer.nokia.com/index.jsp?topic=/GUID-E35887BB-7E58-438C-AA27-97B2CDE7E069/GUID-D93978BE-11A3-5CE3-B110-1DEAA5AD566C.html} + {non-ScreenPlay} devices Qt uses the raster + graphics system by default that has a performance penalty compared to native Symbian rendering. In order to be able to perform all functions provided by QPainter, the @@ -850,7 +895,8 @@ offscreen buffer is blitted to the framebuffer via Symbian Window Server. The following table shows the rendering stacks of native Symbian and Qt in - non-ScreenPlay devices. + \l {http://library.developer.nokia.com/index.jsp?topic=/GUID-E35887BB-7E58-438C-AA27-97B2CDE7E069/GUID-D93978BE-11A3-5CE3-B110-1DEAA5AD566C.html} + {non-ScreenPlay devices}. \table \header \o Symbian diff --git a/doc/src/platforms/symbian-introduction.qdoc b/doc/src/platforms/symbian-introduction.qdoc index 2a5d5b1..82d39f3 100644 --- a/doc/src/platforms/symbian-introduction.qdoc +++ b/doc/src/platforms/symbian-introduction.qdoc @@ -42,7 +42,6 @@ \o \list \o \l {Qt for the Symbian platform Requirements} - \o \l {Installing Qt for the Symbian platform from a Binary Package} \o \l {Installing Qt for the Symbian platform} \o \l {The Symbian platform - Introduction to Qt}{Introduction to using Qt} \endlist @@ -55,7 +54,7 @@ \endlist \o \list - \o \l {Deploying an Application on the Symbian platform}{Deploying Applications} + \o \l {Deploying an Application on the Symbian Platform}{Deploying Applications} \endlist \endtable */ @@ -74,6 +73,8 @@ Platform security capabilities are added via the \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY} qmake variable. + + \sa {platform-notes-symbian.html#required-capabilities}{Required Capabilities} */ /*! @@ -93,9 +94,6 @@ \section1 Installing Qt and Running Demos - Follow the instructions found in \l{Installing Qt for the Symbian platform from a Binary Package} - to learn how to install Qt using a binary package and how to build and run Qt demos. - Follow the instructions found in \l{Installing Qt for the Symbian platform} to learn how to install Qt using using source package and how to build and run the Qt demos. -- cgit v0.12 From ae620eb773a5fd217de4766fc829e51417cb9e70 Mon Sep 17 00:00:00 2001 From: mread Date: Mon, 10 Oct 2011 12:58:12 +0100 Subject: Converting from double to qreal in gui There were a number of places in QtGui where doubles were used in expressions due to the use of floating point constants in the code. Many of these constants are now constructed as qreal, removing the use of double operations where unneeded. These changes have been limited to constants that have exactly the same value whether double or float, to ensure that precision errors are not introduced. This should not affect any of the desktop platforms where qreal is double. On Symbian, where qreal is float, appropriate autotests have been run. Task-number: QTBUG-4894 Reviewed-by: Sami Merila --- src/gui/graphicsview/qgraphicsitem.cpp | 2 +- src/gui/graphicsview/qgraphicsscene.cpp | 2 +- src/gui/graphicsview/qgraphicsview.cpp | 16 ++++++++-------- src/gui/graphicsview/qgraphicswidget_p.cpp | 4 ++-- src/gui/graphicsview/qgridlayoutengine.cpp | 8 ++++---- src/gui/graphicsview/qsimplex_p.cpp | 2 +- src/gui/image/qimage.cpp | 12 ++++++------ src/gui/kernel/qtooltip.cpp | 2 +- src/gui/kernel/qwidget.cpp | 2 +- src/gui/painting/qcolor.cpp | 4 ++-- src/gui/painting/qpaintengine_raster.cpp | 8 ++++---- src/gui/painting/qpaintengineex.cpp | 12 ++++++------ src/gui/painting/qpainter.cpp | 16 ++++++++-------- src/gui/painting/qrasterizer.cpp | 10 +++++----- src/gui/painting/qtessellator.cpp | 2 +- src/gui/styles/qs60style.cpp | 8 ++++---- src/gui/styles/qstylesheetstyle.cpp | 10 +++++----- src/gui/text/qfontdatabase.cpp | 4 ++-- src/gui/text/qfontengine.cpp | 4 ++-- src/gui/text/qtextdocument.cpp | 2 +- src/gui/widgets/qprogressbar.cpp | 2 +- 21 files changed, 66 insertions(+), 66 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 9092593..cb7349c 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -8868,7 +8868,7 @@ QPainterPath QGraphicsEllipseItem::shape() const return path; if (d->spanAngle != 360 * 16) { path.moveTo(d->rect.center()); - path.arcTo(d->rect, d->startAngle / 16.0, d->spanAngle / 16.0); + path.arcTo(d->rect, d->startAngle / qreal(16.0), d->spanAngle / qreal(16.0)); } else { path.addEllipse(d->rect); } diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 867880c..d652f25 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4304,7 +4304,7 @@ static void _q_paintItem(QGraphicsItem *item, QPainter *painter, QGraphicsWidget *widgetItem = static_cast(item); QGraphicsProxyWidget *proxy = qobject_cast(widgetItem); const qreal windowOpacity = (proxy && proxy->widget() && useWindowOpacity) - ? proxy->widget()->windowOpacity() : 1.0; + ? proxy->widget()->windowOpacity() : qreal(1.0); const qreal oldPainterOpacity = painter->opacity(); if (qFuzzyIsNull(windowOpacity)) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 548f79f..d2e21fb 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -298,7 +298,7 @@ inline int q_round_bound(qreal d) //### (int)(qreal) INT_MAX != INT_MAX for sing return INT_MIN; else if (d >= (qreal) INT_MAX) return INT_MAX; - return d >= 0.0 ? int(d + 0.5) : int(d - int(d-1) + 0.5) + int(d-1); + return d >= 0.0 ? int(d + qreal(0.5)) : int(d - int(d-1) + qreal(0.5)) + int(d-1); } void QGraphicsViewPrivate::translateTouchEvent(QGraphicsViewPrivate *d, QTouchEvent *touchEvent) @@ -1830,14 +1830,14 @@ void QGraphicsView::centerOn(const QPointF &pos) qint64 horizontal = 0; horizontal += horizontalScrollBar()->minimum(); horizontal += horizontalScrollBar()->maximum(); - horizontal -= int(viewPoint.x() - width / 2.0); + horizontal -= int(viewPoint.x() - width / qreal(2.0)); horizontalScrollBar()->setValue(horizontal); } else { - horizontalScrollBar()->setValue(int(viewPoint.x() - width / 2.0)); + horizontalScrollBar()->setValue(int(viewPoint.x() - width / qreal(2.0))); } } if (!d->topIndent) - verticalScrollBar()->setValue(int(viewPoint.y() - height / 2.0)); + verticalScrollBar()->setValue(int(viewPoint.y() - height / qreal(2.0))); d->lastCenterPoint = oldCenterPoint; } @@ -1886,22 +1886,22 @@ void QGraphicsView::ensureVisible(const QRectF &rect, int xmargin, int ymargin) if (viewRect.left() <= left + xmargin) { // need to scroll from the left if (!d->leftIndent) - horizontalScrollBar()->setValue(int(viewRect.left() - xmargin - 0.5)); + horizontalScrollBar()->setValue(int(viewRect.left() - xmargin - qreal(0.5))); } if (viewRect.right() >= right - xmargin) { // need to scroll from the right if (!d->leftIndent) - horizontalScrollBar()->setValue(int(viewRect.right() - width + xmargin + 0.5)); + horizontalScrollBar()->setValue(int(viewRect.right() - width + xmargin + qreal(0.5))); } if (viewRect.top() <= top + ymargin) { // need to scroll from the top if (!d->topIndent) - verticalScrollBar()->setValue(int(viewRect.top() - ymargin - 0.5)); + verticalScrollBar()->setValue(int(viewRect.top() - ymargin - qreal(0.5))); } if (viewRect.bottom() >= bottom - ymargin) { // need to scroll from the bottom if (!d->topIndent) - verticalScrollBar()->setValue(int(viewRect.bottom() - height + ymargin + 0.5)); + verticalScrollBar()->setValue(int(viewRect.bottom() - height + ymargin + qreal(0.5))); } } diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp index ca6713b..ec79a2f 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.cpp +++ b/src/gui/graphicsview/qgraphicswidget_p.cpp @@ -482,8 +482,8 @@ static QSizeF closestAcceptableSize(const QSizeF &proposed, minw = maxw; minh = maxh; } - middlew = minw + (maxw - minw)/2.0; - middleh = minh + (maxh - minh)/2.0; + middlew = minw + (maxw - minw)/qreal(2.0); + middleh = minh + (maxh - minh)/qreal(2.0); min_hfw = minimumHeightForWidth(middlew, minh, maxh, widget); diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/gui/graphicsview/qgridlayoutengine.cpp index 66b4a5b..5c61435 100644 --- a/src/gui/graphicsview/qgridlayoutengine.cpp +++ b/src/gui/graphicsview/qgridlayoutengine.cpp @@ -84,7 +84,7 @@ static qreal fixedDescent(qreal descent, qreal ascent, qreal targetSize) Q_ASSERT(targetSize >= ascent + descent); qreal extra = targetSize - (ascent + descent); - return descent + (extra / 2.0); + return descent + (extra / qreal(2.0)); } static qreal compare(const QGridLayoutBox &box1, const QGridLayoutBox &box2, int which) @@ -292,9 +292,9 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz int stretch = stretches[start + i]; if (sumStretches == 0) { if (hasIgnoreFlag) { - factors[i] = (stretch < 0) ? 1.0 : 0.0; + factors[i] = (stretch < 0) ? qreal(1.0) : qreal(0.0); } else { - factors[i] = (stretch < 0) ? sizes[i] : 0.0; + factors[i] = (stretch < 0) ? sizes[i] : qreal(0.0); } } else if (stretch == sumStretches) { factors[i] = 1.0; @@ -373,7 +373,7 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz for (int i = 0; i < n; ++i) { if (newSizes[i] < 0.0) { - qreal delta = (sumFactors == 0.0) ? 0.0 + qreal delta = (sumFactors == 0.0) ? qreal(0.0) : sumCurrentAvailable * factors[i] / sumFactors; newSizes[i] = sizes[i] + delta; } diff --git a/src/gui/graphicsview/qsimplex_p.cpp b/src/gui/graphicsview/qsimplex_p.cpp index eb8bcb8..1b45d9d 100644 --- a/src/gui/graphicsview/qsimplex_p.cpp +++ b/src/gui/graphicsview/qsimplex_p.cpp @@ -486,7 +486,7 @@ bool QSimplex::iterate() // Normalize Pivot Row qreal pivot = valueAt(pivotRow, pivotColumn); if (pivot != 1.0) - combineRows(pivotRow, pivotRow, (1.0 - pivot) / pivot); + combineRows(pivotRow, pivotRow, (qreal(1.0) - pivot) / pivot); // Update other rows for (int row=0; row < rows; ++row) { diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index a3378de..f527bcf 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -5908,12 +5908,12 @@ bool qt_xForm_helper(const QTransform &trueMat, int xoffset, int type, int depth uchar *dptr, int dbpl, int p_inc, int dHeight, const uchar *sptr, int sbpl, int sWidth, int sHeight) { - int m11 = int(trueMat.m11()*4096.0); - int m12 = int(trueMat.m12()*4096.0); - int m21 = int(trueMat.m21()*4096.0); - int m22 = int(trueMat.m22()*4096.0); - int dx = qRound(trueMat.dx()*4096.0); - int dy = qRound(trueMat.dy()*4096.0); + int m11 = int(trueMat.m11()*qreal(4096.0)); + int m12 = int(trueMat.m12()*qreal(4096.0)); + int m21 = int(trueMat.m21()*qreal(4096.0)); + int m22 = int(trueMat.m22()*qreal(4096.0)); + int dx = qRound(trueMat.dx()*qreal(4096.0)); + int dy = qRound(trueMat.dy()*qreal(4096.0)); int m21ydx = dx + (xoffset<<16) + (m11 + m21) / 2; int m22ydy = dy + (m12 + m22) / 2; diff --git a/src/gui/kernel/qtooltip.cpp b/src/gui/kernel/qtooltip.cpp index f880243..178e7b1 100644 --- a/src/gui/kernel/qtooltip.cpp +++ b/src/gui/kernel/qtooltip.cpp @@ -184,7 +184,7 @@ QTipLabel::QTipLabel(const QString &text, QWidget *w) setAlignment(Qt::AlignLeft); setIndent(1); qApp->installEventFilter(this); - setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, 0, this) / 255.0); + setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, 0, this) / qreal(255.0)); setMouseTracking(true); fadingOut = false; reuseTip(text); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 0aa1dfa..e015f5f 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -11049,7 +11049,7 @@ bool QWidget::testAttribute_helper(Qt::WidgetAttribute attribute) const qreal QWidget::windowOpacity() const { Q_D(const QWidget); - return (isWindow() && d->maybeTopData()) ? d->maybeTopData()->opacity / 255. : 1.0; + return (isWindow() && d->maybeTopData()) ? d->maybeTopData()->opacity / qreal(255.) : qreal(1.0); } void QWidget::setWindowOpacity(qreal opacity) diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 3d895b7..2fe68a8 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -1578,7 +1578,7 @@ QColor QColor::toRgb() const } // chromatic case - const qreal h = ct.ahsv.hue == 36000 ? 0 : ct.ahsv.hue / 6000.; + const qreal h = ct.ahsv.hue == 36000 ? 0 : ct.ahsv.hue / qreal(6000.); const qreal s = ct.ahsv.saturation / qreal(USHRT_MAX); const qreal v = ct.ahsv.value / qreal(USHRT_MAX); const int i = int(h); @@ -1638,7 +1638,7 @@ QColor QColor::toRgb() const color.ct.argb.red = color.ct.argb.green = color.ct.argb.blue = 0; } else { // chromatic case - const qreal h = ct.ahsl.hue == 36000 ? 0 : ct.ahsl.hue / 36000.; + const qreal h = ct.ahsl.hue == 36000 ? 0 : ct.ahsl.hue / qreal(36000.); const qreal s = ct.ahsl.saturation / qreal(USHRT_MAX); const qreal l = ct.ahsl.lightness / qreal(USHRT_MAX); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index bcc5f9d..0fea2da 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1649,8 +1649,8 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) if (lines[i].p1() == lines[i].p2()) { if (s->lastPen.capStyle() != Qt::FlatCap) { QPointF p = lines[i].p1(); - QLineF line = s->matrix.map(QLineF(QPointF(p.x() - width*0.5, p.y()), - QPointF(p.x() + width*0.5, p.y()))); + QLineF line = s->matrix.map(QLineF(QPointF(p.x() - width*qreal(0.5), p.y()), + QPointF(p.x() + width*qreal(0.5), p.y()))); d->rasterizer->rasterizeLine(line.p1(), line.p2(), 1); } continue; @@ -5117,7 +5117,7 @@ static void drawEllipse_midpoint_i(const QRect &rect, const QRect &clip, { const qreal a = qreal(rect.width()) / 2; const qreal b = qreal(rect.height()) / 2; - qreal d = b*b - (a*a*b) + 0.25*a*a; + qreal d = b*b - (a*a*b) + qreal(0.25)*a*a; int x = 0; int y = (rect.height() + 1) / 2; @@ -5140,7 +5140,7 @@ static void drawEllipse_midpoint_i(const QRect &rect, const QRect &clip, pen_func, brush_func, pen_data, brush_data); // region 2 - d = b*b*(x + 0.5)*(x + 0.5) + a*a*((y - 1)*(y - 1) - b*b); + d = b*b*(x + qreal(0.5))*(x + qreal(0.5)) + a*a*((y - 1)*(y - 1) - b*b); const int miny = rect.height() & 0x1; while (y > miny) { if (d < 0) { // select SE diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 6df410b..eaedc4c 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -748,8 +748,8 @@ void QPaintEngineEx::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yR qreal y2 = rect.bottom(); if (mode == Qt::RelativeSize) { - xRadius = xRadius * rect.width() / 200.; - yRadius = yRadius * rect.height() / 200.; + xRadius = xRadius * rect.width() / qreal(200.); + yRadius = yRadius * rect.height() / qreal(200.); } xRadius = qMin(xRadius, rect.width() / 2); @@ -863,7 +863,7 @@ void QPaintEngineEx::drawPoints(const QPointF *points, int pointCount) for (int i=0; imatrix).boundingRect(); } else { - strokeOffsetX = qAbs(penWidth * state->matrix.m11() / 2.0); - strokeOffsetY = qAbs(penWidth * state->matrix.m22() / 2.0); + strokeOffsetX = qAbs(penWidth * state->matrix.m11() / qreal(2.0)); + strokeOffsetY = qAbs(penWidth * state->matrix.m22() / qreal(2.0)); } } } @@ -4460,8 +4460,8 @@ void QPainter::drawArc(const QRectF &r, int a, int alen) QRectF rect = r.normalized(); QPainterPath path; - path.arcMoveTo(rect, a/16.0); - path.arcTo(rect, a/16.0, alen/16.0); + path.arcMoveTo(rect, a/qreal(16.0)); + path.arcTo(rect, a/qreal(16.0), alen/qreal(16.0)); strokePath(path, d->state->pen); } @@ -4531,7 +4531,7 @@ void QPainter::drawPie(const QRectF &r, int a, int alen) QPainterPath path; path.moveTo(rect.center()); - path.arcTo(rect.x(), rect.y(), rect.width(), rect.height(), a/16.0, alen/16.0); + path.arcTo(rect.x(), rect.y(), rect.width(), rect.height(), a/qreal(16.0), alen/qreal(16.0)); path.closeSubpath(); drawPath(path); @@ -4592,8 +4592,8 @@ void QPainter::drawChord(const QRectF &r, int a, int alen) QRectF rect = r.normalized(); QPainterPath path; - path.arcMoveTo(rect, a/16.0); - path.arcTo(rect, a/16.0, alen/16.0); + path.arcMoveTo(rect, a/qreal(16.0)); + path.arcTo(rect, a/qreal(16.0), alen/qreal(16.0)); path.closeSubpath(); drawPath(path); } @@ -9242,7 +9242,7 @@ void QPainter::drawPixmapFragments(const PixmapFragment *fragments, int fragment qreal h = fragments[i].scaleY * fragments[i].height; QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop, fragments[i].width, fragments[i].height); - drawPixmap(QRectF(-0.5 * w + xOffset, -0.5 * h + yOffset, w, h), pixmap, sourceRect); + drawPixmap(QRectF(qreal(-0.5) * w + xOffset, qreal(-0.5) * h + yOffset, w, h), pixmap, sourceRect); } setOpacity(oldOpacity); diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp index 1d3f581..ca10e6a 100644 --- a/src/gui/painting/qrasterizer.cpp +++ b/src/gui/painting/qrasterizer.cpp @@ -51,8 +51,8 @@ QT_BEGIN_NAMESPACE typedef int Q16Dot16; -#define Q16Dot16ToFloat(i) ((i)/65536.) -#define FloatToQ16Dot16(i) (int)((i) * 65536.) +#define Q16Dot16ToFloat(i) ((i)/qreal(65536.)) +#define FloatToQ16Dot16(i) (int)((i) * qreal(65536.)) #define IntToQ16Dot16(i) ((i) << 16) #define Q16Dot16ToInt(i) ((i) >> 16) #define Q16Dot16Factor 65536 @@ -701,7 +701,7 @@ static Q16Dot16 intersectPixelFP(int x, Q16Dot16 top, Q16Dot16 bottom, Q16Dot16 static inline bool q26Dot6Compare(qreal p1, qreal p2) { - return int((p2 - p1) * 64.) == 0; + return int((p2 - p1) * qreal(64.)) == 0; } static inline qreal qFloorF(qreal v) @@ -1210,8 +1210,8 @@ void QRasterizer::rasterize(const QPainterPath &path, Qt::FillRule fillRule) QRectF bounds = path.controlPointRect(); - int iTopBound = qMax(d->clipRect.top(), int(bounds.top() + 0.5 + (COORD_OFFSET - COORD_ROUNDING)/64.)); - int iBottomBound = qMin(d->clipRect.bottom(), int(bounds.bottom() - 0.5 + (COORD_OFFSET - COORD_ROUNDING)/64.)); + int iTopBound = qMax(d->clipRect.top(), int(bounds.top() + qreal(0.5) + (COORD_OFFSET - COORD_ROUNDING)/qreal(64.))); + int iBottomBound = qMin(d->clipRect.bottom(), int(bounds.bottom() - qreal(0.5) + (COORD_OFFSET - COORD_ROUNDING)/qreal(64.))); if (iTopBound > iBottomBound) return; diff --git a/src/gui/painting/qtessellator.cpp b/src/gui/painting/qtessellator.cpp index 94a5128..15e4f65 100644 --- a/src/gui/painting/qtessellator.cpp +++ b/src/gui/painting/qtessellator.cpp @@ -1400,7 +1400,7 @@ void QTessellator::tessellateRect(const QPointF &a_, const QPointF &b_, qreal wi if (delta.x == 0 && delta.y == 0) return; - qreal hw = 0.5 * width; + qreal hw = qreal(0.5) * width; if (delta.x == 0) { Q27Dot5 halfWidth = FloatToQ27Dot5(hw); diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index eec2d15..59bd0dd 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -1679,7 +1679,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWaitAnim, painter, progressRect, flags | orientationFlag | QS60StylePrivate::SF_Animation ); } else { - const qreal progressFactor = (optionProgressBar->minimum == optionProgressBar->maximum) ? 1.0 + const qreal progressFactor = (optionProgressBar->minimum == optionProgressBar->maximum) ? qreal(1.0) : (qreal)optionProgressBar->progress / optionProgressBar->maximum; const int frameWidth = pixelMetric(PM_DefaultFrameWidth, option, widget); if (optionProgressBar->orientation == Qt::Horizontal) { @@ -2010,7 +2010,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (focusFrame->widget() && focusFrame->widget()->hasEditFocus()) editFocus = true; } - const qreal opacity = editFocus ? 1 : 0.75; // Trial and error factors. Feel free to improve. + const qreal opacity = editFocus ? 1 : qreal(0.75); // Trial and error factors. Feel free to improve. #else const qreal opacity = 0.85; #endif @@ -2148,8 +2148,8 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti case PE_IndicatorRadioButton: { QRect buttonRect = option->rect; //there is empty (a. 33%) space in svg graphics for radiobutton - const qreal reduceWidth = (qreal)buttonRect.width() / 3.0; - const qreal rectWidth = (qreal)option->rect.width() != 0 ? option->rect.width() : 1.0; + const qreal reduceWidth = (qreal)buttonRect.width() / qreal(3.0); + const qreal rectWidth = (qreal)option->rect.width() != 0 ? option->rect.width() : qreal(1.0); // Try to occupy the full area const qreal scaler = 1 + (reduceWidth/rectWidth); buttonRect.setWidth((int)((buttonRect.width()-reduceWidth) * scaler)); diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index 7d2ed2a..c066631 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -1247,20 +1247,20 @@ QPainterPath QRenderRule::borderClip(QRect r) const QRectF rect(r); const int *borders = border()->borders; QPainterPath path; - qreal curY = rect.y() + borders[TopEdge]/2.0; + qreal curY = rect.y() + borders[TopEdge]/qreal(2.0); path.moveTo(rect.x() + tlr.width(), curY); path.lineTo(rect.right() - trr.width(), curY); - qreal curX = rect.right() - borders[RightEdge]/2.0; + qreal curX = rect.right() - borders[RightEdge]/qreal(2.0); path.arcTo(curX - 2*trr.width() + borders[RightEdge], curY, trr.width()*2 - borders[RightEdge], trr.height()*2 - borders[TopEdge], 90, -90); path.lineTo(curX, rect.bottom() - brr.height()); - curY = rect.bottom() - borders[BottomEdge]/2.0; + curY = rect.bottom() - borders[BottomEdge]/qreal(2.0); path.arcTo(curX - 2*brr.width() + borders[RightEdge], curY - 2*brr.height() + borders[BottomEdge], brr.width()*2 - borders[RightEdge], brr.height()*2 - borders[BottomEdge], 0, -90); path.lineTo(rect.x() + blr.width(), curY); - curX = rect.left() + borders[LeftEdge]/2.0; + curX = rect.left() + borders[LeftEdge]/qreal(2.0); path.arcTo(curX, rect.bottom() - 2*blr.height() + borders[BottomEdge]/2, blr.width()*2 - borders[LeftEdge], blr.height()*2 - borders[BottomEdge], 270, -90); @@ -3810,7 +3810,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if (inverted) reverse = !reverse; const bool indeterminate = pb->minimum == pb->maximum; - qreal fillRatio = indeterminate ? 0.50 : qreal(progress - minimum)/(maximum - minimum); + qreal fillRatio = indeterminate ? qreal(0.50) : qreal(progress - minimum)/(maximum - minimum); int fillWidth = int(rect.width() * fillRatio); int chunkWidth = fillWidth; if (subRule.hasContentsSize()) { diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 1d463c4..796c455 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -1994,7 +1994,7 @@ QList QFontDatabase::pointSizes(const QString &family, const QtFontSize *size = style->pixelSizes + l; if (size->pixelSize != 0 && size->pixelSize != USHRT_MAX) { - const uint pointSize = qRound(size->pixelSize * 72.0 / dpi); + const uint pointSize = qRound(size->pixelSize * qreal(72.0) / dpi); if (! sizes.contains(pointSize)) sizes.append(pointSize); } @@ -2105,7 +2105,7 @@ QList QFontDatabase::smoothSizes(const QString &family, const QtFontSize *size = style->pixelSizes + l; if (size->pixelSize != 0 && size->pixelSize != USHRT_MAX) { - const uint pointSize = qRound(size->pixelSize * 72.0 / dpi); + const uint pointSize = qRound(size->pixelSize * qreal(72.0) / dpi); if (! sizes.contains(pointSize)) sizes.append(pointSize); } diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index c9b672b..8f46a80 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -381,9 +381,9 @@ void QFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rig glyph_metrics_t gi = boundingBox(glyph); bool isValid = gi.isValid(); if (leftBearing != 0) - *leftBearing = isValid ? gi.x.toReal() : 0.0; + *leftBearing = isValid ? gi.x.toReal() : qreal(0.0); if (rightBearing != 0) - *rightBearing = isValid ? (gi.xoff - gi.x - gi.width).toReal() : 0.0; + *rightBearing = isValid ? (gi.xoff - gi.x - gi.width).toReal() : qreal(0.0); } glyph_metrics_t QFontEngine::tightBoundingBox(const QGlyphLayout &glyphs) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 143dc1a..de2e27a 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -159,7 +159,7 @@ bool Qt::mightBeRichText(const QString& text) QString Qt::escape(const QString& plain) { QString rich; - rich.reserve(int(plain.length() * 1.1)); + rich.reserve(int(plain.length() * qreal(1.1))); for (int i = 0; i < plain.length(); ++i) { if (plain.at(i) == QLatin1Char('<')) rich += QLatin1String("<"); diff --git a/src/gui/widgets/qprogressbar.cpp b/src/gui/widgets/qprogressbar.cpp index dd92bda..1b0a1a1 100644 --- a/src/gui/widgets/qprogressbar.cpp +++ b/src/gui/widgets/qprogressbar.cpp @@ -462,7 +462,7 @@ QString QProgressBar::text() const return result; } - int progress = (qreal(d->value) - d->minimum) * 100.0 / totalSteps; + int progress = (qreal(d->value) - d->minimum) * qreal(100.0) / totalSteps; result.replace(QLatin1String("%p"), QString::number(progress)); return result; } -- cgit v0.12 From 2299f684f0ca6bdf49128b17c49488ae27b49479 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 10 Oct 2011 16:29:23 +0300 Subject: Fix QDeclarativeEngine::setOfflineStoragePath() for Symbian In Symbian, the sqlite database doesn't like mixing native and Qt separators in the database name, so ensure only native separators are used when declarative sets the database name. Task-number: QTBUG-20836 Reviewed-by: Sami Merila --- src/declarative/qml/qdeclarativesqldatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativesqldatabase.cpp b/src/declarative/qml/qdeclarativesqldatabase.cpp index 588b6bf..513cae2 100644 --- a/src/declarative/qml/qdeclarativesqldatabase.cpp +++ b/src/declarative/qml/qdeclarativesqldatabase.cpp @@ -175,7 +175,7 @@ static const char* sqlerror[] = { static QString qmlsqldatabase_databasesPath(QScriptEngine *engine) { QDeclarativeScriptEngine *qmlengine = static_cast(engine); - return qmlengine->offlineStoragePath + return QDir::toNativeSeparators(qmlengine->offlineStoragePath) + QDir::separator() + QLatin1String("Databases"); } -- cgit v0.12 From fe5f996eac2a4b4e7e704f7cdaebe990a76c6034 Mon Sep 17 00:00:00 2001 From: Pasi Pentikainen Date: Tue, 27 Sep 2011 17:14:11 +0300 Subject: Put Qt translation files to rom on Symbian. Task-Number: QTBUG-4919 Reviewed-by: Honglei Zhang --- config.profiles/symbian/platform_paths.prf | 13 +++++++++++++ src/s60installs/qt_resources.iby | 11 +++++++++++ src/s60installs/s60installs.pro | 1 + 3 files changed, 25 insertions(+) create mode 100644 src/s60installs/qt_resources.iby diff --git a/config.profiles/symbian/platform_paths.prf b/config.profiles/symbian/platform_paths.prf index 0e2131f..1769885 100644 --- a/config.profiles/symbian/platform_paths.prf +++ b/config.profiles/symbian/platform_paths.prf @@ -239,10 +239,23 @@ defineReplace(CORE_TOOLS_LAYER_IBY_EXPORT_PATH) { defineReplace(CORE_ADAPT_LAYER_IBY_EXPORT_PATH) { return(/epoc32/rom/include/$$1) } + +defineReplace(LANGUAGE_APP_LAYER_IBY_EXPORT_PATH) { + return(/epoc32/rom/include/language/app/$$1) +} +defineReplace(LANGUAGE_MW_LAYER_IBY_EXPORT_PATH) { + return(/epoc32/rom/include/language/mw/$$1) +} +defineReplace(LANGUAGE_OS_LAYER_IBY_EXPORT_PATH) { + return(/epoc32/rom/include/language/os/$$1) +} + defineReplace(CUSTOMER_VARIANT_APP_LAYER_IBY_EXPORT_PATH) { return(/epoc32/rom/include/customervariant/app/$$1) } + + # You need to define the following in pro-file, if you are using the stllib: # QMAKE_CXXFLAGS.CW *= $$STLLIB_USAGE_CW_FLAGS # DEFINES *= $$STLLIB_USAGE_DEFINES diff --git a/src/s60installs/qt_resources.iby b/src/s60installs/qt_resources.iby new file mode 100644 index 0000000..f5fe1c4 --- /dev/null +++ b/src/s60installs/qt_resources.iby @@ -0,0 +1,11 @@ +#ifndef QT_RESOURCES_IBY +#define QT_RESOURCES_IBY + +#include + +// Localisation files + +data=DATAZ_\QT_TRANSLATIONS_DIR\qt.qm QT_TRANSLATIONS_DIR\qt.qm + +#endif // __QT_RESOURCES_IBY__ + diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index c2b462c..08c4829 100755 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -175,4 +175,5 @@ symbian: { } BLD_INF_RULES.prj_exports += "$$S60_INSTALLS_SOURCE_DIR/qt.iby $$CORE_MW_LAYER_IBY_EXPORT_PATH(qt.iby)" + BLD_INF_RULES.prj_exports += "$$S60_INSTALLS_SOURCE_DIR/qt_resources.iby $$LANGUAGE_MW_LAYER_IBY_EXPORT_PATH(qt_resources.iby)" } -- cgit v0.12 From 138b9d7349d5daa1808d8bd891c5ecf817f98c52 Mon Sep 17 00:00:00 2001 From: mread Date: Thu, 13 Oct 2011 14:54:45 +0100 Subject: runonphone timestamps nanosecond formating set to 9 chars, 0 padded runonphone was dropping leading zeros after the decimal point in its timestamp formating. For example [123.000456789] was printed as [123.456789], which is quite a different number. The formatting now pads the nanoseconds component with leading zeros to 9 characters. Timestamps are now always displayed with a 9 character nanoseconds component, with leading and trailing zeros as appropriate. For example: [1897.070556640] [Qt Message] QEglContext::swapBuffers Reviewed-by: Shane Kearns --- tools/runonphone/symbianutils/launcher.cpp | 2 +- tools/runonphone/texttracehandler.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/runonphone/symbianutils/launcher.cpp b/tools/runonphone/symbianutils/launcher.cpp index ff67881..2909696 100644 --- a/tools/runonphone/symbianutils/launcher.cpp +++ b/tools/runonphone/symbianutils/launcher.cpp @@ -440,7 +440,7 @@ void Launcher::handleResult(const TrkResult &result) quint64 timestamp = extractInt64(result.data) & 0x0FFFFFFFFFFFFFFFULL; quint64 secs = timestamp / 1000000000; quint64 ns = timestamp % 1000000000; - msg = QString("[%1.%2] %3").arg(secs).arg(ns).arg(QString(result.data.mid(8))); + msg = QString("[%1.%2] %3").arg(secs).arg(ns,9,10,QLatin1Char('0')).arg(QString(result.data.mid(8))); logMessage("TEXT TRACE: " + msg); } } else { diff --git a/tools/runonphone/texttracehandler.cpp b/tools/runonphone/texttracehandler.cpp index fff02e9..a121c08 100644 --- a/tools/runonphone/texttracehandler.cpp +++ b/tools/runonphone/texttracehandler.cpp @@ -85,5 +85,5 @@ void TextTraceHandler::dataAvailable() secs = timestamp / 1000000000; ns = timestamp % 1000000000; } - d->out << QString("[%1.%2] %3").arg(secs).arg(ns).arg(QString(result.mid(8))) << endl; + d->out << QString("[%1.%2] %3").arg(secs).arg(ns,9,10,QLatin1Char('0')).arg(QString(result.mid(8))) << endl; } -- cgit v0.12