From eeb5c3dba27b02f6ddeb69257e78b22149ca8487 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 28 Jul 2010 19:20:19 +0200 Subject: QScript: document/obsolete things that does not work since the move to JSC Reviewed-by: Kent Hansen --- src/script/api/qscriptcontext.cpp | 10 ++++++++++ src/script/api/qscriptcontextinfo.cpp | 11 ++--------- src/script/api/qscriptcontextinfo.h | 4 +++- src/script/api/qscriptengine.cpp | 11 ++++------- src/script/api/qscriptengineagent.cpp | 7 ++++--- 5 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp index 3f08e74..1a11100 100644 --- a/src/script/api/qscriptcontext.cpp +++ b/src/script/api/qscriptcontext.cpp @@ -323,6 +323,9 @@ QScriptValue QScriptContext::argumentsObject() const When a function is called as constructor, the thisObject() contains the newly constructed object to be initialized. + + \note This function is only guarenteed to work for a context + corresponding to native functions. */ bool QScriptContext::isCalledAsConstructor() const { @@ -413,6 +416,9 @@ void QScriptContext::setReturnValue(const QScriptValue &result) object provides access to the local variables associated with this context. + \note The activation object might not be available if there is no + active QScriptEngineAgent, as it might be optimized. + \sa argument(), argumentsObject() */ @@ -472,6 +478,10 @@ QScriptValue QScriptContext::activationObject() const activation. If \a activation is not an object, this function does nothing. + + \note For a context corresponding to a JavaScript function, this is only + guarenteed to work if there was an QScriptEngineAgent active on the + engine while the function was evaluated. */ void QScriptContext::setActivationObject(const QScriptValue &activation) { diff --git a/src/script/api/qscriptcontextinfo.cpp b/src/script/api/qscriptcontextinfo.cpp index ebb1770..a90e014 100644 --- a/src/script/api/qscriptcontextinfo.cpp +++ b/src/script/api/qscriptcontextinfo.cpp @@ -53,8 +53,7 @@ QT_BEGIN_NAMESPACE current statement. If the called function is executing Qt Script code, you can obtain - the script location with the functions fileName(), lineNumber() and - columnNumber(). + the script location with the functions fileName() and lineNumber(). You can obtain the starting line number and ending line number of a Qt Script function definition with functionStartLineNumber() and @@ -317,13 +316,7 @@ int QScriptContextInfo::lineNumber() const } /*! - Returns the column number corresponding to the statement being - executed, or -1 if the column number is not available. - - The column number is only available if Qt Script code is being - executed. - - \sa lineNumber(), fileName() + \obsolete */ int QScriptContextInfo::columnNumber() const { diff --git a/src/script/api/qscriptcontextinfo.h b/src/script/api/qscriptcontextinfo.h index d0b3f21..64a1e15 100644 --- a/src/script/api/qscriptcontextinfo.h +++ b/src/script/api/qscriptcontextinfo.h @@ -69,7 +69,9 @@ public: qint64 scriptId() const; QString fileName() const; int lineNumber() const; - int columnNumber() const; +#ifdef QT_DEPRECATED + QT_DEPRECATED int columnNumber() const; +#endif QString functionName() const; FunctionType functionType() const; diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 26673f4..c566f25 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -152,8 +152,7 @@ QT_BEGIN_NAMESPACE evaluation caused an exception by calling hasUncaughtException(). In that case, you can call toString() on the error object to obtain an error message. The current uncaught exception is also available - through uncaughtException(). You can obtain a human-readable - backtrace of the exception with uncaughtExceptionBacktrace(). + through uncaughtException(). Calling clearExceptions() will cause any uncaught exceptions to be cleared. @@ -2800,8 +2799,7 @@ void QScriptEnginePrivate::popContext() The exception state is cleared when evaluate() is called. - \sa uncaughtException(), uncaughtExceptionLineNumber(), - uncaughtExceptionBacktrace() + \sa uncaughtException(), uncaughtExceptionLineNumber() */ bool QScriptEngine::hasUncaughtException() const { @@ -2819,7 +2817,6 @@ bool QScriptEngine::hasUncaughtException() const message. \sa hasUncaughtException(), uncaughtExceptionLineNumber(), - uncaughtExceptionBacktrace() */ QScriptValue QScriptEngine::uncaughtException() const { @@ -2839,7 +2836,7 @@ QScriptValue QScriptEngine::uncaughtException() const Line numbers are 1-based, unless a different base was specified as the second argument to evaluate(). - \sa hasUncaughtException(), uncaughtExceptionBacktrace() + \sa hasUncaughtException() */ int QScriptEngine::uncaughtExceptionLineNumber() const { @@ -2851,7 +2848,7 @@ int QScriptEngine::uncaughtExceptionLineNumber() const /*! Returns a human-readable backtrace of the last uncaught exception. - Each line is of the form \c{()@:}. + It is in the form \c{()@:}. \sa uncaughtException() */ diff --git a/src/script/api/qscriptengineagent.cpp b/src/script/api/qscriptengineagent.cpp index c3d1566..b1f131e 100644 --- a/src/script/api/qscriptengineagent.cpp +++ b/src/script/api/qscriptengineagent.cpp @@ -372,9 +372,8 @@ void QScriptEngineAgent::functionExit(qint64 scriptId, /*! This function is called when the engine is about to execute a new statement in the script identified by \a scriptId. The statement - begins on the line and column specified by \a lineNumber and \a - columnNumber. This event is not generated for native Qt Script - functions. + begins on the line and column specified by \a lineNumber + This event is not generated for native Qt Script functions. Reimplement this function to handle this event. For example, a debugger implementation could reimplement this function to provide @@ -383,6 +382,8 @@ void QScriptEngineAgent::functionExit(qint64 scriptId, The default implementation does nothing. + \note \a columnNumber is undefined + \sa scriptLoad(), functionEntry() */ void QScriptEngineAgent::positionChange(qint64 scriptId, -- cgit v0.12 From 5d68ac574e7edbfd91c53e96c80045effa17a1e9 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 28 Jul 2010 19:21:47 +0200 Subject: QScript: remove JSC::JSLock They are useless and cause warnings in the code. Reviewed-by: Kent Hansen --- src/script/api/qscriptengine.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index c566f25..8560214 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -44,7 +44,6 @@ #include "CodeBlock.h" #include "Error.h" -#include "JSLock.h" #include "Interpreter.h" #include "PrototypeFunction.h" @@ -1002,7 +1001,6 @@ QScriptEnginePrivate::~QScriptEnginePrivate() detachAllRegisteredScriptStrings(); qDeleteAll(m_qobjectData); qDeleteAll(m_typeInfos); - JSC::JSLock lock(false); globalData->heap.destroy(); globalData->deref(); while (freeScriptValues) { @@ -1291,7 +1289,6 @@ bool QScriptEnginePrivate::isCollecting() const void QScriptEnginePrivate::collectGarbage() { - JSC::JSLock lock(false); QScript::APIShim shim(this); globalData->heap.collectAllGarbage(); } @@ -1321,7 +1318,6 @@ JSC::JSValue QScriptEnginePrivate::evaluateHelper(JSC::ExecState *exec, intptr_t bool &compile) { Q_Q(QScriptEngine); - JSC::JSLock lock(false); // ### hmmm QBoolBlocker inEvalBlocker(inEval, true); q->currentContext()->activationObject(); //force the creation of a context for native function; -- cgit v0.12 From 121c5143f1002734ff7aa62785ff14e0e6612aae Mon Sep 17 00:00:00 2001 From: John Brooks Date: Thu, 29 Jul 2010 11:06:03 +0200 Subject: Fix the byte order in QImage::fill for 24bpp formats QImage::fill() was using BGR ordering for 24-bit formats, which is always incorrect as QImage does not support BGR. qrgb888 is the correct 24-bit helper class that does use the proper order. Merge-request: 2440 Reviewed-by: Olivier Goffart --- src/gui/image/qimage.cpp | 2 +- tests/auto/qimage/tst_qimage.cpp | 64 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 30cf758..52ba2b9 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -2010,7 +2010,7 @@ void QImage::fill(uint pixel) 0, 0, d->width, d->height, d->bytes_per_line); return; } else if (d->depth == 24) { - qt_rectfill(reinterpret_cast(d->data), pixel, + qt_rectfill(reinterpret_cast(d->data), pixel, 0, 0, d->width, d->height, d->bytes_per_line); return; } diff --git a/tests/auto/qimage/tst_qimage.cpp b/tests/auto/qimage/tst_qimage.cpp index 1330d96..62deb5ae 100644 --- a/tests/auto/qimage/tst_qimage.cpp +++ b/tests/auto/qimage/tst_qimage.cpp @@ -103,6 +103,9 @@ private slots: void copy(); + void fill_data(); + void fill(); + void setPixel_data(); void setPixel(); @@ -1015,6 +1018,67 @@ void tst_QImage::copy() } } +void tst_QImage::fill_data() +{ + QTest::addColumn("format"); + QTest::addColumn("input"); + QTest::addColumn("expectedResult"); + + QTest::newRow("ARGB32") << int(QImage::Format_ARGB32) << 0x33557799u << 0x33557799u; + QTest::newRow("RGB888") << int(QImage::Format_RGB888) << 0x335577u << 0x335577u; + QTest::newRow("RGB16") << int(QImage::Format_RGB16) << 0x3355u << 0x3355u; + QTest::newRow("Indexed8") << int(QImage::Format_Indexed8) << 0x55u << 0x55u; + QTest::newRow("Mono") << int(QImage::Format_Mono) << 1u << 1u; + QTest::newRow("Mono_LSB") << int(QImage::Format_MonoLSB) << 0u << 0u; +} + +void tst_QImage::fill() +{ + QFETCH(int, format); + QFETCH(uint, input); + QFETCH(uint, expectedResult); + + QImage img(13, 15, (QImage::Format)format); + img.fill(input); + + const int bpp = img.depth(); + for (int y = 0; y < img.height(); ++y) { + uchar *line = img.scanLine(y); + for (int x = 0; x < img.width(); ++x) { + uint value; + switch (bpp) { + case 32: + value = *((uint*)line); + line += 4; + break; + case 24: + value = ((uint)line[0] << 16) | ((uint)line[1] << 8) | line[2]; + line += 3; + break; + case 16: + value = *((quint16*)line); + line += 2; + break; + case 8: + value = *line; + line++; + break; + case 1: + if (format == QImage::Format_Mono) + value = (*line >> (7- (x & 7))) & 1; + else if (format == QImage::Format_MonoLSB) + value = (*line >> (x & 7)) & 1; + + if (x && !(x & 7)) + ++line; + break; + } + + QCOMPARE(value, expectedResult); + } + } +} + void tst_QImage::setPixel_data() { QTest::addColumn("format"); -- cgit v0.12 From ebbab30af417dfbf3df47dec15c0e2f8d6a30fa6 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Thu, 29 Jul 2010 11:09:48 +0200 Subject: Fix the rendering of lines with the X11 paint engine On the X11 paint engine, when rendering lines with float coordinates, the lines were one pixel off if the decimal was > 0.5. This fixes the WebKit bug https://bugs.webkit.org/show_bug.cgi?id=42248 Autotest by Yoann Lopes. Reviewed-by: Simon Hausmann Reviewed-by: Yoann Lopes Reviewed-by: Andreas Kling --- src/gui/painting/qpaintengine_x11.cpp | 22 ++++++------ tests/auto/qpainter/tst_qpainter.cpp | 65 +++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 12 deletions(-) diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 910b2df..e521e01 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -696,11 +696,10 @@ void QX11PaintEngine::drawLines(const QLine *lines, int lineCount) linef = d->matrix.map(QLineF(lines[i])); } if (clipLine(&linef, d->polygonClipper.boundingRect())) { - int x1 = qRound(linef.x1() + aliasedCoordinateDelta); - int y1 = qRound(linef.y1() + aliasedCoordinateDelta); - int x2 = qRound(linef.x2() + aliasedCoordinateDelta); - int y2 = qRound(linef.y2() + aliasedCoordinateDelta); - + int x1 = qFloor(linef.x1() + aliasedCoordinateDelta); + int y1 = qFloor(linef.y1() + aliasedCoordinateDelta); + int x2 = qFloor(linef.x2() + aliasedCoordinateDelta); + int y2 = qFloor(linef.y2() + aliasedCoordinateDelta); XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2); } } @@ -730,11 +729,10 @@ void QX11PaintEngine::drawLines(const QLineF *lines, int lineCount) for (int i = 0; i < lineCount; ++i) { QLineF linef = d->matrix.map(lines[i]); if (clipLine(&linef, d->polygonClipper.boundingRect())) { - int x1 = qRound(linef.x1() + aliasedCoordinateDelta); - int y1 = qRound(linef.y1() + aliasedCoordinateDelta); - int x2 = qRound(linef.x2() + aliasedCoordinateDelta); - int y2 = qRound(linef.y2() + aliasedCoordinateDelta); - + int x1 = qFloor(linef.x1() + aliasedCoordinateDelta); + int y1 = qFloor(linef.y1() + aliasedCoordinateDelta); + int x2 = qFloor(linef.x2() + aliasedCoordinateDelta); + int y2 = qFloor(linef.y2() + aliasedCoordinateDelta); XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2); } } @@ -1690,8 +1688,8 @@ void QX11PaintEnginePrivate::strokePolygon_dev(const QPointF *polygonPoints, int if (clippedCount > 0) { QVarLengthArray xpoints(clippedCount); for (int i = 0; i < clippedCount; ++i) { - xpoints[i].x = qRound(clippedPoints[i].x + aliasedCoordinateDelta); - xpoints[i].y = qRound(clippedPoints[i].y + aliasedCoordinateDelta); + xpoints[i].x = qFloor(clippedPoints[i].x + aliasedCoordinateDelta); + xpoints[i].y = qFloor(clippedPoints[i].y + aliasedCoordinateDelta); } uint numberPoints = qMin(clippedCount, xlibMaxLinePoints); XPoint *pts = xpoints.data(); diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index f358681..2cbb9b2 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -118,10 +118,12 @@ private slots: void drawLine_task190634(); void drawLine_task229459(); void drawLine_task234891(); + void drawHorizontalLineF(); void drawRect_data() { fillData(); } void drawRect(); void drawRect2(); + void drawRectFHorizontalLine(); void fillRect(); void fillRect2(); @@ -251,6 +253,7 @@ private slots: void setPenColorOnPixmap(); void QTBUG5939_attachPainterPrivate(); + void drawHorizontalLine(); private: void fillData(); @@ -1218,6 +1221,26 @@ void tst_QPainter::drawLine_task234891() QCOMPARE(expected, img); } +void tst_QPainter::drawHorizontalLineF() +{ + QPixmap pixmap(100, 3); + pixmap.fill(); + + { + QPainter painter(&pixmap); + painter.drawLine(QLineF(1.5f, 1.5f, 98.5f, 1.5f)); + } + + QImage refImage(100, 3, QImage::Format_ARGB32); + refImage.fill(0xFFFFFFFF); + { + QPainter painter(&refImage); + painter.drawLine(QLineF(1.5f, 1.5f, 98.5f, 1.5f)); + } + + QCOMPARE(pixmap.toImage().convertToFormat(QImage::Format_ARGB32), refImage); +} + void tst_QPainter::drawLine_task216948() { QImage img(1, 10, QImage::Format_ARGB32_Premultiplied); @@ -1302,6 +1325,26 @@ void tst_QPainter::drawRect2() } } +void tst_QPainter::drawRectFHorizontalLine() +{ + QPixmap pixmap(100, 3); + pixmap.fill(); + + { + QPainter painter(&pixmap); + painter.drawRect(QRectF(1.5f, 1.5f, 98.5f, 1.5f)); + } + + QImage refImage(100, 3, QImage::Format_ARGB32); + refImage.fill(0xFFFFFFFF); + { + QPainter painter(&refImage); + painter.drawRect(QRectF(1.5f, 1.5f, 98.5f, 1.5f)); + } + + QCOMPARE(pixmap.toImage().convertToFormat(QImage::Format_ARGB32), refImage); +} + void tst_QPainter::fillRect() { QImage image(100, 100, QImage::Format_ARGB32_Premultiplied); @@ -4522,6 +4565,28 @@ void tst_QPainter::QTBUG5939_attachPainterPrivate() QCOMPARE(widget->deviceTransform, proxy->deviceTransform); } +void tst_QPainter::drawHorizontalLine() +{ + QPixmap pixmap(100, 3); + pixmap.fill(); + + { + QPainter painter(&pixmap); + painter.translate(0.3, 0.3); + painter.drawLine(QLine(1, 1, 99, 1)); + } + + QImage refImage(100, 3, QImage::Format_ARGB32); + refImage.fill(0xFFFFFFFF); + { + QPainter painter(&refImage); + painter.translate(0.3, 0.3); + painter.drawLine(QLine(1, 1, 99, 1)); + } + + QCOMPARE(pixmap.toImage().convertToFormat(QImage::Format_ARGB32), refImage); +} + QTEST_MAIN(tst_QPainter) #include "tst_qpainter.moc" -- cgit v0.12 From d8c6ae24f94133828f4f1b536538e69c5e438202 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 30 Jul 2010 11:10:05 +0200 Subject: Fix tst_QPainter::drawImage_task258776 This test was broken, and change 121c5143f1002734ff7aa62785ff14e0e6612aae exposed it. Why would one check red == blue? --- tests/auto/qpainter/tst_qpainter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index 2cbb9b2..7679545 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -3642,7 +3642,7 @@ void tst_QPainter::drawImage_task258776() painter.end(); QImage expected(33, 33, QImage::Format_RGB32); - expected.fill(0xff0000); + expected.fill(0x0000ff); painter.begin(&expected); painter.drawImage(QRectF(0, 0, 32, 32), src); -- cgit v0.12 From 71166652ef13edb9ca19cf0f30a59112e158c72d Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Mon, 2 Aug 2010 10:25:47 +1000 Subject: Fixed configure on Solaris. Fixes: "test: argument expected" Need whitespace before closing ] . Reviewed-by: Toby Tomkins --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index c61250b..5a5ff09 100755 --- a/configure +++ b/configure @@ -8438,7 +8438,7 @@ for file in .projects .projects.3; do *winmain/winmain.pro) [ "$XPLATFORM_MINGW" = "yes" ] || continue SPEC=$XQMAKESPEC ;; - *s60main/s60main.pro) if [ -z "`echo "$XPLATFORM" | grep "symbian" >/dev/null`"]; then + *s60main/s60main.pro) if [ -z "`echo "$XPLATFORM" | grep "symbian" >/dev/null`" ]; then continue fi;; *examples/activeqt/*) continue ;; -- cgit v0.12 From 0ea02a0576ebbc9cf8dfa9fb6c8137f2eb261422 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Mon, 2 Aug 2010 12:24:57 +1000 Subject: Update QtGui def files Task-number: QTBUG-12333 Reviewed-by: Martin Jones --- src/s60installs/bwins/QtGuiu.def | 3 +++ src/s60installs/eabi/QtGuiu.def | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 53ec18c..7844688 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -12883,4 +12883,7 @@ EXPORTS ?focusScopeItemChange@QGraphicsItemPrivate@@UAEX_N@Z @ 12882 NONAME ; void QGraphicsItemPrivate::focusScopeItemChange(bool) ?setTimeout@QTapAndHoldGesture@@SAXH@Z @ 12883 NONAME ; void QTapAndHoldGesture::setTimeout(int) ?childrenBoundingRectHelper@QGraphicsItemPrivate@@QAEXPAVQTransform@@PAVQRectF@@_N@Z @ 12884 NONAME ; void QGraphicsItemPrivate::childrenBoundingRectHelper(class QTransform *, class QRectF *, bool) + ?zScaleChanged@QGraphicsScale@@IAEXXZ @ 12885 NONAME ; void QGraphicsScale::zScaleChanged(void) + ?xScaleChanged@QGraphicsScale@@IAEXXZ @ 12886 NONAME ; void QGraphicsScale::xScaleChanged(void) + ?yScaleChanged@QGraphicsScale@@IAEXXZ @ 12887 NONAME ; void QGraphicsScale::yScaleChanged(void) diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 559c896..a22b4d9 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -12088,4 +12088,7 @@ EXPORTS _ZN18QTapAndHoldGesture7timeoutEv @ 12087 NONAME _ZN20QGraphicsItemPrivate20focusScopeItemChangeEb @ 12088 NONAME _ZN20QGraphicsItemPrivate26childrenBoundingRectHelperEP10QTransformP6QRectFb @ 12089 NONAME + _ZN14QGraphicsScale13xScaleChangedEv @ 12090 NONAME + _ZN14QGraphicsScale13yScaleChangedEv @ 12091 NONAME + _ZN14QGraphicsScale13zScaleChangedEv @ 12092 NONAME -- cgit v0.12 From 969daadd245153e8bb6c9a89a51565b83832f484 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 2 Aug 2010 15:36:35 +1000 Subject: Correctly apply PropertyChanges when entering an extended state directly from the base state. Make sure qmlExecuteDeferred is called on the state being extended. Task-number: QTBUG-12559 --- src/declarative/util/qdeclarativestate.cpp | 4 +++- .../qdeclarativestates/data/extendsBug.qml | 26 ++++++++++++++++++++++ .../qdeclarativestates/tst_qdeclarativestates.cpp | 16 +++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 tests/auto/declarative/qdeclarativestates/data/extendsBug.qml diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp index 9f4cc39..f7dae10 100644 --- a/src/declarative/util/qdeclarativestate.cpp +++ b/src/declarative/util/qdeclarativestate.cpp @@ -358,8 +358,10 @@ QDeclarativeStatePrivate::generateActionList(QDeclarativeStateGroup *group) cons if (!extends.isEmpty()) { QList states = group->states(); for (int ii = 0; ii < states.count(); ++ii) - if (states.at(ii)->name() == extends) + if (states.at(ii)->name() == extends) { + qmlExecuteDeferred(states.at(ii)); applyList = static_cast(states.at(ii)->d_func())->generateActionList(group); + } } foreach(QDeclarativeStateOperation *op, operations) diff --git a/tests/auto/declarative/qdeclarativestates/data/extendsBug.qml b/tests/auto/declarative/qdeclarativestates/data/extendsBug.qml new file mode 100644 index 0000000..a3c4827 --- /dev/null +++ b/tests/auto/declarative/qdeclarativestates/data/extendsBug.qml @@ -0,0 +1,26 @@ +import Qt 4.7 + +Rectangle { + width: 200 + height: 200 + + Rectangle { + id: rect + objectName: "greenRect" + width: 100 + height: 100 + color: "green" + } + + states:[ + State { + name: "a" + PropertyChanges { target: rect; x: 100 } + }, + State { + name: "b" + extend:"a" + PropertyChanges { target: rect; y: 100 } + } + ] +} diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp index 3b6a420..6ae2759 100644 --- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp +++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp @@ -139,6 +139,7 @@ private slots: void urlResolution(); void unnamedWhen(); void returnToBase(); + void extendsBug(); }; void tst_qdeclarativestates::initTestCase() @@ -1186,6 +1187,21 @@ void tst_qdeclarativestates::returnToBase() QCOMPARE(rect->property("stateString").toString(), QLatin1String("originalState")); } +//QTBUG-12559 +void tst_qdeclarativestates::extendsBug() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, SRCDIR "/data/extendsBug.qml"); + QDeclarativeRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect); + QDeclarativeRectangle *greenRect = rect->findChild("greenRect"); + + rectPrivate->setState("b"); + QCOMPARE(greenRect->x(), qreal(100)); + QCOMPARE(greenRect->y(), qreal(100)); +} QTEST_MAIN(tst_qdeclarativestates) -- cgit v0.12 From 2501c66e3795040d72a1922499294a686832e7a2 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 2 Aug 2010 15:45:21 +1000 Subject: Make sure ListView.nextSection attached property is set for the first item Task-number: QTBUG-12470 Reviewed-by: Bea Lam --- src/declarative/graphicsitems/qdeclarativelistview.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index b0a11b9..256948a 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -575,9 +575,11 @@ FxListItem *QDeclarativeListViewPrivate::createItem(int modelIndex) listItem->attached->m_prevSection = item->attached->section(); else listItem->attached->m_prevSection = sectionAt(modelIndex-1); + } + if (modelIndex < model->count()-1) { if (FxListItem *item = visibleItem(modelIndex+1)) listItem->attached->m_nextSection = item->attached->section(); - else if (modelIndex < model->count()-1) + else listItem->attached->m_nextSection = sectionAt(modelIndex+1); } } -- cgit v0.12 From 3daee8e915f9845fb104e57c7f35fdb2f7251df5 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Mon, 2 Aug 2010 16:22:43 +1000 Subject: State doc fixes, improvements Task-number: QTBUG-12570 --- doc/src/declarative/qdeclarativestates.qdoc | 183 +++++++++++++++++++++++----- doc/src/snippets/declarative/state-when.qml | 55 +++++++++ doc/src/snippets/declarative/state.qml | 18 ++- doc/src/snippets/declarative/states.qml | 38 ++---- src/declarative/util/qdeclarativestate.cpp | 15 +-- 5 files changed, 227 insertions(+), 82 deletions(-) create mode 100644 doc/src/snippets/declarative/state-when.qml diff --git a/doc/src/declarative/qdeclarativestates.qdoc b/doc/src/declarative/qdeclarativestates.qdoc index e7607c6..0b91756 100644 --- a/doc/src/declarative/qdeclarativestates.qdoc +++ b/doc/src/declarative/qdeclarativestates.qdoc @@ -32,57 +32,174 @@ \section1 Overview -QML states typically describe user interface configurations, including: +User interfaces are designed to present different interface configurations in +different scenarios, or to modify their appearances in response to user +interaction. Often, there are a set of changes that are made concurrently, such +that the interface could be seen to be internally changing from one \e state to +another. + +This applies generally to interface elements regardless of their complexity. +A photo viewer may initially present images in a grid, and when an image is +clicked, change to a "detailed" state where the individual image is expanded +and the interface is changed to present new options for image editing. On the +other end of the scale, when a simple button is pressed, it may change to a +"pressed" state in which its color and position is modified to give a pressed +appearance. + +In QML, any object can change between different \e states to apply sets of +changes that modify the properties of relevant items. Each \e state could +present a different configuration that could, for example: + \list -\o What UI elements are present -\o The properties of those elements (including how they behave) -\o What actions are available +\o Show some UI elements and hide others +\o Present different available actions to the user +\o Start, stop or pause animations +\o Execute some script required in the new state +\o Change a property value for a particular item +\o Show a different view or "screen" \endlist -A state can also be thought of as a set of batched changes from a default configuration. +Changes between states can be animated using \l {Transitions}{transitions}, as +discussed further below. -Examples of states in modern UI: -\list -\o An Address Book application with a 'View Contact' state and an 'Edit Contact' State. In the first state the contact information presented is read-only (using labels), and in the second it is editable (using editors). -\o A button with a pressed and unpressed state. When pressed the text moves slightly down and to the right, and the button has a slightly darker appearance. -\endlist +All \l {Item}-based objects have a \e {default state}, and can specify additional +states by adding new \l State objects to the item's \l {Item::}{states} +property. Each state has a \e name that is unique for all states within that +item; the default state's name is an empty string. To change the current state +of an item, set the \l {Item::}{state} property to the name of the state. + +Non-Item objects can use states through the StateGroup element. -\section1 States in QML -In QML: +\section1 Creating states + +To create a state, add a \l State object to the item's \l {Item::}{states} property, +which holds a list of states for that item. + +Following is an example. Here, the \l Rectangle is initially placed in the +default (0, 0) position. It has defined an additional state named "moved", in +which a PropertyChanges object repositions the rectangle to (50, 50). Clicking +within the MouseArea changes the state to the "moved" state, thus moving the \l +Rectangle. + +\snippet doc/src/snippets/declarative/states.qml 0 + +A \l State item defines all the changes to be made in the new state. You +could specify additional properties to be changed, or create additional +PropertyChanges for other objects. (Note that a \l State can modify the +properties of other objects, not just the object that owns the state.) + +For example: + +\qml +State { + name: "moved" + PropertyChanges { target: myRect; x: 50; y: 50; color: "blue" } + PropertyChanges { target: someOtherItem; width: 1000 } +} +\endqml + +A \l State is not limited to performing modifications on property values. It +can also: + \list -\o Any object can use states. -\o There is a default state. The default state can be explicitly set. -\o A state can affect the properties of other objects, not just the object owning the state (and not just that object's children). +\o Run some script using StateChangeScript +\o Override an existing signal handler for an object using PropertyChanges +\o Re-parent an \l Item using ParentChanges +\o Modify anchor values using AnchorChanges \endlist -To define a state for an item, add a \l State element to the \l{Item::states}{states} property. To -change the current state of an \l Item, set the \l{Item::state}{state} property to the name -of the required state. +The \l {declarative/animation/states}{States and Transitions example} +demonstrates how to declare a basic set of states and apply animated +transitions between them. -Here is an example of using states. In the default state \c myRect is positioned at 0,0. In the 'moved' state it is positioned at 50,50. Clicking within the mouse area changes the state from the default state to the 'moved' state, thus moving the rectangle. -\snippet doc/src/snippets/declarative/states.qml 0 -\snippet doc/src/snippets/declarative/states.qml 1 +\section1 The default state -State changes can be animated using \l{state-transitions}{Transitions}. +Of course, the \l Rectangle in the example above could have simply been moved +by setting its position to (50, 50) in the mouse area's \c onClicked handler. +However, aside from enabling batched property changes, the use of states allows +an item to revert to its \e {default state}, which contains all of the items' +initial property values before they were modified in a state change. -For example, adding this code to the above \c Item element animates the transition to the "moved" state: +The default state is specified by an empty string. If the MouseArea in the +above example was changed to this: -\snippet doc/src/snippets/declarative/states.qml transitions +\qml +MouseArea { + anchors.fill: parent + onClicked: myRect.state == 'moved' ? myRect.state = "" : myRect.state = 'moved'; +} +\endqml -See \l{state-transitions}{Transitions} for more information. +This would toggle the \l Rectangle's state between the \e moved and \e default +states when clicked. The properties can be reverted to their initial +values without requiring the definition of another \l State that defines these +value changes. -Other things you can do in a state change: -\list -\o Override signal handlers with PropertyChanges -\o Change an item's visual parent with ParentChange -\o Change an item's anchors with AnchorChanges -\o Run some script with StateChangeScript -\endlist +\section1 The "when" property + +The \l {State::}{when} property is useful for specifying when a state should be +applied. This can be set to an expression that evaluates to \c true when an +item should change to a particular state. + +If the above example was changed to this: + +\qml +Rectangle { + ... + + MouseArea { + id: mouseArea + anchors.fill: parent + } + + states: State { + name: "moved"; when: mouseArea.pressed + ... + } +\endqml + +The \l Rectangle would automatically change to the \e moved state when the +mouse is pressed, and revert to the default state when it is released. This is +simpler (and a better, more declarative method) than creating \c onPressed +and \c onReleased handlers in the MouseArea to set the current state. + + +\section1 Animating state changes + + +State changes can be easily animated through \l {Transitions}{transitions}. A +\l Transition defines the animations that should be applied when an item +changes from one state to another. + +If the above example was modified to include the following \l Transition, the +movement of the \l Rectangle would be animated: + +\qml +Rectangle { + ... + + MouseArea { ... } + + states: [ + ... + ] + + transitions: [ + Transition { + NumberAnimation { properties: "x,y"; duration: 500 } + } + ] + } +\endqml + +This \l Transition defines that if any \c x or \c y properties have changed +during a state change within this item, their values should be animated over 500 +millliseconds. -The \l {declarative/animation/states}{States and Transitions example} demonstrates how to declare a basic set of states and then apply animated transitions between them. +See the \l Transitions documentation for more information. */ diff --git a/doc/src/snippets/declarative/state-when.qml b/doc/src/snippets/declarative/state-when.qml new file mode 100644 index 0000000..6d3bb75 --- /dev/null +++ b/doc/src/snippets/declarative/state-when.qml @@ -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 QtDeclarative module 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$ +** +****************************************************************************/ +import Qt 4.7 +//![0] +Rectangle { + id: myRect + width: 100; height: 100 + color: "red" + + MouseArea { id: mouseArea; anchors.fill: parent } + + states: State { + name: "hidden"; when: mouseArea.pressed + PropertyChanges { target: myRect; opacity: 0 } + } +} +//![0] diff --git a/doc/src/snippets/declarative/state.qml b/doc/src/snippets/declarative/state.qml index af6b103..ce2653b 100644 --- a/doc/src/snippets/declarative/state.qml +++ b/doc/src/snippets/declarative/state.qml @@ -44,13 +44,19 @@ import Qt 4.7 Rectangle { id: myRect width: 100; height: 100 - color: "red" + color: "black" - MouseArea { id: mouseArea; anchors.fill: parent } - - states: State { - name: "hidden"; when: mouseArea.pressed - PropertyChanges { target: myRect; opacity: 0 } + MouseArea { + id: mouseArea + anchors.fill: parent + onClicked: myRect.state == 'clicked' ? myRect.state = "" : myRect.state = 'clicked'; } + + states: [ + State { + name: "clicked" + PropertyChanges { target: myRect; color: "red" } + } + ] } //![0] diff --git a/doc/src/snippets/declarative/states.qml b/doc/src/snippets/declarative/states.qml index c3b1796..127e3a7 100644 --- a/doc/src/snippets/declarative/states.qml +++ b/doc/src/snippets/declarative/states.qml @@ -40,42 +40,22 @@ ****************************************************************************/ //![0] import Qt 4.7 - -Item { - id: myItem + +Rectangle { + id: myRect width: 200; height: 200 + color: "red" - Rectangle { - id: myRect - width: 100; height: 100 - color: "red" + MouseArea { + anchors.fill: parent + onClicked: myRect.state = 'moved' } states: [ State { name: "moved" - PropertyChanges { - target: myRect - x: 50 - y: 50 - } + PropertyChanges { target: myRect; x: 50; y: 50 } } ] - - MouseArea { - anchors.fill: parent - onClicked: myItem.state = 'moved' - } -//![0] - -//![transitions] -transitions: [ - Transition { - NumberAnimation { properties: "x,y"; duration: 500 } - } -] -//![transitions] - -//![1] } -//![1] +//![0] diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp index f7dae10..0d43d21 100644 --- a/src/declarative/util/qdeclarativestate.cpp +++ b/src/declarative/util/qdeclarativestate.cpp @@ -229,20 +229,7 @@ bool QDeclarativeState::isWhenKnown() const be applied. For example, the following \l Rectangle changes in and out of the "hidden" state when the \l MouseArea is pressed: - \qml - Rectangle { - id: myRect - width: 100; height: 100 - color: "red" - - MouseArea { id: mouseArea; anchors.fill: parent } - - states: State { - name: "hidden"; when: mouseArea.pressed - PropertyChanges { target: myRect; opacity: 0 } - } - } - \endqml + \snippet doc/src/snippets/declarative/state-when.qml 0 If multiple states in a group have \c when clauses that evaluate to \c true at the same time, the first matching state will be applied. For example, in the following snippet -- cgit v0.12 From a07bae9717168c9605662e117132e16b5f2b2f9d Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 2 Aug 2010 16:44:33 +1000 Subject: Ensure currentItem is released when the delegate changes Otherwise a new delegate isn't created for the currentItem. GridView didn't release any item. It is now equivalent to LsitView. Task-number: QTBUG-12548 Reviewed-by: Bea Lam --- src/declarative/graphicsitems/qdeclarativegridview.cpp | 5 +++++ src/declarative/graphicsitems/qdeclarativelistview.cpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index f02ef6b..68a4c64 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1278,6 +1278,11 @@ void QDeclarativeGridView::setDelegate(QDeclarativeComponent *delegate) if (QDeclarativeVisualDataModel *dataModel = qobject_cast(d->model)) { dataModel->setDelegate(delegate); if (isComponentComplete()) { + for (int i = 0; i < d->visibleItems.count(); ++i) + d->releaseItem(d->visibleItems.at(i)); + d->visibleItems.clear(); + d->releaseItem(d->currentItem); + d->currentItem = 0; refill(); d->moveReason = QDeclarativeGridViewPrivate::SetIndex; d->updateCurrent(d->currentIndex); diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 256948a..82b3e1c 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -1620,6 +1620,8 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) for (int i = 0; i < d->visibleItems.count(); ++i) d->releaseItem(d->visibleItems.at(i)); d->visibleItems.clear(); + d->releaseItem(d->currentItem); + d->currentItem = 0; refill(); d->moveReason = QDeclarativeListViewPrivate::SetIndex; d->updateCurrent(d->currentIndex); -- cgit v0.12 From 43f37074391b338b250883dfeb4a16844ca759fd Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 2 Aug 2010 09:36:00 +0200 Subject: Fix crash when setting font decorations on text drawn with QStaticText Qt has a run-time assert for implementing drawPolygon() in any subclass of QPaintEngine, which will be hit if set font decorations on the font used by QStaticText. Since we don't care about line decorations or any other shapes drawn in the QTextLayout, we simply leave the implementation empty. Reviewed-by: Gunnar --- src/gui/text/qstatictext.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index f6daed8..7396bcd 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -472,7 +472,12 @@ namespace { memcpy(charsDestination, ti.chars, sizeof(QChar) * currentItem.numChars); m_items.append(currentItem); - } + } + + virtual void drawPolygon(const QPointF *, int , PolygonDrawMode ) + { + /* intentionally empty */ + } virtual bool begin(QPaintDevice *) { return true; } virtual bool end() { return true; } -- cgit v0.12 From f127fadc833f7b64977877879787d96586d0a501 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 2 Aug 2010 11:11:52 +0200 Subject: Revert "Fix the byte order in QImage::fill for 24bpp formats" This change the behavior. (as it break tests like drawImage_task258776 and tst_QPainter::drawhelper_blend_color) The bug it fixes is not considered importent enough This reverts commit 121c5143f1002734ff7aa62785ff14e0e6612aae and d8c6ae24f94133828f4f1b536538e69c5e438202 --- src/gui/image/qimage.cpp | 2 +- tests/auto/qimage/tst_qimage.cpp | 64 ------------------------------------ tests/auto/qpainter/tst_qpainter.cpp | 2 +- 3 files changed, 2 insertions(+), 66 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 52ba2b9..30cf758 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -2010,7 +2010,7 @@ void QImage::fill(uint pixel) 0, 0, d->width, d->height, d->bytes_per_line); return; } else if (d->depth == 24) { - qt_rectfill(reinterpret_cast(d->data), pixel, + qt_rectfill(reinterpret_cast(d->data), pixel, 0, 0, d->width, d->height, d->bytes_per_line); return; } diff --git a/tests/auto/qimage/tst_qimage.cpp b/tests/auto/qimage/tst_qimage.cpp index 62deb5ae..1330d96 100644 --- a/tests/auto/qimage/tst_qimage.cpp +++ b/tests/auto/qimage/tst_qimage.cpp @@ -103,9 +103,6 @@ private slots: void copy(); - void fill_data(); - void fill(); - void setPixel_data(); void setPixel(); @@ -1018,67 +1015,6 @@ void tst_QImage::copy() } } -void tst_QImage::fill_data() -{ - QTest::addColumn("format"); - QTest::addColumn("input"); - QTest::addColumn("expectedResult"); - - QTest::newRow("ARGB32") << int(QImage::Format_ARGB32) << 0x33557799u << 0x33557799u; - QTest::newRow("RGB888") << int(QImage::Format_RGB888) << 0x335577u << 0x335577u; - QTest::newRow("RGB16") << int(QImage::Format_RGB16) << 0x3355u << 0x3355u; - QTest::newRow("Indexed8") << int(QImage::Format_Indexed8) << 0x55u << 0x55u; - QTest::newRow("Mono") << int(QImage::Format_Mono) << 1u << 1u; - QTest::newRow("Mono_LSB") << int(QImage::Format_MonoLSB) << 0u << 0u; -} - -void tst_QImage::fill() -{ - QFETCH(int, format); - QFETCH(uint, input); - QFETCH(uint, expectedResult); - - QImage img(13, 15, (QImage::Format)format); - img.fill(input); - - const int bpp = img.depth(); - for (int y = 0; y < img.height(); ++y) { - uchar *line = img.scanLine(y); - for (int x = 0; x < img.width(); ++x) { - uint value; - switch (bpp) { - case 32: - value = *((uint*)line); - line += 4; - break; - case 24: - value = ((uint)line[0] << 16) | ((uint)line[1] << 8) | line[2]; - line += 3; - break; - case 16: - value = *((quint16*)line); - line += 2; - break; - case 8: - value = *line; - line++; - break; - case 1: - if (format == QImage::Format_Mono) - value = (*line >> (7- (x & 7))) & 1; - else if (format == QImage::Format_MonoLSB) - value = (*line >> (x & 7)) & 1; - - if (x && !(x & 7)) - ++line; - break; - } - - QCOMPARE(value, expectedResult); - } - } -} - void tst_QImage::setPixel_data() { QTest::addColumn("format"); diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index 7679545..2cbb9b2 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -3642,7 +3642,7 @@ void tst_QPainter::drawImage_task258776() painter.end(); QImage expected(33, 33, QImage::Format_RGB32); - expected.fill(0x0000ff); + expected.fill(0xff0000); painter.begin(&expected); painter.drawImage(QRectF(0, 0, 32, 32), src); -- cgit v0.12 From fbe41c1e43d1f4fa6a8e0edda5688594801b8be3 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 28 Jul 2010 14:05:52 +0100 Subject: Added support to Phonon MMF backend for playback of Qt resource files The backend accesses the resource file path via MediaSource::url(). A small patch to Phonon was required to enable this, because by default, Phonon passes a QIODevice, rather than the resource file path, to the backend. The backend uses this path to create a QResource object, through which the memory buffer into which the resource file has been read can be accessed. This buffer is wrapped in a Symbian 8-bit descriptor and passed to the OpenDesL() function of the appropriate MMF client utility API. Playback only works for certain file formats, as the Symbian MIME type recognizer does not always work. For example, playback of an audio WAV resource file works, while playback of an MP3 resource file does not. Task-number: QTBUG-6562 Reviewed-by: Justin McPherson --- src/3rdparty/phonon/mmf/abstractmediaplayer.cpp | 28 +++++++-- src/3rdparty/phonon/mmf/abstractmediaplayer.h | 6 +- src/3rdparty/phonon/mmf/abstractplayer.h | 4 +- src/3rdparty/phonon/mmf/abstractvideoplayer.cpp | 6 ++ src/3rdparty/phonon/mmf/abstractvideoplayer.h | 1 + src/3rdparty/phonon/mmf/audioplayer.cpp | 6 ++ src/3rdparty/phonon/mmf/audioplayer.h | 1 + src/3rdparty/phonon/mmf/dummyplayer.cpp | 2 +- src/3rdparty/phonon/mmf/dummyplayer.h | 2 +- src/3rdparty/phonon/mmf/mediaobject.cpp | 75 +++++++++++++++++++++++-- src/3rdparty/phonon/mmf/mediaobject.h | 11 +++- src/3rdparty/phonon/phonon/mediasource.cpp | 1 + 12 files changed, 123 insertions(+), 20 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index be2a568..3702560 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -16,6 +16,7 @@ along with this library. If not, see . */ +#include #include #include "abstractmediaplayer.h" @@ -216,9 +217,10 @@ void MMF::AbstractMediaPlayer::doSetTickInterval(qint32 interval) TRACE_EXIT_0(); } -void MMF::AbstractMediaPlayer::open(const MediaSource &source, RFile& file) +void MMF::AbstractMediaPlayer::open() { - TRACE_CONTEXT(AbstractMediaPlayer::setFileSource, EAudioApi); + TRACE_CONTEXT(AbstractMediaPlayer::open, EAudioApi); + const MediaSource source = m_parent->source(); TRACE_ENTRY("state %d source.type %d", privateState(), source.type()); close(); @@ -229,7 +231,9 @@ void MMF::AbstractMediaPlayer::open(const MediaSource &source, RFile& file) switch (source.type()) { case MediaSource::LocalFile: { - symbianErr = openFile(file); + RFile *const file = m_parent->file(); + Q_ASSERT(file); + symbianErr = openFile(*file); if (KErrNone != symbianErr) errorMessage = tr("Error opening file"); break; @@ -237,9 +241,10 @@ void MMF::AbstractMediaPlayer::open(const MediaSource &source, RFile& file) case MediaSource::Url: { const QUrl url(source.url()); - if (url.scheme() == QLatin1String("file")) { - symbianErr = openFile(file); + RFile *const file = m_parent->file(); + Q_ASSERT(file); + symbianErr = openFile(*file); if (KErrNone != symbianErr) errorMessage = tr("Error opening file"); } else { @@ -251,6 +256,19 @@ void MMF::AbstractMediaPlayer::open(const MediaSource &source, RFile& file) break; } + case MediaSource::Stream: { + QResource *const resource = m_parent->resource(); + if (resource) { + m_buffer.Set(resource->data(), resource->size()); + symbianErr = openDescriptor(m_buffer); + if (KErrNone != symbianErr) + errorMessage = tr("Error opening resource"); + } else { + errorMessage = tr("Error opening source: resource not opened"); + } + break; + } + // Other source types are handled in MediaObject::createPlayer // Protection against adding new media types and forgetting to update this switch diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.h b/src/3rdparty/phonon/mmf/abstractmediaplayer.h index 7d28caf..e795ecb 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.h +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h @@ -47,7 +47,7 @@ protected: AbstractMediaPlayer(MediaObject *parent, const AbstractPlayer *player); public: - virtual void open(const Phonon::MediaSource&, RFile&); + virtual void open(); // MediaObjectInterface virtual void play(); @@ -70,6 +70,7 @@ protected: virtual int setDeviceVolume(int mmfVolume) = 0; virtual int openFile(RFile& file) = 0; virtual int openUrl(const QString& url) = 0; + virtual int openDescriptor(const TDesC8 &des) = 0; virtual int bufferStatus() const = 0; void updateMetaData(); @@ -123,6 +124,9 @@ private: bool m_prefinishMarkSent; bool m_aboutToFinishSent; + // Used for playback of resource files + TPtrC8 m_buffer; + QMultiMap m_metaData; }; diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h index 30d5243..dd98c7c 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.h +++ b/src/3rdparty/phonon/mmf/abstractplayer.h @@ -26,8 +26,6 @@ along with this library. If not, see . #include "abstractvideooutput.h" -class RFile; - QT_BEGIN_NAMESPACE namespace Phonon @@ -54,7 +52,7 @@ class AbstractPlayer : public QObject public: AbstractPlayer(const AbstractPlayer *player); - virtual void open(const Phonon::MediaSource&, RFile&) = 0; + virtual void open() = 0; virtual void close() = 0; // MediaObjectInterface (implemented) diff --git a/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp index 9ea4d18..fb20bea 100644 --- a/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp @@ -144,6 +144,12 @@ int MMF::AbstractVideoPlayer::openUrl(const QString &url) return err; } +int MMF::AbstractVideoPlayer::openDescriptor(const TDesC8 &des) +{ + TRAPD(err, m_player->OpenDesL(des)); + return err; +} + int MMF::AbstractVideoPlayer::bufferStatus() const { int result = 0; diff --git a/src/3rdparty/phonon/mmf/abstractvideoplayer.h b/src/3rdparty/phonon/mmf/abstractvideoplayer.h index d854793..3ff3c75 100644 --- a/src/3rdparty/phonon/mmf/abstractvideoplayer.h +++ b/src/3rdparty/phonon/mmf/abstractvideoplayer.h @@ -66,6 +66,7 @@ public: virtual int setDeviceVolume(int mmfVolume); virtual int openFile(RFile &file); virtual int openUrl(const QString &url); + virtual int openDescriptor(const TDesC8 &des); virtual int bufferStatus() const; virtual void close(); diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp index f49e898..7c8b9bd 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.cpp +++ b/src/3rdparty/phonon/mmf/audioplayer.cpp @@ -137,6 +137,12 @@ int MMF::AudioPlayer::openUrl(const QString& /*url*/) return 0; } +int MMF::AudioPlayer::openDescriptor(const TDesC8 &des) +{ + TRAPD(err, m_player->OpenDesL(des)); + return err; +} + int MMF::AudioPlayer::bufferStatus() const { int result = 0; diff --git a/src/3rdparty/phonon/mmf/audioplayer.h b/src/3rdparty/phonon/mmf/audioplayer.h index 0eb8bb7..e43cadd 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.h +++ b/src/3rdparty/phonon/mmf/audioplayer.h @@ -67,6 +67,7 @@ typedef CMdaAudioPlayerUtility NativePlayer; virtual int setDeviceVolume(int mmfVolume); virtual int openFile(RFile& file); virtual int openUrl(const QString& url); + virtual int openDescriptor(const TDesC8 &des); virtual int bufferStatus() const; virtual void close(); diff --git a/src/3rdparty/phonon/mmf/dummyplayer.cpp b/src/3rdparty/phonon/mmf/dummyplayer.cpp index d39ef76..ba75b02 100644 --- a/src/3rdparty/phonon/mmf/dummyplayer.cpp +++ b/src/3rdparty/phonon/mmf/dummyplayer.cpp @@ -92,7 +92,7 @@ qint64 MMF::DummyPlayer::totalTime() const return 0; } -void MMF::DummyPlayer::open(const Phonon::MediaSource &, RFile &) +void MMF::DummyPlayer::open() { } diff --git a/src/3rdparty/phonon/mmf/dummyplayer.h b/src/3rdparty/phonon/mmf/dummyplayer.h index 9d45696..5b00411 100644 --- a/src/3rdparty/phonon/mmf/dummyplayer.h +++ b/src/3rdparty/phonon/mmf/dummyplayer.h @@ -57,7 +57,7 @@ public: virtual qint64 totalTime() const; // AbstractPlayer - virtual void open(const Phonon::MediaSource&, RFile&); + virtual void open(); virtual void close(); virtual void doSetTickInterval(qint32 interval); }; diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index d264377..b476535 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -34,6 +34,7 @@ along with this library. If not, see . #include "mediaobject.h" #include +#include #include QT_BEGIN_NAMESPACE @@ -52,6 +53,8 @@ using namespace Phonon::MMF; MMF::MediaObject::MediaObject(QObject *parent) : MMF::MediaNode::MediaNode(parent) , m_recognizerOpened(false) , m_nextSourceSet(false) + , m_file(0) + , m_resource(0) { m_player.reset(new DummyPlayer()); @@ -68,7 +71,12 @@ MMF::MediaObject::~MediaObject() TRACE_CONTEXT(MediaObject::~MediaObject, EAudioApi); TRACE_ENTRY_0(); - m_file.Close(); + delete m_resource; + + if (m_file) + m_file->Close(); + delete m_file; + m_fileServer.Close(); m_recognizer.Close(); @@ -122,12 +130,13 @@ MMF::MediaType MMF::MediaObject::fileMediaType const QHBufC fileNameSymbian(QDir::toNativeSeparators(fileName)); - m_file.Close(); - TInt err = m_file.Open(m_fileServer, *fileNameSymbian, EFileRead | EFileShareReadersOnly); + Q_ASSERT(!m_file); + m_file = new RFile; + TInt err = m_file->Open(m_fileServer, *fileNameSymbian, EFileRead | EFileShareReadersOnly); if (KErrNone == err) { TDataRecognitionResult recognizerResult; - err = m_recognizer.RecognizeData(m_file, recognizerResult); + err = m_recognizer.RecognizeData(*m_file, recognizerResult); if (KErrNone == err) { const TPtrC mimeType = recognizerResult.iDataType.Des(); result = Utils::mimeTypeToMediaType(mimeType); @@ -142,6 +151,23 @@ MMF::MediaType MMF::MediaObject::fileMediaType return result; } +MMF::MediaType MMF::MediaObject::bufferMediaType(const uchar *data, qint64 size) +{ + TRACE_CONTEXT(MediaObject::bufferMediaType, EAudioInternal); + MediaType result = MediaTypeUnknown; + if (openRecognizer()) { + TDataRecognitionResult recognizerResult; + const TPtrC8 des(data, size); + const TInt err = m_recognizer.RecognizeData(des, recognizerResult); + if (KErrNone == err) { + const TPtrC mimeType = recognizerResult.iDataType.Des(); + result = Utils::mimeTypeToMediaType(mimeType); + } else { + TRACE("RApaLsSession::RecognizeData error %d", err); + } + } + return result; +} //----------------------------------------------------------------------------- // MediaObjectInterface @@ -228,9 +254,17 @@ void MMF::MediaObject::setSource(const MediaSource &source) void MMF::MediaObject::switchToSource(const MediaSource &source) { + if (m_file) + m_file->Close(); + delete m_file; + m_file = 0; + + delete m_resource; + m_resource = 0; + createPlayer(source); m_source = source; - m_player->open(m_source, m_file); + m_player->open(); emit currentSourceChanged(m_source); } @@ -272,10 +306,29 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) case MediaSource::Invalid: case MediaSource::Disc: - case MediaSource::Stream: errorMessage = tr("Error opening source: type not supported"); break; + case MediaSource::Stream: + { + const QString fileName = source.url().toLocalFile(); + if (fileName.startsWith(QLatin1String(":/")) || fileName.startsWith(QLatin1String("qrc://"))) { + Q_ASSERT(!m_resource); + m_resource = new QResource(fileName); + if (m_resource->isValid()) { + if (m_resource->isCompressed()) + errorMessage = tr("Error opening source: resource is compressed"); + else + mediaType = bufferMediaType(m_resource->data(), m_resource->size()); + } else { + errorMessage = tr("Error opening source: resource not valid"); + } + } else { + errorMessage = tr("Error opening source: type not supported"); + } + } + break; + case MediaSource::Empty: TRACE_0("Empty media source"); break; @@ -374,6 +427,16 @@ void MMF::MediaObject::volumeChanged(qreal volume) m_player->volumeChanged(volume); } +RFile* MMF::MediaObject::file() const +{ + return m_file; +} + +QResource* MMF::MediaObject::resource() const +{ + return m_resource; +} + //----------------------------------------------------------------------------- // MediaNode //----------------------------------------------------------------------------- diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h index f15eb21..5399e27 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.h +++ b/src/3rdparty/phonon/mmf/mediaobject.h @@ -33,6 +33,8 @@ along with this library. If not, see . QT_BEGIN_NAMESPACE +class QResource; + namespace Phonon { namespace MMF @@ -87,6 +89,9 @@ public: void setVideoOutput(AbstractVideoOutput* videoOutput); + RFile* file() const; + QResource* resource() const; + public Q_SLOTS: void volumeChanged(qreal volume); void switchToNextSource(); @@ -117,6 +122,7 @@ private: // Audio / video media type recognition MediaType fileMediaType(const QString& fileName); + MediaType bufferMediaType(const uchar *data, qint64 size); // TODO: urlMediaType function static qint64 toMilliSeconds(const TTimeIntervalMicroSeconds &); @@ -132,9 +138,8 @@ private: MediaSource m_nextSource; bool m_nextSourceSet; - // Storing the file handle here to work around KErrInUse error - // from MMF player utility OpenFileL functions - RFile m_file; + RFile* m_file; + QResource* m_resource; QScopedPointer m_player; diff --git a/src/3rdparty/phonon/phonon/mediasource.cpp b/src/3rdparty/phonon/phonon/mediasource.cpp index 11d2428..d70b38b 100644 --- a/src/3rdparty/phonon/phonon/mediasource.cpp +++ b/src/3rdparty/phonon/phonon/mediasource.cpp @@ -58,6 +58,7 @@ MediaSource::MediaSource(const QString &filename) d->type = Stream; d->ioDevice = new QFile(filename); d->setStream(new IODeviceStream(d->ioDevice, d->ioDevice)); + d->url = QUrl::fromLocalFile(fileInfo.absoluteFilePath()); #else d->type = Invalid; #endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM -- cgit v0.12 From 00370b54a45cd602d04c8479538a177eb548364f Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Thu, 29 Jul 2010 09:41:39 +0100 Subject: Enabled tst_mediaobject::testPlayFromResource on Symbian Task-number: QTBUG-6562 Reviewed-by: Justin McPherson --- tests/auto/mediaobject/tst_mediaobject.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/auto/mediaobject/tst_mediaobject.cpp b/tests/auto/mediaobject/tst_mediaobject.cpp index 2f98521..322e2e4 100644 --- a/tests/auto/mediaobject/tst_mediaobject.cpp +++ b/tests/auto/mediaobject/tst_mediaobject.cpp @@ -201,9 +201,6 @@ void tst_MediaObject::stateChanged(Phonon::State newstate, Phonon::State oldstat void tst_MediaObject::testPlayFromResource() { -#ifdef Q_OS_SYMBIAN - QSKIP("Not implemented yet.", SkipAll); -#else MediaObject media; media.setCurrentSource(QString(MEDIA_FILEPATH)); QVERIFY(media.state() != Phonon::ErrorState); @@ -214,7 +211,6 @@ void tst_MediaObject::testPlayFromResource() if (media.state() != Phonon::PlayingState) QTest::waitForSignal(&media, SIGNAL(stateChanged(Phonon::State, Phonon::State)), 10000); QCOMPARE(media.state(), Phonon::PlayingState); -#endif } void tst_MediaObject::testPlayIllegalFile() -- cgit v0.12 From fa99c88f2a87b98911916b7d701b884281a3342b Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 2 Aug 2010 13:27:29 +0300 Subject: Fixed qsymbianbearer.qtplugin exports in s60installs.pro These exports incorrectly add EPOCROOT to the destination, making it break when EPOCROOT includes drive letter. Reviewed-by: axis --- src/s60installs/s60installs.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 4addb84..8a8167b 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -57,8 +57,8 @@ symbian: { bearerPluginLocation = $${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET) bearerStubZ = $${EPOCROOT}$${HW_ZDIR}$${QT_PLUGINS_BASE_DIR}/bearer/qsymbianbearer$${QT_LIBINFIX}.qtplugin BLD_INF_RULES.prj_exports += \ - "qsymbianbearer.qtplugin $$bearerStubZ" \ - "qsymbianbearer.qtplugin $${EPOCROOT}epoc32/winscw/c$${QT_PLUGINS_BASE_DIR}/bearer/qsymbianbearer$${QT_LIBINFIX}.qtplugin" + "qsymbianbearer.qtplugin /$${HW_ZDIR}$${QT_PLUGINS_BASE_DIR}/bearer/qsymbianbearer$${QT_LIBINFIX}.qtplugin" \ + "qsymbianbearer.qtplugin /epoc32/winscw/c$${QT_PLUGINS_BASE_DIR}/bearer/qsymbianbearer$${QT_LIBINFIX}.qtplugin" } else { pluginLocations = $$QT_BUILD_TREE/plugins/s60 bearerPluginLocation = $$QT_BUILD_TREE/plugins/bearer -- cgit v0.12 From 700ba679e88241ce35b16c46326a854c07ac9b8a Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Mon, 2 Aug 2010 12:10:14 +0100 Subject: Fixed build break on Symbian versions earlier than S^3 The following overload was added in S^3: TInt RApaLsSession::RecognizeData(const TDesC8& aBuffer, TDataRecognitionResult& aDataType) const In order to allow the backend to compile against earlier versions of the platform, this patch calls the RecognizeData overload which taking the same arguments as above, plus a filename (for which KNullDesC is passed). Task-number: QTBUG-6562 Reviewed-by: trustme --- src/3rdparty/phonon/mmf/mediaobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index b476535..98326b8 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -158,7 +158,7 @@ MMF::MediaType MMF::MediaObject::bufferMediaType(const uchar *data, qint64 size) if (openRecognizer()) { TDataRecognitionResult recognizerResult; const TPtrC8 des(data, size); - const TInt err = m_recognizer.RecognizeData(des, recognizerResult); + const TInt err = m_recognizer.RecognizeData(KNullDesC, des, recognizerResult); if (KErrNone == err) { const TPtrC mimeType = recognizerResult.iDataType.Des(); result = Utils::mimeTypeToMediaType(mimeType); -- cgit v0.12 From 4778af08ca848c82526305c66dc23bb6b732b944 Mon Sep 17 00:00:00 2001 From: Hurewitz Kevin Date: Mon, 2 Aug 2010 15:00:00 +0200 Subject: QDesktopServices crashes when accessing the NULL X11 variable It appears that QDesktopServices for X11 assumes that it will be used with a GUI application and may access the X11 variable. The X11 variable will be NULL if it has not been initialized by the QApplication initialization. Merge-request: 2442 Reviewed-by: Olivier Goffart --- src/gui/util/qdesktopservices_x11.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gui/util/qdesktopservices_x11.cpp b/src/gui/util/qdesktopservices_x11.cpp index fe7f9a6..75e7209 100644 --- a/src/gui/util/qdesktopservices_x11.cpp +++ b/src/gui/util/qdesktopservices_x11.cpp @@ -71,10 +71,12 @@ static bool openDocument(const QUrl &url) if (launch(url, QLatin1String("xdg-open"))) return true; - if (X11->desktopEnvironment == DE_GNOME && launch(url, QLatin1String("gnome-open"))) { + // Use the X11->desktopEnvironment value if X11 is non-NULL, + // otherwise just attempt to launch command regardless of the desktop environment + if ((!X11 || (X11 && X11->desktopEnvironment == DE_GNOME)) && launch(url, QLatin1String("gnome-open"))) { return true; } else { - if (X11->desktopEnvironment == DE_KDE && launch(url, QLatin1String("kfmclient exec"))) + if ((!X11 || (X11 && X11->desktopEnvironment == DE_KDE)) && launch(url, QLatin1String("kfmclient exec"))) return true; } @@ -104,10 +106,12 @@ static bool launchWebBrowser(const QUrl &url) if (launch(url, QString::fromLocal8Bit(getenv("BROWSER")))) return true; - if (X11->desktopEnvironment == DE_GNOME && launch(url, QLatin1String("gnome-open"))) { + // Use the X11->desktopEnvironment value if X11 is non-NULL, + // otherwise just attempt to launch command regardless of the desktop environment + if ((!X11 || (X11 && X11->desktopEnvironment == DE_GNOME)) && launch(url, QLatin1String("gnome-open"))) { return true; } else { - if (X11->desktopEnvironment == DE_KDE && launch(url, QLatin1String("kfmclient openURL"))) + if ((!X11 || (X11 && X11->desktopEnvironment == DE_KDE)) && launch(url, QLatin1String("kfmclient openURL"))) return true; } -- cgit v0.12 From ed6d7222894a9bdc804d8c64845e2f0f356d2c01 Mon Sep 17 00:00:00 2001 From: Aaron McCarthy Date: Tue, 3 Aug 2010 11:09:37 +1000 Subject: Update def files. --- src/s60installs/bwins/QtNetworku.def | 2 ++ src/s60installs/eabi/QtNetworku.def | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/s60installs/bwins/QtNetworku.def b/src/s60installs/bwins/QtNetworku.def index 48af60c..2cf62a8 100644 --- a/src/s60installs/bwins/QtNetworku.def +++ b/src/s60installs/bwins/QtNetworku.def @@ -1143,4 +1143,6 @@ EXPORTS ?setNetworkAccessible@QNetworkAccessManager@@QAEXW4NetworkAccessibility@1@@Z @ 1142 NONAME ; void QNetworkAccessManager::setNetworkAccessible(enum QNetworkAccessManager::NetworkAccessibility) ??_EQBearerEngineFactoryInterface@@UAE@I@Z @ 1143 NONAME ; QBearerEngineFactoryInterface::~QBearerEngineFactoryInterface(unsigned int) ?enablePolling@QNetworkConfigurationManagerPrivate@@QAEXXZ @ 1144 NONAME ; void QNetworkConfigurationManagerPrivate::enablePolling(void) + ?bearerTypeName@QNetworkConfiguration@@QBE?AVQString@@XZ @ 1145 NONAME ; class QString QNetworkConfiguration::bearerTypeName(void) const + ?bearerType@QNetworkConfiguration@@QBE?AW4BearerType@1@XZ @ 1146 NONAME ; enum QNetworkConfiguration::BearerType QNetworkConfiguration::bearerType(void) const diff --git a/src/s60installs/eabi/QtNetworku.def b/src/s60installs/eabi/QtNetworku.def index eb30832..6b34a19 100644 --- a/src/s60installs/eabi/QtNetworku.def +++ b/src/s60installs/eabi/QtNetworku.def @@ -1131,7 +1131,7 @@ EXPORTS _ZNK21QNetworkAccessManager13configurationEv @ 1130 NONAME _ZNK21QNetworkAccessManager17networkAccessibleEv @ 1131 NONAME _ZNK21QNetworkAccessManager19activeConfigurationEv @ 1132 NONAME - _ZNK21QNetworkConfiguration10bearerNameEv @ 1133 NONAME + _ZNK21QNetworkConfiguration10bearerNameEv @ 1133 NONAME ABSENT _ZNK21QNetworkConfiguration10identifierEv @ 1134 NONAME _ZNK21QNetworkConfiguration18isRoamingAvailableEv @ 1135 NONAME _ZNK21QNetworkConfiguration4nameEv @ 1136 NONAME @@ -1167,4 +1167,6 @@ EXPORTS _ZN14QAuthenticator9setOptionERK7QStringRK8QVariant @ 1166 NONAME _ZNK14QAuthenticator6optionERK7QString @ 1167 NONAME _ZNK14QAuthenticator7optionsEv @ 1168 NONAME + _ZNK21QNetworkConfiguration10bearerTypeEv @ 1169 NONAME + _ZNK21QNetworkConfiguration14bearerTypeNameEv @ 1170 NONAME -- cgit v0.12 From 1fc6cab93ba2d067fadcd0979640c32aa1d5ae4a Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 3 Aug 2010 11:41:25 +1000 Subject: Limit the pixmap cache in space as well as in time. QTBUG-12590 --- src/declarative/util/qdeclarativepixmapcache.cpp | 33 +++++++++++++---- .../qdeclarativepixmapcache/data/massive.png | Bin 0 -> 31834 bytes .../tst_qdeclarativepixmapcache.cpp | 40 +++++++++++++++++++++ 3 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativepixmapcache/data/massive.png diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp index a83cac8..9ced14f 100644 --- a/src/declarative/util/qdeclarativepixmapcache.cpp +++ b/src/declarative/util/qdeclarativepixmapcache.cpp @@ -70,6 +70,16 @@ QT_BEGIN_NAMESPACE +// The cache limit describes the maximum "junk" in the cache. +// These are the same defaults as QPixmapCache +#if defined(Q_OS_SYMBIAN) +static int cache_limit = 1024 * 1024; // 1048 KB cache limit for symbian +#elif defined(Q_WS_QWS) || defined(Q_WS_WINCE) +static int cache_limit = 2048 * 1024; // 2048 KB cache limit for embedded +#else +static int cache_limit = 10240 * 1024; // 10 MB cache limit for desktop +#endif + class QDeclarativePixmapReader; class QDeclarativePixmapData; class QDeclarativePixmapReply : public QObject @@ -580,6 +590,8 @@ public: QHash m_cache; private: + void shrinkCache(int remove); + QDeclarativePixmapData *m_unreferencedPixmaps; QDeclarativePixmapData *m_lastUnreferencedPixmap; @@ -613,7 +625,9 @@ void QDeclarativePixmapStore::unreferencePixmap(QDeclarativePixmapData *data) m_unreferencedCost += data->cost(); - if (m_timerId == -1) + shrinkCache(-1); // Shrink the cache incase it has become larger than cache_limit + + if (m_timerId == -1 && m_unreferencedPixmaps) m_timerId = startTimer(CACHE_EXPIRE_TIME * 1000); } @@ -636,11 +650,9 @@ void QDeclarativePixmapStore::referencePixmap(QDeclarativePixmapData *data) m_unreferencedCost -= data->cost(); } -void QDeclarativePixmapStore::timerEvent(QTimerEvent *) +void QDeclarativePixmapStore::shrinkCache(int remove) { - int removalCost = m_unreferencedCost / CACHE_REMOVAL_FRACTION; - - while (removalCost > 0 && m_lastUnreferencedPixmap) { + while ((remove > 0 || m_unreferencedCost > cache_limit) && m_lastUnreferencedPixmap) { QDeclarativePixmapData *data = m_lastUnreferencedPixmap; Q_ASSERT(data->nextUnreferenced == 0); @@ -649,10 +661,17 @@ void QDeclarativePixmapStore::timerEvent(QTimerEvent *) data->prevUnreferencedPtr = 0; data->prevUnreferenced = 0; - removalCost -= data->cost(); + remove -= data->cost(); data->removeFromCache(); delete data; } +} + +void QDeclarativePixmapStore::timerEvent(QTimerEvent *) +{ + int removalCost = m_unreferencedCost / CACHE_REMOVAL_FRACTION; + + shrinkCache(removalCost); if (m_unreferencedPixmaps == 0) { killTimer(m_timerId); @@ -702,7 +721,7 @@ bool QDeclarativePixmapReply::event(QEvent *event) int QDeclarativePixmapData::cost() const { - return pixmap.width() * pixmap.height() * pixmap.depth(); + return (pixmap.width() * pixmap.height() * pixmap.depth()) / 8; } void QDeclarativePixmapData::addref() diff --git a/tests/auto/declarative/qdeclarativepixmapcache/data/massive.png b/tests/auto/declarative/qdeclarativepixmapcache/data/massive.png new file mode 100644 index 0000000..bc6cc9e Binary files /dev/null and b/tests/auto/declarative/qdeclarativepixmapcache/data/massive.png differ diff --git a/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp b/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp index 0c7780c..16d2063 100644 --- a/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp +++ b/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp @@ -70,6 +70,7 @@ private slots: void single_data(); void parallel(); void parallel_data(); + void massive(); private: QDeclarativeEngine engine; @@ -276,6 +277,45 @@ void tst_qdeclarativepixmapcache::parallel() qDeleteAll(pixmaps); } +void tst_qdeclarativepixmapcache::massive() +{ + QUrl url = thisfile.resolved(QUrl("data/massive.png")); + + // Confirm that massive images remain in the cache while they are + // in use by the application. + { + qint64 cachekey = 0; + QDeclarativePixmap p(0, url); + QVERIFY(p.isReady()); + QVERIFY(p.pixmap().size() == QSize(10000, 1000)); + cachekey = p.pixmap().cacheKey(); + + QDeclarativePixmap p2(0, url); + QVERIFY(p2.isReady()); + QVERIFY(p2.pixmap().size() == QSize(10000, 1000)); + + QVERIFY(p2.pixmap().cacheKey() == cachekey); + } + + // Confirm that massive images are removed from the cache when + // they become unused + { + qint64 cachekey = 0; + { + QDeclarativePixmap p(0, url); + QVERIFY(p.isReady()); + QVERIFY(p.pixmap().size() == QSize(10000, 1000)); + cachekey = p.pixmap().cacheKey(); + } + + QDeclarativePixmap p2(0, url); + QVERIFY(p2.isReady()); + QVERIFY(p2.pixmap().size() == QSize(10000, 1000)); + + QVERIFY(p2.pixmap().cacheKey() != cachekey); + } +} + QTEST_MAIN(tst_qdeclarativepixmapcache) #include "tst_qdeclarativepixmapcache.moc" -- cgit v0.12 From e62f266a7642e675e9d235a1f54a6b5746500d48 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Wed, 28 Jul 2010 18:45:23 +1000 Subject: Make it possible to manually set the orientation of QML Viewer on Symbian Task-number: QTBUG-12142 Reviewed-by: Warwick Allison This patch brings ability to switch QML Viewer's orientation between auto-orientation (=follow sensor), portrait and landscape orientations (lock orientation) on Symbian. It provides same orientation options as Qt Creator 2.1's Qt QML Standalone Application creation wizard. Also, menu item rotateOrientation now works on Symbian, but it's hidden when orientation mode is set to auto-orientation. Property runtime.orientation has been switched back to supporting four-way orientation on Symbian, previously it only updated values between portrait and landscape. If your application only supports landscape or portrait modes, just don't react to the inverted orientations. Added orientation example screenorientation under examples/declarative. The patch includes a fix for calculator example, which rotated to wrong direction when switching from portrait to landscape. Also, improved qdeclarativeviewer unit tests. Changes have been tested to work on Windows, Linux and Symbian^3. --- demos/declarative/calculator/Core/calculator.js | 4 +- demos/declarative/calculator/calculator.qml | 14 +- doc/src/declarative/examples.qdoc | 5 + doc/src/declarative/qmlviewer.qdoc | 8 +- doc/src/examples/qml-examples.qdoc | 8 + .../declarative/screenorientation/Core/Bubble.qml | 91 ++++++++++ .../declarative/screenorientation/Core/Button.qml | 72 ++++++++ .../screenorientation/Core/screenorientation.js | 95 ++++++++++ .../screenorientation/screenorientation.qml | 202 +++++++++++++++++++++ .../screenorientation/screenorientation.qmlproject | 16 ++ .../qdeclarativeviewer/tst_qdeclarativeviewer.cpp | 36 +++- tools/qml/deviceorientation_symbian.cpp | 15 +- tools/qml/qml.pro | 3 + tools/qml/qmlruntime.cpp | 74 ++++++-- tools/qml/qmlruntime.h | 3 +- 15 files changed, 611 insertions(+), 35 deletions(-) create mode 100644 examples/declarative/screenorientation/Core/Bubble.qml create mode 100644 examples/declarative/screenorientation/Core/Button.qml create mode 100644 examples/declarative/screenorientation/Core/screenorientation.js create mode 100644 examples/declarative/screenorientation/screenorientation.qml create mode 100644 examples/declarative/screenorientation/screenorientation.qmlproject diff --git a/demos/declarative/calculator/Core/calculator.js b/demos/declarative/calculator/Core/calculator.js index c80c42f..16cc309 100644 --- a/demos/declarative/calculator/Core/calculator.js +++ b/demos/declarative/calculator/Core/calculator.js @@ -83,9 +83,9 @@ function doOperation(op) { display.text ="0" } - if (op == rotateLeft) - main.state = "orientation " + Orientation.Landscape if (op == rotateRight) + main.state = "orientation " + Orientation.Landscape + if (op == rotateLeft) main.state = '' } diff --git a/demos/declarative/calculator/calculator.qml b/demos/declarative/calculator/calculator.qml index 63b6c55..288455b 100644 --- a/demos/declarative/calculator/calculator.qml +++ b/demos/declarative/calculator/calculator.qml @@ -85,7 +85,7 @@ Rectangle { Button { id: rotateButton - width: column.w; height: column.h; color: 'purple'; operation: rotateLeft + width: column.w; height: column.h; color: 'purple'; operation: rotateRight } Button { width: column.w; height: column.h; color: 'purple'; operation: leftArrow } Button { width: column.w; height: column.h; color: 'purple'; operation: "C" } @@ -134,18 +134,18 @@ Rectangle { states: [ State { name: "orientation " + Orientation.Landscape - PropertyChanges { target: main; rotation: -90; width: window.height; height: window.width } - PropertyChanges { target: rotateButton; operation: rotateRight } + PropertyChanges { target: main; rotation: 90; width: window.height; height: window.width } + PropertyChanges { target: rotateButton; operation: rotateLeft } }, State { name: "orientation " + Orientation.PortraitInverted - PropertyChanges { target: main; rotation: -180; } - PropertyChanges { target: rotateButton; operation: rotateLeft } + PropertyChanges { target: main; rotation: 180; } + PropertyChanges { target: rotateButton; operation: rotateRight } }, State { name: "orientation " + Orientation.LandscapeInverted - PropertyChanges { target: main; rotation: -270; width: window.height; height: window.width } - PropertyChanges { target: rotateButton; operation: rotateRight } + PropertyChanges { target: main; rotation: 270; width: window.height; height: window.width } + PropertyChanges { target: rotateButton; operation: rotateLeft } } ] diff --git a/doc/src/declarative/examples.qdoc b/doc/src/declarative/examples.qdoc index 39da323..9929cfe 100644 --- a/doc/src/declarative/examples.qdoc +++ b/doc/src/declarative/examples.qdoc @@ -203,6 +203,11 @@ The examples can be found in Qt's \c examples/declarative directory. \o \l{declarative/threading/workerscript}{WorkerScript} \endlist +\section2 Screen orientation +\list +\o \l{declarative/screenorientation}{Example} +\endlist + \section2 SQL Local Storage \list \o \l{declarative/sqllocalstorage}{Example} diff --git a/doc/src/declarative/qmlviewer.qdoc b/doc/src/declarative/qmlviewer.qdoc index 5efc0ce..41c4c80 100644 --- a/doc/src/declarative/qmlviewer.qdoc +++ b/doc/src/declarative/qmlviewer.qdoc @@ -197,10 +197,10 @@ Rectangle { \o \c runtime.orientation \o This property indicates the current orientation of the QML Viewer. On the -N900 platform, this property automatically updates to reflect the device's -actual orientation; on other platforms, this indicates the orientation currently -selected in the QML Viewer's \e {Settings -> Properties} menu. The -\c orientation value can be one of the following: +N900 platform and most S60 5.0-based or newer Symbian devices, this property +automatically updates to reflect the device's actual orientation; on other platforms, +this indicates the orientation currently selected in the QML Viewer's +\e {Settings -> Properties} menu. The \c orientation value can be one of the following: \list \o \c Orientation.Portrait diff --git a/doc/src/examples/qml-examples.qdoc b/doc/src/examples/qml-examples.qdoc index a8be401..8d3aa25 100644 --- a/doc/src/examples/qml-examples.qdoc +++ b/doc/src/examples/qml-examples.qdoc @@ -412,6 +412,14 @@ \endtable */ + +/*! + \title Screen orientation + \example declarative/screenorientation + + This example shows how to implement screen orientation support for your application. +*/ + /*! \title SQL Local Storage Example \example declarative/sqllocalstorage diff --git a/examples/declarative/screenorientation/Core/Bubble.qml b/examples/declarative/screenorientation/Core/Bubble.qml new file mode 100644 index 0000000..2474f30 --- /dev/null +++ b/examples/declarative/screenorientation/Core/Bubble.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** 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 QtDeclarative module 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$ +** +****************************************************************************/ + +import Qt 4.7 + +Rectangle { + property bool rising: false + property bool verticalRise: true + property real xAttractor: 0 + property real yAttractor: 0 + + width: 5 + 10*Math.random() + height: width + radius: Math.floor(width/2)-1 + property real amountOfGray: Math.random() + color: Qt.rgba(amountOfGray,amountOfGray,amountOfGray,1) + + y: (rising && verticalRise) ? yAttractor : Math.random()*(main.inPortrait ? main.baseHeight : main.baseWidth) + x: (rising && !verticalRise) ? xAttractor : Math.random()*(main.inPortrait ? main.baseWidth : main.baseHeight) + Behavior on x { + id: xBehavior + SmoothedAnimation { + velocity: 100+Math.random()*100 + } + } + Behavior on y { + id: yBehavior + SmoothedAnimation { + velocity: 100+Math.random()*100 + } + } + Timer { + interval: 80+Math.random()*40 + repeat: true + running: true + onTriggered: { + if (rising) { + if (x > main.width || x < 0) { + xBehavior.enabled = false; + rising = false; + xBehavior.enabled = true; + rising = true; + } + if (y > main.height || y < 0) { + yBehavior.enabled = false; + rising = false; + yBehavior.enabled = true; + rising = true; + } + } + } + } +} \ No newline at end of file diff --git a/examples/declarative/screenorientation/Core/Button.qml b/examples/declarative/screenorientation/Core/Button.qml new file mode 100644 index 0000000..60083d8 --- /dev/null +++ b/examples/declarative/screenorientation/Core/Button.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** 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 QtDeclarative module 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$ +** +****************************************************************************/ + +import Qt 4.7 +Item { + id: button + signal clicked + property string text + property bool toggled: false + width: 100 + height: 60 + Rectangle { + anchors.fill: button + anchors.margins: mouseArea.pressed ? 3 : 2 + color: toggled ? (mouseArea.pressed ? "#442222" : "darkred") : (mouseArea.pressed ? "#333333": "black") + radius: mouseArea.pressed ? 8 : 6 + Text { + id: text + anchors.centerIn: parent + text: button.text + font.pixelSize: mouseArea.pressed ? 12 : 14 + color: "white" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + MouseArea { + id: mouseArea + anchors.fill: parent + onClicked: { + button.clicked() + } + } + } +} diff --git a/examples/declarative/screenorientation/Core/screenorientation.js b/examples/declarative/screenorientation/Core/screenorientation.js new file mode 100644 index 0000000..f0a5574 --- /dev/null +++ b/examples/declarative/screenorientation/Core/screenorientation.js @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** 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 QtDeclarative module 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$ +** +****************************************************************************/ + +function printOrientation(orientation) { + var orientationString; + if (orientation == Orientation.Portrait) { + orientationString = "Portrait"; + } else if (orientation == Orientation.Landscape) { + orientationString = "Landscape"; + } else if (orientation == Orientation.PortraitInverted) { + orientationString = "Portrait inverted"; + } else if (orientation == Orientation.LandscapeInverted) { + orientationString = "Landscape inverted"; + } else { + orientationString = "UnknownOrientation"; + } + return orientationString; +} + +function getAngle(orientation) { + var angle; + if (orientation == Orientation.Portrait) { + angle = 0; + } else if (orientation == Orientation.Landscape) { + angle = 90; + } else if (orientation == Orientation.PortraitInverted) { + angle = 180; + } else if (orientation == Orientation.LandscapeInverted) { + angle = 270; + } else { + angle = 0; + } + return angle; +} + +function parallel(firstOrientation, secondOrientation) { + var difference = getAngle(firstOrientation) - getAngle(secondOrientation) + return difference % 180 == 0; +} + +function calculateGravityPoint(firstOrientation, secondOrientation) { + var position = Qt.point(0, 0); + var difference = getAngle(firstOrientation) - getAngle(secondOrientation) + if (difference < 0) { + difference = 360 + difference; + } + if (difference == 0) { + position = Qt.point(0, -10); + } else if (difference == 90) { + position = Qt.point(-10, 0); + } else if (difference == 180) { + position = Qt.point(0, 1000); + } else if (difference == 270) { + position = Qt.point(1000, 0); + } + return position; +} diff --git a/examples/declarative/screenorientation/screenorientation.qml b/examples/declarative/screenorientation/screenorientation.qml new file mode 100644 index 0000000..6af38bb --- /dev/null +++ b/examples/declarative/screenorientation/screenorientation.qml @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** 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 QtDeclarative module 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$ +** +****************************************************************************/ + +import Qt 4.7 +import "Core" +import "Core/screenorientation.js" as ScreenOrientation + +Rectangle { + id: window + width: 360 + height: 640 + color: "white" + + Rectangle { + id: main + clip: true + property variant selectedOrientation: Orientation.UnknownOrientation + property variant activeOrientation: selectedOrientation == Orientation.UnknownOrientation ? runtime.orientation : selectedOrientation + state: "orientation " + activeOrientation + property bool inPortrait: (activeOrientation == Orientation.Portrait || activeOrientation == Orientation.PortraitInverted); + + // rotation correction for landscape devices like N900 + property bool landscapeWindow: window.width > window.height + property variant rotationDelta: landscapeWindow ? -90 : 0 + rotation: rotationDelta + + // initial state is portrait + property real baseWidth: landscapeWindow ? window.height-10 : window.width-10 + property real baseHeight: landscapeWindow ? window.width-10 : window.height-10 + + width: baseWidth + height: baseHeight + anchors.centerIn: parent + + color: "black" + gradient: Gradient { + GradientStop { position: 0.0; color: Qt.rgba(0.5,0.5,0.5,0.5) } + GradientStop { position: 0.8; color: "black" } + GradientStop { position: 1.0; color: "black" } + } + Item { + id: bubbles + property bool rising: false + anchors.fill: parent + property variant gravityPoint: ScreenOrientation.calculateGravityPoint(main.activeOrientation, runtime.orientation) + Repeater { + model: 24 + Bubble { + rising: bubbles.rising + verticalRise: ScreenOrientation.parallel(main.activeOrientation, runtime.orientation) + xAttractor: parent.gravityPoint.x + yAttractor: parent.gravityPoint.y + } + } + Component.onCompleted: bubbles.rising = true; + } + + Column { + width: centeredText.width + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenterOffset: 30 + Text { + text: "Orientation" + color: "white" + font.pixelSize: 22 + anchors.horizontalCenter: parent.horizontalCenter + } + Text { + id: centeredText + text: ScreenOrientation.printOrientation(main.activeOrientation) + color: "white" + font.pixelSize: 40 + anchors.horizontalCenter: parent.horizontalCenter + } + Text { + text: "sensor: " + ScreenOrientation.printOrientation(runtime.orientation) + color: "white" + font.pixelSize: 14 + anchors.horizontalCenter: parent.horizontalCenter + } + } + Flow { + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 10 + spacing: 4 + Button { + width: main.inPortrait ? (parent.width-4)/2 : (parent.width-8)/3 + text: "Portrait" + onClicked: main.selectedOrientation = Orientation.Portrait + toggled: main.selectedOrientation == Orientation.Portrait + } + Button { + width: main.inPortrait ? (parent.width-4)/2 : (parent.width-8)/3 + text: "Portrait inverted" + onClicked: main.selectedOrientation = Orientation.PortraitInverted + toggled: main.selectedOrientation == Orientation.PortraitInverted + } + Button { + width: main.inPortrait ? (parent.width-4)/2 : (parent.width-8)/3 + text: "Landscape" + onClicked: main.selectedOrientation = Orientation.Landscape + toggled: main.selectedOrientation == Orientation.Landscape + } + Button { + width: main.inPortrait ? (parent.width-4)/2 : (parent.width-8)/3 + text: "Landscape inverted" + onClicked: main.selectedOrientation = Orientation.LandscapeInverted + toggled: main.selectedOrientation == Orientation.LandscapeInverted + } + Button { + width: main.inPortrait ? parent.width : 2*(parent.width-2)/3 + text: "From runtime.orientation" + onClicked: main.selectedOrientation = Orientation.UnknownOrientation + toggled: main.selectedOrientation == Orientation.UnknownOrientation + } + } + states: [ + State { + name: "orientation " + Orientation.Landscape + PropertyChanges { + target: main + rotation: ScreenOrientation.getAngle(Orientation.Landscape)+rotationDelta + width: baseHeight + height: baseWidth + } + }, + State { + name: "orientation " + Orientation.PortraitInverted + PropertyChanges { + target: main + rotation: ScreenOrientation.getAngle(Orientation.PortraitInverted)+rotationDelta + width: baseWidth + height: baseHeight + } + }, + State { + name: "orientation " + Orientation.LandscapeInverted + PropertyChanges { + target: main + rotation: ScreenOrientation.getAngle(Orientation.LandscapeInverted)+rotationDelta + width: baseHeight + height: baseWidth + } + } + ] + transitions: Transition { + ParallelAnimation { + RotationAnimation { + direction: RotationAnimation.Shortest + duration: 300 + easing.type: Easing.InOutQuint + } + NumberAnimation { + properties: "x,y,width,height" + duration: 300 + easing.type: Easing.InOutQuint + } + } + } + } +} diff --git a/examples/declarative/screenorientation/screenorientation.qmlproject b/examples/declarative/screenorientation/screenorientation.qmlproject new file mode 100644 index 0000000..d4909f8 --- /dev/null +++ b/examples/declarative/screenorientation/screenorientation.qmlproject @@ -0,0 +1,16 @@ +import QmlProject 1.0 + +Project { + /* Include .qml, .js, and image files from current directory and subdirectories */ + QmlFiles { + directory: "." + } + JavaScriptFiles { + directory: "." + } + ImageFiles { + directory: "." + } + /* List of plugin directories passed to QML runtime */ + // importPaths: [ " ../exampleplugin " ] +} diff --git a/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp b/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp index de8d222..1c1c04b 100644 --- a/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp +++ b/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp @@ -43,9 +43,11 @@ #include #include #include +#include #include #include "../../../shared/util.h" #include "qmlruntime.h" +#include "deviceorientation.h" #include "../../../shared/util.h" #ifdef Q_OS_SYMBIAN @@ -67,7 +69,7 @@ public: tst_QDeclarativeViewer(); private slots: - void orientation(); + void runtimeContextProperty(); void loading(); void fileBrowser(); void resizing(); @@ -94,7 +96,7 @@ tst_QDeclarativeViewer::tst_QDeclarativeViewer() QCOMPARE(viewer->size(), viewer->sizeHint()); \ } -void tst_QDeclarativeViewer::orientation() +void tst_QDeclarativeViewer::runtimeContextProperty() { QDeclarativeViewer *viewer = new QDeclarativeViewer(); QVERIFY(viewer); @@ -103,17 +105,30 @@ void tst_QDeclarativeViewer::orientation() QVERIFY(viewer->menuBar()); QDeclarativeItem* rootItem = qobject_cast(viewer->view()->rootObject()); QVERIFY(rootItem); + QObject *runtimeObject = qvariant_cast(viewer->view()->engine()->rootContext()->contextProperty("runtime")); + QVERIFY(runtimeObject); + + // test isActiveWindow property + QVERIFY(!runtimeObject->property("isActiveWindow").toBool()); + viewer->show(); - QApplication::setActiveWindow(viewer); QTest::qWaitForWindowShown(viewer); QTRY_COMPARE(QApplication::activeWindow(), static_cast(viewer)); + QVERIFY(runtimeObject->property("isActiveWindow").toBool()); + TEST_INITIAL_SIZES(viewer); + // test orientation property + QCOMPARE(runtimeObject->property("orientation").toInt(), int(DeviceOrientation::Portrait)); + viewer->rotateOrientation(); qApp->processEvents(); + QCOMPARE(runtimeObject->property("orientation").toInt(), int(DeviceOrientation::Landscape)); + QCOMPARE(rootItem->width(), 300.0); + QCOMPARE(rootItem->width(), 300.0); QCOMPARE(rootItem->height(), 200.0); QTRY_COMPARE(viewer->view()->size(), QSize(300, 200)); @@ -124,6 +139,8 @@ void tst_QDeclarativeViewer::orientation() viewer->rotateOrientation(); qApp->processEvents(); + QCOMPARE(runtimeObject->property("orientation").toInt(), int(DeviceOrientation::PortraitInverted)); + QCOMPARE(rootItem->width(), 200.0); QCOMPARE(rootItem->height(), 300.0); QTRY_COMPARE(viewer->view()->size(), QSize(200, 300)); @@ -131,6 +148,19 @@ void tst_QDeclarativeViewer::orientation() QCOMPARE(viewer->size(), QSize(200, 300 + MENUBAR_HEIGHT(viewer))); QCOMPARE(viewer->size(), viewer->sizeHint()); + viewer->rotateOrientation(); + qApp->processEvents(); + + QCOMPARE(runtimeObject->property("orientation").toInt(), int(DeviceOrientation::LandscapeInverted)); + + viewer->rotateOrientation(); + qApp->processEvents(); + + QCOMPARE(runtimeObject->property("orientation").toInt(), int(DeviceOrientation::Portrait)); + + viewer->hide(); + QVERIFY(!runtimeObject->property("isActiveWindow").toBool()); + delete viewer; } diff --git a/tools/qml/deviceorientation_symbian.cpp b/tools/qml/deviceorientation_symbian.cpp index c305f94..307c417 100644 --- a/tools/qml/deviceorientation_symbian.cpp +++ b/tools/qml/deviceorientation_symbian.cpp @@ -110,22 +110,27 @@ private: void DataReceived(CSensrvChannel &channel, TInt count, TInt dataLost) { + Q_UNUSED(dataLost) if (channel.GetChannelInfo().iChannelType == KSensrvChannelTypeIdOrientationData) { TSensrvOrientationData data; for (int i = 0; i < count; ++i) { TPckgBuf dataBuf; channel.GetData(dataBuf); data = dataBuf(); - Orientation o = UnknownOrientation; + Orientation orientation = UnknownOrientation; switch (data.iDeviceOrientation) { case TSensrvOrientationData::EOrientationDisplayUp: - o = Portrait; + orientation = Portrait; break; case TSensrvOrientationData::EOrientationDisplayRightUp: - o = Landscape; + orientation = Landscape; break; case TSensrvOrientationData::EOrientationDisplayLeftUp: + orientation = LandscapeInverted; + break; case TSensrvOrientationData::EOrientationDisplayDown: + orientation = PortraitInverted; + break; case TSensrvOrientationData::EOrientationUndefined: case TSensrvOrientationData::EOrientationDisplayUpwards: case TSensrvOrientationData::EOrientationDisplayDownwards: @@ -133,8 +138,8 @@ private: break; } - if (m_current != o && o != UnknownOrientation) { - m_current = o; + if (m_current != orientation && orientation != UnknownOrientation) { + m_current = orientation; emit orientationChanged(); } } diff --git a/tools/qml/qml.pro b/tools/qml/qml.pro index bb69e8a..efb82d1 100644 --- a/tools/qml/qml.pro +++ b/tools/qml/qml.pro @@ -40,6 +40,9 @@ symbian { !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) { LIBS += -lsensrvclient -lsensrvutil } + contains(QT_CONFIG, s60): { + LIBS += -lavkon -lcone + } } mac { QMAKE_INFO_PLIST=Info_mac.plist diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index 08a578c..b9fd570 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -98,6 +98,10 @@ #include #endif +#if defined(Q_WS_S60) +#include // For locking app orientation +#endif + #include QT_BEGIN_NAMESPACE @@ -600,6 +604,7 @@ QDeclarativeViewer::QDeclarativeViewer(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags) , loggerWindow(new LoggerWidget(this)) , frame_stream(0) + , rotateAction(0) , orientation(0) , showWarningsWindow(0) , m_scriptOptions(0) @@ -742,22 +747,28 @@ void QDeclarativeViewer::createMenu() fullscreenAction->setCheckable(true); connect(fullscreenAction, SIGNAL(triggered()), this, SLOT(toggleFullScreen())); - QAction *rotateOrientation = new QAction(tr("Rotate orientation"), this); - rotateOrientation->setShortcut(QKeySequence("Ctrl+T")); - connect(rotateOrientation, SIGNAL(triggered()), this, SLOT(rotateOrientation())); + rotateAction = new QAction(tr("Rotate orientation"), this); + rotateAction->setShortcut(QKeySequence("Ctrl+T")); + connect(rotateAction, SIGNAL(triggered()), this, SLOT(rotateOrientation())); orientation = new QActionGroup(this); orientation->setExclusive(true); connect(orientation, SIGNAL(triggered(QAction*)), this, SLOT(changeOrientation(QAction*))); +#if defined(Q_OS_SYMBIAN) + QAction *autoOrientationAction = new QAction(tr("Auto-orientation"), this); + autoOrientationAction->setCheckable(true); +#endif QAction *portraitAction = new QAction(tr("Portrait"), this); portraitAction->setCheckable(true); QAction *landscapeAction = new QAction(tr("Landscape"), this); landscapeAction->setCheckable(true); +#if !defined(Q_OS_SYMBIAN) QAction *portraitInvAction = new QAction(tr("Portrait (inverted)"), this); portraitInvAction->setCheckable(true); QAction *landscapeInvAction = new QAction(tr("Landscape (inverted)"), this); landscapeInvAction->setCheckable(true); +#endif QAction *aboutAction = new QAction(tr("&About Qt..."), this); aboutAction->setMenuRole(QAction::AboutQtRole); @@ -801,9 +812,9 @@ void QDeclarativeViewer::createMenu() fileMenu->addAction(reloadAction); fileMenu->addSeparator(); fileMenu->addAction(closeAction); +#if !defined(Q_OS_SYMBIAN) fileMenu->addAction(quitAction); -#if !defined(Q_OS_SYMBIAN) QMenu *recordMenu = menu->addMenu(tr("&Recording")); recordMenu->addAction(snapshotAction); recordMenu->addAction(recordAction); @@ -813,22 +824,27 @@ void QDeclarativeViewer::createMenu() debugMenu->addAction(showWarningsWindow); #endif // ! Q_OS_SYMBIAN - QMenu *settingsMenu = menu->addMenu(tr("S&ettings")); + QMenu *settingsMenu = menu->addMenu(tr("&Settings")); settingsMenu->addAction(proxyAction); -#if !defined(Q_OS_SYMBIAN) +#if defined(Q_OS_SYMBIAN) + settingsMenu->addAction(fullscreenAction); +#else settingsMenu->addAction(recordOptions); settingsMenu->addMenu(loggerWindow->preferencesMenu()); -#else // ! Q_OS_SYMBIAN - settingsMenu->addAction(fullscreenAction); -#endif // Q_OS_SYMBIAN - settingsMenu->addAction(rotateOrientation); +#endif // !Q_OS_SYMBIAN + settingsMenu->addAction(rotateAction); QMenu *propertiesMenu = settingsMenu->addMenu(tr("Properties")); +#if defined(Q_OS_SYMBIAN) + orientation->addAction(autoOrientationAction); +#endif orientation->addAction(portraitAction); orientation->addAction(landscapeAction); +#if !defined(Q_OS_SYMBIAN) orientation->addAction(portraitInvAction); orientation->addAction(landscapeInvAction); +#endif propertiesMenu->addActions(orientation->actions()); QMenu *helpMenu = menu->addMenu(tr("&Help")); @@ -852,6 +868,23 @@ void QDeclarativeViewer::proxySettingsChanged() void QDeclarativeViewer::rotateOrientation() { +#if defined(Q_WS_S60) + CAknAppUi *appUi = static_cast(CEikonEnv::Static()->AppUi()); + if (appUi) { + CAknAppUi::TAppUiOrientation oldOrientation = appUi->Orientation(); + QString newOrientation; + if (oldOrientation == CAknAppUi::EAppUiOrientationPortrait) { + newOrientation = QLatin1String("Landscape"); + } else { + newOrientation = QLatin1String("Portrait"); + } + foreach (QAction *action, orientation->actions()) { + if (action->text() == newOrientation) { + changeOrientation(action); + } + } + } +#else QAction *current = orientation->checkedAction(); QList actions = orientation->actions(); int index = actions.indexOf(current); @@ -860,6 +893,7 @@ void QDeclarativeViewer::rotateOrientation() QAction *newOrientation = actions[(index + 1) % actions.count()]; changeOrientation(newOrientation); +#endif } void QDeclarativeViewer::toggleFullScreen() @@ -1369,9 +1403,24 @@ void QDeclarativeViewer::changeOrientation(QAction *action) { if (!action) return; - action->setChecked(true); - QString o = action->text(); + action->setChecked(true); +#if defined(Q_WS_S60) + CAknAppUi *appUi = static_cast(CEikonEnv::Static()->AppUi()); + if (appUi) { + CAknAppUi::TAppUiOrientation orientation = appUi->Orientation(); + if (o == QLatin1String("Auto-orientation")) { + appUi->SetOrientationL(CAknAppUi::EAppUiOrientationAutomatic); + rotateAction->setVisible(false); + } else if (o == QLatin1String("Portrait")) { + appUi->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait); + rotateAction->setVisible(true); + } else if (o == QLatin1String("Landscape")) { + appUi->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape); + rotateAction->setVisible(true); + } + } +#else if (o == QLatin1String("Portrait")) DeviceOrientation::instance()->setOrientation(DeviceOrientation::Portrait); else if (o == QLatin1String("Landscape")) @@ -1380,6 +1429,7 @@ void QDeclarativeViewer::changeOrientation(QAction *action) DeviceOrientation::instance()->setOrientation(DeviceOrientation::PortraitInverted); else if (o == QLatin1String("Landscape (inverted)")) DeviceOrientation::instance()->setOrientation(DeviceOrientation::LandscapeInverted); +#endif } void QDeclarativeViewer::orientationChanged() diff --git a/tools/qml/qmlruntime.h b/tools/qml/qmlruntime.h index 7385b14..6fa7d81 100644 --- a/tools/qml/qmlruntime.h +++ b/tools/qml/qmlruntime.h @@ -170,8 +170,6 @@ private: int record_autotime; bool devicemode; QAction *recordAction; - QString currentSkin; - bool scaleSkin; RecordingDialog *recdlg; void senseImageMagick(); @@ -180,6 +178,7 @@ private: bool ffmpegAvailable; bool convertAvailable; + QAction *rotateAction; QActionGroup *orientation; QAction *showWarningsWindow; -- cgit v0.12 From 972191f8e3bdbf702e11be8c0a72fca9e896f395 Mon Sep 17 00:00:00 2001 From: Aaron McCarthy Date: Tue, 3 Aug 2010 15:33:11 +1000 Subject: Return 'Unknown' bearer type name for unknown bearer type. --- src/network/bearer/qnetworkconfiguration.cpp | 2 +- src/network/bearer/qnetworkconfiguration_p.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp index b645916..3190a30 100644 --- a/src/network/bearer/qnetworkconfiguration.cpp +++ b/src/network/bearer/qnetworkconfiguration.cpp @@ -506,7 +506,7 @@ QString QNetworkConfiguration::bearerTypeName() const return QLatin1String("WiMAX"); } - return QString(); + return QLatin1String("Unknown"); } QT_END_NAMESPACE diff --git a/src/network/bearer/qnetworkconfiguration_p.h b/src/network/bearer/qnetworkconfiguration_p.h index 0fc6ee9..2b0bbf6 100644 --- a/src/network/bearer/qnetworkconfiguration_p.h +++ b/src/network/bearer/qnetworkconfiguration_p.h @@ -81,7 +81,7 @@ public: virtual QString bearerTypeName() const { - return QString(); + return QLatin1String("Unknown"); } QMap serviceNetworkMembers; -- cgit v0.12