From 9be25c3847bb90eb2a6cf9cd6d357e83b7ad89a2 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 9 Feb 2010 13:13:31 +0100 Subject: doc: Updated deployment OS X requirements for 4.6 Beginning with Qt 4.6, OS X 103 (Panther) is no longer supported. --- doc/src/deployment/deployment.qdoc | 84 +++++++++++++---------------------- doc/src/platforms/platform-notes.qdoc | 3 ++ 2 files changed, 33 insertions(+), 54 deletions(-) diff --git a/doc/src/deployment/deployment.qdoc b/doc/src/deployment/deployment.qdoc index 575a6dc..9557365 100644 --- a/doc/src/deployment/deployment.qdoc +++ b/doc/src/deployment/deployment.qdoc @@ -963,14 +963,14 @@ \title Deploying an Application on Mac OS X - Starting with version 4.5, Qt now includes a \l {macdeploy}{deployment tool} - that automates the prodecures described in this document. - - This documentation will describe how to create a bundle, and how - to make sure that the application will find the resources it needs - at run-time. We will demonstrate the procedures in terms of - deploying the \l {tools/plugandpaint}{Plug & Paint} application - that is provided in Qt's examples directory. + Beginning with Qt 4.5, a \l {macdeploy}{deployment tool} is + included that automates the prodecures described here. + + This document describes how to create a bundle and how to make + sure that the application will find the resources it needs at + run-time. We demonstrate the procedures in terms of deploying the + \l {tools/plugandpaint}{Plug & Paint} application that is provided + in Qt's examples directory. \tableofcontents @@ -1380,63 +1380,38 @@ \section2 Mac OS X Version Dependencies - Qt 4.2 has been designed to be built and deployed on Mac OS X 10.3 - up until the current version as of this writing, Mac OS X 10.4 and - all their minor releases. Qt achieves this by using "weak - linking." This means that Qt tests if a function added in newer - versions of Mac OS X is available on the computer it is running on - before it uses it. This results in getting access to newer - features when running on newer versions of OS X while still - remaining compatible on older versions. + From Qt 4.6, Mac OS X 10.3 (Panther) is no longer supported. Qt + 4.6 applications can be built and deployed on Mac OS X 10.4 + (Tiger) and higher. This is achieved using \e{weak linking}. In + \e{weak linking}, Qt tests whether a function added in a newer + version of Mac OS X is available on the computer it is running + on. This allows Qt to use newer features, when it runs on a newer + version of OS X, while remaining compatible on the older versions. For more information about cross development issues on Mac OS X, see \l {http://developer.apple.com/documentation/DeveloperTools/Conceptual/cross_development/index.html}{Apple's Developer Website}. - Since the linker is set to be compatible with all OS X version, you have to - change the \c MACOSX_DEPLOYMENT_TARGET environment variable to get weak - linking to work for your application. You can add: + Since the linker is set to be compatible with all OS X versions, + you must change the \c MACOSX_DEPLOYMENT_TARGET environment + variable to get \e{weak linking} to work for your application. You + can add: \snippet doc/src/snippets/code/doc_src_deployment.qdoc 51 - to your .pro file and qmake will take care of this for you. - - However, there is a bit of a wrinkle to keep in mind when your are - deploying. Mac OS X 10.4 ("Tiger") ships GCC 4.0 as its default - compiler. This is also the GCC compiler we use for building the - binary Qt package. If you use GCC 4.0 to build your application, - it will link against a dynamic libstdc++ that is only available on - Mac OS X 10.4 and Mac OS X 10.3.9. The application will refuse to - run on older versions of the operating system. + to your .pro file, and qmake will take care of this for you. For more information about C++ runtime environment, see \l {http://developer.apple.com/documentation/DeveloperTools/Conceptual/CppRuntimeEnv/index.html}{Apple's Developer Website} - If you want to deploy to versions of Mac OS X earlier than 10.3.9, - you must build with GCC 3.3 which is the default on Mac OS X - 10.3. GCC 3.3 is also available on the Mac OS X 10.4 "Xcode Tools" - CD and as a download for earlier versions of Mac OS X from Apple - (\l {https://connect.apple.com/}{connect.apple.com}). You can use - Apple's \c gcc_select(1) command line tool to switch the default - complier on your system. - \section3 Deploying Phonon Applications on Mac OS X \list - \o If you build your Phonon application on Tiger, it will work on - Tiger, Leopard and Panther. - \o If you build your application on Leopard, it will \bold not work - on Panther unless you rename the libraries with the following command - after you have built your application: - - \snippet doc/src/snippets/code/doc_src_deployment.qdoc 51a - This command must be invoked in the directory where - \c{libphonon_qt7.dylib} is located, usually in - \c{yourapp.app/Contents/plugins/phonon_backend/}. - \o The \l {macdeploy}{deployment tool} will perform this step for you. + \o If you build your Qt 4.6 Phonon application on OS X 10.4 + (Tiger), it will run on OS X 10.4 and higher. - \o If you are using Leopard, but would like to build your application + \o If you are using Leopard but would like to build your application against Tiger, you can use: \snippet doc/src/snippets/code/doc_src_deployment.qdoc 51b @@ -1444,12 +1419,13 @@ \section2 Architecture Dependencies - The Qt for Mac OS X libraries, tools, and examples can be built "universal" - (i.e. they run natively on both Intel and PowerPC machines). This - is accomplished by passing \c -universal on the \c configure line - of the source package, and requires that you use GCC 4.0.x. On - PowerPC hardware you will need to pass the universal SDK as a - command line argument to the Qt configure command. For example: + The Qt for Mac OS X libraries, tools, and examples can be built + "universal" (i.e. they run natively on both Intel and PowerPC + machines). This is accomplished by passing \c -universal on the + \c configure line of the source package, and requires that you use + GCC 4.0.x. On PowerPC hardware you will need to pass the universal + SDK as a command line argument to the Qt configure command. For + example: \snippet doc/src/snippets/code/doc_src_deployment.qdoc 52 diff --git a/doc/src/platforms/platform-notes.qdoc b/doc/src/platforms/platform-notes.qdoc index e08bf1a..f513181 100644 --- a/doc/src/platforms/platform-notes.qdoc +++ b/doc/src/platforms/platform-notes.qdoc @@ -293,6 +293,9 @@ \section1 General Information + Qt 4.6 applications can only be deployed on Mac OS X 10.4 (Tiger) + and higher. + Qt 4.4 and Qt 4.5 development is only supported on Mac OS X 10.4 and up. Applications built against these version of Qt can be deployed on Mac OS X 10.3, but cannot be developed on that version of the operating system due -- cgit v0.12 From 4519080aacc480acea59758e4ca4efeed599aaec Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 9 Feb 2010 11:06:44 +0100 Subject: demo browser: Fix the way warnings were (not) displayed Reviewed-by: TrustMe --- demos/browser/browser.pro | 2 -- demos/browser/networkaccessmanager.cpp | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/demos/browser/browser.pro b/demos/browser/browser.pro index a42aa60..f038c61 100644 --- a/demos/browser/browser.pro +++ b/demos/browser/browser.pro @@ -6,8 +6,6 @@ CONFIG += qt warn_on contains(QT_BUILD_PARTS, tools):!embedded: CONFIG += uitools else: DEFINES += QT_NO_UITOOLS -release:DEFINES+=QT_NO_DEBUG_OUTPUT QT_NO_WARNING_OUTPUT - FORMS += \ addbookmarkdialog.ui \ bookmarks.ui \ diff --git a/demos/browser/networkaccessmanager.cpp b/demos/browser/networkaccessmanager.cpp index b0b00a2..70a9305 100644 --- a/demos/browser/networkaccessmanager.cpp +++ b/demos/browser/networkaccessmanager.cpp @@ -112,8 +112,9 @@ void NetworkAccessManager::requestFinished(QNetworkReply *reply) double pctCached = (double(requestFinishedFromCacheCount) * 100.0/ double(requestFinishedCount)); double pctPipelined = (double(requestFinishedPipelinedCount) * 100.0/ double(requestFinishedCount)); double pctSecure = (double(requestFinishedSecureCount) * 100.0/ double(requestFinishedCount)); +#ifdef QT_DEBUG qDebug("STATS [%lli requests total] [%3.2f%% from cache] [%3.2f%% pipelined] [%3.2f%% SSL/TLS]", requestFinishedCount, pctCached, pctPipelined, pctSecure); - +#endif } void NetworkAccessManager::loadSettings() -- cgit v0.12 From 74d3ef60ac8dfa12c90442062307e0c4b2600d03 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 9 Feb 2010 11:29:24 +0100 Subject: Demo browser: Better handleUnsupportedContent implementation Do warnings instead of downloads for sub resources. Show error message for main resources. Reviewed-by: Tor Arne --- demos/browser/webview.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/demos/browser/webview.cpp b/demos/browser/webview.cpp index 1a7e38a..2f9b3e6 100644 --- a/demos/browser/webview.cpp +++ b/demos/browser/webview.cpp @@ -143,11 +143,19 @@ QObject *WebPage::createPlugin(const QString &classId, const QUrl &url, const QS void WebPage::handleUnsupportedContent(QNetworkReply *reply) { - if (reply->error() == QNetworkReply::NoError) { - BrowserApplication::downloadManager()->handleUnsupportedContent(reply); + QString errorString = reply->errorString(); + + if (m_loadingUrl != reply->url()) { + // sub resource of this page + qWarning() << "Resource" << reply->url().toEncoded() << "has unknown Content-Type, will be ignored."; + reply->deleteLater(); return; } + if (reply->error() == QNetworkReply::NoError && !reply->header(QNetworkRequest::ContentTypeHeader).isValid()) { + errorString = "Unknown Content-Type"; + } + QFile file(QLatin1String(":/notfound.html")); bool isOpened = file.open(QIODevice::ReadOnly); Q_ASSERT(isOpened); @@ -156,7 +164,7 @@ void WebPage::handleUnsupportedContent(QNetworkReply *reply) QString title = tr("Error loading page: %1").arg(reply->url().toString()); QString html = QString(QLatin1String(file.readAll())) .arg(title) - .arg(reply->errorString()) + .arg(errorString) .arg(reply->url().toString()); QBuffer imageBuffer; -- cgit v0.12 From c034670d71247954eb918dfc84536ace02c33304 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 9 Feb 2010 12:56:55 +0100 Subject: QNAM HTTP: Improve parseStatus() of HTTP reply Just read() instead us using peek() and bytesAvailable() Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkreply.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index a5223d1..b411467 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -425,11 +425,19 @@ qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) { qint64 bytes = 0; char c; + qint64 haveRead = 0; + + do { + haveRead = socket->read(&c, 1); + if (haveRead == -1) + return -1; // unexpected EOF + else if (haveRead == 0) + break; // read more later + + bytes++; - while (socket->bytesAvailable()) { // allow both CRLF & LF (only) line endings - if (socket->peek(&c, 1) == 1 && c == '\n') { - bytes += socket->read(&c, 1); // read the "n" + if (c == '\n') { // remove the CR at the end if (fragment.endsWith('\r')) { fragment.truncate(fragment.length()-1); @@ -442,11 +450,6 @@ qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) } break; } else { - c = 0; - int haveRead = socket->read(&c, 1); - if (haveRead == -1) - return -1; - bytes += haveRead; fragment.append(c); } @@ -456,8 +459,7 @@ qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) fragment.clear(); return -1; } - - } + } while (haveRead == 1); return bytes; } -- cgit v0.12 From 1263253f298b4cb3f0679cc67b010766b58a4fd9 Mon Sep 17 00:00:00 2001 From: Jedrzej Nowacki Date: Tue, 9 Feb 2010 13:21:44 +0200 Subject: Add QSKIP to functionEntryAndExit_builtin. The function fails on Mac and Windows, but it will be fixed in next JSC update. Lets skip it for now. Reviewed-by: Kent Hansen --- tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp b/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp index 8e26696..ac9ca46 100644 --- a/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp +++ b/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp @@ -832,6 +832,7 @@ void tst_QScriptEngineAgent::functionEntryAndExit_builtin_data() /** check behaiviour of built-in function */ void tst_QScriptEngineAgent::functionEntryAndExit_builtin() { + QSKIP("The test fails on platforms others than Linux. The issue will be fixed with next JSC update", SkipAll); QFETCH(QString, script); QFETCH(QString, result); QScriptEngine eng; -- cgit v0.12 From 057532393ad96cd90a616cb7eccf762ddd0ff4dd Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 9 Feb 2010 13:30:24 +0100 Subject: QNAM HTTP: Improve readHeader() of the HTTP reply Just read() instead us using peek() and bytesAvailable() Also don't use the obfuscated line ending checking code. Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkreply.cpp | 36 ++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index b411467..c56a3a3 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -505,17 +505,31 @@ qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket) qint64 bytes = 0; char c = 0; bool allHeaders = false; - while (!allHeaders && socket->bytesAvailable()) { - if (socket->peek(&c, 1) == 1 && c == '\n') { - // check for possible header endings. As per HTTP rfc, - // the header endings will be marked by CRLFCRLF. But - // we will allow CRLFLF, LFLF & CRLFCRLF - if (fragment.endsWith("\n\r") || fragment.endsWith('\n')) - allHeaders = true; + qint64 haveRead = 0; + do { + haveRead = socket->read(&c, 1); + if (haveRead == 0) { + // read more later + break; + } else if (haveRead == -1) { + // connection broke down + return -1; + } else { + fragment.append(c); + bytes++; + + if (c == '\n') { + // check for possible header endings. As per HTTP rfc, + // the header endings will be marked by CRLFCRLF. But + // we will allow CRLFCRLF, CRLFLF, LFLF + if (fragment.endsWith("\r\n\r\n") + || fragment.endsWith("\r\n\n") + || fragment.endsWith("\n\n")) + allHeaders = true; + } } - bytes += socket->read(&c, 1); - fragment.append(c); - } + } while (!allHeaders && haveRead > 0); + // we received all headers now parse them if (allHeaders) { parseHeader(fragment); @@ -565,7 +579,7 @@ void QHttpNetworkReplyPrivate::parseHeader(const QByteArray &header) } while (i < header.count() && (header.at(i) == ' ' || header.at(i) == '\t')); if (i == -1) break; // something is wrong - + qDebug() << "added header" << field << value; fields.append(qMakePair(field, value)); } } -- cgit v0.12 From 7177a8d02bdec25b1c64dd65c7c7f5803809a244 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Tue, 9 Feb 2010 13:54:33 +0100 Subject: QNetworkCookie(Jar): fix includes we need to include the module preefix in public headers Reviewed-by: Denis Dzyubenko --- src/network/access/qnetworkcookie.h | 2 +- src/network/access/qnetworkcookiejar.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkcookie.h b/src/network/access/qnetworkcookie.h index f34396f..3cc4cee 100644 --- a/src/network/access/qnetworkcookie.h +++ b/src/network/access/qnetworkcookie.h @@ -114,7 +114,7 @@ Q_NETWORK_EXPORT QDebug operator<<(QDebug, const QNetworkCookie &); QT_END_NAMESPACE // ### Qt5 remove this include -#include "qnetworkcookiejar.h" +#include Q_DECLARE_METATYPE(QNetworkCookie) Q_DECLARE_METATYPE(QList) diff --git a/src/network/access/qnetworkcookiejar.h b/src/network/access/qnetworkcookiejar.h index 813bf3e..8086f38 100644 --- a/src/network/access/qnetworkcookiejar.h +++ b/src/network/access/qnetworkcookiejar.h @@ -46,7 +46,7 @@ #include // ### Qt5 remove this include -#include "qnetworkcookie.h" +#include QT_BEGIN_HEADER -- cgit v0.12 From 9d8af1a5a11571d3f514e4ad73a0712ea5d89b0e Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Tue, 9 Feb 2010 11:40:39 +0100 Subject: Skip test that crashes on win32-g++ --- tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp index 147896e..9514cd6 100644 --- a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp +++ b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp @@ -245,6 +245,10 @@ tst_Suite::tst_Suite() addTestExclusion("string-case", "V8-specific behavior? (Doesn't pass on SpiderMonkey either)"); +#ifdef Q_CC_MINGW + addTestExclusion("date$", "QTBUG-7698: Date.prototype.setMonth() crashes on win32-g++"); +#endif + #ifdef Q_OS_WINCE addTestExclusion("deep-recursion", "Demands too much memory on WinCE"); addTestExclusion("nested-repetition-count-overflow", "Demands too much memory on WinCE"); -- cgit v0.12 From 416155f9078d9d055f72b383f7cce113cdc42645 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Tue, 9 Feb 2010 12:29:03 +0100 Subject: Add platform-specific expected failures for JS test suite --- .../qscriptjstestsuite/tst_qscriptjstestsuite.cpp | 53 ++++++++++++++++++++++ .../qscriptv8testsuite/tst_qscriptv8testsuite.cpp | 10 ++++ 2 files changed, 63 insertions(+) diff --git a/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp b/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp index b2a85d7..ffcb56e 100644 --- a/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp +++ b/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp @@ -686,6 +686,59 @@ tst_Suite::tst_Suite() addExpectedFailure("ecma/Expressions/11.4.7-02.js", "-(-2147483648) == 2147483648", willFixInNextReleaseMessage); addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "- -\"0x80000000\"", willFixInNextReleaseMessage); +#ifdef Q_OS_WIN + addExpectedFailure("ecma_3/Expressions/11.7.3-01.js", "11.7.3 - >>> should evaluate operands in order: order", "QTBUG-8056"); + addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.7.3 >>>", "QTBUG-8056"); + addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.13.2 >>>=", "QTBUG-8056"); +#endif + +#ifdef Q_OS_SOLARIS + addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = -0; VAR2= Infinity; VAR2 /= VAR1", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = -0; VAR2= -Infinity; VAR2 /= VAR1", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = 1; VAR2= -0; VAR1 /= VAR2", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = -1; VAR2= -0; VAR1 /= VAR2", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Expressions/11.5.2.js", "Number.POSITIVE_INFINITY / -0", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Expressions/11.5.2.js", "Number.NEGATIVE_INFINITY / -0", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Expressions/11.5.2.js", "1 / -0", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Expressions/11.5.2.js", "-1 / -0", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.10.js", "Math.log(-0.0000001)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.10.js", "Math.log(-1)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.11.js", "Infinity/Math.max(-0,-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.12.js", "Infinity/Math.min(0,-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.12.js", "Infinity/Math.min(-0,-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Infinity/Math.pow(-Infinity, -1)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(0, -1)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(0, -0.5)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(0, -1000)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Infinity/Math.pow(-0, 1)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Infinity/Math.pow(-0, 3)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(-0, -2)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.15.js", "Infinity/Math.round(-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.15.js", "Infinity/Math.round(-0.49)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.15.js", "Infinity/Math.round(-0.5)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.17.js", "Infinity/Math.sqrt(-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.18.js", "Infinity/Math.tan(-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.2.js", "Math.acos(1.00000001)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.2.js", "Math.acos(11.00000001)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.3.js", "Math.asin(1.000001)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.3.js", "Math.asin(-1.000001)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.3.js", "Infinity/Math.asin(-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.4.js", "Infinity/Math.atan(-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(0, -0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Infinity/Math.atan2(-0, 1)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-0,\t-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-0,\t-1)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil('-0')", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil(-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil(-Number.MIN_VALUE)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil(-0.9)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.9.js", "Infinity/Math.floor(-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "var z = 0; print(1/-z)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "1/-1e-2000", willFixInNextReleaseMessage); +#endif + static const char klass[] = "tst_QScriptJsTestSuite"; QVector *data = qt_meta_data_tst_Suite(); diff --git a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp index 9514cd6..a3dfd6c 100644 --- a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp +++ b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp @@ -236,6 +236,16 @@ tst_Suite::tst_Suite() addExpectedFailure("global-const-var-conflicts", "false", "true", willFixInNextReleaseMessage); addExpectedFailure("string-lastindexof", "0", "-1", "test is wrong?"); +#ifndef Q_OS_LINUX + addExpectedFailure("to-precision", "1.235e+27", "1.234e+27", "QTBUG-8053: toPrecision(4) gives wrong result on Mac"); +#endif + +#ifdef Q_OS_SOLARIS + addExpectedFailure("math-min-max", "Infinity", "-Infinity", willFixInNextReleaseMessage); + addExpectedFailure("negate-zero", "false", "true", willFixInNextReleaseMessage); + addExpectedFailure("str-to-num", "Infinity", "-Infinity", willFixInNextReleaseMessage); +#endif + addTestExclusion("debug-*", "not applicable"); addTestExclusion("mirror-*", "not applicable"); -- cgit v0.12 From 79a7572bf2aa42ca246cb7efd53e3dac2cd426bc Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 9 Feb 2010 14:09:24 +0100 Subject: QNAM HTTP: Reserve bytes for HTTP parsing Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkreply.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index c56a3a3..6615410 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -423,6 +423,11 @@ int QHttpNetworkReplyPrivate::gunzipBodyPartially(QByteArray &compressed, QByteA qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) { + if (fragment.isEmpty()) { + // reserve bytes for the status line. This is better than always append() which reallocs the byte array + fragment.reserve(32); + } + qint64 bytes = 0; char c; qint64 haveRead = 0; @@ -502,6 +507,13 @@ bool QHttpNetworkReplyPrivate::parseStatus(const QByteArray &status) qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket) { + if (fragment.isEmpty()) { + // according to http://dev.opera.com/articles/view/mama-http-headers/ the average size of the header + // block is 381 bytes. + // reserve bytes. This is better than always append() which reallocs the byte array. + fragment.reserve(512); + } + qint64 bytes = 0; char c = 0; bool allHeaders = false; -- cgit v0.12 From 169dd653a730342d90b39a0744d2c82d318d8d07 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 9 Feb 2010 14:37:46 +0100 Subject: QNAM HTTP: Forgot to remove a qDebug() Reviewed-by: TrustMe --- 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 6615410..512c045 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -591,7 +591,7 @@ void QHttpNetworkReplyPrivate::parseHeader(const QByteArray &header) } while (i < header.count() && (header.at(i) == ' ' || header.at(i) == '\t')); if (i == -1) break; // something is wrong - qDebug() << "added header" << field << value; + fields.append(qMakePair(field, value)); } } -- cgit v0.12 From 0a9c7a44c6a9ca134c7a23a33a9285787a7a6d19 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Tue, 9 Feb 2010 16:05:50 +0100 Subject: Fix tst_QAbstractItemView::task250754_fontChange and tst_QAbstractItemView::QTBUG6407_extendedSelection for Symbian & 5800 We should consider the difference between Point and Pixel for font size. And also the margin and some other settings in style for views. Reviewed-by: TrustMe --- tests/auto/qabstractitemview/tst_qabstractitemview.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp index 504ceac..ea86c16 100644 --- a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp @@ -1213,14 +1213,14 @@ void tst_QAbstractItemView::task250754_fontChange() tree.setModel(m); w.show(); - w.resize(150,150); + w.resize(150,240); QTest::qWait(30); QFont font = tree.font(); - font.setPointSize(5); + font.setPixelSize(10); tree.setFont(font); QTRY_VERIFY(!tree.verticalScrollBar()->isVisible()); - font.setPointSize(45); + font.setPixelSize(60); tree.setFont(font); //now with the huge items, the scrollbar must be visible QTRY_VERIFY(tree.verticalScrollBar()->isVisible()); @@ -1444,7 +1444,10 @@ void tst_QAbstractItemView::QTBUG6407_extendedSelection() for(int i = 0; i < 50; ++i) view.addItem(QString::number(i)); - view.resize(200,200); + QFont font = view.font(); + font.setPixelSize(10); + view.setFont(font); + view.resize(200,240); view.show(); QApplication::setActiveWindow(&view); -- cgit v0.12 From 43f76aaa733f66895fd672a9243e950d410ef918 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Tue, 9 Feb 2010 15:38:44 +0100 Subject: Add mingw-specific expected failures for JS test suite --- tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp b/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp index ffcb56e..41df98c 100644 --- a/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp +++ b/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp @@ -683,8 +683,10 @@ tst_Suite::tst_Suite() addExpectedFailure("ecma_3/String/15.5.4.11.js", "Section 7", willFixInNextReleaseMessage); addExpectedFailure("ecma_3/String/15.5.4.11.js", "Section 26", willFixInNextReleaseMessage); +#ifndef Q_CC_MINGW addExpectedFailure("ecma/Expressions/11.4.7-02.js", "-(-2147483648) == 2147483648", willFixInNextReleaseMessage); addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "- -\"0x80000000\"", willFixInNextReleaseMessage); +#endif #ifdef Q_OS_WIN addExpectedFailure("ecma_3/Expressions/11.7.3-01.js", "11.7.3 - >>> should evaluate operands in order: order", "QTBUG-8056"); @@ -692,6 +694,15 @@ tst_Suite::tst_Suite() addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.13.2 >>>=", "QTBUG-8056"); #endif +#ifdef Q_CC_MINGW + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,-0)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(Infinity, Infinity)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(Infinity, -Infinity)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-Infinity, Infinity)", willFixInNextReleaseMessage); + addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-Infinity, -Infinity)", willFixInNextReleaseMessage); +#endif + #ifdef Q_OS_SOLARIS addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = -0; VAR2= Infinity; VAR2 /= VAR1", willFixInNextReleaseMessage); addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = -0; VAR2= -Infinity; VAR2 /= VAR1", willFixInNextReleaseMessage); -- cgit v0.12 From 33aa8f4a035c1ce9231b40844e6e0793205d12aa Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Tue, 9 Feb 2010 11:37:18 +0000 Subject: Added qwidget test case which displays a native child widget As of commit bc82db, show()ing a native child widget causes a panic on Symbian. The panic code (WSERV-10) indicates that Activate() is being called on an already-active graphics context. This test case reproduces the defect. Task-number: QTBUG-7960 --- tests/auto/qwidget/tst_qwidget.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 03eddee..b59017b 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -250,6 +250,7 @@ private slots: #else void persistentWinId(); #endif + void showNativeChild(); void qobject_castInDestroyedSlot(); void showHideEvent_data(); @@ -4586,6 +4587,16 @@ void tst_QWidget::persistentWinId() } #endif // Q_OS_SYMBIAN +void tst_QWidget::showNativeChild() +{ + QWidget topLevel; + topLevel.setGeometry(0, 0, 100, 100); + QWidget child(&topLevel); + child.winId(); + topLevel.show(); + QTest::qWaitForWindowShown(&topLevel); +} + class ShowHideEventWidget : public QWidget { public: -- cgit v0.12 From 46df42af1a25fd06247bb96d9e0bf24bf19defe8 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Tue, 9 Feb 2010 09:41:29 +0000 Subject: Fixed defect in handling of expose events for Symbian Commit bc82db did not correctly handle native child widgets. Consider the case when we have a top-level widget A with a native child widget B. When QSymbianControl::Draw() is called on the control corresponding to B, the following occurs: 1. The inExpose flag is set in B's QWExtra structure. 2. The call to syncBackingStore() results in a call to QWidgetBackingStore::flush(), passing default parameters. 3. Because no target widget was passed to flush(), this function selects the top-level widget (A) as the target for the flush operation, passing A as the first argument of QS60WindowSurface::flush(). 4. QS60WindowSurface::flush() checks the inExpose flag from A's QWExtra structure, finds it to be false, and proceeds to call DrawNow() on A's control. Because QSymbianControl::Draw() uses the default graphics context, this context is shared between controls. This means that the DrawNow() call in step 4 causes a WSERV-10 panic (Activate() called on an already-active) graphics context. This patch moves the inExpose flag from B's QWExtra into A's QTLWExtra, with the result that the call to DrawNow() in step 4 is suppressed. Task-number: QTBUG-7960 Reviewed-by: axis --- src/gui/kernel/qapplication_s60.cpp | 11 +++++++---- src/gui/kernel/qwidget_p.h | 3 ++- src/gui/kernel/qwidget_s60.cpp | 2 +- src/gui/painting/qwindowsurface_s60.cpp | 11 +++++++---- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 4a137ee..bf3ad71 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -809,12 +809,15 @@ TCoeInputCapabilities QSymbianControl::InputCapabilities() const void QSymbianControl::Draw(const TRect& controlRect) const { // Set flag to avoid calling DrawNow in window surface - QWExtra *extra = qwidget->d_func()->extraData(); - if (extra && !extra->inExpose) { - extra->inExpose = true; + QWidget *window = qwidget->window(); + Q_ASSERT(window); + QTLWExtra *topExtra = window->d_func()->maybeTopData(); + Q_ASSERT(topExtra); + if (!topExtra->inExpose) { + topExtra->inExpose = true; QRect exposeRect = qt_TRect2QRect(controlRect); qwidget->d_func()->syncBackingStore(exposeRect); - extra->inExpose = false; + topExtra->inExpose = false; } QWindowSurface *surface = qwidget->windowSurface(); diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index b1eb3c3..4b62074 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -173,6 +173,8 @@ struct QTLWExtra { #ifndef QT_NO_QWS_MANAGER QWSManager *qwsManager; #endif +#elif defined(Q_OS_SYMBIAN) + uint inExpose : 1; // Prevents drawing recursion #endif }; @@ -229,7 +231,6 @@ struct QWExtra { #endif #elif defined(Q_OS_SYMBIAN) // <----------------------------------------------------- Symbian uint activated : 1; // RWindowBase::Activated has been called - uint inExpose : 1; // Prevents drawing recursion /** * Defines the behaviour of QSymbianControl::Draw. diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index a844430..ebd289c 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -878,6 +878,7 @@ void QWidgetPrivate::registerDropSite(bool /* on */) void QWidgetPrivate::createTLSysExtra() { extra->topextra->backingStore = 0; + extra->topextra->inExpose = 0; } void QWidgetPrivate::deleteTLSysExtra() @@ -891,7 +892,6 @@ void QWidgetPrivate::createSysExtra() extra->activated = 0; extra->nativePaintMode = QWExtra::Default; extra->receiveNativePaintEvents = 0; - extra->inExpose = 0; } void QWidgetPrivate::deleteSysExtra() diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index b41dc2c..6cbf3d9 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -145,12 +145,15 @@ QImage* QS60WindowSurface::buffer(const QWidget *widget) void QS60WindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &) { - QWExtra *extra = widget->d_func()->extraData(); - if (extra && !extra->inExpose) { - extra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again + QWidget *window = widget->window(); + Q_ASSERT(window); + QTLWExtra *topExtra = window->d_func()->maybeTopData(); + Q_ASSERT(topExtra); + if (!topExtra->inExpose) { + topExtra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again TRect tr = qt_QRect2TRect(region.boundingRect()); widget->winId()->DrawNow(tr); - extra->inExpose = false; + topExtra->inExpose = false; } } -- cgit v0.12 From 500f28f04a08e37525e3d1deb5cfe6e908c66b15 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Tue, 9 Feb 2010 14:52:16 +0100 Subject: Refactor comp_func_solid_Clear() and comp_func_solid_Source() Put the common code together with a #define. Remove the check for the length from comp_func_Clear_impl and move it to qt_memfill() --- src/gui/painting/qdrawhelper.cpp | 36 +++++++++++++++------------------- src/gui/painting/qdrawhelper_mmx_p.h | 38 +++++++++++++++--------------------- src/gui/painting/qdrawhelper_p.h | 3 +++ 3 files changed, 35 insertions(+), 42 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 660a2a8..7a3da20 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1267,32 +1267,28 @@ static const uint L2CacheLineLengthInInts = L2CacheLineLength/sizeof(uint); result = 0 d = d * cia */ +#define comp_func_Clear_impl(dest, length, const_alpha)\ +{\ + if (const_alpha == 255) {\ + QT_MEMFILL_UINT(dest, length, 0);\ + } else {\ + int ialpha = 255 - const_alpha;\ + PRELOAD_INIT(dest)\ + for (int i = 0; i < length; ++i) {\ + PRELOAD_COND(dest)\ + dest[i] = BYTE_MUL(dest[i], ialpha);\ + }\ + }\ +} + static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha) { - if (const_alpha == 255) { - QT_MEMFILL_UINT(dest, length, 0); - } else { - int ialpha = 255 - const_alpha; - PRELOAD_INIT(dest) - for (int i = 0; i < length; ++i) { - PRELOAD_COND(dest) - dest[i] = BYTE_MUL(dest[i], ialpha); - } - } + comp_func_Clear_impl(dest, length, const_alpha); } static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha) { - if (const_alpha == 255) { - QT_MEMFILL_UINT(dest, length, 0); - } else { - int ialpha = 255 - const_alpha; - PRELOAD_INIT(dest) - for (int i = 0; i < length; ++i) { - PRELOAD_COND(dest) - dest[i] = BYTE_MUL(dest[i], ialpha); - } - } + comp_func_Clear_impl(dest, length, const_alpha); } /* diff --git a/src/gui/painting/qdrawhelper_mmx_p.h b/src/gui/painting/qdrawhelper_mmx_p.h index 8482262..f8bc480 100644 --- a/src/gui/painting/qdrawhelper_mmx_p.h +++ b/src/gui/painting/qdrawhelper_mmx_p.h @@ -146,36 +146,30 @@ struct QMMXCommonIntrinsics result = 0 d = d * cia */ +#define comp_func_Clear_impl(dest, length, const_alpha)\ +{\ + if (const_alpha == 255) {\ + qt_memfill(static_cast(dest), quint32(0), length);\ + } else {\ + C_FF; C_80; C_00;\ + m64 ia = MM::negate(MM::load_alpha(const_alpha));\ + for (int i = 0; i < length; ++i) {\ + dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia));\ + }\ + MM::end();\ + }\ +} + template static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha) { - if (!length) - return; - - if (const_alpha == 255) { - qt_memfill(static_cast(dest), quint32(0), length); - } else { - C_FF; C_80; C_00; - m64 ia = MM::negate(MM::load_alpha(const_alpha)); - for (int i = 0; i < length; ++i) { - dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia)); - } - } - MM::end(); + comp_func_Clear_impl(dest, length, const_alpha); } template static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha) { - if (const_alpha == 255) { - qt_memfill(static_cast(dest), quint32(0), length); - } else { - C_FF; C_80; C_00; - m64 ia = MM::negate(MM::load_alpha(const_alpha)); - for (int i = 0; i < length; ++i) - dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia)); - } - MM::end(); + comp_func_Clear_impl(dest, length, const_alpha); } /* diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 6c47aac..cb0db4f 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -1549,6 +1549,9 @@ template<> inline void qt_memfill(quint8 *dest, quint8 color, int count) template inline void qt_memfill(T *dest, T value, int count) { + if (!count) + return; + int n = (count + 7) / 8; switch (count & 0x07) { -- cgit v0.12 From d9354e6e6863bc1f82b9581726c43f3bd76bc44b Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Tue, 9 Feb 2010 16:58:56 +0100 Subject: Skip the transparent pixels when doing the sourceOver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Blending fully transparent pixels take a non-negligible time when webkit use transparent layer. We can avoid that be skipping those pixels since they have no impact on the final result. Reviewed-by: Samuel Rødal --- src/gui/painting/qdrawhelper_mmx_p.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qdrawhelper_mmx_p.h b/src/gui/painting/qdrawhelper_mmx_p.h index f8bc480..59b3804 100644 --- a/src/gui/painting/qdrawhelper_mmx_p.h +++ b/src/gui/painting/qdrawhelper_mmx_p.h @@ -240,7 +240,10 @@ static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int le C_FF; C_80; C_00; if (const_alpha == 255) { for (int i = 0; i < length; ++i) { - if ((0xff000000 & src[i]) == 0xff000000) { + const uint alphaMaskedSource = 0xff000000 & src[i]; + if (alphaMaskedSource == 0) + continue; + if (alphaMaskedSource == 0xff000000) { dest[i] = src[i]; } else { m64 s = MM::load(src[i]); @@ -251,6 +254,8 @@ static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int le } else { m64 ca = MM::load_alpha(const_alpha); for (int i = 0; i < length; ++i) { + if ((0xff000000 & src[i]) == 0) + continue; m64 s = MM::byte_mul(MM::load(src[i]), ca); m64 ia = MM::negate(MM::alpha(s)); dest[i] = MM::store(MM::add(s, MM::byte_mul(MM::load(dest[i]), ia))); -- cgit v0.12 From cf6a427a94b615dcb7ab1e594b27a593dcc73c62 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 10 Feb 2010 04:38:49 +1000 Subject: Tidy the changes file. Reviewed-by: Trust Me --- dist/changes-4.6.2 | 274 +++++++++++++++++++---------------------------------- 1 file changed, 97 insertions(+), 177 deletions(-) diff --git a/dist/changes-4.6.2 b/dist/changes-4.6.2 index aaaaacc..657aafc 100644 --- a/dist/changes-4.6.2 +++ b/dist/changes-4.6.2 @@ -16,22 +16,6 @@ Qt Bug Tracker: http://bugreports.qt.nokia.com Task Tracker: http://qt.nokia.com/developer/task-tracker Merge Request: http://qt.gitorious.org -**************************************************************************** -* General * -**************************************************************************** - -New features ------------- - - - SomeClass, SomeOtherClass - * New classes for foo, bar and baz - -Optimizations -------------- - - - Optimized foo in QSomeClass - * See list of Important Behavior Changes below - **************************************************************************** * Library * @@ -42,98 +26,88 @@ QtCore - QAtomicPointer * [QTBUG-7356] Fixed a compilation failure when using the Intel - compiler on IA-64 - + compiler on IA-64 - QFile * Fixed double-buffering issue when opening files in buffered mode. - * [QTBUG-7285] QFile::remove would fail if an unrelated operation on the - same instance had been previously failed. This manisfested itself in - QTemporaryFile failing to auto-remove files and QFile::copy leaving + * [QTBUG-7285] QFile::remove would() fail if an unrelated operation on the + same instance had been previously failed. This manifested itself in + QTemporaryFile failing to auto-remove files and QFile::copy() leaving temporary files behind in certain situations. - - QFSFileEngine - * Fix typo that made realpath() not being used - + * Fix typo that made realpath() not be used. - QIODevice - * Optimized readAll() - + * Optimized readAll(). - QReadWriteLock - * [MR 426] Fixed documentation - + * [MR 426] Fixed documentation. - QXmlStreamWriter - * [QTBUG-6893] Fixed adding extra Byte Order Marks when writing to a xml file. + * [QTBUG-6893] Fixed adding extra Byte Order Marks when writing to a + .xml file. QtGui ----- + - QApplication + * [QTBUG-6098] Added a flag to avoid construction of application panes. + * [QTBUG-7029] Fixed a crash when re-creating QApplication object due + to a dangling gesture manager pointer. - QAbstractScrollArea - * [QTBUG-1760] Reverted horizontal scrolling with mouse wheel when vertical scrollbar is hidden - + * [QTBUG-1760] Reverted horizontal scrolling with mouse wheel when vertical + scrollbar is hidden - QBmpHandler - * [QTBUG-7530] Fixed an infinite loop that could occur when reading invalid BMP images. - + * [QTBUG-7530] Fixed an infinite loop that could occur when reading invalid + BMP images. - QGraphicsEffect * [QTBUG-6901] Fixed performance problem when translating items with graphics effects. - - QImage * [QTBUG-7231] Avoid an unnecessary copy in QImage::scaled(). - - - QPDFEngine - * [QTBUG-7249] Fixed the encoding of the Tile and Creator tags in the PDF engine. - - - QApplication - * [QTBUG-6098] Added a flag to avoid construction of application panes. - QInputContext - * [QTBUG-7439] Avoided the loss of preedit text when losing focus on Symbian. - - * [QT-2629] Implemented event filter functions for Symbian. - * [QTBUG-7029] Fixed a crash when re-creating QApplication object due to a - dangling gesture manager pointer. - * [QTBUG-7198] Setting a style sheet could break the checkbox position in item views. - * [QTBUG-7253] Fixed wrong stroke clipping with the raster engine when using a QPen - with a style other than SolidLine. - - - * [MR 2077] Integrated merge request 2077 + * [QTBUG-7439] Avoided the loss of preedit text when losing focus on + Symbian. + - QPDFEngine + * [QTBUG-7249] Fixed the encoding of the Tile and Creator tags in the PDF + engine. + - [QT-2629] Implemented event filter functions for Symbian. + - [QTBUG-7198] Setting a style sheet could break the checkbox position in + item views. + - [QTBUG-7253] Fixed wrong stroke clipping with the raster engine when using + a QPen with a style other than SolidLine. QtDBus ------ - QDBusConnection - * [QT-2307] Fixed sending of D-Bus method calls with QDBus::BlockWithGui + * [QT-2307] Fixed sending of D-Bus method calls with QDBus::BlockWithGui. QtNetwork --------- - QNetworkAccessManager * Optimizations - * HTTP: Get rid of QAbstractSocket warnings that were sometimes displayed - * HTTP: setReadBufferSize() of the QNetworkReply finally is working on all layers - * [QTBUG-7713] HTTP: Fix bug related to re-sending a request + * HTTP: Get rid of QAbstractSocket warnings that were sometimes displayed. + * HTTP: setReadBufferSize() of the QNetworkReply finally is working on all + layers. + * [QTBUG-7713] HTTP: Fix bug related to re-sending a request. * [QTBUG-7060] Fixed an issue with parsing of HTTP headers like - "private, max-age=300" - + "private, max-age=300". - QSslCertificate - * [QTBUG-6466] Fix issuerInfo() and subjectInfo() - + * [QTBUG-6466] Fix issuerInfo() and subjectInfo(). - QTcpSocket - * [QTBUG-7344] Fix performance degredation with write() on Windows - * [QTBUG-7316,QTBUG-7317] Also handle unknown errors from socket engine + * [QTBUG-7344] Fix performance degredation with write() on Windows. + * [QTBUG-7316,QTBUG-7317] Handle unknown errors from socket engine. QtOpenGL -------- - [QTBUG-7490] Better support for user-generated binary shaders. - - - QGLWidget - * [QTBUG-7213] Fixed QGLWidget::renderPixmap() on Windows. - - QGLPixelBuffer - * [QTBUG-7476] Fixed a crash under X11 when drawing QPixmaps to QGLPixelBuffers. - + * [QTBUG-7476] Fixed a crash under X11 when drawing QPixmaps to + QGLPixelBuffers. - QGL2PaintEngineEx * [QTBUG-7203] Reset the GL stencil mask, op and function in resetGLState(). + - QGLWidget + * [QTBUG-7213] Fixed QGLWidget::renderPixmap() on Windows. + QtOpenVG -------- @@ -141,137 +115,89 @@ QtOpenVG - [QTBUG-7791] Optimize single-rect IntersectClip in OpenVG using the scissor. - [QTBUG-7864] Use OpenVG scissor on 90/180/270 rotations and simple clips. -QtScript --------- - - - foo - * bar - -QtSql ------ - - - foo - * bar - -QtXml ------ - - - foo - * bar - QtMultimedia ------------ - QAudioInput - * [QTBUG-7044]: QAudioInput stopped working correctly after suspend()/resume() on linux. - -Qt Plugins ----------- - - - foo - * bar + * [QTBUG-7044]: QAudioInput stopped working correctly after + suspend()/resume() on linux. Examples -------- - QtMultimedia - * [MR 418] Fixed the example for QAudioOutput - + * [MR 418] Fixed the example for QAudioOutput. - WebKit - * [MR 2235] Added the framecapture example to the default build - -Third party components ----------------------- - - - Updated foo to version 2.3.9. - - - Updated bar to the latest version from baz.org. + * [MR 2235] Added the framecapture example to the default build. **************************************************************************** * Platform Specific Changes * **************************************************************************** -Qt for Unix (X11 and Mac OS X) ------------------------------- - - - - Qt for Linux/X11 ---------------- - * Fix a bug where QPixmap::serialNumber was not set on a transformed pixmap - in Qt/X11. - - * Fixed a crash when an input method tries to create a widget after the - application is destroyed. - - - [QTBUG-6952] Fixed a problem using NoButtons in spinbox with QGtkStyle - - [QTBUG-7504] Fixed missing focus rect on check- and radiobutton with - some GTK+ themes. - - [QTBUG-6522] Fixed missing menu separator in some GTK+ themes. - -Qt for Windows --------------- + - Fix a bug where QPixmap::serialNumber was not set on a transformed pixmap + in Qt/X11. + - Fixed a crash when an input method tries to create a widget after the + application is destroyed. + - [QTBUG-6952] Fixed a problem using NoButtons in spinbox with QGtkStyle. + - [QTBUG-7504] Fixed missing focus rect on check- and radiobutton with + some GTK+ themes. + - [QTBUG-6522] Fixed missing menu separator in some GTK+ themes. Qt for Mac OS X --------------- - [QTBUG-7832]: Restored missing margins around non-unified toolbars. - - [QTBUG-7312]: Menubar and dock disappear after hiding a fullscreen widget on Cocoa. - - [QTBUG-7481]: Re-added the Close button in QPrintPreviewDialog for Mac/Carbon. - - [QTBUG-7522]: Drawing fake buttons using QMacStyle+QStyleOptionViewItemV4 lead to crash. - - [QTBUG-7625]: Calling showFullScreen() then showNormal() on a widget results in top menu hiding. - - [QTBUG-7086]: QFileDialog now correctly responds to fileMode & acceptMode changes. - - [QTBUG-7162]: Fixed a crash in Designer when previewing a QMainWindow with native toolbar. - - [QTBUG-7305]: Fixed a crash when deleting QMainWindow with native toolbar on Cocoa. - - [QTBUG-6882]: Fixed a text layout issue with QHeaderView in right-to-left mode. - - -Qt for Embedded Linux ---------------------- - - - + - [QTBUG-7312]: Menubar and dock disappear after hiding a fullscreen widget + on Cocoa. + - [QTBUG-7481]: Re-added the Close button in QPrintPreviewDialog for + Mac/Carbon. + - [QTBUG-7522]: Drawing fake buttons using QMacStyle+QStyleOptionViewItemV4 + lead to crash. + - [QTBUG-7625]: Calling showFullScreen() then showNormal() on a widget results + in top menu hiding. + - [QTBUG-7086]: QFileDialog now correctly responds to fileMode & acceptMode + changes. + - [QTBUG-7162]: Fixed a crash in Designer when previewing a QMainWindow with + native toolbar. + - [QTBUG-7305]: Fixed a crash when deleting QMainWindow with native toolbar + on Cocoa. + - [QTBUG-6882]: Fixed a text layout issue with QHeaderView in right-to-left + mode. DirectFB -------- - * Fix a bug where QPixmap::serialNumber was not set on a transformed pixmap - in DirectFB. - * Reimplement QPixmapData::scroll for QDirectFBPixmapData which optimizes - QPixmap::scroll - * Fix a rendering issue for semi-transparent top level windows in DirectFB. - * Make it possible to fall back to the raster engine for stretch blits in - DirectFB using QT_NO_DIRECTFB_STRETCHBLIT - - - -Qt for Windows CE ------------------ - - + - Fix a bug where QPixmap::serialNumber was not set on a transformed pixmap + in DirectFB. + - Reimplement QPixmapData::scroll for QDirectFBPixmapData which optimizes + QPixmap::scroll. + - Fix a rendering issue for semi-transparent top level windows in DirectFB. + - Make it possible to fall back to the raster engine for stretch blits in + DirectFB using QT_NO_DIRECTFB_STRETCHBLIT. Qt for Symbian -------------- - * [QTBUG-6556] Improve the DEF file handling scheme, to allow simple enable/ - disable of DEF file usage (for use _during development only_ to decouple - the need to update the DEF files at the precise point that symbols are - removed, therefore allowing builds by CI systems to succeed even if symbols - have been removed. This does not remove the need to update the DEF files - before release. NOTE: Builds generated using this flag are not binary - compatible with previous versions of Qt.) - -- QProcess - * [QTBUG-7667] Fixed no-timeout case for QProcess::waitForFinished. - -- qmake - * [QTBUG-7695] Added support for ifdeffing for manufacturer in generated - pkg files. - * [QTBUG-7908] Smart installer package generation support - -- Patch_capabilities script + - [QTBUG-6556] Improve the DEF file handling scheme, to allow simple enable/ + disable of DEF file usage (for use _during development only_ to decouple + the need to update the DEF files at the precise point that symbols are + removed, therefore allowing builds by CI systems to succeed even if symbols + have been removed. This does not remove the need to update the DEF files + before release. NOTE: Builds generated using this flag are not binary + compatible with previous versions of Qt.) + - QProcess + * [QTBUG-7667] Fixed no-timeout case for QProcess::waitForFinished. + - qmake + * [QTBUG-7695] Added support for ifdeffing for manufacturer in generated + pkg files. + * [QTBUG-7908] Smart installer package generation support. + - Patch_capabilities script * Added support for embedded sis name/uid patching. - -- Qt deployment - * [QTBUG-7518] Backup and restore support for Qt libs + - Qt deployment + * [QTBUG-7518] Backup and restore support for Qt libs. **************************************************************************** @@ -279,28 +205,22 @@ Qt for Symbian **************************************************************************** - Designer - * [QTBUG-6965] Enabled editing seconds of QDateTime-type properties + * [QTBUG-6965] Enabled editing seconds of QDateTime-type properties. * [QTBUG-6757] Fixed bug where selection handles would be affected by a style sheet set on the main form. - uic3 * [QTBUG-7404] Added option to preserve layout names set by Qt 3 Designer. - - qdoc3 - * bar - - - Linguist - * baz - **************************************************************************** * Important Behavior Changes * **************************************************************************** - QNetworkAccessManager cache - * QNetworkAccessManager will no longer return expired pages, as - stated in the documentation - * The behaviour of PreferCache and PreferNetwork modes now match - the documentation more closely + * QNetworkAccessManager will no longer return expired pages, as + stated in the documentation + * The behaviour of PreferCache and PreferNetwork modes now match + the documentation more closely - QUrl * QUrl will now accept hostnames ending in dot and will not treat -- cgit v0.12 From 3208a33a18d7eb666f0f47eff02ce4b21e248c10 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 9 Feb 2010 11:45:01 +0100 Subject: Catch up TRK library to creator f2b3e9f2dfbc580389b9b683a3e46e5a8422f55b This is the last SHA before trk directory is renamed. Note the \\.\ is prepended to windows com ports inside the library now, so main.cpp no longer has this windows specific code. commit f2b3e9f2dfbc580389b9b683a3e46e5a8422f55b Author: Friedemann Kleint Date: Fri Feb 5 12:24:46 2010 +0100 S60/Trk: Change trkutils to be a library of its own. To be able to share TrkDevices between Debugger and Qt4ProjectManager. commit 61c3a260b59433abf8c3ef481ec536af88f8026c Author: Sarika Kamisetty Date: Thu Feb 4 09:57:54 2010 +0100 Fix to App TRK connection with 'high COM port' does not work Merge-request: 111 Reviewed-by: hjk commit 2fd8b2d7ffa2ac032bfe3a17efe7d152c4cef14d Author: Friedemann Kleint Date: Mon Feb 1 12:43:56 2010 +0100 Fix some code scanning issues. QString: Use QChar where appropriate. commit 805b0a9cc165ef6cd596bd8f5e59f650cd0eebb2 Author: hjk Date: Mon Feb 1 11:45:44 2010 +0100 debugger: trk log output cosmetic commit 75b42f18d886b59dbf3380dd12f39f40005ef08b Merge: 4320314 a6ca348 Author: Oswald Buddenhagen Date: Fri Jan 29 22:49:55 2010 +0100 Merge remote branch 'origin/1.3' Trailing whitespace removal re-applied manually. commit a6ca348636dd92ab1445cff2286b3293163f5cea Author: Oswald Buddenhagen Date: Fri Jan 29 21:33:57 2010 +0100 remove trailing whitespace doing it in 1.3 as well to avoid possible later conflicts commit 4ec51219ed5c2150e164473b9c5326b6c68d096a Author: Friedemann Kleint Date: Thu Jan 28 17:04:05 2010 +0100 Trk: Fix source code scanning tool issues. showing up in Qt. --- tools/runonphone/main.cpp | 4 - tools/runonphone/trk/bluetoothlistener.cpp | 2 +- tools/runonphone/trk/bluetoothlistener.h | 4 +- tools/runonphone/trk/bluetoothlistener_gui.cpp | 6 +- tools/runonphone/trk/bluetoothlistener_gui.h | 8 +- tools/runonphone/trk/callback.h | 2 +- tools/runonphone/trk/communicationstarter.h | 8 +- tools/runonphone/trk/launcher.cpp | 25 +++--- tools/runonphone/trk/launcher.h | 2 +- tools/runonphone/trk/symbianutils_global.h | 55 +++++++++++++ tools/runonphone/trk/trk.pri | 4 +- tools/runonphone/trk/trkdevice.cpp | 18 +++-- tools/runonphone/trk/trkdevice.h | 3 +- tools/runonphone/trk/trkutils.cpp | 105 ++++++++++++------------- tools/runonphone/trk/trkutils.h | 45 +++++------ tools/runonphone/trk/trkutils_p.h | 62 +++++++++++++++ 16 files changed, 233 insertions(+), 120 deletions(-) create mode 100644 tools/runonphone/trk/symbianutils_global.h create mode 100644 tools/runonphone/trk/trkutils_p.h diff --git a/tools/runonphone/main.cpp b/tools/runonphone/main.cpp index a77e713..1a5cdee 100644 --- a/tools/runonphone/main.cpp +++ b/tools/runonphone/main.cpp @@ -174,11 +174,7 @@ int main(int argc, char *argv[]) } if(loglevel > 0) outstream << "Connecting to target via " << serialPortName << endl; -#ifdef Q_OS_WIN - launcher->setTrkServerName(QString("\\\\.\\") + serialPortName); -#else launcher->setTrkServerName(serialPortName); -#endif launcher->setFileName(QString("c:\\sys\\bin\\") + exeFile); launcher->setCommandLineArgs(cmdLine); diff --git a/tools/runonphone/trk/bluetoothlistener.cpp b/tools/runonphone/trk/bluetoothlistener.cpp index 8d45fb5..df04288 100644 --- a/tools/runonphone/trk/bluetoothlistener.cpp +++ b/tools/runonphone/trk/bluetoothlistener.cpp @@ -184,7 +184,7 @@ bool BluetoothListener::start(const QString &device, QString *errorMessage) return true; } -void BluetoothListener::slotStdOutput() +void BluetoothListener::slotStdOutput() { emitMessage(QString::fromLocal8Bit(d->process.readAllStandardOutput())); } diff --git a/tools/runonphone/trk/bluetoothlistener.h b/tools/runonphone/trk/bluetoothlistener.h index 027f286..36894e7 100644 --- a/tools/runonphone/trk/bluetoothlistener.h +++ b/tools/runonphone/trk/bluetoothlistener.h @@ -42,6 +42,8 @@ #ifndef BLUETOOTHLISTENER_H #define BLUETOOTHLISTENER_H +#include "symbianutils_global.h" + #include #include @@ -53,7 +55,7 @@ struct BluetoothListenerPrivate; * The rfcomm command is used. It process can be started in the background * while connection attempts (TrkDevice::open()) are made in the foreground. */ -class BluetoothListener : public QObject +class SYMBIANUTILS_EXPORT BluetoothListener : public QObject { Q_OBJECT Q_DISABLE_COPY(BluetoothListener) diff --git a/tools/runonphone/trk/bluetoothlistener_gui.cpp b/tools/runonphone/trk/bluetoothlistener_gui.cpp index 6ffdaef..5994eb5 100644 --- a/tools/runonphone/trk/bluetoothlistener_gui.cpp +++ b/tools/runonphone/trk/bluetoothlistener_gui.cpp @@ -50,7 +50,7 @@ namespace trk { -PromptStartCommunicationResult +SYMBIANUTILS_EXPORT PromptStartCommunicationResult promptStartCommunication(BaseCommunicationStarter &starter, const QString &msgBoxTitle, const QString &msgBoxText, @@ -88,7 +88,7 @@ PromptStartCommunicationResult return PromptStartCommunicationConnected; } -PromptStartCommunicationResult +SYMBIANUTILS_EXPORT PromptStartCommunicationResult promptStartSerial(BaseCommunicationStarter &starter, QWidget *msgBoxParent, QString *errorMessage) @@ -98,7 +98,7 @@ PromptStartCommunicationResult return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage); } -PromptStartCommunicationResult +SYMBIANUTILS_EXPORT PromptStartCommunicationResult promptStartBluetooth(BaseCommunicationStarter &starter, QWidget *msgBoxParent, QString *errorMessage) diff --git a/tools/runonphone/trk/bluetoothlistener_gui.h b/tools/runonphone/trk/bluetoothlistener_gui.h index d673ffe..10e7145 100644 --- a/tools/runonphone/trk/bluetoothlistener_gui.h +++ b/tools/runonphone/trk/bluetoothlistener_gui.h @@ -42,6 +42,8 @@ #ifndef BLUETOOTHLISTENER_GUI_H #define BLUETOOTHLISTENER_GUI_H +#include "symbianutils_global.h" + #include QT_BEGIN_NAMESPACE @@ -62,7 +64,7 @@ enum PromptStartCommunicationResult { PromptStartCommunicationError }; -PromptStartCommunicationResult +SYMBIANUTILS_EXPORT PromptStartCommunicationResult promptStartCommunication(BaseCommunicationStarter &starter, const QString &msgBoxTitle, const QString &msgBoxText, @@ -71,14 +73,14 @@ PromptStartCommunicationResult // Convenience to start a serial connection (messages prompting // to launch Trk). -PromptStartCommunicationResult +SYMBIANUTILS_EXPORT PromptStartCommunicationResult promptStartSerial(BaseCommunicationStarter &starter, QWidget *msgBoxParent, QString *errorMessage); // Convenience to start blue tooth connection (messages // prompting to connect). -PromptStartCommunicationResult +SYMBIANUTILS_EXPORT PromptStartCommunicationResult promptStartBluetooth(BaseCommunicationStarter &starter, QWidget *msgBoxParent, QString *errorMessage); diff --git a/tools/runonphone/trk/callback.h b/tools/runonphone/trk/callback.h index edc2c74..3996d73 100644 --- a/tools/runonphone/trk/callback.h +++ b/tools/runonphone/trk/callback.h @@ -42,7 +42,7 @@ #ifndef DEBUGGER_CALLBACK_H #define DEBUGGER_CALLBACK_H -#include +#include "symbianutils_global.h" namespace trk { namespace Internal { diff --git a/tools/runonphone/trk/communicationstarter.h b/tools/runonphone/trk/communicationstarter.h index 34cf398..2d7dc50 100644 --- a/tools/runonphone/trk/communicationstarter.h +++ b/tools/runonphone/trk/communicationstarter.h @@ -42,6 +42,8 @@ #ifndef COMMUNICATIONSTARTER_H #define COMMUNICATIONSTARTER_H +#include "symbianutils_global.h" + #include #include @@ -60,7 +62,7 @@ struct BaseCommunicationStarterPrivate; * The base class can be used as is to prompt the user to launch App TRK for a * serial communication as this requires no further resource setup. */ -class BaseCommunicationStarter : public QObject { +class SYMBIANUTILS_EXPORT BaseCommunicationStarter : public QObject { Q_OBJECT Q_DISABLE_COPY(BaseCommunicationStarter) public: @@ -117,7 +119,7 @@ private: * implement as a factory function that creates and sets up the * listener (mode, message connection, etc). */ -class AbstractBluetoothStarter : public BaseCommunicationStarter { +class SYMBIANUTILS_EXPORT AbstractBluetoothStarter : public BaseCommunicationStarter { Q_OBJECT Q_DISABLE_COPY(AbstractBluetoothStarter) public: @@ -134,7 +136,7 @@ protected: /* ConsoleBluetoothStarter: Convenience class for console processes. Creates a * listener in "Listen" mode with the messages redirected to standard output. */ -class ConsoleBluetoothStarter : public AbstractBluetoothStarter { +class SYMBIANUTILS_EXPORT ConsoleBluetoothStarter : public AbstractBluetoothStarter { Q_OBJECT Q_DISABLE_COPY(ConsoleBluetoothStarter) public: diff --git a/tools/runonphone/trk/launcher.cpp b/tools/runonphone/trk/launcher.cpp index 1796fc5..4f91545 100644 --- a/tools/runonphone/trk/launcher.cpp +++ b/tools/runonphone/trk/launcher.cpp @@ -41,6 +41,7 @@ #include "launcher.h" #include "trkutils.h" +#include "trkutils_p.h" #include "trkdevice.h" #include "bluetoothlistener.h" @@ -595,17 +596,19 @@ void Launcher::handleSupportMask(const TrkResult &result) return; const char *data = result.data.data() + 1; - QByteArray str; + QString str = QLatin1String("SUPPORTED: "); for (int i = 0; i < 32; ++i) { //str.append(" [" + formatByte(data[i]) + "]: "); - for (int j = 0; j < 8; ++j) - if (data[i] & (1 << j)) - str.append(QByteArray::number(i * 8 + j, 16) + " "); + for (int j = 0; j < 8; ++j) { + if (data[i] & (1 << j)) { + str.append(QString::number(i * 8 + j, 16)); + str.append(QLatin1Char(' ')); + } + } } - logMessage("SUPPORTED: " + str); + logMessage(str); } - void Launcher::cleanUp() { // @@ -614,9 +617,7 @@ void Launcher::cleanUp() // Sub Cmd: Delete Process //ProcessID: 0x0000071F (1823) // [41 24 00 00 00 00 07 1F] - QByteArray ba; - appendByte(&ba, 0x00); - appendByte(&ba, 0x00); + QByteArray ba(2, char(0)); appendInt(&ba, d->m_session.pid); d->m_device->sendTrkMessage(TrkDeleteItem, TrkCallback(), ba, "Delete process"); @@ -669,7 +670,7 @@ void Launcher::copyFileToRemote() { emit copyingStarted(); QByteArray ba; - appendByte(&ba, 0x10); + ba.append(char(10)); appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false); d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba); } @@ -678,7 +679,7 @@ void Launcher::installRemotePackageSilently() { emit installingStarted(); QByteArray ba; - appendByte(&ba, 'C'); + ba.append('C'); appendString(&ba, d->m_installFileName.toLocal8Bit(), TargetByteOrder, false); d->m_device->sendTrkMessage(TrkInstallFile, TrkCallback(this, &Launcher::handleInstallPackageFinished), ba); } @@ -705,7 +706,7 @@ QByteArray Launcher::startProcessMessage(const QString &executable, // It's not started yet QByteArray ba; appendShort(&ba, 0, TargetByteOrder); // create new process - appendByte(&ba, 0); // options - currently unused + ba.append(char(0)); // options - currently unused if(arguments.isEmpty()) { appendString(&ba, executable.toLocal8Bit(), TargetByteOrder); return ba; diff --git a/tools/runonphone/trk/launcher.h b/tools/runonphone/trk/launcher.h index 8dc6ebe..2b23fd8 100644 --- a/tools/runonphone/trk/launcher.h +++ b/tools/runonphone/trk/launcher.h @@ -56,7 +56,7 @@ struct LauncherPrivate; typedef QSharedPointer TrkDevicePtr; -class Launcher : public QObject +class SYMBIANUTILS_EXPORT Launcher : public QObject { Q_OBJECT Q_DISABLE_COPY(Launcher) diff --git a/tools/runonphone/trk/symbianutils_global.h b/tools/runonphone/trk/symbianutils_global.h new file mode 100644 index 0000000..a6ffbe7 --- /dev/null +++ b/tools/runonphone/trk/symbianutils_global.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIANUTILS_GLOBAL_H +#define SYMBIANUTILS_GLOBAL_H + +#include + +#if defined(SYMBIANUTILS_BUILD_LIB) +# define SYMBIANUTILS_EXPORT Q_DECL_EXPORT +#elif defined(SYMBIANUTILS_BUILD_STATIC_LIB) || defined(SYMBIANUTILS_INCLUDE_PRI) +# define SYMBIANUTILS_EXPORT +#else +# define SYMBIANUTILS_EXPORT Q_DECL_IMPORT +#endif + +#endif // SYMBIANUTILS_GLOBAL_H diff --git a/tools/runonphone/trk/trk.pri b/tools/runonphone/trk/trk.pri index 2ce17c0..a54df76 100644 --- a/tools/runonphone/trk/trk.pri +++ b/tools/runonphone/trk/trk.pri @@ -1,8 +1,10 @@ INCLUDEPATH *= $$PWD # Input -HEADERS += $$PWD/callback.h \ +HEADERS += $$PWD/symbianutils_global.h \ + $$PWD/callback.h \ $$PWD/trkutils.h \ + $$PWD/trkutils_p.h \ $$PWD/trkdevice.h \ $$PWD/launcher.h \ $$PWD/bluetoothlistener.h \ diff --git a/tools/runonphone/trk/trkdevice.cpp b/tools/runonphone/trk/trkdevice.cpp index fe3261b..d587135 100644 --- a/tools/runonphone/trk/trkdevice.cpp +++ b/tools/runonphone/trk/trkdevice.cpp @@ -41,6 +41,7 @@ #include "trkdevice.h" #include "trkutils.h" +#include "trkutils_p.h" #include #include @@ -516,7 +517,7 @@ static inline bool overlappedSyncWrite(HANDLE file, bool WriterThread::write(const QByteArray &data, QString *errorMessage) { if (verboseTrk) - qDebug() << "Write raw data: " << data.toHex(); + qDebug() << "Write raw data: " << stringFromArray(data).toLatin1(); QMutexLocker locker(&m_context->mutex); #ifdef Q_OS_WIN DWORD charsWritten; @@ -856,8 +857,8 @@ void UnixReaderThread::terminate() { // Trigger select() by writing to the pipe char c = 0; - int written = write(m_terminatePipeFileDescriptors[1], &c, 1); - // FIXME: Use result. + const int written = write(m_terminatePipeFileDescriptors[1], &c, 1); + Q_UNUSED(written) wait(); } @@ -919,7 +920,7 @@ bool TrkDevice::open(const QString &port, QString *errorMessage) qDebug() << "Opening" << port << "is open: " << isOpen() << " serialFrame=" << serialFrame(); close(); #ifdef Q_OS_WIN - d->deviceContext->device = CreateFile(port.toStdWString().c_str(), + d->deviceContext->device = CreateFile(QString("\\\\.\\").append(port).toStdWString().c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, @@ -1061,8 +1062,13 @@ void TrkDevice::sendTrkMessage(byte code, TrkCallback callback, const QByteArray &data, const QVariant &cookie) { if (!d->writerThread.isNull()) { - if (d->verbose > 1) - qDebug() << "Sending " << code << data.toHex(); + if (d->verbose > 1) { + QByteArray msg = "Sending: "; + msg += QByteArray::number(code, 16); + msg += ": "; + msg += stringFromArray(data).toLatin1(); + qDebug("%s", msg.data()); + } d->writerThread->queueTrkMessage(code, callback, data, cookie); } } diff --git a/tools/runonphone/trk/trkdevice.h b/tools/runonphone/trk/trkdevice.h index e04f791..21a3cc1 100644 --- a/tools/runonphone/trk/trkdevice.h +++ b/tools/runonphone/trk/trkdevice.h @@ -42,6 +42,7 @@ #ifndef TRKDEVICE_H #define TRKDEVICE_H +#include "symbianutils_global.h" #include "callback.h" #include @@ -74,7 +75,7 @@ enum { TRK_WRITE_QUEUE_NOOP_CODE = 0x7f }; typedef trk::Callback TrkCallback; -class TrkDevice : public QObject +class SYMBIANUTILS_EXPORT TrkDevice : public QObject { Q_OBJECT Q_PROPERTY(bool serialFrame READ serialFrame WRITE setSerialFrame) diff --git a/tools/runonphone/trk/trkutils.cpp b/tools/runonphone/trk/trkutils.cpp index 3a96053..5cce950 100644 --- a/tools/runonphone/trk/trkutils.cpp +++ b/tools/runonphone/trk/trkutils.cpp @@ -86,7 +86,7 @@ void Session::reset() trkAppVersion.reset(); } -QString formatCpu(int major, int minor) +static QString formatCpu(int major, int minor) { //: CPU description of an S60 device //: %1 major verison, %2 minor version @@ -144,13 +144,44 @@ QString Session::deviceDescription(unsigned verbose) const } +QByteArray decode7d(const QByteArray &ba) +{ + QByteArray res; + res.reserve(ba.size()); + for (int i = 0; i < ba.size(); ++i) { + byte c = byte(ba.at(i)); + if (c == 0x7d) { + ++i; + c = 0x20 ^ byte(ba.at(i)); + } + res.append(c); + } + return res; +} + +QByteArray encode7d(const QByteArray &ba) +{ + QByteArray res; + res.reserve(ba.size() + 2); + for (int i = 0; i < ba.size(); ++i) { + byte c = byte(ba.at(i)); + if (c == 0x7e || c == 0x7d) { + res.append(0x7d); + res.append(0x20 ^ c); + } else { + res.append(c); + } + } + return res; +} + // FIXME: Use the QByteArray based version below? -QString stringFromByte(byte c) +static inline QString stringFromByte(byte c) { - return QString("%1 ").arg(c, 2, 16, QChar('0')); + return QString::fromLatin1("%1").arg(c, 2, 16, QChar('0')); } -QString stringFromArray(const QByteArray &ba, int maxLen) +SYMBIANUTILS_EXPORT QString stringFromArray(const QByteArray &ba, int maxLen) { QString str; QString ascii; @@ -170,7 +201,7 @@ QString stringFromArray(const QByteArray &ba, int maxLen) return str + " " + ascii; } -QByteArray hexNumber(uint n, int digits) +SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits) { QByteArray ba = QByteArray::number(n, 16); if (digits == 0 || ba.size() == digits) @@ -178,7 +209,7 @@ QByteArray hexNumber(uint n, int digits) return QByteArray(digits - ba.size(), '0') + ba; } -QByteArray hexxNumber(uint n, int digits) +SYMBIANUTILS_EXPORT QByteArray hexxNumber(uint n, int digits) { return "0x" + hexNumber(n, digits); } @@ -200,9 +231,13 @@ void TrkResult::clear() QString TrkResult::toString() const { - QString res = stringFromByte(code) + "[" + stringFromByte(token); - res.chop(1); - return res + "] " + stringFromArray(data); + QString res = stringFromByte(code); + res += QLatin1String(" ["); + res += stringFromByte(token); + res += QLatin1Char(']'); + res += QLatin1Char(' '); + res += stringFromArray(data); + return res; } QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame) @@ -303,12 +338,12 @@ bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *result, QByt return true; } -ushort extractShort(const char *data) +SYMBIANUTILS_EXPORT ushort extractShort(const char *data) { return byte(data[0]) * 256 + byte(data[1]); } -uint extractInt(const char *data) +SYMBIANUTILS_EXPORT uint extractInt(const char *data) { uint res = byte(data[0]); res *= 256; res += byte(data[1]); @@ -317,7 +352,7 @@ uint extractInt(const char *data) return res; } -QString quoteUnprintableLatin1(const QByteArray &ba) +SYMBIANUTILS_EXPORT QString quoteUnprintableLatin1(const QByteArray &ba) { QString res; char buf[10]; @@ -333,49 +368,7 @@ QString quoteUnprintableLatin1(const QByteArray &ba) return res; } -QByteArray decode7d(const QByteArray &ba) -{ - QByteArray res; - res.reserve(ba.size()); - for (int i = 0; i < ba.size(); ++i) { - byte c = byte(ba.at(i)); - if (c == 0x7d) { - ++i; - c = 0x20 ^ byte(ba.at(i)); - } - res.append(c); - } - //if (res != ba) - // logMessage("DECODED: " << stringFromArray(ba) - // << " -> " << stringFromArray(res)); - return res; -} - -QByteArray encode7d(const QByteArray &ba) -{ - QByteArray res; - res.reserve(ba.size() + 2); - for (int i = 0; i < ba.size(); ++i) { - byte c = byte(ba.at(i)); - if (c == 0x7e || c == 0x7d) { - res.append(0x7d); - res.append(0x20 ^ c); - } else { - res.append(c); - } - } - //if (res != ba) - // logMessage("ENCODED: " << stringFromArray(ba) - // << " -> " << stringFromArray(res)); - return res; -} - -void appendByte(QByteArray *ba, byte b) -{ - ba->append(b); -} - -void appendShort(QByteArray *ba, ushort s, Endianness endian) +SYMBIANUTILS_EXPORT void appendShort(QByteArray *ba, ushort s, Endianness endian) { if (endian == BigEndian) { ba->append(s / 256); @@ -386,7 +379,7 @@ void appendShort(QByteArray *ba, ushort s, Endianness endian) } } -void appendInt(QByteArray *ba, uint i, Endianness endian) +SYMBIANUTILS_EXPORT void appendInt(QByteArray *ba, uint i, Endianness endian) { const uchar b3 = i % 256; i /= 256; const uchar b2 = i % 256; i /= 256; diff --git a/tools/runonphone/trk/trkutils.h b/tools/runonphone/trk/trkutils.h index 328dd2b..3a485c7 100644 --- a/tools/runonphone/trk/trkutils.h +++ b/tools/runonphone/trk/trkutils.h @@ -42,19 +42,20 @@ #ifndef DEBUGGER_TRK_UTILS #define DEBUGGER_TRK_UTILS +#include "symbianutils_global.h" #include #include #include #include -typedef unsigned char byte; - QT_BEGIN_NAMESPACE class QDateTime; QT_END_NAMESPACE namespace trk { +typedef unsigned char byte; + enum Command { TrkPing = 0x00, TrkConnect = 0x01, @@ -85,17 +86,14 @@ enum Command { TrkNotifyProcessorReset = 0xa7 }; -QByteArray decode7d(const QByteArray &ba); -QByteArray encode7d(const QByteArray &ba); - inline byte extractByte(const char *data) { return *data; } -ushort extractShort(const char *data); -uint extractInt(const char *data); +SYMBIANUTILS_EXPORT ushort extractShort(const char *data); +SYMBIANUTILS_EXPORT uint extractInt(const char *data); -QString quoteUnprintableLatin1(const QByteArray &ba); +SYMBIANUTILS_EXPORT QString quoteUnprintableLatin1(const QByteArray &ba); // produces "xx xx xx " -QString stringFromArray(const QByteArray &ba, int maxLen = - 1); +SYMBIANUTILS_EXPORT QString stringFromArray(const QByteArray &ba, int maxLen = - 1); enum Endianness { @@ -104,13 +102,11 @@ enum Endianness TargetByteOrder = BigEndian, }; -void appendByte(QByteArray *ba, byte b); -void appendShort(QByteArray *ba, ushort s, Endianness = TargetByteOrder); -void appendInt(QByteArray *ba, uint i, Endianness = TargetByteOrder); -void appendString(QByteArray *ba, const QByteArray &str, Endianness = TargetByteOrder, bool appendNullTerminator = true); -void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness = TargetByteOrder); +SYMBIANUTILS_EXPORT void appendShort(QByteArray *ba, ushort s, Endianness = TargetByteOrder); +SYMBIANUTILS_EXPORT void appendInt(QByteArray *ba, uint i, Endianness = TargetByteOrder); +SYMBIANUTILS_EXPORT void appendString(QByteArray *ba, const QByteArray &str, Endianness = TargetByteOrder, bool appendNullTerminator = true); -struct Library +struct SYMBIANUTILS_EXPORT Library { Library() {} @@ -119,7 +115,7 @@ struct Library uint dataseg; }; -struct TrkAppVersion +struct SYMBIANUTILS_EXPORT TrkAppVersion { TrkAppVersion(); void reset(); @@ -130,7 +126,7 @@ struct TrkAppVersion int protocolMinor; }; -struct Session +struct SYMBIANUTILS_EXPORT Session { Session(); void reset(); @@ -163,7 +159,7 @@ struct Session QStringList modules; }; -struct TrkResult +struct SYMBIANUTILS_EXPORT TrkResult { TrkResult(); void clear(); @@ -179,15 +175,10 @@ struct TrkResult bool isDebugOutput; }; -// returns a QByteArray containing optionally -// the serial frame [0x01 0x90 ] and 0x7e encoded7d(ba) 0x7e -QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame); -ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame); -bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *r, QByteArray *rawData = 0); -QByteArray errorMessage(byte code); -QByteArray hexNumber(uint n, int digits = 0); -QByteArray hexxNumber(uint n, int digits = 0); // prepends '0x', too -uint swapEndian(uint in); +SYMBIANUTILS_EXPORT QByteArray errorMessage(byte code); +SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits = 0); +SYMBIANUTILS_EXPORT QByteArray hexxNumber(uint n, int digits = 0); // prepends '0x', too +SYMBIANUTILS_EXPORT uint swapEndian(uint in); } // namespace trk diff --git a/tools/runonphone/trk/trkutils_p.h b/tools/runonphone/trk/trkutils_p.h new file mode 100644 index 0000000..12b0109 --- /dev/null +++ b/tools/runonphone/trk/trkutils_p.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DEBUGGER_TRK_PRIVATE_UTILS +#define DEBUGGER_TRK_PRIVATE_UTILS + +#include "trkutils.h" +#include "symbianutils_global.h" + +QT_BEGIN_NAMESPACE +class QDateTime; +QT_END_NAMESPACE + +namespace trk { + +void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness = TargetByteOrder); +// returns a QByteArray containing optionally +// the serial frame [0x01 0x90 ] and 0x7e encoded7d(ba) 0x7e +QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame); +bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *r, QByteArray *rawData = 0); + +} // namespace trk + +#endif // DEBUGGER_TRK_PRIVATE_UTILS -- cgit v0.12 From 9965d0e0484882d905c1f8a3bdf19f6eecd30226 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 9 Feb 2010 11:50:08 +0100 Subject: rename trk -> symbianutils commit 9c2676167a3aaeb99024a22343c3d998f191a75f Author: Friedemann Kleint Date: Fri Feb 5 12:32:32 2010 +0100 src/shared: Rename trk to symbianutils --- tools/runonphone/runonphone.pro | 4 +- .../runonphone/symbianutils/bluetoothlistener.cpp | 224 ++++ tools/runonphone/symbianutils/bluetoothlistener.h | 103 ++ .../symbianutils/bluetoothlistener_gui.cpp | 111 ++ .../symbianutils/bluetoothlistener_gui.h | 89 ++ tools/runonphone/symbianutils/callback.h | 160 +++ .../symbianutils/communicationstarter.cpp | 260 +++++ .../runonphone/symbianutils/communicationstarter.h | 162 +++ tools/runonphone/symbianutils/launcher.cpp | 741 +++++++++++++ tools/runonphone/symbianutils/launcher.h | 179 ++++ tools/runonphone/symbianutils/symbianutils.pri | 25 + .../runonphone/symbianutils/symbianutils_global.h | 55 + tools/runonphone/symbianutils/trkdevice.cpp | 1105 ++++++++++++++++++++ tools/runonphone/symbianutils/trkdevice.h | 134 +++ tools/runonphone/symbianutils/trkutils.cpp | 479 +++++++++ tools/runonphone/symbianutils/trkutils.h | 185 ++++ tools/runonphone/symbianutils/trkutils_p.h | 62 ++ tools/runonphone/trk/bluetoothlistener.cpp | 224 ---- tools/runonphone/trk/bluetoothlistener.h | 103 -- tools/runonphone/trk/bluetoothlistener_gui.cpp | 111 -- tools/runonphone/trk/bluetoothlistener_gui.h | 89 -- tools/runonphone/trk/callback.h | 160 --- tools/runonphone/trk/communicationstarter.cpp | 260 ----- tools/runonphone/trk/communicationstarter.h | 162 --- tools/runonphone/trk/launcher.cpp | 741 ------------- tools/runonphone/trk/launcher.h | 179 ---- tools/runonphone/trk/symbianutils_global.h | 55 - tools/runonphone/trk/trk.pri | 25 - tools/runonphone/trk/trkdevice.cpp | 1105 -------------------- tools/runonphone/trk/trkdevice.h | 134 --- tools/runonphone/trk/trkutils.cpp | 479 --------- tools/runonphone/trk/trkutils.h | 185 ---- tools/runonphone/trk/trkutils_p.h | 62 -- 33 files changed, 4077 insertions(+), 4075 deletions(-) create mode 100644 tools/runonphone/symbianutils/bluetoothlistener.cpp create mode 100644 tools/runonphone/symbianutils/bluetoothlistener.h create mode 100644 tools/runonphone/symbianutils/bluetoothlistener_gui.cpp create mode 100644 tools/runonphone/symbianutils/bluetoothlistener_gui.h create mode 100644 tools/runonphone/symbianutils/callback.h create mode 100644 tools/runonphone/symbianutils/communicationstarter.cpp create mode 100644 tools/runonphone/symbianutils/communicationstarter.h create mode 100644 tools/runonphone/symbianutils/launcher.cpp create mode 100644 tools/runonphone/symbianutils/launcher.h create mode 100644 tools/runonphone/symbianutils/symbianutils.pri create mode 100644 tools/runonphone/symbianutils/symbianutils_global.h create mode 100644 tools/runonphone/symbianutils/trkdevice.cpp create mode 100644 tools/runonphone/symbianutils/trkdevice.h create mode 100644 tools/runonphone/symbianutils/trkutils.cpp create mode 100644 tools/runonphone/symbianutils/trkutils.h create mode 100644 tools/runonphone/symbianutils/trkutils_p.h delete mode 100644 tools/runonphone/trk/bluetoothlistener.cpp delete mode 100644 tools/runonphone/trk/bluetoothlistener.h delete mode 100644 tools/runonphone/trk/bluetoothlistener_gui.cpp delete mode 100644 tools/runonphone/trk/bluetoothlistener_gui.h delete mode 100644 tools/runonphone/trk/callback.h delete mode 100644 tools/runonphone/trk/communicationstarter.cpp delete mode 100644 tools/runonphone/trk/communicationstarter.h delete mode 100644 tools/runonphone/trk/launcher.cpp delete mode 100644 tools/runonphone/trk/launcher.h delete mode 100644 tools/runonphone/trk/symbianutils_global.h delete mode 100644 tools/runonphone/trk/trk.pri delete mode 100644 tools/runonphone/trk/trkdevice.cpp delete mode 100644 tools/runonphone/trk/trkdevice.h delete mode 100644 tools/runonphone/trk/trkutils.cpp delete mode 100644 tools/runonphone/trk/trkutils.h delete mode 100644 tools/runonphone/trk/trkutils_p.h diff --git a/tools/runonphone/runonphone.pro b/tools/runonphone/runonphone.pro index 2c1be98..7bed3e5 100644 --- a/tools/runonphone/runonphone.pro +++ b/tools/runonphone/runonphone.pro @@ -4,7 +4,7 @@ QT -= gui CONFIG += console CONFIG -= app_bundle -include(trk/trk.pri) +include(symbianutils/symbianutils.pri) SOURCES += main.cpp \ trksignalhandler.cpp @@ -12,6 +12,8 @@ SOURCES += main.cpp \ HEADERS += trksignalhandler.h \ serenum.h +DEFINES += SYMBIANUTILS_INCLUDE_PRI + windows { SOURCES += serenum_win.cpp LIBS += -lsetupapi \ diff --git a/tools/runonphone/symbianutils/bluetoothlistener.cpp b/tools/runonphone/symbianutils/bluetoothlistener.cpp new file mode 100644 index 0000000..df04288 --- /dev/null +++ b/tools/runonphone/symbianutils/bluetoothlistener.cpp @@ -0,0 +1,224 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "bluetoothlistener.h" +#include "trkdevice.h" + +#include + +#ifdef Q_OS_UNIX +# include +# include +#else +# include +#endif + +// Process id helpers. +#ifdef Q_OS_WIN +inline DWORD processId(const QProcess &p) +{ + if (const Q_PID processInfoStruct = p.pid()) + return processInfoStruct->dwProcessId; + return 0; +} +#else +inline Q_PID processId(const QProcess &p) +{ + return p.pid(); +} +#endif + + +enum { debug = 0 }; + +namespace trk { + +struct BluetoothListenerPrivate { + BluetoothListenerPrivate(); + QString device; + QProcess process; +#ifdef Q_OS_WIN + DWORD pid; +#else + Q_PID pid; +#endif + bool printConsoleMessages; + BluetoothListener::Mode mode; +}; + +BluetoothListenerPrivate::BluetoothListenerPrivate() : + pid(0), + printConsoleMessages(false), + mode(BluetoothListener::Listen) +{ +} + +BluetoothListener::BluetoothListener(QObject *parent) : + QObject(parent), + d(new BluetoothListenerPrivate) +{ + d->process.setProcessChannelMode(QProcess::MergedChannels); + + connect(&d->process, SIGNAL(readyReadStandardError()), + this, SLOT(slotStdError())); + connect(&d->process, SIGNAL(readyReadStandardOutput()), + this, SLOT(slotStdOutput())); + connect(&d->process, SIGNAL(finished(int, QProcess::ExitStatus)), + this, SLOT(slotProcessFinished(int,QProcess::ExitStatus))); + connect(&d->process, SIGNAL(error(QProcess::ProcessError)), + this, SLOT(slotProcessError(QProcess::ProcessError))); +} + +BluetoothListener::~BluetoothListener() +{ + const int trc = terminateProcess(); + if (debug) + qDebug() << "~BluetoothListener: terminated" << trc; + delete d; +} + +BluetoothListener::Mode BluetoothListener::mode() const +{ + return d->mode; +} + +void BluetoothListener::setMode(Mode m) +{ + d->mode = m; +} + +bool BluetoothListener::printConsoleMessages() const +{ + return d->printConsoleMessages; +} + +void BluetoothListener::setPrintConsoleMessages(bool p) +{ + d->printConsoleMessages = p; +} + +int BluetoothListener::terminateProcess() +{ + enum { TimeOutMS = 200 }; + if (debug) + qDebug() << "terminateProcess" << d->process.pid() << d->process.state(); + if (d->process.state() == QProcess::NotRunning) + return -1; + emitMessage(tr("%1: Stopping listener %2...").arg(d->device).arg(processId(d->process))); + // When listening, the process should terminate by itself after closing the connection + if (mode() == Listen && d->process.waitForFinished(TimeOutMS)) + return 0; +#ifdef Q_OS_UNIX + kill(d->process.pid(), SIGHUP); // Listens for SIGHUP + if (d->process.waitForFinished(TimeOutMS)) + return 1; +#endif + d->process.terminate(); + if (d->process.waitForFinished(TimeOutMS)) + return 2; + d->process.kill(); + return 3; +} + +bool BluetoothListener::start(const QString &device, QString *errorMessage) +{ + if (d->process.state() != QProcess::NotRunning) { + *errorMessage = QLatin1String("Internal error: Still running."); + return false; + } + d->device = device; + const QString binary = QLatin1String("rfcomm"); + QStringList arguments; + arguments << QLatin1String("-r") + << (d->mode == Listen ? QLatin1String("listen") : QLatin1String("watch")) + << device << QString(QLatin1Char('1')); + if (debug) + qDebug() << binary << arguments; + emitMessage(tr("%1: Starting Bluetooth listener %2...").arg(device, binary)); + d->pid = 0; + d->process.start(binary, arguments); + if (!d->process.waitForStarted()) { + *errorMessage = tr("Unable to run '%1': %2").arg(binary, d->process.errorString()); + return false; + } + d->pid = processId(d->process); // Forgets it after crash/termination + emitMessage(tr("%1: Bluetooth listener running (%2).").arg(device).arg(processId(d->process))); + return true; +} + +void BluetoothListener::slotStdOutput() +{ + emitMessage(QString::fromLocal8Bit(d->process.readAllStandardOutput())); +} + +void BluetoothListener::emitMessage(const QString &m) +{ + if (d->printConsoleMessages || debug) + qDebug("%s\n", qPrintable(m)); + emit message(m); +} + +void BluetoothListener::slotStdError() +{ + emitMessage(QString::fromLocal8Bit(d->process.readAllStandardError())); +} + +void BluetoothListener::slotProcessFinished(int ex, QProcess::ExitStatus state) +{ + switch (state) { + case QProcess::NormalExit: + emitMessage(tr("%1: Process %2 terminated with exit code %3.") + .arg(d->device).arg(d->pid).arg(ex)); + break; + case QProcess::CrashExit: + emitMessage(tr("%1: Process %2 crashed.").arg(d->device).arg(d->pid)); + break; + } + emit terminated(); +} + +void BluetoothListener::slotProcessError(QProcess::ProcessError error) +{ + emitMessage(tr("%1: Process error %2: %3") + .arg(d->device).arg(error).arg(d->process.errorString())); +} + +} // namespace trk diff --git a/tools/runonphone/symbianutils/bluetoothlistener.h b/tools/runonphone/symbianutils/bluetoothlistener.h new file mode 100644 index 0000000..36894e7 --- /dev/null +++ b/tools/runonphone/symbianutils/bluetoothlistener.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BLUETOOTHLISTENER_H +#define BLUETOOTHLISTENER_H + +#include "symbianutils_global.h" + +#include +#include + +namespace trk { +struct BluetoothListenerPrivate; + +/* BluetoothListener: Starts a helper process watching connections on a + * Bluetooth device, Linux only: + * The rfcomm command is used. It process can be started in the background + * while connection attempts (TrkDevice::open()) are made in the foreground. */ + +class SYMBIANUTILS_EXPORT BluetoothListener : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(BluetoothListener) +public: + // The Mode property must be set before calling start(). + enum Mode { + Listen, /* Terminate after client closed (read: Trk app + * on the phone terminated or disconnected).*/ + Watch // Keep running, watch for next connection from client + }; + + explicit BluetoothListener(QObject *parent = 0); + virtual ~BluetoothListener(); + + Mode mode() const; + void setMode(Mode m); + + bool start(const QString &device, QString *errorMessage); + + // Print messages on the console. + bool printConsoleMessages() const; + void setPrintConsoleMessages(bool p); + +signals: + void terminated(); + void message(const QString &); + +public slots: + void emitMessage(const QString &m); // accessed by starter + +private slots: + void slotStdOutput(); + void slotStdError(); + void slotProcessFinished(int, QProcess::ExitStatus); + void slotProcessError(QProcess::ProcessError error); + +private: + int terminateProcess(); + + BluetoothListenerPrivate *d; +}; + +} // namespace trk + +#endif // BLUETOOTHLISTENER_H diff --git a/tools/runonphone/symbianutils/bluetoothlistener_gui.cpp b/tools/runonphone/symbianutils/bluetoothlistener_gui.cpp new file mode 100644 index 0000000..5994eb5 --- /dev/null +++ b/tools/runonphone/symbianutils/bluetoothlistener_gui.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "bluetoothlistener_gui.h" +#include "bluetoothlistener.h" +#include "communicationstarter.h" + +#include +#include +#include +#include + +namespace trk { + +SYMBIANUTILS_EXPORT PromptStartCommunicationResult + promptStartCommunication(BaseCommunicationStarter &starter, + const QString &msgBoxTitle, + const QString &msgBoxText, + QWidget *msgBoxParent, + QString *errorMessage) +{ + errorMessage->clear(); + // Initial connection attempt. + switch (starter.start()) { + case BaseCommunicationStarter::Started: + break; + case BaseCommunicationStarter::ConnectionSucceeded: + return PromptStartCommunicationConnected; + case BaseCommunicationStarter::StartError: + *errorMessage = starter.errorString(); + return PromptStartCommunicationError; + } + // Run the starter with the event loop of a message box, have the box + // closed by the signals of the starter. + QMessageBox messageBox(QMessageBox::Information, msgBoxTitle, msgBoxText, QMessageBox::Cancel, msgBoxParent); + QObject::connect(&starter, SIGNAL(connected()), &messageBox, SLOT(close())); + QObject::connect(&starter, SIGNAL(timeout()), &messageBox, SLOT(close())); + messageBox.exec(); + // Only starter.state() is reliable here to obtain the state. + switch (starter.state()) { + case AbstractBluetoothStarter::Running: + *errorMessage = QCoreApplication::translate("trk::promptStartCommunication", "Connection on %1 canceled.").arg(starter.device()); + return PromptStartCommunicationCanceled; + case AbstractBluetoothStarter::TimedOut: + *errorMessage = starter.errorString(); + return PromptStartCommunicationError; + case AbstractBluetoothStarter::Connected: + break; + } + return PromptStartCommunicationConnected; +} + +SYMBIANUTILS_EXPORT PromptStartCommunicationResult + promptStartSerial(BaseCommunicationStarter &starter, + QWidget *msgBoxParent, + QString *errorMessage) +{ + const QString title = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for App TRK"); + const QString message = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for App TRK to start on %1...").arg(starter.device()); + return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage); +} + +SYMBIANUTILS_EXPORT PromptStartCommunicationResult + promptStartBluetooth(BaseCommunicationStarter &starter, + QWidget *msgBoxParent, + QString *errorMessage) +{ + const QString title = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for Bluetooth Connection"); + const QString message = QCoreApplication::translate("trk::promptStartCommunication", "Connecting to %1...").arg(starter.device()); + return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage); +} + +} // namespace trk diff --git a/tools/runonphone/symbianutils/bluetoothlistener_gui.h b/tools/runonphone/symbianutils/bluetoothlistener_gui.h new file mode 100644 index 0000000..10e7145 --- /dev/null +++ b/tools/runonphone/symbianutils/bluetoothlistener_gui.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BLUETOOTHLISTENER_GUI_H +#define BLUETOOTHLISTENER_GUI_H + +#include "symbianutils_global.h" + +#include + +QT_BEGIN_NAMESPACE +class QWidget; +QT_END_NAMESPACE + +namespace trk { +class BaseCommunicationStarter; + +/* promptStartCommunication(): Convenience functions that + * prompt the user to start a communication (launching or + * connecting TRK) using a modal message box in which they can cancel. + * Pass in the starter with device and parameters set up. */ + +enum PromptStartCommunicationResult { + PromptStartCommunicationConnected, + PromptStartCommunicationCanceled, + PromptStartCommunicationError +}; + +SYMBIANUTILS_EXPORT PromptStartCommunicationResult + promptStartCommunication(BaseCommunicationStarter &starter, + const QString &msgBoxTitle, + const QString &msgBoxText, + QWidget *msgBoxParent, + QString *errorMessage); + +// Convenience to start a serial connection (messages prompting +// to launch Trk). +SYMBIANUTILS_EXPORT PromptStartCommunicationResult + promptStartSerial(BaseCommunicationStarter &starter, + QWidget *msgBoxParent, + QString *errorMessage); + +// Convenience to start blue tooth connection (messages +// prompting to connect). +SYMBIANUTILS_EXPORT PromptStartCommunicationResult + promptStartBluetooth(BaseCommunicationStarter &starter, + QWidget *msgBoxParent, + QString *errorMessage); +} // namespace trk + +#endif // BLUETOOTHLISTENER_GUI_H diff --git a/tools/runonphone/symbianutils/callback.h b/tools/runonphone/symbianutils/callback.h new file mode 100644 index 0000000..3996d73 --- /dev/null +++ b/tools/runonphone/symbianutils/callback.h @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DEBUGGER_CALLBACK_H +#define DEBUGGER_CALLBACK_H + +#include "symbianutils_global.h" + +namespace trk { +namespace Internal { + +/* Helper class for the 1-argument functor: + * Cloneable base class for the implementation which is + * invokeable with the argument. */ +template +class CallbackImplBase +{ + Q_DISABLE_COPY(CallbackImplBase) +public: + CallbackImplBase() {} + virtual CallbackImplBase *clone() const = 0; + virtual void invoke(Argument a) = 0; + virtual ~CallbackImplBase() {} +}; + +/* Helper class for the 1-argument functor: Implementation for + * a class instance with a member function pointer. */ +template +class CallbackMemberPtrImpl : public CallbackImplBase +{ +public: + typedef void (Class::*MemberFuncPtr)(Argument); + + CallbackMemberPtrImpl(Class *instance, + MemberFuncPtr memberFunc) : + m_instance(instance), + m_memberFunc(memberFunc) {} + + virtual CallbackImplBase *clone() const + { + return new CallbackMemberPtrImpl(m_instance, m_memberFunc); + } + + virtual void invoke(Argument a) + { (m_instance->*m_memberFunc)(a); } +private: + Class *m_instance; + MemberFuncPtr m_memberFunc; +}; + +} // namespace Internal + +/* Default-constructible, copyable 1-argument functor providing an + * operator()(Argument) that invokes a member function of a class: + * \code +class Foo { +public: + void print(const std::string &); +}; +... +Foo foo; +Callback f1(&foo, &Foo::print); +f1("test"); +\endcode */ + +template +class Callback +{ +public: + Callback() : m_impl(0) {} + + template + Callback(Class *instance, void (Class::*memberFunc)(Argument)) : + m_impl(new Internal::CallbackMemberPtrImpl(instance, memberFunc)) + {} + + ~Callback() + { + clean(); + } + + Callback(const Callback &rhs) : + m_impl(0) + { + if (rhs.m_impl) + m_impl = rhs.m_impl->clone(); + } + + Callback &operator=(const Callback &rhs) + { + if (this != &rhs) { + clean(); + if (rhs.m_impl) + m_impl = rhs.m_impl->clone(); + } + return *this; + } + + bool isNull() const { return m_impl == 0; } + operator bool() const { return !isNull(); } + + void operator()(Argument a) + { + if (m_impl) + m_impl->invoke(a); + } + +private: + void clean() + { + if (m_impl) { + delete m_impl; + m_impl = 0; + } + } + + Internal::CallbackImplBase *m_impl; +}; + +} // namespace trk + +#endif // DEBUGGER_CALLBACK_H diff --git a/tools/runonphone/symbianutils/communicationstarter.cpp b/tools/runonphone/symbianutils/communicationstarter.cpp new file mode 100644 index 0000000..e5e556e --- /dev/null +++ b/tools/runonphone/symbianutils/communicationstarter.cpp @@ -0,0 +1,260 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "communicationstarter.h" +#include "bluetoothlistener.h" +#include "trkdevice.h" + +#include +#include + +namespace trk { + +// --------------- AbstractBluetoothStarter +struct BaseCommunicationStarterPrivate { + explicit BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d); + + const BaseCommunicationStarter::TrkDevicePtr trkDevice; + BluetoothListener *listener; + QTimer *timer; + int intervalMS; + int attempts; + int n; + QString device; + QString errorString; + BaseCommunicationStarter::State state; +}; + +BaseCommunicationStarterPrivate::BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d) : + trkDevice(d), + listener(0), + timer(0), + intervalMS(1000), + attempts(-1), + n(0), + device(QLatin1String("/dev/rfcomm0")), + state(BaseCommunicationStarter::TimedOut) +{ +} + +BaseCommunicationStarter::BaseCommunicationStarter(const TrkDevicePtr &trkDevice, QObject *parent) : + QObject(parent), + d(new BaseCommunicationStarterPrivate(trkDevice)) +{ +} + +BaseCommunicationStarter::~BaseCommunicationStarter() +{ + stopTimer(); + delete d; +} + +void BaseCommunicationStarter::stopTimer() +{ + if (d->timer && d->timer->isActive()) + d->timer->stop(); +} + +bool BaseCommunicationStarter::initializeStartupResources(QString *errorMessage) +{ + errorMessage->clear(); + return true; +} + +BaseCommunicationStarter::StartResult BaseCommunicationStarter::start() +{ + if (state() == Running) { + d->errorString = QLatin1String("Internal error, attempt to re-start BaseCommunicationStarter.\n"); + return StartError; + } + // Before we instantiate timers, and such, try to open the device, + // which should succeed if another listener is already running in + // 'Watch' mode + if (d->trkDevice->open(d->device , &(d->errorString))) + return ConnectionSucceeded; + // Pull up resources for next attempt + d->n = 0; + if (!initializeStartupResources(&(d->errorString))) + return StartError; + // Start timer + if (!d->timer) { + d->timer = new QTimer; + connect(d->timer, SIGNAL(timeout()), this, SLOT(slotTimer())); + } + d->timer->setInterval(d->intervalMS); + d->timer->setSingleShot(false); + d->timer->start(); + d->state = Running; + return Started; +} + +BaseCommunicationStarter::State BaseCommunicationStarter::state() const +{ + return d->state; +} + +int BaseCommunicationStarter::intervalMS() const +{ + return d->intervalMS; +} + +void BaseCommunicationStarter::setIntervalMS(int i) +{ + d->intervalMS = i; + if (d->timer) + d->timer->setInterval(i); +} + +int BaseCommunicationStarter::attempts() const +{ + return d->attempts; +} + +void BaseCommunicationStarter::setAttempts(int a) +{ + d->attempts = a; +} + +QString BaseCommunicationStarter::device() const +{ + return d->device; +} + +void BaseCommunicationStarter::setDevice(const QString &dv) +{ + d->device = dv; +} + +QString BaseCommunicationStarter::errorString() const +{ + return d->errorString; +} + +void BaseCommunicationStarter::slotTimer() +{ + ++d->n; + // Check for timeout + if (d->attempts >= 0 && d->n >= d->attempts) { + stopTimer(); + d->errorString = tr("%1: timed out after %n attempts using an interval of %2ms.", 0, d->n) + .arg(d->device).arg(d->intervalMS); + d->state = TimedOut; + emit timeout(); + } else { + // Attempt n to connect? + if (d->trkDevice->open(d->device , &(d->errorString))) { + stopTimer(); + const QString msg = tr("%1: Connection attempt %2 succeeded.").arg(d->device).arg(d->n); + emit message(msg); + d->state = Connected; + emit connected(); + } else { + const QString msg = tr("%1: Connection attempt %2 failed: %3 (retrying)...") + .arg(d->device).arg(d->n).arg(d->errorString); + emit message(msg); + } + } +} + +// --------------- AbstractBluetoothStarter + +AbstractBluetoothStarter::AbstractBluetoothStarter(const TrkDevicePtr &trkDevice, QObject *parent) : + BaseCommunicationStarter(trkDevice, parent) +{ +} + +bool AbstractBluetoothStarter::initializeStartupResources(QString *errorMessage) +{ + // Create the listener and forward messages to it. + BluetoothListener *listener = createListener(); + connect(this, SIGNAL(message(QString)), listener, SLOT(emitMessage(QString))); + return listener->start(device(), errorMessage); +} + +// -------- ConsoleBluetoothStarter +ConsoleBluetoothStarter::ConsoleBluetoothStarter(const TrkDevicePtr &trkDevice, + QObject *listenerParent, + QObject *parent) : +AbstractBluetoothStarter(trkDevice, parent), +m_listenerParent(listenerParent) +{ +} + +BluetoothListener *ConsoleBluetoothStarter::createListener() +{ + BluetoothListener *rc = new BluetoothListener(m_listenerParent); + rc->setMode(BluetoothListener::Listen); + rc->setPrintConsoleMessages(true); + return rc; +} + +bool ConsoleBluetoothStarter::startBluetooth(const TrkDevicePtr &trkDevice, + QObject *listenerParent, + const QString &device, + int attempts, + QString *errorMessage) +{ + // Set up a console starter to print to stdout. + ConsoleBluetoothStarter starter(trkDevice, listenerParent); + starter.setDevice(device); + starter.setAttempts(attempts); + switch (starter.start()) { + case Started: + break; + case ConnectionSucceeded: + return true; + case StartError: + *errorMessage = starter.errorString(); + return false; + } + // Run the starter with an event loop. @ToDo: Implement + // some asynchronous keypress read to cancel. + QEventLoop eventLoop; + connect(&starter, SIGNAL(connected()), &eventLoop, SLOT(quit())); + connect(&starter, SIGNAL(timeout()), &eventLoop, SLOT(quit())); + eventLoop.exec(QEventLoop::ExcludeUserInputEvents); + if (starter.state() != AbstractBluetoothStarter::Connected) { + *errorMessage = starter.errorString(); + return false; + } + return true; +} +} // namespace trk diff --git a/tools/runonphone/symbianutils/communicationstarter.h b/tools/runonphone/symbianutils/communicationstarter.h new file mode 100644 index 0000000..2d7dc50 --- /dev/null +++ b/tools/runonphone/symbianutils/communicationstarter.h @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef COMMUNICATIONSTARTER_H +#define COMMUNICATIONSTARTER_H + +#include "symbianutils_global.h" + +#include +#include + +namespace trk { +class TrkDevice; +class BluetoothListener; +struct BaseCommunicationStarterPrivate; + +/* BaseCommunicationStarter: A QObject that repeatedly tries to open a + * trk device until a connection succeeds or a timeout occurs (emitting + * signals), allowing to do something else in the foreground (local event loop + * [say QMessageBox] or some asynchronous operation). If the initial + * connection attempt in start() fails, the + * virtual initializeStartupResources() is called to initialize resources + * required to pull up the communication (namely Bluetooth listeners). + * The base class can be used as is to prompt the user to launch App TRK for a + * serial communication as this requires no further resource setup. */ + +class SYMBIANUTILS_EXPORT BaseCommunicationStarter : public QObject { + Q_OBJECT + Q_DISABLE_COPY(BaseCommunicationStarter) +public: + typedef QSharedPointer TrkDevicePtr; + + enum State { Running, Connected, TimedOut }; + + explicit BaseCommunicationStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); + virtual ~BaseCommunicationStarter(); + + int intervalMS() const; + void setIntervalMS(int i); + + int attempts() const; + void setAttempts(int a); + + QString device() const; + void setDevice(const QString &); + + State state() const; + QString errorString() const; + + enum StartResult { + Started, // Starter is now running. + ConnectionSucceeded, /* Initial connection attempt succeeded, + * no need to keep running. */ + StartError // Error occurred during start. + }; + + StartResult start(); + +signals: + void connected(); + void timeout(); + void message(const QString &); + +private slots: + void slotTimer(); + +protected: + virtual bool initializeStartupResources(QString *errorMessage); + +private: + inline void stopTimer(); + + BaseCommunicationStarterPrivate *d; +}; + +/* AbstractBluetoothStarter: Repeatedly tries to open a trk Bluetooth + * device. Note that in case a Listener is already running mode, the + * connection will succeed immediately. + * initializeStartupResources() is implemented to fire up the listener. + * Introduces a new virtual createListener() that derived classes must + * implement as a factory function that creates and sets up the + * listener (mode, message connection, etc). */ + +class SYMBIANUTILS_EXPORT AbstractBluetoothStarter : public BaseCommunicationStarter { + Q_OBJECT + Q_DISABLE_COPY(AbstractBluetoothStarter) +public: + +protected: + explicit AbstractBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); + + // Implemented to fire up the listener. + virtual bool initializeStartupResources(QString *errorMessage); + // New virtual: Overwrite to create and parametrize the listener. + virtual BluetoothListener *createListener() = 0; +}; + +/* ConsoleBluetoothStarter: Convenience class for console processes. Creates a + * listener in "Listen" mode with the messages redirected to standard output. */ + +class SYMBIANUTILS_EXPORT ConsoleBluetoothStarter : public AbstractBluetoothStarter { + Q_OBJECT + Q_DISABLE_COPY(ConsoleBluetoothStarter) +public: + static bool startBluetooth(const TrkDevicePtr& trkDevice, + QObject *listenerParent, + const QString &device, + int attempts, + QString *errorMessage); + +protected: + virtual BluetoothListener *createListener(); + +private: + explicit ConsoleBluetoothStarter(const TrkDevicePtr& trkDevice, + QObject *listenerParent, + QObject *parent = 0); + + QObject *m_listenerParent; +}; + +} // namespace trk + +#endif // COMMUNICATIONSTARTER_H diff --git a/tools/runonphone/symbianutils/launcher.cpp b/tools/runonphone/symbianutils/launcher.cpp new file mode 100644 index 0000000..4f91545 --- /dev/null +++ b/tools/runonphone/symbianutils/launcher.cpp @@ -0,0 +1,741 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "launcher.h" +#include "trkutils.h" +#include "trkutils_p.h" +#include "trkdevice.h" +#include "bluetoothlistener.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace trk { + +struct LauncherPrivate { + struct CopyState { + QString sourceFileName; + QString destinationFileName; + uint copyFileHandle; + QScopedPointer data; + int position; + }; + + explicit LauncherPrivate(const TrkDevicePtr &d); + + TrkDevicePtr m_device; + QString m_trkServerName; + QByteArray m_trkReadBuffer; + Launcher::State m_state; + + void logMessage(const QString &msg); + // Debuggee state + Session m_session; // global-ish data (process id, target information) + + CopyState m_copyState; + QString m_fileName; + QStringList m_commandLineArgs; + QString m_installFileName; + int m_verbose; + Launcher::Actions m_startupActions; + bool m_closeDevice; +}; + +LauncherPrivate::LauncherPrivate(const TrkDevicePtr &d) : + m_device(d), + m_state(Launcher::Disconnected), + m_verbose(0), + m_closeDevice(true) +{ + if (m_device.isNull()) + m_device = TrkDevicePtr(new TrkDevice); +} + +Launcher::Launcher(Actions startupActions, + const TrkDevicePtr &dev, + QObject *parent) : + QObject(parent), + d(new LauncherPrivate(dev)) +{ + d->m_startupActions = startupActions; + connect(d->m_device.data(), SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleResult(trk::TrkResult))); + connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close())); +} + +Launcher::~Launcher() +{ + logMessage("Shutting down.\n"); + delete d; +} + +Launcher::State Launcher::state() const +{ + return d->m_state; +} + +void Launcher::setState(State s) +{ + if (s != d->m_state) { + d->m_state = s; + emit stateChanged(s); + } +} + +void Launcher::addStartupActions(trk::Launcher::Actions startupActions) +{ + d->m_startupActions = Actions(d->m_startupActions | startupActions); +} + +void Launcher::setTrkServerName(const QString &name) +{ + d->m_trkServerName = name; +} + +QString Launcher::trkServerName() const +{ + return d->m_trkServerName; +} + +TrkDevicePtr Launcher::trkDevice() const +{ + return d->m_device; +} + +void Launcher::setFileName(const QString &name) +{ + d->m_fileName = name; +} + +void Launcher::setCopyFileName(const QString &srcName, const QString &dstName) +{ + d->m_copyState.sourceFileName = srcName; + d->m_copyState.destinationFileName = dstName; +} + +void Launcher::setInstallFileName(const QString &name) +{ + d->m_installFileName = name; +} + +void Launcher::setCommandLineArgs(const QStringList &args) +{ + d->m_commandLineArgs = args; +} + +void Launcher::setSerialFrame(bool b) +{ + d->m_device->setSerialFrame(b); +} + +bool Launcher::serialFrame() const +{ + return d->m_device->serialFrame(); +} + + +bool Launcher::closeDevice() const +{ + return d->m_closeDevice; +} + +void Launcher::setCloseDevice(bool c) +{ + d->m_closeDevice = c; +} + +bool Launcher::startServer(QString *errorMessage) +{ + errorMessage->clear(); + if (d->m_verbose) { + const QString msg = QString::fromLatin1("Port=%1 Executable=%2 Arguments=%3 Package=%4 Remote Package=%5 Install file=%6") + .arg(d->m_trkServerName, d->m_fileName, + d->m_commandLineArgs.join(QString(QLatin1Char(' '))), + d->m_copyState.sourceFileName, d->m_copyState.destinationFileName, d->m_installFileName); + logMessage(msg); + } + if (d->m_startupActions & ActionCopy) { + if (d->m_copyState.sourceFileName.isEmpty()) { + qWarning("No local filename given for copying package."); + return false; + } else if (d->m_copyState.destinationFileName.isEmpty()) { + qWarning("No remote filename given for copying package."); + return false; + } + } + if (d->m_startupActions & ActionInstall && d->m_installFileName.isEmpty()) { + qWarning("No package name given for installing."); + return false; + } + if (d->m_startupActions & ActionRun && d->m_fileName.isEmpty()) { + qWarning("No remote executable given for running."); + return false; + } + if (!d->m_device->isOpen() && !d->m_device->open(d->m_trkServerName, errorMessage)) + return false; + if (d->m_closeDevice) { + connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close())); + } else { + disconnect(this, SIGNAL(finished()), d->m_device.data(), 0); + } + setState(Connecting); + // Set up the temporary 'waiting' state if we do not get immediate connection + QTimer::singleShot(1000, this, SLOT(slotWaitingForTrk())); + d->m_device->sendTrkInitialPing(); + d->m_device->sendTrkMessage(TrkDisconnect); // Disconnect, as trk might be still connected + d->m_device->sendTrkMessage(TrkSupported, TrkCallback(this, &Launcher::handleSupportMask)); + d->m_device->sendTrkMessage(TrkCpuType, TrkCallback(this, &Launcher::handleCpuType)); + d->m_device->sendTrkMessage(TrkVersions, TrkCallback(this, &Launcher::handleTrkVersion)); + if (d->m_startupActions != ActionPingOnly) + d->m_device->sendTrkMessage(TrkConnect, TrkCallback(this, &Launcher::handleConnect)); + return true; +} + +void Launcher::slotWaitingForTrk() +{ + // Set temporary state if we are still in connected state + if (state() == Connecting) + setState(WaitingForTrk); +} + +void Launcher::handleConnect(const TrkResult &result) +{ + if (result.errorCode()) { + emit canNotConnect(result.errorString()); + return; + } + setState(Connected); + if (d->m_startupActions & ActionCopy) + copyFileToRemote(); + else if (d->m_startupActions & ActionInstall) + installRemotePackageSilently(); + else if (d->m_startupActions & ActionRun) + startInferiorIfNeeded(); +} + +void Launcher::setVerbose(int v) +{ + d->m_verbose = v; + d->m_device->setVerbose(v); +} + +void Launcher::logMessage(const QString &msg) +{ + if (d->m_verbose) + qDebug() << "LAUNCHER: " << qPrintable(msg); +} + +void Launcher::terminate() +{ + switch (state()) { + case DeviceDescriptionReceived: + case Connected: + if (d->m_session.pid) { + QByteArray ba; + appendShort(&ba, 0x0000, TargetByteOrder); + appendInt(&ba, d->m_session.pid, TargetByteOrder); + d->m_device->sendTrkMessage(TrkDeleteItem, TrkCallback(this, &Launcher::handleRemoteProcessKilled), ba); + return; + } + if (d->m_copyState.copyFileHandle) + closeRemoteFile(true); + disconnectTrk(); + break; + case Disconnected: + break; + case Connecting: + case WaitingForTrk: + setState(Disconnected); + emit finished(); + break; + } +} + +void Launcher::handleRemoteProcessKilled(const TrkResult &result) +{ + Q_UNUSED(result) + disconnectTrk(); +} + +QString Launcher::msgStopped(uint pid, uint tid, uint address, const QString &why) +{ + return QString::fromLatin1("Process %1, thread %2 stopped at 0x%3: %4"). + arg(pid).arg(tid).arg(address, 0, 16). + arg(why.isEmpty() ? QString::fromLatin1("") : why); +} + +bool Launcher::parseNotifyStopped(const QByteArray &dataBA, + uint *pid, uint *tid, uint *address, + QString *why /* = 0 */) +{ + if (why) + why->clear(); + *address = *pid = *tid = 0; + if (dataBA.size() < 12) + return false; + const char *data = dataBA.data(); + *address = extractInt(data); + *pid = extractInt(data + 4); + *tid = extractInt(data + 8); + if (why && dataBA.size() >= 14) { + const unsigned short len = extractShort(data + 12); + if (len > 0) + *why = QString::fromLatin1(data + 14, len); + } + return true; +} + +void Launcher::handleResult(const TrkResult &result) +{ + QByteArray prefix = "READ BUF: "; + QByteArray str = result.toString().toUtf8(); + if (result.isDebugOutput) { // handle application output + logMessage("APPLICATION OUTPUT: " + result.data); + emit applicationOutputReceived(result.data); + return; + } + switch (result.code) { + case TrkNotifyAck: + break; + case TrkNotifyNak: { // NAK + logMessage(prefix + "NAK: " + str); + //logMessage(prefix << "TOKEN: " << result.token); + logMessage(prefix + "ERROR: " + errorMessage(result.data.at(0))); + break; + } + case TrkNotifyStopped: { // Notified Stopped + QString reason; + uint pc; + uint pid; + uint tid; + parseNotifyStopped(result.data, &pid, &tid, &pc, &reason); + logMessage(prefix + msgStopped(pid, tid, pc, reason)); + emit(processStopped(pc, pid, tid, reason)); + d->m_device->sendTrkAck(result.token); + break; + } + case TrkNotifyException: { // Notify Exception (obsolete) + logMessage(prefix + "NOTE: EXCEPTION " + str); + d->m_device->sendTrkAck(result.token); + break; + } + case TrkNotifyInternalError: { // + logMessage(prefix + "NOTE: INTERNAL ERROR: " + str); + d->m_device->sendTrkAck(result.token); + break; + } + + // target->host OS notification + case TrkNotifyCreated: { // Notify Created + /* + const char *data = result.data.data(); + byte error = result.data.at(0); + byte type = result.data.at(1); // type: 1 byte; for dll item, this value is 2. + uint pid = extractInt(data + 2); // ProcessID: 4 bytes; + uint tid = extractInt(data + 6); //threadID: 4 bytes + uint codeseg = extractInt(data + 10); //code address: 4 bytes; code base address for the library + uint dataseg = extractInt(data + 14); //data address: 4 bytes; data base address for the library + uint len = extractShort(data + 18); //length: 2 bytes; length of the library name string to follow + QByteArray name = result.data.mid(20, len); // name: library name + + logMessage(prefix + "NOTE: LIBRARY LOAD: " + str); + logMessage(prefix + "TOKEN: " + result.token); + logMessage(prefix + "ERROR: " + int(error)); + logMessage(prefix + "TYPE: " + int(type)); + logMessage(prefix + "PID: " + pid); + logMessage(prefix + "TID: " + tid); + logMessage(prefix + "CODE: " + codeseg); + logMessage(prefix + "DATA: " + dataseg); + logMessage(prefix + "LEN: " + len); + logMessage(prefix + "NAME: " + name); + */ + + if (result.data.size() < 10) + break; + QByteArray ba; + ba.append(result.data.mid(2, 8)); + d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); + //d->m_device->sendTrkAck(result.token) + break; + } + case TrkNotifyDeleted: { // NotifyDeleted + const ushort itemType = (unsigned char)result.data.at(1); + const ushort len = result.data.size() > 12 ? extractShort(result.data.data() + 10) : ushort(0); + const QString name = len ? QString::fromAscii(result.data.mid(12, len)) : QString(); + logMessage(QString::fromLatin1("%1 %2 UNLOAD: %3"). + arg(QString::fromAscii(prefix)).arg(itemType ? QLatin1String("LIB") : QLatin1String("PROCESS")). + arg(name)); + d->m_device->sendTrkAck(result.token); + if (itemType == 0 // process + && result.data.size() >= 10 + && d->m_session.pid == extractInt(result.data.data() + 6)) { + disconnectTrk(); + } + break; + } + case TrkNotifyProcessorStarted: { // NotifyProcessorStarted + logMessage(prefix + "NOTE: PROCESSOR STARTED: " + str); + d->m_device->sendTrkAck(result.token); + break; + } + case TrkNotifyProcessorStandBy: { // NotifyProcessorStandby + logMessage(prefix + "NOTE: PROCESSOR STANDBY: " + str); + d->m_device->sendTrkAck(result.token); + break; + } + case TrkNotifyProcessorReset: { // NotifyProcessorReset + logMessage(prefix + "NOTE: PROCESSOR RESET: " + str); + d->m_device->sendTrkAck(result.token); + break; + } + default: { + logMessage(prefix + "INVALID: " + str); + break; + } + } +} + +QString Launcher::deviceDescription(unsigned verbose) const +{ + return d->m_session.deviceDescription(verbose); +} + +void Launcher::handleTrkVersion(const TrkResult &result) +{ + if (result.errorCode() || result.data.size() < 5) { + if (d->m_startupActions == ActionPingOnly) { + setState(Disconnected); + emit finished(); + } + return; + } + d->m_session.trkAppVersion.trkMajor = result.data.at(1); + d->m_session.trkAppVersion.trkMinor = result.data.at(2); + d->m_session.trkAppVersion.protocolMajor = result.data.at(3); + d->m_session.trkAppVersion.protocolMinor = result.data.at(4); + setState(DeviceDescriptionReceived); + // Ping mode: Log & Terminate + if (d->m_startupActions == ActionPingOnly) { + qWarning("%s", qPrintable(deviceDescription())); + setState(Disconnected); + emit finished(); + } +} + +void Launcher::handleFileCreation(const TrkResult &result) +{ + if (result.errorCode() || result.data.size() < 6) { + emit canNotCreateFile(d->m_copyState.destinationFileName, result.errorString()); + disconnectTrk(); + return; + } + const char *data = result.data.data(); + d->m_copyState.copyFileHandle = extractInt(data + 2); + QFile file(d->m_copyState.sourceFileName); + file.open(QIODevice::ReadOnly); + d->m_copyState.data.reset(new QByteArray(file.readAll())); + d->m_copyState.position = 0; + file.close(); + continueCopying(); +} + +void Launcher::handleCopy(const TrkResult &result) +{ + if (result.errorCode() || result.data.size() < 4) { + closeRemoteFile(true); + emit canNotWriteFile(d->m_copyState.destinationFileName, result.errorString()); + disconnectTrk(); + } else { + continueCopying(extractShort(result.data.data() + 2)); + } +} + +void Launcher::continueCopying(uint lastCopiedBlockSize) +{ + int size = d->m_copyState.data->length(); + d->m_copyState.position += lastCopiedBlockSize; + if (size == 0) + emit copyProgress(100); + else { + int percent = qMin((d->m_copyState.position*100)/size, 100); + emit copyProgress(percent); + } + if (d->m_copyState.position < size) { + QByteArray ba; + appendInt(&ba, d->m_copyState.copyFileHandle, TargetByteOrder); + appendString(&ba, d->m_copyState.data->mid(d->m_copyState.position, 2048), TargetByteOrder, false); + d->m_device->sendTrkMessage(TrkWriteFile, TrkCallback(this, &Launcher::handleCopy), ba); + } else { + closeRemoteFile(); + } +} + +void Launcher::closeRemoteFile(bool failed) +{ + QByteArray ba; + appendInt(&ba, d->m_copyState.copyFileHandle, TargetByteOrder); + appendDateTime(&ba, QDateTime::currentDateTime(), TargetByteOrder); + d->m_device->sendTrkMessage(TrkCloseFile, + failed ? TrkCallback() : TrkCallback(this, &Launcher::handleFileCopied), + ba); + d->m_copyState.data.reset(); + d->m_copyState.copyFileHandle = 0; + d->m_copyState.position = 0; +} + +void Launcher::handleFileCopied(const TrkResult &result) +{ + if (result.errorCode()) + emit canNotCloseFile(d->m_copyState.destinationFileName, result.errorString()); + if (d->m_startupActions & ActionInstall) + installRemotePackageSilently(); + else if (d->m_startupActions & ActionRun) + startInferiorIfNeeded(); + else + disconnectTrk(); +} + +void Launcher::handleCpuType(const TrkResult &result) +{ + logMessage("HANDLE CPU TYPE: " + result.toString()); + if(result.errorCode() || result.data.size() < 7) + return; + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 03 00 04 00 00 04 00 00 00] + d->m_session.cpuMajor = result.data.at(1); + d->m_session.cpuMinor = result.data.at(2); + d->m_session.bigEndian = result.data.at(3); + d->m_session.defaultTypeSize = result.data.at(4); + d->m_session.fpTypeSize = result.data.at(5); + d->m_session.extended1TypeSize = result.data.at(6); + //d->m_session.extended2TypeSize = result.data[6]; +} + +void Launcher::handleCreateProcess(const TrkResult &result) +{ + if (result.errorCode()) { + emit canNotRun(result.errorString()); + disconnectTrk(); + return; + } + // 40 00 00] + //logMessage(" RESULT: " + result.toString()); + // [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 40 00 00] + const char *data = result.data.data(); + d->m_session.pid = extractInt(data + 1); + d->m_session.tid = extractInt(data + 5); + d->m_session.codeseg = extractInt(data + 9); + d->m_session.dataseg = extractInt(data + 13); + if (d->m_verbose) { + const QString msg = QString::fromLatin1("Process id: %1 Thread id: %2 code: 0x%3 data: 0x%4"). + arg(d->m_session.pid).arg(d->m_session.tid).arg(d->m_session.codeseg, 0, 16). + arg(d->m_session.dataseg, 0 ,16); + logMessage(msg); + } + emit applicationRunning(d->m_session.pid); + QByteArray ba; + appendInt(&ba, d->m_session.pid); + appendInt(&ba, d->m_session.tid); + d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); +} + +void Launcher::handleWaitForFinished(const TrkResult &result) +{ + logMessage(" FINISHED: " + stringFromArray(result.data)); + setState(Disconnected); + emit finished(); +} + +void Launcher::handleSupportMask(const TrkResult &result) +{ + if (result.errorCode() || result.data.size() < 32) + return; + const char *data = result.data.data() + 1; + + QString str = QLatin1String("SUPPORTED: "); + for (int i = 0; i < 32; ++i) { + //str.append(" [" + formatByte(data[i]) + "]: "); + for (int j = 0; j < 8; ++j) { + if (data[i] & (1 << j)) { + str.append(QString::number(i * 8 + j, 16)); + str.append(QLatin1Char(' ')); + } + } + } + logMessage(str); +} + +void Launcher::cleanUp() +{ + // + //---IDE------------------------------------------------------ + // Command: 0x41 Delete Item + // Sub Cmd: Delete Process + //ProcessID: 0x0000071F (1823) + // [41 24 00 00 00 00 07 1F] + QByteArray ba(2, char(0)); + appendInt(&ba, d->m_session.pid); + d->m_device->sendTrkMessage(TrkDeleteItem, TrkCallback(), ba, "Delete process"); + + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 24 00] + + //---IDE------------------------------------------------------ + // Command: 0x1C Clear Break + // [1C 25 00 00 00 0A 78 6A 43 40] + + //---TRK------------------------------------------------------ + // Command: 0xA1 Notify Deleted + // [A1 09 00 00 00 00 00 00 00 00 07 1F] + //---IDE------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 09 00] + + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 25 00] + + //---IDE------------------------------------------------------ + // Command: 0x1C Clear Break + // [1C 26 00 00 00 0B 78 6A 43 70] + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 26 00] + + + //---IDE------------------------------------------------------ + // Command: 0x02 Disconnect + // [02 27] +// sendTrkMessage(0x02, TrkCallback(this, &Launcher::handleDisconnect)); + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 +} + +void Launcher::disconnectTrk() +{ + d->m_device->sendTrkMessage(TrkDisconnect, TrkCallback(this, &Launcher::handleWaitForFinished)); +} + +void Launcher::copyFileToRemote() +{ + emit copyingStarted(); + QByteArray ba; + ba.append(char(10)); + appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false); + d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba); +} + +void Launcher::installRemotePackageSilently() +{ + emit installingStarted(); + QByteArray ba; + ba.append('C'); + appendString(&ba, d->m_installFileName.toLocal8Bit(), TargetByteOrder, false); + d->m_device->sendTrkMessage(TrkInstallFile, TrkCallback(this, &Launcher::handleInstallPackageFinished), ba); +} + +void Launcher::handleInstallPackageFinished(const TrkResult &result) +{ + if (result.errorCode()) { + emit canNotInstall(d->m_installFileName, result.errorString()); + disconnectTrk(); + return; + } else { + emit installingFinished(); + } + if (d->m_startupActions & ActionRun) { + startInferiorIfNeeded(); + } else { + disconnectTrk(); + } +} + +QByteArray Launcher::startProcessMessage(const QString &executable, + const QStringList &arguments) +{ + // It's not started yet + QByteArray ba; + appendShort(&ba, 0, TargetByteOrder); // create new process + ba.append(char(0)); // options - currently unused + if(arguments.isEmpty()) { + appendString(&ba, executable.toLocal8Bit(), TargetByteOrder); + return ba; + } + // Append full command line as one string (leading length information). + QByteArray commandLineBa; + commandLineBa.append(executable.toLocal8Bit()); + commandLineBa.append('\0'); + commandLineBa.append(arguments.join(QString(QLatin1Char(' '))).toLocal8Bit()); + appendString(&ba, commandLineBa, TargetByteOrder); + return ba; +} + +void Launcher::startInferiorIfNeeded() +{ + emit startingApplication(); + if (d->m_session.pid != 0) { + logMessage("Process already 'started'"); + return; + } + d->m_device->sendTrkMessage(TrkCreateItem, TrkCallback(this, &Launcher::handleCreateProcess), + startProcessMessage(d->m_fileName, d->m_commandLineArgs)); // Create Item +} + +void Launcher::resumeProcess(uint pid, uint tid) +{ + QByteArray ba; + appendInt(&ba, pid, BigEndian); + appendInt(&ba, tid, BigEndian); + d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); +} +} // namespace trk diff --git a/tools/runonphone/symbianutils/launcher.h b/tools/runonphone/symbianutils/launcher.h new file mode 100644 index 0000000..2b23fd8 --- /dev/null +++ b/tools/runonphone/symbianutils/launcher.h @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef LAUNCHER_H +#define LAUNCHER_H + +#include "trkdevice.h" + +#include +#include +#include + +namespace trk { + +struct TrkResult; +struct TrkMessage; +struct LauncherPrivate; + +typedef QSharedPointer TrkDevicePtr; + +class SYMBIANUTILS_EXPORT Launcher : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(Launcher) +public: + typedef void (Launcher::*TrkCallBack)(const TrkResult &); + + enum Actions { + ActionPingOnly = 0x0, + ActionCopy = 0x1, + ActionInstall = 0x2, + ActionCopyInstall = ActionCopy | ActionInstall, + ActionRun = 0x4, + ActionCopyRun = ActionCopy | ActionRun, + ActionInstallRun = ActionInstall | ActionRun, + ActionCopyInstallRun = ActionCopy | ActionInstall | ActionRun + }; + + enum State { Disconnected, Connecting, Connected, + WaitingForTrk, // This occurs only if the initial ping times out after + // a reasonable timeout, indicating that Trk is not + // running. Note that this will never happen with + // Bluetooth as communication immediately starts + // after connecting. + DeviceDescriptionReceived }; + + explicit Launcher(trk::Launcher::Actions startupActions = trk::Launcher::ActionPingOnly, + const TrkDevicePtr &trkDevice = TrkDevicePtr(), + QObject *parent = 0); + ~Launcher(); + + State state() const; + + void addStartupActions(trk::Launcher::Actions startupActions); + void setTrkServerName(const QString &name); + QString trkServerName() const; + void setFileName(const QString &name); + void setCopyFileName(const QString &srcName, const QString &dstName); + void setInstallFileName(const QString &name); + void setCommandLineArgs(const QStringList &args); + bool startServer(QString *errorMessage); + void setVerbose(int v); + void setSerialFrame(bool b); + bool serialFrame() const; + // Close device or leave it open + bool closeDevice() const; + void setCloseDevice(bool c); + + TrkDevicePtr trkDevice() const; + + // becomes valid after successful execution of ActionPingOnly + QString deviceDescription(unsigned verbose = 0u) const; + + static QByteArray startProcessMessage(const QString &executable, + const QStringList &arguments); + // Parse a TrkNotifyStopped message + static bool parseNotifyStopped(const QByteArray &a, + uint *pid, uint *tid, uint *address, + QString *why = 0); + // Helper message + static QString msgStopped(uint pid, uint tid, uint address, const QString &why); + +signals: + void copyingStarted(); + void canNotConnect(const QString &errorMessage); + void canNotCreateFile(const QString &filename, const QString &errorMessage); + void canNotWriteFile(const QString &filename, const QString &errorMessage); + void canNotCloseFile(const QString &filename, const QString &errorMessage); + void installingStarted(); + void canNotInstall(const QString &packageFilename, const QString &errorMessage); + void installingFinished(); + void startingApplication(); + void applicationRunning(uint pid); + void canNotRun(const QString &errorMessage); + void finished(); + void applicationOutputReceived(const QString &output); + void copyProgress(int percent); + void stateChanged(int); + void processStopped(uint pc, uint pid, uint tid, const QString& reason); + +public slots: + void terminate(); + void resumeProcess(uint pid, uint tid); + +private slots: + void handleResult(const trk::TrkResult &data); + void slotWaitingForTrk(); + +private: + // kill process and breakpoints + void cleanUp(); + void disconnectTrk(); + + void handleRemoteProcessKilled(const TrkResult &result); + void handleConnect(const TrkResult &result); + void handleFileCreation(const TrkResult &result); + void handleCopy(const TrkResult &result); + void continueCopying(uint lastCopiedBlockSize = 0); + void closeRemoteFile(bool failed = false); + void handleFileCopied(const TrkResult &result); + void handleInstallPackageFinished(const TrkResult &result); + void handleCpuType(const TrkResult &result); + void handleCreateProcess(const TrkResult &result); + void handleWaitForFinished(const TrkResult &result); + void handleStop(const TrkResult &result); + void handleSupportMask(const TrkResult &result); + void handleTrkVersion(const TrkResult &result); + + void copyFileToRemote(); + void installRemotePackageSilently(); + void startInferiorIfNeeded(); + + void logMessage(const QString &msg); + void setState(State s); + + LauncherPrivate *d; +}; + +} // namespace Trk + +#endif // LAUNCHER_H diff --git a/tools/runonphone/symbianutils/symbianutils.pri b/tools/runonphone/symbianutils/symbianutils.pri new file mode 100644 index 0000000..a54df76 --- /dev/null +++ b/tools/runonphone/symbianutils/symbianutils.pri @@ -0,0 +1,25 @@ +INCLUDEPATH *= $$PWD + +# Input +HEADERS += $$PWD/symbianutils_global.h \ + $$PWD/callback.h \ + $$PWD/trkutils.h \ + $$PWD/trkutils_p.h \ + $$PWD/trkdevice.h \ + $$PWD/launcher.h \ + $$PWD/bluetoothlistener.h \ + $$PWD/communicationstarter.h + +SOURCES += $$PWD/trkutils.cpp \ + $$PWD/trkdevice.cpp \ + $$PWD/launcher.cpp \ + $$PWD/bluetoothlistener.cpp \ + $$PWD/communicationstarter.cpp + +# Tests/trklauncher is a console application +contains(QT, gui) { + HEADERS += $$PWD/bluetoothlistener_gui.h + SOURCES += $$PWD/bluetoothlistener_gui.cpp +} else { + message(Trk: Console ...) +} diff --git a/tools/runonphone/symbianutils/symbianutils_global.h b/tools/runonphone/symbianutils/symbianutils_global.h new file mode 100644 index 0000000..a6ffbe7 --- /dev/null +++ b/tools/runonphone/symbianutils/symbianutils_global.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIANUTILS_GLOBAL_H +#define SYMBIANUTILS_GLOBAL_H + +#include + +#if defined(SYMBIANUTILS_BUILD_LIB) +# define SYMBIANUTILS_EXPORT Q_DECL_EXPORT +#elif defined(SYMBIANUTILS_BUILD_STATIC_LIB) || defined(SYMBIANUTILS_INCLUDE_PRI) +# define SYMBIANUTILS_EXPORT +#else +# define SYMBIANUTILS_EXPORT Q_DECL_IMPORT +#endif + +#endif // SYMBIANUTILS_GLOBAL_H diff --git a/tools/runonphone/symbianutils/trkdevice.cpp b/tools/runonphone/symbianutils/trkdevice.cpp new file mode 100644 index 0000000..d587135 --- /dev/null +++ b/tools/runonphone/symbianutils/trkdevice.cpp @@ -0,0 +1,1105 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "trkdevice.h" +#include "trkutils.h" +#include "trkutils_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_OS_WIN +# include +#else +# include + +# include +# include +# include +# include +# include +# include +# include +/* Required headers for select() according to POSIX.1-2001 */ +# include +/* Required headers for select() according to earlier standards: + #include + #include + #include +*/ +#endif + +#ifdef Q_OS_WIN + +// Format windows error from GetLastError() value: +// TODO: Use the one provided by the utils lib. +QString winErrorMessage(unsigned long error) +{ + QString rc = QString::fromLatin1("#%1: ").arg(error); + ushort *lpMsgBuf; + + const int len = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, error, 0, (LPTSTR)&lpMsgBuf, 0, NULL); + if (len) { + rc = QString::fromUtf16(lpMsgBuf, len); + LocalFree(lpMsgBuf); + } else { + rc += QString::fromLatin1(""); + } + return rc; +} + +#endif + +enum { verboseTrk = 0 }; + +namespace trk { + +/////////////////////////////////////////////////////////////////////// +// +// TrkMessage +// +/////////////////////////////////////////////////////////////////////// + +/* A message to be send to TRK, triggering a callback on receipt + * of the answer. */ +struct TrkMessage +{ + explicit TrkMessage(byte code = 0u, byte token = 0u, + TrkCallback callback = TrkCallback()); + + byte code; + byte token; + QByteArray data; + QVariant cookie; + TrkCallback callback; +}; + +TrkMessage::TrkMessage(byte c, byte t, TrkCallback cb) : + code(c), + token(t), + callback(cb) +{ +} + +QDebug operator<<(QDebug d, const TrkMessage &msg) +{ + return d << "Message: Code: " << msg.code + << " Token: " << msg.token << " " << msg.data.toHex(); +} + +} // namespace trk + +Q_DECLARE_METATYPE(trk::TrkMessage) +Q_DECLARE_METATYPE(trk::TrkResult) + +namespace trk { + +/////////////////////////////////////////////////////////////////////// +// +// TrkWriteQueue: Mixin class that manages a write queue of Trk messages. +// pendingMessage()/notifyWriteResult() should be called from a worked/timer +// that writes the messages. The class does not take precautions for multithreading. +// A no-op message is simply taken off the queue. The calling class +// can use the helper invokeNoopMessage() to trigger its callback. +// +/////////////////////////////////////////////////////////////////////// + +class TrkWriteQueue +{ + Q_DISABLE_COPY(TrkWriteQueue) +public: + explicit TrkWriteQueue(); + + // Enqueue messages. + void queueTrkMessage(byte code, TrkCallback callback, + const QByteArray &data, const QVariant &cookie); + void queueTrkInitialPing(); + + // Call this from the device read notification with the results. + void slotHandleResult(const TrkResult &result, QMutex *mutex = 0); + + // pendingMessage() can be called periodically in a timer to retrieve + // the pending messages to be sent. + enum PendingMessageResult { + NoMessage, // No message in queue. + PendingMessage, /* There is a queued message. The calling class + * can write it out and use notifyWriteResult() + * to notify about the result. */ + NoopMessageDequeued // A no-op message has been dequeued. see invokeNoopMessage(). + }; + + PendingMessageResult pendingMessage(TrkMessage *message); + // Notify the queue about the success of the write operation + // after taking the pendingMessage off. + enum WriteResult { + WriteOk, + WriteFailedDiscard, // Discard failed message + WriteFailedKeep, // Keep failed message + }; + void notifyWriteResult(WriteResult ok); + + // Helper function that invokes the callback of a no-op message + static void invokeNoopMessage(trk::TrkMessage); + +private: + typedef QMap TokenMessageMap; + + byte nextTrkWriteToken(); + + byte m_trkWriteToken; + QQueue m_trkWriteQueue; + TokenMessageMap m_writtenTrkMessages; + bool m_trkWriteBusy; +}; + +TrkWriteQueue::TrkWriteQueue() : + m_trkWriteToken(0), + m_trkWriteBusy(false) +{ +} + +byte TrkWriteQueue::nextTrkWriteToken() +{ + ++m_trkWriteToken; + if (m_trkWriteToken == 0) + ++m_trkWriteToken; + if (verboseTrk) + qDebug() << "Write token: " << m_trkWriteToken; + return m_trkWriteToken; +} + +void TrkWriteQueue::queueTrkMessage(byte code, TrkCallback callback, + const QByteArray &data, const QVariant &cookie) +{ + const byte token = code == TRK_WRITE_QUEUE_NOOP_CODE ? + byte(0) : nextTrkWriteToken(); + TrkMessage msg(code, token, callback); + msg.data = data; + msg.cookie = cookie; + m_trkWriteQueue.append(msg); +} + +TrkWriteQueue::PendingMessageResult TrkWriteQueue::pendingMessage(TrkMessage *message) +{ + // Invoked from timer, try to flush out message queue + if (m_trkWriteBusy || m_trkWriteQueue.isEmpty()) + return NoMessage; + // Handle the noop message, just invoke CB in slot (ower thread) + if (m_trkWriteQueue.front().code == TRK_WRITE_QUEUE_NOOP_CODE) { + *message = m_trkWriteQueue.dequeue(); + return NoopMessageDequeued; + } + // Insert into map fir answers (as reading threads might get an + // answer before notifyWriteResult(true)) is called. + *message = m_trkWriteQueue.front(); + m_writtenTrkMessages.insert(message->token, *message); + m_trkWriteBusy = true; + return PendingMessage; +} + +void TrkWriteQueue::invokeNoopMessage(trk::TrkMessage noopMessage) +{ + TrkResult result; + result.code = noopMessage.code; + result.token = noopMessage.token; + result.data = noopMessage.data; + result.cookie = noopMessage.cookie; + noopMessage.callback(result); +} + +void TrkWriteQueue::notifyWriteResult(WriteResult wr) +{ + // On success, dequeue message and await result + const byte token = m_trkWriteQueue.front().token; + switch (wr) { + case WriteOk: + m_trkWriteQueue.dequeue(); + break; + case WriteFailedKeep: + case WriteFailedDiscard: + m_writtenTrkMessages.remove(token); + m_trkWriteBusy = false; + if (wr == WriteFailedDiscard) + m_trkWriteQueue.dequeue(); + break; + } +} + +void TrkWriteQueue::slotHandleResult(const TrkResult &result, QMutex *mutex) +{ + // Find which request the message belongs to and invoke callback + // if ACK or on NAK if desired. + if (mutex) + mutex->lock(); + m_trkWriteBusy = false; + const TokenMessageMap::iterator it = m_writtenTrkMessages.find(result.token); + if (it == m_writtenTrkMessages.end()) { + if (mutex) + mutex->unlock(); + return; + } + TrkCallback callback = it.value().callback; + const QVariant cookie = it.value().cookie; + m_writtenTrkMessages.erase(it); + if (mutex) + mutex->unlock(); + // Invoke callback + if (callback) { + TrkResult result1 = result; + result1.cookie = cookie; + callback(result1); + } +} + +void TrkWriteQueue::queueTrkInitialPing() +{ + // Ping, reset sequence count + m_trkWriteToken = 0; + m_trkWriteQueue.append(TrkMessage(TrkPing, 0)); +} + +/////////////////////////////////////////////////////////////////////// +// +// DeviceContext to be shared between threads +// +/////////////////////////////////////////////////////////////////////// + +struct DeviceContext { + DeviceContext(); +#ifdef Q_OS_WIN + HANDLE device; + OVERLAPPED readOverlapped; + OVERLAPPED writeOverlapped; +#else + QFile file; +#endif + bool serialFrame; + QMutex mutex; +}; + +DeviceContext::DeviceContext() : +#ifdef Q_OS_WIN + device(INVALID_HANDLE_VALUE), +#endif + serialFrame(true) +{ +} + +/////////////////////////////////////////////////////////////////////// +// +// TrkWriterThread: A thread operating a TrkWriteQueue. +// with exception of the handling of the TRK_WRITE_QUEUE_NOOP_CODE +// synchronization message. The invocation of the callback is then +// done by the thread owning the TrkWriteQueue, while pendingMessage() is called +// from another thread. This happens via a Qt::BlockingQueuedConnection. + +/////////////////////////////////////////////////////////////////////// + +class WriterThread : public QThread +{ + Q_OBJECT + Q_DISABLE_COPY(WriterThread) +public: + explicit WriterThread(const QSharedPointer &context); + + // Enqueue messages. + void queueTrkMessage(byte code, TrkCallback callback, + const QByteArray &data, const QVariant &cookie); + void queueTrkInitialPing(); + + // Call this from the device read notification with the results. + void slotHandleResult(const TrkResult &result); + + virtual void run(); + +signals: + void error(const QString &); + void internalNoopMessageDequeued(const trk::TrkMessage&); + +public slots: + bool trkWriteRawMessage(const TrkMessage &msg); + void terminate(); + void tryWrite(); + +private slots: + void invokeNoopMessage(const trk::TrkMessage &); + +private: + bool write(const QByteArray &data, QString *errorMessage); + inline int writePendingMessage(); + + const QSharedPointer m_context; + QMutex m_dataMutex; + QMutex m_waitMutex; + QWaitCondition m_waitCondition; + TrkWriteQueue m_queue; + bool m_terminate; +}; + +WriterThread::WriterThread(const QSharedPointer &context) : + m_context(context), + m_terminate(false) +{ + static const int trkMessageMetaId = qRegisterMetaType(); + Q_UNUSED(trkMessageMetaId) + connect(this, SIGNAL(internalNoopMessageDequeued(trk::TrkMessage)), + this, SLOT(invokeNoopMessage(trk::TrkMessage)), Qt::BlockingQueuedConnection); +} + +void WriterThread::run() +{ + while (writePendingMessage() == 0) ; +} + +int WriterThread::writePendingMessage() +{ + enum { MaxAttempts = 100, RetryIntervalMS = 200 }; + + // Wait. Use a timeout in case something is already queued before we + // start up or some weird hanging exit condition + m_waitMutex.lock(); + m_waitCondition.wait(&m_waitMutex, 100); + m_waitMutex.unlock(); + if (m_terminate) + return 1; + + // Send off message + m_dataMutex.lock(); + TrkMessage message; + const TrkWriteQueue::PendingMessageResult pr = m_queue.pendingMessage(&message); + m_dataMutex.unlock(); + + switch (pr) { + case TrkWriteQueue::NoMessage: + break; + case TrkWriteQueue::PendingMessage: { + //qDebug() << "Write pending message " << message; + // Untested: try to re-send a few times + bool success = false; + for (int r = 0; !success && (r < MaxAttempts); r++) { + success = trkWriteRawMessage(message); + if (!success) { + emit error(QString::fromLatin1("Write failure, attempt %1 of %2.").arg(r).arg(int(MaxAttempts))); + if (m_terminate) + return 1; + QThread::msleep(RetryIntervalMS); + } + } + // Notify queue. If still failed, give up. + m_dataMutex.lock(); + m_queue.notifyWriteResult(success ? TrkWriteQueue::WriteOk : TrkWriteQueue::WriteFailedDiscard); + m_dataMutex.unlock(); + } + break; + case TrkWriteQueue::NoopMessageDequeued: + // Sync with thread that owns us via a blocking signal + if (verboseTrk) + qDebug() << "Noop message dequeued" << message; + emit internalNoopMessageDequeued(message); + break; + } // switch + return 0; +} + +void WriterThread::invokeNoopMessage(const trk::TrkMessage &msg) +{ + TrkWriteQueue::invokeNoopMessage(msg); +} + +void WriterThread::terminate() +{ + m_terminate = true; + m_waitCondition.wakeAll(); + wait(); + m_terminate = false; +} + +#ifdef Q_OS_WIN + +static inline QString msgTerminated(int size) +{ + return QString::fromLatin1("Terminated with %1 bytes pending.").arg(size); +} + +// Interruptible synchronous write function. +static inline bool overlappedSyncWrite(HANDLE file, + const bool &terminateFlag, + const char *data, + DWORD size, DWORD *charsWritten, + OVERLAPPED *overlapped, + QString *errorMessage) +{ + if (WriteFile(file, data, size, charsWritten, overlapped)) + return true; + const DWORD writeError = GetLastError(); + if (writeError != ERROR_IO_PENDING) { + *errorMessage = QString::fromLatin1("WriteFile failed: %1").arg(winErrorMessage(writeError)); + return false; + } + // Wait for written or thread terminated + const DWORD timeoutMS = 200; + const unsigned maxAttempts = 20; + DWORD wr = WaitForSingleObject(overlapped->hEvent, timeoutMS); + for (unsigned n = 0; wr == WAIT_TIMEOUT && n < maxAttempts && !terminateFlag; + wr = WaitForSingleObject(overlapped->hEvent, timeoutMS), n++); + if (terminateFlag) { + *errorMessage = msgTerminated(size); + return false; + } + switch (wr) { + case WAIT_OBJECT_0: + break; + case WAIT_TIMEOUT: + *errorMessage = QString::fromLatin1("Write timed out."); + return false; + default: + *errorMessage = QString::fromLatin1("Error while waiting for WriteFile results: %1").arg(winErrorMessage(GetLastError())); + return false; + } + if (!GetOverlappedResult(file, overlapped, charsWritten, TRUE)) { + *errorMessage = QString::fromLatin1("Error writing %1 bytes: %2").arg(size).arg(winErrorMessage(GetLastError())); + return false; + } + return true; +} +#endif + +bool WriterThread::write(const QByteArray &data, QString *errorMessage) +{ + if (verboseTrk) + qDebug() << "Write raw data: " << stringFromArray(data).toLatin1(); + QMutexLocker locker(&m_context->mutex); +#ifdef Q_OS_WIN + DWORD charsWritten; + if (!overlappedSyncWrite(m_context->device, m_terminate, data.data(), data.size(), &charsWritten, &m_context->writeOverlapped, errorMessage)) { + return false; + } + FlushFileBuffers(m_context->device); + return true; +#else + if (m_context->file.write(data) == -1 || !m_context->file.flush()) { + *errorMessage = QString::fromLatin1("Cannot write: %1").arg(m_context->file.errorString()); + return false; + } + return true; +#endif +} + +bool WriterThread::trkWriteRawMessage(const TrkMessage &msg) +{ + const QByteArray ba = frameMessage(msg.code, msg.token, msg.data, m_context->serialFrame); + QString errorMessage; + const bool rc = write(ba, &errorMessage); + if (!rc) { + qWarning("%s\n", qPrintable(errorMessage)); + emit error(errorMessage); + } + return rc; +} + +void WriterThread::tryWrite() +{ + m_waitCondition.wakeAll(); +} + +void WriterThread::queueTrkMessage(byte code, TrkCallback callback, + const QByteArray &data, const QVariant &cookie) +{ + m_dataMutex.lock(); + m_queue.queueTrkMessage(code, callback, data, cookie); + m_dataMutex.unlock(); + tryWrite(); +} + +void WriterThread::queueTrkInitialPing() +{ + m_dataMutex.lock(); + m_queue.queueTrkInitialPing(); + m_dataMutex.unlock(); + tryWrite(); +} + +// Call this from the device read notification with the results. +void WriterThread::slotHandleResult(const TrkResult &result) +{ + m_queue.slotHandleResult(result, &m_dataMutex); + tryWrite(); // Have messages been enqueued in-between? +} + + +/////////////////////////////////////////////////////////////////////// +// +// ReaderThreadBase: Base class for a thread that reads data from +// the device, decodes the messages and emit signals for the messages. +// A Qt::BlockingQueuedConnection should be used for the message signal +// to ensure messages are processed in the correct sequence. +// +/////////////////////////////////////////////////////////////////////// + +class ReaderThreadBase : public QThread +{ + Q_OBJECT + Q_DISABLE_COPY(ReaderThreadBase) +public: + +signals: + void messageReceived(const trk::TrkResult &result, const QByteArray &rawData); + +protected: + explicit ReaderThreadBase(const QSharedPointer &context); + void processData(const QByteArray &a); + void processData(char c); + + const QSharedPointer m_context; + +private: + void readMessages(); + + QByteArray m_trkReadBuffer; +}; + +ReaderThreadBase::ReaderThreadBase(const QSharedPointer &context) : + m_context(context) +{ + static const int trkResultMetaId = qRegisterMetaType(); + Q_UNUSED(trkResultMetaId) +} + +void ReaderThreadBase::processData(const QByteArray &a) +{ + m_trkReadBuffer += a; + readMessages(); +} + +void ReaderThreadBase::processData(char c) +{ + m_trkReadBuffer += c; + if (m_trkReadBuffer.size() > 1) + readMessages(); +} + +void ReaderThreadBase::readMessages() +{ + TrkResult r; + QByteArray rawData; + while (extractResult(&m_trkReadBuffer, m_context->serialFrame, &r, &rawData)) { + emit messageReceived(r, rawData); + } +} + +#ifdef Q_OS_WIN +/////////////////////////////////////////////////////////////////////// +// +// WinReaderThread: A thread reading from the device using Windows API. +// Waits on an overlapped I/O handle and an event that tells the thread to +// terminate. +// +/////////////////////////////////////////////////////////////////////// + +class WinReaderThread : public ReaderThreadBase +{ + Q_OBJECT + Q_DISABLE_COPY(WinReaderThread) +public: + explicit WinReaderThread(const QSharedPointer &context); + ~WinReaderThread(); + + virtual void run(); + +signals: + void error(const QString &); + +public slots: + void terminate(); + +private: + enum Handles { FileHandle, TerminateEventHandle, HandleCount }; + + inline int tryRead(); + + HANDLE m_handles[HandleCount]; +}; + +WinReaderThread::WinReaderThread(const QSharedPointer &context) : + ReaderThreadBase(context) +{ + m_handles[FileHandle] = NULL; + m_handles[TerminateEventHandle] = CreateEvent(NULL, FALSE, FALSE, NULL); +} + +WinReaderThread::~WinReaderThread() +{ + CloseHandle(m_handles[TerminateEventHandle]); +} + +// Return 0 to continue or error code +int WinReaderThread::tryRead() +{ + enum { BufSize = 1024 }; + char buffer[BufSize]; + // Check if there are already bytes waiting. If not, wait for first byte + COMSTAT comStat; + if (!ClearCommError(m_context->device, NULL, &comStat)){ + emit error(QString::fromLatin1("ClearCommError failed: %1").arg(winErrorMessage(GetLastError()))); + return -7; + } + const DWORD bytesToRead = qMax(DWORD(1), qMin(comStat.cbInQue, DWORD(BufSize))); + // Trigger read + DWORD bytesRead = 0; + if (ReadFile(m_context->device, &buffer, bytesToRead, &bytesRead, &m_context->readOverlapped)) { + if (bytesRead == 1) { + processData(buffer[0]); + } else { + processData(QByteArray(buffer, bytesRead)); + } + return 0; + } + const DWORD readError = GetLastError(); + if (readError != ERROR_IO_PENDING) { + emit error(QString::fromLatin1("Read error: %1").arg(winErrorMessage(readError))); + return -1; + } + // Wait for either termination or data + const DWORD wr = WaitForMultipleObjects(HandleCount, m_handles, false, INFINITE); + if (wr == WAIT_FAILED) { + emit error(QString::fromLatin1("Wait failed: %1").arg(winErrorMessage(GetLastError()))); + return -2; + } + if (wr - WAIT_OBJECT_0 == TerminateEventHandle) { + return 1; // Terminate + } + // Check data + if (!GetOverlappedResult(m_context->device, &m_context->readOverlapped, &bytesRead, true)) { + emit error(QString::fromLatin1("GetOverlappedResult failed: %1").arg(winErrorMessage(GetLastError()))); + return -3; + } + if (bytesRead == 1) { + processData(buffer[0]); + } else { + processData(QByteArray(buffer, bytesRead)); + } + return 0; +} + +void WinReaderThread::run() +{ + m_handles[FileHandle] = m_context->readOverlapped.hEvent; + while ( tryRead() == 0) ; +} + +void WinReaderThread::terminate() +{ + SetEvent(m_handles[TerminateEventHandle]); + wait(); +} + +typedef WinReaderThread ReaderThread; + +#else + +/////////////////////////////////////////////////////////////////////// +// +// UnixReaderThread: A thread reading from the device. +// Uses select() to wait and a special ioctl() to find out the number +// of bytes queued. For clean termination, the self-pipe trick is used. +// The class maintains a pipe, on whose read end the select waits besides +// the device file handle. To terminate, a byte is written to the pipe. +// +/////////////////////////////////////////////////////////////////////// + +static inline QString msgUnixCallFailedErrno(const char *func, int errorNumber) +{ + return QString::fromLatin1("Call to %1() failed: %2").arg(QLatin1String(func), QString::fromLocal8Bit(strerror(errorNumber))); +} + +class UnixReaderThread : public ReaderThreadBase { + Q_OBJECT + Q_DISABLE_COPY(UnixReaderThread) +public: + explicit UnixReaderThread(const QSharedPointer &context); + ~UnixReaderThread(); + + virtual void run(); + +signals: + void error(const QString &); + +public slots: + void terminate(); + +private: + inline int tryRead(); + + int m_terminatePipeFileDescriptors[2]; +}; + +UnixReaderThread::UnixReaderThread(const QSharedPointer &context) : + ReaderThreadBase(context) +{ + m_terminatePipeFileDescriptors[0] = m_terminatePipeFileDescriptors[1] = -1; + // Set up pipes for termination. Should not fail + if (pipe(m_terminatePipeFileDescriptors) < 0) + qWarning("%s\n", qPrintable(msgUnixCallFailedErrno("pipe", errno))); +} + +UnixReaderThread::~UnixReaderThread() +{ + close(m_terminatePipeFileDescriptors[0]); + close(m_terminatePipeFileDescriptors[1]); +} + +int UnixReaderThread::tryRead() +{ + fd_set readSet, tempReadSet, tempExceptionSet; + struct timeval timeOut; + const int fileDescriptor = m_context->file.handle(); + FD_ZERO(&readSet); + FD_SET(fileDescriptor, &readSet); + FD_SET(m_terminatePipeFileDescriptors[0], &readSet); + const int maxFileDescriptor = qMax(m_terminatePipeFileDescriptors[0], fileDescriptor); + int result = 0; + do { + memcpy(&tempReadSet, &readSet, sizeof(fd_set)); + memcpy(&tempExceptionSet, &readSet, sizeof(fd_set)); + timeOut.tv_sec = 1; + timeOut.tv_usec = 0; + result = select(maxFileDescriptor + 1, &tempReadSet, NULL, &tempExceptionSet, &timeOut); + } while ( result < 0 && errno == EINTR ); + // Timeout? + if (result == 0) + return 0; + // Something wrong? + if (result < 0) { + emit error(msgUnixCallFailedErrno("select", errno)); + return -1; + } + // Did the exception set trigger on the device? + if (FD_ISSET(fileDescriptor,&tempExceptionSet)) { + emit error(QLatin1String("An Exception occurred on the device.")); + return -2; + } + // Check termination pipe. + if (FD_ISSET(m_terminatePipeFileDescriptors[0], &tempReadSet) + || FD_ISSET(m_terminatePipeFileDescriptors[0], &tempExceptionSet)) + return 1; + + // determine number of pending bytes and read + int numBytes; + if (ioctl(fileDescriptor, FIONREAD, &numBytes) < 0) { + emit error(msgUnixCallFailedErrno("ioctl", errno)); + return -1; + } + m_context->mutex.lock(); + const QByteArray data = m_context->file.read(numBytes); + m_context->mutex.unlock(); + processData(data); + return 0; +} + +void UnixReaderThread::run() +{ + // Read loop + while (tryRead() == 0) + ; +} + +void UnixReaderThread::terminate() +{ + // Trigger select() by writing to the pipe + char c = 0; + const int written = write(m_terminatePipeFileDescriptors[1], &c, 1); + Q_UNUSED(written) + wait(); +} + +typedef UnixReaderThread ReaderThread; + +#endif + +/////////////////////////////////////////////////////////////////////// +// +// TrkDevicePrivate +// +/////////////////////////////////////////////////////////////////////// + +struct TrkDevicePrivate +{ + TrkDevicePrivate(); + + QSharedPointer deviceContext; + QSharedPointer writerThread; + QSharedPointer readerThread; + + QByteArray trkReadBuffer; + int verbose; + QString errorString; +}; + +/////////////////////////////////////////////////////////////////////// +// +// TrkDevice +// +/////////////////////////////////////////////////////////////////////// + +TrkDevicePrivate::TrkDevicePrivate() : + deviceContext(new DeviceContext), + verbose(0) +{ +} + +/////////////////////////////////////////////////////////////////////// +// +// TrkDevice +// +/////////////////////////////////////////////////////////////////////// + +TrkDevice::TrkDevice(QObject *parent) : + QObject(parent), + d(new TrkDevicePrivate) +{} + +TrkDevice::~TrkDevice() +{ + close(); + delete d; +} + +bool TrkDevice::open(const QString &port, QString *errorMessage) +{ + if (d->verbose) + qDebug() << "Opening" << port << "is open: " << isOpen() << " serialFrame=" << serialFrame(); + close(); +#ifdef Q_OS_WIN + d->deviceContext->device = CreateFile(QString("\\\\.\\").append(port).toStdWString().c_str(), + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING|FILE_FLAG_OVERLAPPED, + NULL); + + if (INVALID_HANDLE_VALUE == d->deviceContext->device) { + *errorMessage = QString::fromLatin1("Could not open device '%1': %2").arg(port, winErrorMessage(GetLastError())); + return false; + } + memset(&d->deviceContext->readOverlapped, 0, sizeof(OVERLAPPED)); + d->deviceContext->readOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + memset(&d->deviceContext->writeOverlapped, 0, sizeof(OVERLAPPED)); + d->deviceContext->writeOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (d->deviceContext->readOverlapped.hEvent == NULL || d->deviceContext->writeOverlapped.hEvent == NULL) { + *errorMessage = QString::fromLatin1("Failed to create events: %1").arg(winErrorMessage(GetLastError())); + return false; + } +#else + d->deviceContext->file.setFileName(port); + if (!d->deviceContext->file.open(QIODevice::ReadWrite|QIODevice::Unbuffered)) { + *errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(port, d->deviceContext->file.errorString()); + return false; + } + + struct termios termInfo; + if (tcgetattr(d->deviceContext->file.handle(), &termInfo) < 0) { + *errorMessage = QString::fromLatin1("Unable to retrieve terminal settings: %1 %2").arg(errno).arg(QString::fromAscii(strerror(errno))); + return false; + } + // Turn off terminal echo as not get messages back, among other things + termInfo.c_cflag |= CREAD|CLOCAL; + termInfo.c_lflag &= (~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); + termInfo.c_iflag &= (~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY)); + termInfo.c_oflag &= (~OPOST); + termInfo.c_cc[VMIN] = 0; + termInfo.c_cc[VINTR] = _POSIX_VDISABLE; + termInfo.c_cc[VQUIT] = _POSIX_VDISABLE; + termInfo.c_cc[VSTART] = _POSIX_VDISABLE; + termInfo.c_cc[VSTOP] = _POSIX_VDISABLE; + termInfo.c_cc[VSUSP] = _POSIX_VDISABLE; + if (tcsetattr(d->deviceContext->file.handle(), TCSAFLUSH, &termInfo) < 0) { + *errorMessage = QString::fromLatin1("Unable to apply terminal settings: %1 %2").arg(errno).arg(QString::fromAscii(strerror(errno))); + return false; + } +#endif + d->readerThread = QSharedPointer(new ReaderThread(d->deviceContext)); + connect(d->readerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)), + Qt::QueuedConnection); + connect(d->readerThread.data(), SIGNAL(messageReceived(trk::TrkResult,QByteArray)), + this, SLOT(slotMessageReceived(trk::TrkResult,QByteArray)), + Qt::QueuedConnection); + d->readerThread->start(); + + d->writerThread = QSharedPointer(new WriterThread(d->deviceContext)); + connect(d->writerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)), + Qt::QueuedConnection); + d->writerThread->start(); + + if (d->verbose) + qDebug() << "Opened" << port; + return true; +} + +void TrkDevice::close() +{ + if (!isOpen()) + return; + if (d->readerThread) + d->readerThread->terminate(); + if (d->writerThread) + d->writerThread->terminate(); +#ifdef Q_OS_WIN + CloseHandle(d->deviceContext->device); + d->deviceContext->device = INVALID_HANDLE_VALUE; + CloseHandle(d->deviceContext->readOverlapped.hEvent); + CloseHandle(d->deviceContext->writeOverlapped.hEvent); + d->deviceContext->readOverlapped.hEvent = d->deviceContext->writeOverlapped.hEvent = NULL; +#else + d->deviceContext->file.close(); +#endif + if (d->verbose) + emitLogMessage("Close"); +} + +bool TrkDevice::isOpen() const +{ +#ifdef Q_OS_WIN + return d->deviceContext->device != INVALID_HANDLE_VALUE; +#else + return d->deviceContext->file.isOpen(); +#endif +} + +QString TrkDevice::errorString() const +{ + return d->errorString; +} + +bool TrkDevice::serialFrame() const +{ + return d->deviceContext->serialFrame; +} + +void TrkDevice::setSerialFrame(bool f) +{ + d->deviceContext->serialFrame = f; +} + +int TrkDevice::verbose() const +{ + return d->verbose; +} + +void TrkDevice::setVerbose(int b) +{ + d->verbose = b; +} + +void TrkDevice::slotMessageReceived(const trk::TrkResult &result, const QByteArray &rawData) +{ + d->writerThread->slotHandleResult(result); + if (d->verbose > 1) + qDebug() << "Received: " << result.toString(); + emit messageReceived(result); + if (!rawData.isEmpty()) + emit rawDataReceived(rawData); +} + +void TrkDevice::emitError(const QString &s) +{ + d->errorString = s; + qWarning("%s\n", qPrintable(s)); + emit error(s); +} + +void TrkDevice::sendTrkMessage(byte code, TrkCallback callback, + const QByteArray &data, const QVariant &cookie) +{ + if (!d->writerThread.isNull()) { + if (d->verbose > 1) { + QByteArray msg = "Sending: "; + msg += QByteArray::number(code, 16); + msg += ": "; + msg += stringFromArray(data).toLatin1(); + qDebug("%s", msg.data()); + } + d->writerThread->queueTrkMessage(code, callback, data, cookie); + } +} + +void TrkDevice::sendTrkInitialPing() +{ + if (!d->writerThread.isNull()) + d->writerThread->queueTrkInitialPing(); +} + +bool TrkDevice::sendTrkAck(byte token) +{ + if (d->writerThread.isNull()) + return false; + // The acknowledgement must not be queued! + TrkMessage msg(0x80, token); + msg.token = token; + msg.data.append('\0'); + if (verboseTrk) + qDebug() << "Write synchroneous message: " << msg; + return d->writerThread->trkWriteRawMessage(msg); + // 01 90 00 07 7e 80 01 00 7d 5e 7e +} + +void TrkDevice::emitLogMessage(const QString &msg) +{ + if (d->verbose) + qDebug("%s\n", qPrintable(msg)); + emit logMessage(msg); +} + +} // namespace trk + +#include "trkdevice.moc" diff --git a/tools/runonphone/symbianutils/trkdevice.h b/tools/runonphone/symbianutils/trkdevice.h new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/tools/runonphone/symbianutils/trkdevice.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TRKDEVICE_H +#define TRKDEVICE_H + +#include "symbianutils_global.h" +#include "callback.h" + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QIODevice; +QT_END_NAMESPACE + +namespace trk { + +struct TrkResult; +struct TrkMessage; +struct TrkDevicePrivate; + +/* TrkDevice: Implements a Windows COM or Linux device for + * Trk communications. Provides synchronous write and asynchronous + * read operation. + * The serialFrames property specifies whether packets are encapsulated in + * "0x90 " frames, which is currently the case for serial ports. + * Contains a write message queue allowing + * for queueing messages with a notification callback. If the message receives + * an ACK, the callback is invoked. + * The special message TRK_WRITE_QUEUE_NOOP_CODE code can be used for synchronisation. + * The respective message will not be sent, the callback is just invoked. */ + +enum { TRK_WRITE_QUEUE_NOOP_CODE = 0x7f }; + +typedef trk::Callback TrkCallback; + +class SYMBIANUTILS_EXPORT TrkDevice : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool serialFrame READ serialFrame WRITE setSerialFrame) + Q_PROPERTY(bool verbose READ verbose WRITE setVerbose) +public: + explicit TrkDevice(QObject *parent = 0); + virtual ~TrkDevice(); + + bool open(const QString &port, QString *errorMessage); + bool isOpen() const; + + QString errorString() const; + + bool serialFrame() const; + void setSerialFrame(bool f); + + int verbose() const; + void setVerbose(int b); + + // Enqueue a message with a notification callback. + void sendTrkMessage(unsigned char code, + TrkCallback callBack = TrkCallback(), + const QByteArray &data = QByteArray(), + const QVariant &cookie = QVariant()); + + // Enqeue an initial ping + void sendTrkInitialPing(); + + // Send an Ack synchronously, bypassing the queue + bool sendTrkAck(unsigned char token); + +signals: + void messageReceived(const trk::TrkResult &result); + // Emitted with the contents of messages enclosed in 07e, not for log output + void rawDataReceived(const QByteArray &data); + void error(const QString &msg); + void logMessage(const QString &msg); + +private slots: + void slotMessageReceived(const trk::TrkResult &result, const QByteArray &a); + +protected slots: + void emitError(const QString &msg); + void emitLogMessage(const QString &msg); + +public slots: + void close(); + +private: + void readMessages(); + TrkDevicePrivate *d; +}; + +} // namespace trk + +#endif // TRKDEVICE_H diff --git a/tools/runonphone/symbianutils/trkutils.cpp b/tools/runonphone/symbianutils/trkutils.cpp new file mode 100644 index 0000000..5cce950 --- /dev/null +++ b/tools/runonphone/symbianutils/trkutils.cpp @@ -0,0 +1,479 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "trkutils.h" +#include + +#include +#include +#include +#include +#include + +#define logMessage(s) do { qDebug() << "TRKCLIENT: " << s; } while (0) + +namespace trk { + +TrkAppVersion::TrkAppVersion() +{ + reset(); +} + +void TrkAppVersion::reset() +{ + trkMajor = trkMinor= protocolMajor = protocolMinor = 0; +} + +Session::Session() +{ + reset(); +} + +void Session::reset() +{ + cpuMajor = 0; + cpuMinor = 0; + bigEndian = 0; + defaultTypeSize = 0; + fpTypeSize = 0; + extended1TypeSize = 0; + extended2TypeSize = 0; + pid = 0; + tid = 0; + codeseg = 0; + dataseg = 0; + + currentThread = 0; + libraries.clear(); + trkAppVersion.reset(); +} + +static QString formatCpu(int major, int minor) +{ + //: CPU description of an S60 device + //: %1 major verison, %2 minor version + //: %3 real name of major verison, %4 real name of minor version + const QString str = QCoreApplication::translate("trk::Session", "CPU: v%1.%2%3%4"); + QString majorStr; + QString minorStr; + switch (major) { + case 0x04: + majorStr = " ARM"; + break; + } + switch (minor) { + case 0x00: + minorStr = " 920T"; + break; + } + return str.arg(major).arg(minor).arg(majorStr).arg(minorStr); + } + +QString formatTrkVersion(const TrkAppVersion &version) +{ + QString str = QCoreApplication::translate("trk::Session", + "App TRK: v%1.%2 TRK protocol: v%3.%4"); + str = str.arg(version.trkMajor).arg(version.trkMinor); + return str.arg(version.protocolMajor).arg(version.protocolMinor); +} + +QString Session::deviceDescription(unsigned verbose) const +{ + if (!cpuMajor) + return QString(); + + //: s60description + //: description of an S60 device + //: %1 CPU description, %2 endianness + //: %3 default type size (if any), %4 float size (if any) + //: %5 TRK version + QString msg = QCoreApplication::translate("trk::Session", "%1, %2%3%4, %5"); + QString endianness = bigEndian + ? QCoreApplication::translate("trk::Session", "big endian") + : QCoreApplication::translate("trk::Session", "little endian"); + msg = msg.arg(formatCpu(cpuMajor, cpuMinor)).arg(endianness); + //: The separator in a list of strings + QString defaultTypeSizeStr; + QString fpTypeSizeStr; + if (verbose && defaultTypeSize) + //: will be inserted into s60description + defaultTypeSizeStr = QCoreApplication::translate("trk::Session", ", type size: %1").arg(defaultTypeSize); + if (verbose && fpTypeSize) + //: will be inserted into s60description + fpTypeSizeStr = QCoreApplication::translate("trk::Session", ", float size: %1").arg(fpTypeSize); + msg = msg.arg(defaultTypeSizeStr).arg(fpTypeSizeStr); + return msg.arg(formatTrkVersion(trkAppVersion)); +} + + +QByteArray decode7d(const QByteArray &ba) +{ + QByteArray res; + res.reserve(ba.size()); + for (int i = 0; i < ba.size(); ++i) { + byte c = byte(ba.at(i)); + if (c == 0x7d) { + ++i; + c = 0x20 ^ byte(ba.at(i)); + } + res.append(c); + } + return res; +} + +QByteArray encode7d(const QByteArray &ba) +{ + QByteArray res; + res.reserve(ba.size() + 2); + for (int i = 0; i < ba.size(); ++i) { + byte c = byte(ba.at(i)); + if (c == 0x7e || c == 0x7d) { + res.append(0x7d); + res.append(0x20 ^ c); + } else { + res.append(c); + } + } + return res; +} + +// FIXME: Use the QByteArray based version below? +static inline QString stringFromByte(byte c) +{ + return QString::fromLatin1("%1").arg(c, 2, 16, QChar('0')); +} + +SYMBIANUTILS_EXPORT QString stringFromArray(const QByteArray &ba, int maxLen) +{ + QString str; + QString ascii; + const int size = maxLen == -1 ? ba.size() : qMin(ba.size(), maxLen); + for (int i = 0; i < size; ++i) { + //if (i == 5 || i == ba.size() - 2) + // str += " "; + int c = byte(ba.at(i)); + str += QString("%1 ").arg(c, 2, 16, QChar('0')); + if (i >= 8 && i < ba.size() - 2) + ascii += QChar(c).isPrint() ? QChar(c) : QChar('.'); + } + if (size != ba.size()) { + str += "..."; + ascii += "..."; + } + return str + " " + ascii; +} + +SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits) +{ + QByteArray ba = QByteArray::number(n, 16); + if (digits == 0 || ba.size() == digits) + return ba; + return QByteArray(digits - ba.size(), '0') + ba; +} + +SYMBIANUTILS_EXPORT QByteArray hexxNumber(uint n, int digits) +{ + return "0x" + hexNumber(n, digits); +} + +TrkResult::TrkResult() : + code(0), + token(0), + isDebugOutput(false) +{ +} + +void TrkResult::clear() +{ + code = token= 0; + isDebugOutput = false; + data.clear(); + cookie = QVariant(); +} + +QString TrkResult::toString() const +{ + QString res = stringFromByte(code); + res += QLatin1String(" ["); + res += stringFromByte(token); + res += QLatin1Char(']'); + res += QLatin1Char(' '); + res += stringFromArray(data); + return res; +} + +QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame) +{ + byte s = command + token; + for (int i = 0; i != data.size(); ++i) + s += data.at(i); + byte checksum = 255 - (s & 0xff); + //int x = s + ~s; + //logMessage("check: " << s << checksum << x; + + QByteArray response; + response.reserve(data.size() + 3); + response.append(char(command)); + response.append(char(token)); + response.append(data); + response.append(char(checksum)); + + QByteArray encodedData = encode7d(response); + + QByteArray ba; + ba.reserve(encodedData.size() + 6); + if (serialFrame) { + ba.append(char(0x01)); + ba.append(char(0x90)); + const ushort encodedSize = encodedData.size() + 2; // 2 x 0x7e + appendShort(&ba, encodedSize, BigEndian); + } + ba.append(char(0x7e)); + ba.append(encodedData); + ba.append(char(0x7e)); + + return ba; +} + +/* returns 0 if array doesn't represent a result, +otherwise returns the length of the result data */ +ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame) +{ + if (serialFrame) { + // Serial protocol with length info + if (buffer.length() < 4) + return 0; + if (buffer.at(0) != 0x01 || byte(buffer.at(1)) != 0x90) + return 0; + const ushort len = extractShort(buffer.data() + 2); + return (buffer.size() >= len + 4) ? len : ushort(0); + } + // Frameless protocol without length info + const char delimiter = char(0x7e); + const int firstDelimiterPos = buffer.indexOf(delimiter); + // Regular message delimited by 0x7e..0x7e + if (firstDelimiterPos == 0) { + const int endPos = buffer.indexOf(delimiter, firstDelimiterPos + 1); + return endPos != -1 ? endPos + 1 - firstDelimiterPos : 0; + } + // Some ASCII log message up to first delimiter or all + return firstDelimiterPos != -1 ? firstDelimiterPos : buffer.size(); +} + +bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *result, QByteArray *rawData) +{ + result->clear(); + if(rawData) + rawData->clear(); + const ushort len = isValidTrkResult(*buffer, serialFrame); + if (!len) + return false; + // handle receiving application output, which is not a regular command + const int delimiterPos = serialFrame ? 4 : 0; + if (buffer->at(delimiterPos) != 0x7e) { + result->isDebugOutput = true; + result->data = buffer->mid(delimiterPos, len); + result->data.replace("\r\n", "\n"); + *buffer->remove(0, delimiterPos + len); + return true; + } + // FIXME: what happens if the length contains 0xfe? + // Assume for now that it passes unencoded! + const QByteArray data = decode7d(buffer->mid(delimiterPos + 1, len - 2)); + if(rawData) + *rawData = data; + *buffer->remove(0, delimiterPos + len); + + byte sum = 0; + for (int i = 0; i < data.size(); ++i) // 3 = 2 * 0xfe + sum + sum += byte(data.at(i)); + if (sum != 0xff) + logMessage("*** CHECKSUM ERROR: " << byte(sum)); + + result->code = data.at(0); + result->token = data.at(1); + result->data = data.mid(2, data.size() - 3); + //logMessage(" REST BUF: " << stringFromArray(*buffer)); + //logMessage(" CURR DATA: " << stringFromArray(data)); + //QByteArray prefix = "READ BUF: "; + //logMessage((prefix + "HEADER: " + stringFromArray(header).toLatin1()).data()); + return true; +} + +SYMBIANUTILS_EXPORT ushort extractShort(const char *data) +{ + return byte(data[0]) * 256 + byte(data[1]); +} + +SYMBIANUTILS_EXPORT uint extractInt(const char *data) +{ + uint res = byte(data[0]); + res *= 256; res += byte(data[1]); + res *= 256; res += byte(data[2]); + res *= 256; res += byte(data[3]); + return res; +} + +SYMBIANUTILS_EXPORT QString quoteUnprintableLatin1(const QByteArray &ba) +{ + QString res; + char buf[10]; + for (int i = 0, n = ba.size(); i != n; ++i) { + const byte c = ba.at(i); + if (isprint(c)) { + res += c; + } else { + qsnprintf(buf, sizeof(buf) - 1, "\\%x", int(c)); + res += buf; + } + } + return res; +} + +SYMBIANUTILS_EXPORT void appendShort(QByteArray *ba, ushort s, Endianness endian) +{ + if (endian == BigEndian) { + ba->append(s / 256); + ba->append(s % 256); + } else { + ba->append(s % 256); + ba->append(s / 256); + } +} + +SYMBIANUTILS_EXPORT void appendInt(QByteArray *ba, uint i, Endianness endian) +{ + const uchar b3 = i % 256; i /= 256; + const uchar b2 = i % 256; i /= 256; + const uchar b1 = i % 256; i /= 256; + const uchar b0 = i; + ba->reserve(ba->size() + 4); + if (endian == BigEndian) { + ba->append(b0); + ba->append(b1); + ba->append(b2); + ba->append(b3); + } else { + ba->append(b3); + ba->append(b2); + ba->append(b1); + ba->append(b0); + } +} + +void appendString(QByteArray *ba, const QByteArray &str, Endianness endian, bool appendNullTerminator) +{ + const int fullSize = str.size() + (appendNullTerminator ? 1 : 0); + appendShort(ba, fullSize, endian); // count the terminating \0 + ba->append(str); + if (appendNullTerminator) + ba->append('\0'); +} + +void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness endian) +{ + // convert the QDateTime to UTC and append its representation to QByteArray + // format is the same as in FAT file system + dateTime = dateTime.toUTC(); + const QTime utcTime = dateTime.time(); + const QDate utcDate = dateTime.date(); + uint fatDateTime = (utcTime.hour() << 11 | utcTime.minute() << 5 | utcTime.second()/2) << 16; + fatDateTime |= (utcDate.year()-1980) << 9 | utcDate.month() << 5 | utcDate.day(); + appendInt(ba, fatDateTime, endian); +} + +QByteArray errorMessage(byte code) +{ + switch (code) { + case 0x00: return "No error"; + case 0x01: return "Generic error in CWDS message"; + case 0x02: return "Unexpected packet size in send msg"; + case 0x03: return "Internal error occurred in CWDS"; + case 0x04: return "Escape followed by frame flag"; + case 0x05: return "Bad FCS in packet"; + case 0x06: return "Packet too long"; + case 0x07: return "Sequence ID not expected (gap in sequence)"; + + case 0x10: return "Command not supported"; + case 0x11: return "Command param out of range"; + case 0x12: return "An option was not supported"; + case 0x13: return "Read/write to invalid memory"; + case 0x14: return "Read/write invalid registers"; + case 0x15: return "Exception occurred in CWDS"; + case 0x16: return "Targeted system or thread is running"; + case 0x17: return "Breakpoint resources (HW or SW) exhausted"; + case 0x18: return "Requested breakpoint conflicts with existing one"; + + case 0x20: return "General OS-related error"; + case 0x21: return "Request specified invalid process"; + case 0x22: return "Request specified invalid thread"; + } + return "Unknown error"; +} + +uint swapEndian(uint in) +{ + return (in>>24) | ((in<<8) & 0x00FF0000) | ((in>>8) & 0x0000FF00) | (in<<24); +} + +int TrkResult::errorCode() const +{ + // NAK means always error, else data sized 1 with a non-null element + const bool isNAK = code == 0xff; + if (data.size() != 1 && !isNAK) + return 0; + if (const int errorCode = data.at(0)) + return errorCode; + return isNAK ? 0xff : 0; +} + +QString TrkResult::errorString() const +{ + // NAK means always error, else data sized 1 with a non-null element + if (code == 0xff) + return "NAK"; + if (data.size() < 1) + return "Unknown error packet"; + return errorMessage(data.at(0)); +} + +} // namespace trk + diff --git a/tools/runonphone/symbianutils/trkutils.h b/tools/runonphone/symbianutils/trkutils.h new file mode 100644 index 0000000..3a485c7 --- /dev/null +++ b/tools/runonphone/symbianutils/trkutils.h @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DEBUGGER_TRK_UTILS +#define DEBUGGER_TRK_UTILS + +#include "symbianutils_global.h" +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QDateTime; +QT_END_NAMESPACE + +namespace trk { + +typedef unsigned char byte; + +enum Command { + TrkPing = 0x00, + TrkConnect = 0x01, + TrkDisconnect = 0x02, + TrkVersions = 0x04, + TrkSupported = 0x05, + TrkCpuType = 0x06, + TrkHostVersions = 0x09, + TrkContinue = 0x18, + TrkCreateItem = 0x40, + TrkDeleteItem = 0x41, + + TrkWriteFile = 0x48, + TrkOpenFile = 0x4a, + TrkCloseFile = 0x4b, + TrkInstallFile = 0x4d, + TrkInstallFile2 = 0x4e, + + TrkNotifyAck = 0x80, + TrkNotifyNak = 0xff, + TrkNotifyStopped = 0x90, + TrkNotifyException = 0x91, + TrkNotifyInternalError = 0x92, + TrkNotifyCreated = 0xa0, + TrkNotifyDeleted = 0xa1, + TrkNotifyProcessorStarted = 0xa2, + TrkNotifyProcessorStandBy = 0xa6, + TrkNotifyProcessorReset = 0xa7 +}; + +inline byte extractByte(const char *data) { return *data; } +SYMBIANUTILS_EXPORT ushort extractShort(const char *data); +SYMBIANUTILS_EXPORT uint extractInt(const char *data); + +SYMBIANUTILS_EXPORT QString quoteUnprintableLatin1(const QByteArray &ba); + +// produces "xx xx xx " +SYMBIANUTILS_EXPORT QString stringFromArray(const QByteArray &ba, int maxLen = - 1); + +enum Endianness +{ + LittleEndian, + BigEndian, + TargetByteOrder = BigEndian, +}; + +SYMBIANUTILS_EXPORT void appendShort(QByteArray *ba, ushort s, Endianness = TargetByteOrder); +SYMBIANUTILS_EXPORT void appendInt(QByteArray *ba, uint i, Endianness = TargetByteOrder); +SYMBIANUTILS_EXPORT void appendString(QByteArray *ba, const QByteArray &str, Endianness = TargetByteOrder, bool appendNullTerminator = true); + +struct SYMBIANUTILS_EXPORT Library +{ + Library() {} + + QByteArray name; + uint codeseg; + uint dataseg; +}; + +struct SYMBIANUTILS_EXPORT TrkAppVersion +{ + TrkAppVersion(); + void reset(); + + int trkMajor; + int trkMinor; + int protocolMajor; + int protocolMinor; +}; + +struct SYMBIANUTILS_EXPORT Session +{ + Session(); + void reset(); + QString deviceDescription(unsigned verbose) const; + + // Trk feedback + byte cpuMajor; + byte cpuMinor; + byte bigEndian; + byte defaultTypeSize; + byte fpTypeSize; + byte extended1TypeSize; + byte extended2TypeSize; + TrkAppVersion trkAppVersion; + uint pid; + uint tid; + uint codeseg; + uint dataseg; + QHash addressToBP; + + typedef QList Libraries; + Libraries libraries; + + typedef uint Thread; + typedef QList Threads; + Threads threads; + + // Gdb request + uint currentThread; + QStringList modules; +}; + +struct SYMBIANUTILS_EXPORT TrkResult +{ + TrkResult(); + void clear(); + QString toString() const; + // 0 for no error. + int errorCode() const; + QString errorString() const; + + byte code; + byte token; + QByteArray data; + QVariant cookie; + bool isDebugOutput; +}; + +SYMBIANUTILS_EXPORT QByteArray errorMessage(byte code); +SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits = 0); +SYMBIANUTILS_EXPORT QByteArray hexxNumber(uint n, int digits = 0); // prepends '0x', too +SYMBIANUTILS_EXPORT uint swapEndian(uint in); + +} // namespace trk + +#endif // DEBUGGER_TRK_UTILS diff --git a/tools/runonphone/symbianutils/trkutils_p.h b/tools/runonphone/symbianutils/trkutils_p.h new file mode 100644 index 0000000..12b0109 --- /dev/null +++ b/tools/runonphone/symbianutils/trkutils_p.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DEBUGGER_TRK_PRIVATE_UTILS +#define DEBUGGER_TRK_PRIVATE_UTILS + +#include "trkutils.h" +#include "symbianutils_global.h" + +QT_BEGIN_NAMESPACE +class QDateTime; +QT_END_NAMESPACE + +namespace trk { + +void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness = TargetByteOrder); +// returns a QByteArray containing optionally +// the serial frame [0x01 0x90 ] and 0x7e encoded7d(ba) 0x7e +QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame); +bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *r, QByteArray *rawData = 0); + +} // namespace trk + +#endif // DEBUGGER_TRK_PRIVATE_UTILS diff --git a/tools/runonphone/trk/bluetoothlistener.cpp b/tools/runonphone/trk/bluetoothlistener.cpp deleted file mode 100644 index df04288..0000000 --- a/tools/runonphone/trk/bluetoothlistener.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "bluetoothlistener.h" -#include "trkdevice.h" - -#include - -#ifdef Q_OS_UNIX -# include -# include -#else -# include -#endif - -// Process id helpers. -#ifdef Q_OS_WIN -inline DWORD processId(const QProcess &p) -{ - if (const Q_PID processInfoStruct = p.pid()) - return processInfoStruct->dwProcessId; - return 0; -} -#else -inline Q_PID processId(const QProcess &p) -{ - return p.pid(); -} -#endif - - -enum { debug = 0 }; - -namespace trk { - -struct BluetoothListenerPrivate { - BluetoothListenerPrivate(); - QString device; - QProcess process; -#ifdef Q_OS_WIN - DWORD pid; -#else - Q_PID pid; -#endif - bool printConsoleMessages; - BluetoothListener::Mode mode; -}; - -BluetoothListenerPrivate::BluetoothListenerPrivate() : - pid(0), - printConsoleMessages(false), - mode(BluetoothListener::Listen) -{ -} - -BluetoothListener::BluetoothListener(QObject *parent) : - QObject(parent), - d(new BluetoothListenerPrivate) -{ - d->process.setProcessChannelMode(QProcess::MergedChannels); - - connect(&d->process, SIGNAL(readyReadStandardError()), - this, SLOT(slotStdError())); - connect(&d->process, SIGNAL(readyReadStandardOutput()), - this, SLOT(slotStdOutput())); - connect(&d->process, SIGNAL(finished(int, QProcess::ExitStatus)), - this, SLOT(slotProcessFinished(int,QProcess::ExitStatus))); - connect(&d->process, SIGNAL(error(QProcess::ProcessError)), - this, SLOT(slotProcessError(QProcess::ProcessError))); -} - -BluetoothListener::~BluetoothListener() -{ - const int trc = terminateProcess(); - if (debug) - qDebug() << "~BluetoothListener: terminated" << trc; - delete d; -} - -BluetoothListener::Mode BluetoothListener::mode() const -{ - return d->mode; -} - -void BluetoothListener::setMode(Mode m) -{ - d->mode = m; -} - -bool BluetoothListener::printConsoleMessages() const -{ - return d->printConsoleMessages; -} - -void BluetoothListener::setPrintConsoleMessages(bool p) -{ - d->printConsoleMessages = p; -} - -int BluetoothListener::terminateProcess() -{ - enum { TimeOutMS = 200 }; - if (debug) - qDebug() << "terminateProcess" << d->process.pid() << d->process.state(); - if (d->process.state() == QProcess::NotRunning) - return -1; - emitMessage(tr("%1: Stopping listener %2...").arg(d->device).arg(processId(d->process))); - // When listening, the process should terminate by itself after closing the connection - if (mode() == Listen && d->process.waitForFinished(TimeOutMS)) - return 0; -#ifdef Q_OS_UNIX - kill(d->process.pid(), SIGHUP); // Listens for SIGHUP - if (d->process.waitForFinished(TimeOutMS)) - return 1; -#endif - d->process.terminate(); - if (d->process.waitForFinished(TimeOutMS)) - return 2; - d->process.kill(); - return 3; -} - -bool BluetoothListener::start(const QString &device, QString *errorMessage) -{ - if (d->process.state() != QProcess::NotRunning) { - *errorMessage = QLatin1String("Internal error: Still running."); - return false; - } - d->device = device; - const QString binary = QLatin1String("rfcomm"); - QStringList arguments; - arguments << QLatin1String("-r") - << (d->mode == Listen ? QLatin1String("listen") : QLatin1String("watch")) - << device << QString(QLatin1Char('1')); - if (debug) - qDebug() << binary << arguments; - emitMessage(tr("%1: Starting Bluetooth listener %2...").arg(device, binary)); - d->pid = 0; - d->process.start(binary, arguments); - if (!d->process.waitForStarted()) { - *errorMessage = tr("Unable to run '%1': %2").arg(binary, d->process.errorString()); - return false; - } - d->pid = processId(d->process); // Forgets it after crash/termination - emitMessage(tr("%1: Bluetooth listener running (%2).").arg(device).arg(processId(d->process))); - return true; -} - -void BluetoothListener::slotStdOutput() -{ - emitMessage(QString::fromLocal8Bit(d->process.readAllStandardOutput())); -} - -void BluetoothListener::emitMessage(const QString &m) -{ - if (d->printConsoleMessages || debug) - qDebug("%s\n", qPrintable(m)); - emit message(m); -} - -void BluetoothListener::slotStdError() -{ - emitMessage(QString::fromLocal8Bit(d->process.readAllStandardError())); -} - -void BluetoothListener::slotProcessFinished(int ex, QProcess::ExitStatus state) -{ - switch (state) { - case QProcess::NormalExit: - emitMessage(tr("%1: Process %2 terminated with exit code %3.") - .arg(d->device).arg(d->pid).arg(ex)); - break; - case QProcess::CrashExit: - emitMessage(tr("%1: Process %2 crashed.").arg(d->device).arg(d->pid)); - break; - } - emit terminated(); -} - -void BluetoothListener::slotProcessError(QProcess::ProcessError error) -{ - emitMessage(tr("%1: Process error %2: %3") - .arg(d->device).arg(error).arg(d->process.errorString())); -} - -} // namespace trk diff --git a/tools/runonphone/trk/bluetoothlistener.h b/tools/runonphone/trk/bluetoothlistener.h deleted file mode 100644 index 36894e7..0000000 --- a/tools/runonphone/trk/bluetoothlistener.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef BLUETOOTHLISTENER_H -#define BLUETOOTHLISTENER_H - -#include "symbianutils_global.h" - -#include -#include - -namespace trk { -struct BluetoothListenerPrivate; - -/* BluetoothListener: Starts a helper process watching connections on a - * Bluetooth device, Linux only: - * The rfcomm command is used. It process can be started in the background - * while connection attempts (TrkDevice::open()) are made in the foreground. */ - -class SYMBIANUTILS_EXPORT BluetoothListener : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(BluetoothListener) -public: - // The Mode property must be set before calling start(). - enum Mode { - Listen, /* Terminate after client closed (read: Trk app - * on the phone terminated or disconnected).*/ - Watch // Keep running, watch for next connection from client - }; - - explicit BluetoothListener(QObject *parent = 0); - virtual ~BluetoothListener(); - - Mode mode() const; - void setMode(Mode m); - - bool start(const QString &device, QString *errorMessage); - - // Print messages on the console. - bool printConsoleMessages() const; - void setPrintConsoleMessages(bool p); - -signals: - void terminated(); - void message(const QString &); - -public slots: - void emitMessage(const QString &m); // accessed by starter - -private slots: - void slotStdOutput(); - void slotStdError(); - void slotProcessFinished(int, QProcess::ExitStatus); - void slotProcessError(QProcess::ProcessError error); - -private: - int terminateProcess(); - - BluetoothListenerPrivate *d; -}; - -} // namespace trk - -#endif // BLUETOOTHLISTENER_H diff --git a/tools/runonphone/trk/bluetoothlistener_gui.cpp b/tools/runonphone/trk/bluetoothlistener_gui.cpp deleted file mode 100644 index 5994eb5..0000000 --- a/tools/runonphone/trk/bluetoothlistener_gui.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "bluetoothlistener_gui.h" -#include "bluetoothlistener.h" -#include "communicationstarter.h" - -#include -#include -#include -#include - -namespace trk { - -SYMBIANUTILS_EXPORT PromptStartCommunicationResult - promptStartCommunication(BaseCommunicationStarter &starter, - const QString &msgBoxTitle, - const QString &msgBoxText, - QWidget *msgBoxParent, - QString *errorMessage) -{ - errorMessage->clear(); - // Initial connection attempt. - switch (starter.start()) { - case BaseCommunicationStarter::Started: - break; - case BaseCommunicationStarter::ConnectionSucceeded: - return PromptStartCommunicationConnected; - case BaseCommunicationStarter::StartError: - *errorMessage = starter.errorString(); - return PromptStartCommunicationError; - } - // Run the starter with the event loop of a message box, have the box - // closed by the signals of the starter. - QMessageBox messageBox(QMessageBox::Information, msgBoxTitle, msgBoxText, QMessageBox::Cancel, msgBoxParent); - QObject::connect(&starter, SIGNAL(connected()), &messageBox, SLOT(close())); - QObject::connect(&starter, SIGNAL(timeout()), &messageBox, SLOT(close())); - messageBox.exec(); - // Only starter.state() is reliable here to obtain the state. - switch (starter.state()) { - case AbstractBluetoothStarter::Running: - *errorMessage = QCoreApplication::translate("trk::promptStartCommunication", "Connection on %1 canceled.").arg(starter.device()); - return PromptStartCommunicationCanceled; - case AbstractBluetoothStarter::TimedOut: - *errorMessage = starter.errorString(); - return PromptStartCommunicationError; - case AbstractBluetoothStarter::Connected: - break; - } - return PromptStartCommunicationConnected; -} - -SYMBIANUTILS_EXPORT PromptStartCommunicationResult - promptStartSerial(BaseCommunicationStarter &starter, - QWidget *msgBoxParent, - QString *errorMessage) -{ - const QString title = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for App TRK"); - const QString message = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for App TRK to start on %1...").arg(starter.device()); - return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage); -} - -SYMBIANUTILS_EXPORT PromptStartCommunicationResult - promptStartBluetooth(BaseCommunicationStarter &starter, - QWidget *msgBoxParent, - QString *errorMessage) -{ - const QString title = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for Bluetooth Connection"); - const QString message = QCoreApplication::translate("trk::promptStartCommunication", "Connecting to %1...").arg(starter.device()); - return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage); -} - -} // namespace trk diff --git a/tools/runonphone/trk/bluetoothlistener_gui.h b/tools/runonphone/trk/bluetoothlistener_gui.h deleted file mode 100644 index 10e7145..0000000 --- a/tools/runonphone/trk/bluetoothlistener_gui.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef BLUETOOTHLISTENER_GUI_H -#define BLUETOOTHLISTENER_GUI_H - -#include "symbianutils_global.h" - -#include - -QT_BEGIN_NAMESPACE -class QWidget; -QT_END_NAMESPACE - -namespace trk { -class BaseCommunicationStarter; - -/* promptStartCommunication(): Convenience functions that - * prompt the user to start a communication (launching or - * connecting TRK) using a modal message box in which they can cancel. - * Pass in the starter with device and parameters set up. */ - -enum PromptStartCommunicationResult { - PromptStartCommunicationConnected, - PromptStartCommunicationCanceled, - PromptStartCommunicationError -}; - -SYMBIANUTILS_EXPORT PromptStartCommunicationResult - promptStartCommunication(BaseCommunicationStarter &starter, - const QString &msgBoxTitle, - const QString &msgBoxText, - QWidget *msgBoxParent, - QString *errorMessage); - -// Convenience to start a serial connection (messages prompting -// to launch Trk). -SYMBIANUTILS_EXPORT PromptStartCommunicationResult - promptStartSerial(BaseCommunicationStarter &starter, - QWidget *msgBoxParent, - QString *errorMessage); - -// Convenience to start blue tooth connection (messages -// prompting to connect). -SYMBIANUTILS_EXPORT PromptStartCommunicationResult - promptStartBluetooth(BaseCommunicationStarter &starter, - QWidget *msgBoxParent, - QString *errorMessage); -} // namespace trk - -#endif // BLUETOOTHLISTENER_GUI_H diff --git a/tools/runonphone/trk/callback.h b/tools/runonphone/trk/callback.h deleted file mode 100644 index 3996d73..0000000 --- a/tools/runonphone/trk/callback.h +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DEBUGGER_CALLBACK_H -#define DEBUGGER_CALLBACK_H - -#include "symbianutils_global.h" - -namespace trk { -namespace Internal { - -/* Helper class for the 1-argument functor: - * Cloneable base class for the implementation which is - * invokeable with the argument. */ -template -class CallbackImplBase -{ - Q_DISABLE_COPY(CallbackImplBase) -public: - CallbackImplBase() {} - virtual CallbackImplBase *clone() const = 0; - virtual void invoke(Argument a) = 0; - virtual ~CallbackImplBase() {} -}; - -/* Helper class for the 1-argument functor: Implementation for - * a class instance with a member function pointer. */ -template -class CallbackMemberPtrImpl : public CallbackImplBase -{ -public: - typedef void (Class::*MemberFuncPtr)(Argument); - - CallbackMemberPtrImpl(Class *instance, - MemberFuncPtr memberFunc) : - m_instance(instance), - m_memberFunc(memberFunc) {} - - virtual CallbackImplBase *clone() const - { - return new CallbackMemberPtrImpl(m_instance, m_memberFunc); - } - - virtual void invoke(Argument a) - { (m_instance->*m_memberFunc)(a); } -private: - Class *m_instance; - MemberFuncPtr m_memberFunc; -}; - -} // namespace Internal - -/* Default-constructible, copyable 1-argument functor providing an - * operator()(Argument) that invokes a member function of a class: - * \code -class Foo { -public: - void print(const std::string &); -}; -... -Foo foo; -Callback f1(&foo, &Foo::print); -f1("test"); -\endcode */ - -template -class Callback -{ -public: - Callback() : m_impl(0) {} - - template - Callback(Class *instance, void (Class::*memberFunc)(Argument)) : - m_impl(new Internal::CallbackMemberPtrImpl(instance, memberFunc)) - {} - - ~Callback() - { - clean(); - } - - Callback(const Callback &rhs) : - m_impl(0) - { - if (rhs.m_impl) - m_impl = rhs.m_impl->clone(); - } - - Callback &operator=(const Callback &rhs) - { - if (this != &rhs) { - clean(); - if (rhs.m_impl) - m_impl = rhs.m_impl->clone(); - } - return *this; - } - - bool isNull() const { return m_impl == 0; } - operator bool() const { return !isNull(); } - - void operator()(Argument a) - { - if (m_impl) - m_impl->invoke(a); - } - -private: - void clean() - { - if (m_impl) { - delete m_impl; - m_impl = 0; - } - } - - Internal::CallbackImplBase *m_impl; -}; - -} // namespace trk - -#endif // DEBUGGER_CALLBACK_H diff --git a/tools/runonphone/trk/communicationstarter.cpp b/tools/runonphone/trk/communicationstarter.cpp deleted file mode 100644 index e5e556e..0000000 --- a/tools/runonphone/trk/communicationstarter.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "communicationstarter.h" -#include "bluetoothlistener.h" -#include "trkdevice.h" - -#include -#include - -namespace trk { - -// --------------- AbstractBluetoothStarter -struct BaseCommunicationStarterPrivate { - explicit BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d); - - const BaseCommunicationStarter::TrkDevicePtr trkDevice; - BluetoothListener *listener; - QTimer *timer; - int intervalMS; - int attempts; - int n; - QString device; - QString errorString; - BaseCommunicationStarter::State state; -}; - -BaseCommunicationStarterPrivate::BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d) : - trkDevice(d), - listener(0), - timer(0), - intervalMS(1000), - attempts(-1), - n(0), - device(QLatin1String("/dev/rfcomm0")), - state(BaseCommunicationStarter::TimedOut) -{ -} - -BaseCommunicationStarter::BaseCommunicationStarter(const TrkDevicePtr &trkDevice, QObject *parent) : - QObject(parent), - d(new BaseCommunicationStarterPrivate(trkDevice)) -{ -} - -BaseCommunicationStarter::~BaseCommunicationStarter() -{ - stopTimer(); - delete d; -} - -void BaseCommunicationStarter::stopTimer() -{ - if (d->timer && d->timer->isActive()) - d->timer->stop(); -} - -bool BaseCommunicationStarter::initializeStartupResources(QString *errorMessage) -{ - errorMessage->clear(); - return true; -} - -BaseCommunicationStarter::StartResult BaseCommunicationStarter::start() -{ - if (state() == Running) { - d->errorString = QLatin1String("Internal error, attempt to re-start BaseCommunicationStarter.\n"); - return StartError; - } - // Before we instantiate timers, and such, try to open the device, - // which should succeed if another listener is already running in - // 'Watch' mode - if (d->trkDevice->open(d->device , &(d->errorString))) - return ConnectionSucceeded; - // Pull up resources for next attempt - d->n = 0; - if (!initializeStartupResources(&(d->errorString))) - return StartError; - // Start timer - if (!d->timer) { - d->timer = new QTimer; - connect(d->timer, SIGNAL(timeout()), this, SLOT(slotTimer())); - } - d->timer->setInterval(d->intervalMS); - d->timer->setSingleShot(false); - d->timer->start(); - d->state = Running; - return Started; -} - -BaseCommunicationStarter::State BaseCommunicationStarter::state() const -{ - return d->state; -} - -int BaseCommunicationStarter::intervalMS() const -{ - return d->intervalMS; -} - -void BaseCommunicationStarter::setIntervalMS(int i) -{ - d->intervalMS = i; - if (d->timer) - d->timer->setInterval(i); -} - -int BaseCommunicationStarter::attempts() const -{ - return d->attempts; -} - -void BaseCommunicationStarter::setAttempts(int a) -{ - d->attempts = a; -} - -QString BaseCommunicationStarter::device() const -{ - return d->device; -} - -void BaseCommunicationStarter::setDevice(const QString &dv) -{ - d->device = dv; -} - -QString BaseCommunicationStarter::errorString() const -{ - return d->errorString; -} - -void BaseCommunicationStarter::slotTimer() -{ - ++d->n; - // Check for timeout - if (d->attempts >= 0 && d->n >= d->attempts) { - stopTimer(); - d->errorString = tr("%1: timed out after %n attempts using an interval of %2ms.", 0, d->n) - .arg(d->device).arg(d->intervalMS); - d->state = TimedOut; - emit timeout(); - } else { - // Attempt n to connect? - if (d->trkDevice->open(d->device , &(d->errorString))) { - stopTimer(); - const QString msg = tr("%1: Connection attempt %2 succeeded.").arg(d->device).arg(d->n); - emit message(msg); - d->state = Connected; - emit connected(); - } else { - const QString msg = tr("%1: Connection attempt %2 failed: %3 (retrying)...") - .arg(d->device).arg(d->n).arg(d->errorString); - emit message(msg); - } - } -} - -// --------------- AbstractBluetoothStarter - -AbstractBluetoothStarter::AbstractBluetoothStarter(const TrkDevicePtr &trkDevice, QObject *parent) : - BaseCommunicationStarter(trkDevice, parent) -{ -} - -bool AbstractBluetoothStarter::initializeStartupResources(QString *errorMessage) -{ - // Create the listener and forward messages to it. - BluetoothListener *listener = createListener(); - connect(this, SIGNAL(message(QString)), listener, SLOT(emitMessage(QString))); - return listener->start(device(), errorMessage); -} - -// -------- ConsoleBluetoothStarter -ConsoleBluetoothStarter::ConsoleBluetoothStarter(const TrkDevicePtr &trkDevice, - QObject *listenerParent, - QObject *parent) : -AbstractBluetoothStarter(trkDevice, parent), -m_listenerParent(listenerParent) -{ -} - -BluetoothListener *ConsoleBluetoothStarter::createListener() -{ - BluetoothListener *rc = new BluetoothListener(m_listenerParent); - rc->setMode(BluetoothListener::Listen); - rc->setPrintConsoleMessages(true); - return rc; -} - -bool ConsoleBluetoothStarter::startBluetooth(const TrkDevicePtr &trkDevice, - QObject *listenerParent, - const QString &device, - int attempts, - QString *errorMessage) -{ - // Set up a console starter to print to stdout. - ConsoleBluetoothStarter starter(trkDevice, listenerParent); - starter.setDevice(device); - starter.setAttempts(attempts); - switch (starter.start()) { - case Started: - break; - case ConnectionSucceeded: - return true; - case StartError: - *errorMessage = starter.errorString(); - return false; - } - // Run the starter with an event loop. @ToDo: Implement - // some asynchronous keypress read to cancel. - QEventLoop eventLoop; - connect(&starter, SIGNAL(connected()), &eventLoop, SLOT(quit())); - connect(&starter, SIGNAL(timeout()), &eventLoop, SLOT(quit())); - eventLoop.exec(QEventLoop::ExcludeUserInputEvents); - if (starter.state() != AbstractBluetoothStarter::Connected) { - *errorMessage = starter.errorString(); - return false; - } - return true; -} -} // namespace trk diff --git a/tools/runonphone/trk/communicationstarter.h b/tools/runonphone/trk/communicationstarter.h deleted file mode 100644 index 2d7dc50..0000000 --- a/tools/runonphone/trk/communicationstarter.h +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef COMMUNICATIONSTARTER_H -#define COMMUNICATIONSTARTER_H - -#include "symbianutils_global.h" - -#include -#include - -namespace trk { -class TrkDevice; -class BluetoothListener; -struct BaseCommunicationStarterPrivate; - -/* BaseCommunicationStarter: A QObject that repeatedly tries to open a - * trk device until a connection succeeds or a timeout occurs (emitting - * signals), allowing to do something else in the foreground (local event loop - * [say QMessageBox] or some asynchronous operation). If the initial - * connection attempt in start() fails, the - * virtual initializeStartupResources() is called to initialize resources - * required to pull up the communication (namely Bluetooth listeners). - * The base class can be used as is to prompt the user to launch App TRK for a - * serial communication as this requires no further resource setup. */ - -class SYMBIANUTILS_EXPORT BaseCommunicationStarter : public QObject { - Q_OBJECT - Q_DISABLE_COPY(BaseCommunicationStarter) -public: - typedef QSharedPointer TrkDevicePtr; - - enum State { Running, Connected, TimedOut }; - - explicit BaseCommunicationStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); - virtual ~BaseCommunicationStarter(); - - int intervalMS() const; - void setIntervalMS(int i); - - int attempts() const; - void setAttempts(int a); - - QString device() const; - void setDevice(const QString &); - - State state() const; - QString errorString() const; - - enum StartResult { - Started, // Starter is now running. - ConnectionSucceeded, /* Initial connection attempt succeeded, - * no need to keep running. */ - StartError // Error occurred during start. - }; - - StartResult start(); - -signals: - void connected(); - void timeout(); - void message(const QString &); - -private slots: - void slotTimer(); - -protected: - virtual bool initializeStartupResources(QString *errorMessage); - -private: - inline void stopTimer(); - - BaseCommunicationStarterPrivate *d; -}; - -/* AbstractBluetoothStarter: Repeatedly tries to open a trk Bluetooth - * device. Note that in case a Listener is already running mode, the - * connection will succeed immediately. - * initializeStartupResources() is implemented to fire up the listener. - * Introduces a new virtual createListener() that derived classes must - * implement as a factory function that creates and sets up the - * listener (mode, message connection, etc). */ - -class SYMBIANUTILS_EXPORT AbstractBluetoothStarter : public BaseCommunicationStarter { - Q_OBJECT - Q_DISABLE_COPY(AbstractBluetoothStarter) -public: - -protected: - explicit AbstractBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); - - // Implemented to fire up the listener. - virtual bool initializeStartupResources(QString *errorMessage); - // New virtual: Overwrite to create and parametrize the listener. - virtual BluetoothListener *createListener() = 0; -}; - -/* ConsoleBluetoothStarter: Convenience class for console processes. Creates a - * listener in "Listen" mode with the messages redirected to standard output. */ - -class SYMBIANUTILS_EXPORT ConsoleBluetoothStarter : public AbstractBluetoothStarter { - Q_OBJECT - Q_DISABLE_COPY(ConsoleBluetoothStarter) -public: - static bool startBluetooth(const TrkDevicePtr& trkDevice, - QObject *listenerParent, - const QString &device, - int attempts, - QString *errorMessage); - -protected: - virtual BluetoothListener *createListener(); - -private: - explicit ConsoleBluetoothStarter(const TrkDevicePtr& trkDevice, - QObject *listenerParent, - QObject *parent = 0); - - QObject *m_listenerParent; -}; - -} // namespace trk - -#endif // COMMUNICATIONSTARTER_H diff --git a/tools/runonphone/trk/launcher.cpp b/tools/runonphone/trk/launcher.cpp deleted file mode 100644 index 4f91545..0000000 --- a/tools/runonphone/trk/launcher.cpp +++ /dev/null @@ -1,741 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "launcher.h" -#include "trkutils.h" -#include "trkutils_p.h" -#include "trkdevice.h" -#include "bluetoothlistener.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace trk { - -struct LauncherPrivate { - struct CopyState { - QString sourceFileName; - QString destinationFileName; - uint copyFileHandle; - QScopedPointer data; - int position; - }; - - explicit LauncherPrivate(const TrkDevicePtr &d); - - TrkDevicePtr m_device; - QString m_trkServerName; - QByteArray m_trkReadBuffer; - Launcher::State m_state; - - void logMessage(const QString &msg); - // Debuggee state - Session m_session; // global-ish data (process id, target information) - - CopyState m_copyState; - QString m_fileName; - QStringList m_commandLineArgs; - QString m_installFileName; - int m_verbose; - Launcher::Actions m_startupActions; - bool m_closeDevice; -}; - -LauncherPrivate::LauncherPrivate(const TrkDevicePtr &d) : - m_device(d), - m_state(Launcher::Disconnected), - m_verbose(0), - m_closeDevice(true) -{ - if (m_device.isNull()) - m_device = TrkDevicePtr(new TrkDevice); -} - -Launcher::Launcher(Actions startupActions, - const TrkDevicePtr &dev, - QObject *parent) : - QObject(parent), - d(new LauncherPrivate(dev)) -{ - d->m_startupActions = startupActions; - connect(d->m_device.data(), SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleResult(trk::TrkResult))); - connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close())); -} - -Launcher::~Launcher() -{ - logMessage("Shutting down.\n"); - delete d; -} - -Launcher::State Launcher::state() const -{ - return d->m_state; -} - -void Launcher::setState(State s) -{ - if (s != d->m_state) { - d->m_state = s; - emit stateChanged(s); - } -} - -void Launcher::addStartupActions(trk::Launcher::Actions startupActions) -{ - d->m_startupActions = Actions(d->m_startupActions | startupActions); -} - -void Launcher::setTrkServerName(const QString &name) -{ - d->m_trkServerName = name; -} - -QString Launcher::trkServerName() const -{ - return d->m_trkServerName; -} - -TrkDevicePtr Launcher::trkDevice() const -{ - return d->m_device; -} - -void Launcher::setFileName(const QString &name) -{ - d->m_fileName = name; -} - -void Launcher::setCopyFileName(const QString &srcName, const QString &dstName) -{ - d->m_copyState.sourceFileName = srcName; - d->m_copyState.destinationFileName = dstName; -} - -void Launcher::setInstallFileName(const QString &name) -{ - d->m_installFileName = name; -} - -void Launcher::setCommandLineArgs(const QStringList &args) -{ - d->m_commandLineArgs = args; -} - -void Launcher::setSerialFrame(bool b) -{ - d->m_device->setSerialFrame(b); -} - -bool Launcher::serialFrame() const -{ - return d->m_device->serialFrame(); -} - - -bool Launcher::closeDevice() const -{ - return d->m_closeDevice; -} - -void Launcher::setCloseDevice(bool c) -{ - d->m_closeDevice = c; -} - -bool Launcher::startServer(QString *errorMessage) -{ - errorMessage->clear(); - if (d->m_verbose) { - const QString msg = QString::fromLatin1("Port=%1 Executable=%2 Arguments=%3 Package=%4 Remote Package=%5 Install file=%6") - .arg(d->m_trkServerName, d->m_fileName, - d->m_commandLineArgs.join(QString(QLatin1Char(' '))), - d->m_copyState.sourceFileName, d->m_copyState.destinationFileName, d->m_installFileName); - logMessage(msg); - } - if (d->m_startupActions & ActionCopy) { - if (d->m_copyState.sourceFileName.isEmpty()) { - qWarning("No local filename given for copying package."); - return false; - } else if (d->m_copyState.destinationFileName.isEmpty()) { - qWarning("No remote filename given for copying package."); - return false; - } - } - if (d->m_startupActions & ActionInstall && d->m_installFileName.isEmpty()) { - qWarning("No package name given for installing."); - return false; - } - if (d->m_startupActions & ActionRun && d->m_fileName.isEmpty()) { - qWarning("No remote executable given for running."); - return false; - } - if (!d->m_device->isOpen() && !d->m_device->open(d->m_trkServerName, errorMessage)) - return false; - if (d->m_closeDevice) { - connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close())); - } else { - disconnect(this, SIGNAL(finished()), d->m_device.data(), 0); - } - setState(Connecting); - // Set up the temporary 'waiting' state if we do not get immediate connection - QTimer::singleShot(1000, this, SLOT(slotWaitingForTrk())); - d->m_device->sendTrkInitialPing(); - d->m_device->sendTrkMessage(TrkDisconnect); // Disconnect, as trk might be still connected - d->m_device->sendTrkMessage(TrkSupported, TrkCallback(this, &Launcher::handleSupportMask)); - d->m_device->sendTrkMessage(TrkCpuType, TrkCallback(this, &Launcher::handleCpuType)); - d->m_device->sendTrkMessage(TrkVersions, TrkCallback(this, &Launcher::handleTrkVersion)); - if (d->m_startupActions != ActionPingOnly) - d->m_device->sendTrkMessage(TrkConnect, TrkCallback(this, &Launcher::handleConnect)); - return true; -} - -void Launcher::slotWaitingForTrk() -{ - // Set temporary state if we are still in connected state - if (state() == Connecting) - setState(WaitingForTrk); -} - -void Launcher::handleConnect(const TrkResult &result) -{ - if (result.errorCode()) { - emit canNotConnect(result.errorString()); - return; - } - setState(Connected); - if (d->m_startupActions & ActionCopy) - copyFileToRemote(); - else if (d->m_startupActions & ActionInstall) - installRemotePackageSilently(); - else if (d->m_startupActions & ActionRun) - startInferiorIfNeeded(); -} - -void Launcher::setVerbose(int v) -{ - d->m_verbose = v; - d->m_device->setVerbose(v); -} - -void Launcher::logMessage(const QString &msg) -{ - if (d->m_verbose) - qDebug() << "LAUNCHER: " << qPrintable(msg); -} - -void Launcher::terminate() -{ - switch (state()) { - case DeviceDescriptionReceived: - case Connected: - if (d->m_session.pid) { - QByteArray ba; - appendShort(&ba, 0x0000, TargetByteOrder); - appendInt(&ba, d->m_session.pid, TargetByteOrder); - d->m_device->sendTrkMessage(TrkDeleteItem, TrkCallback(this, &Launcher::handleRemoteProcessKilled), ba); - return; - } - if (d->m_copyState.copyFileHandle) - closeRemoteFile(true); - disconnectTrk(); - break; - case Disconnected: - break; - case Connecting: - case WaitingForTrk: - setState(Disconnected); - emit finished(); - break; - } -} - -void Launcher::handleRemoteProcessKilled(const TrkResult &result) -{ - Q_UNUSED(result) - disconnectTrk(); -} - -QString Launcher::msgStopped(uint pid, uint tid, uint address, const QString &why) -{ - return QString::fromLatin1("Process %1, thread %2 stopped at 0x%3: %4"). - arg(pid).arg(tid).arg(address, 0, 16). - arg(why.isEmpty() ? QString::fromLatin1("") : why); -} - -bool Launcher::parseNotifyStopped(const QByteArray &dataBA, - uint *pid, uint *tid, uint *address, - QString *why /* = 0 */) -{ - if (why) - why->clear(); - *address = *pid = *tid = 0; - if (dataBA.size() < 12) - return false; - const char *data = dataBA.data(); - *address = extractInt(data); - *pid = extractInt(data + 4); - *tid = extractInt(data + 8); - if (why && dataBA.size() >= 14) { - const unsigned short len = extractShort(data + 12); - if (len > 0) - *why = QString::fromLatin1(data + 14, len); - } - return true; -} - -void Launcher::handleResult(const TrkResult &result) -{ - QByteArray prefix = "READ BUF: "; - QByteArray str = result.toString().toUtf8(); - if (result.isDebugOutput) { // handle application output - logMessage("APPLICATION OUTPUT: " + result.data); - emit applicationOutputReceived(result.data); - return; - } - switch (result.code) { - case TrkNotifyAck: - break; - case TrkNotifyNak: { // NAK - logMessage(prefix + "NAK: " + str); - //logMessage(prefix << "TOKEN: " << result.token); - logMessage(prefix + "ERROR: " + errorMessage(result.data.at(0))); - break; - } - case TrkNotifyStopped: { // Notified Stopped - QString reason; - uint pc; - uint pid; - uint tid; - parseNotifyStopped(result.data, &pid, &tid, &pc, &reason); - logMessage(prefix + msgStopped(pid, tid, pc, reason)); - emit(processStopped(pc, pid, tid, reason)); - d->m_device->sendTrkAck(result.token); - break; - } - case TrkNotifyException: { // Notify Exception (obsolete) - logMessage(prefix + "NOTE: EXCEPTION " + str); - d->m_device->sendTrkAck(result.token); - break; - } - case TrkNotifyInternalError: { // - logMessage(prefix + "NOTE: INTERNAL ERROR: " + str); - d->m_device->sendTrkAck(result.token); - break; - } - - // target->host OS notification - case TrkNotifyCreated: { // Notify Created - /* - const char *data = result.data.data(); - byte error = result.data.at(0); - byte type = result.data.at(1); // type: 1 byte; for dll item, this value is 2. - uint pid = extractInt(data + 2); // ProcessID: 4 bytes; - uint tid = extractInt(data + 6); //threadID: 4 bytes - uint codeseg = extractInt(data + 10); //code address: 4 bytes; code base address for the library - uint dataseg = extractInt(data + 14); //data address: 4 bytes; data base address for the library - uint len = extractShort(data + 18); //length: 2 bytes; length of the library name string to follow - QByteArray name = result.data.mid(20, len); // name: library name - - logMessage(prefix + "NOTE: LIBRARY LOAD: " + str); - logMessage(prefix + "TOKEN: " + result.token); - logMessage(prefix + "ERROR: " + int(error)); - logMessage(prefix + "TYPE: " + int(type)); - logMessage(prefix + "PID: " + pid); - logMessage(prefix + "TID: " + tid); - logMessage(prefix + "CODE: " + codeseg); - logMessage(prefix + "DATA: " + dataseg); - logMessage(prefix + "LEN: " + len); - logMessage(prefix + "NAME: " + name); - */ - - if (result.data.size() < 10) - break; - QByteArray ba; - ba.append(result.data.mid(2, 8)); - d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); - //d->m_device->sendTrkAck(result.token) - break; - } - case TrkNotifyDeleted: { // NotifyDeleted - const ushort itemType = (unsigned char)result.data.at(1); - const ushort len = result.data.size() > 12 ? extractShort(result.data.data() + 10) : ushort(0); - const QString name = len ? QString::fromAscii(result.data.mid(12, len)) : QString(); - logMessage(QString::fromLatin1("%1 %2 UNLOAD: %3"). - arg(QString::fromAscii(prefix)).arg(itemType ? QLatin1String("LIB") : QLatin1String("PROCESS")). - arg(name)); - d->m_device->sendTrkAck(result.token); - if (itemType == 0 // process - && result.data.size() >= 10 - && d->m_session.pid == extractInt(result.data.data() + 6)) { - disconnectTrk(); - } - break; - } - case TrkNotifyProcessorStarted: { // NotifyProcessorStarted - logMessage(prefix + "NOTE: PROCESSOR STARTED: " + str); - d->m_device->sendTrkAck(result.token); - break; - } - case TrkNotifyProcessorStandBy: { // NotifyProcessorStandby - logMessage(prefix + "NOTE: PROCESSOR STANDBY: " + str); - d->m_device->sendTrkAck(result.token); - break; - } - case TrkNotifyProcessorReset: { // NotifyProcessorReset - logMessage(prefix + "NOTE: PROCESSOR RESET: " + str); - d->m_device->sendTrkAck(result.token); - break; - } - default: { - logMessage(prefix + "INVALID: " + str); - break; - } - } -} - -QString Launcher::deviceDescription(unsigned verbose) const -{ - return d->m_session.deviceDescription(verbose); -} - -void Launcher::handleTrkVersion(const TrkResult &result) -{ - if (result.errorCode() || result.data.size() < 5) { - if (d->m_startupActions == ActionPingOnly) { - setState(Disconnected); - emit finished(); - } - return; - } - d->m_session.trkAppVersion.trkMajor = result.data.at(1); - d->m_session.trkAppVersion.trkMinor = result.data.at(2); - d->m_session.trkAppVersion.protocolMajor = result.data.at(3); - d->m_session.trkAppVersion.protocolMinor = result.data.at(4); - setState(DeviceDescriptionReceived); - // Ping mode: Log & Terminate - if (d->m_startupActions == ActionPingOnly) { - qWarning("%s", qPrintable(deviceDescription())); - setState(Disconnected); - emit finished(); - } -} - -void Launcher::handleFileCreation(const TrkResult &result) -{ - if (result.errorCode() || result.data.size() < 6) { - emit canNotCreateFile(d->m_copyState.destinationFileName, result.errorString()); - disconnectTrk(); - return; - } - const char *data = result.data.data(); - d->m_copyState.copyFileHandle = extractInt(data + 2); - QFile file(d->m_copyState.sourceFileName); - file.open(QIODevice::ReadOnly); - d->m_copyState.data.reset(new QByteArray(file.readAll())); - d->m_copyState.position = 0; - file.close(); - continueCopying(); -} - -void Launcher::handleCopy(const TrkResult &result) -{ - if (result.errorCode() || result.data.size() < 4) { - closeRemoteFile(true); - emit canNotWriteFile(d->m_copyState.destinationFileName, result.errorString()); - disconnectTrk(); - } else { - continueCopying(extractShort(result.data.data() + 2)); - } -} - -void Launcher::continueCopying(uint lastCopiedBlockSize) -{ - int size = d->m_copyState.data->length(); - d->m_copyState.position += lastCopiedBlockSize; - if (size == 0) - emit copyProgress(100); - else { - int percent = qMin((d->m_copyState.position*100)/size, 100); - emit copyProgress(percent); - } - if (d->m_copyState.position < size) { - QByteArray ba; - appendInt(&ba, d->m_copyState.copyFileHandle, TargetByteOrder); - appendString(&ba, d->m_copyState.data->mid(d->m_copyState.position, 2048), TargetByteOrder, false); - d->m_device->sendTrkMessage(TrkWriteFile, TrkCallback(this, &Launcher::handleCopy), ba); - } else { - closeRemoteFile(); - } -} - -void Launcher::closeRemoteFile(bool failed) -{ - QByteArray ba; - appendInt(&ba, d->m_copyState.copyFileHandle, TargetByteOrder); - appendDateTime(&ba, QDateTime::currentDateTime(), TargetByteOrder); - d->m_device->sendTrkMessage(TrkCloseFile, - failed ? TrkCallback() : TrkCallback(this, &Launcher::handleFileCopied), - ba); - d->m_copyState.data.reset(); - d->m_copyState.copyFileHandle = 0; - d->m_copyState.position = 0; -} - -void Launcher::handleFileCopied(const TrkResult &result) -{ - if (result.errorCode()) - emit canNotCloseFile(d->m_copyState.destinationFileName, result.errorString()); - if (d->m_startupActions & ActionInstall) - installRemotePackageSilently(); - else if (d->m_startupActions & ActionRun) - startInferiorIfNeeded(); - else - disconnectTrk(); -} - -void Launcher::handleCpuType(const TrkResult &result) -{ - logMessage("HANDLE CPU TYPE: " + result.toString()); - if(result.errorCode() || result.data.size() < 7) - return; - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 03 00 04 00 00 04 00 00 00] - d->m_session.cpuMajor = result.data.at(1); - d->m_session.cpuMinor = result.data.at(2); - d->m_session.bigEndian = result.data.at(3); - d->m_session.defaultTypeSize = result.data.at(4); - d->m_session.fpTypeSize = result.data.at(5); - d->m_session.extended1TypeSize = result.data.at(6); - //d->m_session.extended2TypeSize = result.data[6]; -} - -void Launcher::handleCreateProcess(const TrkResult &result) -{ - if (result.errorCode()) { - emit canNotRun(result.errorString()); - disconnectTrk(); - return; - } - // 40 00 00] - //logMessage(" RESULT: " + result.toString()); - // [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 40 00 00] - const char *data = result.data.data(); - d->m_session.pid = extractInt(data + 1); - d->m_session.tid = extractInt(data + 5); - d->m_session.codeseg = extractInt(data + 9); - d->m_session.dataseg = extractInt(data + 13); - if (d->m_verbose) { - const QString msg = QString::fromLatin1("Process id: %1 Thread id: %2 code: 0x%3 data: 0x%4"). - arg(d->m_session.pid).arg(d->m_session.tid).arg(d->m_session.codeseg, 0, 16). - arg(d->m_session.dataseg, 0 ,16); - logMessage(msg); - } - emit applicationRunning(d->m_session.pid); - QByteArray ba; - appendInt(&ba, d->m_session.pid); - appendInt(&ba, d->m_session.tid); - d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); -} - -void Launcher::handleWaitForFinished(const TrkResult &result) -{ - logMessage(" FINISHED: " + stringFromArray(result.data)); - setState(Disconnected); - emit finished(); -} - -void Launcher::handleSupportMask(const TrkResult &result) -{ - if (result.errorCode() || result.data.size() < 32) - return; - const char *data = result.data.data() + 1; - - QString str = QLatin1String("SUPPORTED: "); - for (int i = 0; i < 32; ++i) { - //str.append(" [" + formatByte(data[i]) + "]: "); - for (int j = 0; j < 8; ++j) { - if (data[i] & (1 << j)) { - str.append(QString::number(i * 8 + j, 16)); - str.append(QLatin1Char(' ')); - } - } - } - logMessage(str); -} - -void Launcher::cleanUp() -{ - // - //---IDE------------------------------------------------------ - // Command: 0x41 Delete Item - // Sub Cmd: Delete Process - //ProcessID: 0x0000071F (1823) - // [41 24 00 00 00 00 07 1F] - QByteArray ba(2, char(0)); - appendInt(&ba, d->m_session.pid); - d->m_device->sendTrkMessage(TrkDeleteItem, TrkCallback(), ba, "Delete process"); - - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 24 00] - - //---IDE------------------------------------------------------ - // Command: 0x1C Clear Break - // [1C 25 00 00 00 0A 78 6A 43 40] - - //---TRK------------------------------------------------------ - // Command: 0xA1 Notify Deleted - // [A1 09 00 00 00 00 00 00 00 00 07 1F] - //---IDE------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 09 00] - - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 25 00] - - //---IDE------------------------------------------------------ - // Command: 0x1C Clear Break - // [1C 26 00 00 00 0B 78 6A 43 70] - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 26 00] - - - //---IDE------------------------------------------------------ - // Command: 0x02 Disconnect - // [02 27] -// sendTrkMessage(0x02, TrkCallback(this, &Launcher::handleDisconnect)); - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 -} - -void Launcher::disconnectTrk() -{ - d->m_device->sendTrkMessage(TrkDisconnect, TrkCallback(this, &Launcher::handleWaitForFinished)); -} - -void Launcher::copyFileToRemote() -{ - emit copyingStarted(); - QByteArray ba; - ba.append(char(10)); - appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false); - d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba); -} - -void Launcher::installRemotePackageSilently() -{ - emit installingStarted(); - QByteArray ba; - ba.append('C'); - appendString(&ba, d->m_installFileName.toLocal8Bit(), TargetByteOrder, false); - d->m_device->sendTrkMessage(TrkInstallFile, TrkCallback(this, &Launcher::handleInstallPackageFinished), ba); -} - -void Launcher::handleInstallPackageFinished(const TrkResult &result) -{ - if (result.errorCode()) { - emit canNotInstall(d->m_installFileName, result.errorString()); - disconnectTrk(); - return; - } else { - emit installingFinished(); - } - if (d->m_startupActions & ActionRun) { - startInferiorIfNeeded(); - } else { - disconnectTrk(); - } -} - -QByteArray Launcher::startProcessMessage(const QString &executable, - const QStringList &arguments) -{ - // It's not started yet - QByteArray ba; - appendShort(&ba, 0, TargetByteOrder); // create new process - ba.append(char(0)); // options - currently unused - if(arguments.isEmpty()) { - appendString(&ba, executable.toLocal8Bit(), TargetByteOrder); - return ba; - } - // Append full command line as one string (leading length information). - QByteArray commandLineBa; - commandLineBa.append(executable.toLocal8Bit()); - commandLineBa.append('\0'); - commandLineBa.append(arguments.join(QString(QLatin1Char(' '))).toLocal8Bit()); - appendString(&ba, commandLineBa, TargetByteOrder); - return ba; -} - -void Launcher::startInferiorIfNeeded() -{ - emit startingApplication(); - if (d->m_session.pid != 0) { - logMessage("Process already 'started'"); - return; - } - d->m_device->sendTrkMessage(TrkCreateItem, TrkCallback(this, &Launcher::handleCreateProcess), - startProcessMessage(d->m_fileName, d->m_commandLineArgs)); // Create Item -} - -void Launcher::resumeProcess(uint pid, uint tid) -{ - QByteArray ba; - appendInt(&ba, pid, BigEndian); - appendInt(&ba, tid, BigEndian); - d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); -} -} // namespace trk diff --git a/tools/runonphone/trk/launcher.h b/tools/runonphone/trk/launcher.h deleted file mode 100644 index 2b23fd8..0000000 --- a/tools/runonphone/trk/launcher.h +++ /dev/null @@ -1,179 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef LAUNCHER_H -#define LAUNCHER_H - -#include "trkdevice.h" - -#include -#include -#include - -namespace trk { - -struct TrkResult; -struct TrkMessage; -struct LauncherPrivate; - -typedef QSharedPointer TrkDevicePtr; - -class SYMBIANUTILS_EXPORT Launcher : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(Launcher) -public: - typedef void (Launcher::*TrkCallBack)(const TrkResult &); - - enum Actions { - ActionPingOnly = 0x0, - ActionCopy = 0x1, - ActionInstall = 0x2, - ActionCopyInstall = ActionCopy | ActionInstall, - ActionRun = 0x4, - ActionCopyRun = ActionCopy | ActionRun, - ActionInstallRun = ActionInstall | ActionRun, - ActionCopyInstallRun = ActionCopy | ActionInstall | ActionRun - }; - - enum State { Disconnected, Connecting, Connected, - WaitingForTrk, // This occurs only if the initial ping times out after - // a reasonable timeout, indicating that Trk is not - // running. Note that this will never happen with - // Bluetooth as communication immediately starts - // after connecting. - DeviceDescriptionReceived }; - - explicit Launcher(trk::Launcher::Actions startupActions = trk::Launcher::ActionPingOnly, - const TrkDevicePtr &trkDevice = TrkDevicePtr(), - QObject *parent = 0); - ~Launcher(); - - State state() const; - - void addStartupActions(trk::Launcher::Actions startupActions); - void setTrkServerName(const QString &name); - QString trkServerName() const; - void setFileName(const QString &name); - void setCopyFileName(const QString &srcName, const QString &dstName); - void setInstallFileName(const QString &name); - void setCommandLineArgs(const QStringList &args); - bool startServer(QString *errorMessage); - void setVerbose(int v); - void setSerialFrame(bool b); - bool serialFrame() const; - // Close device or leave it open - bool closeDevice() const; - void setCloseDevice(bool c); - - TrkDevicePtr trkDevice() const; - - // becomes valid after successful execution of ActionPingOnly - QString deviceDescription(unsigned verbose = 0u) const; - - static QByteArray startProcessMessage(const QString &executable, - const QStringList &arguments); - // Parse a TrkNotifyStopped message - static bool parseNotifyStopped(const QByteArray &a, - uint *pid, uint *tid, uint *address, - QString *why = 0); - // Helper message - static QString msgStopped(uint pid, uint tid, uint address, const QString &why); - -signals: - void copyingStarted(); - void canNotConnect(const QString &errorMessage); - void canNotCreateFile(const QString &filename, const QString &errorMessage); - void canNotWriteFile(const QString &filename, const QString &errorMessage); - void canNotCloseFile(const QString &filename, const QString &errorMessage); - void installingStarted(); - void canNotInstall(const QString &packageFilename, const QString &errorMessage); - void installingFinished(); - void startingApplication(); - void applicationRunning(uint pid); - void canNotRun(const QString &errorMessage); - void finished(); - void applicationOutputReceived(const QString &output); - void copyProgress(int percent); - void stateChanged(int); - void processStopped(uint pc, uint pid, uint tid, const QString& reason); - -public slots: - void terminate(); - void resumeProcess(uint pid, uint tid); - -private slots: - void handleResult(const trk::TrkResult &data); - void slotWaitingForTrk(); - -private: - // kill process and breakpoints - void cleanUp(); - void disconnectTrk(); - - void handleRemoteProcessKilled(const TrkResult &result); - void handleConnect(const TrkResult &result); - void handleFileCreation(const TrkResult &result); - void handleCopy(const TrkResult &result); - void continueCopying(uint lastCopiedBlockSize = 0); - void closeRemoteFile(bool failed = false); - void handleFileCopied(const TrkResult &result); - void handleInstallPackageFinished(const TrkResult &result); - void handleCpuType(const TrkResult &result); - void handleCreateProcess(const TrkResult &result); - void handleWaitForFinished(const TrkResult &result); - void handleStop(const TrkResult &result); - void handleSupportMask(const TrkResult &result); - void handleTrkVersion(const TrkResult &result); - - void copyFileToRemote(); - void installRemotePackageSilently(); - void startInferiorIfNeeded(); - - void logMessage(const QString &msg); - void setState(State s); - - LauncherPrivate *d; -}; - -} // namespace Trk - -#endif // LAUNCHER_H diff --git a/tools/runonphone/trk/symbianutils_global.h b/tools/runonphone/trk/symbianutils_global.h deleted file mode 100644 index a6ffbe7..0000000 --- a/tools/runonphone/trk/symbianutils_global.h +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SYMBIANUTILS_GLOBAL_H -#define SYMBIANUTILS_GLOBAL_H - -#include - -#if defined(SYMBIANUTILS_BUILD_LIB) -# define SYMBIANUTILS_EXPORT Q_DECL_EXPORT -#elif defined(SYMBIANUTILS_BUILD_STATIC_LIB) || defined(SYMBIANUTILS_INCLUDE_PRI) -# define SYMBIANUTILS_EXPORT -#else -# define SYMBIANUTILS_EXPORT Q_DECL_IMPORT -#endif - -#endif // SYMBIANUTILS_GLOBAL_H diff --git a/tools/runonphone/trk/trk.pri b/tools/runonphone/trk/trk.pri deleted file mode 100644 index a54df76..0000000 --- a/tools/runonphone/trk/trk.pri +++ /dev/null @@ -1,25 +0,0 @@ -INCLUDEPATH *= $$PWD - -# Input -HEADERS += $$PWD/symbianutils_global.h \ - $$PWD/callback.h \ - $$PWD/trkutils.h \ - $$PWD/trkutils_p.h \ - $$PWD/trkdevice.h \ - $$PWD/launcher.h \ - $$PWD/bluetoothlistener.h \ - $$PWD/communicationstarter.h - -SOURCES += $$PWD/trkutils.cpp \ - $$PWD/trkdevice.cpp \ - $$PWD/launcher.cpp \ - $$PWD/bluetoothlistener.cpp \ - $$PWD/communicationstarter.cpp - -# Tests/trklauncher is a console application -contains(QT, gui) { - HEADERS += $$PWD/bluetoothlistener_gui.h - SOURCES += $$PWD/bluetoothlistener_gui.cpp -} else { - message(Trk: Console ...) -} diff --git a/tools/runonphone/trk/trkdevice.cpp b/tools/runonphone/trk/trkdevice.cpp deleted file mode 100644 index d587135..0000000 --- a/tools/runonphone/trk/trkdevice.cpp +++ /dev/null @@ -1,1105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "trkdevice.h" -#include "trkutils.h" -#include "trkutils_p.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef Q_OS_WIN -# include -#else -# include - -# include -# include -# include -# include -# include -# include -# include -/* Required headers for select() according to POSIX.1-2001 */ -# include -/* Required headers for select() according to earlier standards: - #include - #include - #include -*/ -#endif - -#ifdef Q_OS_WIN - -// Format windows error from GetLastError() value: -// TODO: Use the one provided by the utils lib. -QString winErrorMessage(unsigned long error) -{ - QString rc = QString::fromLatin1("#%1: ").arg(error); - ushort *lpMsgBuf; - - const int len = FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER - | FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, error, 0, (LPTSTR)&lpMsgBuf, 0, NULL); - if (len) { - rc = QString::fromUtf16(lpMsgBuf, len); - LocalFree(lpMsgBuf); - } else { - rc += QString::fromLatin1(""); - } - return rc; -} - -#endif - -enum { verboseTrk = 0 }; - -namespace trk { - -/////////////////////////////////////////////////////////////////////// -// -// TrkMessage -// -/////////////////////////////////////////////////////////////////////// - -/* A message to be send to TRK, triggering a callback on receipt - * of the answer. */ -struct TrkMessage -{ - explicit TrkMessage(byte code = 0u, byte token = 0u, - TrkCallback callback = TrkCallback()); - - byte code; - byte token; - QByteArray data; - QVariant cookie; - TrkCallback callback; -}; - -TrkMessage::TrkMessage(byte c, byte t, TrkCallback cb) : - code(c), - token(t), - callback(cb) -{ -} - -QDebug operator<<(QDebug d, const TrkMessage &msg) -{ - return d << "Message: Code: " << msg.code - << " Token: " << msg.token << " " << msg.data.toHex(); -} - -} // namespace trk - -Q_DECLARE_METATYPE(trk::TrkMessage) -Q_DECLARE_METATYPE(trk::TrkResult) - -namespace trk { - -/////////////////////////////////////////////////////////////////////// -// -// TrkWriteQueue: Mixin class that manages a write queue of Trk messages. -// pendingMessage()/notifyWriteResult() should be called from a worked/timer -// that writes the messages. The class does not take precautions for multithreading. -// A no-op message is simply taken off the queue. The calling class -// can use the helper invokeNoopMessage() to trigger its callback. -// -/////////////////////////////////////////////////////////////////////// - -class TrkWriteQueue -{ - Q_DISABLE_COPY(TrkWriteQueue) -public: - explicit TrkWriteQueue(); - - // Enqueue messages. - void queueTrkMessage(byte code, TrkCallback callback, - const QByteArray &data, const QVariant &cookie); - void queueTrkInitialPing(); - - // Call this from the device read notification with the results. - void slotHandleResult(const TrkResult &result, QMutex *mutex = 0); - - // pendingMessage() can be called periodically in a timer to retrieve - // the pending messages to be sent. - enum PendingMessageResult { - NoMessage, // No message in queue. - PendingMessage, /* There is a queued message. The calling class - * can write it out and use notifyWriteResult() - * to notify about the result. */ - NoopMessageDequeued // A no-op message has been dequeued. see invokeNoopMessage(). - }; - - PendingMessageResult pendingMessage(TrkMessage *message); - // Notify the queue about the success of the write operation - // after taking the pendingMessage off. - enum WriteResult { - WriteOk, - WriteFailedDiscard, // Discard failed message - WriteFailedKeep, // Keep failed message - }; - void notifyWriteResult(WriteResult ok); - - // Helper function that invokes the callback of a no-op message - static void invokeNoopMessage(trk::TrkMessage); - -private: - typedef QMap TokenMessageMap; - - byte nextTrkWriteToken(); - - byte m_trkWriteToken; - QQueue m_trkWriteQueue; - TokenMessageMap m_writtenTrkMessages; - bool m_trkWriteBusy; -}; - -TrkWriteQueue::TrkWriteQueue() : - m_trkWriteToken(0), - m_trkWriteBusy(false) -{ -} - -byte TrkWriteQueue::nextTrkWriteToken() -{ - ++m_trkWriteToken; - if (m_trkWriteToken == 0) - ++m_trkWriteToken; - if (verboseTrk) - qDebug() << "Write token: " << m_trkWriteToken; - return m_trkWriteToken; -} - -void TrkWriteQueue::queueTrkMessage(byte code, TrkCallback callback, - const QByteArray &data, const QVariant &cookie) -{ - const byte token = code == TRK_WRITE_QUEUE_NOOP_CODE ? - byte(0) : nextTrkWriteToken(); - TrkMessage msg(code, token, callback); - msg.data = data; - msg.cookie = cookie; - m_trkWriteQueue.append(msg); -} - -TrkWriteQueue::PendingMessageResult TrkWriteQueue::pendingMessage(TrkMessage *message) -{ - // Invoked from timer, try to flush out message queue - if (m_trkWriteBusy || m_trkWriteQueue.isEmpty()) - return NoMessage; - // Handle the noop message, just invoke CB in slot (ower thread) - if (m_trkWriteQueue.front().code == TRK_WRITE_QUEUE_NOOP_CODE) { - *message = m_trkWriteQueue.dequeue(); - return NoopMessageDequeued; - } - // Insert into map fir answers (as reading threads might get an - // answer before notifyWriteResult(true)) is called. - *message = m_trkWriteQueue.front(); - m_writtenTrkMessages.insert(message->token, *message); - m_trkWriteBusy = true; - return PendingMessage; -} - -void TrkWriteQueue::invokeNoopMessage(trk::TrkMessage noopMessage) -{ - TrkResult result; - result.code = noopMessage.code; - result.token = noopMessage.token; - result.data = noopMessage.data; - result.cookie = noopMessage.cookie; - noopMessage.callback(result); -} - -void TrkWriteQueue::notifyWriteResult(WriteResult wr) -{ - // On success, dequeue message and await result - const byte token = m_trkWriteQueue.front().token; - switch (wr) { - case WriteOk: - m_trkWriteQueue.dequeue(); - break; - case WriteFailedKeep: - case WriteFailedDiscard: - m_writtenTrkMessages.remove(token); - m_trkWriteBusy = false; - if (wr == WriteFailedDiscard) - m_trkWriteQueue.dequeue(); - break; - } -} - -void TrkWriteQueue::slotHandleResult(const TrkResult &result, QMutex *mutex) -{ - // Find which request the message belongs to and invoke callback - // if ACK or on NAK if desired. - if (mutex) - mutex->lock(); - m_trkWriteBusy = false; - const TokenMessageMap::iterator it = m_writtenTrkMessages.find(result.token); - if (it == m_writtenTrkMessages.end()) { - if (mutex) - mutex->unlock(); - return; - } - TrkCallback callback = it.value().callback; - const QVariant cookie = it.value().cookie; - m_writtenTrkMessages.erase(it); - if (mutex) - mutex->unlock(); - // Invoke callback - if (callback) { - TrkResult result1 = result; - result1.cookie = cookie; - callback(result1); - } -} - -void TrkWriteQueue::queueTrkInitialPing() -{ - // Ping, reset sequence count - m_trkWriteToken = 0; - m_trkWriteQueue.append(TrkMessage(TrkPing, 0)); -} - -/////////////////////////////////////////////////////////////////////// -// -// DeviceContext to be shared between threads -// -/////////////////////////////////////////////////////////////////////// - -struct DeviceContext { - DeviceContext(); -#ifdef Q_OS_WIN - HANDLE device; - OVERLAPPED readOverlapped; - OVERLAPPED writeOverlapped; -#else - QFile file; -#endif - bool serialFrame; - QMutex mutex; -}; - -DeviceContext::DeviceContext() : -#ifdef Q_OS_WIN - device(INVALID_HANDLE_VALUE), -#endif - serialFrame(true) -{ -} - -/////////////////////////////////////////////////////////////////////// -// -// TrkWriterThread: A thread operating a TrkWriteQueue. -// with exception of the handling of the TRK_WRITE_QUEUE_NOOP_CODE -// synchronization message. The invocation of the callback is then -// done by the thread owning the TrkWriteQueue, while pendingMessage() is called -// from another thread. This happens via a Qt::BlockingQueuedConnection. - -/////////////////////////////////////////////////////////////////////// - -class WriterThread : public QThread -{ - Q_OBJECT - Q_DISABLE_COPY(WriterThread) -public: - explicit WriterThread(const QSharedPointer &context); - - // Enqueue messages. - void queueTrkMessage(byte code, TrkCallback callback, - const QByteArray &data, const QVariant &cookie); - void queueTrkInitialPing(); - - // Call this from the device read notification with the results. - void slotHandleResult(const TrkResult &result); - - virtual void run(); - -signals: - void error(const QString &); - void internalNoopMessageDequeued(const trk::TrkMessage&); - -public slots: - bool trkWriteRawMessage(const TrkMessage &msg); - void terminate(); - void tryWrite(); - -private slots: - void invokeNoopMessage(const trk::TrkMessage &); - -private: - bool write(const QByteArray &data, QString *errorMessage); - inline int writePendingMessage(); - - const QSharedPointer m_context; - QMutex m_dataMutex; - QMutex m_waitMutex; - QWaitCondition m_waitCondition; - TrkWriteQueue m_queue; - bool m_terminate; -}; - -WriterThread::WriterThread(const QSharedPointer &context) : - m_context(context), - m_terminate(false) -{ - static const int trkMessageMetaId = qRegisterMetaType(); - Q_UNUSED(trkMessageMetaId) - connect(this, SIGNAL(internalNoopMessageDequeued(trk::TrkMessage)), - this, SLOT(invokeNoopMessage(trk::TrkMessage)), Qt::BlockingQueuedConnection); -} - -void WriterThread::run() -{ - while (writePendingMessage() == 0) ; -} - -int WriterThread::writePendingMessage() -{ - enum { MaxAttempts = 100, RetryIntervalMS = 200 }; - - // Wait. Use a timeout in case something is already queued before we - // start up or some weird hanging exit condition - m_waitMutex.lock(); - m_waitCondition.wait(&m_waitMutex, 100); - m_waitMutex.unlock(); - if (m_terminate) - return 1; - - // Send off message - m_dataMutex.lock(); - TrkMessage message; - const TrkWriteQueue::PendingMessageResult pr = m_queue.pendingMessage(&message); - m_dataMutex.unlock(); - - switch (pr) { - case TrkWriteQueue::NoMessage: - break; - case TrkWriteQueue::PendingMessage: { - //qDebug() << "Write pending message " << message; - // Untested: try to re-send a few times - bool success = false; - for (int r = 0; !success && (r < MaxAttempts); r++) { - success = trkWriteRawMessage(message); - if (!success) { - emit error(QString::fromLatin1("Write failure, attempt %1 of %2.").arg(r).arg(int(MaxAttempts))); - if (m_terminate) - return 1; - QThread::msleep(RetryIntervalMS); - } - } - // Notify queue. If still failed, give up. - m_dataMutex.lock(); - m_queue.notifyWriteResult(success ? TrkWriteQueue::WriteOk : TrkWriteQueue::WriteFailedDiscard); - m_dataMutex.unlock(); - } - break; - case TrkWriteQueue::NoopMessageDequeued: - // Sync with thread that owns us via a blocking signal - if (verboseTrk) - qDebug() << "Noop message dequeued" << message; - emit internalNoopMessageDequeued(message); - break; - } // switch - return 0; -} - -void WriterThread::invokeNoopMessage(const trk::TrkMessage &msg) -{ - TrkWriteQueue::invokeNoopMessage(msg); -} - -void WriterThread::terminate() -{ - m_terminate = true; - m_waitCondition.wakeAll(); - wait(); - m_terminate = false; -} - -#ifdef Q_OS_WIN - -static inline QString msgTerminated(int size) -{ - return QString::fromLatin1("Terminated with %1 bytes pending.").arg(size); -} - -// Interruptible synchronous write function. -static inline bool overlappedSyncWrite(HANDLE file, - const bool &terminateFlag, - const char *data, - DWORD size, DWORD *charsWritten, - OVERLAPPED *overlapped, - QString *errorMessage) -{ - if (WriteFile(file, data, size, charsWritten, overlapped)) - return true; - const DWORD writeError = GetLastError(); - if (writeError != ERROR_IO_PENDING) { - *errorMessage = QString::fromLatin1("WriteFile failed: %1").arg(winErrorMessage(writeError)); - return false; - } - // Wait for written or thread terminated - const DWORD timeoutMS = 200; - const unsigned maxAttempts = 20; - DWORD wr = WaitForSingleObject(overlapped->hEvent, timeoutMS); - for (unsigned n = 0; wr == WAIT_TIMEOUT && n < maxAttempts && !terminateFlag; - wr = WaitForSingleObject(overlapped->hEvent, timeoutMS), n++); - if (terminateFlag) { - *errorMessage = msgTerminated(size); - return false; - } - switch (wr) { - case WAIT_OBJECT_0: - break; - case WAIT_TIMEOUT: - *errorMessage = QString::fromLatin1("Write timed out."); - return false; - default: - *errorMessage = QString::fromLatin1("Error while waiting for WriteFile results: %1").arg(winErrorMessage(GetLastError())); - return false; - } - if (!GetOverlappedResult(file, overlapped, charsWritten, TRUE)) { - *errorMessage = QString::fromLatin1("Error writing %1 bytes: %2").arg(size).arg(winErrorMessage(GetLastError())); - return false; - } - return true; -} -#endif - -bool WriterThread::write(const QByteArray &data, QString *errorMessage) -{ - if (verboseTrk) - qDebug() << "Write raw data: " << stringFromArray(data).toLatin1(); - QMutexLocker locker(&m_context->mutex); -#ifdef Q_OS_WIN - DWORD charsWritten; - if (!overlappedSyncWrite(m_context->device, m_terminate, data.data(), data.size(), &charsWritten, &m_context->writeOverlapped, errorMessage)) { - return false; - } - FlushFileBuffers(m_context->device); - return true; -#else - if (m_context->file.write(data) == -1 || !m_context->file.flush()) { - *errorMessage = QString::fromLatin1("Cannot write: %1").arg(m_context->file.errorString()); - return false; - } - return true; -#endif -} - -bool WriterThread::trkWriteRawMessage(const TrkMessage &msg) -{ - const QByteArray ba = frameMessage(msg.code, msg.token, msg.data, m_context->serialFrame); - QString errorMessage; - const bool rc = write(ba, &errorMessage); - if (!rc) { - qWarning("%s\n", qPrintable(errorMessage)); - emit error(errorMessage); - } - return rc; -} - -void WriterThread::tryWrite() -{ - m_waitCondition.wakeAll(); -} - -void WriterThread::queueTrkMessage(byte code, TrkCallback callback, - const QByteArray &data, const QVariant &cookie) -{ - m_dataMutex.lock(); - m_queue.queueTrkMessage(code, callback, data, cookie); - m_dataMutex.unlock(); - tryWrite(); -} - -void WriterThread::queueTrkInitialPing() -{ - m_dataMutex.lock(); - m_queue.queueTrkInitialPing(); - m_dataMutex.unlock(); - tryWrite(); -} - -// Call this from the device read notification with the results. -void WriterThread::slotHandleResult(const TrkResult &result) -{ - m_queue.slotHandleResult(result, &m_dataMutex); - tryWrite(); // Have messages been enqueued in-between? -} - - -/////////////////////////////////////////////////////////////////////// -// -// ReaderThreadBase: Base class for a thread that reads data from -// the device, decodes the messages and emit signals for the messages. -// A Qt::BlockingQueuedConnection should be used for the message signal -// to ensure messages are processed in the correct sequence. -// -/////////////////////////////////////////////////////////////////////// - -class ReaderThreadBase : public QThread -{ - Q_OBJECT - Q_DISABLE_COPY(ReaderThreadBase) -public: - -signals: - void messageReceived(const trk::TrkResult &result, const QByteArray &rawData); - -protected: - explicit ReaderThreadBase(const QSharedPointer &context); - void processData(const QByteArray &a); - void processData(char c); - - const QSharedPointer m_context; - -private: - void readMessages(); - - QByteArray m_trkReadBuffer; -}; - -ReaderThreadBase::ReaderThreadBase(const QSharedPointer &context) : - m_context(context) -{ - static const int trkResultMetaId = qRegisterMetaType(); - Q_UNUSED(trkResultMetaId) -} - -void ReaderThreadBase::processData(const QByteArray &a) -{ - m_trkReadBuffer += a; - readMessages(); -} - -void ReaderThreadBase::processData(char c) -{ - m_trkReadBuffer += c; - if (m_trkReadBuffer.size() > 1) - readMessages(); -} - -void ReaderThreadBase::readMessages() -{ - TrkResult r; - QByteArray rawData; - while (extractResult(&m_trkReadBuffer, m_context->serialFrame, &r, &rawData)) { - emit messageReceived(r, rawData); - } -} - -#ifdef Q_OS_WIN -/////////////////////////////////////////////////////////////////////// -// -// WinReaderThread: A thread reading from the device using Windows API. -// Waits on an overlapped I/O handle and an event that tells the thread to -// terminate. -// -/////////////////////////////////////////////////////////////////////// - -class WinReaderThread : public ReaderThreadBase -{ - Q_OBJECT - Q_DISABLE_COPY(WinReaderThread) -public: - explicit WinReaderThread(const QSharedPointer &context); - ~WinReaderThread(); - - virtual void run(); - -signals: - void error(const QString &); - -public slots: - void terminate(); - -private: - enum Handles { FileHandle, TerminateEventHandle, HandleCount }; - - inline int tryRead(); - - HANDLE m_handles[HandleCount]; -}; - -WinReaderThread::WinReaderThread(const QSharedPointer &context) : - ReaderThreadBase(context) -{ - m_handles[FileHandle] = NULL; - m_handles[TerminateEventHandle] = CreateEvent(NULL, FALSE, FALSE, NULL); -} - -WinReaderThread::~WinReaderThread() -{ - CloseHandle(m_handles[TerminateEventHandle]); -} - -// Return 0 to continue or error code -int WinReaderThread::tryRead() -{ - enum { BufSize = 1024 }; - char buffer[BufSize]; - // Check if there are already bytes waiting. If not, wait for first byte - COMSTAT comStat; - if (!ClearCommError(m_context->device, NULL, &comStat)){ - emit error(QString::fromLatin1("ClearCommError failed: %1").arg(winErrorMessage(GetLastError()))); - return -7; - } - const DWORD bytesToRead = qMax(DWORD(1), qMin(comStat.cbInQue, DWORD(BufSize))); - // Trigger read - DWORD bytesRead = 0; - if (ReadFile(m_context->device, &buffer, bytesToRead, &bytesRead, &m_context->readOverlapped)) { - if (bytesRead == 1) { - processData(buffer[0]); - } else { - processData(QByteArray(buffer, bytesRead)); - } - return 0; - } - const DWORD readError = GetLastError(); - if (readError != ERROR_IO_PENDING) { - emit error(QString::fromLatin1("Read error: %1").arg(winErrorMessage(readError))); - return -1; - } - // Wait for either termination or data - const DWORD wr = WaitForMultipleObjects(HandleCount, m_handles, false, INFINITE); - if (wr == WAIT_FAILED) { - emit error(QString::fromLatin1("Wait failed: %1").arg(winErrorMessage(GetLastError()))); - return -2; - } - if (wr - WAIT_OBJECT_0 == TerminateEventHandle) { - return 1; // Terminate - } - // Check data - if (!GetOverlappedResult(m_context->device, &m_context->readOverlapped, &bytesRead, true)) { - emit error(QString::fromLatin1("GetOverlappedResult failed: %1").arg(winErrorMessage(GetLastError()))); - return -3; - } - if (bytesRead == 1) { - processData(buffer[0]); - } else { - processData(QByteArray(buffer, bytesRead)); - } - return 0; -} - -void WinReaderThread::run() -{ - m_handles[FileHandle] = m_context->readOverlapped.hEvent; - while ( tryRead() == 0) ; -} - -void WinReaderThread::terminate() -{ - SetEvent(m_handles[TerminateEventHandle]); - wait(); -} - -typedef WinReaderThread ReaderThread; - -#else - -/////////////////////////////////////////////////////////////////////// -// -// UnixReaderThread: A thread reading from the device. -// Uses select() to wait and a special ioctl() to find out the number -// of bytes queued. For clean termination, the self-pipe trick is used. -// The class maintains a pipe, on whose read end the select waits besides -// the device file handle. To terminate, a byte is written to the pipe. -// -/////////////////////////////////////////////////////////////////////// - -static inline QString msgUnixCallFailedErrno(const char *func, int errorNumber) -{ - return QString::fromLatin1("Call to %1() failed: %2").arg(QLatin1String(func), QString::fromLocal8Bit(strerror(errorNumber))); -} - -class UnixReaderThread : public ReaderThreadBase { - Q_OBJECT - Q_DISABLE_COPY(UnixReaderThread) -public: - explicit UnixReaderThread(const QSharedPointer &context); - ~UnixReaderThread(); - - virtual void run(); - -signals: - void error(const QString &); - -public slots: - void terminate(); - -private: - inline int tryRead(); - - int m_terminatePipeFileDescriptors[2]; -}; - -UnixReaderThread::UnixReaderThread(const QSharedPointer &context) : - ReaderThreadBase(context) -{ - m_terminatePipeFileDescriptors[0] = m_terminatePipeFileDescriptors[1] = -1; - // Set up pipes for termination. Should not fail - if (pipe(m_terminatePipeFileDescriptors) < 0) - qWarning("%s\n", qPrintable(msgUnixCallFailedErrno("pipe", errno))); -} - -UnixReaderThread::~UnixReaderThread() -{ - close(m_terminatePipeFileDescriptors[0]); - close(m_terminatePipeFileDescriptors[1]); -} - -int UnixReaderThread::tryRead() -{ - fd_set readSet, tempReadSet, tempExceptionSet; - struct timeval timeOut; - const int fileDescriptor = m_context->file.handle(); - FD_ZERO(&readSet); - FD_SET(fileDescriptor, &readSet); - FD_SET(m_terminatePipeFileDescriptors[0], &readSet); - const int maxFileDescriptor = qMax(m_terminatePipeFileDescriptors[0], fileDescriptor); - int result = 0; - do { - memcpy(&tempReadSet, &readSet, sizeof(fd_set)); - memcpy(&tempExceptionSet, &readSet, sizeof(fd_set)); - timeOut.tv_sec = 1; - timeOut.tv_usec = 0; - result = select(maxFileDescriptor + 1, &tempReadSet, NULL, &tempExceptionSet, &timeOut); - } while ( result < 0 && errno == EINTR ); - // Timeout? - if (result == 0) - return 0; - // Something wrong? - if (result < 0) { - emit error(msgUnixCallFailedErrno("select", errno)); - return -1; - } - // Did the exception set trigger on the device? - if (FD_ISSET(fileDescriptor,&tempExceptionSet)) { - emit error(QLatin1String("An Exception occurred on the device.")); - return -2; - } - // Check termination pipe. - if (FD_ISSET(m_terminatePipeFileDescriptors[0], &tempReadSet) - || FD_ISSET(m_terminatePipeFileDescriptors[0], &tempExceptionSet)) - return 1; - - // determine number of pending bytes and read - int numBytes; - if (ioctl(fileDescriptor, FIONREAD, &numBytes) < 0) { - emit error(msgUnixCallFailedErrno("ioctl", errno)); - return -1; - } - m_context->mutex.lock(); - const QByteArray data = m_context->file.read(numBytes); - m_context->mutex.unlock(); - processData(data); - return 0; -} - -void UnixReaderThread::run() -{ - // Read loop - while (tryRead() == 0) - ; -} - -void UnixReaderThread::terminate() -{ - // Trigger select() by writing to the pipe - char c = 0; - const int written = write(m_terminatePipeFileDescriptors[1], &c, 1); - Q_UNUSED(written) - wait(); -} - -typedef UnixReaderThread ReaderThread; - -#endif - -/////////////////////////////////////////////////////////////////////// -// -// TrkDevicePrivate -// -/////////////////////////////////////////////////////////////////////// - -struct TrkDevicePrivate -{ - TrkDevicePrivate(); - - QSharedPointer deviceContext; - QSharedPointer writerThread; - QSharedPointer readerThread; - - QByteArray trkReadBuffer; - int verbose; - QString errorString; -}; - -/////////////////////////////////////////////////////////////////////// -// -// TrkDevice -// -/////////////////////////////////////////////////////////////////////// - -TrkDevicePrivate::TrkDevicePrivate() : - deviceContext(new DeviceContext), - verbose(0) -{ -} - -/////////////////////////////////////////////////////////////////////// -// -// TrkDevice -// -/////////////////////////////////////////////////////////////////////// - -TrkDevice::TrkDevice(QObject *parent) : - QObject(parent), - d(new TrkDevicePrivate) -{} - -TrkDevice::~TrkDevice() -{ - close(); - delete d; -} - -bool TrkDevice::open(const QString &port, QString *errorMessage) -{ - if (d->verbose) - qDebug() << "Opening" << port << "is open: " << isOpen() << " serialFrame=" << serialFrame(); - close(); -#ifdef Q_OS_WIN - d->deviceContext->device = CreateFile(QString("\\\\.\\").append(port).toStdWString().c_str(), - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING|FILE_FLAG_OVERLAPPED, - NULL); - - if (INVALID_HANDLE_VALUE == d->deviceContext->device) { - *errorMessage = QString::fromLatin1("Could not open device '%1': %2").arg(port, winErrorMessage(GetLastError())); - return false; - } - memset(&d->deviceContext->readOverlapped, 0, sizeof(OVERLAPPED)); - d->deviceContext->readOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - memset(&d->deviceContext->writeOverlapped, 0, sizeof(OVERLAPPED)); - d->deviceContext->writeOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (d->deviceContext->readOverlapped.hEvent == NULL || d->deviceContext->writeOverlapped.hEvent == NULL) { - *errorMessage = QString::fromLatin1("Failed to create events: %1").arg(winErrorMessage(GetLastError())); - return false; - } -#else - d->deviceContext->file.setFileName(port); - if (!d->deviceContext->file.open(QIODevice::ReadWrite|QIODevice::Unbuffered)) { - *errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(port, d->deviceContext->file.errorString()); - return false; - } - - struct termios termInfo; - if (tcgetattr(d->deviceContext->file.handle(), &termInfo) < 0) { - *errorMessage = QString::fromLatin1("Unable to retrieve terminal settings: %1 %2").arg(errno).arg(QString::fromAscii(strerror(errno))); - return false; - } - // Turn off terminal echo as not get messages back, among other things - termInfo.c_cflag |= CREAD|CLOCAL; - termInfo.c_lflag &= (~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); - termInfo.c_iflag &= (~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY)); - termInfo.c_oflag &= (~OPOST); - termInfo.c_cc[VMIN] = 0; - termInfo.c_cc[VINTR] = _POSIX_VDISABLE; - termInfo.c_cc[VQUIT] = _POSIX_VDISABLE; - termInfo.c_cc[VSTART] = _POSIX_VDISABLE; - termInfo.c_cc[VSTOP] = _POSIX_VDISABLE; - termInfo.c_cc[VSUSP] = _POSIX_VDISABLE; - if (tcsetattr(d->deviceContext->file.handle(), TCSAFLUSH, &termInfo) < 0) { - *errorMessage = QString::fromLatin1("Unable to apply terminal settings: %1 %2").arg(errno).arg(QString::fromAscii(strerror(errno))); - return false; - } -#endif - d->readerThread = QSharedPointer(new ReaderThread(d->deviceContext)); - connect(d->readerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)), - Qt::QueuedConnection); - connect(d->readerThread.data(), SIGNAL(messageReceived(trk::TrkResult,QByteArray)), - this, SLOT(slotMessageReceived(trk::TrkResult,QByteArray)), - Qt::QueuedConnection); - d->readerThread->start(); - - d->writerThread = QSharedPointer(new WriterThread(d->deviceContext)); - connect(d->writerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)), - Qt::QueuedConnection); - d->writerThread->start(); - - if (d->verbose) - qDebug() << "Opened" << port; - return true; -} - -void TrkDevice::close() -{ - if (!isOpen()) - return; - if (d->readerThread) - d->readerThread->terminate(); - if (d->writerThread) - d->writerThread->terminate(); -#ifdef Q_OS_WIN - CloseHandle(d->deviceContext->device); - d->deviceContext->device = INVALID_HANDLE_VALUE; - CloseHandle(d->deviceContext->readOverlapped.hEvent); - CloseHandle(d->deviceContext->writeOverlapped.hEvent); - d->deviceContext->readOverlapped.hEvent = d->deviceContext->writeOverlapped.hEvent = NULL; -#else - d->deviceContext->file.close(); -#endif - if (d->verbose) - emitLogMessage("Close"); -} - -bool TrkDevice::isOpen() const -{ -#ifdef Q_OS_WIN - return d->deviceContext->device != INVALID_HANDLE_VALUE; -#else - return d->deviceContext->file.isOpen(); -#endif -} - -QString TrkDevice::errorString() const -{ - return d->errorString; -} - -bool TrkDevice::serialFrame() const -{ - return d->deviceContext->serialFrame; -} - -void TrkDevice::setSerialFrame(bool f) -{ - d->deviceContext->serialFrame = f; -} - -int TrkDevice::verbose() const -{ - return d->verbose; -} - -void TrkDevice::setVerbose(int b) -{ - d->verbose = b; -} - -void TrkDevice::slotMessageReceived(const trk::TrkResult &result, const QByteArray &rawData) -{ - d->writerThread->slotHandleResult(result); - if (d->verbose > 1) - qDebug() << "Received: " << result.toString(); - emit messageReceived(result); - if (!rawData.isEmpty()) - emit rawDataReceived(rawData); -} - -void TrkDevice::emitError(const QString &s) -{ - d->errorString = s; - qWarning("%s\n", qPrintable(s)); - emit error(s); -} - -void TrkDevice::sendTrkMessage(byte code, TrkCallback callback, - const QByteArray &data, const QVariant &cookie) -{ - if (!d->writerThread.isNull()) { - if (d->verbose > 1) { - QByteArray msg = "Sending: "; - msg += QByteArray::number(code, 16); - msg += ": "; - msg += stringFromArray(data).toLatin1(); - qDebug("%s", msg.data()); - } - d->writerThread->queueTrkMessage(code, callback, data, cookie); - } -} - -void TrkDevice::sendTrkInitialPing() -{ - if (!d->writerThread.isNull()) - d->writerThread->queueTrkInitialPing(); -} - -bool TrkDevice::sendTrkAck(byte token) -{ - if (d->writerThread.isNull()) - return false; - // The acknowledgement must not be queued! - TrkMessage msg(0x80, token); - msg.token = token; - msg.data.append('\0'); - if (verboseTrk) - qDebug() << "Write synchroneous message: " << msg; - return d->writerThread->trkWriteRawMessage(msg); - // 01 90 00 07 7e 80 01 00 7d 5e 7e -} - -void TrkDevice::emitLogMessage(const QString &msg) -{ - if (d->verbose) - qDebug("%s\n", qPrintable(msg)); - emit logMessage(msg); -} - -} // namespace trk - -#include "trkdevice.moc" diff --git a/tools/runonphone/trk/trkdevice.h b/tools/runonphone/trk/trkdevice.h deleted file mode 100644 index 21a3cc1..0000000 --- a/tools/runonphone/trk/trkdevice.h +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TRKDEVICE_H -#define TRKDEVICE_H - -#include "symbianutils_global.h" -#include "callback.h" - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE -class QIODevice; -QT_END_NAMESPACE - -namespace trk { - -struct TrkResult; -struct TrkMessage; -struct TrkDevicePrivate; - -/* TrkDevice: Implements a Windows COM or Linux device for - * Trk communications. Provides synchronous write and asynchronous - * read operation. - * The serialFrames property specifies whether packets are encapsulated in - * "0x90 " frames, which is currently the case for serial ports. - * Contains a write message queue allowing - * for queueing messages with a notification callback. If the message receives - * an ACK, the callback is invoked. - * The special message TRK_WRITE_QUEUE_NOOP_CODE code can be used for synchronisation. - * The respective message will not be sent, the callback is just invoked. */ - -enum { TRK_WRITE_QUEUE_NOOP_CODE = 0x7f }; - -typedef trk::Callback TrkCallback; - -class SYMBIANUTILS_EXPORT TrkDevice : public QObject -{ - Q_OBJECT - Q_PROPERTY(bool serialFrame READ serialFrame WRITE setSerialFrame) - Q_PROPERTY(bool verbose READ verbose WRITE setVerbose) -public: - explicit TrkDevice(QObject *parent = 0); - virtual ~TrkDevice(); - - bool open(const QString &port, QString *errorMessage); - bool isOpen() const; - - QString errorString() const; - - bool serialFrame() const; - void setSerialFrame(bool f); - - int verbose() const; - void setVerbose(int b); - - // Enqueue a message with a notification callback. - void sendTrkMessage(unsigned char code, - TrkCallback callBack = TrkCallback(), - const QByteArray &data = QByteArray(), - const QVariant &cookie = QVariant()); - - // Enqeue an initial ping - void sendTrkInitialPing(); - - // Send an Ack synchronously, bypassing the queue - bool sendTrkAck(unsigned char token); - -signals: - void messageReceived(const trk::TrkResult &result); - // Emitted with the contents of messages enclosed in 07e, not for log output - void rawDataReceived(const QByteArray &data); - void error(const QString &msg); - void logMessage(const QString &msg); - -private slots: - void slotMessageReceived(const trk::TrkResult &result, const QByteArray &a); - -protected slots: - void emitError(const QString &msg); - void emitLogMessage(const QString &msg); - -public slots: - void close(); - -private: - void readMessages(); - TrkDevicePrivate *d; -}; - -} // namespace trk - -#endif // TRKDEVICE_H diff --git a/tools/runonphone/trk/trkutils.cpp b/tools/runonphone/trk/trkutils.cpp deleted file mode 100644 index 5cce950..0000000 --- a/tools/runonphone/trk/trkutils.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "trkutils.h" -#include - -#include -#include -#include -#include -#include - -#define logMessage(s) do { qDebug() << "TRKCLIENT: " << s; } while (0) - -namespace trk { - -TrkAppVersion::TrkAppVersion() -{ - reset(); -} - -void TrkAppVersion::reset() -{ - trkMajor = trkMinor= protocolMajor = protocolMinor = 0; -} - -Session::Session() -{ - reset(); -} - -void Session::reset() -{ - cpuMajor = 0; - cpuMinor = 0; - bigEndian = 0; - defaultTypeSize = 0; - fpTypeSize = 0; - extended1TypeSize = 0; - extended2TypeSize = 0; - pid = 0; - tid = 0; - codeseg = 0; - dataseg = 0; - - currentThread = 0; - libraries.clear(); - trkAppVersion.reset(); -} - -static QString formatCpu(int major, int minor) -{ - //: CPU description of an S60 device - //: %1 major verison, %2 minor version - //: %3 real name of major verison, %4 real name of minor version - const QString str = QCoreApplication::translate("trk::Session", "CPU: v%1.%2%3%4"); - QString majorStr; - QString minorStr; - switch (major) { - case 0x04: - majorStr = " ARM"; - break; - } - switch (minor) { - case 0x00: - minorStr = " 920T"; - break; - } - return str.arg(major).arg(minor).arg(majorStr).arg(minorStr); - } - -QString formatTrkVersion(const TrkAppVersion &version) -{ - QString str = QCoreApplication::translate("trk::Session", - "App TRK: v%1.%2 TRK protocol: v%3.%4"); - str = str.arg(version.trkMajor).arg(version.trkMinor); - return str.arg(version.protocolMajor).arg(version.protocolMinor); -} - -QString Session::deviceDescription(unsigned verbose) const -{ - if (!cpuMajor) - return QString(); - - //: s60description - //: description of an S60 device - //: %1 CPU description, %2 endianness - //: %3 default type size (if any), %4 float size (if any) - //: %5 TRK version - QString msg = QCoreApplication::translate("trk::Session", "%1, %2%3%4, %5"); - QString endianness = bigEndian - ? QCoreApplication::translate("trk::Session", "big endian") - : QCoreApplication::translate("trk::Session", "little endian"); - msg = msg.arg(formatCpu(cpuMajor, cpuMinor)).arg(endianness); - //: The separator in a list of strings - QString defaultTypeSizeStr; - QString fpTypeSizeStr; - if (verbose && defaultTypeSize) - //: will be inserted into s60description - defaultTypeSizeStr = QCoreApplication::translate("trk::Session", ", type size: %1").arg(defaultTypeSize); - if (verbose && fpTypeSize) - //: will be inserted into s60description - fpTypeSizeStr = QCoreApplication::translate("trk::Session", ", float size: %1").arg(fpTypeSize); - msg = msg.arg(defaultTypeSizeStr).arg(fpTypeSizeStr); - return msg.arg(formatTrkVersion(trkAppVersion)); -} - - -QByteArray decode7d(const QByteArray &ba) -{ - QByteArray res; - res.reserve(ba.size()); - for (int i = 0; i < ba.size(); ++i) { - byte c = byte(ba.at(i)); - if (c == 0x7d) { - ++i; - c = 0x20 ^ byte(ba.at(i)); - } - res.append(c); - } - return res; -} - -QByteArray encode7d(const QByteArray &ba) -{ - QByteArray res; - res.reserve(ba.size() + 2); - for (int i = 0; i < ba.size(); ++i) { - byte c = byte(ba.at(i)); - if (c == 0x7e || c == 0x7d) { - res.append(0x7d); - res.append(0x20 ^ c); - } else { - res.append(c); - } - } - return res; -} - -// FIXME: Use the QByteArray based version below? -static inline QString stringFromByte(byte c) -{ - return QString::fromLatin1("%1").arg(c, 2, 16, QChar('0')); -} - -SYMBIANUTILS_EXPORT QString stringFromArray(const QByteArray &ba, int maxLen) -{ - QString str; - QString ascii; - const int size = maxLen == -1 ? ba.size() : qMin(ba.size(), maxLen); - for (int i = 0; i < size; ++i) { - //if (i == 5 || i == ba.size() - 2) - // str += " "; - int c = byte(ba.at(i)); - str += QString("%1 ").arg(c, 2, 16, QChar('0')); - if (i >= 8 && i < ba.size() - 2) - ascii += QChar(c).isPrint() ? QChar(c) : QChar('.'); - } - if (size != ba.size()) { - str += "..."; - ascii += "..."; - } - return str + " " + ascii; -} - -SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits) -{ - QByteArray ba = QByteArray::number(n, 16); - if (digits == 0 || ba.size() == digits) - return ba; - return QByteArray(digits - ba.size(), '0') + ba; -} - -SYMBIANUTILS_EXPORT QByteArray hexxNumber(uint n, int digits) -{ - return "0x" + hexNumber(n, digits); -} - -TrkResult::TrkResult() : - code(0), - token(0), - isDebugOutput(false) -{ -} - -void TrkResult::clear() -{ - code = token= 0; - isDebugOutput = false; - data.clear(); - cookie = QVariant(); -} - -QString TrkResult::toString() const -{ - QString res = stringFromByte(code); - res += QLatin1String(" ["); - res += stringFromByte(token); - res += QLatin1Char(']'); - res += QLatin1Char(' '); - res += stringFromArray(data); - return res; -} - -QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame) -{ - byte s = command + token; - for (int i = 0; i != data.size(); ++i) - s += data.at(i); - byte checksum = 255 - (s & 0xff); - //int x = s + ~s; - //logMessage("check: " << s << checksum << x; - - QByteArray response; - response.reserve(data.size() + 3); - response.append(char(command)); - response.append(char(token)); - response.append(data); - response.append(char(checksum)); - - QByteArray encodedData = encode7d(response); - - QByteArray ba; - ba.reserve(encodedData.size() + 6); - if (serialFrame) { - ba.append(char(0x01)); - ba.append(char(0x90)); - const ushort encodedSize = encodedData.size() + 2; // 2 x 0x7e - appendShort(&ba, encodedSize, BigEndian); - } - ba.append(char(0x7e)); - ba.append(encodedData); - ba.append(char(0x7e)); - - return ba; -} - -/* returns 0 if array doesn't represent a result, -otherwise returns the length of the result data */ -ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame) -{ - if (serialFrame) { - // Serial protocol with length info - if (buffer.length() < 4) - return 0; - if (buffer.at(0) != 0x01 || byte(buffer.at(1)) != 0x90) - return 0; - const ushort len = extractShort(buffer.data() + 2); - return (buffer.size() >= len + 4) ? len : ushort(0); - } - // Frameless protocol without length info - const char delimiter = char(0x7e); - const int firstDelimiterPos = buffer.indexOf(delimiter); - // Regular message delimited by 0x7e..0x7e - if (firstDelimiterPos == 0) { - const int endPos = buffer.indexOf(delimiter, firstDelimiterPos + 1); - return endPos != -1 ? endPos + 1 - firstDelimiterPos : 0; - } - // Some ASCII log message up to first delimiter or all - return firstDelimiterPos != -1 ? firstDelimiterPos : buffer.size(); -} - -bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *result, QByteArray *rawData) -{ - result->clear(); - if(rawData) - rawData->clear(); - const ushort len = isValidTrkResult(*buffer, serialFrame); - if (!len) - return false; - // handle receiving application output, which is not a regular command - const int delimiterPos = serialFrame ? 4 : 0; - if (buffer->at(delimiterPos) != 0x7e) { - result->isDebugOutput = true; - result->data = buffer->mid(delimiterPos, len); - result->data.replace("\r\n", "\n"); - *buffer->remove(0, delimiterPos + len); - return true; - } - // FIXME: what happens if the length contains 0xfe? - // Assume for now that it passes unencoded! - const QByteArray data = decode7d(buffer->mid(delimiterPos + 1, len - 2)); - if(rawData) - *rawData = data; - *buffer->remove(0, delimiterPos + len); - - byte sum = 0; - for (int i = 0; i < data.size(); ++i) // 3 = 2 * 0xfe + sum - sum += byte(data.at(i)); - if (sum != 0xff) - logMessage("*** CHECKSUM ERROR: " << byte(sum)); - - result->code = data.at(0); - result->token = data.at(1); - result->data = data.mid(2, data.size() - 3); - //logMessage(" REST BUF: " << stringFromArray(*buffer)); - //logMessage(" CURR DATA: " << stringFromArray(data)); - //QByteArray prefix = "READ BUF: "; - //logMessage((prefix + "HEADER: " + stringFromArray(header).toLatin1()).data()); - return true; -} - -SYMBIANUTILS_EXPORT ushort extractShort(const char *data) -{ - return byte(data[0]) * 256 + byte(data[1]); -} - -SYMBIANUTILS_EXPORT uint extractInt(const char *data) -{ - uint res = byte(data[0]); - res *= 256; res += byte(data[1]); - res *= 256; res += byte(data[2]); - res *= 256; res += byte(data[3]); - return res; -} - -SYMBIANUTILS_EXPORT QString quoteUnprintableLatin1(const QByteArray &ba) -{ - QString res; - char buf[10]; - for (int i = 0, n = ba.size(); i != n; ++i) { - const byte c = ba.at(i); - if (isprint(c)) { - res += c; - } else { - qsnprintf(buf, sizeof(buf) - 1, "\\%x", int(c)); - res += buf; - } - } - return res; -} - -SYMBIANUTILS_EXPORT void appendShort(QByteArray *ba, ushort s, Endianness endian) -{ - if (endian == BigEndian) { - ba->append(s / 256); - ba->append(s % 256); - } else { - ba->append(s % 256); - ba->append(s / 256); - } -} - -SYMBIANUTILS_EXPORT void appendInt(QByteArray *ba, uint i, Endianness endian) -{ - const uchar b3 = i % 256; i /= 256; - const uchar b2 = i % 256; i /= 256; - const uchar b1 = i % 256; i /= 256; - const uchar b0 = i; - ba->reserve(ba->size() + 4); - if (endian == BigEndian) { - ba->append(b0); - ba->append(b1); - ba->append(b2); - ba->append(b3); - } else { - ba->append(b3); - ba->append(b2); - ba->append(b1); - ba->append(b0); - } -} - -void appendString(QByteArray *ba, const QByteArray &str, Endianness endian, bool appendNullTerminator) -{ - const int fullSize = str.size() + (appendNullTerminator ? 1 : 0); - appendShort(ba, fullSize, endian); // count the terminating \0 - ba->append(str); - if (appendNullTerminator) - ba->append('\0'); -} - -void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness endian) -{ - // convert the QDateTime to UTC and append its representation to QByteArray - // format is the same as in FAT file system - dateTime = dateTime.toUTC(); - const QTime utcTime = dateTime.time(); - const QDate utcDate = dateTime.date(); - uint fatDateTime = (utcTime.hour() << 11 | utcTime.minute() << 5 | utcTime.second()/2) << 16; - fatDateTime |= (utcDate.year()-1980) << 9 | utcDate.month() << 5 | utcDate.day(); - appendInt(ba, fatDateTime, endian); -} - -QByteArray errorMessage(byte code) -{ - switch (code) { - case 0x00: return "No error"; - case 0x01: return "Generic error in CWDS message"; - case 0x02: return "Unexpected packet size in send msg"; - case 0x03: return "Internal error occurred in CWDS"; - case 0x04: return "Escape followed by frame flag"; - case 0x05: return "Bad FCS in packet"; - case 0x06: return "Packet too long"; - case 0x07: return "Sequence ID not expected (gap in sequence)"; - - case 0x10: return "Command not supported"; - case 0x11: return "Command param out of range"; - case 0x12: return "An option was not supported"; - case 0x13: return "Read/write to invalid memory"; - case 0x14: return "Read/write invalid registers"; - case 0x15: return "Exception occurred in CWDS"; - case 0x16: return "Targeted system or thread is running"; - case 0x17: return "Breakpoint resources (HW or SW) exhausted"; - case 0x18: return "Requested breakpoint conflicts with existing one"; - - case 0x20: return "General OS-related error"; - case 0x21: return "Request specified invalid process"; - case 0x22: return "Request specified invalid thread"; - } - return "Unknown error"; -} - -uint swapEndian(uint in) -{ - return (in>>24) | ((in<<8) & 0x00FF0000) | ((in>>8) & 0x0000FF00) | (in<<24); -} - -int TrkResult::errorCode() const -{ - // NAK means always error, else data sized 1 with a non-null element - const bool isNAK = code == 0xff; - if (data.size() != 1 && !isNAK) - return 0; - if (const int errorCode = data.at(0)) - return errorCode; - return isNAK ? 0xff : 0; -} - -QString TrkResult::errorString() const -{ - // NAK means always error, else data sized 1 with a non-null element - if (code == 0xff) - return "NAK"; - if (data.size() < 1) - return "Unknown error packet"; - return errorMessage(data.at(0)); -} - -} // namespace trk - diff --git a/tools/runonphone/trk/trkutils.h b/tools/runonphone/trk/trkutils.h deleted file mode 100644 index 3a485c7..0000000 --- a/tools/runonphone/trk/trkutils.h +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DEBUGGER_TRK_UTILS -#define DEBUGGER_TRK_UTILS - -#include "symbianutils_global.h" -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE -class QDateTime; -QT_END_NAMESPACE - -namespace trk { - -typedef unsigned char byte; - -enum Command { - TrkPing = 0x00, - TrkConnect = 0x01, - TrkDisconnect = 0x02, - TrkVersions = 0x04, - TrkSupported = 0x05, - TrkCpuType = 0x06, - TrkHostVersions = 0x09, - TrkContinue = 0x18, - TrkCreateItem = 0x40, - TrkDeleteItem = 0x41, - - TrkWriteFile = 0x48, - TrkOpenFile = 0x4a, - TrkCloseFile = 0x4b, - TrkInstallFile = 0x4d, - TrkInstallFile2 = 0x4e, - - TrkNotifyAck = 0x80, - TrkNotifyNak = 0xff, - TrkNotifyStopped = 0x90, - TrkNotifyException = 0x91, - TrkNotifyInternalError = 0x92, - TrkNotifyCreated = 0xa0, - TrkNotifyDeleted = 0xa1, - TrkNotifyProcessorStarted = 0xa2, - TrkNotifyProcessorStandBy = 0xa6, - TrkNotifyProcessorReset = 0xa7 -}; - -inline byte extractByte(const char *data) { return *data; } -SYMBIANUTILS_EXPORT ushort extractShort(const char *data); -SYMBIANUTILS_EXPORT uint extractInt(const char *data); - -SYMBIANUTILS_EXPORT QString quoteUnprintableLatin1(const QByteArray &ba); - -// produces "xx xx xx " -SYMBIANUTILS_EXPORT QString stringFromArray(const QByteArray &ba, int maxLen = - 1); - -enum Endianness -{ - LittleEndian, - BigEndian, - TargetByteOrder = BigEndian, -}; - -SYMBIANUTILS_EXPORT void appendShort(QByteArray *ba, ushort s, Endianness = TargetByteOrder); -SYMBIANUTILS_EXPORT void appendInt(QByteArray *ba, uint i, Endianness = TargetByteOrder); -SYMBIANUTILS_EXPORT void appendString(QByteArray *ba, const QByteArray &str, Endianness = TargetByteOrder, bool appendNullTerminator = true); - -struct SYMBIANUTILS_EXPORT Library -{ - Library() {} - - QByteArray name; - uint codeseg; - uint dataseg; -}; - -struct SYMBIANUTILS_EXPORT TrkAppVersion -{ - TrkAppVersion(); - void reset(); - - int trkMajor; - int trkMinor; - int protocolMajor; - int protocolMinor; -}; - -struct SYMBIANUTILS_EXPORT Session -{ - Session(); - void reset(); - QString deviceDescription(unsigned verbose) const; - - // Trk feedback - byte cpuMajor; - byte cpuMinor; - byte bigEndian; - byte defaultTypeSize; - byte fpTypeSize; - byte extended1TypeSize; - byte extended2TypeSize; - TrkAppVersion trkAppVersion; - uint pid; - uint tid; - uint codeseg; - uint dataseg; - QHash addressToBP; - - typedef QList Libraries; - Libraries libraries; - - typedef uint Thread; - typedef QList Threads; - Threads threads; - - // Gdb request - uint currentThread; - QStringList modules; -}; - -struct SYMBIANUTILS_EXPORT TrkResult -{ - TrkResult(); - void clear(); - QString toString() const; - // 0 for no error. - int errorCode() const; - QString errorString() const; - - byte code; - byte token; - QByteArray data; - QVariant cookie; - bool isDebugOutput; -}; - -SYMBIANUTILS_EXPORT QByteArray errorMessage(byte code); -SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits = 0); -SYMBIANUTILS_EXPORT QByteArray hexxNumber(uint n, int digits = 0); // prepends '0x', too -SYMBIANUTILS_EXPORT uint swapEndian(uint in); - -} // namespace trk - -#endif // DEBUGGER_TRK_UTILS diff --git a/tools/runonphone/trk/trkutils_p.h b/tools/runonphone/trk/trkutils_p.h deleted file mode 100644 index 12b0109..0000000 --- a/tools/runonphone/trk/trkutils_p.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DEBUGGER_TRK_PRIVATE_UTILS -#define DEBUGGER_TRK_PRIVATE_UTILS - -#include "trkutils.h" -#include "symbianutils_global.h" - -QT_BEGIN_NAMESPACE -class QDateTime; -QT_END_NAMESPACE - -namespace trk { - -void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness = TargetByteOrder); -// returns a QByteArray containing optionally -// the serial frame [0x01 0x90 ] and 0x7e encoded7d(ba) 0x7e -QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame); -bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *r, QByteArray *rawData = 0); - -} // namespace trk - -#endif // DEBUGGER_TRK_PRIVATE_UTILS -- cgit v0.12 From 39709d61fbd4a17edf5f141877d312d3872ccce0 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 9 Feb 2010 11:56:37 +0100 Subject: Catch up symbianutils to creator 3efdb87682a5785bac7b90f9f9a8bb819a1cb053 commit 3efdb87682a5785bac7b90f9f9a8bb819a1cb053 Author: Friedemann Kleint Date: Mon Feb 8 14:10:51 2010 +0100 S60/Trk: Make the port a property of TrkDevice. Associate the port with the device instead of passing it to open for better handling. commit 76872c6ed8a1477f1914266d6917ee4aad6ff7e9 Author: Friedemann Kleint Date: Fri Feb 5 17:34:02 2010 +0100 S60: Move serialdevicelister.cpp to symbianutils/symbiandevicemanager.cpp --- .../symbianutils/communicationstarter.cpp | 21 +- .../runonphone/symbianutils/communicationstarter.h | 2 - tools/runonphone/symbianutils/launcher.cpp | 9 +- .../symbianutils/symbiandevicemanager.cpp | 331 +++++++++++++++++++++ .../runonphone/symbianutils/symbiandevicemanager.h | 145 +++++++++ tools/runonphone/symbianutils/symbianutils.pri | 6 +- tools/runonphone/symbianutils/trkdevice.cpp | 31 +- tools/runonphone/symbianutils/trkdevice.h | 6 +- tools/runonphone/symbianutils/trkutils.cpp | 1 + 9 files changed, 520 insertions(+), 32 deletions(-) create mode 100644 tools/runonphone/symbianutils/symbiandevicemanager.cpp create mode 100644 tools/runonphone/symbianutils/symbiandevicemanager.h diff --git a/tools/runonphone/symbianutils/communicationstarter.cpp b/tools/runonphone/symbianutils/communicationstarter.cpp index e5e556e..cdee49f 100644 --- a/tools/runonphone/symbianutils/communicationstarter.cpp +++ b/tools/runonphone/symbianutils/communicationstarter.cpp @@ -58,7 +58,6 @@ struct BaseCommunicationStarterPrivate { int intervalMS; int attempts; int n; - QString device; QString errorString; BaseCommunicationStarter::State state; }; @@ -70,7 +69,6 @@ BaseCommunicationStarterPrivate::BaseCommunicationStarterPrivate(const BaseCommu intervalMS(1000), attempts(-1), n(0), - device(QLatin1String("/dev/rfcomm0")), state(BaseCommunicationStarter::TimedOut) { } @@ -108,7 +106,7 @@ BaseCommunicationStarter::StartResult BaseCommunicationStarter::start() // Before we instantiate timers, and such, try to open the device, // which should succeed if another listener is already running in // 'Watch' mode - if (d->trkDevice->open(d->device , &(d->errorString))) + if (d->trkDevice->open(&(d->errorString))) return ConnectionSucceeded; // Pull up resources for next attempt d->n = 0; @@ -155,12 +153,7 @@ void BaseCommunicationStarter::setAttempts(int a) QString BaseCommunicationStarter::device() const { - return d->device; -} - -void BaseCommunicationStarter::setDevice(const QString &dv) -{ - d->device = dv; + return d->trkDevice->port(); } QString BaseCommunicationStarter::errorString() const @@ -175,20 +168,20 @@ void BaseCommunicationStarter::slotTimer() if (d->attempts >= 0 && d->n >= d->attempts) { stopTimer(); d->errorString = tr("%1: timed out after %n attempts using an interval of %2ms.", 0, d->n) - .arg(d->device).arg(d->intervalMS); + .arg(d->trkDevice->port()).arg(d->intervalMS); d->state = TimedOut; emit timeout(); } else { // Attempt n to connect? - if (d->trkDevice->open(d->device , &(d->errorString))) { + if (d->trkDevice->open(&(d->errorString))) { stopTimer(); - const QString msg = tr("%1: Connection attempt %2 succeeded.").arg(d->device).arg(d->n); + const QString msg = tr("%1: Connection attempt %2 succeeded.").arg(d->trkDevice->port()).arg(d->n); emit message(msg); d->state = Connected; emit connected(); } else { const QString msg = tr("%1: Connection attempt %2 failed: %3 (retrying)...") - .arg(d->device).arg(d->n).arg(d->errorString); + .arg(d->trkDevice->port()).arg(d->n).arg(d->errorString); emit message(msg); } } @@ -228,13 +221,11 @@ BluetoothListener *ConsoleBluetoothStarter::createListener() bool ConsoleBluetoothStarter::startBluetooth(const TrkDevicePtr &trkDevice, QObject *listenerParent, - const QString &device, int attempts, QString *errorMessage) { // Set up a console starter to print to stdout. ConsoleBluetoothStarter starter(trkDevice, listenerParent); - starter.setDevice(device); starter.setAttempts(attempts); switch (starter.start()) { case Started: diff --git a/tools/runonphone/symbianutils/communicationstarter.h b/tools/runonphone/symbianutils/communicationstarter.h index 2d7dc50..0a060ee 100644 --- a/tools/runonphone/symbianutils/communicationstarter.h +++ b/tools/runonphone/symbianutils/communicationstarter.h @@ -80,7 +80,6 @@ public: void setAttempts(int a); QString device() const; - void setDevice(const QString &); State state() const; QString errorString() const; @@ -142,7 +141,6 @@ class SYMBIANUTILS_EXPORT ConsoleBluetoothStarter : public AbstractBluetoothStar public: static bool startBluetooth(const TrkDevicePtr& trkDevice, QObject *listenerParent, - const QString &device, int attempts, QString *errorMessage); diff --git a/tools/runonphone/symbianutils/launcher.cpp b/tools/runonphone/symbianutils/launcher.cpp index 4f91545..408829b 100644 --- a/tools/runonphone/symbianutils/launcher.cpp +++ b/tools/runonphone/symbianutils/launcher.cpp @@ -67,7 +67,6 @@ struct LauncherPrivate { explicit LauncherPrivate(const TrkDevicePtr &d); TrkDevicePtr m_device; - QString m_trkServerName; QByteArray m_trkReadBuffer; Launcher::State m_state; @@ -131,12 +130,12 @@ void Launcher::addStartupActions(trk::Launcher::Actions startupActions) void Launcher::setTrkServerName(const QString &name) { - d->m_trkServerName = name; + d->m_device->setPort(name); } QString Launcher::trkServerName() const { - return d->m_trkServerName; + return d->m_device->port(); } TrkDevicePtr Launcher::trkDevice() const @@ -191,7 +190,7 @@ bool Launcher::startServer(QString *errorMessage) errorMessage->clear(); if (d->m_verbose) { const QString msg = QString::fromLatin1("Port=%1 Executable=%2 Arguments=%3 Package=%4 Remote Package=%5 Install file=%6") - .arg(d->m_trkServerName, d->m_fileName, + .arg(trkServerName(), d->m_fileName, d->m_commandLineArgs.join(QString(QLatin1Char(' '))), d->m_copyState.sourceFileName, d->m_copyState.destinationFileName, d->m_installFileName); logMessage(msg); @@ -213,7 +212,7 @@ bool Launcher::startServer(QString *errorMessage) qWarning("No remote executable given for running."); return false; } - if (!d->m_device->isOpen() && !d->m_device->open(d->m_trkServerName, errorMessage)) + if (!d->m_device->isOpen() && !d->m_device->open(errorMessage)) return false; if (d->m_closeDevice) { connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close())); diff --git a/tools/runonphone/symbianutils/symbiandevicemanager.cpp b/tools/runonphone/symbianutils/symbiandevicemanager.cpp new file mode 100644 index 0000000..f663816 --- /dev/null +++ b/tools/runonphone/symbianutils/symbiandevicemanager.cpp @@ -0,0 +1,331 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "symbiandevicemanager.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace SymbianUtils { + +enum { debug = 0 }; + +static const char REGKEY_CURRENT_CONTROL_SET[] = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet"; +static const char USBSER[] = "Services/usbser/Enum"; + +const char *SymbianDeviceManager::linuxBlueToothDeviceRootC = "/dev/rfcomm"; + +// ------------- SymbianDevice +class SymbianDeviceData : public QSharedData { +public: + SymbianDeviceData() : type(SerialPortCommunication) {} + + QString portName; + QString friendlyName; + QString deviceDesc; + QString manufacturer; + DeviceCommunicationType type; +}; + +SymbianDevice::SymbianDevice(SymbianDeviceData *data) : + m_data(data) +{ + +} + +SymbianDevice::SymbianDevice() : + m_data(new SymbianDeviceData) +{ +} +SymbianDevice::SymbianDevice(const SymbianDevice &rhs) : + m_data(rhs.m_data) +{ +} + +SymbianDevice &SymbianDevice::operator=(const SymbianDevice &rhs) +{ + if (this != &rhs) + m_data = rhs.m_data; + return *this; +} + +SymbianDevice::~SymbianDevice() +{ +} + +QString SymbianDevice::portName() const +{ + return m_data->portName; +} + +QString SymbianDevice::friendlyName() const +{ + return m_data->friendlyName; +} + +QString SymbianDevice::deviceDesc() const +{ + return m_data->deviceDesc; +} + +QString SymbianDevice::manufacturer() const +{ + return m_data->manufacturer; +} + +DeviceCommunicationType SymbianDevice::type() const +{ + return m_data->type; +} + +bool SymbianDevice::isNull() const +{ + return !m_data->portName.isEmpty(); +} + +QString SymbianDevice::toString() const +{ + QString rc; + QTextStream str(&rc); + format(str); + return rc; +} + +void SymbianDevice::format(QTextStream &str) const +{ + str << (m_data->type == BlueToothCommunication ? "Bluetooth: " : "Serial: ") + << m_data->portName; + if (!m_data->friendlyName.isEmpty()) { + str << " (" << m_data->friendlyName; + if (!m_data->deviceDesc.isEmpty()) + str << " / " << m_data->deviceDesc; + str << ')'; + } + if (!m_data->manufacturer.isEmpty()) + str << " [" << m_data->manufacturer << ']'; +} + +// Compare by port and friendly name +int SymbianDevice::compare(const SymbianDevice &rhs) const +{ + if (const int prc = m_data->portName.compare(rhs.m_data->portName)) + return prc; + if (const int frc = m_data->friendlyName.compare(rhs.m_data->friendlyName)) + return frc; + return 0; +} + +QDebug operator<<(QDebug d, const SymbianDevice &cd) +{ + d.nospace() << cd.toString(); + return d; +} + +// ------------- SymbianDeviceManagerPrivate +struct SymbianDeviceManagerPrivate { + SymbianDeviceManagerPrivate() : m_initialized(false) {} + + bool m_initialized; + SymbianDeviceManager::SymbianDeviceList m_devices; +}; + +SymbianDeviceManager::SymbianDeviceManager(QObject *parent) : + QObject(parent), + d(new SymbianDeviceManagerPrivate) +{ +} + +SymbianDeviceManager::~SymbianDeviceManager() +{ + delete d; +} + +SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::devices() const +{ + if (!d->m_initialized) + const_cast(this)->update(false); + return d->m_devices; +} + +QString SymbianDeviceManager::toString() const +{ + QString rc; + QTextStream str(&rc); + const int count = d->m_devices.size(); + for (int i = 0; i < count; i++) { + str << '#' << i << ' '; + d->m_devices.at(i).format(str); + str << '\n'; + } + return rc; +} + +QString SymbianDeviceManager::friendlyNameForPort(const QString &port) const +{ + foreach (const SymbianDevice &device, d->m_devices) { + if (device.portName() == port) + return device.friendlyName(); + } + return QString(); +} + +void SymbianDeviceManager::update() +{ + update(true); +} + +void SymbianDeviceManager::update(bool emitSignals) +{ + typedef SymbianDeviceList::iterator SymbianDeviceListIterator; + + if (debug) + qDebug(">SerialDeviceLister::update(%d)\n%s", int(emitSignals), + qPrintable(toString())); + + d->m_initialized = true; + // Get ordered new list + SymbianDeviceList newDevices = serialPorts() + blueToothDevices(); + if (newDevices.size() > 1) + qStableSort(newDevices.begin(), newDevices.end()); + if (d->m_devices == newDevices) // Happy, nothing changed. + return; + // Merge the lists and emit the respective added/removed signals, assuming + // no one can plug a different device on the same port at the speed of lightning + if (!d->m_devices.isEmpty()) { + // Find deleted devices + for (SymbianDeviceListIterator oldIt = d->m_devices.begin(); oldIt != d->m_devices.end(); ) { + if (newDevices.contains(*oldIt)) { + ++oldIt; + } else { + const SymbianDevice toBeDeleted = *oldIt; + oldIt = d->m_devices.erase(oldIt); + if (emitSignals) + emit deviceRemoved(toBeDeleted); + } + } + } + if (!newDevices.isEmpty()) { + // Find new devices and insert in order + foreach(const SymbianDevice &newDevice, newDevices) { + if (!d->m_devices.contains(newDevice)) { + d->m_devices.append(newDevice); + if (emitSignals) + emit deviceAdded(newDevice); + } + } + if (d->m_devices.size() > 1) + qStableSort(d->m_devices.begin(), d->m_devices.end()); + } + if (emitSignals) + emit updated(); + + if (debug) + qDebug(" 1) + qDebug() << "SerialDeviceLister::serialPorts(): Checking " << i << count + << REGKEY_CURRENT_CONTROL_SET << usbSerialRootKey << driverRootKey; + QScopedPointer device(new SymbianDeviceData); + device->type = SerialPortCommunication; + device->friendlyName = registry.value(driverRootKey + QLatin1String("FriendlyName")).toString(); + device->portName = registry.value(driverRootKey + QLatin1String("Device Parameters/PortName")).toString(); + device->deviceDesc = registry.value(driverRootKey + QLatin1String("DeviceDesc")).toString(); + device->manufacturer = registry.value(driverRootKey + QLatin1String("Mfg")).toString(); + rc.append(SymbianDevice(device.take())); + } + } +#endif + return rc; +} + +SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::blueToothDevices() const +{ + SymbianDeviceList rc; +#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) + // Bluetooth devices are created on connection. List the existing ones + // or at least the first one. + const QString prefix = QLatin1String(linuxBlueToothDeviceRootC); + const QString friendlyFormat = QLatin1String("Bluetooth device (%1)"); + for (int d = 0; d < 4; d++) { + QScopedPointer device(new SymbianDeviceData); + device->type = BlueToothCommunication; + device->portName = prefix + QString::number(d); + if (d == 0 || QFileInfo(device->portName).exists()) { + device->friendlyName = friendlyFormat.arg(device->portName); + rc.push_back(SymbianDevice(device.take())); + } + } +#endif + return rc; +} + +Q_GLOBAL_STATIC(SymbianDeviceManager, symbianDeviceManager) + +SymbianDeviceManager *SymbianDeviceManager::instance() +{ + return symbianDeviceManager(); +} + +QDebug operator<<(QDebug d, const SymbianDeviceManager &sdm) +{ + d.nospace() << sdm.toString(); + return d; +} + +} // namespace SymbianUtilsInternal diff --git a/tools/runonphone/symbianutils/symbiandevicemanager.h b/tools/runonphone/symbianutils/symbiandevicemanager.h new file mode 100644 index 0000000..dcf131a --- /dev/null +++ b/tools/runonphone/symbianutils/symbiandevicemanager.h @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIANDEVICEMANAGER_H +#define SYMBIANDEVICEMANAGER_H + +#include "symbianutils_global.h" + +#include +#include + +QT_BEGIN_NAMESPACE +class QDebug; +class QTextStream; +QT_END_NAMESPACE + +namespace SymbianUtils { + +struct SymbianDeviceManagerPrivate; +class SymbianDeviceData; + +enum DeviceCommunicationType { + SerialPortCommunication = 0, + BlueToothCommunication = 1 +}; + +// SymbianDevice, explicitly shared. +class SYMBIANUTILS_EXPORT SymbianDevice { + explicit SymbianDevice(SymbianDeviceData *data); + friend class SymbianDeviceManager; +public: + SymbianDevice(); + SymbianDevice(const SymbianDevice &rhs); + SymbianDevice &operator=(const SymbianDevice &rhs); + ~SymbianDevice(); + int compare(const SymbianDevice &rhs) const; + + DeviceCommunicationType type() const; + bool isNull() const; + QString portName() const; + QString friendlyName() const; + + // Windows only. + QString deviceDesc() const; + QString manufacturer() const; + + void format(QTextStream &str) const; + QString toString() const; + +private: + QExplicitlySharedDataPointer m_data; +}; + +QDebug operator<<(QDebug d, const SymbianDevice &); + +inline bool operator==(const SymbianDevice &d1, const SymbianDevice &d2) + { return d1.compare(d2) == 0; } +inline bool operator!=(const SymbianDevice &d1, const SymbianDevice &d2) + { return d1.compare(d2) != 0; } +inline bool operator<(const SymbianDevice &d1, const SymbianDevice &d2) + { return d1.compare(d2) < 0; } + +/* SymbianDeviceManager: Singleton that maintains a list of Symbian devices. + * and emits change signals. + * On Windows, the update slot must be connected to a signal + * emitted from an event handler listening for WM_DEVICECHANGE. */ +class SYMBIANUTILS_EXPORT SymbianDeviceManager : public QObject +{ + Q_OBJECT +public: + typedef QList SymbianDeviceList; + + static const char *linuxBlueToothDeviceRootC; + + // Do not use this constructor, it is just public for Q_GLOBAL_STATIC + explicit SymbianDeviceManager(QObject *parent = 0); + virtual ~SymbianDeviceManager(); + + // Singleton access. + static SymbianDeviceManager *instance(); + + SymbianDeviceList devices() const; + QString toString() const; + + QString friendlyNameForPort(const QString &port) const; + +public slots: + void update(); + +signals: + void deviceRemoved(const SymbianDevice &d); + void deviceAdded(const SymbianDevice &d); + void updated(); + +private: + void update(bool emitSignals); + SymbianDeviceList serialPorts() const; + SymbianDeviceList blueToothDevices() const; + + SymbianDeviceManagerPrivate *d; +}; + +QDebug operator<<(QDebug d, const SymbianDeviceManager &); + +} // namespace SymbianUtils + +#endif // SYMBIANDEVICEMANAGER_H diff --git a/tools/runonphone/symbianutils/symbianutils.pri b/tools/runonphone/symbianutils/symbianutils.pri index a54df76..6309517 100644 --- a/tools/runonphone/symbianutils/symbianutils.pri +++ b/tools/runonphone/symbianutils/symbianutils.pri @@ -8,13 +8,15 @@ HEADERS += $$PWD/symbianutils_global.h \ $$PWD/trkdevice.h \ $$PWD/launcher.h \ $$PWD/bluetoothlistener.h \ - $$PWD/communicationstarter.h + $$PWD/communicationstarter.h \ + $$PWD/symbiandevicemanager.h SOURCES += $$PWD/trkutils.cpp \ $$PWD/trkdevice.cpp \ $$PWD/launcher.cpp \ $$PWD/bluetoothlistener.cpp \ - $$PWD/communicationstarter.cpp + $$PWD/communicationstarter.cpp \ + $$PWD/symbiandevicemanager.cpp # Tests/trklauncher is a console application contains(QT, gui) { diff --git a/tools/runonphone/symbianutils/trkdevice.cpp b/tools/runonphone/symbianutils/trkdevice.cpp index d587135..b327ab3 100644 --- a/tools/runonphone/symbianutils/trkdevice.cpp +++ b/tools/runonphone/symbianutils/trkdevice.cpp @@ -883,6 +883,7 @@ struct TrkDevicePrivate QByteArray trkReadBuffer; int verbose; QString errorString; + QString port; }; /////////////////////////////////////////////////////////////////////// @@ -914,13 +915,19 @@ TrkDevice::~TrkDevice() delete d; } -bool TrkDevice::open(const QString &port, QString *errorMessage) +bool TrkDevice::open(QString *errorMessage) { if (d->verbose) - qDebug() << "Opening" << port << "is open: " << isOpen() << " serialFrame=" << serialFrame(); + qDebug() << "Opening" << port() << "is open: " << isOpen() << " serialFrame=" << serialFrame(); + if (d->port.isEmpty()) { + *errorMessage = QLatin1String("Internal error: No port set on TrkDevice"); + return false; + } + close(); #ifdef Q_OS_WIN - d->deviceContext->device = CreateFile(QString("\\\\.\\").append(port).toStdWString().c_str(), + const QString fullPort = QLatin1String("\\\\.\\") + d->port; + d->deviceContext->device = CreateFile(reinterpret_cast(fullPort.utf16()), GENERIC_READ | GENERIC_WRITE, 0, NULL, @@ -929,7 +936,7 @@ bool TrkDevice::open(const QString &port, QString *errorMessage) NULL); if (INVALID_HANDLE_VALUE == d->deviceContext->device) { - *errorMessage = QString::fromLatin1("Could not open device '%1': %2").arg(port, winErrorMessage(GetLastError())); + *errorMessage = QString::fromLatin1("Could not open device '%1': %2").arg(port(), winErrorMessage(GetLastError())); return false; } memset(&d->deviceContext->readOverlapped, 0, sizeof(OVERLAPPED)); @@ -941,9 +948,9 @@ bool TrkDevice::open(const QString &port, QString *errorMessage) return false; } #else - d->deviceContext->file.setFileName(port); + d->deviceContext->file.setFileName(d->port); if (!d->deviceContext->file.open(QIODevice::ReadWrite|QIODevice::Unbuffered)) { - *errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(port, d->deviceContext->file.errorString()); + *errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(d->port, d->deviceContext->file.errorString()); return false; } @@ -982,7 +989,7 @@ bool TrkDevice::open(const QString &port, QString *errorMessage) d->writerThread->start(); if (d->verbose) - qDebug() << "Opened" << port; + qDebug() << "Opened" << d->port; return true; } @@ -1016,6 +1023,16 @@ bool TrkDevice::isOpen() const #endif } +QString TrkDevice::port() const +{ + return d->port; +} + +void TrkDevice::setPort(const QString &p) +{ + d->port = p; +} + QString TrkDevice::errorString() const { return d->errorString; diff --git a/tools/runonphone/symbianutils/trkdevice.h b/tools/runonphone/symbianutils/trkdevice.h index 21a3cc1..78012fd 100644 --- a/tools/runonphone/symbianutils/trkdevice.h +++ b/tools/runonphone/symbianutils/trkdevice.h @@ -80,13 +80,17 @@ class SYMBIANUTILS_EXPORT TrkDevice : public QObject Q_OBJECT Q_PROPERTY(bool serialFrame READ serialFrame WRITE setSerialFrame) Q_PROPERTY(bool verbose READ verbose WRITE setVerbose) + Q_PROPERTY(QString port READ port WRITE setPort) public: explicit TrkDevice(QObject *parent = 0); virtual ~TrkDevice(); - bool open(const QString &port, QString *errorMessage); + bool open(QString *errorMessage); bool isOpen() const; + QString port() const; + void setPort(const QString &p); + QString errorString() const; bool serialFrame() const; diff --git a/tools/runonphone/symbianutils/trkutils.cpp b/tools/runonphone/symbianutils/trkutils.cpp index 5cce950..9b43c96 100644 --- a/tools/runonphone/symbianutils/trkutils.cpp +++ b/tools/runonphone/symbianutils/trkutils.cpp @@ -143,6 +143,7 @@ QString Session::deviceDescription(unsigned verbose) const return msg.arg(formatTrkVersion(trkAppVersion)); } +// -------------- QByteArray decode7d(const QByteArray &ba) { -- cgit v0.12 From b0c972dfd208411086b53ee2c2b0594ade3e2d10 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 9 Feb 2010 20:04:09 +0100 Subject: Add the download URI for smart installer package to documentation Task-number: QTBUG-8068 Reviewed-by: David Boddie --- doc/src/deployment/deployment.qdoc | 7 ++++++- doc/src/platforms/symbian-introduction.qdoc | 11 ++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/doc/src/deployment/deployment.qdoc b/doc/src/deployment/deployment.qdoc index 41babd9..43f5d33 100644 --- a/doc/src/deployment/deployment.qdoc +++ b/doc/src/deployment/deployment.qdoc @@ -1581,7 +1581,12 @@ \snippet doc/src/snippets/code/doc_src_deployment.qdoc 58 If everything compiled and linked without any errors, we are now ready to create - an application installation package (\c wiggly_installer.sis): + an application installation package (\c wiggly_installer.sis). + + If you haven't done so already, download the latest release of the Smart Installer + from \l{http://get.qt.nokia.com/nokiasmartinstaller/}, and install it on top of the Qt package + + Then use this command to create the installer sis package: \snippet doc/src/snippets/code/doc_src_deployment.qdoc 59 diff --git a/doc/src/platforms/symbian-introduction.qdoc b/doc/src/platforms/symbian-introduction.qdoc index 94075f5..5cebee3 100644 --- a/doc/src/platforms/symbian-introduction.qdoc +++ b/doc/src/platforms/symbian-introduction.qdoc @@ -127,7 +127,8 @@ \row \o \c run \o Run the application on the emulator. \row \o \c runonphone \o Run the application on a device. \row \o \c sis \o Create signed \c .sis file for project. - \row \o \c installer_sis \o Create signed smart installer \c .sis file for project. + \row \o \c installer_sis \o Create signed \l{Smart Installer}{smart installer} + \c .sis file for project. Smart installer will attempt to download missing dependencies in addition to just installing the application. @@ -141,6 +142,14 @@ To work on your project in Carbide, simply import the \c .pro file by right clicking on the project explorer and executing "Import...". + \section2 Smart Installer + + The Smart Installer makes sure that deployed applications have all the Qt dependencies + they need to run on a device. + + Download the latest release of the Smart Installer from \l{http://get.qt.nokia.com/nokiasmartinstaller/}, + and install it on top of the Qt package. + \section1 Installing your own applications To install your own applications on hardware, you need a signed \c .sis file. -- cgit v0.12 From 52e46af04738af62ad0da0daa161de707ff855e0 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 9 Feb 2010 18:12:12 +0100 Subject: Cannot drag actions in Designer on Mac OS X/Cocoa. QMimeData sub classes reimplementing the formats() might not expose the temporary "application/x-qt-mime-type-name" mimetype used by DnD. So make sure that the NSDragPboard PasteBoard will contain this dummy mime type. Task-number: QTBUG-7981 Reviewed-by: mortens --- src/gui/kernel/qclipboard_mac.cpp | 12 ++++++++++++ src/gui/kernel/qcocoaview_mac.mm | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qclipboard_mac.cpp b/src/gui/kernel/qclipboard_mac.cpp index f3a971d..49a6cc8 100644 --- a/src/gui/kernel/qclipboard_mac.cpp +++ b/src/gui/kernel/qclipboard_mac.cpp @@ -388,6 +388,18 @@ QMacPasteboard::setMimeData(QMimeData *mime_src) clear_helper(); QStringList formats = mime_src->formats(); +#ifdef QT_MAC_USE_COCOA + // QMimeData sub classes reimplementing the formats() might not expose the + // temporary "application/x-qt-mime-type-name" mimetype. So check the existence + // of this mime type while doing drag and drop. + QString dummyMimeType(QLatin1String("application/x-qt-mime-type-name")); + if (!formats.contains(dummyMimeType)) { + QByteArray dummyType = mime_src->data(dummyMimeType); + if (!dummyType.isEmpty()) { + formats.append(dummyMimeType); + } + } +#endif for(int f = 0; f < formats.size(); ++f) { QString mimeType = formats.at(f); for (QList::Iterator it = availableConverters.begin(); it != availableConverters.end(); ++it) { diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 2c35be2..756cf92 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -1404,7 +1404,7 @@ Qt::DropAction QDragManager::drag(QDrag *o) // setup the data QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacPasteboardMime::MIME_DND); - dragPrivate()->data->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray()); + dragPrivate()->data->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy")); dragBoard.setMimeData(dragPrivate()->data); // create the image -- cgit v0.12 From 3930b896eba50eb657c88923b2922a2fba0d6385 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 10 Feb 2010 10:27:32 +0100 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit/qtwebkit-4.6 ( 36fe058a9001e6d47f0fd41c6304cdfdf3a735ed ) Changes in WebKit/qt since the last update: * Missing fileSystemPath() method in Qt KURL implementation --- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 12 ++++++++++++ src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp | 6 ++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 4348cbc..2b39e81 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - da5d96a26e80162027bc95ce7e5725fe4b277ff7 + 36fe058a9001e6d47f0fd41c6304cdfdf3a735ed diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 1f6f290..61c2227 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,15 @@ +2010-01-14 Diego Gonzalez + + Reviewed by Kenneth Christiansen. + + [Qt] Missing fileSystemPath() method in Qt KURL implementation + https://bugs.webkit.org/show_bug.cgi?id=33614 + + No new tests. + + * platform/qt/KURLQt.cpp: + (WebCore::KURL::fileSystemPath): + 2010-02-01 Andreas Kling Reviewed by Kenneth Rohde Christiansen. diff --git a/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp index 0763fe0..1f62006 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp @@ -95,8 +95,10 @@ KURL::operator QUrl() const String KURL::fileSystemPath() const { - notImplemented(); - return String(); + if (!isValid() || !protocolIs("file")) + return String(); + + return String(path()); } } -- cgit v0.12 From 8c8aabdfac1518f9d62097ea5c80cea3d50131a3 Mon Sep 17 00:00:00 2001 From: Jedrzej Nowacki Date: Tue, 9 Feb 2010 16:32:10 +0200 Subject: Fix an unhandled exception in QScriptValue's test generator. $QT_END_LICENSE was interpreted as a template key by Template() object, causing substitute() call to throw a KeyError exception. The bug was introduced in 9962e2d96a212c518054220167eb6f61e1052bcc. Reviewed-by: TrustMe --- tests/auto/qscriptvalue/testgen/gen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qscriptvalue/testgen/gen.py b/tests/auto/qscriptvalue/testgen/gen.py index 7161e6b..b3c81b9 100755 --- a/tests/auto/qscriptvalue/testgen/gen.py +++ b/tests/auto/qscriptvalue/testgen/gen.py @@ -231,7 +231,7 @@ if __name__ == '__main__': row_esc = escape(row) out.append(qsvTempl.substitute(expr = row, expr_esc = row_esc)) - result = mainTempl.substitute(dump= "".join(out) \ + result = mainTempl.safe_substitute(dump= "".join(out) \ , values = (11 * ' ' + '<< ').join(qsv) \ , count = len(qsv) \ , dataTags = (11 * ' ' + '<< ').join(map(lambda w: '"' + escape(w.replace('\n','')) + '"\n', qsv))) -- cgit v0.12 From e6f401fb1a25f133bd3476ff327b2ba45fd741b7 Mon Sep 17 00:00:00 2001 From: Jedrzej Nowacki Date: Tue, 9 Feb 2010 16:39:03 +0200 Subject: Add new test values to QScriptValue test generator. Two new values were added; results from QScriptEngine::nullValue() and QScriptEngine::undefinedValue(). Reviewed-by: Kent Hansen --- tests/auto/qscriptvalue/testgen/data.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/qscriptvalue/testgen/data.txt b/tests/auto/qscriptvalue/testgen/data.txt index 8e7026e..a041c9b 100644 --- a/tests/auto/qscriptvalue/testgen/data.txt +++ b/tests/auto/qscriptvalue/testgen/data.txt @@ -114,3 +114,7 @@ engine->evaluate("/foo/") engine->evaluate("new Object()") engine->evaluate("new Array()") engine->evaluate("new Error()") + +#other +engine->nullValue() +engine->undefinedValue() \ No newline at end of file -- cgit v0.12 From caf93a2b6d3df012055ab70ad4bba1bb7b29141d Mon Sep 17 00:00:00 2001 From: Jedrzej Nowacki Date: Tue, 9 Feb 2010 16:47:51 +0200 Subject: Apply newly generated test values. Apply test results for values created directly from QScriptEngine (results of nullValue() and undefinedValue()) Reviewed-by: Kent Hansen --- .../qscriptvalue/tst_qscriptvalue_generated.cpp | 127 +++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue_generated.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue_generated.cpp index 1d105b4..4e621b3 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue_generated.cpp +++ b/tests/auto/qscriptvalue/tst_qscriptvalue_generated.cpp @@ -152,6 +152,8 @@ void tst_QScriptValue::initScriptValues() DEFINE_TEST_VALUE(engine->evaluate("new Object()")); DEFINE_TEST_VALUE(engine->evaluate("new Array()")); DEFINE_TEST_VALUE(engine->evaluate("new Error()")); + DEFINE_TEST_VALUE(engine->nullValue()); + DEFINE_TEST_VALUE(engine->undefinedValue()); } @@ -267,6 +269,8 @@ void tst_QScriptValue::isValid_makeData(const char* expr) << "engine->evaluate(\"new Object()\")" << "engine->evaluate(\"new Array()\")" << "engine->evaluate(\"new Error()\")" + << "engine->nullValue()" + << "engine->undefinedValue()" ; } newRow(expr) << isValid.contains(expr); @@ -453,6 +457,7 @@ void tst_QScriptValue::isNull_makeData(const char* expr) isNull << "QScriptValue(QScriptValue::NullValue)" << "QScriptValue(0, QScriptValue::NullValue)" << "QScriptValue(engine, QScriptValue::NullValue)" + << "engine->nullValue()" ; } newRow(expr) << isNull.contains(expr); @@ -535,6 +540,7 @@ void tst_QScriptValue::isUndefined_makeData(const char* expr) << "QScriptValue(0, QScriptValue::UndefinedValue)" << "QScriptValue(engine, QScriptValue::UndefinedValue)" << "engine->evaluate(\"{}\")" + << "engine->undefinedValue()" ; } newRow(expr) << isUndefined.contains(expr); @@ -810,6 +816,8 @@ void tst_QScriptValue::toString_makeData(const char* expr) toString.insert("engine->evaluate(\"new Object()\")", "[object Object]"); toString.insert("engine->evaluate(\"new Array()\")", ""); toString.insert("engine->evaluate(\"new Error()\")", "Error: Unknown error"); + toString.insert("engine->nullValue()", "null"); + toString.insert("engine->undefinedValue()", "undefined"); } newRow(expr) << toString.value(expr); } @@ -936,6 +944,8 @@ void tst_QScriptValue::toNumber_makeData(const char* expr) toNumber.insert("engine->evaluate(\"new Object()\")", qQNaN()); toNumber.insert("engine->evaluate(\"new Array()\")", 0); toNumber.insert("engine->evaluate(\"new Error()\")", qQNaN()); + toNumber.insert("engine->nullValue()", 0); + toNumber.insert("engine->undefinedValue()", qQNaN()); } newRow(expr) << toNumber.value(expr); } @@ -1070,6 +1080,8 @@ void tst_QScriptValue::toBool_makeData(const char* expr) toBool.insert("engine->evaluate(\"new Object()\")", true); toBool.insert("engine->evaluate(\"new Array()\")", true); toBool.insert("engine->evaluate(\"new Error()\")", true); + toBool.insert("engine->nullValue()", false); + toBool.insert("engine->undefinedValue()", false); } newRow(expr) << toBool.value(expr); } @@ -1196,6 +1208,8 @@ void tst_QScriptValue::toBoolean_makeData(const char* expr) toBoolean.insert("engine->evaluate(\"new Object()\")", true); toBoolean.insert("engine->evaluate(\"new Array()\")", true); toBoolean.insert("engine->evaluate(\"new Error()\")", true); + toBoolean.insert("engine->nullValue()", false); + toBoolean.insert("engine->undefinedValue()", false); } newRow(expr) << toBoolean.value(expr); } @@ -1322,6 +1336,8 @@ void tst_QScriptValue::toInteger_makeData(const char* expr) toInteger.insert("engine->evaluate(\"new Object()\")", 0); toInteger.insert("engine->evaluate(\"new Array()\")", 0); toInteger.insert("engine->evaluate(\"new Error()\")", 0); + toInteger.insert("engine->nullValue()", 0); + toInteger.insert("engine->undefinedValue()", 0); } newRow(expr) << toInteger.value(expr); } @@ -1452,6 +1468,8 @@ void tst_QScriptValue::toInt32_makeData(const char* expr) toInt32.insert("engine->evaluate(\"new Object()\")", 0); toInt32.insert("engine->evaluate(\"new Array()\")", 0); toInt32.insert("engine->evaluate(\"new Error()\")", 0); + toInt32.insert("engine->nullValue()", 0); + toInt32.insert("engine->undefinedValue()", 0); } newRow(expr) << toInt32.value(expr); } @@ -1578,6 +1596,8 @@ void tst_QScriptValue::toUInt32_makeData(const char* expr) toUInt32.insert("engine->evaluate(\"new Object()\")", 0); toUInt32.insert("engine->evaluate(\"new Array()\")", 0); toUInt32.insert("engine->evaluate(\"new Error()\")", 0); + toUInt32.insert("engine->nullValue()", 0); + toUInt32.insert("engine->undefinedValue()", 0); } newRow(expr) << toUInt32.value(expr); } @@ -1704,6 +1724,8 @@ void tst_QScriptValue::toUInt16_makeData(const char* expr) toUInt16.insert("engine->evaluate(\"new Object()\")", 0); toUInt16.insert("engine->evaluate(\"new Array()\")", 0); toUInt16.insert("engine->evaluate(\"new Error()\")", 0); + toUInt16.insert("engine->nullValue()", 0); + toUInt16.insert("engine->undefinedValue()", 0); } newRow(expr) << toUInt16.value(expr); } @@ -1736,6 +1758,8 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> engine->nullValue()"); + equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)"); @@ -1743,6 +1767,8 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(QScriptValue::NullValue) <=> engine->nullValue()"); + equals.insert("QScriptValue(QScriptValue::NullValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(true) <=> QScriptValue(true)"); equals.insert("QScriptValue(true) <=> QScriptValue(0, true)"); equals.insert("QScriptValue(true) <=> QScriptValue(engine, true)"); @@ -1937,6 +1963,8 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->nullValue()"); + equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)"); @@ -1944,6 +1972,8 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> engine->nullValue()"); + equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(0, true) <=> QScriptValue(true)"); equals.insert("QScriptValue(0, true) <=> QScriptValue(0, true)"); equals.insert("QScriptValue(0, true) <=> QScriptValue(engine, true)"); @@ -2138,6 +2168,8 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->nullValue()"); + equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)"); @@ -2145,6 +2177,8 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> engine->nullValue()"); + equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(engine, true) <=> QScriptValue(true)"); equals.insert("QScriptValue(engine, true) <=> QScriptValue(0, true)"); equals.insert("QScriptValue(engine, true) <=> QScriptValue(engine, true)"); @@ -2355,6 +2389,8 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("engine->evaluate(\"{}\") <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("engine->evaluate(\"{}\") <=> QScriptValue(engine, QScriptValue::NullValue)"); equals.insert("engine->evaluate(\"{}\") <=> engine->evaluate(\"{}\")"); + equals.insert("engine->evaluate(\"{}\") <=> engine->nullValue()"); + equals.insert("engine->evaluate(\"{}\") <=> engine->undefinedValue()"); equals.insert("engine->evaluate(\"Object.prototype\") <=> engine->evaluate(\"Object.prototype\")"); equals.insert("engine->evaluate(\"Date.prototype\") <=> engine->evaluate(\"Date.prototype\")"); equals.insert("engine->evaluate(\"Array.prototype\") <=> QScriptValue(false)"); @@ -2401,6 +2437,24 @@ void tst_QScriptValue::equals_makeData(const char *expr) equals.insert("engine->evaluate(\"new Array()\") <=> QScriptValue(engine, QString())"); equals.insert("engine->evaluate(\"new Array()\") <=> engine->evaluate(\"new Array()\")"); equals.insert("engine->evaluate(\"new Error()\") <=> engine->evaluate(\"new Error()\")"); + equals.insert("engine->nullValue() <=> QScriptValue(QScriptValue::UndefinedValue)"); + equals.insert("engine->nullValue() <=> QScriptValue(QScriptValue::NullValue)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, QScriptValue::UndefinedValue)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, QScriptValue::NullValue)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, QScriptValue::NullValue)"); + equals.insert("engine->nullValue() <=> engine->evaluate(\"{}\")"); + equals.insert("engine->nullValue() <=> engine->nullValue()"); + equals.insert("engine->nullValue() <=> engine->undefinedValue()"); + equals.insert("engine->undefinedValue() <=> QScriptValue(QScriptValue::UndefinedValue)"); + equals.insert("engine->undefinedValue() <=> QScriptValue(QScriptValue::NullValue)"); + equals.insert("engine->undefinedValue() <=> QScriptValue(0, QScriptValue::UndefinedValue)"); + equals.insert("engine->undefinedValue() <=> QScriptValue(0, QScriptValue::NullValue)"); + equals.insert("engine->undefinedValue() <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); + equals.insert("engine->undefinedValue() <=> QScriptValue(engine, QScriptValue::NullValue)"); + equals.insert("engine->undefinedValue() <=> engine->evaluate(\"{}\")"); + equals.insert("engine->undefinedValue() <=> engine->nullValue()"); + equals.insert("engine->undefinedValue() <=> engine->undefinedValue()"); } QHash::const_iterator it; for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) { @@ -2435,9 +2489,11 @@ void tst_QScriptValue::strictlyEquals_makeData(const char *expr) equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(QScriptValue::UndefinedValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)"); equals.insert("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); + equals.insert("QScriptValue(QScriptValue::NullValue) <=> engine->nullValue()"); equals.insert("QScriptValue(true) <=> QScriptValue(true)"); equals.insert("QScriptValue(true) <=> QScriptValue(0, true)"); equals.insert("QScriptValue(true) <=> QScriptValue(engine, true)"); @@ -2530,9 +2586,11 @@ void tst_QScriptValue::strictlyEquals_makeData(const char *expr) equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)"); equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); + equals.insert("QScriptValue(0, QScriptValue::NullValue) <=> engine->nullValue()"); equals.insert("QScriptValue(0, true) <=> QScriptValue(true)"); equals.insert("QScriptValue(0, true) <=> QScriptValue(0, true)"); equals.insert("QScriptValue(0, true) <=> QScriptValue(engine, true)"); @@ -2625,9 +2683,11 @@ void tst_QScriptValue::strictlyEquals_makeData(const char *expr) equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")"); + equals.insert("QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->undefinedValue()"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)"); equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)"); + equals.insert("QScriptValue(engine, QScriptValue::NullValue) <=> engine->nullValue()"); equals.insert("QScriptValue(engine, true) <=> QScriptValue(true)"); equals.insert("QScriptValue(engine, true) <=> QScriptValue(0, true)"); equals.insert("QScriptValue(engine, true) <=> QScriptValue(engine, true)"); @@ -2721,6 +2781,7 @@ void tst_QScriptValue::strictlyEquals_makeData(const char *expr) equals.insert("engine->evaluate(\"{}\") <=> QScriptValue(0, QScriptValue::UndefinedValue)"); equals.insert("engine->evaluate(\"{}\") <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); equals.insert("engine->evaluate(\"{}\") <=> engine->evaluate(\"{}\")"); + equals.insert("engine->evaluate(\"{}\") <=> engine->undefinedValue()"); equals.insert("engine->evaluate(\"Object.prototype\") <=> engine->evaluate(\"Object.prototype\")"); equals.insert("engine->evaluate(\"Date.prototype\") <=> engine->evaluate(\"Date.prototype\")"); equals.insert("engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"Array.prototype\")"); @@ -2737,6 +2798,15 @@ void tst_QScriptValue::strictlyEquals_makeData(const char *expr) equals.insert("engine->evaluate(\"new Object()\") <=> engine->evaluate(\"new Object()\")"); equals.insert("engine->evaluate(\"new Array()\") <=> engine->evaluate(\"new Array()\")"); equals.insert("engine->evaluate(\"new Error()\") <=> engine->evaluate(\"new Error()\")"); + equals.insert("engine->nullValue() <=> QScriptValue(QScriptValue::NullValue)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, QScriptValue::NullValue)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, QScriptValue::NullValue)"); + equals.insert("engine->nullValue() <=> engine->nullValue()"); + equals.insert("engine->undefinedValue() <=> QScriptValue(QScriptValue::UndefinedValue)"); + equals.insert("engine->undefinedValue() <=> QScriptValue(0, QScriptValue::UndefinedValue)"); + equals.insert("engine->undefinedValue() <=> QScriptValue(engine, QScriptValue::UndefinedValue)"); + equals.insert("engine->undefinedValue() <=> engine->evaluate(\"{}\")"); + equals.insert("engine->undefinedValue() <=> engine->undefinedValue()"); } QHash::const_iterator it; for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) { @@ -3090,6 +3160,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(-6.37e-8) <=> engine->evaluate(\"[]\")"); equals.insert("QScriptValue(-6.37e-8) <=> engine->evaluate(\"Array.prototype\")"); equals.insert("QScriptValue(-6.37e-8) <=> engine->evaluate(\"new Array()\")"); + equals.insert("QScriptValue(-6.37e-8) <=> engine->nullValue()"); equals.insert("QScriptValue(0x43211234) <=> QScriptValue(qInf())"); equals.insert("QScriptValue(0x43211234) <=> QScriptValue(\"Infinity\")"); equals.insert("QScriptValue(0x43211234) <=> QScriptValue(0, qInf())"); @@ -3180,6 +3251,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(-qInf()) <=> engine->evaluate(\"[]\")"); equals.insert("QScriptValue(-qInf()) <=> engine->evaluate(\"Array.prototype\")"); equals.insert("QScriptValue(-qInf()) <=> engine->evaluate(\"new Array()\")"); + equals.insert("QScriptValue(-qInf()) <=> engine->nullValue()"); equals.insert("QScriptValue(\"NaN\") <=> QScriptValue(\"ciao\")"); equals.insert("QScriptValue(\"NaN\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))"); equals.insert("QScriptValue(\"NaN\") <=> QScriptValue(0, \"ciao\")"); @@ -3291,6 +3363,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(\"-Infinity\") <=> engine->evaluate(\"/foo/\")"); equals.insert("QScriptValue(\"-Infinity\") <=> engine->evaluate(\"new Object()\")"); equals.insert("QScriptValue(\"-Infinity\") <=> engine->evaluate(\"new Error()\")"); + equals.insert("QScriptValue(\"-Infinity\") <=> engine->nullValue()"); equals.insert("QScriptValue(\"ciao\") <=> engine->evaluate(\"Function.prototype\")"); equals.insert("QScriptValue(\"ciao\") <=> engine->evaluate(\"Object\")"); equals.insert("QScriptValue(\"ciao\") <=> engine->evaluate(\"Array\")"); @@ -3903,6 +3976,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"[]\")"); equals.insert("QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"Array.prototype\")"); equals.insert("QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"new Array()\")"); + equals.insert("QScriptValue(0, -6.37e-8) <=> engine->nullValue()"); equals.insert("QScriptValue(0, 0x43211234) <=> QScriptValue(qInf())"); equals.insert("QScriptValue(0, 0x43211234) <=> QScriptValue(\"Infinity\")"); equals.insert("QScriptValue(0, 0x43211234) <=> QScriptValue(0, qInf())"); @@ -3993,6 +4067,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(0, -qInf()) <=> engine->evaluate(\"[]\")"); equals.insert("QScriptValue(0, -qInf()) <=> engine->evaluate(\"Array.prototype\")"); equals.insert("QScriptValue(0, -qInf()) <=> engine->evaluate(\"new Array()\")"); + equals.insert("QScriptValue(0, -qInf()) <=> engine->nullValue()"); equals.insert("QScriptValue(0, \"NaN\") <=> QScriptValue(\"ciao\")"); equals.insert("QScriptValue(0, \"NaN\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))"); equals.insert("QScriptValue(0, \"NaN\") <=> QScriptValue(0, \"ciao\")"); @@ -4104,6 +4179,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"/foo/\")"); equals.insert("QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"new Object()\")"); equals.insert("QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"new Error()\")"); + equals.insert("QScriptValue(0, \"-Infinity\") <=> engine->nullValue()"); equals.insert("QScriptValue(0, \"ciao\") <=> engine->evaluate(\"Function.prototype\")"); equals.insert("QScriptValue(0, \"ciao\") <=> engine->evaluate(\"Object\")"); equals.insert("QScriptValue(0, \"ciao\") <=> engine->evaluate(\"Array\")"); @@ -4717,6 +4793,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"[]\")"); equals.insert("QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"Array.prototype\")"); equals.insert("QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"new Array()\")"); + equals.insert("QScriptValue(engine, -6.37e-8) <=> engine->nullValue()"); equals.insert("QScriptValue(engine, 0x43211234) <=> QScriptValue(qInf())"); equals.insert("QScriptValue(engine, 0x43211234) <=> QScriptValue(\"Infinity\")"); equals.insert("QScriptValue(engine, 0x43211234) <=> QScriptValue(0, qInf())"); @@ -4807,6 +4884,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(engine, -qInf()) <=> engine->evaluate(\"[]\")"); equals.insert("QScriptValue(engine, -qInf()) <=> engine->evaluate(\"Array.prototype\")"); equals.insert("QScriptValue(engine, -qInf()) <=> engine->evaluate(\"new Array()\")"); + equals.insert("QScriptValue(engine, -qInf()) <=> engine->nullValue()"); equals.insert("QScriptValue(engine, \"NaN\") <=> QScriptValue(\"ciao\")"); equals.insert("QScriptValue(engine, \"NaN\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))"); equals.insert("QScriptValue(engine, \"NaN\") <=> QScriptValue(0, \"ciao\")"); @@ -4918,6 +4996,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"/foo/\")"); equals.insert("QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"new Object()\")"); equals.insert("QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"new Error()\")"); + equals.insert("QScriptValue(engine, \"-Infinity\") <=> engine->nullValue()"); equals.insert("QScriptValue(engine, \"ciao\") <=> engine->evaluate(\"Function.prototype\")"); equals.insert("QScriptValue(engine, \"ciao\") <=> engine->evaluate(\"Object\")"); equals.insert("QScriptValue(engine, \"ciao\") <=> engine->evaluate(\"Array\")"); @@ -5533,6 +5612,42 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) equals.insert("engine->evaluate(\"new Error()\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")"); equals.insert("engine->evaluate(\"new Error()\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")"); equals.insert("engine->evaluate(\"new Error()\") <=> engine->evaluate(\"new Object()\")"); + equals.insert("engine->nullValue() <=> QScriptValue(true)"); + equals.insert("engine->nullValue() <=> QScriptValue(int(122))"); + equals.insert("engine->nullValue() <=> QScriptValue(uint(124))"); + equals.insert("engine->nullValue() <=> QScriptValue(123.0)"); + equals.insert("engine->nullValue() <=> QScriptValue(6.37e-8)"); + equals.insert("engine->nullValue() <=> QScriptValue(0x43211234)"); + equals.insert("engine->nullValue() <=> QScriptValue(0x10000)"); + equals.insert("engine->nullValue() <=> QScriptValue(0x10001)"); + equals.insert("engine->nullValue() <=> QScriptValue(qInf())"); + equals.insert("engine->nullValue() <=> QScriptValue(\"Infinity\")"); + equals.insert("engine->nullValue() <=> QScriptValue(QString(\"123\"))"); + equals.insert("engine->nullValue() <=> QScriptValue(QString(\"12.4\"))"); + equals.insert("engine->nullValue() <=> QScriptValue(0, true)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, int(122))"); + equals.insert("engine->nullValue() <=> QScriptValue(0, uint(124))"); + equals.insert("engine->nullValue() <=> QScriptValue(0, 123.0)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, 6.37e-8)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, 0x43211234)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, 0x10000)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, 0x10001)"); + equals.insert("engine->nullValue() <=> QScriptValue(0, qInf())"); + equals.insert("engine->nullValue() <=> QScriptValue(0, \"Infinity\")"); + equals.insert("engine->nullValue() <=> QScriptValue(0, QString(\"123\"))"); + equals.insert("engine->nullValue() <=> QScriptValue(0, QString(\"12.3\"))"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, true)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, int(122))"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, uint(124))"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, 123.0)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, 6.37e-8)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, 0x43211234)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, 0x10000)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, 0x10001)"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, qInf())"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, \"Infinity\")"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, QString(\"123\"))"); + equals.insert("engine->nullValue() <=> QScriptValue(engine, QString(\"1.23\"))"); } QHash::const_iterator it; for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) { @@ -5718,6 +5833,8 @@ void tst_QScriptValue::qscriptvalue_castQString_makeData(const char* expr) value.insert("engine->evaluate(\"new Object()\")", "[object Object]"); value.insert("engine->evaluate(\"new Array()\")", ""); value.insert("engine->evaluate(\"new Error()\")", "Error: Unknown error"); + value.insert("engine->nullValue()", ""); + value.insert("engine->undefinedValue()", ""); } newRow(expr) << value.value(expr); } @@ -5844,6 +5961,8 @@ void tst_QScriptValue::qscriptvalue_castqsreal_makeData(const char* expr) value.insert("engine->evaluate(\"new Object()\")", qQNaN()); value.insert("engine->evaluate(\"new Array()\")", 0); value.insert("engine->evaluate(\"new Error()\")", qQNaN()); + value.insert("engine->nullValue()", 0); + value.insert("engine->undefinedValue()", qQNaN()); } newRow(expr) << value.value(expr); } @@ -5978,6 +6097,8 @@ void tst_QScriptValue::qscriptvalue_castbool_makeData(const char* expr) value.insert("engine->evaluate(\"new Object()\")", true); value.insert("engine->evaluate(\"new Array()\")", true); value.insert("engine->evaluate(\"new Error()\")", true); + value.insert("engine->nullValue()", false); + value.insert("engine->undefinedValue()", false); } newRow(expr) << value.value(expr); } @@ -6104,6 +6225,8 @@ void tst_QScriptValue::qscriptvalue_castqint32_makeData(const char* expr) value.insert("engine->evaluate(\"new Object()\")", 0); value.insert("engine->evaluate(\"new Array()\")", 0); value.insert("engine->evaluate(\"new Error()\")", 0); + value.insert("engine->nullValue()", 0); + value.insert("engine->undefinedValue()", 0); } newRow(expr) << value.value(expr); } @@ -6230,6 +6353,8 @@ void tst_QScriptValue::qscriptvalue_castquint32_makeData(const char* expr) value.insert("engine->evaluate(\"new Object()\")", 0); value.insert("engine->evaluate(\"new Array()\")", 0); value.insert("engine->evaluate(\"new Error()\")", 0); + value.insert("engine->nullValue()", 0); + value.insert("engine->undefinedValue()", 0); } newRow(expr) << value.value(expr); } @@ -6356,6 +6481,8 @@ void tst_QScriptValue::qscriptvalue_castquint16_makeData(const char* expr) value.insert("engine->evaluate(\"new Object()\")", 0); value.insert("engine->evaluate(\"new Array()\")", 0); value.insert("engine->evaluate(\"new Error()\")", 0); + value.insert("engine->nullValue()", 0); + value.insert("engine->undefinedValue()", 0); } newRow(expr) << value.value(expr); } -- cgit v0.12 From 37ffa8f59c5dc1f4a1174a07e0a6df6e266d40c0 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 10 Feb 2010 10:05:41 +0100 Subject: Stabilize QListView test on Mac --- tests/auto/qlistview/tst_qlistview.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index 2c31d8b..d2181f8 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -779,6 +779,7 @@ void tst_QListView::batchedMode() view.resize(200,400); view.show(); QTest::qWaitForWindowShown(&view); + QTest::qWait(100); #if defined(Q_OS_WINCE) QTest::qWait(2000); @@ -1846,6 +1847,7 @@ void tst_QListView::taskQTBUG_2233_scrollHiddenItems() view.setRowHidden(i, true); } QApplication::processEvents(); + QTest::qWait(50); QCOMPARE(bar->value(), bar->maximum()); QCOMPARE(bar->maximum(), rowCount/4 - nbVisibleItem); } -- cgit v0.12 From 31ba9218c63b6c0177fabae3ff33cc5f3c2df8d5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 10 Feb 2010 11:05:59 +0100 Subject: Fix warnings ~QX11PixmapData(): QPixmap objects must be destroyed.. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in the property browser solution. Reviewed-by: Trond Kjernåsen Task-number: QTBUG-8046 --- .../qtpropertybrowser/qtpropertybrowserutils.cpp | 16 +++-- .../qtpropertybrowser/qtpropertybrowserutils_p.h | 1 + .../shared/qtpropertybrowser/qtpropertymanager.cpp | 82 +++++++++++++--------- 3 files changed, 61 insertions(+), 38 deletions(-) diff --git a/tools/shared/qtpropertybrowser/qtpropertybrowserutils.cpp b/tools/shared/qtpropertybrowser/qtpropertybrowserutils.cpp index b84de11..0b14292 100644 --- a/tools/shared/qtpropertybrowser/qtpropertybrowserutils.cpp +++ b/tools/shared/qtpropertybrowser/qtpropertybrowserutils.cpp @@ -93,15 +93,23 @@ QtCursorDatabase::QtCursorDatabase() QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-busy.png"))); } +void QtCursorDatabase::clear() +{ + m_cursorNames.clear(); + m_cursorIcons.clear(); + m_valueToCursorShape.clear(); + m_cursorShapeToValue.clear(); +} + void QtCursorDatabase::appendCursor(Qt::CursorShape shape, const QString &name, const QIcon &icon) { if (m_cursorShapeToValue.contains(shape)) return; - int value = m_cursorNames.count(); + const int value = m_cursorNames.count(); m_cursorNames.append(name); - m_cursorIcons[value] = icon; - m_valueToCursorShape[value] = shape; - m_cursorShapeToValue[shape] = value; + m_cursorIcons.insert(value, icon); + m_valueToCursorShape.insert(value, shape); + m_cursorShapeToValue.insert(shape, value); } QStringList QtCursorDatabase::cursorShapeNames() const diff --git a/tools/shared/qtpropertybrowser/qtpropertybrowserutils_p.h b/tools/shared/qtpropertybrowser/qtpropertybrowserutils_p.h index b60fb94..baa7a4a 100644 --- a/tools/shared/qtpropertybrowser/qtpropertybrowserutils_p.h +++ b/tools/shared/qtpropertybrowser/qtpropertybrowserutils_p.h @@ -68,6 +68,7 @@ class QtCursorDatabase { public: QtCursorDatabase(); + void clear(); QStringList cursorShapeNames() const; QMap cursorShapeIcons() const; diff --git a/tools/shared/qtpropertybrowser/qtpropertymanager.cpp b/tools/shared/qtpropertybrowser/qtpropertymanager.cpp index 67ab2fb..d9ff10a 100644 --- a/tools/shared/qtpropertybrowser/qtpropertymanager.cpp +++ b/tools/shared/qtpropertybrowser/qtpropertymanager.cpp @@ -1391,16 +1391,54 @@ void QtStringPropertyManager::uninitializeProperty(QtProperty *property) } // QtBoolPropertyManager +// Return an icon containing a check box indicator +static QIcon drawCheckBox(bool value) +{ + QStyleOptionButton opt; + opt.state |= value ? QStyle::State_On : QStyle::State_Off; + opt.state |= QStyle::State_Enabled; + const QStyle *style = QApplication::style(); + // Figure out size of an indicator and make sure it is not scaled down in a list view item + // by making the pixmap as big as a list view icon and centering the indicator in it. + // (if it is smaller, it can't be helped) + const int indicatorWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &opt); + const int indicatorHeight = style->pixelMetric(QStyle::PM_IndicatorHeight, &opt); + const int listViewIconSize = indicatorWidth; + const int pixmapWidth = indicatorWidth; + const int pixmapHeight = qMax(indicatorHeight, listViewIconSize); + + opt.rect = QRect(0, 0, indicatorWidth, indicatorHeight); + QPixmap pixmap = QPixmap(pixmapWidth, pixmapHeight); + pixmap.fill(Qt::transparent); + { + // Center? + const int xoff = (pixmapWidth > indicatorWidth) ? (pixmapWidth - indicatorWidth) / 2 : 0; + const int yoff = (pixmapHeight > indicatorHeight) ? (pixmapHeight - indicatorHeight) / 2 : 0; + QPainter painter(&pixmap); + painter.translate(xoff, yoff); + style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt, &painter); + } + return QIcon(pixmap); +} class QtBoolPropertyManagerPrivate { QtBoolPropertyManager *q_ptr; Q_DECLARE_PUBLIC(QtBoolPropertyManager) public: + QtBoolPropertyManagerPrivate(); QMap m_values; + const QIcon m_checkedIcon; + const QIcon m_uncheckedIcon; }; +QtBoolPropertyManagerPrivate::QtBoolPropertyManagerPrivate() : + m_checkedIcon(drawCheckBox(true)), + m_uncheckedIcon(drawCheckBox(false)) +{ +} + /*! \class QtBoolPropertyManager \internal @@ -1471,36 +1509,6 @@ QString QtBoolPropertyManager::valueText(const QtProperty *property) const return it.value() ? trueText : falseText; } -// Return an icon containing a check box indicator -static QIcon drawCheckBox(bool value) -{ - QStyleOptionButton opt; - opt.state |= value ? QStyle::State_On : QStyle::State_Off; - opt.state |= QStyle::State_Enabled; - const QStyle *style = QApplication::style(); - // Figure out size of an indicator and make sure it is not scaled down in a list view item - // by making the pixmap as big as a list view icon and centering the indicator in it. - // (if it is smaller, it can't be helped) - const int indicatorWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &opt); - const int indicatorHeight = style->pixelMetric(QStyle::PM_IndicatorHeight, &opt); - const int listViewIconSize = indicatorWidth; - const int pixmapWidth = indicatorWidth; - const int pixmapHeight = qMax(indicatorHeight, listViewIconSize); - - opt.rect = QRect(0, 0, indicatorWidth, indicatorHeight); - QPixmap pixmap = QPixmap(pixmapWidth, pixmapHeight); - pixmap.fill(Qt::transparent); - { - // Center? - const int xoff = (pixmapWidth > indicatorWidth) ? (pixmapWidth - indicatorWidth) / 2 : 0; - const int yoff = (pixmapHeight > indicatorHeight) ? (pixmapHeight - indicatorHeight) / 2 : 0; - QPainter painter(&pixmap); - painter.translate(xoff, yoff); - style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt, &painter); - } - return QIcon(pixmap); -} - /*! \reimp */ @@ -1510,9 +1518,7 @@ QIcon QtBoolPropertyManager::valueIcon(const QtProperty *property) const if (it == d_ptr->m_values.constEnd()) return QIcon(); - static const QIcon checkedIcon = drawCheckBox(true); - static const QIcon uncheckedIcon = drawCheckBox(false); - return it.value() ? checkedIcon : uncheckedIcon; + return it.value() ? d_ptr->m_checkedIcon : d_ptr->m_uncheckedIcon; } /*! @@ -6287,7 +6293,15 @@ void QtColorPropertyManager::uninitializeProperty(QtProperty *property) // QtCursorPropertyManager -Q_GLOBAL_STATIC(QtCursorDatabase, cursorDatabase) +// Make sure icons are removed as soon as QApplication is destroyed, otherwise, +// handles are leaked on X11. +static void clearCursorDatabase(); +Q_GLOBAL_STATIC_WITH_INITIALIZER(QtCursorDatabase, cursorDatabase, qAddPostRoutine(clearCursorDatabase)) + +static void clearCursorDatabase() +{ + cursorDatabase()->clear(); +} class QtCursorPropertyManagerPrivate { -- cgit v0.12 From de88b9663c01691c64e2677444aab5c1b806c4c2 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 10 Feb 2010 12:12:00 +0200 Subject: Removed dependency to moc.exe from Symbian builds Having dependency to moc.exe makes no sense since we cannot build it anyway when building with Symbian toolchain. Task-number: QTBUG-7836 Reviewed-by: Janne Koskinen --- mkspecs/features/moc.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index 42ce1bc..e4b7dae 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -97,7 +97,7 @@ equals(MOC_DIR, .) { } #auto depend on moc -unix:!no_mocdepend { +unix:!symbian:!no_mocdepend { moc_source.depends += $$first(QMAKE_MOC) moc_header.depends += $$first(QMAKE_MOC) !contains(TARGET, moc) { #auto build moc -- cgit v0.12 From d7f8be6ec47bc8c241df95f7d13547a60362677b Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 10 Feb 2010 11:24:27 +0100 Subject: Make compile Reviewed-By: Alessandro Portale --- src/gui/text/qfontengine_s60.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp index 9dd4af7..3ea084b 100644 --- a/src/gui/text/qfontengine_s60.cpp +++ b/src/gui/text/qfontengine_s60.cpp @@ -44,7 +44,7 @@ #include "qglobal.h" #include #include "qimage.h" -#include "qt_s60_p.h" +#include #include #include -- cgit v0.12 From 72b510e78973e47c31ae60070cb74b41f291b1ec Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 10 Feb 2010 12:18:39 +0100 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit/qtwebkit-4.6 ( ffae5e11181a3961193fa21ea405851cad714d4b ) Changes in WebKit/qt since the last update: * https://bugs.webkit.org/show_bug.cgi?id=34170 -- [Qt] Javascript undefined > 0 returns true on Symbian --- src/3rdparty/webkit/JavaScriptCore/ChangeLog | 13 +++++++++++++ src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp | 4 ++++ src/3rdparty/webkit/VERSION | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index b943840..6446773 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,16 @@ +2010-02-09 Janne Koskinen + + Reviewed by Laszlo Gombos. + + [Qt] use nanval() for Symbian as nonInlineNaN + https://bugs.webkit.org/show_bug.cgi?id=34170 + + numeric_limits::quiet_NaN is broken in Symbian + causing NaN to be evaluated as a number. + + * runtime/JSValue.cpp: + (JSC::nonInlineNaN): + 2010-01-07 Norbert Leser Reviewed by NOBODY (OOPS!). diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp index 699c1cd..502312c 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp @@ -174,7 +174,11 @@ uint32_t toUInt32SlowCase(double d, bool& ok) NEVER_INLINE double nonInlineNaN() { +#if OS(SYMBIAN) + return nanval(); +#else return std::numeric_limits::quiet_NaN(); +#endif } } // namespace JSC diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 2b39e81..cc0e04f 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - 36fe058a9001e6d47f0fd41c6304cdfdf3a735ed + ffae5e11181a3961193fa21ea405851cad714d4b -- cgit v0.12 From 64233a38fe5a1755a6426caf55eaf8abbd4187ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Wed, 10 Feb 2010 12:48:55 +0100 Subject: Clarify QFont::rawName() docs. Task-number: related to QTBUG-8038 Reviewed-by: Kim --- src/gui/text/qfont.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index bbd35f1..dd9e69e 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -629,8 +629,9 @@ QFontEngineData::~QFontEngineData() Returns the name of the font within the underlying window system. - Only on X11 when Qt was built without FontConfig support the XLFD (X Logical Font Description) - is returned; otherwise an empty string. + On X11, this function will return an empty string if Qt is built with + FontConfig support; otherwise the XLFD (X Logical Font Description) is + returned. Using the return value of this function is usually \e not \e portable. -- cgit v0.12 From 709a3a4b96f4cc483e63958494adbc5efdf6c57d Mon Sep 17 00:00:00 2001 From: Janne Anttila Date: Wed, 10 Feb 2010 14:08:17 +0200 Subject: License update as requested by legal for file relicensed from S60. Rev-By: TrustMe --- src/3rdparty/s60/eiksoftkeyimage.h | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/3rdparty/s60/eiksoftkeyimage.h b/src/3rdparty/s60/eiksoftkeyimage.h index 84f6108a..a658421 100644 --- a/src/3rdparty/s60/eiksoftkeyimage.h +++ b/src/3rdparty/s60/eiksoftkeyimage.h @@ -39,23 +39,6 @@ ** ****************************************************************************/ -/* -* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: Changes cba button's label to image. -* -*/ - #ifndef EIKSOFTKEYIMAGE_H #define EIKSOFTKEYIMAGE_H -- cgit v0.12 From f04f014835e9fd4c41e9113e8036ba71ff884ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 10 Feb 2010 13:11:01 +0100 Subject: Prevented assert when using drop shadow effect in the GL 2 engine. The GL 2 pixmap filter uses Indexed8 images in the drop shadow case. Reviewed-by: Tom Cooksey --- src/gui/image/qpixmapfilter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index 7cf942c..2792e45 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -713,7 +713,8 @@ void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transp radius *= qreal(0.5); Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied - || img.format() == QImage::Format_RGB32); + || img.format() == QImage::Format_RGB32 + || img.format() == QImage::Format_Indexed8); // choose the alpha such that pixels at radius distance from a fully // saturated pixel will have an alpha component of no greater than -- cgit v0.12 From 0d1e1f26cd9c29e960117e23c57a84055f1cc9e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Wed, 10 Feb 2010 13:26:21 +0100 Subject: Fixed drawing pixmaps onto bitmaps on X11 w/o Xrender support. Task-number: QTBUG-8032 Reviewed-by: Kim --- src/gui/painting/qpaintengine_x11.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 147491e..da48fcb 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -1989,6 +1989,9 @@ void QX11PaintEngine::drawPixmap(const QRectF &r, const QPixmap &px, const QRect } XFillRectangle(d->dpy, d->hd, d->gc, x, y, sw, sh); restore_clip = true; + } else if (mono_dst && !mono_src) { + QBitmap bitmap(pixmap); + XCopyArea(d->dpy, bitmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y); } else { XCopyArea(d->dpy, pixmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y); } -- cgit v0.12 From e950fad2ab8b0c93da176ce2f07a4d45a3185cb4 Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Wed, 10 Feb 2010 14:00:57 +0100 Subject: Take into account the solaris-cc-64-stlport mkspec Reviewed-by: Simon Hausmann --- src/corelib/arch/sparc/arch.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/arch/sparc/arch.pri b/src/corelib/arch/sparc/arch.pri index 3113dd3..9bb3a88 100644 --- a/src/corelib/arch/sparc/arch.pri +++ b/src/corelib/arch/sparc/arch.pri @@ -1,7 +1,7 @@ # # SPARC architecture # -*-64 { +*-64* { SOURCES += $$QT_ARCH_CPP/qatomic64.s } else { -- cgit v0.12 From 0d27306664188a61571d31a38fec1d9040aae5f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Wed, 10 Feb 2010 14:19:08 +0100 Subject: Fixed drawing QPixmaps on QGLWidgets on different X11 screens. Don't try to use the texture_from_pixmap extension when drawing a pixmap from one X11 screen onto a different X11 screen in the GL 2 engine. For that to work, the pixmap will have to be re-created on the new screen, which is exactly what the default bind method does (via QImage conversion). Task-number: QTBUG-8054 Reviewed-by: Kim --- src/opengl/qgl.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index fce9fdb..0a89412 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -104,6 +104,10 @@ QT_BEGIN_NAMESPACE QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs; #endif +#ifdef Q_WS_X11 +extern const QX11Info *qt_x11Info(const QPaintDevice *pd); +#endif + struct QGLThreadContext { QGLContext *context; }; @@ -2350,7 +2354,10 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, #if defined(Q_WS_X11) // Try to use texture_from_pixmap - if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType) { + const QX11Info *xinfo = qt_x11Info(paintDevice); + if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType + && xinfo && xinfo->screen() == pixmap.x11Info().screen()) + { texture = bindTextureFromNativePixmap(pd, key, options); if (texture) { texture->options |= QGLContext::MemoryManagedBindOption; -- cgit v0.12 From 358bbd707bb5e0ce255559e45f8dedb9e9243a9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Wed, 10 Feb 2010 14:37:58 +0100 Subject: Fixed usage of QGLPixelBuffer with share widgets on other X11 screens. When trying to share the internal pbo context with a widget context, the pbo context needs to be created on the same X11 screen as the widget context. Task-number: QTBUG-8047 Reviewed-by: Kim --- src/opengl/qglpixelbuffer_x11.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/opengl/qglpixelbuffer_x11.cpp b/src/opengl/qglpixelbuffer_x11.cpp index 5b34cbb..32a42a2 100644 --- a/src/opengl/qglpixelbuffer_x11.cpp +++ b/src/opengl/qglpixelbuffer_x11.cpp @@ -181,7 +181,11 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge qt_format_to_attrib_list(f, attribs); - GLXFBConfig *configs = glXChooseFBConfig(X11->display, X11->defaultScreen, attribs, &num_configs); + int screen = X11->defaultScreen; + if (shareWidget) + screen = shareWidget->x11Info().screen(); + + GLXFBConfig *configs = glXChooseFBConfig(X11->display, screen, attribs, &num_configs); if (configs && num_configs) { int res; glXGetFBConfigAttrib(X11->display, configs[0], GLX_LEVEL, &res); -- cgit v0.12 From 5ab191af20bf2b1fed2b8886ac247c2953087c14 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 9 Feb 2010 12:33:52 +0100 Subject: Fixed compilation with QT_NO_WHEELEVENT Reviewed-by: Prasanth --- src/gui/kernel/qapplication_mac.mm | 6 ++++++ src/gui/kernel/qapplication_p.h | 2 ++ src/gui/kernel/qapplication_x11.cpp | 8 ++++++++ src/gui/kernel/qcocoaview_mac.mm | 3 +++ src/gui/util/qsystemtrayicon_p.h | 2 ++ src/gui/util/qsystemtrayicon_x11.cpp | 2 ++ src/gui/widgets/qabstractslider.cpp | 6 +++++- src/gui/widgets/qabstractspinbox.h | 2 ++ src/gui/widgets/qcombobox.h | 2 ++ src/gui/widgets/qmenu.h | 2 ++ src/gui/widgets/qscrollbar.cpp | 2 ++ 11 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index e8b821af..54a4901 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -2143,6 +2143,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event } if (wheel_deltaX || wheel_deltaY) { +#ifndef QT_NO_WHEELEVENT if (wheel_deltaX) { QWheelEvent qwe(plocal, p, wheel_deltaX, buttons, modifiers, Qt::Horizontal); QApplication::sendSpontaneousEvent(widget, &qwe); @@ -2165,6 +2166,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event handled_event = false; } } +#endif // QT_NO_WHEELEVENT } else { #ifdef QMAC_SPEAK_TO_ME const int speak_keys = Qt::AltModifier | Qt::ShiftModifier; @@ -2717,6 +2719,7 @@ int QApplication::keyboardInputInterval() return QApplicationPrivate::keyboard_input_time; } +#ifndef QT_NO_WHEELEVENT void QApplication::setWheelScrollLines(int n) { QApplicationPrivate::wheel_scroll_lines = n; @@ -2726,6 +2729,7 @@ int QApplication::wheelScrollLines() { return QApplicationPrivate::wheel_scroll_lines; } +#endif void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable) { @@ -2888,9 +2892,11 @@ bool QApplicationPrivate::qt_mac_apply_settings() QApplication::cursorFlashTime()).toInt(); QApplication::setCursorFlashTime(num); +#ifndef QT_NO_WHEELEVENT num = settings.value(QLatin1String("wheelScrollLines"), QApplication::wheelScrollLines()).toInt(); QApplication::setWheelScrollLines(num); +#endif QString colorspec = settings.value(QLatin1String("colorSpec"), QVariant(QLatin1String("default"))).toString(); diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 9c001ab..b3ec732 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -427,7 +427,9 @@ public: static int cursor_flash_time; static int mouse_double_click_time; static int keyboard_input_time; +#ifndef QT_NO_WHEELEVENT static int wheel_scroll_lines; +#endif static bool animate_ui; static bool animate_menu; diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 2a1f655..afd927b 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -944,10 +944,12 @@ bool QApplicationPrivate::x11_apply_settings() QApplication::cursorFlashTime()).toInt(); QApplication::setCursorFlashTime(num); +#ifndef QT_NO_WHEELEVENT num = settings.value(QLatin1String("wheelScrollLines"), QApplication::wheelScrollLines()).toInt(); QApplication::setWheelScrollLines(num); +#endif QString colorspec = settings.value(QLatin1String("colorSpec"), QVariant(QLatin1String("default"))).toString(); @@ -4401,8 +4403,10 @@ bool QETWidget::translateWheelEvent(int global_x, int global_y, int delta, QWidget* popup = qApp->activePopupWidget(); if (popup && window() != popup) popup->close(); +#ifndef QT_NO_WHEELEVENT QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient); if (QApplication::sendSpontaneousEvent(widget, &e)) +#endif return true; } @@ -4413,8 +4417,10 @@ bool QETWidget::translateWheelEvent(int global_x, int global_y, int delta, QWidget* popup = qApp->activePopupWidget(); if (popup && widget != popup) popup->hide(); +#ifndef QT_NO_WHEELEVENT QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient); if (QApplication::sendSpontaneousEvent(widget, &e)) +#endif return true; } return false; @@ -5313,6 +5319,7 @@ int QApplication::keyboardInputInterval() return QApplicationPrivate::keyboard_input_time; } +#ifndef QT_NO_WHEELEVENT void QApplication::setWheelScrollLines(int n) { QApplicationPrivate::wheel_scroll_lines = n; @@ -5322,6 +5329,7 @@ int QApplication::wheelScrollLines() { return QApplicationPrivate::wheel_scroll_lines; } +#endif void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable) { diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 756cf92..ad64a91 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -828,6 +828,7 @@ extern "C" { deltaZ = qBound(-120, int([theEvent deltaZ] * 10000), 120); } +#ifndef QT_NO_WHEELEVENT if (deltaX != 0) { QWheelEvent qwe(qlocal, qglobal, deltaX, buttons, keyMods, Qt::Horizontal); qt_sendSpontaneousEvent(widgetToGetMouse, &qwe); @@ -868,6 +869,8 @@ extern "C" { wheelOK = qwe2.isAccepted(); } } +#endif //QT_NO_WHEELEVENT + if (!wheelOK) { return [super scrollWheel:theEvent]; } diff --git a/src/gui/util/qsystemtrayicon_p.h b/src/gui/util/qsystemtrayicon_p.h index b881f68..e8bf197 100644 --- a/src/gui/util/qsystemtrayicon_p.h +++ b/src/gui/util/qsystemtrayicon_p.h @@ -164,7 +164,9 @@ protected: bool x11Event(XEvent *event); void mousePressEvent(QMouseEvent *event); void mouseDoubleClickEvent(QMouseEvent *event); +#ifndef QT_NO_WHEELEVENT void wheelEvent(QWheelEvent *event); +#endif bool event(QEvent *e); private: diff --git a/src/gui/util/qsystemtrayicon_x11.cpp b/src/gui/util/qsystemtrayicon_x11.cpp index a645050..82b4325 100644 --- a/src/gui/util/qsystemtrayicon_x11.cpp +++ b/src/gui/util/qsystemtrayicon_x11.cpp @@ -308,10 +308,12 @@ void QSystemTrayIconSys::mouseDoubleClickEvent(QMouseEvent *ev) emit q->activated(QSystemTrayIcon::DoubleClick); } +#ifndef QT_NO_WHEELEVENT void QSystemTrayIconSys::wheelEvent(QWheelEvent *e) { QApplication::sendEvent(q, e); } +#endif bool QSystemTrayIconSys::event(QEvent *e) { diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp index 73c17db..4bd7b5a 100644 --- a/src/gui/widgets/qabstractslider.cpp +++ b/src/gui/widgets/qabstractslider.cpp @@ -705,7 +705,11 @@ bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::Keyb // Calculate how many lines to scroll. Depending on what delta is (and // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can // only scroll whole lines, so we keep the reminder until next event. - qreal stepsToScrollF = offset * QApplication::wheelScrollLines() * effectiveSingleStep(); + qreal stepsToScrollF = +#ifndef QT_NO_WHEELEVENT + QApplication::wheelScrollLines() * +#endif + offset * effectiveSingleStep(); // Check if wheel changed direction since last event: if (offset_accumulated != 0 && (offset / offset_accumulated) < 0) offset_accumulated = 0; diff --git a/src/gui/widgets/qabstractspinbox.h b/src/gui/widgets/qabstractspinbox.h index 059943a..6c062c0 100644 --- a/src/gui/widgets/qabstractspinbox.h +++ b/src/gui/widgets/qabstractspinbox.h @@ -137,7 +137,9 @@ protected: void resizeEvent(QResizeEvent *event); void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); +#ifndef QT_NO_WHEELEVENT void wheelEvent(QWheelEvent *event); +#endif void focusInEvent(QFocusEvent *event); void focusOutEvent(QFocusEvent *event); void contextMenuEvent(QContextMenuEvent *event); diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h index f332d31..9b19a66 100644 --- a/src/gui/widgets/qcombobox.h +++ b/src/gui/widgets/qcombobox.h @@ -245,7 +245,9 @@ protected: void mouseReleaseEvent(QMouseEvent *e); void keyPressEvent(QKeyEvent *e); void keyReleaseEvent(QKeyEvent *e); +#ifndef QT_NO_WHEELEVENT void wheelEvent(QWheelEvent *e); +#endif void contextMenuEvent(QContextMenuEvent *e); void inputMethodEvent(QInputMethodEvent *); QVariant inputMethodQuery(Qt::InputMethodQuery) const; diff --git a/src/gui/widgets/qmenu.h b/src/gui/widgets/qmenu.h index 5a6a5c7..47dff2b 100644 --- a/src/gui/widgets/qmenu.h +++ b/src/gui/widgets/qmenu.h @@ -162,7 +162,9 @@ protected: void mouseReleaseEvent(QMouseEvent *); void mousePressEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); +#ifndef QT_NO_WHEELEVENT void wheelEvent(QWheelEvent *); +#endif void enterEvent(QEvent *); void leaveEvent(QEvent *); void hideEvent(QHideEvent *); diff --git a/src/gui/widgets/qscrollbar.cpp b/src/gui/widgets/qscrollbar.cpp index 3eed3a9..4eff260 100644 --- a/src/gui/widgets/qscrollbar.cpp +++ b/src/gui/widgets/qscrollbar.cpp @@ -521,6 +521,7 @@ bool QScrollBar::event(QEvent *event) if (const QHoverEvent *he = static_cast(event)) d_func()->updateHoverControl(he->pos()); break; +#ifndef QT_NO_WHEELEVENT case QEvent::Wheel: { // override wheel event without adding virtual function override QWheelEvent *ev = static_cast(event); @@ -537,6 +538,7 @@ bool QScrollBar::event(QEvent *event) event->accept(); return true; } +#endif default: break; } -- cgit v0.12 From 620dd47c3b790b99f76793f4b4e6f22e3984558e Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 10 Feb 2010 17:26:24 +0100 Subject: Blinking cursors are 2 pixels wide on Mac OS X/Cocoa. Blinking cursors drawn in positions other than zero, can become 2 pixel wide. This is caused by a rendering bug in the paint engine used by Cocoa. If a fillRect() is called in a nox pixel boundary this engine draws them 2 pixels wide instead of one. So make sure this is always on a pixel boundary. Task-number: QTBUG-8100 Reviewed-by: Trond --- src/gui/text/qtextlayout.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 26c7c1e..af91603 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1331,7 +1331,7 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition QTextLine l(line, d); const QScriptLine &sl = d->lines[line]; - const qreal x = position.x() + l.cursorToX(cursorPosition); + qreal x = position.x() + l.cursorToX(cursorPosition); int itm = d->findItem(cursorPosition - 1); QFixed base = sl.base(); @@ -1350,6 +1350,10 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition && (p->transform().type() > QTransform::TxTranslate); if (toggleAntialiasing) p->setRenderHint(QPainter::Antialiasing); +#if defined(QT_MAC_USE_COCOA) + // Always draw the cursor aligned to pixel boundary. + x = qRound(x); +#endif p->fillRect(QRectF(x, y, qreal(width), (base + descent + 1).toReal()), p->pen().brush()); if (toggleAntialiasing) p->setRenderHint(QPainter::Antialiasing, false); -- cgit v0.12 From 1407f3c1815addf6b9cac7503d38b670bbeab895 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 10 Feb 2010 17:39:59 +0100 Subject: Fix the WebKit build It's PLATFORM(SYMBIAN) in 4.x, not OS() like in the trunk Reviewed-by: Trust me --- src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp index 502312c..bafb85b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp @@ -174,7 +174,7 @@ uint32_t toUInt32SlowCase(double d, bool& ok) NEVER_INLINE double nonInlineNaN() { -#if OS(SYMBIAN) +#if PLATFORM(SYMBIAN) return nanval(); #else return std::numeric_limits::quiet_NaN(); -- cgit v0.12 From 24239b56ab563a30facde3a5217536e7276f9bb8 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 14 Dec 2009 10:23:39 -0800 Subject: Export a function to get dfb-surface from a pixmap This function is only exported when DirectFB is built as part of libQtGui. Reviewed-by: Jervey Kong --- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index f27440e..ba50329 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -593,6 +593,17 @@ void QDirectFBPixmapData::invalidate() imageFormat = QImage::Format_Invalid; } +#ifndef QT_DIRECTFB_PLUGIN +Q_GUI_EXPORT IDirectFBSurface *qt_directfb_surface_for_pixmap(const QPixmap &pixmap) +{ + const QPixmapData *data = pixmap.pixmapData(); + if (!data || data->classId() != QPixmapData::DirectFBClass) + return 0; + const QDirectFBPixmapData *dfbData = static_cast(data); + return dfbData->directFBSurface(); +} +#endif + QT_END_NAMESPACE #endif // QT_NO_QWS_DIRECTFB -- cgit v0.12 From f627b87822f92aaf060271ab16e64088df1be32e Mon Sep 17 00:00:00 2001 From: Iain Date: Wed, 10 Feb 2010 23:27:17 +0100 Subject: Update Symbian DEF files Reserve ordinal numbers in the WINSCW DEF file for EGL exports from QtGui (now added, but marked as ABSENT) Update OpenVG DEF files for EABI and WINSCW Update QtGui DEF file for WINSCW with 2 non-EGL-related exports Reviewed-by: TrustMe --- src/s60installs/bwins/QtGuiu.def | 53 +++++++++++++++++++++++++++++++++++++ src/s60installs/bwins/QtOpenVGu.def | 29 ++++++++++++++++++-- src/s60installs/eabi/QtOpenVGu.def | 23 ++++++++++++++++ 3 files changed, 103 insertions(+), 2 deletions(-) diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index be7a6a0..4f30cb5 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -12548,4 +12548,57 @@ EXPORTS ?timerEvent@QS60Style@@MAEXPAVQTimerEvent@@@Z @ 12547 NONAME ; void QS60Style::timerEvent(class QTimerEvent *) ?updateAncestorFlags@QGraphicsItemPrivate@@QAEXXZ @ 12548 NONAME ; void QGraphicsItemPrivate::updateAncestorFlags(void) ?updateChildWithGraphicsEffectFlagRecursively@QGraphicsItemPrivate@@QAEXXZ @ 12549 NONAME ; void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively(void) + ?isOpacityNull@QGraphicsItemPrivate@@SA_NM@Z @ 12550 NONAME ; bool QGraphicsItemPrivate::isOpacityNull(float) + ?isOpacityNull@QGraphicsItemPrivate@@QBE_NXZ @ 12551 NONAME ; bool QGraphicsItemPrivate::isOpacityNull(void) const + ?api@QEglContext@@QBE?AW4API@QEgl@@XZ @ 12552 NONAME ABSENT ; enum QEgl::API QEglContext::api(void) const + ?chooseConfig@QEglContext@@QAE_NABVQEglProperties@@W4PixelFormatMatch@QEgl@@@Z @ 12553 NONAME ABSENT ; bool QEglContext::chooseConfig(class QEglProperties const &, enum QEgl::PixelFormatMatch) + ?destroySurface@QEglContext@@QAEXH@Z @ 12554 NONAME ABSENT ; void QEglContext::destroySurface(int) + ?lazyDoneCurrent@QEglContext@@QAE_NXZ @ 12555 NONAME ABSENT ; bool QEglContext::lazyDoneCurrent(void) + ?waitNative@QEglContext@@QAEXXZ @ 12556 NONAME ABSENT ; void QEglContext::waitNative(void) + ?context@QEglContext@@QBEHXZ @ 12557 NONAME ABSENT ; int QEglContext::context(void) const + ?configAttrib@QEglContext@@QBE_NHPAH@Z @ 12558 NONAME ABSENT ; bool QEglContext::configAttrib(int, int *) const + ??0QEglProperties@@QAE@ABV0@@Z @ 12559 NONAME ABSENT ; QEglProperties::QEglProperties(class QEglProperties const &) + ?config@QEglContext@@QBEHXZ @ 12560 NONAME ABSENT ; int QEglContext::config(void) const + ?openDisplay@QEglContext@@QAE_NPAVQPaintDevice@@@Z @ 12561 NONAME ABSENT ; bool QEglContext::openDisplay(class QPaintDevice *) + ?error@QEglContext@@SAHXZ @ 12562 NONAME ABSENT ; int QEglContext::error(void) + ?swapBuffers@QEglContext@@QAE_NH@Z @ 12563 NONAME ABSENT ; bool QEglContext::swapBuffers(int) + ?setApi@QEglContext@@QAEXW4API@QEgl@@@Z @ 12564 NONAME ABSENT ; void QEglContext::setApi(enum QEgl::API) + ?makeCurrent@QEglContext@@QAE_NH@Z @ 12565 NONAME ABSENT ; bool QEglContext::makeCurrent(int) + ?createSurface@QEglContext@@QAEHPAVQPaintDevice@@PBVQEglProperties@@@Z @ 12566 NONAME ABSENT ; int QEglContext::createSurface(class QPaintDevice *, class QEglProperties const *) + ?dumpAllConfigs@QEglContext@@QAEXXZ @ 12567 NONAME ABSENT ; void QEglContext::dumpAllConfigs(void) + ?reduceConfiguration@QEglProperties@@QAE_NXZ @ 12568 NONAME ABSENT ; bool QEglProperties::reduceConfiguration(void) + ?removeValue@QEglProperties@@QAE_NH@Z @ 12569 NONAME ABSENT ; bool QEglProperties::removeValue(int) + ?toString@QEglProperties@@QBE?AVQString@@XZ @ 12570 NONAME ABSENT ; class QString QEglProperties::toString(void) const + ?dumpAllConfigs@QEglProperties@@SAXXZ @ 12571 NONAME ABSENT ; void QEglProperties::dumpAllConfigs(void) + ?defaultDisplay@QEglContext@@SAHPAVQPaintDevice@@@Z @ 12572 NONAME ABSENT ; int QEglContext::defaultDisplay(class QPaintDevice *) + ?configProperties@QEglContext@@QBE?AVQEglProperties@@H@Z @ 12573 NONAME ABSENT ; class QEglProperties QEglContext::configProperties(int) const + ?properties@QEglProperties@@QBEPBHXZ @ 12574 NONAME ABSENT ; int const * QEglProperties::properties(void) const + ??0QEglContext@@QAE@XZ @ 12575 NONAME ABSENT ; QEglContext::QEglContext(void) + ??1QEglContext@@QAE@XZ @ 12576 NONAME ABSENT ; QEglContext::~QEglContext(void) + ?isValid@QEglContext@@QBE_NXZ @ 12577 NONAME ABSENT ; bool QEglContext::isValid(void) const + ?value@QEglProperties@@QBEHH@Z @ 12578 NONAME ABSENT ; int QEglProperties::value(int) const + ?clearError@QEglContext@@SAXXZ @ 12579 NONAME ABSENT ; void QEglContext::clearError(void) + ??0QEglProperties@@QAE@H@Z @ 12580 NONAME ABSENT ; QEglProperties::QEglProperties(int) + ?setValue@QEglProperties@@QAEXHH@Z @ 12581 NONAME ABSENT ; void QEglProperties::setValue(int, int) + ?setPaintDeviceFormat@QEglProperties@@QAEXPAVQPaintDevice@@@Z @ 12582 NONAME ABSENT ; void QEglProperties::setPaintDeviceFormat(class QPaintDevice *) + ?destroy@QEglContext@@QAEXXZ @ 12583 NONAME ABSENT ; void QEglContext::destroy(void) + ?setRenderableType@QEglProperties@@QAEXW4API@QEgl@@@Z @ 12584 NONAME ABSENT ; void QEglProperties::setRenderableType(enum QEgl::API) + ?setContext@QEglContext@@QAEXH@Z @ 12585 NONAME ABSENT ; void QEglContext::setContext(int) + ?waitClient@QEglContext@@QAEXXZ @ 12586 NONAME ABSENT ; void QEglContext::waitClient(void) + ?isEmpty@QEglProperties@@QBE_NXZ @ 12587 NONAME ABSENT ; bool QEglProperties::isEmpty(void) const + ?getDisplay@QEglContext@@CAHPAVQPaintDevice@@@Z @ 12588 NONAME ABSENT ; int QEglContext::getDisplay(class QPaintDevice *) + ?isSharing@QEglContext@@QBE_NXZ @ 12589 NONAME ABSENT ; bool QEglContext::isSharing(void) const + ?isCurrent@QEglContext@@QBE_NXZ @ 12590 NONAME ABSENT ; bool QEglContext::isCurrent(void) const + ??0QEglProperties@@QAE@XZ @ 12591 NONAME ABSENT ; QEglProperties::QEglProperties(void) + ?extensions@QEglContext@@SA?AVQString@@XZ @ 12592 NONAME ABSENT ; class QString QEglContext::extensions(void) + ?setCurrentContext@QEglContext@@CAXW4API@QEgl@@PAV1@@Z @ 12593 NONAME ABSENT ; void QEglContext::setCurrentContext(enum QEgl::API, class QEglContext *) + ??1QEglProperties@@QAE@XZ @ 12594 NONAME ABSENT ; QEglProperties::~QEglProperties(void) + ?createContext@QEglContext@@QAE_NPAV1@PBVQEglProperties@@@Z @ 12595 NONAME ABSENT ; bool QEglContext::createContext(class QEglContext *, class QEglProperties const *) + ?setConfig@QEglContext@@QAEXH@Z @ 12596 NONAME ABSENT ; void QEglContext::setConfig(int) + ?hasExtension@QEglContext@@SA_NPBD@Z @ 12597 NONAME ABSENT ; bool QEglContext::hasExtension(char const *) + ?doneCurrent@QEglContext@@QAE_NXZ @ 12598 NONAME ABSENT ; bool QEglContext::doneCurrent(void) + ?display@QEglContext@@QBEHXZ @ 12599 NONAME ABSENT ; int QEglContext::display(void) const + ?setPixelFormat@QEglProperties@@QAEXW4Format@QImage@@@Z @ 12600 NONAME ABSENT ; void QEglProperties::setPixelFormat(enum QImage::Format) + ?currentContext@QEglContext@@CAPAV1@W4API@QEgl@@@Z @ 12601 NONAME ABSENT ; class QEglContext * QEglContext::currentContext(enum QEgl::API) + ?errorString@QEglContext@@SA?AVQString@@H@Z @ 12602 NONAME ABSENT ; class QString QEglContext::errorString(int) diff --git a/src/s60installs/bwins/QtOpenVGu.def b/src/s60installs/bwins/QtOpenVGu.def index 88e724f..26ee862 100644 --- a/src/s60installs/bwins/QtOpenVGu.def +++ b/src/s60installs/bwins/QtOpenVGu.def @@ -48,7 +48,7 @@ EXPORTS ?paintEngine@QVGWindowSurface@@UBEPAVQPaintEngine@@XZ @ 47 NONAME ; class QPaintEngine * QVGWindowSurface::paintEngine(void) const ??0QVGPainterState@@QAE@XZ @ 48 NONAME ; QVGPainterState::QVGPainterState(void) ?d_func@QVGPaintEngine@@ABEPBVQVGPaintEnginePrivate@@XZ @ 49 NONAME ; class QVGPaintEnginePrivate const * QVGPaintEngine::d_func(void) const - ?qt_vg_create_context@@YAPAVQEglContext@@PAVQPaintDevice@@@Z @ 50 NONAME ; class QEglContext * qt_vg_create_context(class QPaintDevice *) + ?qt_vg_create_context@@YAPAVQEglContext@@PAVQPaintDevice@@@Z @ 50 NONAME ABSENT ; class QEglContext * qt_vg_create_context(class QPaintDevice *) ?clip@QVGPaintEngine@@UAEXABVQRegion@@W4ClipOperation@Qt@@@Z @ 51 NONAME ; void QVGPaintEngine::clip(class QRegion const &, enum Qt::ClipOperation) ?endNativePainting@QVGPaintEngine@@UAEXXZ @ 52 NONAME ; void QVGPaintEngine::endNativePainting(void) ?brushChanged@QVGPaintEngine@@UAEXXZ @ 53 NONAME ; void QVGPaintEngine::brushChanged(void) @@ -78,7 +78,7 @@ EXPORTS ?beginPaint@QVGEGLWindowSurfaceVGImage@@UAEXPAVQWidget@@@Z @ 77 NONAME ; void QVGEGLWindowSurfaceVGImage::beginPaint(class QWidget *) ?createState@QVGPaintEngine@@UBEPAVQPainterState@@PAV2@@Z @ 78 NONAME ; class QPainterState * QVGPaintEngine::createState(class QPainterState *) const ?buffer@QVGPixmapData@@UAEPAVQImage@@XZ @ 79 NONAME ; class QImage * QVGPixmapData::buffer(void) - ?qt_vg_destroy_context@@YAXPAVQEglContext@@@Z @ 80 NONAME ; void qt_vg_destroy_context(class QEglContext *) + ?qt_vg_destroy_context@@YAXPAVQEglContext@@@Z @ 80 NONAME ABSENT ; void qt_vg_destroy_context(class QEglContext *) ?clip@QVGPaintEngine@@UAEXABVQVectorPath@@W4ClipOperation@Qt@@@Z @ 81 NONAME ; void QVGPaintEngine::clip(class QVectorPath const &, enum Qt::ClipOperation) ?drawPolygon@QVGPaintEngine@@UAEXPBVQPoint@@HW4PolygonDrawMode@QPaintEngine@@@Z @ 82 NONAME ; void QVGPaintEngine::drawPolygon(class QPoint const *, int, enum QPaintEngine::PolygonDrawMode) ?fromImage@QVGPixmapData@@UAEXABVQImage@@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 83 NONAME ; void QVGPixmapData::fromImage(class QImage const &, class QFlags) @@ -139,4 +139,29 @@ EXPORTS ??_EQVGPaintEngine@@UAE@I@Z @ 138 NONAME ; QVGPaintEngine::~QVGPaintEngine(unsigned int) ?clip@QVGPaintEngine@@UAEXABVQPainterPath@@W4ClipOperation@Qt@@@Z @ 139 NONAME ; void QVGPaintEngine::clip(class QPainterPath const &, enum Qt::ClipOperation) ?vgPrivate@QVGPaintEngine@@QAEPAVQVGPaintEnginePrivate@@XZ @ 140 NONAME ; class QVGPaintEnginePrivate * QVGPaintEngine::vgPrivate(void) + ?removeFromLRU@QVGImagePool@@IAEXPAVQVGPixmapData@@@Z @ 141 NONAME ; void QVGImagePool::removeFromLRU(class QVGPixmapData *) + ?releaseImage@QVGImagePool@@UAEXPAVQVGPixmapData@@K@Z @ 142 NONAME ; void QVGImagePool::releaseImage(class QVGPixmapData *, unsigned long) + ?d_func@QVGImagePool@@AAEPAVQVGImagePoolPrivate@@XZ @ 143 NONAME ; class QVGImagePoolPrivate * QVGImagePool::d_func(void) + ?detachImageFromPool@QVGPixmapData@@UAEXXZ @ 144 NONAME ; void QVGPixmapData::detachImageFromPool(void) + ?createImageForPixmap@QVGImagePool@@UAEKW4VGImageFormat@@JJKPAVQVGPixmapData@@@Z @ 145 NONAME ; unsigned long QVGImagePool::createImageForPixmap(enum VGImageFormat, long, long, unsigned long, class QVGPixmapData *) + ?destroyImageAndContext@QVGPixmapData@@IAEXXZ @ 146 NONAME ; void QVGPixmapData::destroyImageAndContext(void) + ?moveToHeadOfLRU@QVGImagePool@@IAEXPAVQVGPixmapData@@@Z @ 147 NONAME ; void QVGImagePool::moveToHeadOfLRU(class QVGPixmapData *) + ?instance@QVGImagePool@@SAPAV1@XZ @ 148 NONAME ; class QVGImagePool * QVGImagePool::instance(void) + ?useImage@QVGImagePool@@UAEXPAVQVGPixmapData@@@Z @ 149 NONAME ; void QVGImagePool::useImage(class QVGPixmapData *) + ??1QVGImagePool@@UAE@XZ @ 150 NONAME ; QVGImagePool::~QVGImagePool(void) + ?destroyImages@QVGPixmapData@@IAEXXZ @ 151 NONAME ; void QVGPixmapData::destroyImages(void) + ?reclaimSpace@QVGImagePool@@UAE_NW4VGImageFormat@@JJPAVQVGPixmapData@@@Z @ 152 NONAME ; bool QVGImagePool::reclaimSpace(enum VGImageFormat, long, long, class QVGPixmapData *) + ?detachImage@QVGImagePool@@UAEXPAVQVGPixmapData@@@Z @ 153 NONAME ; void QVGImagePool::detachImage(class QVGPixmapData *) + ?createPermanentImage@QVGImagePool@@UAEKW4VGImageFormat@@JJK@Z @ 154 NONAME ; unsigned long QVGImagePool::createPermanentImage(enum VGImageFormat, long, long, unsigned long) + ?d_func@QVGImagePool@@ABEPBVQVGImagePoolPrivate@@XZ @ 155 NONAME ; class QVGImagePoolPrivate const * QVGImagePool::d_func(void) const + ?createTemporaryImage@QVGImagePool@@UAEKW4VGImageFormat@@JJKPAVQVGPixmapData@@@Z @ 156 NONAME ; unsigned long QVGImagePool::createTemporaryImage(enum VGImageFormat, long, long, unsigned long, class QVGPixmapData *) + ??_EQVGImagePool@@UAE@I@Z @ 157 NONAME ; QVGImagePool::~QVGImagePool(unsigned int) + ?hibernate@QVGImagePool@@UAEXXZ @ 158 NONAME ; void QVGImagePool::hibernate(void) + ?qt_vg_destroy_context@@YAXPAVQEglContext@@H@Z @ 159 NONAME ; void qt_vg_destroy_context(class QEglContext *, int) + ??0QVGImagePool@@QAE@XZ @ 160 NONAME ; QVGImagePool::QVGImagePool(void) + ?setImagePool@QVGImagePool@@SAXPAV1@@Z @ 161 NONAME ; void QVGImagePool::setImagePool(class QVGImagePool *) + ?pixmapLRU@QVGImagePool@@IAEPAVQVGPixmapData@@XZ @ 162 NONAME ; class QVGPixmapData * QVGImagePool::pixmapLRU(void) + ?qt_vg_create_context@@YAPAVQEglContext@@PAVQPaintDevice@@H@Z @ 163 NONAME ; class QEglContext * qt_vg_create_context(class QPaintDevice *, int) + ?reclaimImages@QVGPixmapData@@UAEXXZ @ 164 NONAME ; void QVGPixmapData::reclaimImages(void) + ?hibernate@QVGPixmapData@@UAEXXZ @ 165 NONAME ; void QVGPixmapData::hibernate(void) diff --git a/src/s60installs/eabi/QtOpenVGu.def b/src/s60installs/eabi/QtOpenVGu.def index 7526632..eb4caef 100644 --- a/src/s60installs/eabi/QtOpenVGu.def +++ b/src/s60installs/eabi/QtOpenVGu.def @@ -173,4 +173,27 @@ EXPORTS _Z21qt_vg_destroy_contextP11QEglContexti @ 172 NONAME _ZN13QVGPixmapData22destroyImageAndContextEv @ 173 NONAME _ZN13QVGPixmapData9hibernateEv @ 174 NONAME + _ZN12QVGImagePool11detachImageEP13QVGPixmapData @ 175 NONAME + _ZN12QVGImagePool12reclaimSpaceE13VGImageFormatllP13QVGPixmapData @ 176 NONAME + _ZN12QVGImagePool12releaseImageEP13QVGPixmapDatam @ 177 NONAME + _ZN12QVGImagePool12setImagePoolEPS_ @ 178 NONAME + _ZN12QVGImagePool13removeFromLRUEP13QVGPixmapData @ 179 NONAME + _ZN12QVGImagePool15moveToHeadOfLRUEP13QVGPixmapData @ 180 NONAME + _ZN12QVGImagePool20createImageForPixmapE13VGImageFormatllmP13QVGPixmapData @ 181 NONAME + _ZN12QVGImagePool20createPermanentImageE13VGImageFormatllm @ 182 NONAME + _ZN12QVGImagePool20createTemporaryImageE13VGImageFormatllmP13QVGPixmapData @ 183 NONAME + _ZN12QVGImagePool8instanceEv @ 184 NONAME + _ZN12QVGImagePool8useImageEP13QVGPixmapData @ 185 NONAME + _ZN12QVGImagePool9hibernateEv @ 186 NONAME + _ZN12QVGImagePool9pixmapLRUEv @ 187 NONAME + _ZN12QVGImagePoolC1Ev @ 188 NONAME + _ZN12QVGImagePoolC2Ev @ 189 NONAME + _ZN12QVGImagePoolD0Ev @ 190 NONAME + _ZN12QVGImagePoolD1Ev @ 191 NONAME + _ZN12QVGImagePoolD2Ev @ 192 NONAME + _ZN13QVGPixmapData13destroyImagesEv @ 193 NONAME + _ZN13QVGPixmapData13reclaimImagesEv @ 194 NONAME + _ZN13QVGPixmapData19detachImageFromPoolEv @ 195 NONAME + _ZTI12QVGImagePool @ 196 NONAME + _ZTV12QVGImagePool @ 197 NONAME -- cgit v0.12 From 84ef315a9ff6014056d7b6313cf9b1f8bdf06cdc Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 11 Feb 2010 10:29:13 +1000 Subject: Revert "(ODBC) Use wchar_t instead of assuming 2 bytes." This reverts commit 4935ec52fc07d4aaa7ae594cfe9986e25ca62dcb. --- src/sql/drivers/odbc/qsql_odbc.cpp | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index 4d3663e..2049a76 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -144,7 +144,6 @@ public: QSqlRecord rInf; QVector fieldCache; - QVector paramCache; int fieldCacheIdx; int disconnectCount; bool hasSQLFetchScroll; @@ -203,7 +202,7 @@ static QString qWarnODBCHandle(int handleType, SQLHANDLE handle, int *nativeCode *nativeCode = nativeCode_; QString tmpstore; #ifdef UNICODE - tmpstore = QString::fromWCharArray((const wchar_t*)description_, msgLen); + tmpstore = QString((const QChar*)description_.data(), msgLen); #else tmpstore = QString::fromLocal8Bit((const char*)description_.data(), msgLen); #endif @@ -333,7 +332,7 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool uni } else { colSize++; // make sure there is room for more than the 0 termination if (unicode) { - colSize *= sizeof(wchar_t); // a tiny bit faster, since it saves a SQLGetData() call + colSize *= 2; // a tiny bit faster, since it saves a SQLGetData() call } } QVarLengthArray buf(colSize); @@ -354,9 +353,9 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool uni // contain the number of bytes returned - it contains the // total number of bytes that CAN be fetched // colSize-1: remove 0 termination when there is more data to fetch - int rSize = (r == SQL_SUCCESS_WITH_INFO) ? (unicode ? colSize-sizeof(wchar_t) : colSize-1) : lengthIndicator; + int rSize = (r == SQL_SUCCESS_WITH_INFO) ? (unicode ? colSize-2 : colSize-1) : lengthIndicator; if (unicode) { - fieldVal += QString::fromWCharArray((wchar_t*)buf.constData(), rSize / sizeof(wchar_t)); + fieldVal += QString((const QChar*) buf.constData(), rSize / 2); } else { fieldVal += QString::fromAscii(buf.constData(), rSize); } @@ -552,7 +551,7 @@ static QSqlField qMakeFieldInfo(const QODBCPrivate* p, int i ) } #ifdef UNICODE - QString qColName = QString::fromWCharArray((const wchar_t*)colName, colNameLen); + QString qColName((const QChar*)colName, colNameLen); #else QString qColName = QString::fromLocal8Bit((const char*)colName); #endif @@ -1271,12 +1270,9 @@ bool QODBCResult::exec() // bind parameters - only positional binding allowed QVector& values = boundValues(); - QVector wcharstorage; - int i; SQLRETURN r; for (i = 0; i < values.count(); ++i) { - wcharstorage.append(NULL); if (bindValueType(i) & QSql::Out) values[i].detach(); const QVariant &val = values.at(i); @@ -1439,14 +1435,13 @@ bool QODBCResult::exec() #ifndef Q_ODBC_VERSION_2 if (d->unicode) { QString str = val.toString(); - int strSize = str.length() * sizeof(wchar_t); + str.utf16(); if (*ind != SQL_NULL_DATA) - *ind = strSize; + *ind = str.length() * sizeof(QChar); + int strSize = str.length() * sizeof(QChar); if (bindValueType(i) & QSql::Out) { - wchar_t *temp=new wchar_t[str.capacity()*sizeof(wchar_t)]; - str.toWCharArray(temp); - QByteArray ba((char*)temp, str.capacity() * sizeof(wchar_t)); + QByteArray ba((char*)str.constData(), str.capacity() * sizeof(QChar)); r = SQLBindParameter(d->hStmt, i + 1, qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], @@ -1458,13 +1453,9 @@ bool QODBCResult::exec() ba.size(), ind); tmpStorage.append(ba); - wcharstorage.replace(i,temp); break; } - wchar_t *temp=new wchar_t[(1+str.length())*sizeof(wchar_t)]; - str.toWCharArray(temp); - temp[str.length()]=0; r = SQLBindParameter(d->hStmt, i + 1, qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], @@ -1472,10 +1463,9 @@ bool QODBCResult::exec() strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR, strSize, 0, - (void *)temp, + (void *)str.constData(), strSize, ind); - wcharstorage.replace(i,temp); break; } else @@ -1525,13 +1515,6 @@ bool QODBCResult::exec() } } r = SQLExecute(d->hStmt); - - for(int i=0;i Date: Thu, 11 Feb 2010 10:10:54 +0100 Subject: now really fix the message editor for dark backgrounds of course, the palette was also set to explicitly white ... also remove the now obsolete transbox image. Task-number: QTBUG-7778 --- tools/linguist/linguist/images/transbox.png | Bin 782 -> 0 bytes tools/linguist/linguist/linguist.qrc | 3 +-- tools/linguist/linguist/messageeditor.cpp | 8 +------- 3 files changed, 2 insertions(+), 9 deletions(-) delete mode 100644 tools/linguist/linguist/images/transbox.png diff --git a/tools/linguist/linguist/images/transbox.png b/tools/linguist/linguist/images/transbox.png deleted file mode 100644 index 2d7219b..0000000 Binary files a/tools/linguist/linguist/images/transbox.png and /dev/null differ diff --git a/tools/linguist/linguist/linguist.qrc b/tools/linguist/linguist/linguist.qrc index a43f0ce..b70b9cd 100644 --- a/tools/linguist/linguist/linguist.qrc +++ b/tools/linguist/linguist/linguist.qrc @@ -1,5 +1,5 @@ - + images/appicon.png images/mac/accelerator.png images/mac/book.png @@ -28,7 +28,6 @@ images/s_check_on.png images/s_check_warning.png images/splash.png - images/transbox.png images/up.png images/down.png images/editdelete.png diff --git a/tools/linguist/linguist/messageeditor.cpp b/tools/linguist/linguist/messageeditor.cpp index b6c1688..3848723 100644 --- a/tools/linguist/linguist/messageeditor.cpp +++ b/tools/linguist/linguist/messageeditor.cpp @@ -98,14 +98,8 @@ MessageEditor::MessageEditor(MultiDataModel *dataModel, QMainWindow *parent) { setObjectName(QLatin1String("scroll area")); - // Use white explicitly as the background color for the editor page. QPalette p; - p.setColor(QPalette::Active, QPalette::Base, Qt::white); - p.setColor(QPalette::Inactive, QPalette::Base, Qt::white); - p.setColor(QPalette::Disabled, QPalette::Base, Qt::white); - p.setColor(QPalette::Active, QPalette::Window, Qt::white); - p.setColor(QPalette::Inactive, QPalette::Window, Qt::white); - p.setColor(QPalette::Disabled, QPalette::Window, Qt::white); + p.setBrush(QPalette::Window, p.brush(QPalette::Active, QPalette::Base)); setPalette(p); setupEditorPage(); -- cgit v0.12 From 8a8e6d8f0b5368710174726a1c9c2379541899c4 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Thu, 11 Feb 2010 10:31:40 +0100 Subject: We need to export qBadAlloc() on all platforms This supports the (documented) case when mixing Qt built without exception support with code that was built against Qt with exception support. Reviewed-by: Robert Griebl --- src/corelib/global/qglobal.cpp | 2 -- src/corelib/global/qglobal.h | 3 --- 2 files changed, 5 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index f48c1b3..c8f836a 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1994,7 +1994,6 @@ void qt_check_pointer(const char *n, int l) qWarning("In file %s, line %d: Out of memory", n, l); } -#ifndef QT_NO_EXCEPTIONS /* \internal Allows you to throw an exception without including Called internally from Q_CHECK_PTR on certain OS combinations @@ -2003,7 +2002,6 @@ void qBadAlloc() { QT_THROW(std::bad_alloc()); } -#endif /* The Q_ASSERT macro calls this function when the test fails. diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index abdafc3..f51849b 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1674,10 +1674,7 @@ Q_CORE_EXPORT void qt_assert_x(const char *where, const char *what, const char * #endif Q_CORE_EXPORT void qt_check_pointer(const char *, int); - -#ifndef QT_NO_EXCEPTIONS Q_CORE_EXPORT void qBadAlloc(); -#endif #ifdef QT_NO_EXCEPTIONS # if defined(QT_NO_DEBUG) -- cgit v0.12 From eab121a9023eee10b49813161867011dc9fb9689 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Thu, 11 Feb 2010 10:58:05 +0100 Subject: QXmlSchema: fix crash in schema parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit previously, annotations were only supposed to appear within elements of the form ; However, they can also appear in elements of the form Patch-by: Tobias König --- src/xmlpatterns/schema/qxsdschemaparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xmlpatterns/schema/qxsdschemaparser.cpp b/src/xmlpatterns/schema/qxsdschemaparser.cpp index 6d878e8..6ed28af 100644 --- a/src/xmlpatterns/schema/qxsdschemaparser.cpp +++ b/src/xmlpatterns/schema/qxsdschemaparser.cpp @@ -4832,7 +4832,7 @@ XsdTerm::Ptr XsdSchemaParser::parseLocalElement(const XsdParticle::Ptr &particle if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { const XsdAnnotation::Ptr annotation = parseAnnotation(); - element->addAnnotation(annotation); + term->addAnnotation(annotation); } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) { if (hasRefAttribute) { error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.") -- cgit v0.12 From 52a65fde8e97f1f6dc26192058fadc1d2275983a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Thu, 11 Feb 2010 13:26:22 +0100 Subject: Speed up custom bitmap brushes on X11 without Xrender support. There's no need to fall back and go via draw_helper() if we're using a bitmap brush that's drawn using a solid color. Task-number: QTBUG-8140 Reviewed-by: Kim --- src/gui/painting/qpainter.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 3bcaf8c..075c457 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -708,13 +708,14 @@ void QPainterPrivate::updateEmulationSpecifier(QPainterState *s) bool penTextureAlpha = false; if (penBrush.style() == Qt::TexturePattern) penTextureAlpha = qHasPixmapTexture(penBrush) - ? penBrush.texture().hasAlpha() + ? (penBrush.texture().depth() > 1) && penBrush.texture().hasAlpha() : penBrush.textureImage().hasAlphaChannel(); bool brushTextureAlpha = false; - if (s->brush.style() == Qt::TexturePattern) + if (s->brush.style() == Qt::TexturePattern) { brushTextureAlpha = qHasPixmapTexture(s->brush) - ? s->brush.texture().hasAlpha() + ? (s->brush.texture().depth() > 1) && s->brush.texture().hasAlpha() : s->brush.textureImage().hasAlphaChannel(); + } if (((penBrush.style() == Qt::TexturePattern && penTextureAlpha) || (s->brush.style() == Qt::TexturePattern && brushTextureAlpha)) && !engine->hasFeature(QPaintEngine::MaskedBrush)) -- cgit v0.12 From 232defa5d084386a9cdeb229cefee0a4a09bca85 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 11 Feb 2010 13:21:57 +0100 Subject: QNAM HTTP: Set channel to IdleState at better place The readyRead() from the expand() function called from allDone() had a new request triggered for that channel even if it is not really finished yet. Move the assignment to IdleState inside allDone to avoid this error. Reviewed-by: Andreas Kling Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkconnectionchannel.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 5bd972c..64969b0 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -286,7 +286,6 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() if (!socket->bytesAvailable()) { if (reply && reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) { reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState; - this->state = QHttpNetworkConnectionChannel::IdleState; allDone(); } else { // try to reconnect/resend before sending an error. @@ -347,7 +346,6 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() emit reply->headerChanged(); if (!replyPrivate->expectContent()) { replyPrivate->state = QHttpNetworkReplyPrivate::AllDoneState; - this->state = QHttpNetworkConnectionChannel::IdleState; allDone(); return; } @@ -424,7 +422,6 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() // everything done, fall through } case QHttpNetworkReplyPrivate::AllDoneState: - this->state = QHttpNetworkConnectionChannel::IdleState; allDone(); break; default: @@ -570,6 +567,9 @@ void QHttpNetworkConnectionChannel::allDone() // in case of failures, each channel will attempt two reconnects before emitting error. reconnectAttempts = 2; + // now the channel can be seen as free/idle again, all signal emissions for the reply have been done + this->state = QHttpNetworkConnectionChannel::IdleState; + detectPipeliningSupport(); // move next from pipeline to current request -- cgit v0.12 From 439626ffafae7d0480e66a6795df647fd32bbc64 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 11 Feb 2010 13:47:19 +0100 Subject: QNAM HTTP: Optimize detectPipeliningSupport() Do cheap checks first. Reviewed-by: TrustMe --- src/network/access/qhttpnetworkconnectionchannel.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 64969b0..b0e632a 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -610,19 +610,19 @@ void QHttpNetworkConnectionChannel::allDone() void QHttpNetworkConnectionChannel::detectPipeliningSupport() { // detect HTTP Pipelining support - QByteArray serverHeaderField = reply->headerField("Server"); + QByteArray serverHeaderField; if ( - // check for broken servers in server reply header - // this is adapted from http://mxr.mozilla.org/firefox/ident?i=SupportsPipelining - (!serverHeaderField.contains("Microsoft-IIS/4.")) - && (!serverHeaderField.contains("Microsoft-IIS/5.")) - && (!serverHeaderField.contains("Netscape-Enterprise/3.")) // check for HTTP/1.1 - && (reply->d_func()->majorVersion == 1 && reply->d_func()->minorVersion == 1) + (reply->d_func()->majorVersion == 1 && reply->d_func()->minorVersion == 1) // check for not having connection close && (!reply->d_func()->isConnectionCloseEnabled()) // check if it is still connected && (socket->state() == QAbstractSocket::ConnectedState) + // check for broken servers in server reply header + // this is adapted from http://mxr.mozilla.org/firefox/ident?i=SupportsPipelining + && (serverHeaderField = reply->headerField("Server"), !serverHeaderField.contains("Microsoft-IIS/4.")) + && (!serverHeaderField.contains("Microsoft-IIS/5.")) + && (!serverHeaderField.contains("Netscape-Enterprise/3.")) ) { pipeliningSupported = QHttpNetworkConnectionChannel::PipeliningProbablySupported; } else { -- cgit v0.12 From 86d724590212825ba6db87da75117911880a30a8 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 11 Feb 2010 14:51:47 +0100 Subject: Revert WebCore.pro part of 2761e6f57ecd00c3435dbb8a6cf5f40653195d5d to build QtWebKit with THUMB again This restores the library size and memory consumption. Reviewed-by: Janne Koskinen Reviewed-by: Iain --- src/3rdparty/webkit/WebCore/WebCore.pro | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index 7b0366d..c9b622a 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -26,9 +26,7 @@ symbian: { # RO text (code) section in qtwebkit.dll exceeds allocated space for gcce udeb target. # Move RW-section base address to start from 0xE00000 instead of the toolchain default 0x400000. - MMP_RULES += "LINKEROPTION armcc --rw-base 0xE00000" - MMP_RULES += ALWAYS_BUILD_AS_ARM - QMAKE_CXXFLAGS.ARMCC += -OTime -O3 + QMAKE_LFLAGS.ARMCC += --rw-base 0xE00000 } include($$PWD/../WebKit.pri) -- cgit v0.12 From 2acc883b3a339b716da9249a1366b08225acbd8a Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 11 Feb 2010 15:16:44 +0100 Subject: document the slowness of QPixmap::hasAlpha() Reviewed-by: Kim --- src/gui/image/qpixmap.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index d1e5c40..1df7946 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1670,10 +1670,9 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) \o The hasAlphaChannel() returns true if the pixmap has a format that - respects the alpha channel, otherwise returns false, while the - hasAlpha() function returns true if the pixmap has an alpha - channel \e or a mask (otherwise false). The mask() function returns - the mask as a QBitmap object, which can be set using setMask(). + respects the alpha channel, otherwise returns false. The hasAlpha(), + setMask() and mask() functions are legacy and should not be used. + They are potentially very slow. The createHeuristicMask() function creates and returns a 1-bpp heuristic mask (i.e. a QBitmap) for this pixmap. It works by @@ -1760,6 +1759,8 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) Returns true if this pixmap has an alpha channel, \e or has a mask, otherwise returns false. + \warning This is potentially an expensive operation. + \sa hasAlphaChannel(), mask() */ bool QPixmap::hasAlpha() const -- cgit v0.12 From 898a85964830ac17e44675b75c6584866bcf767a Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 11 Feb 2010 16:37:24 +0200 Subject: Fixed the perl download link and description in docs Old link was defunct as the version it pointed is no longer available. Task-number: QTBUG-8134 Reviewed-by: TrustMe --- doc/src/getting-started/installation.qdoc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/src/getting-started/installation.qdoc b/doc/src/getting-started/installation.qdoc index abdfcd2..561cc07 100644 --- a/doc/src/getting-started/installation.qdoc +++ b/doc/src/getting-started/installation.qdoc @@ -1023,9 +1023,11 @@ If you are using pre-built binaries, follow the instructions given in the See \l{http://pepper.troll.no/s60prereleases/patches/}{here} for instructions how to check your compiler version and how to patch it, if needed. \endlist - \o \l{http://downloads.activestate.com/ActivePerl/Windows/5.6/ActivePerl-5.6.1.638-MSWin32-x86.msi}{ActivePerl v5.6.1 build 638} + \o \l{http://downloads.activestate.com/ActivePerl/releases}{ActivePerl 5.6.1 build 638 or higher} \list - \o \bold{Note:} According to Symbian, version 5.6.1 build 638 is mandatory. Using later versions may result in unexplained errors. + \o \bold{Note:} According to Symbian, version 5.6.1 build 638 is mandatory for building Symbian applications, + but that version is no longer available from ActiveState. However, Qt for Symbian has been successfully + compiled using both 5.8.x and 5.10.x versions. \endlist \o \l{http://www.forum.nokia.com/main/resources/tools_and_sdks/S60SDK/}{S60 Platform SDK 3rd Edition FP1 or higher} \list -- cgit v0.12 From d9a6d2e28e4a38ff1242e5e9b1d2225844a51a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Thu, 11 Feb 2010 15:39:56 +0100 Subject: Make QCUPSSupport::printerHasPPD() clean up after itself. This call "leaked" a temporary file in /tmp every time a QPrinter object was created. Not very nice at all. Task-number: QTBUG-6419 Reviewed-by: Kim --- src/gui/painting/qcups.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qcups.cpp b/src/gui/painting/qcups.cpp index 7903762..ac41692 100644 --- a/src/gui/painting/qcups.cpp +++ b/src/gui/painting/qcups.cpp @@ -342,7 +342,9 @@ bool QCUPSSupport::printerHasPPD(const char *printerName) { if (!isAvailable()) return false; - return _cupsGetPPD(printerName) != 0; + const char *ppdFile = _cupsGetPPD(printerName); + unlink(ppdFile); + return (ppdFile != 0); } QString QCUPSSupport::unicodeString(const char *s) -- cgit v0.12 From 2f389a95f5b9e4c7130aa333586d803b639bf259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Mon, 8 Feb 2010 17:08:01 +0100 Subject: Add functional Graphics View benchmarks. Widgets and use cases are externally developed and imported from: git://gitorious.org/+qt-performance-test-developers/qt/qt-performance-test-developers-clone.git (master branch, tests/benchmarks/uimodels/GraphicsViewBenchmark) I couldn't simply import everything because the benchmarks were heavily dependent on an internal measuring tool involving QtScripts and whatnot, not suitable for inclusion in the Qt repository. Everything is now converted into proper QTestLib compatible benchmark functions. --- .../GraphicsViewBenchmark.pro | 71 + .../GraphicsViewBenchmark.qrc | 85 + .../functional/GraphicsViewBenchmark/main.cpp | 686 ++++ .../resources/avatars/avatar_man_001_58x58.png | Bin 0 -> 6598 bytes .../resources/avatars/avatar_man_002_58x58.png | Bin 0 -> 6687 bytes .../resources/avatars/avatar_man_003_58x58.png | Bin 0 -> 6261 bytes .../resources/avatars/avatar_man_004_58x58.png | Bin 0 -> 6783 bytes .../resources/avatars/avatar_man_005_58x58.png | Bin 0 -> 6317 bytes .../resources/avatars/avatar_man_006_58x58.png | Bin 0 -> 7020 bytes .../resources/avatars/avatar_man_007_58x58.png | Bin 0 -> 3706 bytes .../resources/avatars/avatar_man_008_58x58.png | Bin 0 -> 6749 bytes .../resources/avatars/avatar_man_009_58x58.png | Bin 0 -> 5436 bytes .../resources/avatars/avatar_man_010_58x58.png | Bin 0 -> 1454 bytes .../resources/avatars/avatar_picture_001_58x58.png | Bin 0 -> 2983 bytes .../resources/avatars/avatar_picture_002_58x58.png | Bin 0 -> 3463 bytes .../resources/avatars/avatar_picture_003_58x58.png | Bin 0 -> 763 bytes .../resources/avatars/avatar_picture_004_58x58.png | Bin 0 -> 2252 bytes .../resources/avatars/avatar_picture_005_58x58.png | Bin 0 -> 2451 bytes .../resources/avatars/avatar_woman_001_58x58.png | Bin 0 -> 6330 bytes .../resources/avatars/avatar_woman_002_58x58.png | Bin 0 -> 6237 bytes .../resources/avatars/avatar_woman_003_58x58.png | Bin 0 -> 6192 bytes .../resources/avatars/avatar_woman_004_58x58.png | Bin 0 -> 7489 bytes .../resources/avatars/avatar_woman_005_58x58.png | Bin 0 -> 6764 bytes .../resources/avatars/avatar_woman_006_58x58.png | Bin 0 -> 6218 bytes .../resources/avatars/avatar_woman_007_58x58.png | Bin 0 -> 6122 bytes .../resources/avatars/avatar_woman_008_58x58.png | Bin 0 -> 6658 bytes .../resources/avatars/avatar_woman_009_58x58.png | Bin 0 -> 8293 bytes .../resources/avatars/avatar_woman_010_58x58.png | Bin 0 -> 4783 bytes .../blue_SVG/blue_background_360x640px.svg | 14 + .../blue_background_horisontal_640x360px.svg | 16 + .../blue_SVG/blue_contact_default_icon_52x52px.svg | 22 + .../blue_contact_list_divider_360x76px.svg | 7 + .../blue_contact_list_highlighter_360x76px.svg | 10 + .../blue_SVG/blue_contact_status_idle_33x33px.svg | 55 + .../blue_contact_status_offline_33x33px.svg | 55 + .../blue_contact_status_online_33x33px.svg | 56 + .../resources/blue_SVG/blue_scroll_16x80px.svg | 39 + .../resources/blue_SVG/blue_scrollbar_7x14px.svg | 7 + .../blue_SVG/blue_status_field_left_14x24px.svg | 24 + .../blue_SVG/blue_status_field_middle_14x24px.svg | 11 + .../blue_SVG/blue_status_field_right_14x24px.svg | 13 + .../resources/blue_SVG/blue_topbar_356x96px.svg | 2007 ++++++++++ .../blue_SVG/blue_topbar_horisontal_636x96px.svg | 4060 ++++++++++++++++++++ .../blue_SVG/blue_user_default_icon_68x68px.svg | 22 + .../blue_SVG/blue_user_status_idle_38x38px.svg | 55 + .../blue_SVG/blue_user_status_offline_38x38px.svg | 55 + .../blue_SVG/blue_user_status_online_38x38px.svg | 55 + .../resources/contacts/areacodes.txt | 62 + .../resources/contacts/firstnamesF.txt | 100 + .../resources/contacts/firstnamesM.txt | 100 + .../resources/contacts/lastnames.txt | 150 + .../lime_SVG/lime_background_360x640px.svg | 40 + .../lime_background_horisontal_640x360px.svg | 39 + .../lime_SVG/lime_contact_default_icon_53x53px.svg | 30 + ...lime_contact_default_icon_highlight_53x53px.svg | 31 + .../lime_contact_list_divider_360x76px.svg | 7 + .../lime_contact_list_highlighter_357x80px.svg | 11 + .../lime_SVG/lime_contact_status_idle_27x47.svg | 63 + .../lime_SVG/lime_contact_status_offline_27x47.svg | 58 + .../lime_SVG/lime_contact_status_online_27x47.svg | 63 + .../resources/lime_SVG/lime_scroll_5x80px.svg | 12 + .../resources/lime_SVG/lime_scrollbar_5x14px.svg | 7 + .../lime_SVG/lime_status_field_left_14x24px.svg | 30 + .../lime_SVG/lime_status_field_middle_10x24px.svg | 18 + .../lime_SVG/lime_status_field_right_14x24px.svg | 19 + .../resources/lime_SVG/lime_topbar_356x96px.svg | 26 + .../lime_SVG/lime_topbar_horisontal_636x96px.svg | 26 + .../lime_SVG/lime_user_default_icon_84x68px.svg | 32 + .../lime_SVG/lime_user_status_idle_24x24px.svg | 53 + .../lime_SVG/lime_user_status_offline_24x24px.svg | 53 + .../lime_SVG/lime_user_status_online_24x24px.svg | 53 + .../widgets/abstractitemcontainer.cpp | 401 ++ .../widgets/abstractitemcontainer.h | 111 + .../widgets/abstractitemview.cpp | 444 +++ .../widgets/abstractitemview.h | 118 + .../widgets/abstractscrollarea.cpp | 249 ++ .../widgets/abstractscrollarea.h | 101 + .../widgets/abstractviewitem.cpp | 117 + .../widgets/abstractviewitem.h | 96 + .../widgets/backgrounditem.cpp | 85 + .../GraphicsViewBenchmark/widgets/backgrounditem.h | 72 + .../GraphicsViewBenchmark/widgets/button.cpp | 209 + .../GraphicsViewBenchmark/widgets/button.h | 102 + .../GraphicsViewBenchmark/widgets/commandline.cpp | 206 + .../GraphicsViewBenchmark/widgets/commandline.h | 52 + .../GraphicsViewBenchmark/widgets/dummydatagen.cpp | 141 + .../GraphicsViewBenchmark/widgets/dummydatagen.h | 72 + .../GraphicsViewBenchmark/widgets/gvbwidget.cpp | 59 + .../GraphicsViewBenchmark/widgets/gvbwidget.h | 58 + .../GraphicsViewBenchmark/widgets/iconitem.cpp | 169 + .../GraphicsViewBenchmark/widgets/iconitem.h | 96 + .../widgets/itemrecyclinglist.cpp | 275 ++ .../widgets/itemrecyclinglist.h | 85 + .../widgets/itemrecyclinglist.pri | 19 + .../widgets/itemrecyclinglistview.cpp | 79 + .../widgets/itemrecyclinglistview.h | 67 + .../GraphicsViewBenchmark/widgets/label.cpp | 98 + .../GraphicsViewBenchmark/widgets/label.h | 76 + .../GraphicsViewBenchmark/widgets/listitem.cpp | 314 ++ .../GraphicsViewBenchmark/widgets/listitem.h | 109 + .../widgets/listitemcache.cpp | 92 + .../GraphicsViewBenchmark/widgets/listitemcache.h | 69 + .../widgets/listitemcontainer.cpp | 211 + .../widgets/listitemcontainer.h | 92 + .../GraphicsViewBenchmark/widgets/listmodel.cpp | 146 + .../GraphicsViewBenchmark/widgets/listmodel.h | 82 + .../GraphicsViewBenchmark/widgets/listwidget.cpp | 132 + .../GraphicsViewBenchmark/widgets/listwidget.h | 87 + .../GraphicsViewBenchmark/widgets/mainview.cpp | 348 ++ .../GraphicsViewBenchmark/widgets/mainview.h | 123 + .../GraphicsViewBenchmark/widgets/menu.cpp | 202 + .../GraphicsViewBenchmark/widgets/menu.h | 84 + .../widgets/recycledlistitem.cpp | 147 + .../widgets/recycledlistitem.h | 83 + .../widgets/resourcemoninterface.h | 97 + .../GraphicsViewBenchmark/widgets/scrollbar.cpp | 299 ++ .../GraphicsViewBenchmark/widgets/scrollbar.h | 97 + .../GraphicsViewBenchmark/widgets/scroller.cpp | 305 ++ .../GraphicsViewBenchmark/widgets/scroller.h | 79 + .../GraphicsViewBenchmark/widgets/scroller_p.h | 103 + .../GraphicsViewBenchmark/widgets/settings.cpp | 59 + .../GraphicsViewBenchmark/widgets/settings.h | 115 + .../GraphicsViewBenchmark/widgets/simplelist.cpp | 164 + .../GraphicsViewBenchmark/widgets/simplelist.h | 80 + .../widgets/simplelistview.cpp | 500 +++ .../GraphicsViewBenchmark/widgets/simplelistview.h | 92 + .../GraphicsViewBenchmark/widgets/theme.cpp | 240 ++ .../GraphicsViewBenchmark/widgets/theme.h | 134 + .../GraphicsViewBenchmark/widgets/themeevent.cpp | 53 + .../GraphicsViewBenchmark/widgets/themeevent.h | 64 + .../GraphicsViewBenchmark/widgets/topbar.cpp | 359 ++ .../GraphicsViewBenchmark/widgets/topbar.h | 126 + .../GraphicsViewBenchmark/widgets/webview.cpp | 263 ++ .../GraphicsViewBenchmark/widgets/webview.h | 40 + .../GraphicsViewBenchmark/widgets/webview_p.h | 58 + .../gui/graphicsview/functional/functional.pro | 3 + tests/benchmarks/gui/graphicsview/graphicsview.pro | 1 + 137 files changed, 17817 insertions(+) create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.pro create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.qrc create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/main.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_001_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_002_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_003_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_004_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_005_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_006_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_007_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_008_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_009_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_010_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_001_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_002_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_003_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_004_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_005_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_001_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_002_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_003_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_004_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_005_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_006_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_007_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_008_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_009_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_010_58x58.png create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_360x640px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_horisontal_640x360px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_default_icon_52x52px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_divider_360x76px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_highlighter_360x76px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_idle_33x33px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_offline_33x33px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_online_33x33px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scroll_16x80px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scrollbar_7x14px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_left_14x24px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_middle_14x24px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_right_14x24px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_356x96px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_horisontal_636x96px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_default_icon_68x68px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_idle_38x38px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_offline_38x38px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_online_38x38px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/areacodes.txt create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesF.txt create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesM.txt create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/lastnames.txt create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_360x640px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_horisontal_640x360px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_53x53px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_highlight_53x53px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_divider_360x76px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_highlighter_357x80px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_idle_27x47.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_offline_27x47.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_online_27x47.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scroll_5x80px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scrollbar_5x14px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_left_14x24px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_middle_10x24px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_right_14x24px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_356x96px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_horisontal_636x96px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_default_icon_84x68px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_idle_24x24px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_offline_24x24px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_online_24x24px.svg create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/button.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/button.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.pri create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/label.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/label.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/resourcemoninterface.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller_p.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.cpp create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/webview_p.h create mode 100644 tests/benchmarks/gui/graphicsview/functional/functional.pro diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.pro b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.pro new file mode 100644 index 0000000..131ec12 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.pro @@ -0,0 +1,71 @@ +load(qttest_p4) +TEMPLATE = app + +QT += svg +contains(QT_CONFIG, opengl):QT += opengl + +HEADERS += widgets/gvbwidget.h \ + widgets/abstractscrollarea.h \ + widgets/mainview.h \ + widgets/iconitem.h \ + widgets/label.h \ + widgets/listitem.h \ + widgets/scrollbar.h \ + widgets/simplelistview.h \ + widgets/scroller.h \ + widgets/scroller_p.h \ + widgets/button.h \ + widgets/menu.h \ + widgets/themeevent.h \ + widgets/theme.h \ + widgets/backgrounditem.h \ + widgets/topbar.h \ + widgets/commandline.h \ + widgets/dummydatagen.h \ + widgets/settings.h \ + widgets/listitemcache.h \ + widgets/listwidget.h \ + widgets/simplelist.h \ + widgets/itemrecyclinglist.h \ + widgets/itemrecyclinglistview.h \ + widgets/abstractitemview.h \ + widgets/abstractviewitem.h \ + widgets/recycledlistitem.h \ + widgets/listitemcontainer.h \ + widgets/abstractitemcontainer.h \ + widgets/listmodel.h + +SOURCES += main.cpp \ + widgets/gvbwidget.cpp \ + widgets/abstractscrollarea.cpp \ + widgets/mainview.cpp \ + widgets/iconitem.cpp \ + widgets/label.cpp \ + widgets/listitem.cpp \ + widgets/scrollbar.cpp \ + widgets/simplelistview.cpp \ + widgets/scroller.cpp \ + widgets/button.cpp \ + widgets/menu.cpp \ + widgets/themeevent.cpp \ + widgets/theme.cpp \ + widgets/backgrounditem.cpp \ + widgets/topbar.cpp \ + widgets/commandline.cpp \ + widgets/dummydatagen.cpp \ + widgets/settings.cpp \ + widgets/listitemcache.cpp \ + widgets/listwidget.cpp \ + widgets/simplelist.cpp \ + widgets/itemrecyclinglist.cpp \ + widgets/itemrecyclinglistview.cpp \ + widgets/abstractitemview.cpp \ + widgets/abstractviewitem.cpp \ + widgets/recycledlistitem.cpp \ + widgets/listitemcontainer.cpp \ + widgets/abstractitemcontainer.cpp \ + widgets/listmodel.cpp + +TARGET = tst_GraphicsViewBenchmark +RESOURCES += GraphicsViewBenchmark.qrc +INCLUDEPATH += widgets diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.qrc b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.qrc new file mode 100644 index 0000000..18ae04d --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.qrc @@ -0,0 +1,85 @@ + + + resources/blue_SVG/blue_background_360x640px.svg + resources/blue_SVG/blue_background_horisontal_640x360px.svg + resources/blue_SVG/blue_contact_default_icon_52x52px.svg + resources/blue_SVG/blue_contact_list_divider_360x76px.svg + resources/blue_SVG/blue_contact_list_highlighter_360x76px.svg + resources/blue_SVG/blue_contact_status_idle_33x33px.svg + resources/blue_SVG/blue_contact_status_offline_33x33px.svg + resources/blue_SVG/blue_contact_status_online_33x33px.svg + resources/blue_SVG/blue_scrollbar_7x14px.svg + resources/blue_SVG/blue_scroll_16x80px.svg + resources/blue_SVG/blue_status_field_left_14x24px.svg + resources/blue_SVG/blue_status_field_middle_14x24px.svg + resources/blue_SVG/blue_status_field_right_14x24px.svg + resources/blue_SVG/blue_topbar_356x96px.svg + resources/blue_SVG/blue_topbar_horisontal_636x96px.svg + resources/blue_SVG/blue_user_default_icon_68x68px.svg + resources/blue_SVG/blue_user_status_idle_38x38px.svg + resources/blue_SVG/blue_user_status_offline_38x38px.svg + resources/blue_SVG/blue_user_status_online_38x38px.svg + + + + resources/lime_SVG/lime_background_360x640px.svg + resources/lime_SVG/lime_background_horisontal_640x360px.svg + resources/lime_SVG/lime_contact_default_icon_53x53px.svg + resources/lime_SVG/lime_contact_default_icon_highlight_53x53px.svg + resources/lime_SVG/lime_contact_list_divider_360x76px.svg + resources/lime_SVG/lime_contact_list_highlighter_357x80px.svg + resources/blue_SVG/blue_contact_status_idle_33x33px.svg + resources/blue_SVG/blue_contact_status_offline_33x33px.svg + resources/blue_SVG/blue_contact_status_online_33x33px.svg + resources/lime_SVG/lime_scrollbar_5x14px.svg + resources/lime_SVG/lime_scroll_5x80px.svg + resources/lime_SVG/lime_status_field_left_14x24px.svg + resources/lime_SVG/lime_status_field_middle_10x24px.svg + resources/lime_SVG/lime_status_field_right_14x24px.svg + resources/lime_SVG/lime_topbar_356x96px.svg + resources/lime_SVG/lime_topbar_horisontal_636x96px.svg + resources/lime_SVG/lime_user_default_icon_84x68px.svg + resources/lime_SVG/lime_user_status_idle_24x24px.svg + resources/lime_SVG/lime_user_status_offline_24x24px.svg + resources/lime_SVG/lime_user_status_online_24x24px.svg + + + + resources/avatars/avatar_man_001_58x58.png + resources/avatars/avatar_man_002_58x58.png + resources/avatars/avatar_man_003_58x58.png + resources/avatars/avatar_man_004_58x58.png + resources/avatars/avatar_man_005_58x58.png + resources/avatars/avatar_man_006_58x58.png + resources/avatars/avatar_man_007_58x58.png + resources/avatars/avatar_man_008_58x58.png + resources/avatars/avatar_man_009_58x58.png + resources/avatars/avatar_man_010_58x58.png + + resources/avatars/avatar_picture_001_58x58.png + resources/avatars/avatar_picture_002_58x58.png + resources/avatars/avatar_picture_003_58x58.png + resources/avatars/avatar_picture_004_58x58.png + resources/avatars/avatar_picture_005_58x58.png + + resources/avatars/avatar_woman_001_58x58.png + resources/avatars/avatar_woman_002_58x58.png + resources/avatars/avatar_woman_003_58x58.png + resources/avatars/avatar_woman_004_58x58.png + resources/avatars/avatar_woman_005_58x58.png + resources/avatars/avatar_woman_006_58x58.png + resources/avatars/avatar_woman_007_58x58.png + resources/avatars/avatar_woman_008_58x58.png + resources/avatars/avatar_woman_009_58x58.png + resources/avatars/avatar_woman_010_58x58.png + + + + resources/contacts/areacodes.txt + resources/contacts/firstnamesF.txt + resources/contacts/firstnamesM.txt + resources/contacts/lastnames.txt + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/main.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/main.cpp new file mode 100644 index 0000000..f294717 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/main.cpp @@ -0,0 +1,686 @@ +#include +#include +#include + +#include "mainview.h" +#include "dummydatagen.h" +#include "simplelist.h" +#include "itemrecyclinglist.h" +#include "simplelist.h" +#include "theme.h" + +class tst_GraphicsViewBenchmark : public QObject +{ + Q_OBJECT +public: + enum ListType { + Simple, + Recycling, + None + }; + + enum ScrollStep { + Slow = 2, + Normal = 8, + Fast = 64 + }; + + tst_GraphicsViewBenchmark() + : mMainView(0), currentListSize(-1), currentListType(None) {} + ~tst_GraphicsViewBenchmark() {} + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + +private slots: + // Benchmarks: + void createAndFillList_data(); + void createAndFillList(); + void add100ItemsToBeginningOfList_data(); + void add100ItemsToBeginningOfList(); + void remove100ItemsFromBeginningOfList_data(); + void remove100ItemsFromBeginningOfList(); + void deleteList_data(); + void deleteList(); + void themeChange_data(); + void themeChange(); + void update_data(); + void update(); + void scroll_data(); + void scroll(); + +private: + MainView *mMainView; + DummyDataGenerator mDataGenerator; + int currentListSize; + ListType currentListType; + + void resetView(); + void ensureListSizeAndType(int listSize, ListType listType); + void ensureTheme(Theme::Themes theme); + void ensureRotationAngle(int rotation); + void ensureSubtreeCache(bool enable); + void ensureImageBasedRendering(bool enable); + void insertListData(); + inline void setTestWidget(QGraphicsWidget *widget, int listSize, ListType listType) + { + currentListSize = listSize; + currentListType = listType; + mMainView->setTestWidget(widget); + } +}; + +Q_DECLARE_METATYPE(tst_GraphicsViewBenchmark::ListType) +Q_DECLARE_METATYPE(Theme::Themes) +Q_DECLARE_METATYPE(tst_GraphicsViewBenchmark::ScrollStep) + +const int AddRemoveCount = 100; + +static ListItem *newSimpleListItem(DummyDataGenerator &dataGenerator, const int id) +{ + ListItem *item = new ListItem(); + item->setText(dataGenerator.randomName(), ListItem::FirstPos ); + item->setText(dataGenerator.randomPhoneNumber(QString("%1").arg(id)), ListItem::SecondPos ); + item->setIcon(new IconItem(dataGenerator.randomIconItem(), item), ListItem::LeftIcon ); + item->setIcon(new IconItem(dataGenerator.randomStatusItem(), item), ListItem::RightIcon); + item->setFont(Theme::p()->font(Theme::ContactName), ListItem::FirstPos); + item->setFont(Theme::p()->font(Theme::ContactNumber), ListItem::SecondPos); + item->setBorderPen(Theme::p()->listItemBorderPen()); + item->setRounding(Theme::p()->listItemRounding()); + item->icon(ListItem::LeftIcon)->setRotation(Theme::p()->iconRotation(ListItem::LeftIcon)); + item->icon(ListItem::RightIcon)->setRotation(Theme::p()->iconRotation(ListItem::RightIcon)); + item->icon(ListItem::LeftIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::LeftIcon)); + item->icon(ListItem::RightIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::RightIcon)); + item->icon(ListItem::LeftIcon)->setOpacityEffectEnabled(Theme::p()->isIconOpacityEffectEnabled(ListItem::LeftIcon)); + item->icon(ListItem::RightIcon)->setOpacityEffectEnabled(Theme::p()->isIconOpacityEffectEnabled(ListItem::RightIcon)); + return item; +} + +static RecycledListItem *newRecyclingListItem(DummyDataGenerator &dataGenerator, const int id) +{ + RecycledListItem *item = new RecycledListItem(); + item->item()->setText(dataGenerator.randomName(), ListItem::FirstPos ); + item->item()->setText(dataGenerator.randomPhoneNumber(QString("%1").arg(id)), ListItem::SecondPos ); + item->item()->setIcon(new IconItem(dataGenerator.randomIconItem()), ListItem::LeftIcon ); + item->item()->setIcon(new IconItem(dataGenerator.randomStatusItem()), ListItem::RightIcon); + item->item()->setFont(Theme::p()->font(Theme::ContactName), ListItem::FirstPos); + item->item()->setFont(Theme::p()->font(Theme::ContactNumber), ListItem::SecondPos); + item->item()->setBorderPen(Theme::p()->listItemBorderPen()); + item->item()->setRounding(Theme::p()->listItemRounding()); + item->item()->icon(ListItem::LeftIcon)->setRotation(Theme::p()->iconRotation(ListItem::LeftIcon)); + item->item()->icon(ListItem::RightIcon)->setRotation(Theme::p()->iconRotation(ListItem::RightIcon)); + item->item()->icon(ListItem::LeftIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::LeftIcon)); + item->item()->icon(ListItem::RightIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::RightIcon)); + item->item()->icon(ListItem::LeftIcon)->setOpacityEffectEnabled(Theme::p()->isIconOpacityEffectEnabled(ListItem::LeftIcon)); + item->item()->icon(ListItem::RightIcon)->setOpacityEffectEnabled(Theme::p()->isIconOpacityEffectEnabled(ListItem::RightIcon)); + return item; +} + +static void fillList(DummyDataGenerator &dataGenerator, int itemCount, QGraphicsWidget *list) +{ + if (SimpleList *simpleList = qobject_cast(list)) { + for (int i = 0; i < itemCount; ++i) + simpleList->addItem(newSimpleListItem(dataGenerator, i)); + } else if (ItemRecyclingList *recyclingList = qobject_cast(list)) { + for (int i = 0; i < itemCount; ++i) + recyclingList->addItem(newRecyclingListItem(dataGenerator, i)); + } else { + qFatal("fillList: internal error"); + } +} + +void tst_GraphicsViewBenchmark::resetView() +{ + if (QGraphicsWidget *widget = mMainView->takeTestWidget()) { + delete widget; + currentListSize = -1; + currentListType = None; + QTest::qWait(50); + } else { + if (currentListSize != -1) + qFatal("tst_GraphicsViewBenchmark::resetView: internal error: wrong list size"); + if (currentListType != None) + qFatal("tst_GraphicsViewBenchmark::resetView: internal error: wrong list type"); + } + ensureTheme(Theme::Blue); + ensureRotationAngle(0); + ensureSubtreeCache(false); + ensureImageBasedRendering(false); +} + +void tst_GraphicsViewBenchmark::ensureListSizeAndType(int listSize, ListType listType) +{ + if (currentListSize != listSize || currentListType != listType) { + resetView(); + if (listType == Simple) { + SimpleList *list = new SimpleList; + fillList(mDataGenerator, listSize, list); + setTestWidget(list, listSize, listType); + } else if (listType == Recycling) { + ItemRecyclingList *list = new ItemRecyclingList; + fillList(mDataGenerator, listSize, list); + setTestWidget(list, listSize, listType); + } + QTest::qWait(50); + return; + } + + // Okay, we're supposed to have the right list type and size. Make sure we actually have it. + QGraphicsWidget *widget = mMainView->testWidget(); + if (!widget) { + if (currentListType != None || currentListSize != -1) + qFatal("tst_GraphicsViewBenchmark::ensureListSizeAndType: internal error: no test widget"); + return; + } + + if (listType == Simple) { + SimpleList *list = qobject_cast(widget); + if (!list) + qFatal("tst_GraphicsViewBenchmark::ensureListSizeAndType: internal error: wrong list type"); + if (list->itemCount() != listSize) + qFatal("tst_GraphicsViewBenchmark::ensureListSizeAndType: internal error: wrong list size"); + } else if (listType == Recycling){ + ItemRecyclingList *list = qobject_cast(widget); + if (!list) + qFatal("tst_GraphicsViewBenchmark::ensureListSizeAndType: internal error: wrong list type"); + if (list->rows() != listSize) + qFatal("tst_GraphicsViewBenchmark::ensureListSizeAndType: internal error: wrong list size"); + } +} + +void tst_GraphicsViewBenchmark::ensureTheme(Theme::Themes theme) +{ + if (Theme::p()->theme() != theme) { + Theme::p()->setTheme(theme); + // The theme change itself can take a lot of time, so make + // sure we give it a little bit time to stabilize *after* + // the changes, hence sendPostedEvents(); qWait(); + QApplication::sendPostedEvents(); + QTest::qWait(50); + } +} + +void tst_GraphicsViewBenchmark::ensureRotationAngle(int angle) +{ + const bool useTwoColumns = angle != 0; + bool wait = false; + if (mMainView->rotationAngle() != angle) { + mMainView->rotateContent(-mMainView->rotationAngle() + angle); + wait = true; + } + if (QGraphicsWidget *widget = mMainView->testWidget()) { + if (SimpleList *list = qobject_cast(widget)) { + if (list->twoColumns() != useTwoColumns) { + list->setTwoColumns(useTwoColumns); + wait = true; + } + } else if (ItemRecyclingList *list = qobject_cast(widget)) { + if (list->twoColumns() != useTwoColumns) { + list->setTwoColumns(useTwoColumns); + wait = true; + } + } + } + if (wait) + QTest::qWait(50); +} + +void tst_GraphicsViewBenchmark::ensureSubtreeCache(bool enable) +{ + QGraphicsWidget *widget = mMainView->testWidget(); + if (!widget) + return; + + if (SimpleList *list = qobject_cast(widget)) { + if (list->listItemCaching() != enable) { + list->setListItemCaching(enable); + QTest::qWait(50); + } + } else if (ItemRecyclingList *list = qobject_cast(widget)) { + if (list->listItemCaching() != enable) { + list->setListItemCaching(enable); + QTest::qWait(50); + } + } + QPixmapCache::clear(); +} + +void tst_GraphicsViewBenchmark::ensureImageBasedRendering(bool enable) +{ + if (mMainView->imageBasedRendering() != enable) { + mMainView->setImageBasedRendering(enable); + QTest::qWait(50); + } +} + +void tst_GraphicsViewBenchmark::insertListData() +{ + QTest::addColumn("listSize"); + QTest::addColumn("listType"); + + QTest::newRow("Simple list containing 10 items") << 10 << Simple; + QTest::newRow("Recycling list containing 10 items") << 10 << Recycling; + QTest::newRow("Simple list containing 50 items") << 50 << Simple; + QTest::newRow("Recycling list containing 50 items") << 50 << Recycling; + QTest::newRow("Simple list containing 500 items") << 500 << Simple; + QTest::newRow("Recycling list containing 500 items") << 500 << Recycling; +} + +void tst_GraphicsViewBenchmark::initTestCase() +{ + // ### Add support for: + // 1) OpenGL + // 2) FPS + // 3) Running the test manually + // Everything we need is already in widgets/[settings.cpp, commandline.cpp] + mMainView = new MainView(/*enableOpenGL=*/false, /*outputFPS=*/false); + +#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) + mMainView->showFullScreen(); +#else + mMainView->resize(360, 640); + mMainView->show(); +#endif + + mDataGenerator.Reset(); + SimpleList *list = new SimpleList; + list->setListItemCaching(false); + mMainView->setTestWidget(list); + fillList(mDataGenerator, 5, list); + mMainView->takeTestWidget(); + delete list; + + currentListSize = -1; + currentListType = None; + + QTest::qWaitForWindowShown(mMainView); +} + +void tst_GraphicsViewBenchmark::cleanupTestCase() +{ + delete mMainView; + mMainView = 0; +} + +void tst_GraphicsViewBenchmark::init() +{ + // Make sure we don't have pending events in the queue. + // Yes, each test run takes a little bit longer, but the results are more stable. + QTest::qWait(150); +} + +void tst_GraphicsViewBenchmark::createAndFillList_data() +{ + insertListData(); +} + +void tst_GraphicsViewBenchmark::createAndFillList() +{ + QFETCH(int, listSize); + QFETCH(ListType, listType); + + resetView(); + + if (listType == Simple) { + QBENCHMARK { + SimpleList *list = new SimpleList; + setTestWidget(list, listSize, listType); + fillList(mDataGenerator, listSize, list); + } + } else { + QBENCHMARK { + ItemRecyclingList *list = new ItemRecyclingList; + setTestWidget(list, listSize, listType); + fillList(mDataGenerator, listSize, list); + } + } + + resetView(); +} + +void tst_GraphicsViewBenchmark::add100ItemsToBeginningOfList_data() +{ + insertListData(); +} + +void tst_GraphicsViewBenchmark::add100ItemsToBeginningOfList() +{ + QFETCH(int, listSize); + QFETCH(ListType, listType); + + resetView(); + + if (listType == Simple) { + SimpleList *list = new SimpleList; + fillList(mDataGenerator, listSize, list); + setTestWidget(list, listSize, listType); + QTest::qWait(50); + QBENCHMARK { + for (int i = 0; i < AddRemoveCount; ++i) + list->insertItem(0, newSimpleListItem(mDataGenerator, i)); + } + } else { + ItemRecyclingList *list = new ItemRecyclingList; + fillList(mDataGenerator, listSize, list); + setTestWidget(list, listSize, listType); + QTest::qWait(50); + QBENCHMARK { + for (int i = 0; i < AddRemoveCount; ++i) + list->insertItem(0, newRecyclingListItem(mDataGenerator, i)); + } + } + + resetView(); +} + +void tst_GraphicsViewBenchmark::remove100ItemsFromBeginningOfList_data() +{ + insertListData(); +} + +void tst_GraphicsViewBenchmark::remove100ItemsFromBeginningOfList() +{ + QFETCH(int, listSize); + QFETCH(ListType, listType); + + resetView(); + + if (listType == Simple) { + SimpleList *list = new SimpleList; + fillList(mDataGenerator, listSize, list); + setTestWidget(list, listSize, listType); + QTest::qWait(50); + QBENCHMARK { + for (int i = 0; i < AddRemoveCount; ++i) + delete list->takeItem(0); + } + } else { + ItemRecyclingList *list = new ItemRecyclingList; + fillList(mDataGenerator, listSize, list); + setTestWidget(list, listSize, listType); + QTest::qWait(50); + QBENCHMARK { + for (int i = 0; i < AddRemoveCount; ++i) + delete list->takeItem(0); + } + } + + resetView(); +} + +void tst_GraphicsViewBenchmark::deleteList_data() +{ + insertListData(); + QTest::newRow("Simple list containing 1000 items") << 1000 << Simple; + QTest::newRow("Recycling list containing 1000 items") << 1000 << Recycling; +} + +void tst_GraphicsViewBenchmark::deleteList() +{ + QFETCH(int, listSize); + QFETCH(ListType, listType); + + if (listSize < 500) + return; // Too small to measure. + + QGraphicsWidget *list = 0; + if (listType == Simple) + list = new SimpleList; + else + list = new ItemRecyclingList; + fillList(mDataGenerator, listSize, list); + QTest::qWait(20); + + QBENCHMARK_ONCE { + delete list; + } +} + +void tst_GraphicsViewBenchmark::themeChange_data() +{ + QTest::addColumn("listSize"); + QTest::addColumn("listType"); + QTest::addColumn("fromTheme"); + QTest::addColumn("toTheme"); + + QTest::newRow("From Blue to Lime, simple list containing 10 items") << 10 << Simple << Theme::Blue << Theme::Lime; + QTest::newRow("From Lime to Blue, simple list containing 10 items") << 10 << Simple << Theme::Lime << Theme::Blue; + + QTest::newRow("From Blue to Lime, recycling list containing 10 items") << 10 << Recycling << Theme::Blue << Theme::Lime; + QTest::newRow("From Lime to Blue, recycling list containing 10 items") << 10 << Recycling << Theme::Lime << Theme::Blue; + + QTest::newRow("From Blue to Lime, simple list containing 50 items") << 50 << Simple << Theme::Blue << Theme::Lime; + QTest::newRow("From Lime to Blue, simple list containing 50 items") << 50 << Simple << Theme::Lime << Theme::Blue; + + QTest::newRow("From Blue to Lime, recycling list containing 50 items") << 50 << Recycling << Theme::Blue << Theme::Lime; + QTest::newRow("From Lime to Blue, recycling list containing 50 items") << 50 << Recycling << Theme::Lime << Theme::Blue; + + QTest::newRow("From Blue to Lime, simple list containing 500 items") << 500 << Simple << Theme::Blue << Theme::Lime; + QTest::newRow("From Lime to Blue, simple list containing 500 items") << 500 << Simple << Theme::Lime << Theme::Blue; + + QTest::newRow("From Blue to Lime, recycling list containing 500 items") << 500 << Recycling << Theme::Blue << Theme::Lime; + QTest::newRow("From Lime to Blue, recycling list containing 500 items") << 500 << Recycling << Theme::Lime << Theme::Blue; +} + +void tst_GraphicsViewBenchmark::themeChange() +{ + QFETCH(int, listSize); + QFETCH(ListType, listType); + QFETCH(Theme::Themes, fromTheme); + QFETCH(Theme::Themes, toTheme); + + if (fromTheme == toTheme) + qFatal("tst_GraphicsViewBenchmark::themeChange: to and from theme is the same"); + + ensureListSizeAndType(listSize, listType); + ensureTheme(fromTheme); + + QBENCHMARK { + Theme::p()->setTheme(toTheme); + } +} + +static inline QLatin1String stringForTheme(Theme::Themes theme) +{ + if (theme == Theme::Blue) + return QLatin1String("Blue"); + return QLatin1String("Lime"); +} + +static inline QLatin1String stringForListType(tst_GraphicsViewBenchmark::ListType type) +{ + if (type == tst_GraphicsViewBenchmark::Simple) + return QLatin1String("Simple"); + if (type == tst_GraphicsViewBenchmark::Recycling) + return QLatin1String("Recycling"); + return QLatin1String("None"); +} + +static inline QLatin1String stringForScrollStep(tst_GraphicsViewBenchmark::ScrollStep step) +{ + if (step == tst_GraphicsViewBenchmark::Slow) + return QLatin1String("Slow"); + if (step == tst_GraphicsViewBenchmark::Normal) + return QLatin1String("Normal"); + return QLatin1String("Fast"); +} + +static inline QString rowString(int listSize, tst_GraphicsViewBenchmark::ListType listType, + Theme::Themes theme, int toImage, int cache, int angle) +{ + return QString("Items=%1, List=%2, Theme=%3, RenderToImage=%4, Cache=%5, RotAngle=%6") + .arg(QString::number(listSize)).arg(stringForListType(listType)) + .arg(stringForTheme(theme)).arg(QString::number(toImage)) + .arg(QString::number(cache)).arg(QString::number(angle)); +} + +static inline QString rowString(int listSize, tst_GraphicsViewBenchmark::ListType listType, + Theme::Themes theme, int cache, int angle, + tst_GraphicsViewBenchmark::ScrollStep step) +{ + return QString("Items=%1, List=%2, Theme=%3, Cache=%4, RotAngle=%5, Speed=%6") + .arg(QString::number(listSize)).arg(stringForListType(listType)) + .arg(stringForTheme(theme)).arg(QString::number(cache)) + .arg(QString::number(angle)).arg(stringForScrollStep(step)); +} + +void tst_GraphicsViewBenchmark::update_data() +{ + QTest::addColumn("listSize"); + QTest::addColumn("listType"); + QTest::addColumn("theme"); + QTest::addColumn("renderToImage"); + QTest::addColumn("subtreeCache"); + QTest::addColumn("rotationAngle"); + + QList listTypes; + listTypes << Simple << Recycling; + + QList listSizes; + listSizes << 10 << 50 << 500; + + QList themes; + themes << Theme::Blue << Theme::Lime; + + QList rotationAngles; + rotationAngles << 0 << 90; + + // Generate rows: + foreach (ListType listType, listTypes) { + foreach (int listSize, listSizes) { + foreach (int angle, rotationAngles) { + foreach (Theme::Themes theme, themes) { + for (int toImage = 0; toImage < 2; ++toImage) { + for (int cache = 0; cache < 2; ++cache) { + QString string = rowString(listSize, listType, theme, toImage, cache, angle); + QTest::newRow(string.toLatin1()) << listSize << listType << theme << bool(toImage) + << bool(cache) << angle; + } + } + } + } + } + } +} + +void tst_GraphicsViewBenchmark::update() +{ + QFETCH(int, listSize); + QFETCH(ListType, listType); + QFETCH(Theme::Themes, theme); + QFETCH(bool, renderToImage); + QFETCH(bool, subtreeCache); + QFETCH(int, rotationAngle); + + mMainView->viewport()->setUpdatesEnabled(false); + + ensureListSizeAndType(listSize, listType); + ensureTheme(theme); + ensureRotationAngle(rotationAngle); + ensureSubtreeCache(subtreeCache); + ensureImageBasedRendering(renderToImage); + + QEventLoop loop; + QObject::connect(mMainView, SIGNAL(repainted()), &loop, SLOT(quit())); + QTimer::singleShot(4000, &loop, SLOT(quit())); + // Dry run (especially important when cache is enabled). + // NB! setUpdatesEnabled triggers an update(). + mMainView->viewport()->setUpdatesEnabled(true); + loop.exec(QEventLoop::AllEvents | QEventLoop::ExcludeUserInputEvents| QEventLoop::ExcludeSocketNotifiers); + QTest::qWait(50); + + QTimer::singleShot(4000, &loop, SLOT(quit())); + QBENCHMARK { + mMainView->viewport()->update(); + loop.exec(QEventLoop::AllEvents | QEventLoop::ExcludeUserInputEvents| QEventLoop::ExcludeSocketNotifiers); + } +} + +void tst_GraphicsViewBenchmark::scroll_data() +{ + QTest::addColumn("listSize"); + QTest::addColumn("listType"); + QTest::addColumn("theme"); + QTest::addColumn("subtreeCache"); + QTest::addColumn("rotationAngle"); + QTest::addColumn("scrollStep"); + + QList listTypes; + listTypes << Simple << Recycling; + + QList listSizes; + listSizes << 10 << 50 << 500; + + QList themes; + themes << Theme::Blue << Theme::Lime; + + QList rotationAngles; + rotationAngles << 0 << 90; + + QList scrollSteps; + scrollSteps << Slow << Normal << Fast; + + // Generate rows: + foreach (ListType listType, listTypes) { + foreach (int listSize, listSizes) { + foreach (int angle, rotationAngles) { + foreach (ScrollStep step, scrollSteps) { + foreach (Theme::Themes theme, themes) { + for (int cache = 0; cache < 2; ++cache) { + QString string = rowString(listSize, listType, theme, cache, angle, step); + QTest::newRow(string.toLatin1()) << listSize << listType << theme + << bool(cache) << angle << step; + } + } + } + } + } + } +} + +void tst_GraphicsViewBenchmark::scroll() +{ + QFETCH(int, listSize); + QFETCH(ListType, listType); + QFETCH(Theme::Themes, theme); + QFETCH(bool, subtreeCache); + QFETCH(int, rotationAngle); + QFETCH(ScrollStep, scrollStep); + + mMainView->viewport()->setUpdatesEnabled(false); + + ensureListSizeAndType(listSize, listType); + ensureTheme(theme); + ensureRotationAngle(rotationAngle); + ensureSubtreeCache(subtreeCache); + ensureImageBasedRendering(false); + + ScrollBar *sb = 0; + if (listType == Simple) + sb = static_cast(mMainView->testWidget())->verticalScrollBar(); + else + sb = static_cast(mMainView->testWidget())->verticalScrollBar(); + const qreal sliderStart = sb->sliderSize() / qreal(2.0); + const qreal sliderTarget = sliderStart + qreal(scrollStep); + sb->setSliderPosition(sliderStart); + + QEventLoop loop; + QObject::connect(mMainView, SIGNAL(repainted()), &loop, SLOT(quit())); + QTimer::singleShot(4000, &loop, SLOT(quit())); + // Dry run (especially important when cache is enabled). + // NB! setUpdatesEnabled triggers an update(). + mMainView->viewport()->setUpdatesEnabled(true); + loop.exec(QEventLoop::AllEvents | QEventLoop::ExcludeUserInputEvents| QEventLoop::ExcludeSocketNotifiers); + QTest::qWait(50); + + QTimer::singleShot(4000, &loop, SLOT(quit())); + QBENCHMARK { + sb->setSliderPosition(sliderTarget); + loop.exec(QEventLoop::AllEvents | QEventLoop::ExcludeUserInputEvents| QEventLoop::ExcludeSocketNotifiers); + } +} + +QTEST_MAIN(tst_GraphicsViewBenchmark) +#include "main.moc" diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_001_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_001_58x58.png new file mode 100644 index 0000000..525b555 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_001_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_002_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_002_58x58.png new file mode 100644 index 0000000..3d93298 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_002_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_003_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_003_58x58.png new file mode 100644 index 0000000..556cfcb Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_003_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_004_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_004_58x58.png new file mode 100644 index 0000000..94acf9e Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_004_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_005_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_005_58x58.png new file mode 100644 index 0000000..ed0c7c4 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_005_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_006_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_006_58x58.png new file mode 100644 index 0000000..d4b4dc3 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_006_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_007_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_007_58x58.png new file mode 100644 index 0000000..0e45d18 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_007_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_008_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_008_58x58.png new file mode 100644 index 0000000..0c25540 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_008_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_009_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_009_58x58.png new file mode 100644 index 0000000..ce435ea Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_009_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_010_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_010_58x58.png new file mode 100644 index 0000000..021db25 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_010_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_001_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_001_58x58.png new file mode 100644 index 0000000..0051da3 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_001_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_002_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_002_58x58.png new file mode 100644 index 0000000..e8a946a Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_002_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_003_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_003_58x58.png new file mode 100644 index 0000000..b2bb851 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_003_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_004_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_004_58x58.png new file mode 100644 index 0000000..871c075 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_004_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_005_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_005_58x58.png new file mode 100644 index 0000000..d4c18b8 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_005_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_001_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_001_58x58.png new file mode 100644 index 0000000..10a5947 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_001_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_002_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_002_58x58.png new file mode 100644 index 0000000..65b4e03 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_002_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_003_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_003_58x58.png new file mode 100644 index 0000000..935ec07 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_003_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_004_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_004_58x58.png new file mode 100644 index 0000000..fbc1a93 Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_004_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_005_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_005_58x58.png new file mode 100644 index 0000000..af96d3e Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_005_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_006_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_006_58x58.png new file mode 100644 index 0000000..fb4192d Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_006_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_007_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_007_58x58.png new file mode 100644 index 0000000..f5d6dea Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_007_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_008_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_008_58x58.png new file mode 100644 index 0000000..d08b8dc Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_008_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_009_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_009_58x58.png new file mode 100644 index 0000000..768b97d Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_009_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_010_58x58.png b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_010_58x58.png new file mode 100644 index 0000000..d1fe28e Binary files /dev/null and b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_010_58x58.png differ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_360x640px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_360x640px.svg new file mode 100644 index 0000000..1552baf --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_360x640px.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_horisontal_640x360px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_horisontal_640x360px.svg new file mode 100644 index 0000000..5589110 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_horisontal_640x360px.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_default_icon_52x52px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_default_icon_52x52px.svg new file mode 100644 index 0000000..665675b --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_default_icon_52x52px.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_divider_360x76px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_divider_360x76px.svg new file mode 100644 index 0000000..db9fc7a --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_divider_360x76px.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_highlighter_360x76px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_highlighter_360x76px.svg new file mode 100644 index 0000000..dae2bd4 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_highlighter_360x76px.svg @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_idle_33x33px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_idle_33x33px.svg new file mode 100644 index 0000000..fe12e78 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_idle_33x33px.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_offline_33x33px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_offline_33x33px.svg new file mode 100644 index 0000000..0c973f1 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_offline_33x33px.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_online_33x33px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_online_33x33px.svg new file mode 100644 index 0000000..fcb434a --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_online_33x33px.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scroll_16x80px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scroll_16x80px.svg new file mode 100644 index 0000000..897be81 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scroll_16x80px.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scrollbar_7x14px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scrollbar_7x14px.svg new file mode 100644 index 0000000..3baec2f --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scrollbar_7x14px.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_left_14x24px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_left_14x24px.svg new file mode 100644 index 0000000..dd6fb70 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_left_14x24px.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_middle_14x24px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_middle_14x24px.svg new file mode 100644 index 0000000..cabf928 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_middle_14x24px.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_right_14x24px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_right_14x24px.svg new file mode 100644 index 0000000..f3a795b --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_right_14x24px.svg @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_356x96px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_356x96px.svg new file mode 100644 index 0000000..a0efd34 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_356x96px.svg @@ -0,0 +1,2007 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_horisontal_636x96px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_horisontal_636x96px.svg new file mode 100644 index 0000000..0a3efd8 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_horisontal_636x96px.svg @@ -0,0 +1,4060 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_default_icon_68x68px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_default_icon_68x68px.svg new file mode 100644 index 0000000..1ffeedd --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_default_icon_68x68px.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_idle_38x38px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_idle_38x38px.svg new file mode 100644 index 0000000..71f49aa --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_idle_38x38px.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_offline_38x38px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_offline_38x38px.svg new file mode 100644 index 0000000..84c2514 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_offline_38x38px.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_online_38x38px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_online_38x38px.svg new file mode 100644 index 0000000..76daf31 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_online_38x38px.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/areacodes.txt b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/areacodes.txt new file mode 100644 index 0000000..dc7e7d8 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/areacodes.txt @@ -0,0 +1,62 @@ ++30 ++31 ++32 ++33 ++34 ++350 ++351 ++352 ++353 ++354 ++355 ++356 ++357 ++358 ++359 ++36 ++3 ++370 ++371 ++372 ++373 ++374 ++375 ++376 ++377 ++377 44 ++378 ++379 ++38 ++380 ++381 ++382 ++383 ++384 ++385 ++386 ++386 49 ++387 ++388 ++388 3 ++389 ++39 ++40 ++41 ++42 ++420 ++421 ++422 ++423 ++424 ++425 ++426 ++427 ++428 ++429 ++43 ++44 ++45 ++46 ++47 ++48 ++49 \ No newline at end of file diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesF.txt b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesF.txt new file mode 100644 index 0000000..4bf1492 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesF.txt @@ -0,0 +1,100 @@ +Aida +Aija +Aila +Aili +Ailikki +Aimi +Aina +Alexia +Alice +Amanda +Amber +Amy +Angela +Angelica +Ann +Beth +Brenda +Brooke +Caitlin +Camilla +Camille +Carmen +Cassandra +Catherine +Edna +Eeva +Eeve +Eevi +Eija +Eila +Eimi +Eleanor +Eleonora +Elizabeth +Ellen +Enna +Enni +Erica +Erika +Erja +Essi +Essie +Heini +Heleena +Helen +Helena +Helene +Helga +Hilja +Hilkka +Hille +Hillervo +Hillevi +Hilma +Irene +Irina +Irja +Irma +Irmeli +Iro +Jacqueline +Jane +Jennifer +Jenny +Jessica +Jill +Kaire +Kaisa +Kaisla +Kaisu +Katarine +Kate +Kate +Kateriina +Katharina +Katharine +Katherine +Kathleen +Marge +Mary +May +Megan +Melinda +Morgan +Nellie +Nelly +Pauline +Peggy +Pepi +Scarlett +Sheila +Shirley +Sissy +Stephanie +Sylvia +Taylor +Terrie +Terry +Victoria +Violet \ No newline at end of file diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesM.txt b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesM.txt new file mode 100644 index 0000000..189d8d0 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesM.txt @@ -0,0 +1,100 @@ +Aabraham +Aadam +Aadolf +Aake +Aaku +Aatu +Ahti +Ahvo +Aimo +Aki +Akseli +Aku +Bartholomew +Ben +Benjamin +Bill +Billie +Billy +Bob +Brendan +Brian +Bryan +Calvin +Carl +Charles +Chester +Chris +Christian +Christopher +Chuck +Dale +Dave +David +Dennis +Dick +Dominick +Donald +Dustin +Dusty +Harri +Heikki +Heimo +Heino +Helmer +Helmeri +Hemmi +Hemmo +Henri +Jeff +Jeffrey +Jermu +Jero +Jerri +Jerry +Jesper +Jesperi +Jesse +Jetro +Jim +Jimi +Jimmy +Joakim +Joe +John +Johnny +Jonah +Jonathan +Joseph +Leevi +Leimo +Leimu +Leino +Leivo +Lenne +Lennu +Mark +Martin +Matt +Matthew +Michael +Mike +Niko +Nooa +Nuutti +Nyyrikki +Okke +Okko +Olavi +Oliver +Olli +Onni +Pertti +Perttu +Walter +Warren +Wesley +William +Willie +Winston +Woodrow \ No newline at end of file diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/lastnames.txt b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/lastnames.txt new file mode 100644 index 0000000..35b3f9f --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/lastnames.txt @@ -0,0 +1,150 @@ +Adams +Allen +Anderson +Bailey +Baker +Barnes +Bell +Bennett +Brooks +Brown +Butler +Campbell +Carter +Clark +Collins +Cook +Cooper +Cox +Cruz +Davis +Daz +Edwards +Evans +Fisher +Flores +Foster +Garca +Gmez +Gonzlez +Gray +Green +Gutirrez +Hall +Harris +Heikkinen +Helenius +Helve +Hernndez +Hill +Hiltunen +Hirvonen +Holm +Honkanen +Howard +Hughes +Huhtala +Huttunen +Hyppnen +Jackson +James +Jenkins +Johnson +Jones +Kauppinen +Kelly +Kemppainen +King +Klemetti +Kokkonen +Kolehmainen +Korhonen +Kurikka +Kuura +Kyr +Krkkinen +Lee +Lewis +Long +Lpez +Martikainen +Martin +Martnez +Mattila +Mikkola +Mikkonen +Miller +Mitchell +Moore +Morales +Morgan +Morris +Muje +Murphy +Mustonen +Myers +Myllrinen +Menp +Mkel +Mkinen +Nelson +Nguyen +Ortiz +Parker +Prez +Perry +Peterson +Phillips +Powell +Price +Ramrez +Reed +Reyes +Richardson +Rivera +Roberts +Robinson +Rodrguez +Rogers +Ross +Russell +Saarinen +Saaristo +Salminen +Salo +Salonen +Snchez +Sanders +Scott +Seppnen +Silvennoinen +Silvo +Smith +Sokura +Stewart +Sullivan +Suomalainen +Taylor +Thomas +Thompson +Torres +Turner +Valkeap +Walker +Valo +Valtonen +Vanhanen +Ward +Watson +Venlinen +Vesa +White +Vihavainen +Williams +Wilson +Virtanen +Wood +Voutilainen +Wright +Vuorela +Young \ No newline at end of file diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_360x640px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_360x640px.svg new file mode 100644 index 0000000..8daf275 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_360x640px.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_horisontal_640x360px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_horisontal_640x360px.svg new file mode 100644 index 0000000..c2b070a --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_horisontal_640x360px.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_53x53px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_53x53px.svg new file mode 100644 index 0000000..6e34f25 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_53x53px.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_highlight_53x53px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_highlight_53x53px.svg new file mode 100644 index 0000000..29c284d --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_highlight_53x53px.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_divider_360x76px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_divider_360x76px.svg new file mode 100644 index 0000000..db9fc7a --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_divider_360x76px.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_highlighter_357x80px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_highlighter_357x80px.svg new file mode 100644 index 0000000..0ee3ea2 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_highlighter_357x80px.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_idle_27x47.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_idle_27x47.svg new file mode 100644 index 0000000..925d3eb --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_idle_27x47.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_offline_27x47.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_offline_27x47.svg new file mode 100644 index 0000000..6f74723 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_offline_27x47.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_online_27x47.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_online_27x47.svg new file mode 100644 index 0000000..5695160 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_online_27x47.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scroll_5x80px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scroll_5x80px.svg new file mode 100644 index 0000000..4f6482a --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scroll_5x80px.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scrollbar_5x14px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scrollbar_5x14px.svg new file mode 100644 index 0000000..54a40c3 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scrollbar_5x14px.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_left_14x24px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_left_14x24px.svg new file mode 100644 index 0000000..a21c91d --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_left_14x24px.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_middle_10x24px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_middle_10x24px.svg new file mode 100644 index 0000000..b84200d --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_middle_10x24px.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_right_14x24px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_right_14x24px.svg new file mode 100644 index 0000000..231560d --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_right_14x24px.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_356x96px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_356x96px.svg new file mode 100644 index 0000000..679d9a5 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_356x96px.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_horisontal_636x96px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_horisontal_636x96px.svg new file mode 100644 index 0000000..1ef4fb9 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_horisontal_636x96px.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_default_icon_84x68px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_default_icon_84x68px.svg new file mode 100644 index 0000000..4df0214 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_default_icon_84x68px.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_idle_24x24px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_idle_24x24px.svg new file mode 100644 index 0000000..2d6da38 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_idle_24x24px.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_offline_24x24px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_offline_24x24px.svg new file mode 100644 index 0000000..d592026 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_offline_24x24px.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_online_24x24px.svg b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_online_24x24px.svg new file mode 100644 index 0000000..46ad07d --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_online_24x24px.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.cpp new file mode 100644 index 0000000..a3628fd --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.cpp @@ -0,0 +1,401 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include + +#include "abstractitemcontainer.h" +#include "abstractitemview.h" +#include "abstractviewitem.h" +#include "scrollbar.h" + +AbstractItemContainer::AbstractItemContainer(int bufferSize, QGraphicsWidget *parent) + : GvbWidget(parent), + m_items(), + m_itemView(0), + m_prototype(0), + m_bufferSize(bufferSize), + m_twoColumns(false) +{ +} + +AbstractItemContainer::~AbstractItemContainer() +{ + delete m_prototype; + m_prototype = 0; +} + +AbstractViewItem *AbstractItemContainer::prototype() +{ + return m_prototype; +} + +int AbstractItemContainer::bufferSize() const +{ + return m_bufferSize; +} + +bool AbstractItemContainer::event(QEvent *e) +{ + if (e->type() == QEvent::LayoutRequest) + updateItemBuffer(); + + return QGraphicsWidget::event(e); +} + + +bool AbstractItemContainer::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type()==QEvent::GraphicsSceneResize && m_itemView) { +#if (QT_VERSION >= 0x040600) + const bool caching = m_itemView->listItemCaching(); + m_itemView->setListItemCaching(false); +#endif + + QSizeF s = m_itemView->size(); + s.setWidth(s.width()-m_itemView->verticalScrollBar()->size().width()); + adjustVisibleContainerSize(s); + + m_itemView->updateViewContent(); + updateItemBuffer(); + +#if (QT_VERSION >= 0x040600) + m_itemView->setListItemCaching(caching); +#endif + } + + return QGraphicsWidget::eventFilter(obj, event); +} + +QVariant AbstractItemContainer::itemChange(GraphicsItemChange change, const QVariant &value) +{ + QVariant ichange = QGraphicsWidget::itemChange(change,value); + + if (change == ItemPositionChange) { + if (m_itemView && layout() && !layout()->isActivated()) + m_itemView->refreshContainerGeometry(); + } + return ichange; + } + +/*virtual*/ +void AbstractItemContainer::setItemView(AbstractItemView *view) +{ + m_itemView = view; + + if (m_itemView) { + setParentItem(m_itemView); + m_itemView->installEventFilter(this); + } +} +/*virtual*/ +void AbstractItemContainer::setItemPrototype(AbstractViewItem *ptype) +{ + m_prototype = ptype; + m_prototype->setParentItem(0); + m_prototype->hide(); +} + +/*virtual*/ +void AbstractItemContainer::reset() +{ + qDeleteAll(m_items); + m_items.clear(); + updateItemBuffer(); +} + + +/*virtual*/ +void AbstractItemContainer::addItem(const QModelIndex &index) +{ + if (m_items.count() < maxItemCountInItemBuffer() || + (m_items.count() > 0 && + m_items.first()->modelIndex().row()-1 <= index.row() && + m_items.last()->modelIndex().row() >= index.row())) { + int itemPos = 0; + if (m_items.count() != 0) + itemPos = qMax(0, index.row() - m_items.first()->modelIndex().row()); + + if (itemPos >= m_items.count() || m_items.at(itemPos)->modelIndex() != index) { + AbstractViewItem *item = 0; + if (m_prototype) + item = m_prototype->newItemInstance(); + + if (item) { + item->setModel(m_itemView->model()); + item->setTwoColumns(m_twoColumns); + m_items.insert(itemPos, item); + addItemToVisibleLayout(itemPos, item); + + if (item->modelIndex() != index) { + item->setModelIndex(index); + } + } + } + updateItemBuffer(); + } +} +void AbstractItemContainer::removeItem(const QModelIndex &index) +{ + AbstractViewItem *item = findItemByIndex(index); + + if (item) { + if (maxItemCountInItemBuffer() < m_items.count()) { + m_items.removeOne(item); + removeItemFromVisibleLayout(item); + + delete item; + } + else { + m_items.removeOne(item); + removeItemFromVisibleLayout(item); + + QModelIndex newIndex = m_itemView->nextIndex(m_items.last()->modelIndex()); + if (newIndex.isValid()) { + // Item readded as last item in buffer. + m_items.append(item); + addItemToVisibleLayout(m_items.count() - 1, item); + item->setModelIndex(newIndex); + } else { + // Item readded as first item in buffer. + newIndex = m_itemView->previousIndex(m_items.first()->modelIndex()); + + m_items.prepend(item); + addItemToVisibleLayout(0, item); + item->setModelIndex(newIndex); + } + } + } +} + +/*virtual*/ +int AbstractItemContainer::itemCount() const +{ + return m_items.count(); +} + +AbstractViewItem *AbstractItemContainer::firstItem() +{ + return m_items.first(); +} + +/*virtual*/ +AbstractViewItem* AbstractItemContainer::itemAt(const int row) const +{ + if (row<0 || row >= m_items.count()) + return 0; + return m_items.at(row); +} + +AbstractViewItem* AbstractItemContainer::findItemByIndex(const QModelIndex &index) const +{ + AbstractViewItem *item = 0; + for (int i = 0; i < m_items.count(); ++i) { + if (m_items.at(i)->modelIndex() == index) { + item = m_items.at(i); + break; + } + } + return item; +} + +bool AbstractItemContainer::itemVisibleInView(AbstractViewItem* item, const QRectF &viewRect, bool fullyVisible) const +{ + if (!item || !m_itemView) + return false; + + QRectF itemRectBoundingRect = item->mapToItem(m_itemView, item->boundingRect()).boundingRect(); + + if (fullyVisible && viewRect.contains(itemRectBoundingRect)) + return true; + else if (viewRect.intersects(itemRectBoundingRect)) + return true; + + return false; +} + +void AbstractItemContainer::updateItemBuffer() +{ + if (!m_itemView || (m_itemView && !m_itemView->boundingRect().isValid())) + return; + + int maxCount = maxItemCountInItemBuffer(); + + if (m_items.count() < maxCount) { + // New items needs to be added. + QModelIndex index; + if (m_items.count() > 0) + index = m_items.last()->modelIndex(); + while (m_items.count() < maxCount) { + index = m_itemView->nextIndex(index); + + if (!index.isValid()) + break; + + insertItem(m_items.count(), index); + } + + index = m_items.first()->modelIndex(); + while (m_items.count() < maxCount) { + index = m_itemView->previousIndex(index); + + if (!index.isValid()) + break; + + insertItem(0, index); + } + } + + QRectF viewRect = boundingRect(); + + while (m_items.count() > maxCount) { + int firstVisible = 0; + int lastVisible = 0; + findFirstAndLastVisibleBufferIndex(firstVisible, lastVisible, viewRect, false); + + AbstractViewItem* item = 0; + if (lastVisible != m_items.count() - 1) { + item = m_items.takeLast(); + } + else if (firstVisible != 0 && m_items.first()->modelIndex().row() != firstVisible-1) { + item = m_items.takeFirst(); + } + else { + // All the items are visible. Take the item at the end of the buffer. + item = m_items.takeLast(); + } + + m_items.removeOne(item); + removeItemFromVisibleLayout(item); + delete item; + } +} + +void AbstractItemContainer::insertItem(int pos, const QModelIndex &index) +{ + AbstractViewItem *item = 0; + if (m_prototype) + item = m_prototype->newItemInstance(); + + if (item) { + item->setModel(m_itemView->model()); + item->setModelIndex(index); + item->setTwoColumns(m_twoColumns); + m_items.insert(pos, item); + addItemToVisibleLayout(pos, item); + item->updateItemContents(); + if (pos == 0) + m_itemView->scrollContentsBy(qreal(0.0), + item->effectiveSizeHint(Qt::PreferredSize).height()); + } +} + +void AbstractItemContainer::findFirstAndLastVisibleBufferIndex(int &firstVisibleBufferIndex, + int &lastVisibleBufferIndex, + const QRectF &viewRect, + bool fullyVisible) const +{ + if (layout() && !layout()->isActivated()) + layout()->activate(); + + firstVisibleBufferIndex = -1; + lastVisibleBufferIndex = -1; + + int count = m_items.count(); + for (int i = 0; i < count; ++i) { + if (itemVisibleInView(m_items.at(i), viewRect, fullyVisible)) { + if (firstVisibleBufferIndex == -1) + firstVisibleBufferIndex = i; + lastVisibleBufferIndex = i; + } + else if ( lastVisibleBufferIndex != -1 ) + break; // lastVisibleBufferIndex is already set + } +} + +/*virtual*/ +int AbstractItemContainer::maxItemCountInItemBuffer() const +{ + if (m_itemView && !m_itemView->boundingRect().isEmpty()) + { + return m_itemView->indexCount(); + } + return 0; +} + + +void AbstractItemContainer::themeChange() +{ + for (int i = 0; i themeChange(); +} + +void AbstractItemContainer::updateContent() +{ + for (int i = 0; i updateItemContents(); +} + +#if (QT_VERSION >= 0x040600) +void AbstractItemContainer::setSubtreeCacheEnabled(bool enabled) +{ + for (int i = 0; i setSubtreeCacheEnabled(enabled); + if (m_prototype) + m_prototype->setSubtreeCacheEnabled(enabled); +} +#endif + +void AbstractItemContainer::setTwoColumns(const bool enabled) +{ + if (m_twoColumns == enabled) + return; + + m_twoColumns = enabled; + + for (int i = 0; i < m_items.count(); ++i) + m_items.at(i)->setTwoColumns(enabled); +} + +bool AbstractItemContainer::twoColumns() +{ + return m_twoColumns; +} + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.h b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.h new file mode 100644 index 0000000..a0e49ce --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ABSTRACTITEMCONTAINER_H +#define ABSTRACTITEMCONTAINER_H + +#include + +#include "gvbwidget.h" + +class QGraphicsWidget; +class AbstractItemView; +class AbstractViewItem; + +class AbstractItemContainer : public GvbWidget +{ + Q_OBJECT +public: + AbstractItemContainer(int bufferSize, QGraphicsWidget *parent=0); + virtual ~AbstractItemContainer(); + + virtual void addItem(const QModelIndex &index); + virtual void removeItem(const QModelIndex &index); + + virtual void setItemView(AbstractItemView *view); + virtual void setItemPrototype(AbstractViewItem *ptype); + virtual void reset(); + virtual int itemCount() const; + virtual AbstractViewItem* itemAt(const int row) const; + AbstractViewItem* findItemByIndex(const QModelIndex &index) const; + AbstractViewItem *prototype(); + AbstractViewItem *firstItem(); + void updateContent(); + void themeChange(); + int bufferSize() const; + virtual void setTwoColumns(const bool enabled); + bool twoColumns(); + +#if (QT_VERSION >= 0x040600) + void setSubtreeCacheEnabled(const bool enabled); + virtual void setListItemCaching(const bool enabled, const int index) = 0; +#endif + +protected: + virtual void adjustVisibleContainerSize(const QSizeF &size) = 0; + virtual void addItemToVisibleLayout(int index, AbstractViewItem *item) = 0; + virtual void removeItemFromVisibleLayout(AbstractViewItem *item) = 0; + + virtual bool event(QEvent *e); + virtual bool eventFilter(QObject *obj, QEvent *event); + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + virtual int maxItemCountInItemBuffer() const; + bool itemVisibleInView(AbstractViewItem* item, const QRectF &viewRect, bool fullyVisible = true) const; + +protected: + void updateItemBuffer(); + void findFirstAndLastVisibleBufferIndex(int &firstVisibleBufferIndex, + int &lastVisibleBufferIndex, + const QRectF &viewRect, + bool fullyVisible) const; + QList m_items; + AbstractItemView *m_itemView; + AbstractViewItem *m_prototype; + int m_bufferSize; + +private: + void insertItem(int pos, const QModelIndex &index); + bool m_twoColumns; + + Q_DISABLE_COPY(AbstractItemContainer) +}; + +#endif // ABSTRACTITEMCONTAINER_H diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.cpp new file mode 100644 index 0000000..ba958ca --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.cpp @@ -0,0 +1,444 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "abstractitemview.h" +#include "abstractviewitem.h" +#include "scrollbar.h" + +AbstractItemView::AbstractItemView(QGraphicsWidget *parent) + : AbstractScrollArea(parent), + m_model(0), + m_rootIndex(), + m_container(0), + m_selectionModel(0), + m_currentIndex(), + m_scroller() +{ + setRootIndex(QModelIndex()); +} + +/*virtual*/ +AbstractItemView::~AbstractItemView() +{ +} + +/*virtual*/ +void AbstractItemView::setModel(QAbstractItemModel *model, AbstractViewItem *prototype) +{ + if( m_model == model || !model) + return; + + if (m_model) { + disconnect(m_model, SIGNAL(destroyed()), + this, SLOT(_q_modelDestroyed())); + disconnect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), + this, SLOT( dataChanged(QModelIndex,QModelIndex))); + disconnect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), + this, SLOT(rowsInserted(QModelIndex,int,int))); + disconnect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), + this, SLOT(rowsRemoved(QModelIndex,int,int))); + disconnect(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), + this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int))); + disconnect(m_model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), + this, SLOT(rowsAboutToBeInserted(QModelIndex,int,int))); + disconnect(m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), + this, SLOT(columnsInserted(QModelIndex,int,int))); + disconnect(m_model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), + this, SLOT(columnsAboutToBeInserted(QModelIndex,int,int))); + disconnect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), + this, SLOT(columnsRemoved(QModelIndex,int,int))); + disconnect(m_model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), + this, SLOT(columnsAboutToBeRemoved(QModelIndex,int,int))); + disconnect(m_model, SIGNAL(modelReset()), this, SLOT(reset())); + disconnect(m_model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged())); + + m_model = 0; + } + + setSelectionModel(0); + + m_currentIndex = QModelIndex(); + m_rootIndex = QModelIndex(); + + m_model = model; + + Q_ASSERT_X(m_model->index(0,0) == m_model->index(0,0), + "AbstractItemView::setModel", + "A model should return the exact same index " + "(including its internal id/pointer) when asked for it twice in a row."); + Q_ASSERT_X(m_model->index(0,0).parent() == QModelIndex(), + "AbstractItemView::setModel", + "The parent of a top level index should be invalid"); + + + connect(m_model, SIGNAL(destroyed()), this, SLOT(modelDestroyed())); + connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), + this, SLOT( dataChanged(QModelIndex,QModelIndex))); + connect(m_model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), + this, SLOT(rowsAboutToBeInserted(QModelIndex,int,int))); + connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), + this, SLOT(rowsInserted(QModelIndex,int,int))); + connect(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), + this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int))); + connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), + this, SLOT(rowsRemoved(QModelIndex,int,int))); + connect(m_model, SIGNAL(modelReset()), this, SLOT(reset())); + connect(m_model, SIGNAL(layoutChanged()), this, SLOT(layoutChanged())); + + setSelectionModel(new QItemSelectionModel(m_model)); + + if (prototype && m_container) { + m_container->setItemPrototype(prototype); + m_container->reset(); + } +} + +/*virtual*/ +void AbstractItemView::setContainer(AbstractItemContainer *container) +{ + m_container = container; + m_container->setItemView(this); + m_container->setParentItem(viewport()); + + viewport()->setFlag( + QGraphicsItem::ItemClipsChildrenToShape, true); + m_scroller.setScrollable(this); + installEventFilter(&m_scroller); +} + +/*virtual*/ +void AbstractItemView::setRootIndex(const QModelIndex &index) +{ + m_rootIndex = index; + // TODO fix this if we change index, container should be updated? Or do we need root index? +} + +/*virtual*/ +int AbstractItemView::indexCount() const +{ + if (m_model) + return m_model->rowCount(m_rootIndex); + return 0; +} + +/*virtual*/ +QAbstractItemModel* AbstractItemView::model() const +{ + return m_model; +} + +/*virtual*/ +QModelIndex AbstractItemView::nextIndex(const QModelIndex &index) const +{ + if (!m_model) + return QModelIndex(); + + if (index.isValid()) + return m_model->index(index.row() + 1, 0, m_rootIndex); + else + return m_model->index(0, 0, m_rootIndex); +} + +/*virtual*/ +QModelIndex AbstractItemView::previousIndex(const QModelIndex &index) const +{ + if (!m_model) + return QModelIndex(); + + if (index.isValid()) + return m_model->index(index.row() - 1, 0, m_rootIndex); + else + return m_model->index(m_model->rowCount(m_rootIndex) - 1, 0, m_rootIndex); +} + +/*virtual*/ +void AbstractItemView::setItemPrototype(AbstractViewItem* prototype) +{ + if (prototype && m_container) { + m_container->setItemPrototype(prototype); + m_container->reset(); + } +} + +void AbstractItemView::setSelectionModel(QItemSelectionModel *smodel) +{ + if (smodel && smodel->model() != m_model) { + return; + } + if (m_selectionModel) { + disconnect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(currentSelectionChanged(QItemSelection, QItemSelection))); + + disconnect(m_selectionModel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + this, SLOT(currentIndexChanged(QModelIndex, QModelIndex))); + + delete m_selectionModel; + m_selectionModel = 0; + } + + m_selectionModel = smodel; + + if (m_selectionModel) { + connect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(currentSelectionChanged(QItemSelection, QItemSelection))); + connect(m_selectionModel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + this, SLOT(currentIndexChanged(QModelIndex, QModelIndex))); + } +} + +/*virtual*/ +void AbstractItemView::currentIndexChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + Q_UNUSED(previous) + + if (current != m_currentIndex) + m_currentIndex = current; +} + +/*virtual*/ +void AbstractItemView::currentSelectionChanged(const QItemSelection &selected, + const QItemSelection &deselected) +{ + Q_UNUSED(selected) + Q_UNUSED(deselected) +} + +/*virtual*/ +void AbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) +{ + Q_UNUSED(topLeft) + Q_UNUSED(bottomRight) + // TODO implement if we like to edit view items. +} + +/*virtual*/ +void AbstractItemView::rowsAboutToBeInserted(const QModelIndex &index, int start, int end) +{ + Q_UNUSED(index) + Q_UNUSED(start) + Q_UNUSED(end) + + // TODO implement +} + + +/*virtual*/ +void AbstractItemView::rowsAboutToBeRemoved(const QModelIndex &index,int start, int end) +{ + Q_UNUSED(index) + Q_UNUSED(start) + Q_UNUSED(end) +} + +/*virtual*/ +void AbstractItemView::rowsRemoved(const QModelIndex &parent,int start, int end) +{ + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + + if (start <= m_currentIndex.row() && m_currentIndex.row() <= end) { + QModelIndex newCurrentIndex = m_model->index(start, 0, m_rootIndex); + if (!newCurrentIndex.isValid()) { + newCurrentIndex = m_model->index(qMax(0,start - 1), 0, m_rootIndex); + } + + if (m_selectionModel) { + m_selectionModel->setCurrentIndex(newCurrentIndex, QItemSelectionModel::NoUpdate); + } + } + for (int i = end; i >= start; --i) //The items are already removed from the model. + m_container->removeItem(QModelIndex()); // Indexes are already invalid. +} + +/*virtual*/ +void AbstractItemView::reset() +{ + m_rootIndex = QModelIndex(); + + if (m_container) + m_container->reset(); + + setCurrentIndex(QModelIndex()); + + ScrollBar *sb = verticalScrollBar(); + + if (sb) + sb->setSliderSize(0); +} + +/*virtual*/ +void AbstractItemView::rowsInserted(const QModelIndex &parent, int start, int end) +{ + if (!m_container) + return; + + for (int i = start; i <= end; ++i) + m_container->addItem(m_model->index(i, 0, parent)); + + refreshContainerGeometry(); +} + +/*virtual*/ +void AbstractItemView::modelDestroyed() +{ + m_model = 0; + setSelectionModel(0); + reset(); +} + +/*virtual*/ +void AbstractItemView::layoutChanged() +{ + m_container->reset(); +} + +bool AbstractItemView::event(QEvent *e) +{ + bool result = AbstractScrollArea::event(e); + if (e && e->type()==QEvent::LayoutRequest) { + refreshContainerGeometry(); + result = true; + } + if (e && e->type()==QEvent::GraphicsSceneResize) { + m_scroller.stopScrolling(); + refreshContainerGeometry(); + + m_container->resize(this->size().width()-verticalScrollBar()->size().width(), + m_container->preferredHeight()); + + if(verticalScrollBar()->sliderPosition() > verticalScrollBar()->sliderSize()) + verticalScrollBar()->setSliderPosition(verticalScrollBar()->sliderSize()); + + result = true; + } + return result; +} + +void AbstractItemView::setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags selectionFlag) +{ + if (m_selectionModel) + m_selectionModel->setCurrentIndex(index, selectionFlag); +} + +void AbstractItemView::refreshContainerGeometry() +{ + if (!m_container || !m_model) + return; + + if (m_container->layout() && !m_container->layout()->isActivated()) + m_container->layout()->activate(); + + ScrollBar *sb = verticalScrollBar(); + + if (sb) { + AbstractViewItem *item = m_container->itemAt(0); + if (item) { + qreal oneItemH = item->size().height(); + sb->setSliderSize(oneItemH*m_model->rowCount(m_rootIndex)-size().height()); + } + if (!sb->isVisible() && verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff && + contentsRect().height() < m_container->boundingRect().height()) + sb->show(); + } +} + +void AbstractItemView::scrollContentsBy(qreal dx, qreal dy) +{ + AbstractScrollArea::scrollContentsBy(dx, dy); + + if (!viewport() || !m_container || (m_container && m_container->itemCount() <= 0) || + !m_model || (m_model && m_model->rowCount() <= 0) || + (viewport() && viewport()->boundingRect().height() < contentsRect().height())) + return; + + qreal itemH = 1; + + AbstractViewItem *item = m_container->itemAt(0); + if(item && item->size().height() > 1) { + itemH = item->size().height(); + } + else if(item && item->preferredHeight() > 1) { + itemH = item->preferredHeight(); + } + + qreal vpx = m_container->pos().x(); + qreal vpy = m_container->pos().y(); + + if ((vpy+m_container->size().height()-dy > pos().y()+size().height()) && + (qAbs(dy) < itemH) && (vpy-dy <= 0)) { + m_container->setPos(vpx, vpy-dy); + } + else { + qreal vPos = verticalScrollBar()->sliderPosition(); + int startRow = m_model->index(vPos/itemH, 0).row(); + int itemsInContainer = m_container->itemCount(); + + for (int i = 0; iitemAt(i); + changedItem->setModelIndex(m_model->index(startRow+i,0)); +#if (QT_VERSION >= 0x040600) + m_container->setListItemCaching(listItemCaching(), i); +#endif + } + + qreal diff = vPos-startRow*itemH; + + if (diff < 0) + m_container->setPos(vpx, diff); + else + m_container->setPos(vpx, -diff); + } +} + +void AbstractItemView::changeTheme() +{ + if (m_container) + m_container->themeChange(); +} + +void AbstractItemView::updateViewContent() +{ + if (m_container) + m_container->updateContent(); +} diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.h b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.h new file mode 100644 index 0000000..9d8220e --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ABSTRACTITEMVIEW_H +#define ABSTRACTITEMVIEW_H + +#include +#include +#include +#include + +#include "listitemcontainer.h" +#include "abstractscrollarea.h" +#include "scroller.h" + +class QItemSelectionModel; + +class AbstractItemView : public AbstractScrollArea +{ + Q_OBJECT +public: + AbstractItemView(QGraphicsWidget *parent = 0); + virtual ~AbstractItemView(); + virtual void setContainer(AbstractItemContainer *container); + virtual void setModel(QAbstractItemModel *model, AbstractViewItem *prototype); + virtual QAbstractItemModel* model() const; + virtual void setItemPrototype(AbstractViewItem* prototype); + + void setSelectionModel(QItemSelectionModel *smodel); + + virtual QModelIndex nextIndex(const QModelIndex &index) const; + virtual QModelIndex previousIndex(const QModelIndex &index) const; + + virtual int indexCount() const; + + void refreshContainerGeometry(); // TODO Can this be moved to scroll area? + + void updateViewContent(); + virtual void scrollContentsBy(qreal dx, qreal dy); + +#if (QT_VERSION >= 0x040600) + virtual bool listItemCaching() const = 0; + virtual void setListItemCaching(bool enabled) = 0; +#endif + +protected: + virtual bool event(QEvent *e); + void changeTheme(); + +public slots: + virtual void setRootIndex(const QModelIndex &index); + void setCurrentIndex(const QModelIndex &index, + QItemSelectionModel::SelectionFlags selectionFlag = QItemSelectionModel::NoUpdate); +protected slots: + virtual void currentIndexChanged(const QModelIndex ¤t, const QModelIndex &previous); + virtual void currentSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); + virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + virtual void rowsAboutToBeInserted(const QModelIndex &index, int start, int end); + virtual void rowsInserted(const QModelIndex &parent, int start, int end); + virtual void rowsAboutToBeRemoved(const QModelIndex &index,int start, int end); + virtual void rowsRemoved(const QModelIndex &parent,int start, int end); + virtual void modelDestroyed(); + virtual void layoutChanged(); + virtual void reset(); + +protected: + + QAbstractItemModel *m_model; + QPersistentModelIndex m_rootIndex; + AbstractItemContainer *m_container; + QItemSelectionModel *m_selectionModel; + QPersistentModelIndex m_currentIndex; + +private: + Q_DISABLE_COPY(AbstractItemView) + Scroller m_scroller; +}; + + +#endif // ABSTRACTITEMVIEW_H diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.cpp new file mode 100644 index 0000000..8bef331 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.cpp @@ -0,0 +1,249 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include "abstractscrollarea.h" +#include "scrollbar.h" + +AbstractScrollArea::AbstractScrollArea(QGraphicsWidget *parent) + : GvbWidget(parent) + , m_viewport(0) + , m_horizontalScrollBar(0) + , m_verticalScrollBar(0) + , m_prevHorizontalValue(0.0) + , m_prevVerticalValue(0.0) +{ + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + setContentsMargins(0, 0, 0, 0); + + m_horizontalScrollBar = new ScrollBar(Qt::Horizontal, this); + m_horizontalScrollBar->hide(); + m_horizontalScrollBar->setContentsMargins(0, 0, 0, 0); + m_horizontalScrollBarPolicy = Qt::ScrollBarAsNeeded; + m_horizontalScrollBar->setZValue(zValue()+1); // Raise scroll bar to top + m_horizontalScrollBar->setVisible(false); + + connect(m_horizontalScrollBar, SIGNAL(sliderPositionChange(qreal)), + this, SLOT(horizontalScroll(qreal))); + connect(m_horizontalScrollBar, SIGNAL(sliderPressed()), + this, SLOT(horizontalScrollStart())); + + m_verticalScrollBar = new ScrollBar(Qt::Vertical, this); + m_verticalScrollBar->hide(); + m_verticalScrollBar->setContentsMargins(0, 0, 0, 0); + m_verticalScrollBarPolicy = Qt::ScrollBarAsNeeded; + m_verticalScrollBar->setZValue(zValue()+1); // Raise scroll bar to top + m_verticalScrollBar->setVisible(false); + + connect(m_verticalScrollBar, SIGNAL(sliderPositionChange(qreal)), + this, SLOT(verticalScroll(qreal))); + connect(m_verticalScrollBar, SIGNAL(sliderPressed()), + this, SLOT(verticalScrollStart())); + + QGraphicsWidget *viewport = new QGraphicsWidget; + setViewport(viewport); +} + +AbstractScrollArea::~AbstractScrollArea() +{ +} + +ScrollBar *AbstractScrollArea::verticalScrollBar() const +{ + return m_verticalScrollBar; +} + +ScrollBar *AbstractScrollArea::horizontalScrollBar() const +{ + return m_horizontalScrollBar; +} + +void AbstractScrollArea::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy) +{ + m_horizontalScrollBarPolicy = policy; +} + +void AbstractScrollArea::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy) +{ + m_verticalScrollBarPolicy = policy; +} + +Qt::ScrollBarPolicy AbstractScrollArea::verticalScrollBarPolicy() const +{ + return m_verticalScrollBarPolicy; +} + +Qt::ScrollBarPolicy AbstractScrollArea::horizontalScrollBarPolicy() const +{ + return m_horizontalScrollBarPolicy; +} + +QGraphicsWidget *AbstractScrollArea::viewport() const +{ + return m_viewport; +} + +void AbstractScrollArea::setViewport(QGraphicsWidget *viewport) +{ + if (m_viewport) { + m_viewport->setParentItem(0); + + QList children = m_viewport->childItems(); + + foreach (QGraphicsItem *child, children) + child->setParentItem(0); + + delete m_viewport; + } + + m_viewport = viewport; + + if (viewport) { + + m_viewport->setParentItem(this); + m_viewport->setContentsMargins(0, 0, 0, 0); + + adjustScrollBars(); + } + + emit viewportChanged(viewport); +} + +bool AbstractScrollArea::event(QEvent *e) +{ + if (e->type() == QEvent::ApplicationLayoutDirectionChange + || e->type() == QEvent::LayoutDirectionChange) { + } else if (e->type() == QEvent::GraphicsSceneResize) { + QGraphicsSceneResizeEvent *event = + static_cast(e); + + QSizeF newSize = event->newSize(); + QRectF hrect = m_horizontalScrollBar->boundingRect(); + QRectF vrect = m_verticalScrollBar->boundingRect(); + + QSizeF vpSize = newSize; + + if (m_horizontalScrollBarPolicy != Qt::ScrollBarAlwaysOff) + vpSize.setHeight(newSize.height() - hrect.height()); + if (m_verticalScrollBarPolicy != Qt::ScrollBarAlwaysOff) + vpSize.setWidth(newSize.width() - vrect.width()); + + m_viewport->resize(vpSize); + + adjustScrollBars(); + } + + return QGraphicsWidget::event(e); +} + + +void AbstractScrollArea::scrollContentsBy(qreal dx, qreal dy) +{ + Q_UNUSED(dx) + Q_UNUSED(dy) + prepareGeometryChange(); +} + +void AbstractScrollArea::verticalScrollStart() +{ + m_prevVerticalValue = m_verticalScrollBar->sliderPosition(); +} + +void AbstractScrollArea::verticalScroll(qreal value) +{ + qreal dy = value - m_prevVerticalValue; + if (!qFuzzyCompare(dy,qreal(0.0))) { + scrollContentsBy(0.0, dy); + m_prevVerticalValue = value; + } +} + +void AbstractScrollArea::horizontalScrollStart() +{ + m_prevHorizontalValue = m_horizontalScrollBar->sliderPosition(); +} + +void AbstractScrollArea::horizontalScroll(qreal value) +{ + qreal dx = value - m_prevHorizontalValue; + if (!qFuzzyCompare(dx,qreal(0.0))) { + scrollContentsBy(dx, 0.0); + m_prevHorizontalValue = value; + } +} + +void AbstractScrollArea::adjustScrollBars() +{ + if (m_horizontalScrollBarPolicy == Qt::ScrollBarAlwaysOff) { + m_horizontalScrollBar->hide(); + } else { + m_horizontalScrollBar->show(); + + QRectF sbgeom = boundingRect(); + + sbgeom.setTop(sbgeom.bottom() - m_horizontalScrollBar->boundingRect().height()); + sbgeom.setRight(sbgeom.right() - m_verticalScrollBar->boundingRect().width()); + m_horizontalScrollBar->setGeometry(sbgeom); + } + + if (m_verticalScrollBarPolicy == Qt::ScrollBarAlwaysOff) { + m_verticalScrollBar->hide(); + QRectF sbgeom = boundingRect(); + sbgeom.setLeft(sbgeom.right()); + sbgeom.setBottom(sbgeom.bottom()); + m_verticalScrollBar->setGeometry(sbgeom); + } else { + m_verticalScrollBar->show(); + + QRectF sbgeom = boundingRect(); + + sbgeom.setLeft(sbgeom.right() - m_verticalScrollBar->boundingRect().width()); + if (m_horizontalScrollBarPolicy != Qt::ScrollBarAlwaysOff) + sbgeom.setBottom(sbgeom.bottom() - m_horizontalScrollBar->boundingRect().height()); + m_verticalScrollBar->setGeometry(sbgeom); + } +} + + + + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.h b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.h new file mode 100644 index 0000000..c39da14 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ABSTRACTSCROLLAREA_H +#define ABSTRACTSCROLLAREA_H + +#include "gvbwidget.h" + +class ScrollBar; +class QGraphicsGridLayout; + +class AbstractScrollArea : public GvbWidget +{ + Q_OBJECT + +public: + + AbstractScrollArea(QGraphicsWidget *parent = 0); + ~AbstractScrollArea(); + +public: + + void setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy); + void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy); + Qt::ScrollBarPolicy verticalScrollBarPolicy() const; + Qt::ScrollBarPolicy horizontalScrollBarPolicy() const; + + QGraphicsWidget *viewport() const; + void setViewport(QGraphicsWidget *viewport); + + ScrollBar *verticalScrollBar() const; + ScrollBar *horizontalScrollBar() const; + +signals: + + void viewportChanged(QGraphicsWidget *viewport); + +protected: + + virtual bool event(QEvent *e); + virtual void scrollContentsBy(qreal dx, qreal dy); + +private slots: + + void verticalScrollStart(); + void verticalScroll(qreal); + void horizontalScrollStart(); + void horizontalScroll(qreal); + +private: + + void adjustScrollBars(); + + QGraphicsWidget *m_viewport; + ScrollBar *m_horizontalScrollBar; + ScrollBar *m_verticalScrollBar; + Qt::ScrollBarPolicy m_verticalScrollBarPolicy; + Qt::ScrollBarPolicy m_horizontalScrollBarPolicy; + qreal m_prevHorizontalValue; + qreal m_prevVerticalValue; +}; + +#endif // ABSTRACTSCROLLAREA_H diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.cpp new file mode 100644 index 0000000..83938c1 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "abstractviewitem.h" + +AbstractViewItem::AbstractViewItem(QGraphicsWidget *parent) + : GvbWidget(parent), + m_index(), + m_itemView(0), + m_prototype(0) +{ +} + +/*virtual*/ +AbstractViewItem::~AbstractViewItem() +{ +} + +QModelIndex AbstractViewItem::modelIndex() const +{ + return m_index; +} + +AbstractViewItem *AbstractViewItem::prototype() const +{ + return m_prototype; +} + +AbstractItemView *AbstractViewItem::itemView() const +{ + return m_itemView; +} + +void AbstractViewItem::setItemView(AbstractItemView *itemView) +{ + m_itemView = itemView; +} + +void AbstractViewItem::setModelIndex(const QModelIndex &index) +{ + if (m_index != index) { + m_index = index; + updateItemContents(); + } +} + +/*virtual*/ +QSizeF AbstractViewItem::effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + return GvbWidget::effectiveSizeHint(which, constraint); +} + +/*virtual*/ +bool AbstractViewItem::event(QEvent *e) +{ + return QGraphicsWidget::event(e); +} + +/*virtual*/ +void AbstractViewItem::updateItemContents() +{ + ; // No impl yet +} + +/*virtual*/ +void AbstractViewItem::themeChange() +{ + ; // No impl yet +} + +#if (QT_VERSION >= 0x040600) +/*virtual*/ +void AbstractViewItem::setSubtreeCacheEnabled(bool enabled) +{ + Q_UNUSED(enabled) + ; // No impl +} +#endif + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.h b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.h new file mode 100644 index 0000000..54552c2 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ABSTRACTVIEWITEM_H +#define ABSTRACTVIEWITEM_H + +#include + +#include "gvbwidget.h" +#include "abstractitemview.h" +#include "listitem.h" + +class QGraphicsWidget; + +class AbstractViewItem : public GvbWidget +{ + Q_OBJECT +public: + AbstractViewItem(QGraphicsWidget *parent = 0); + virtual ~AbstractViewItem(); + + virtual AbstractViewItem *newItemInstance() = 0; + + QModelIndex modelIndex() const; + + void setModelIndex(const QModelIndex &index); + + AbstractViewItem *prototype() const; + AbstractItemView *itemView() const; + void setItemView(AbstractItemView *itemView) ; + virtual void updateItemContents(); + virtual void themeChange(); + +#if (QT_VERSION >= 0x040600) + virtual void setSubtreeCacheEnabled(bool enabled); +#endif + + virtual QSizeF effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + + virtual void setModel(QAbstractItemModel *model) = 0; + virtual QVariant data(int role) const = 0; + virtual void setData(const QVariant &value, int role = Qt::DisplayRole) = 0; + virtual void setTwoColumns(const bool enabled) = 0; + +protected: + virtual bool event(QEvent *e); + + QPersistentModelIndex m_index; + +private: + Q_DISABLE_COPY(AbstractViewItem) + + AbstractItemView *m_itemView; + AbstractViewItem *m_prototype; + +}; + +#endif // ABSTRACTVIEWITEM_H diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.cpp new file mode 100644 index 0000000..fc3ed61 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +#include "backgrounditem.h" +#include "theme.h" + +BackgroundItem::BackgroundItem(const QString &filename, QGraphicsWidget *parent) + : GvbWidget(parent), + m_background(), + m_fileName(filename) +{ + setContentsMargins(0,0,0,0); + + connect(Theme::p(), SIGNAL(themeChanged()), this, SLOT(themeChange())); +} + +BackgroundItem::~BackgroundItem() +{ + +} + +void BackgroundItem::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + GvbWidget::resizeEvent(event); + m_background = Theme::p()->pixmap(m_fileName, size().toSize()); +} + +void BackgroundItem::paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + Q_UNUSED(widget) + painter->setCompositionMode(QPainter::CompositionMode_Source); + painter->drawPixmap(option->exposedRect, m_background, option->exposedRect); +} + +void BackgroundItem::themeChange() +{ + m_background = Theme::p()->pixmap(m_fileName, size().toSize()); + update(); +} + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.h b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.h new file mode 100644 index 0000000..f127a7b --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __BACKGROUNDITEM_H__ +#define __BACKGROUNDITEM_H__ + +#include + +#include "gvbwidget.h" + +class QGraphicsWidget; + +class BackgroundItem : public GvbWidget +{ + Q_OBJECT + +public: + BackgroundItem(const QString &filename, QGraphicsWidget *parent=0); + ~BackgroundItem(); + + void paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *widget = 0); + void resizeEvent(QGraphicsSceneResizeEvent *event); + +public slots: + void themeChange(); + +private: + QPixmap m_background; + QString m_fileName; +}; + +#endif /* __BACKGROUNDITEM_H__ */ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/button.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/button.cpp new file mode 100644 index 0000000..6a8e81c --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/button.cpp @@ -0,0 +1,209 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "button.h" +#include "theme.h" + +static const int MinTextWidthAsChars = 8; + +class ButtonPrivate { + Q_DECLARE_PUBLIC(Button) + +public: + + ButtonPrivate(Button *button) + : down(false) + , q_ptr(button) + { + textItem = new QGraphicsSimpleTextItem(q_ptr); + } + + QGraphicsSimpleTextItem *textItem; + bool down; + Button *q_ptr; +}; + +Button::Button(const QString &text, QGraphicsItem *parent, QSizeF minimumSize) + : QGraphicsWidget(parent) + , d_ptr(new ButtonPrivate(this)), m_background(), m_selected(false) +{ + Q_D(Button); + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + //setCacheMode(QGraphicsItem::ItemCoordinateCache); + if(minimumSize.isValid()) + setMinimumSize(minimumSize); + setContentsMargins(0, 0, 0, 0); + d->textItem->setText(text); + prepareGeometryChange(); + + m_font = Theme::p()->font(Theme::MenuItem); + d->textItem->setFont(m_font); + connect(Theme::p(), SIGNAL(themeChanged()), this, SLOT(themeChange())); +} + +Button::~Button() +{ + delete d_ptr; +} + +bool Button::isDown() +{ + Q_D(Button); + + return d->down; +} + +void Button::setText(const QString &text) +{ + Q_D(Button); + d->textItem->setText(text); + update(); +} + +QString Button::text() +{ + Q_D(Button); + return d->textItem->text(); +} + +void Button::paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + Q_UNUSED(widget); + Q_UNUSED(option); + + if(!m_background.isNull()) + painter->drawPixmap(QPoint(), m_background); + if(m_selected) { + painter->setBrush(Qt::black); + painter->setOpacity(0.2); + painter->drawRect(boundingRect().toRect()); + } +} + +QSizeF Button::sizeHint(Qt::SizeHint which, + const QSizeF &constraint) const +{ + Q_D(const Button); + + switch (which) + { + case Qt::MinimumSize: + { + QFontMetricsF fm(d->textItem->font()); + return QSizeF(MinTextWidthAsChars * fm.maxWidth(), fm.height()); + } + case Qt::PreferredSize: + { + QFontMetricsF fm(d->textItem->font()); + return QSizeF(fm.width(d->textItem->text()), fm.height()); + } + default: + return QGraphicsWidget::sizeHint(which, constraint); + } +} + +void Button::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(Button); + + if (event->button() != Qt::LeftButton || + !sceneBoundingRect().contains(event->scenePos())) + return; + + d->down = true; + + prepareGeometryChange(); + emit pressed(); + +} + +void Button::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(Button); + + if (!d->down || event->button() != Qt::LeftButton) + return; + + d->down = false; + + prepareGeometryChange(); + + emit released(); + + if (sceneBoundingRect().contains(event->scenePos())) + emit clicked(); +} + +void Button::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); +} + +void Button::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_D(Button); + QGraphicsWidget::resizeEvent(event); + + QRectF rect = d->textItem->boundingRect(); + QRectF buttonrect = this->boundingRect(); + d->textItem->setPos((buttonrect.width() - rect.width())/2, (buttonrect.height() - rect.height())/2 ); + + QSize currentSize = buttonrect.size().toSize(); + if( m_background.size() != currentSize && (currentSize.width() > 0 && currentSize.height() > 0) ) { + m_background = Theme::p()->pixmap("status_field_middle.svg", buttonrect.size().toSize()); + } +} + +void Button::setBackground(QPixmap& background) +{ + m_background = background; +} + +void Button::themeChange() +{ + Q_D(Button); + + m_font = Theme::p()->font(Theme::MenuItem); + d->textItem->setFont(m_font); +} diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/button.h b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/button.h new file mode 100644 index 0000000..d4fca2f --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/button.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BUTTON_H +#define BUTTON_H + +#include + +class ButtonPrivate; +class QTextDocument; + +class QPixmap; +class QFont; + +class Button : public QGraphicsWidget +{ + Q_OBJECT + Q_DECLARE_PRIVATE(Button) + +public: + + Button(const QString &text, QGraphicsItem *parent=0, QSizeF minimumSize = QSizeF()); + virtual ~Button(); + +signals: + + void clicked(bool checked = false); + void pressed(); + void released(); + +public slots: + + void themeChange(); + void setText(const QString &text); + QString text(); + +public: + + void setBackground(QPixmap& background); + bool isDown(); + void select(bool select){m_selected = select;} + void click() {emit clicked();} + +private: + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget = 0); + QSizeF sizeHint(Qt::SizeHint which, + const QSizeF &constraint = QSizeF()) const; + + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void resizeEvent(QGraphicsSceneResizeEvent *event); + +private: + Q_DISABLE_COPY(Button) + ButtonPrivate *d_ptr; + QPixmap m_background; + QFont m_font; + bool m_selected; +}; + +#endif // BUTTON_H diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.cpp new file mode 100644 index 0000000..9205bed --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.cpp @@ -0,0 +1,206 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "commandline.h" + +static void usage(const char *appname) +{ + printf("%s [options]\n", appname); + printf("Options:\n"); + printf("\t -h,-help : This help\n"); +#ifdef AUTO_TESTS + printf("\t -o file : Write output to file\n"); + printf("\t -xml : Outputs results as XML document\n"); + printf("\t -lightxml : Outputs results as stream of XML tags\n"); + printf("\t -script-name file : Use this script instead of internal script file\n"); +#endif + printf("\t -resolution : UI resolution in format WxH where width and height are positive values\n"); + printf("\t -rotation : UI rotation in degrees\n"); + printf("\t -subtree-cache : Enables usage of subtree caching method\n"); + printf("\t -noresusage : Disables CPU and Memory usage measurement\n"); +#ifndef AUTO_TESTS + printf("\t -fps : Output FPS count to stdout during application execution\n"); + printf("\t -items : Count of items created to the list\n"); +#endif +#if ENABLE_OPENGL +#ifndef QT_NO_OPENGL + printf("\t -opengl : Enables OpenGL usage. Building PRECONDITIONS: ENABLE_OPENGL is on. QT_NO_OPENGL is off.\n"); +#endif +#endif + printf("\n"); +} + +bool readSettingsFromCommandLine(int argc, char *argv[], + Settings& config) +{ + bool builtWithOpenGL = false; + Settings::Options options; + +#if ENABLE_OPENGL +#ifndef QT_NO_OPENGL + builtWithOpenGL = true; +#endif +#endif + for (int i=0; i= argc) { + printf("-o needs an extra parameter specifying the filename\n"); + usage(argv[0]); + return false; + } else { + config.setOutputFileName(QString(argv[i+1])); + i++; + } + } + if (strcmp(argv[i], "-xml") == 0) { + config.setResultFormat(1); // See FileLogger::ResultFormat + } + if (strcmp(argv[i], "-lightxml") == 0) { + config.setResultFormat(2); // See FileLogger::ResultFormat + } + if (strcmp(argv[i], "-script-name") == 0) { + if (i + 1 >= argc) { + printf("-script-name needs an extra parameter specifying the filename\n"); + usage(argv[0]); + return false; + } else { + config.setScriptName(QString(argv[i+1])); + i++; + } + } +#endif + if (strcmp(argv[i], "-resolution") == 0) { + if (i + 1 >= argc) { + printf("-resolution needs an extra parameter specifying the application UI resolution\n"); + usage(argv[0]); + return false; + } + else { + QStringList res = QString(argv[i+1]).split("x"); + if (res.count() != 2) { + printf("-resolution parameter UI resolution should be set in format WxH where width and height are positive values\n"); + usage(argv[0]); + return false; + } + int width = res.at(0).toInt(); + int height = res.at(1).toInt(); + + config.setSize(QSize(width, height)); + + if (width <=0 || height <=0) { + printf("-resolution parameter UI resolution should be set in format WxH where width and height are positive values\n"); + usage(argv[0]); + return false; + } + i++; + } + } + if (strcmp(argv[i], "-rotation") == 0) { + if (i + 1 >= argc) { + printf("-rotation needs an extra parameter specifying the application UI rotation in degrees\n"); + usage(argv[0]); + return false; + } + else { + bool ok; + int angle = QString(argv[i+1]).toInt(&ok); + if (!ok) { + printf("-rotation parameter should specify rotation angle in degrees\n"); + usage(argv[0]); + return false; + } + config.setAngle(angle); + i++; + } + } + if (strcmp(argv[i], "-subtree-cache") == 0) { + options |= Settings::UseListItemCache; + } + if (strcmp(argv[i], "-opengl") == 0) { + if (builtWithOpenGL) + options |= Settings::UseOpenGL; + else { + printf("-opengl parameter can be used only with building PRECONDITIONS: ENABLE_OPENGL is on. QT_NO_OPENGL is off.\n"); + usage(argv[0]); + return false; + } + } + if (strcmp(argv[i], "-noresusage") == 0) { + options |= Settings::NoResourceUsage; + } +#ifndef AUTO_TESTS + if (strcmp(argv[i], "-fps") == 0) { + options |= Settings::OutputFps; + } + if (strcmp(argv[i], "-items") == 0) { + if (i + 1 >= argc) { + printf("-items needs an extra parameter specifying amount of list items\n"); + usage(argv[0]); + return false; + } + else { + bool ok; + int amount = QString(argv[i+1]).toInt(&ok); + if (!ok) { + printf("-items needs an extra parameter specifying amount (integer) of list items\n"); + usage(argv[0]); + return false; + } + config.setListItemCount(amount); + i++; + } + } +#endif + } + + config.setOptions(options); + + return true; +} + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.h b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.h new file mode 100644 index 0000000..3794638 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef COMMANDLINE_H +#define COMMANDLINE_H + +#include "settings.h" + +bool readSettingsFromCommandLine(int argc, + char *argv[], + Settings& settings); + + +#endif // COMMANDLINE_H diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp new file mode 100644 index 0000000..2716227 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "theme.h" + +#include "dummydatagen.h" + +DummyDataGenerator::DummyDataGenerator() : m_isMale(false) +{ + QFile countryCodeFile(":/contact/areacodes.txt"); + countryCodeFile.open(QIODevice::ReadOnly); + while (!countryCodeFile.atEnd()) { + m_countryCodes << QString(countryCodeFile.readLine()).remove("\n"); + } + + QFile firstNameFFile(":/contact/firstnamesF.txt"); + firstNameFFile.open(QIODevice::ReadOnly); + while (!firstNameFFile.atEnd()) { + m_firstNamesF << QString(firstNameFFile.readLine()).remove("\n"); + } + + QFile firstNameMFile(":/contact/firstnamesM.txt"); + firstNameMFile.open(QIODevice::ReadOnly); + while (!firstNameMFile.atEnd()) { + m_firstNamesM << QString(firstNameMFile.readLine()).remove("\n"); + } + + QFile lastNameFile(":/contact/lastnames.txt"); + lastNameFile.open(QIODevice::ReadOnly); + while (!lastNameFile.atEnd()) { + m_lastNames << QString(lastNameFile.readLine()).remove("\n"); + } + Reset(); +} + +DummyDataGenerator::~DummyDataGenerator() +{ + +} + +void DummyDataGenerator::Reset() +{ + qsrand(100); +} + +QString DummyDataGenerator::randomPhoneNumber(QString indexNumber) +{ + int index = qrand()%m_countryCodes.count(); + QString countryCode = m_countryCodes.at(index); + QString areaCode = QString::number(index) + QString("0").repeated(2-QString::number(index).length()); + QString beginNumber = QString::number(555-index*2); + QString endNumber = QString("0").repeated(4-indexNumber.length()) + indexNumber; + + return countryCode +" " + areaCode +" " + beginNumber +" " + endNumber; +} + +QString DummyDataGenerator::randomFirstName() +{ + m_isMale = !m_isMale; + if (m_isMale) + return m_firstNamesM.at(qrand()%m_firstNamesM.count()); + return m_firstNamesF.at(qrand()%m_firstNamesF.count()); +} + +QString DummyDataGenerator::randomLastName() +{ + return m_lastNames.at(qrand()%m_lastNames.count()); +} + +QString DummyDataGenerator::randomName() +{ + return QString(randomFirstName()+QString(", ")+randomLastName()); +} + +QString DummyDataGenerator::randomIconItem() +{ + QString avatar = Theme::p()->pixmapPath() + "contact_default_icon.svg"; + if (qrand()%4) { + int randVal = 1+qrand()%25; + + if(m_isMale && randVal > 15) { + randVal -= 15; + } + if(!m_isMale && randVal <= 10) { + randVal += 10; + } + + avatar = QString(":/avatars/avatar_%1.png").arg(randVal, 3, 10, QChar('0')); + } + return avatar; +} + +QString DummyDataGenerator::randomStatusItem() +{ + switch ( qrand()%3 ) + { + case 0: return Theme::p()->pixmapPath() + "contact_status_online.svg"; + case 1: return Theme::p()->pixmapPath() + "contact_status_offline.svg"; + case 2: return Theme::p()->pixmapPath() + "contact_status_idle.svg"; + } + return 0; +} diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.h b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.h new file mode 100644 index 0000000..df59221 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __DUMMYDATAGEN_H__ +#define __DUMMYDATAGEN_H__ + +#include +#include + +class DummyDataGenerator : public QObject +{ + Q_OBJECT +public: + DummyDataGenerator(); + ~DummyDataGenerator(); + +public: + void Reset(); + QString randomPhoneNumber(QString indexNumber); + QString randomFirstName(); + QString randomLastName(); + QString randomName(); + QString randomIconItem(); + QString randomStatusItem(); + +private: + QStringList m_countryCodes; + QStringList m_firstNamesF; + QStringList m_firstNamesM; + QStringList m_lastNames; + bool m_isMale; +}; + +#endif // __DUMMYDATAGEN_H__ diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.cpp new file mode 100644 index 0000000..244b76b --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "gvbwidget.h" + +GvbWidget::GvbWidget(QGraphicsItem * parent, Qt::WindowFlags wFlags) + : QGraphicsWidget(parent, wFlags) +{ + +} + +GvbWidget::~GvbWidget() +{ +} + +void GvbWidget::keyPressEvent(QKeyEvent *event) +{ + Q_UNUSED(event) +} + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.h b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.h new file mode 100644 index 0000000..d4ae6de --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GVBWIDGET_H +#define GVBWIDGET_H + +#include + +class GvbWidget : public QGraphicsWidget +{ + Q_OBJECT + +public: + + GvbWidget(QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0); + ~GvbWidget(); + virtual void keyPressEvent(QKeyEvent *event); +}; + +#endif diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.cpp new file mode 100644 index 0000000..77866e4 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.cpp @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#if (QT_VERSION >= 0x040600) +#include +#endif + +#include "iconitem.h" + +IconItem::IconItem(const QString &filename, QGraphicsItem *parent) + : GvbWidget(parent) + , m_filename(filename) + , m_rotation(0.0) +#if (QT_VERSION >= 0x040600) + , m_opacityEffect(0) +#endif + , m_smoothTransformation(false) +{ + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + setContentsMargins(0,0,0,0); + setPreferredSize(58,58); +} + +IconItem::~IconItem() +{ +} + +void IconItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + reload(); + + const QPointF c = boundingRect().center(); + painter->translate(c.x(), c.y()); + painter->rotate(m_rotation); + painter->translate(-c.x(), -c.y()); + + if (m_smoothTransformation) + painter->setRenderHints(QPainter::SmoothPixmapTransform); + + painter->drawPixmap(0,0, m_pixmap); +} + +QSizeF IconItem::sizeHint(Qt::SizeHint which, + const QSizeF &constraint) const +{ + switch (which) + { + case Qt::MinimumSize: + case Qt::PreferredSize: + case Qt::MaximumSize: + return m_pixmap.size(); + + default: + return GvbWidget::sizeHint(which, constraint); + } +} + +void IconItem::reload() +{ + const QSize iconSize = size().toSize(); + if (iconSize.width() == 0 || iconSize.height() == 0) + return; + + const QString key = m_filename+QString::number(iconSize.width())+QString::number(iconSize.height()); + if (QPixmapCache::find(key, m_pixmap)) + return; + + if (m_filename.endsWith(".svg", Qt::CaseInsensitive)) + { + m_pixmap = QPixmap(iconSize); + m_pixmap.fill(Qt::transparent); + QSvgRenderer doc(m_filename); + QPainter painter(&m_pixmap); + painter.setViewport(0, 0, iconSize.width(), iconSize.height()); + doc.render(&painter); + } + else + { + m_pixmap = QPixmap(m_filename).scaled(iconSize); + } + + QPixmapCache::insert(key, m_pixmap); + updateGeometry(); +} + +QString IconItem::fileName() const +{ + return m_filename; +} + +void IconItem::setFileName(const QString &filename) +{ + if( m_filename != filename) { + m_filename = filename; + reload(); + } +} + +#if (QT_VERSION >= 0x040600) +void IconItem::setOpacityEffectEnabled(const bool enable) +{ + if (!m_opacityEffect) + { + QRadialGradient gradient(0.5, 0.5, 1.0); + gradient.setCoordinateMode(QGradient::ObjectBoundingMode); + gradient.setColorAt(0.0, QColor(0,0,0, 255)); + gradient.setColorAt(0.46, QColor(0,0,0, 255)); + gradient.setColorAt(0.62, QColor(0,0,0, 0)); + + m_opacityEffect = new QGraphicsOpacityEffect; + m_opacityEffect->setOpacityMask(gradient); + m_opacityEffect->setOpacity(1.0); + this->setGraphicsEffect(m_opacityEffect); + } + m_opacityEffect->setEnabled(enable); +} + +bool IconItem::isOpacityEffectEnabled() const +{ + if (m_opacityEffect) + return m_opacityEffect->isEnabled(); + + return false; +} +#endif diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.h b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.h new file mode 100644 index 0000000..7f0a232 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ICONITEM_H +#define ICONITEM_H + +#include + +#include "gvbwidget.h" + +#if (QT_VERSION >= 0x040600) +class QGraphicsOpacityEffect; +#endif +class QPainter; + +class IconItem : public GvbWidget +{ + Q_OBJECT + +public: + + IconItem(const QString &filename = "", QGraphicsItem *parent = 0); + + virtual ~IconItem(); + + QString fileName() const; + void setFileName(const QString &filename); + +#if (QT_VERSION >= 0x040600) + void setOpacityEffectEnabled(const bool enable); + bool isOpacityEffectEnabled() const; +#endif + void setRotation(const qreal rotation) { m_rotation = rotation; } + qreal rotation() const { return m_rotation; } + + void setSmoothTransformationEnabled(const bool enable) { m_smoothTransformation = enable; } + bool isSmoothTransformationEnabled() const { return m_smoothTransformation; } + +private: + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget */*widget = 0*/); + QSizeF sizeHint(Qt::SizeHint which, + const QSizeF &constraint = QSizeF()) const; + +private: + Q_DISABLE_COPY(IconItem) + void reload(); + + QString m_filename; + QPixmap m_pixmap; + qreal m_rotation; +#if (QT_VERSION >= 0x040600) + QGraphicsOpacityEffect *m_opacityEffect; +#endif + bool m_smoothTransformation; +}; + +#endif diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.cpp new file mode 100644 index 0000000..3b62a38 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.cpp @@ -0,0 +1,275 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "itemrecyclinglist.h" +#include "listitemcontainer.h" +#include "abstractviewitem.h" +#include "recycledlistitem.h" +#include "theme.h" +#include "scrollbar.h" + +ItemRecyclingList::ItemRecyclingList(const int itemBuffer, QGraphicsWidget * parent) + : ItemRecyclingListView(parent), + m_listModel(new ListModel(this)) +{ + ListItemContainer *container = new ListItemContainer(itemBuffer, this, this); + container->setParentItem(this); + ItemRecyclingListView::setContainer(container); + ItemRecyclingListView::setModel(m_listModel, new RecycledListItem(this)); + setObjectName("ItemRecyclingList"); + connect(Theme::p(), SIGNAL(themeChanged()), this, SLOT(themeChange())); + + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); +} + +/* virtual */ +ItemRecyclingList::~ItemRecyclingList() +{ +} + +/* virtual */ +void ItemRecyclingList::insertItem(int index, RecycledListItem *item) +{ + if (index<0) + index = 0; + if (index > m_listModel->rowCount()) + index = m_listModel->rowCount(); + if (m_listModel && item) + m_listModel->insert(index,item); + + updateListItemBackgrounds(index); +} + +/* virtual */ +void ItemRecyclingList::addItem(RecycledListItem *item) +{ + if (item) + m_listModel->appendRow(item); + + const int index = m_listModel->rowCount()-1; + updateListItemBackgrounds(index); +} + +/* virtual */ +void ItemRecyclingList::clear() +{ + m_listModel->clear(); +} + +/* virtual */ +AbstractViewItem *ItemRecyclingList::takeItem(const int row) +{ + if (row < 0 || row >= m_listModel->rowCount() || !m_listModel) + return 0; + return m_listModel->takeItem(row); +} + +/*virtual*/ +void ItemRecyclingList::setItemPrototype(AbstractViewItem* prototype) +{ + ItemRecyclingListView::setItemPrototype(prototype); +} + +void ItemRecyclingList::themeChange() +{ + const bool caching = listItemCaching(); + setListItemCaching(false); + + const QString iconName = Theme::p()->pixmapPath()+"contact_default_icon.svg"; + const int count = m_listModel->rowCount(); + + for (int i=0; iitem(i); + if (ritem) { + ListItem *item = ritem->item(); + + // Update default icons + const QString filename = item->icon(ListItem::LeftIcon)->fileName(); + if (filename.contains("contact_default_icon")) { + item->icon(ListItem::LeftIcon)->setFileName(iconName); + } + + // Update status icons + QString statusIcon = item->icon(ListItem::RightIcon)->fileName(); + const int index = statusIcon.indexOf("contact_status"); + if (index != -1) { + statusIcon.remove(0, index); + item->icon(ListItem::RightIcon)->setFileName(Theme::p()->pixmapPath()+statusIcon); + } + + // Update fonts + item->setFont(Theme::p()->font(Theme::ContactName), ListItem::FirstPos); + item->setFont(Theme::p()->font(Theme::ContactNumber), ListItem::SecondPos); + item->setFont(Theme::p()->font(Theme::ContactEmail), ListItem::ThirdPos); + + // Update list dividers + if (i%2) { + item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushOdd()); + item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityOdd()); + } + else { + item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushEven()); + item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityEven()); + } + + // Update borders + item->setBorderPen(Theme::p()->listItemBorderPen()); + item->setRounding(Theme::p()->listItemRounding()); + + // Update icons + item->icon(ListItem::LeftIcon)->setRotation(Theme::p()->iconRotation(ListItem::LeftIcon)); + item->icon(ListItem::RightIcon)->setRotation(Theme::p()->iconRotation(ListItem::RightIcon)); +#if (QT_VERSION >= 0x040600) + item->icon(ListItem::LeftIcon)->setOpacityEffectEnabled(Theme::p()->isIconOpacityEffectEnabled(ListItem::LeftIcon)); + item->icon(ListItem::RightIcon)->setOpacityEffectEnabled(Theme::p()->isIconOpacityEffectEnabled(ListItem::RightIcon)); +#endif + item->icon(ListItem::LeftIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::LeftIcon)); + item->icon(ListItem::RightIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::RightIcon)); + } + } + updateViewContent(); + setListItemCaching(caching); +} + +void ItemRecyclingList::keyPressEvent(QKeyEvent *event) +{ + static QTime keyPressInterval = QTime::currentTime(); + static qreal step = 0.0; + static bool repeat = false; + int interval = keyPressInterval.elapsed(); + + ScrollBar* sb = verticalScrollBar(); + qreal currentValue = sb->sliderPosition(); + + if(interval < 250 ) { + if(!repeat) step = 0.0; + step = step + 2.0; + if(step > 100) step = 100; + repeat = true; + } + else { + step = 1.0; + if(m_listModel->item(0)) m_listModel->item(0)->size().height(); + step = m_listModel->item(0)->size().height(); + repeat = false; + } + + if(event->key() == Qt::Key_Up ) { //Up Arrow + sb->setSliderPosition(currentValue - step); + } + + if(event->key() == Qt::Key_Down ) { //Down Arrow + sb->setSliderPosition(currentValue + step); + } + keyPressInterval.start(); +} + +bool ItemRecyclingList::listItemCaching() const +{ +#if (QT_VERSION >= 0x040600) + ListItemContainer *container = + static_cast(m_container); + + return container->listItemCaching(); +#else + return false; +#endif +} + +void ItemRecyclingList::setListItemCaching(bool enabled) +{ +#if (QT_VERSION >= 0x040600) + ListItemContainer *container = + static_cast(m_container); + container->setListItemCaching(enabled); +#else + Q_UNUSED(enabled) +#endif +} + +void ItemRecyclingList::updateListItemBackgrounds(int index) +{ + const int itemCount = m_listModel->rowCount(); + + for (int i=index; iitem(i); + if (ritem) { + ListItem *item = ritem->item(); + if (i%2) { + item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushOdd()); + item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityOdd()); + } + else { + item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushEven()); + item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityEven()); + } + } + } +} + +void ItemRecyclingList::setTwoColumns(const bool enabled) +{ + if (twoColumns() == enabled) + return; + +#if (QT_VERSION >= 0x040600) + const bool caching = listItemCaching(); + setListItemCaching(false); +#endif + + m_container->setTwoColumns(enabled); + refreshContainerGeometry(); + +#if (QT_VERSION >= 0x040600) + setListItemCaching(caching); +#endif +} + +bool ItemRecyclingList::twoColumns() +{ + return m_container->twoColumns(); +} + diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.h b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.h new file mode 100644 index 0000000..1be1562 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ITEMRECYCLINGLIST_H +#define ITEMRECYCLINGLIST_H + +#include "listitem.h" +#include "abstractitemview.h" +#include "listmodel.h" +#include "itemrecyclinglistview.h" +#include "recycledlistitem.h" + +class QGraphicsWidget; + +class ItemRecyclingList : public ItemRecyclingListView +{ + Q_OBJECT + +public: + ItemRecyclingList(const int itemBuffer = 4, QGraphicsWidget * parent = 0); + virtual ~ItemRecyclingList(); + + virtual void insertItem(int index, RecycledListItem *item); + virtual void addItem(RecycledListItem *item); + virtual void clear(); + virtual AbstractViewItem *takeItem(const int row); + virtual void setItemPrototype(AbstractViewItem* prototype); + virtual void keyPressEvent(QKeyEvent *event); + virtual bool listItemCaching() const; + virtual void setListItemCaching(bool enabled); + + void setTwoColumns(const bool enabled); + bool twoColumns(); + +public slots: + void themeChange(); + +private: + void updateListItemBackgrounds(int index); + +private: + Q_DISABLE_COPY(ItemRecyclingList) + + ListModel *m_listModel; +}; + +#endif // ITEMRECYCLINGLIST_H diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.pri b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.pri new file mode 100644 index 0000000..55b551e --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.pri @@ -0,0 +1,19 @@ +HEADERS += $$ROOTDIR/tests/itemrecyclinglist/itemrecyclinglist.h \ + $$ROOTDIR/tests/itemrecyclinglist/itemrecyclinglistview.h \ + $$ROOTDIR/tests/itemrecyclinglist/abstractitemview.h \ + $$ROOTDIR/tests/itemrecyclinglist/abstractviewitem.h \ + $$ROOTDIR/tests/itemrecyclinglist/recycledlistitem.h \ + $$ROOTDIR/tests/itemrecyclinglist/listitemcontainer.h \ + $$ROOTDIR/tests/itemrecyclinglist/abstractitemcontainer.h \ + $$ROOTDIR/tests/itemrecyclinglist/listmodel.h + +SOURCES += $$ROOTDIR/tests/itemrecyclinglist/itemrecyclinglist.cpp \ + $$ROOTDIR/tests/itemrecyclinglist/itemrecyclinglistview.cpp \ + $$ROOTDIR/tests/itemrecyclinglist/abstractitemview.cpp \ + $$ROOTDIR/tests/itemrecyclinglist/abstractviewitem.cpp \ + $$ROOTDIR/tests/itemrecyclinglist/recycledlistitem.cpp \ + $$ROOTDIR/tests/itemrecyclinglist/listitemcontainer.cpp \ + $$ROOTDIR/tests/itemrecyclinglist/abstractitemcontainer.cpp \ + $$ROOTDIR/tests/itemrecyclinglist/listmodel.cpp + +INCLUDEPATH += $$ROOTDIR/tests/itemrecyclinglist diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.cpp new file mode 100644 index 0000000..d069a33 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "itemrecyclinglistview.h" + +ItemRecyclingListView::ItemRecyclingListView(QGraphicsWidget * parent) + : AbstractItemView(parent), m_rootIndex() +{ +} + +/*virtual*/ +ItemRecyclingListView::~ItemRecyclingListView() +{ +} +void ItemRecyclingListView::setCurrentRow(const int row) +{ + setCurrentIndex(model()->index(row,0)); +} + +int ItemRecyclingListView::rows() const +{ + if (m_model) + return m_model->rowCount(); + return 0; +} + +/*virtual*/ +void ItemRecyclingListView::rowsInserted(const QModelIndex &parent, int start, int end) +{ + if (parent == m_rootIndex) { + AbstractItemView::rowsInserted(parent, start, end); + } +} + +/*virtual*/ +void ItemRecyclingListView::rowsRemoved(const QModelIndex &parent, int start, int end) +{ + if (parent == m_rootIndex) { + AbstractItemView::rowsRemoved(parent, start, end); + } +} diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.h b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.h new file mode 100644 index 0000000..f52001f --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ITEMRECYCLINGLISTVIEW_H +#define ITEMRECYCLINGLISTVIEW_H + +#include "abstractitemview.h" + +class ItemRecyclingListView : public AbstractItemView +{ +public: + ItemRecyclingListView(QGraphicsWidget * parent = 0); + virtual ~ItemRecyclingListView(); + void setCurrentRow(const int row); + int rows() const; +#if (QT_VERSION >= 0x040600) + virtual bool listItemCaching() const = 0; + virtual void setListItemCaching(bool enabled) = 0; +#endif + +protected: + void rowsInserted(const QModelIndex &parent, int start, int end); + void rowsRemoved(const QModelIndex &parent,int start,int end); + +private: + QModelIndex m_rootIndex; +}; + +#endif // ITEMRECYCLINGLISTVIEW_H diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/label.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/label.cpp new file mode 100644 index 0000000..38ef86f --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/label.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "label.h" + +Label::Label(const QString& text, QGraphicsItem *parent) + : GvbWidget(parent) +{ + m_textItem = new QGraphicsSimpleTextItem(this); + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + setContentsMargins(0, 0, 0, 0); + setText(text); +#if QT_VERSION >= 0x040600 + // This flag was introduced in Qt 4.6. + setFlag(QGraphicsItem::ItemHasNoContents, true); +#endif +} + +Label::~Label() +{ +} + +void Label::setText(const QString& text) +{ + m_textItem->setText(text); + prepareGeometryChange(); +} + +QString Label::text() const +{ + return m_textItem->text(); +} + +void Label::setFont(const QFont font) +{ + m_textItem->setFont(font); +} + +void Label::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + GvbWidget::resizeEvent(event); +} + +QSizeF Label::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + switch (which) + { + case Qt::MinimumSize: + // fall thru + case Qt::PreferredSize: + { + QFontMetricsF fm(m_textItem->font()); + return QSizeF(fm.width(m_textItem->text()), fm.height()); + } + default: + return GvbWidget::sizeHint(which, constraint); + } +} diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/label.h b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/label.h new file mode 100644 index 0000000..dee35b9 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/label.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TEXTITEM_H +#define TEXTITEM_H + +#include "gvbwidget.h" + +class QPainter; +class QStyleOptionGraphicsItem; +class QGraphicsTextItem; + +class Label : public GvbWidget +{ + Q_OBJECT + +public: + + Label(const QString& text, QGraphicsItem *parent = 0); + ~Label(); + +public: + + void setText(const QString& text); + QString text() const; + void setFont(const QFont font); + +private: + void resizeEvent(QGraphicsSceneResizeEvent *event); + QSizeF sizeHint(Qt::SizeHint which, + const QSizeF &constraint = QSizeF()) const; + +private: + Q_DISABLE_COPY(Label) + QGraphicsSimpleTextItem *m_textItem; +}; + +#endif diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.cpp b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.cpp new file mode 100644 index 0000000..937ad9d --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.cpp @@ -0,0 +1,314 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "listitem.h" +#include "theme.h" + +struct ItemData +{ + QHash texts; + QHash fonts; + QHash icons; + QHash iconRotations; + QHash iconSmoothTransformations; + QHash iconOpacityEffets; + QPen borderPen; + QBrush backgroundBrush; + qreal backgroundOpacity; + QSize rounding; +}; +Q_DECLARE_METATYPE(ItemData); + +ListItem::ListItem(QGraphicsWidget *parent) + : GvbWidget(parent), + m_txtlayout(new QGraphicsGridLayout()), + m_layout(new QGraphicsLinearLayout(Qt::Horizontal)), + m_liconlayout(new QGraphicsLinearLayout(Qt::Horizontal)), + m_riconlayout(new QGraphicsLinearLayout(Qt::Horizontal)) + ,m_fonts() + ,m_borderPen(Qt::NoPen) + ,m_backgroundBrush(QBrush()) + ,m_backgroundOpacity(1.0) + ,m_rounding(0.0, 0.0) +{ + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + setContentsMargins(0,4,4,0); + m_layout->setContentsMargins(0,0,0,0); + + m_txtlayout->setContentsMargins(0,8,0,8); + m_liconlayout->setContentsMargins(8,8,8,8); + m_riconlayout->setContentsMargins(0,8,4,8); + + m_layout->insertItem(0, m_liconlayout); + m_layout->insertItem(1, m_txtlayout); + m_layout->insertItem(2, m_riconlayout); + + m_layout->setStretchFactor(m_liconlayout, 1); + m_layout->setStretchFactor(m_txtlayout, 5); + m_layout->setStretchFactor(m_riconlayout, 1); + + setFlag(QGraphicsItem::ItemClipsToShape); + setLayout(m_layout); +} + +ListItem::~ListItem() +{ + if ( !m_liconlayout->parentLayoutItem() ) + delete m_liconlayout; + + if ( !m_riconlayout->parentLayoutItem() ) + delete m_riconlayout; +} + +void ListItem::setIcon( IconItem *iconItem, const IconItemPos iconPos ) +{ + if (iconPos == LeftIcon) { + if (m_liconlayout->count() > 0 && m_liconlayout->itemAt(0)) { + delete m_liconlayout->itemAt(0); + m_liconlayout->addItem( iconItem ); + } + else { + m_liconlayout->addItem( iconItem ); + } + m_liconlayout->itemAt(0)->setMaximumSize(58,58); + } + else if (iconPos == RightIcon) { + if (m_riconlayout->count() > 0 && m_riconlayout->itemAt(0)) { + delete m_riconlayout->itemAt(0); + m_riconlayout->addItem( iconItem ); + } + else { + m_riconlayout->addItem( iconItem ); + } + m_riconlayout->itemAt(0)->setMaximumSize(22,22); + } + m_layout->invalidate(); +} + +IconItem* ListItem::icon( const IconItemPos iconPos ) const +{ + QGraphicsLayoutItem* item = 0; + + if (iconPos == LeftIcon && m_liconlayout->count() > 0) { + item = m_liconlayout->itemAt(0); + } + else if (iconPos == RightIcon && m_riconlayout->count() > 0) { + item = m_riconlayout->itemAt(0); + } + + if (item) { + IconItem* titem = static_cast(item); + return titem; + } + return 0; +} + +QVariant ListItem::data(int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + ItemData data; + + if (text(ListItem::FirstPos).size() > 0) { + data.texts[ListItem::FirstPos] = text(ListItem::FirstPos); + data.fonts[ListItem::FirstPos] = m_fonts[ListItem::FirstPos]; + } + if (text(ListItem::SecondPos).size() > 0) { + data.texts[ListItem::SecondPos] = text(ListItem::SecondPos); + data.fonts[ListItem::SecondPos] = m_fonts[ListItem::SecondPos]; + } + if (text(ListItem::ThirdPos).size() > 0) { + data.texts[ListItem::ThirdPos] = text(ListItem::ThirdPos); + data.fonts[ListItem::ThirdPos] = m_fonts[ListItem::ThirdPos]; + } + if (text(ListItem::LastPos).size() > 0) { + data.texts[ListItem::LastPos] = text(ListItem::LastPos); + data.fonts[ListItem::LastPos] = m_fonts[ListItem::LastPos]; + } + + if (icon(ListItem::LeftIcon)) { + data.icons[ListItem::LeftIcon] = icon(ListItem::LeftIcon)->fileName(); + data.iconRotations[ListItem::LeftIcon] = icon(ListItem::LeftIcon)->rotation(); + data.iconSmoothTransformations[ListItem::LeftIcon] = icon(ListItem::LeftIcon)->isSmoothTransformationEnabled(); +#if (QT_VERSION >= 0x040600) + data.iconOpacityEffets[ListItem::LeftIcon] = icon(ListItem::LeftIcon)->isOpacityEffectEnabled(); +#endif + } + + if (icon(ListItem::RightIcon)) { + data.icons[ListItem::RightIcon] = icon(ListItem::RightIcon)->fileName(); + data.iconRotations[ListItem::RightIcon] = icon(ListItem::RightIcon)->rotation(); + data.iconSmoothTransformations[ListItem::RightIcon] = icon(ListItem::RightIcon)->isSmoothTransformationEnabled(); +#if (QT_VERSION >= 0x040600) + data.iconOpacityEffets[ListItem::RightIcon] = icon(ListItem::RightIcon)->isOpacityEffectEnabled(); +#endif + } + + data.borderPen = m_borderPen; + data.backgroundBrush = m_backgroundBrush; + data.backgroundOpacity = m_backgroundOpacity; + data.rounding = m_rounding; + + QVariant var; + var.setValue(data); + return var; +} + +void ListItem::setData(const QVariant &value, int role) +{ + if (role != Qt::DisplayRole) + return; + + ItemData data = value.value(); + QList textkeys = data.texts.keys(); + + for( int i = 0; i iconkeys = data.icons.keys(); + for( int i = 0; isetFileName(data.icons[iconkeys.at(i)]); + else { + IconItem *iconItem = new IconItem(data.icons[iconkeys.at(i)], this); + setIcon(iconItem, iconkeys.at(i)); + } + } + + if (icon(ListItem::LeftIcon)) { + icon(ListItem::LeftIcon)->setRotation(data.iconRotations[ListItem::LeftIcon]); + icon(ListItem::LeftIcon)->setSmoothTransformationEnabled(data.iconSmoothTransformations[ListItem::LeftIcon]); +#if (QT_VERSION >= 0x040600) + icon(ListItem::LeftIcon)->setOpacityEffectEnabled(data.iconOpacityEffets[ListItem::LeftIcon]); +#endif + } + + if (icon(ListItem::RightIcon)) { + icon(ListItem::RightIcon)->setRotation(data.iconRotations[ListItem::RightIcon]); + icon(ListItem::RightIcon)->setSmoothTransformationEnabled(data.iconSmoothTransformations[ListItem::RightIcon]); +#if (QT_VERSION >= 0x040600) + icon(ListItem::RightIcon)->setOpacityEffectEnabled(data.iconOpacityEffets[ListItem::RightIcon]); +#endif + } + + m_borderPen = data.borderPen; + m_backgroundBrush = data.backgroundBrush; + m_backgroundOpacity = data.backgroundOpacity; + m_rounding = data.rounding; +} + +void ListItem::setText(const QString str, const TextPos position) +{ + QGraphicsLayoutItem * item = 0; + + if (m_txtlayout->rowCount() > position && position >= 0) + item = m_txtlayout->itemAt(position, 0); + + if (!item) { + Label *label = new Label(str,this); + m_txtlayout->addItem(label, position, 0); + if (m_fonts.contains(position)) + label->setFont(m_fonts[position]); + } + else { + Label *titem = static_cast