diff options
author | Alan Alpert <alan.alpert@nokia.com> | 2011-06-14 11:45:20 +1000 |
---|---|---|
committer | Alan Alpert <alan.alpert@nokia.com> | 2011-06-14 11:45:20 +1000 |
commit | ba7e87ffe0f1cb356dc31dc2d43640d06309eaa7 (patch) | |
tree | 24a88f3d9cb26edf4e8f8fec720f6851bd5b0502 | |
parent | 7b28a7eebeb8cbe5d356fc9b24651a36d73ab1ad (diff) | |
parent | e86bdcd3ce686eb14bb70e0b18b227f713a902b6 (diff) |
Merge branch 'qtquick2' of scm.dev.nokia.troll.no:qt/qtdeclarative-staging into qtquick2
28 files changed, 528 insertions, 52 deletions
diff --git a/src/declarative/debugger/qjsdebuggeragent.cpp b/src/declarative/debugger/qjsdebuggeragent.cpp index 9b76592c48..dff637b7da 100644 --- a/src/declarative/debugger/qjsdebuggeragent.cpp +++ b/src/declarative/debugger/qjsdebuggeragent.cpp @@ -56,7 +56,7 @@ class QJSDebuggerAgentPrivate { public: QJSDebuggerAgentPrivate(QJSDebuggerAgent *q) - : q(q), state(NoState) + : q(q), state(NoState), isInitialized(false) {} void continueExec(); @@ -79,6 +79,7 @@ public: QHash<QString, JSAgentBreakpointData> fileNameToBreakpoints; QStringList watchExpressions; QSet<qint64> knownObjectIds; + bool isInitialized; }; namespace { @@ -252,6 +253,14 @@ QJSDebuggerAgent::~QJSDebuggerAgent() delete d; } +/*! + Indicates whether the agent got the list of breakpoints. + */ +bool QJSDebuggerAgent::isInitialized() const +{ + return d->isInitialized; +} + void QJSDebuggerAgent::setBreakpoints(const JSAgentBreakpoints &breakpoints) { d->breakpoints = breakpoints; @@ -259,6 +268,8 @@ void QJSDebuggerAgent::setBreakpoints(const JSAgentBreakpoints &breakpoints) d->fileNameToBreakpoints.clear(); foreach (const JSAgentBreakpointData &bp, breakpoints) d->fileNameToBreakpoints.insertMulti(fileName(QString::fromUtf8(bp.fileUrl)), bp); + + d->isInitialized = true; } void QJSDebuggerAgent::setWatchExpressions(const QStringList &watchExpressions) diff --git a/src/declarative/debugger/qjsdebuggeragent_p.h b/src/declarative/debugger/qjsdebuggeragent_p.h index 5aa3c9ccbc..309588eb2f 100644 --- a/src/declarative/debugger/qjsdebuggeragent_p.h +++ b/src/declarative/debugger/qjsdebuggeragent_p.h @@ -145,6 +145,8 @@ public: QJSDebuggerAgent(QDeclarativeEngine *engine, QObject *parent = 0); ~QJSDebuggerAgent(); + bool isInitialized() const; + void setBreakpoints(const JSAgentBreakpoints &); void setWatchExpressions(const QStringList &); diff --git a/src/declarative/debugger/qjsdebugservice.cpp b/src/declarative/debugger/qjsdebugservice.cpp index 4ce2c906bc..ad84f656f7 100644 --- a/src/declarative/debugger/qjsdebugservice.cpp +++ b/src/declarative/debugger/qjsdebugservice.cpp @@ -71,6 +71,16 @@ void QJSDebugService::addEngine(QDeclarativeEngine *engine) Q_ASSERT(!m_engines.contains(engine)); m_engines.append(engine); + + if (status() == Enabled && !m_engines.isEmpty() && !m_agent) { + m_agent = new QJSDebuggerAgent(engine, engine); + connect(m_agent, SIGNAL(stopped(bool,QString)), + this, SLOT(executionStopped(bool,QString))); + + while (!m_agent->isInitialized()) { + waitForMessage(); + } + } } void QJSDebugService::removeEngine(QDeclarativeEngine *engine) diff --git a/src/declarative/debugger/qpacketprotocol.cpp b/src/declarative/debugger/qpacketprotocol.cpp index a40a9ab8a6..9caaa79011 100644 --- a/src/declarative/debugger/qpacketprotocol.cpp +++ b/src/declarative/debugger/qpacketprotocol.cpp @@ -198,6 +198,8 @@ public Q_SLOTS: packets.append(inProgress); inProgressSize = -1; inProgress.clear(); + + waitingForPacket = false; emit readyRead(); } else return; diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 98ec2050e9..b456d07c02 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -236,11 +236,11 @@ void QDeclarativeTextInput::setFont(const QFont &font) if (oldFont != d->font) { d->control->setFont(d->font); + updateSize(); + updateCursorRectangle(); if(d->cursorItem){ d->cursorItem->setHeight(QFontMetrics(d->font).height()); - moveCursor(); } - updateSize(); } emit fontChanged(d->sourceFont); } @@ -359,8 +359,7 @@ void QDeclarativeTextInput::setHAlign(HAlignment align) bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror; d->hAlignImplicit = false; if (d->setHAlign(align, forceAlign) && isComponentComplete()) { - updateRect(); - d->updateHorizontalScroll(); + updateCursorRectangle(); } } @@ -369,8 +368,7 @@ void QDeclarativeTextInput::resetHAlign() Q_D(QDeclarativeTextInput); d->hAlignImplicit = true; if (d->determineHorizontalAlignment() && isComponentComplete()) { - updateRect(); - d->updateHorizontalScroll(); + updateCursorRectangle(); } } @@ -423,8 +421,7 @@ void QDeclarativeTextInputPrivate::mirrorChange() Q_Q(QDeclarativeTextInput); if (q->isComponentComplete()) { if (!hAlignImplicit && (hAlign == QDeclarativeTextInput::AlignRight || hAlign == QDeclarativeTextInput::AlignLeft)) { - q->updateRect(); - updateHorizontalScroll(); + q->updateCursorRectangle(); emit q->effectiveHorizontalAlignmentChanged(); } } @@ -683,7 +680,7 @@ void QDeclarativeTextInput::setAutoScroll(bool b) d->autoScroll = b; //We need to repaint so that the scrolling is taking into account. updateSize(true); - d->updateHorizontalScroll(); + updateCursorRectangle(); emit autoScrollChanged(d->autoScroll); } @@ -947,10 +944,6 @@ void QDeclarativeTextInput::setCursorDelegate(QDeclarativeComponent* c) d->cursorComponent = c; if(!c){ //note that the components are owned by something else - disconnect(d->control, SIGNAL(cursorPositionChanged(int,int)), - this, SLOT(moveCursor())); - disconnect(d->control, SIGNAL(updateMicroFocus()), - this, SLOT(moveCursor())); delete d->cursorItem; }else{ d->startCreatingCursor(); @@ -962,10 +955,6 @@ void QDeclarativeTextInput::setCursorDelegate(QDeclarativeComponent* c) void QDeclarativeTextInputPrivate::startCreatingCursor() { Q_Q(QDeclarativeTextInput); - q->connect(control, SIGNAL(cursorPositionChanged(int,int)), - q, SLOT(moveCursor()), Qt::UniqueConnection); - q->connect(control, SIGNAL(updateMicroFocus()), - q, SLOT(moveCursor()), Qt::UniqueConnection); if(cursorComponent->isReady()){ q->createCursor(); }else if(cursorComponent->isLoading()){ @@ -1001,15 +990,6 @@ void QDeclarativeTextInput::createCursor() d->cursorItem->setHeight(d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text. } -void QDeclarativeTextInput::moveCursor() -{ - Q_D(QDeclarativeTextInput); - if(!d->cursorItem) - return; - d->updateHorizontalScroll(); - d->cursorItem->setX(d->control->cursorToX() - d->hscroll); -} - /*! \qmlmethod rect TextInput::positionToRectangle(int pos) @@ -1118,8 +1098,6 @@ void QDeclarativeTextInput::inputMethodEvent(QInputMethodEvent *ev) ev->ignore(); } else { d->control->processInputMethodEvent(ev); - updateSize(); - d->updateHorizontalScroll(); } } if (!ev->isAccepted()) @@ -1297,7 +1275,7 @@ void QDeclarativeTextInput::geometryChanged(const QRectF &newGeometry, Q_D(QDeclarativeTextInput); if (newGeometry.width() != oldGeometry.width()) { updateSize(); - d->updateHorizontalScroll(); + updateCursorRectangle(); } QDeclarativePaintedItem::geometryChanged(newGeometry, oldGeometry); } @@ -1643,7 +1621,6 @@ void QDeclarativeTextInput::moveCursorSelection(int position) { Q_D(QDeclarativeTextInput); d->control->moveCursor(position, true); - d->updateHorizontalScroll(); } /*! @@ -1901,7 +1878,7 @@ void QDeclarativeTextInputPrivate::init() canPaste = !control->isReadOnly() && QApplication::clipboard()->text().length() != 0; #endif // QT_NO_CLIPBOARD q->connect(control, SIGNAL(updateMicroFocus()), - q, SLOT(updateMicroFocus())); + q, SLOT(updateCursorRectangle())); q->connect(control, SIGNAL(displayTextChanged(QString)), q, SLOT(updateRect())); q->updateSize(); @@ -1917,9 +1894,7 @@ void QDeclarativeTextInputPrivate::init() void QDeclarativeTextInput::cursorPosChanged() { Q_D(QDeclarativeTextInput); - d->updateHorizontalScroll(); - updateRect();//TODO: Only update rect between pos's - updateMicroFocus(); + updateCursorRectangle(); emit cursorPositionChanged(); d->control->resetCursorBlinkTimer(); @@ -1935,6 +1910,17 @@ void QDeclarativeTextInput::cursorPosChanged() } } +void QDeclarativeTextInput::updateCursorRectangle() +{ + Q_D(QDeclarativeTextInput); + d->updateHorizontalScroll(); + updateRect();//TODO: Only update rect between pos's + updateMicroFocus(); + emit cursorRectangleChanged(); + if (d->cursorItem) + d->cursorItem->setX(d->control->cursorToX() - d->hscroll); +} + void QDeclarativeTextInput::selectionChanged() { Q_D(QDeclarativeTextInput); diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h index aaf8859150..8b7fff9cfb 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h @@ -75,7 +75,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeTextInput : public QDeclarativeImplicitSizeP Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged) Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible NOTIFY cursorVisibleChanged) Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged) - Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorPositionChanged) + Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged) Q_PROPERTY(QDeclarativeComponent *cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged) Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged) Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged) @@ -221,6 +221,7 @@ public: Q_SIGNALS: void textChanged(); void cursorPositionChanged(); + void cursorRectangleChanged(); void selectionStartChanged(); void selectionEndChanged(); void selectedTextChanged(); @@ -279,8 +280,8 @@ private Q_SLOTS: void q_textChanged(); void selectionChanged(); void createCursor(); - void moveCursor(); void cursorPosChanged(); + void updateCursorRectangle(); void updateRect(const QRect &r = QRect()); void q_canPasteChanged(); diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp index 3a88fbb790..fee58b87a8 100644 --- a/src/declarative/items/qsgcanvas.cpp +++ b/src/declarative/items/qsgcanvas.cpp @@ -174,7 +174,7 @@ void QSGCanvas::paintEvent(QPaintEvent *) int lastFrame = frameTimer.restart(); #endif - if (d->animationDriver->isRunning()) + if (d->animationDriver && d->animationDriver->isRunning()) d->animationDriver->advance(); #ifdef FRAME_TIMING @@ -222,10 +222,10 @@ void QSGCanvas::paintEvent(QPaintEvent *) QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Painting); - if (d->animationDriver->isRunning()) + if (d->animationDriver && d->animationDriver->isRunning()) update(); } else { - if (isUpdatesEnabled()) { + if (updatesEnabled()) { d->thread->paint(); setUpdatesEnabled(false); } @@ -252,12 +252,14 @@ void QSGCanvas::showEvent(QShowEvent *e) if (!d->contextFailed) { if (d->threadedRendering) { - if (!d->animationDriver) { - d->animationDriver = d->context->createAnimationDriver(this); - connect(d->animationDriver, SIGNAL(started()), d->thread, SLOT(animationStarted()), Qt::DirectConnection); - connect(d->animationDriver, SIGNAL(stopped()), d->thread, SLOT(animationStopped()), Qt::DirectConnection); + if (d->vsyncAnimations) { + if (!d->animationDriver) { + d->animationDriver = d->context->createAnimationDriver(this); + connect(d->animationDriver, SIGNAL(started()), d->thread, SLOT(animationStarted()), Qt::DirectConnection); + connect(d->animationDriver, SIGNAL(stopped()), d->thread, SLOT(animationStopped()), Qt::DirectConnection); + } + d->animationDriver->install(); } - d->animationDriver->install(); d->thread->startRenderThread(); setUpdatesEnabled(true); } else { @@ -265,11 +267,14 @@ void QSGCanvas::showEvent(QShowEvent *e) if (!d->context || !d->context->isReady()) { d->initializeSceneGraph(); - d->animationDriver = d->context->createAnimationDriver(this); - connect(d->animationDriver, SIGNAL(started()), this, SLOT(update())); + if (d->vsyncAnimations) { + d->animationDriver = d->context->createAnimationDriver(this); + connect(d->animationDriver, SIGNAL(started()), this, SLOT(update())); + } } - d->animationDriver->install(); + if (d->animationDriver) + d->animationDriver->install(); } } } @@ -283,12 +288,52 @@ void QSGCanvas::hideEvent(QHideEvent *e) d->thread->stopRenderThread(); } - d->animationDriver->uninstall(); + if (d->animationDriver) + d->animationDriver->uninstall(); } QGLWidget::hideEvent(e); } + + +/*! + Sets weither this canvas should use vsync driven animations. + + This option can only be set on one single QSGCanvas, and that it's + vsync signal will then be used to drive all animations in the + process. + + This feature is primarily useful for single QSGCanvas, QML-only + applications. + + \warning Enabling vsync on multiple QSGCanvas instances has + undefined behavior. + */ +void QSGCanvas::setVSyncAnimations(bool enabled) +{ + Q_D(QSGCanvas); + if (isVisible()) { + qWarning("QSGCanvas::setVSyncAnimations: Cannot be changed when widget is shown"); + return; + } + d->vsyncAnimations = enabled; +} + + + +/*! + Returns true if this canvas should use vsync driven animations; + otherwise returns false. + */ +bool QSGCanvas::vsyncAnimations() const +{ + Q_D(const QSGCanvas); + return d->vsyncAnimations; +} + + + void QSGCanvas::focusOutEvent(QFocusEvent *event) { Q_D(QSGCanvas); @@ -384,6 +429,7 @@ QSGCanvasPrivate::QSGCanvasPrivate() , threadedRendering(false) , animationRunning(false) , renderThreadAwakened(false) + , vsyncAnimations(false) , thread(0) , animationDriver(0) { @@ -958,7 +1004,7 @@ bool QSGCanvas::event(QEvent *e) d->thread->syncAlreadyHappened = false; - if (d->animationRunning) { + if (d->animationRunning && d->animationDriver) { #ifdef THREAD_DEBUG qDebug("GUI: Advancing animations...\n"); #endif @@ -2053,7 +2099,7 @@ void QSGCanvasRenderThread::run() // but we don't want to lock an extra time. wake(); - if (!d->animationRunning && !isExternalUpdatePending) { + if (!d->animationRunning && !isExternalUpdatePending && !shouldExit) { #ifdef THREAD_DEBUG printf(" RenderThread: nothing to do, going to sleep...\n"); #endif diff --git a/src/declarative/items/qsgcanvas.h b/src/declarative/items/qsgcanvas.h index d0d0c79d5e..8913e41b86 100644 --- a/src/declarative/items/qsgcanvas.h +++ b/src/declarative/items/qsgcanvas.h @@ -75,6 +75,9 @@ public: QSGEngine *sceneGraphEngine() const; + void setVSyncAnimations(bool enabled); + bool vsyncAnimations() const; + QImage grabFrameBuffer(); Q_SIGNALS: diff --git a/src/declarative/items/qsgcanvas_p.h b/src/declarative/items/qsgcanvas_p.h index 9b2683cc38..7f7182ee52 100644 --- a/src/declarative/items/qsgcanvas_p.h +++ b/src/declarative/items/qsgcanvas_p.h @@ -160,6 +160,8 @@ public: uint animationRunning: 1; uint renderThreadAwakened : 1; + uint vsyncAnimations : 1; + QSGCanvasRenderThread *thread; QSize widgetSize; QSize viewportSize; diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 72010c0ef2..43bb58c88a 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -650,6 +650,7 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine, out->dumpInstructions(); if (compilerStatDump()) dumpStats(); + Q_ASSERT(out->rootPropertyCache); } else { reset(out); } @@ -1230,6 +1231,11 @@ void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj) id.setId.index = obj->idIndex; output->addInstruction(id); } + + if (obj == unitRoot) { + output->rootPropertyCache = output->types[obj->type].createPropertyCache(engine); + output->rootPropertyCache->addref(); + } } bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj, diff --git a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp index be1f9e05af..fda16409b7 100644 --- a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp +++ b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp @@ -535,7 +535,7 @@ void tst_qdeclarativeinstruction::dump() << "25\t\tSTORE_VARIANT_OBJECT\t22" << "26\t\tSTORE_INTERFACE\t\t23" << "27\t\tSTORE_SIGNAL\t\t2\t3\t\t\"console.log(1921)\"" - << "28\t\tSTORE_SCRIPT_STRING\t24\t3\t1" + << "28\t\tSTORE_SCRIPT_STRING\t24\t3\t1\t0" << "29\t\tASSIGN_SIGNAL_OBJECT\t0\t\t\t\"mySignal\"" << "30\t\tASSIGN_CUSTOMTYPE\t25\t6\t9" << "31\t\tSTORE_BINDING\t26\t3\t2" diff --git a/tests/auto/declarative/qdeclarativelanguage/data/NestedComponentRoot.qml b/tests/auto/declarative/qdeclarativelanguage/data/NestedComponentRoot.qml new file mode 100644 index 0000000000..785a27dd79 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/NestedComponentRoot.qml @@ -0,0 +1,6 @@ +import QtQuick 1.0 + +Component { + Item { + } +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/nestedComponentRoots.qml b/tests/auto/declarative/qdeclarativelanguage/data/nestedComponentRoots.qml new file mode 100644 index 0000000000..361bcbcb56 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/nestedComponentRoots.qml @@ -0,0 +1,4 @@ +import QtQuick 1.0 + +NestedComponentRoot { +} diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 132c947d93..3c6ce9da6d 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -135,6 +135,7 @@ private slots: void reservedWords_data(); void reservedWords(); void inlineAssignmentsOverrideBindings(); + void nestedComponentRoots(); void basicRemote_data(); void basicRemote(); @@ -1428,6 +1429,12 @@ void tst_qdeclarativelanguage::inlineAssignmentsOverrideBindings() delete o; } +// QTBUG-19354 +void tst_qdeclarativelanguage::nestedComponentRoots() +{ + QDeclarativeComponent component(&engine, TEST_FILE("nestedComponentRoots.qml")); +} + // Import tests (QT-558) void tst_qdeclarativelanguage::importsBuiltin_data() { diff --git a/tests/auto/declarative/qdeclarativetextedit/data/mouseselection_multiline.qml b/tests/auto/declarative/qdeclarativetextedit/data/mouseselection_multiline.qml new file mode 100644 index 0000000000..af23f6d91c --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextedit/data/mouseselection_multiline.qml @@ -0,0 +1,8 @@ +import QtQuick 1.1 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRS\nTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextInput.SelectWords +} diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index 3f30a52204..8530c7f6ee 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -119,6 +119,7 @@ private slots: void moveCursorSelectionSequence(); void mouseSelection_data(); void mouseSelection(); + void multilineMouseSelection(); void deferEnableSelectByMouse_data(); void deferEnableSelectByMouse(); void deferDisableSelectByMouse_data(); @@ -1364,6 +1365,41 @@ void tst_qdeclarativetextedit::mouseSelection() delete canvas; } +void tst_qdeclarativetextedit::multilineMouseSelection() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/mouseselection_multiline.qml"); + + canvas->show(); + QApplication::setActiveWindow(canvas); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas)); + + QVERIFY(canvas->rootObject() != 0); + QDeclarativeTextEdit *textEditObject = qobject_cast<QDeclarativeTextEdit *>(canvas->rootObject()); + QVERIFY(textEditObject != 0); + + // press-and-drag from x1,y1 to x2,y1 + int x1 = 10; + int x2 = textEditObject->width() - 10; + int y1 = textEditObject->height() / 4; + int y2 = textEditObject->height() * 3 / 4; + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y1))); + QMouseEvent mv1(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y1)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv1); + QString str1 = textEditObject->selectedText(); + QVERIFY(str1.length() > 3); // don't reallly care *what* was selected (and it's too sensitive to platform) + + // drag-and-release from x2,y1 to x2,y2 + QMouseEvent mv2(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y2)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv2); + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y2))); + QString str2 = textEditObject->selectedText(); + QVERIFY(str1 != str2); + QVERIFY(str2.length() > 3); + + delete canvas; +} + void tst_qdeclarativetextedit::deferEnableSelectByMouse_data() { QTest::addColumn<QString>("qmlfile"); @@ -1639,6 +1675,26 @@ void tst_qdeclarativetextedit::cursorDelegate() QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); } + // Clear preedit text; + QInputMethodEvent event; + QApplication::sendEvent(view, &event); + + // Test delegate gets moved on mouse press. + textEditObject->setSelectByMouse(true); + textEditObject->setCursorPosition(0); + qDebug() << textEditObject->boundingRect() << textEditObject->positionToRectangle(5).center() << view->mapFromScene(textEditObject->positionToRectangle(5).center()); + QTest::mouseClick(view->viewport(), Qt::LeftButton, 0, view->mapFromScene(textEditObject->positionToRectangle(5).center())); + QVERIFY(textEditObject->cursorPosition() != 0); + QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); + QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + + textEditObject->setReadOnly(true); + textEditObject->setCursorPosition(0); + QTest::mouseClick(view->viewport(), Qt::LeftButton, 0, view->mapFromScene(textEditObject->positionToRectangle(5).center())); + QVERIFY(textEditObject->cursorPosition() != 0); + QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); + QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + textEditObject->setCursorPosition(0); QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp index f1f23af423..63b768ca33 100644 --- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp +++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp @@ -2439,15 +2439,20 @@ void tst_qdeclarativetextinput::preeditAutoScroll() QTest::qWaitForWindowShown(&view); QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view)); + QSignalSpy cursorRectangleSpy(&input, SIGNAL(cursorRectangleChanged())); + int cursorRectangleChanges = 0; + // test the text is scrolled so the preedit is visible. ic.sendPreeditText(preeditText.mid(0, 3), 1); QVERIFY(input.positionAt(0) != 0); QVERIFY(input.cursorRectangle().left() < input.boundingRect().width()); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); // test the text is scrolled back when the preedit is removed. ic.sendEvent(QInputMethodEvent()); QCOMPARE(input.positionAt(0), 0); QCOMPARE(input.positionAt(input.width()), 5); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); // some tolerance for different fonts. #ifdef Q_OS_LINUX @@ -2463,26 +2468,31 @@ void tst_qdeclarativetextinput::preeditAutoScroll() ic.sendPreeditText(preeditText, i + 1); QVERIFY(input.cursorRectangle().right() >= fm.width(preeditText.at(i)) - error); QVERIFY(input.positionToRectangle(0).x() < x); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); x = input.positionToRectangle(0).x(); } for (int i = 1; i >= 0; --i) { ic.sendPreeditText(preeditText, i + 1); QVERIFY(input.cursorRectangle().right() >= fm.width(preeditText.at(i)) - error); QVERIFY(input.positionToRectangle(0).x() > x); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); x = input.positionToRectangle(0).x(); } // Test incrementing the preedit cursor doesn't cause further // scrolling when right most text is visible. ic.sendPreeditText(preeditText, preeditText.length() - 3); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); x = input.positionToRectangle(0).x(); for (int i = 2; i >= 0; --i) { ic.sendPreeditText(preeditText, preeditText.length() - i); QCOMPARE(input.positionToRectangle(0).x(), x); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); } for (int i = 1; i < 3; ++i) { ic.sendPreeditText(preeditText, preeditText.length() - i); QCOMPARE(input.positionToRectangle(0).x(), x); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); } // Test disabling auto scroll. diff --git a/tests/benchmarks/declarative/declarative.pro b/tests/benchmarks/declarative/declarative.pro index a827978d63..f2dfdf971a 100644 --- a/tests/benchmarks/declarative/declarative.pro +++ b/tests/benchmarks/declarative/declarative.pro @@ -3,6 +3,7 @@ TEMPLATE = subdirs SUBDIRS += \ binding \ creation \ + javascript \ holistic \ pointers \ qdeclarativecomponent \ diff --git a/tests/benchmarks/declarative/javascript/data/NestedIdObject.qml b/tests/benchmarks/declarative/javascript/data/NestedIdObject.qml new file mode 100644 index 0000000000..410ee00ddc --- /dev/null +++ b/tests/benchmarks/declarative/javascript/data/NestedIdObject.qml @@ -0,0 +1,9 @@ +import QtQuick 1.0 + +QtObject { + function runtest() { + for (var ii = 0; ii < 5000000; ++ii) { + root + } + } +} diff --git a/tests/benchmarks/declarative/javascript/data/intQObjectProperty.qml b/tests/benchmarks/declarative/javascript/data/intQObjectProperty.qml new file mode 100644 index 0000000000..c3e6ebc16a --- /dev/null +++ b/tests/benchmarks/declarative/javascript/data/intQObjectProperty.qml @@ -0,0 +1,13 @@ +import Qt.test 1.0 + +TestObject { + id: root + + function runtest() { + var r = root; + + for (var ii = 0; ii < 5000000; ++ii) { + r.intValue + } + } +} diff --git a/tests/benchmarks/declarative/javascript/data/localId.qml b/tests/benchmarks/declarative/javascript/data/localId.qml new file mode 100644 index 0000000000..474d0760a3 --- /dev/null +++ b/tests/benchmarks/declarative/javascript/data/localId.qml @@ -0,0 +1,13 @@ +// Benchmarks the cost of accessing an id in the same file as the script. + +import QtQuick 1.0 + +QtObject { + id: root + + function runtest() { + for (var ii = 0; ii < 5000000; ++ii) { + root + } + } +} diff --git a/tests/benchmarks/declarative/javascript/data/nestedId.qml b/tests/benchmarks/declarative/javascript/data/nestedId.qml new file mode 100644 index 0000000000..49c4e3ca43 --- /dev/null +++ b/tests/benchmarks/declarative/javascript/data/nestedId.qml @@ -0,0 +1,13 @@ +// Benchmarks the cost of accessing an id in a parent context of the script. + +import QtQuick 1.0 + +QtObject { + id: root + + property variant object: NestedIdObject {} + function runtest() { + object.runtest(); + } +} + diff --git a/tests/benchmarks/declarative/javascript/data/stringQObjectProperty.qml b/tests/benchmarks/declarative/javascript/data/stringQObjectProperty.qml new file mode 100644 index 0000000000..ccd8a791b6 --- /dev/null +++ b/tests/benchmarks/declarative/javascript/data/stringQObjectProperty.qml @@ -0,0 +1,14 @@ +import Qt.test 1.0 + +TestObject { + id: root + + function runtest() { + var r = root; + + for (var ii = 0; ii < 5000000; ++ii) { + r.stringValue + } + } +} + diff --git a/tests/benchmarks/declarative/javascript/javascript.pro b/tests/benchmarks/declarative/javascript/javascript.pro new file mode 100644 index 0000000000..7395cef07e --- /dev/null +++ b/tests/benchmarks/declarative/javascript/javascript.pro @@ -0,0 +1,11 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_javascript +QT += declarative +macx:CONFIG -= app_bundle + +SOURCES += tst_javascript.cpp testtypes.cpp +HEADERS += testtypes.h + +# Define SRCDIR equal to test's source directory +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/benchmarks/declarative/javascript/testtypes.cpp b/tests/benchmarks/declarative/javascript/testtypes.cpp new file mode 100644 index 0000000000..f490b770fd --- /dev/null +++ b/tests/benchmarks/declarative/javascript/testtypes.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "testtypes.h" +#include <QtDeclarative/qdeclarative.h> + +void registerTypes() +{ + qmlRegisterType<TestObject>("Qt.test", 1,0, "TestObject"); +} diff --git a/tests/benchmarks/declarative/javascript/testtypes.h b/tests/benchmarks/declarative/javascript/testtypes.h new file mode 100644 index 0000000000..c89f10757b --- /dev/null +++ b/tests/benchmarks/declarative/javascript/testtypes.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TESTTYPES_H +#define TESTTYPES_H + +#include <QtCore/qobject.h> + +class TestObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int intValue READ intValue); + Q_PROPERTY(QString stringValue READ stringValue); + +public: + TestObject() : m_string("Hello world!") {} + + int intValue() const { return 13; } + QString stringValue() const { return m_string; } + +private: + QString m_string; +}; + +void registerTypes(); + +#endif // TESTTYPES_H diff --git a/tests/benchmarks/declarative/javascript/tst_javascript.cpp b/tests/benchmarks/declarative/javascript/tst_javascript.cpp new file mode 100644 index 0000000000..73c1d7c7ad --- /dev/null +++ b/tests/benchmarks/declarative/javascript/tst_javascript.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDir> +#include <QDebug> +#include <qtest.h> +#include <QDeclarativeEngine> +#include <QDeclarativeComponent> + +#include "testtypes.h" + +class tst_javascript : public QObject +{ + Q_OBJECT + +public: + tst_javascript(); + virtual ~tst_javascript(); + +private slots: + void run_data(); + void run(); + +private: + QDeclarativeEngine engine; +}; + +tst_javascript::tst_javascript() +{ + registerTypes(); +} + +tst_javascript::~tst_javascript() +{ +} + +void tst_javascript::run_data() +{ + QTest::addColumn<QString>("file"); + + QDir dir(SRCDIR "/data"); + + QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot); + + for (int ii = 0; ii < files.count(); ++ii) { + QString file = files.at(ii); + if (file.endsWith(".qml") && file.at(0).isLower()) { + + QString testName = file.left(file.length() - 4 /* strlen(".qml") */); + QString fileName = QLatin1String(SRCDIR) + QLatin1String("/data/") + file; + + + QTest::newRow(qPrintable(testName)) << fileName; + + } + } +} + +void tst_javascript::run() +{ + QFETCH(QString, file); + + QDeclarativeComponent c(&engine, file); + + if (c.isError()) { + qWarning() << c.errors(); + } + + QVERIFY(!c.isError()); + + QObject *o = c.create(); + QVERIFY(o != 0); + + QMetaMethod method = o->metaObject()->method(o->metaObject()->indexOfMethod("runtest()")); + + QBENCHMARK { + method.invoke(o); + } + + delete o; +} + +QTEST_MAIN(tst_javascript) + +#include "tst_javascript.moc" diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp index 765a9dc2fb..d351b27e7e 100644 --- a/tools/qmlscene/main.cpp +++ b/tools/qmlscene/main.cpp @@ -252,6 +252,7 @@ struct Options , scenegraphOnGraphicsview(false) , clip(false) , versionDetection(true) + , vsync(true) { } @@ -263,6 +264,7 @@ struct Options bool scenegraphOnGraphicsview; bool clip; bool versionDetection; + bool vsync; }; #if defined(QMLSCENE_BUNDLE) @@ -440,6 +442,7 @@ static void usage() qWarning(" --sg-on-gv [--clip] ....................... Scenegraph on graphicsview (and clip to item)"); #endif qWarning(" --no-version-detection .................... Do not try to detect the version of the .qml file"); + qWarning(" --no-vsync-animations ..................... Do not use vsync based animations"); qWarning(" "); exit(1); @@ -474,6 +477,8 @@ int main(int argc, char ** argv) options.versionDetection = false; else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("-i") && i + 1 < argc) imports.append(QString::fromLatin1(argv[++i])); + else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("--no-vsync-animations")) + options.vsync = false; else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("--help") || QString::fromLatin1(argv[i]).toLower() == QLatin1String("-help") || QString::fromLatin1(argv[i]).toLower() == QLatin1String("--h") @@ -520,6 +525,7 @@ int main(int argc, char ** argv) if (options.versionDetection) checkAndAdaptVersion(options.file); QSGView *qxView = new MyQSGView(); + qxView->setVSyncAnimations(options.vsync); engine = qxView->engine(); for (int i = 0; i < imports.size(); ++i) engine->addImportPath(imports.at(i)); |