From 32e8cef8f0792727134ee64f196529ed19f35d6a Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 21 Feb 2011 09:42:09 +1000 Subject: Ensure QDeclarativeListProperty docs are associated with QtDeclarative. There is a copy of QDeclarativeListProperty in qgraphicsitem_p.h, which confused qdoc. Change-Id: I159b5e51af11a8b5874b0ffeb923cbd67df86d0d Task-number: QTBUG-17555 --- src/declarative/qml/qdeclarativelist.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/declarative/qml/qdeclarativelist.cpp b/src/declarative/qml/qdeclarativelist.cpp index 9598d98..346fee5 100644 --- a/src/declarative/qml/qdeclarativelist.cpp +++ b/src/declarative/qml/qdeclarativelist.cpp @@ -88,6 +88,7 @@ void QDeclarativeListReferencePrivate::release() /*! \class QDeclarativeListReference \since 4.7 +\module QtDeclarative \brief The QDeclarativeListReference class allows the manipulation of QDeclarativeListProperty properties. QDeclarativeListReference allows C++ programs to read from, and assign values to a QML list property in a -- cgit v0.12 From f141b42b87e0835552c85dbfd1ccce950da5aee3 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Mon, 21 Feb 2011 09:50:19 +1000 Subject: Docs: fix inherits tag for SpringAnimation --- src/declarative/util/qdeclarativespringanimation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/util/qdeclarativespringanimation.cpp b/src/declarative/util/qdeclarativespringanimation.cpp index ec2b083..1212a1c 100644 --- a/src/declarative/util/qdeclarativespringanimation.cpp +++ b/src/declarative/util/qdeclarativespringanimation.cpp @@ -236,7 +236,7 @@ void QDeclarativeSpringAnimationPrivate::updateMode() /*! \qmlclass SpringAnimation QDeclarativeSpringAnimation \ingroup qml-animation-transition - \inherits Animation + \inherits NumberAnimation \since 4.7 \brief The SpringAnimation element allows a property to track a value in a spring-like motion. -- cgit v0.12 From 521a9bba59fe198ec7b1afe9bb25a9d3334675cf Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Mon, 14 Feb 2011 18:00:15 +1000 Subject: Forward mouse events from TextInput and TextEdit to QInputContext. This brings TextInput in line with QLineEdit. The fix for TextEdit applies equally to QTextEdit. Change-Id: I5c47e5c8e951ee53cb1fe45d9c302050cd19deef Task-number: QTBUG-15705 Reviewed-by: axis --- .../graphicsitems/qdeclarativetextedit.cpp | 36 +++--- .../graphicsitems/qdeclarativetextinput.cpp | 47 +++++++ .../graphicsitems/qdeclarativetextinput_p_p.h | 1 + src/gui/text/qtextcontrol.cpp | 120 +++++++++++------ src/gui/text/qtextcontrol_p_p.h | 20 ++- .../tst_qdeclarativetextedit.cpp | 142 ++++++++++++++++++++- .../tst_qdeclarativetextinput.cpp | 140 +++++++++++++++++++- 7 files changed, 442 insertions(+), 64 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index 87a49bd..2946f6e 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -975,6 +975,10 @@ void QDeclarativeTextEdit::setSelectByMouse(bool on) if (d->selectByMouse != on) { d->selectByMouse = on; setKeepMouseGrab(on); + if (on) + setTextInteractionFlags(d->control->textInteractionFlags() | Qt::TextSelectableByMouse); + else + setTextInteractionFlags(d->control->textInteractionFlags() & ~Qt::TextSelectableByMouse); emit selectByMouseChanged(on); } } @@ -1027,11 +1031,10 @@ void QDeclarativeTextEdit::setReadOnly(bool r) setFlag(QGraphicsItem::ItemAcceptsInputMethod, !r); Qt::TextInteractionFlags flags = Qt::LinksAccessibleByMouse; - if (r) { + if (d->selectByMouse) flags = flags | Qt::TextSelectableByMouse; - } else { - flags = flags | Qt::TextEditorInteraction; - } + if (!r) + flags = flags | Qt::TextSelectableByKeyboard | Qt::TextEditable; d->control->setTextInteractionFlags(flags); if (!r) d->control->moveCursor(QTextCursor::End); @@ -1249,8 +1252,8 @@ void QDeclarativeTextEdit::mousePressEvent(QGraphicsSceneMouseEvent *event) } } } - if (event->type() != QEvent::GraphicsSceneMouseDoubleClick || d->selectByMouse) - d->control->processEvent(event, QPointF(0, -d->yoff)); + + d->control->processEvent(event, QPointF(0, -d->yoff)); if (!event->isAccepted()) QDeclarativePaintedItem::mousePressEvent(event); } @@ -1285,13 +1288,11 @@ Handles the given mouse \a event. void QDeclarativeTextEdit::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextEdit); - if (d->selectByMouse) { - d->control->processEvent(event, QPointF(0, -d->yoff)); - if (!event->isAccepted()) - QDeclarativePaintedItem::mouseDoubleClickEvent(event); - } else { + + d->control->processEvent(event, QPointF(0, -d->yoff)); + if (!event->isAccepted()) QDeclarativePaintedItem::mouseDoubleClickEvent(event); - } + } /*! @@ -1301,14 +1302,9 @@ Handles the given mouse \a event. void QDeclarativeTextEdit::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextEdit); - if (d->selectByMouse) { - d->control->processEvent(event, QPointF(0, -d->yoff)); - if (!event->isAccepted()) - QDeclarativePaintedItem::mouseMoveEvent(event); - event->setAccepted(true); - } else { + d->control->processEvent(event, QPointF(0, -d->yoff)); + if (!event->isAccepted()) QDeclarativePaintedItem::mouseMoveEvent(event); - } } /*! @@ -1407,7 +1403,7 @@ void QDeclarativeTextEditPrivate::init() control = new QTextControl(q); control->setIgnoreUnusedNavigationEvents(true); - control->setTextInteractionFlags(control->textInteractionFlags() | Qt::LinksAccessibleByMouse); + control->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard | Qt::TextEditable); control->setDragEnabled(false); // QTextControl follows the default text color diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index e7c2ac7..bfcd715 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #ifndef QT_NO_LINEEDIT @@ -1002,6 +1003,8 @@ Handles the given mouse \a event. void QDeclarativeTextInput::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextInput); + if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonDblClick)) + return; if (d->selectByMouse) { int cursor = d->xToPos(event->pos().x()); d->control->selectWordAtPos(cursor); @@ -1014,6 +1017,8 @@ void QDeclarativeTextInput::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *even void QDeclarativeTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextInput); + if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonPress)) + return; if(d->focusOnPress){ bool hadActiveFocus = hasActiveFocus(); forceActiveFocus(); @@ -1041,6 +1046,8 @@ void QDeclarativeTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event) void QDeclarativeTextInput::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextInput); + if (d->sendMouseEventToInputContext(event, QEvent::MouseMove)) + event->setAccepted(true); if (d->selectByMouse) { if (qAbs(int(event->pos().x() - d->pressPos.x())) > QApplication::startDragDistance()) setKeepMouseGrab(true); @@ -1058,6 +1065,8 @@ Handles the given mouse \a event. void QDeclarativeTextInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextInput); + if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonRelease)) + return; if (d->selectByMouse) setKeepMouseGrab(false); if (!d->showInputPanelOnFocus) { // input panel on click @@ -1075,6 +1084,44 @@ void QDeclarativeTextInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QDeclarativePaintedItem::mouseReleaseEvent(event); } +bool QDeclarativeTextInputPrivate::sendMouseEventToInputContext( + QGraphicsSceneMouseEvent *event, QEvent::Type eventType) +{ +#if !defined QT_NO_IM + if (event->widget() && control->composeMode()) { + int tmp_cursor = xToPos(event->pos().x()); + int mousePos = tmp_cursor - control->cursor(); + if (mousePos < 0 || mousePos > control->preeditAreaText().length()) { + mousePos = -1; + // don't send move events outside the preedit area + if (eventType == QEvent::MouseMove) + return true; + } + + QInputContext *qic = event->widget()->inputContext(); + if (qic) { + QMouseEvent mouseEvent( + eventType, + event->widget()->mapFromGlobal(event->screenPos()), + event->screenPos(), + event->button(), + event->buttons(), + event->modifiers()); + // may be causing reset() in some input methods + qic->mouseHandler(mousePos, &mouseEvent); + event->setAccepted(mouseEvent.isAccepted()); + } + if (!control->preeditAreaText().isEmpty()) + return true; + } +#else + Q_UNUSED(event); + Q_UNUSED(eventType) +#endif + + return false; +} + bool QDeclarativeTextInput::sceneEvent(QEvent *event) { bool rv = QDeclarativeItem::sceneEvent(event); diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h index f7446b4..ab2838b 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h @@ -104,6 +104,7 @@ public: void focusChanged(bool hasFocus); void updateHorizontalScroll(); int calculateTextWidth(); + bool sendMouseEventToInputContext(QGraphicsSceneMouseEvent *event, QEvent::Type eventType); QLineControl* control; diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index e380b37..b25588d 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -932,15 +932,18 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte break; } case QEvent::MouseMove: { QMouseEvent *ev = static_cast(e); - d->mouseMoveEvent(ev->buttons(), matrix.map(ev->pos())); + d->mouseMoveEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), + ev->buttons(), ev->globalPos()); break; } case QEvent::MouseButtonRelease: { QMouseEvent *ev = static_cast(e); - d->mouseReleaseEvent(ev->button(), matrix.map(ev->pos())); + d->mouseReleaseEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), + ev->buttons(), ev->globalPos()); break; } case QEvent::MouseButtonDblClick: { QMouseEvent *ev = static_cast(e); - d->mouseDoubleClickEvent(e, ev->button(), matrix.map(ev->pos())); + d->mouseDoubleClickEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), + ev->buttons(), ev->globalPos()); break; } case QEvent::InputMethod: d->inputMethodEvent(static_cast(e)); @@ -1000,15 +1003,18 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte break; } case QEvent::GraphicsSceneMouseMove: { QGraphicsSceneMouseEvent *ev = static_cast(e); - d->mouseMoveEvent(ev->buttons(), matrix.map(ev->pos())); + d->mouseMoveEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(), + ev->screenPos()); break; } case QEvent::GraphicsSceneMouseRelease: { QGraphicsSceneMouseEvent *ev = static_cast(e); - d->mouseReleaseEvent(ev->button(), matrix.map(ev->pos())); + d->mouseReleaseEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(), + ev->screenPos()); break; } case QEvent::GraphicsSceneMouseDoubleClick: { QGraphicsSceneMouseEvent *ev = static_cast(e); - d->mouseDoubleClickEvent(e, ev->button(), matrix.map(ev->pos())); + d->mouseDoubleClickEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(), + ev->screenPos()); break; } case QEvent::GraphicsSceneContextMenu: { QGraphicsSceneContextMenuEvent *ev = static_cast(e); @@ -1017,7 +1023,8 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte case QEvent::GraphicsSceneHoverMove: { QGraphicsSceneHoverEvent *ev = static_cast(e); - d->mouseMoveEvent(Qt::NoButton, matrix.map(ev->pos())); + d->mouseMoveEvent(ev, Qt::NoButton, matrix.map(ev->pos()), ev->modifiers(),Qt::NoButton, + ev->screenPos()); break; } case QEvent::GraphicsSceneDragEnter: { @@ -1487,6 +1494,11 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con { Q_Q(QTextControl); + if (sendMouseEventToInputContext( + e, QEvent::MouseButtonPress, button, pos, modifiers, buttons, globalPos)) { + return; + } + if (interactionFlags & Qt::LinksAccessibleByMouse) { anchorOnMousePress = q->anchorAt(pos); @@ -1529,22 +1541,7 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con return; } -#if !defined(QT_NO_IM) - QTextLayout *layout = cursor.block().layout(); - if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) { - QInputContext *ctx = inputContext(); - if (ctx) { - QMouseEvent ev(QEvent::MouseButtonPress, contextWidget->mapFromGlobal(globalPos), globalPos, - button, buttons, modifiers); - ctx->mouseHandler(cursorPos - cursor.position(), &ev); - } - if (!layout->preeditAreaText().isEmpty()) { - e->ignore(); - return; - } - } -#endif - if (modifiers == Qt::ShiftModifier) { + if (modifiers == Qt::ShiftModifier && (interactionFlags & Qt::TextSelectableByMouse)) { if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) { selectedWordOnDoubleClick = cursor; selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor); @@ -1589,10 +1586,16 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con hadSelectionOnMousePress = cursor.hasSelection(); } -void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF &mousePos) +void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, const QPointF &mousePos, Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, const QPoint &globalPos) { Q_Q(QTextControl); + if (sendMouseEventToInputContext( + e, QEvent::MouseMove, button, mousePos, modifiers, buttons, globalPos)) { + return; + } + if (interactionFlags & Qt::LinksAccessibleByMouse) { QString anchor = q->anchorAt(mousePos); if (anchor != highlightedAnchor) { @@ -1622,12 +1625,6 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF } const qreal mouseX = qreal(mousePos.x()); -#if !defined(QT_NO_IM) - QTextLayout *layout = cursor.block().layout(); - if (layout && !layout->preeditAreaText().isEmpty()) - return; -#endif - int newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit); if (newCursorPos == -1) return; @@ -1641,7 +1638,7 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF extendBlockwiseSelection(newCursorPos); else if (selectedWordOnDoubleClick.hasSelection()) extendWordwiseSelection(newCursorPos, mouseX); - else + else if (interactionFlags & Qt::TextSelectableByMouse) setCursorPosition(newCursorPos, QTextCursor::KeepAnchor); if (interactionFlags & Qt::TextEditable) { @@ -1665,10 +1662,16 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF repaintOldAndNewSelection(oldSelection); } -void QTextControlPrivate::mouseReleaseEvent(Qt::MouseButton button, const QPointF &pos) +void QTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, const QPoint &globalPos) { Q_Q(QTextControl); + if (sendMouseEventToInputContext( + e, QEvent::MouseButtonRelease, button, pos, modifiers, buttons, globalPos)) { + return; + } + const QTextCursor oldSelection = cursor; const int oldCursorPos = cursor.position(); @@ -1726,19 +1729,21 @@ void QTextControlPrivate::mouseReleaseEvent(Qt::MouseButton button, const QPoint } } -void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos) +void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, const QPoint &globalPos) { Q_Q(QTextControl); + + if (sendMouseEventToInputContext( + e, QEvent::MouseButtonDblClick, button, pos, modifiers, buttons, globalPos)) { + return; + } + if (button != Qt::LeftButton || !(interactionFlags & Qt::TextSelectableByMouse)) { e->ignore(); return; } -#if !defined(QT_NO_IM) - QTextLayout *layout = cursor.block().layout(); - if (layout && !layout->preeditAreaText().isEmpty()) - return; -#endif #ifndef QT_NO_DRAGANDDROP mightStartDrag = false; @@ -1767,6 +1772,45 @@ void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton butto } } +bool QTextControlPrivate::sendMouseEventToInputContext( + QEvent *e, QEvent::Type eventType, Qt::MouseButton button, const QPointF &pos, + Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, const QPoint &globalPos) +{ +#if !defined(QT_NO_IM) + Q_Q(QTextControl); + + QTextLayout *layout = cursor.block().layout(); + if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) { + QInputContext *ctx = inputContext(); + int cursorPos = q->hitTest(pos, Qt::FuzzyHit) - cursor.position(); + + if (cursorPos < 0 || cursorPos > layout->preeditAreaText().length()) { + cursorPos = -1; + // don't send move events outside the preedit area + if (eventType == QEvent::MouseMove) + return true; + } + if (ctx) { + QMouseEvent ev(eventType, contextWidget->mapFromGlobal(globalPos), globalPos, + button, buttons, modifiers); + ctx->mouseHandler(cursorPos, &ev); + e->setAccepted(ev.isAccepted()); + } + if (!layout->preeditAreaText().isEmpty()) + return true; + } +#else + Q_UNUSED(e); + Q_UNUSED(eventType); + Q_UNUSED(button); + Q_UNUSED(pos); + Q_UNUSED(modifiers); + Q_UNUSED(buttons); + Q_UNUSED(globalPos); +#endif + return false; +} + void QTextControlPrivate::contextMenuEvent(const QPoint &screenPos, const QPointF &docPos, QWidget *contextWidget) { #ifdef QT_NO_CONTEXTMENU diff --git a/src/gui/text/qtextcontrol_p_p.h b/src/gui/text/qtextcontrol_p_p.h index ecd13ea..94670e2 100644 --- a/src/gui/text/qtextcontrol_p_p.h +++ b/src/gui/text/qtextcontrol_p_p.h @@ -135,9 +135,23 @@ public: Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, const QPoint &globalPos); - void mouseMoveEvent(Qt::MouseButtons buttons, const QPointF &pos); - void mouseReleaseEvent(Qt::MouseButton button, const QPointF &pos); - void mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos); + void mouseMoveEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, + Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, + const QPoint &globalPos); + void mouseReleaseEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, + Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, + const QPoint &globalPos); + void mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, + Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, + const QPoint &globalPos); + bool sendMouseEventToInputContext(QEvent *e, QEvent::Type eventType, Qt::MouseButton button, + const QPointF &pos, + Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, + const QPoint &globalPos); void contextMenuEvent(const QPoint &screenPos, const QPointF &docPos, QWidget *contextWidget); void focusEvent(QFocusEvent *e); #ifdef QT_KEYPAD_NAVIGATION diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index a052752..f74a27d 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -138,6 +138,7 @@ private slots: void testQtQuick11Attributes_data(); void preeditMicroFocus(); + void inputContextMouseHandler(); private: void simulateKey(QDeclarativeView *, int key); @@ -1464,7 +1465,7 @@ QDeclarativeView *tst_qdeclarativetextedit::createView(const QString &filename) class MyInputContext : public QInputContext { public: - MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false) {} + MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false), eventType(QEvent::None) {} ~MyInputContext() {} QString identifierName() { return QString(); } @@ -1495,9 +1496,27 @@ public: sendEvent(event); } + void mouseHandler(int x, QMouseEvent *event) + { + cursor = x; + eventType = event->type(); + eventPosition = event->pos(); + eventGlobalPosition = event->globalPos(); + eventButton = event->button(); + eventButtons = event->buttons(); + eventModifiers = event->modifiers(); + } + bool openInputPanelReceived; bool closeInputPanelReceived; bool updateReceived; + int cursor; + QEvent::Type eventType; + QPoint eventPosition; + QPoint eventGlobalPosition; + Qt::MouseButton eventButton; + Qt::MouseButtons eventButtons; + Qt::KeyboardModifiers eventModifiers; }; void tst_qdeclarativetextedit::textInput() @@ -1824,7 +1843,6 @@ void tst_qdeclarativetextedit::preeditMicroFocus() MyInputContext ic; view.setInputContext(&ic); QDeclarativeTextEdit edit; - edit.setPos(0, 0); edit.setFocus(true); scene.addItem(&edit); view.show(); @@ -1870,6 +1888,126 @@ void tst_qdeclarativetextedit::preeditMicroFocus() #endif } +void tst_qdeclarativetextedit::inputContextMouseHandler() +{ + QString text = "supercalifragisiticexpialidocious!"; + + QGraphicsScene scene; + QGraphicsView view(&scene); + MyInputContext ic; + view.setInputContext(&ic); + QDeclarativeTextEdit edit; + edit.setPos(0, 0); + edit.setWidth(200); + edit.setText(text.mid(0, 5)); + edit.setPos(0, 0); + edit.setCursorPosition(5); + edit.setFocus(true); + scene.addItem(&edit); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&view)); + view.setFocus(); + + QFontMetricsF fm(edit.font()); + const qreal y = fm.height() / 2; + + QPoint position2 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 2)), y))); + QPoint position4 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 4)), y))); + QPoint position7 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 7)), y))); + QPoint position12 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 12)), y))); + QPoint globalPosition2 = view.viewport()->mapToGlobal(position2); + QPoint globalPosition4 = view.viewport()->mapToGlobal(position4); + QPoint globalPosition7 = view.viewport()->mapToGlobal(position7); + QPoint globalPosition12 = view.viewport()->mapToGlobal(position12); + + ic.sendEvent(QInputMethodEvent(text.mid(5), QList())); + + QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2); + QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick); + QCOMPARE(ic.eventPosition, position2); + QCOMPARE(ic.eventGlobalPosition, globalPosition2); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::NoModifier); + QVERIFY(ic.cursor < 0); + ic.eventType = QEvent::None; + + QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2); + QCOMPARE(ic.eventType, QEvent::MouseButtonPress); + QCOMPARE(ic.eventPosition, position2); + QCOMPARE(ic.eventGlobalPosition, globalPosition2); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::NoModifier); + QVERIFY(ic.cursor < 0); + ic.eventType = QEvent::None; + + { QMouseEvent mv(QEvent::MouseMove, position4, globalPosition4, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(view.viewport(), &mv); } + QCOMPARE(ic.eventType, QEvent::None); + + { QMouseEvent mv(QEvent::MouseMove, position12, globalPosition12, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(view.viewport(), &mv); } + QCOMPARE(ic.eventType, QEvent::MouseMove); + QCOMPARE(ic.eventPosition, position12); + QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::NoModifier); + QCOMPARE(ic.cursor, 7); + ic.eventType = QEvent::None; + + QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position12); + QCOMPARE(ic.eventType, QEvent::MouseButtonRelease); + QCOMPARE(ic.eventPosition, position12); + QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::NoModifier); + QCOMPARE(ic.cursor, 7); + ic.eventType = QEvent::None; + + // And in the other direction. + QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position12); + QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick); + QCOMPARE(ic.eventPosition, position12); + QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::ControlModifier); + QCOMPARE(ic.cursor, 7); + ic.eventType = QEvent::None; + + QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position12); + QCOMPARE(ic.eventType, QEvent::MouseButtonPress); + QCOMPARE(ic.eventPosition, position12); + QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventButton, Qt::RightButton); + QCOMPARE(ic.eventModifiers, Qt::ControlModifier); + QCOMPARE(ic.cursor, 7); + ic.eventType = QEvent::None; + + { QMouseEvent mv(QEvent::MouseMove, position7, globalPosition7, Qt::RightButton, Qt::RightButton,Qt::ControlModifier); + QApplication::sendEvent(view.viewport(), &mv); } + QCOMPARE(ic.eventType, QEvent::MouseMove); + QCOMPARE(ic.eventPosition, position7); + QCOMPARE(ic.eventGlobalPosition, globalPosition7); + QCOMPARE(ic.eventButton, Qt::RightButton); + QCOMPARE(ic.eventModifiers, Qt::ControlModifier); + QCOMPARE(ic.cursor, 2); + ic.eventType = QEvent::None; + + { QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier); + QApplication::sendEvent(view.viewport(), &mv); } + QCOMPARE(ic.eventType, QEvent::None); + + QTest::mouseRelease(view.viewport(), Qt::RightButton, Qt::ControlModifier, position2); + QCOMPARE(ic.eventType, QEvent::MouseButtonRelease); + QCOMPARE(ic.eventPosition, position2); + QCOMPARE(ic.eventGlobalPosition, globalPosition2); + QCOMPARE(ic.eventButton, Qt::RightButton); + QCOMPARE(ic.eventModifiers, Qt::ControlModifier); + QVERIFY(ic.cursor < 0); + ic.eventType = QEvent::None; +} + QTEST_MAIN(tst_qdeclarativetextedit) #include "tst_qdeclarativetextedit.moc" diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp index 7753f11..b601af8 100644 --- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp +++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp @@ -126,6 +126,7 @@ private slots: void preeditAutoScroll(); void preeditMicroFocus(); + void inputContextMouseHandler(); private: void simulateKey(QDeclarativeView *, int key); @@ -1420,7 +1421,7 @@ QDeclarativeView *tst_qdeclarativetextinput::createView(const QString &filename) class MyInputContext : public QInputContext { public: - MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false) {} + MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false), eventType(QEvent::None) {} ~MyInputContext() {} QString identifierName() { return QString(); } @@ -1441,6 +1442,17 @@ public: void update() { updateReceived = true; } + void mouseHandler(int x, QMouseEvent *event) + { + cursor = x; + eventType = event->type(); + eventPosition = event->pos(); + eventGlobalPosition = event->globalPos(); + eventButton = event->button(); + eventButtons = event->buttons(); + eventModifiers = event->modifiers(); + } + void sendPreeditText(const QString &text, int cursor) { QList attributes; @@ -1454,6 +1466,13 @@ public: bool openInputPanelReceived; bool closeInputPanelReceived; bool updateReceived; + int cursor; + QEvent::Type eventType; + QPoint eventPosition; + QPoint eventGlobalPosition; + Qt::MouseButton eventButton; + Qt::MouseButtons eventButtons; + Qt::KeyboardModifiers eventModifiers; }; void tst_qdeclarativetextinput::openInputPanelOnClick() @@ -1859,6 +1878,125 @@ void tst_qdeclarativetextinput::preeditMicroFocus() #endif } +void tst_qdeclarativetextinput::inputContextMouseHandler() +{ + QString text = "supercalifragisiticexpialidocious!"; + + QGraphicsScene scene; + QGraphicsView view(&scene); + MyInputContext ic; + view.setInputContext(&ic); + QDeclarativeTextInput input; + input.setWidth(200); + input.setText(text.mid(0, 5)); + input.setPos(0, 0); + input.setFocus(true); + scene.addItem(&input); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&view)); + + ic.sendEvent(QInputMethodEvent(text.mid(5), QList())); + + QFontMetricsF fm(input.font()); + const qreal y = fm.height() / 2; + + QPoint position2 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 2)), y))); + QPoint position4 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 4)), y))); + QPoint position7 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 7)), y))); + QPoint position12 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 12)), y))); + QPoint globalPosition2 = view.viewport()->mapToGlobal(position2); + QPoint globalPosition4 = view.viewport()->mapToGlobal(position4); + QPoint globalPosition7 = view.viewport()->mapToGlobal(position7); + QPoint globalPosition12 = view.viewport()->mapToGlobal(position12); + + ic.sendEvent(QInputMethodEvent(text.mid(5), QList())); + + QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2); + QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick); + QCOMPARE(ic.eventPosition, position2); + QCOMPARE(ic.eventGlobalPosition, globalPosition2); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::NoModifier); + QVERIFY(ic.cursor < 0); + ic.eventType = QEvent::None; + + QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2); + QCOMPARE(ic.eventType, QEvent::MouseButtonPress); + QCOMPARE(ic.eventPosition, position2); + QCOMPARE(ic.eventGlobalPosition, globalPosition2); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::NoModifier); + QVERIFY(ic.cursor < 0); + ic.eventType = QEvent::None; + + { QMouseEvent mv(QEvent::MouseMove, position4, globalPosition4, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(view.viewport(), &mv); } + QCOMPARE(ic.eventType, QEvent::None); + + { QMouseEvent mv(QEvent::MouseMove, position12, globalPosition12, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(view.viewport(), &mv); } + QCOMPARE(ic.eventType, QEvent::MouseMove); + QCOMPARE(ic.eventPosition, position12); + QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::NoModifier); + QCOMPARE(ic.cursor, 7); + ic.eventType = QEvent::None; + + QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position12); + QCOMPARE(ic.eventType, QEvent::MouseButtonRelease); + QCOMPARE(ic.eventPosition, position12); + QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::NoModifier); + QCOMPARE(ic.cursor, 7); + ic.eventType = QEvent::None; + + // And in the other direction. + QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position12); + QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick); + QCOMPARE(ic.eventPosition, position12); + QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventButton, Qt::LeftButton); + QCOMPARE(ic.eventModifiers, Qt::ControlModifier); + QCOMPARE(ic.cursor, 7); + ic.eventType = QEvent::None; + + QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position12); + QCOMPARE(ic.eventType, QEvent::MouseButtonPress); + QCOMPARE(ic.eventPosition, position12); + QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventButton, Qt::RightButton); + QCOMPARE(ic.eventModifiers, Qt::ControlModifier); + QCOMPARE(ic.cursor, 7); + ic.eventType = QEvent::None; + + { QMouseEvent mv(QEvent::MouseMove, position7, globalPosition7, Qt::RightButton, Qt::RightButton,Qt::ControlModifier); + QApplication::sendEvent(view.viewport(), &mv); } + QCOMPARE(ic.eventType, QEvent::MouseMove); + QCOMPARE(ic.eventPosition, position7); + QCOMPARE(ic.eventGlobalPosition, globalPosition7); + QCOMPARE(ic.eventButton, Qt::RightButton); + QCOMPARE(ic.eventModifiers, Qt::ControlModifier); + QCOMPARE(ic.cursor, 2); + ic.eventType = QEvent::None; + + { QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier); + QApplication::sendEvent(view.viewport(), &mv); } + QCOMPARE(ic.eventType, QEvent::None); + + QTest::mouseRelease(view.viewport(), Qt::RightButton, Qt::ControlModifier, position2); + QCOMPARE(ic.eventType, QEvent::MouseButtonRelease); + QCOMPARE(ic.eventPosition, position2); + QCOMPARE(ic.eventGlobalPosition, globalPosition2); + QCOMPARE(ic.eventButton, Qt::RightButton); + QCOMPARE(ic.eventModifiers, Qt::ControlModifier); + QVERIFY(ic.cursor < 0); + ic.eventType = QEvent::None; +} + QTEST_MAIN(tst_qdeclarativetextinput) #include "tst_qdeclarativetextinput.moc" -- cgit v0.12 From fd198736e1da02f535bc81d9934cb4e8412a87bc Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Wed, 16 Feb 2011 13:33:52 +1000 Subject: Hide the TextInput/Edit cursor when the view doesn't have focus. Only display a cursor if both the item and its scene have focus. Change-Id: I0c91ab4d533cd7d773ffc2489633e12c0d399ad9 Task-number: QTBUG-17365 Reviewed-by: Martin Jones --- .../graphicsitems/qdeclarativetextedit.cpp | 2 +- .../graphicsitems/qdeclarativetextinput.cpp | 2 +- .../tst_qdeclarativetextedit.cpp | 71 ++++++++++++++++++++++ .../tst_qdeclarativetextinput.cpp | 70 +++++++++++++++++++++ 4 files changed, 143 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index 2946f6e..83c7420 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -1126,7 +1126,7 @@ void QDeclarativeTextEdit::keyReleaseEvent(QKeyEvent *event) void QDeclarativeTextEditPrivate::focusChanged(bool hasFocus) { Q_Q(QDeclarativeTextEdit); - q->setCursorVisible(hasFocus); + q->setCursorVisible(hasFocus && scene && scene->hasFocus()); QDeclarativeItemPrivate::focusChanged(hasFocus); } diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index bfcd715..ba1ae63 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -948,7 +948,7 @@ void QDeclarativeTextInputPrivate::focusChanged(bool hasFocus) { Q_Q(QDeclarativeTextInput); focused = hasFocus; - q->setCursorVisible(hasFocus); + q->setCursorVisible(hasFocus && scene && scene->hasFocus()); if(q->echoMode() == QDeclarativeTextInput::PasswordEchoOnEdit && !hasFocus) control->updatePasswordEchoEditing(false);//QLineControl sets it on key events, but doesn't deal with focus events if (!hasFocus) diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index f74a27d..ba410ce 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -122,6 +122,7 @@ private slots: void inputMethodHints(); void cursorDelegate(); + void cursorVisible(); void delegateLoading_data(); void delegateLoading(); void navigation(); @@ -1277,6 +1278,76 @@ void tst_qdeclarativetextedit::cursorDelegate() delete view; } +void tst_qdeclarativetextedit::cursorVisible() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&view)); + view.setFocus(); + + QDeclarativeTextEdit edit; + QSignalSpy spy(&edit, SIGNAL(cursorVisibleChanged(bool))); + + QCOMPARE(edit.isCursorVisible(), false); + + edit.setCursorVisible(true); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 1); + + edit.setCursorVisible(false); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 2); + + edit.setFocus(true); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 2); + + scene.addItem(&edit); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 3); + + edit.setFocus(false); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 4); + + edit.setFocus(true); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 5); + + scene.clearFocus(); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 6); + + scene.setFocus(); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 7); + + view.clearFocus(); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 8); + + view.setFocus(); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 9); + + // on mac, setActiveWindow(0) on mac does not deactivate the current application + // (you have to switch to a different app or hide the current app to trigger this) +#if !defined(Q_WS_MAC) + QApplication::setActiveWindow(0); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(0)); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 10); + + QApplication::setActiveWindow(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&view)); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 11); +#endif +} + void tst_qdeclarativetextedit::delegateLoading_data() { QTest::addColumn("qmlfile"); diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp index b601af8..b8f73bd 100644 --- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp +++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp @@ -110,6 +110,7 @@ private slots: void passwordCharacter(); void cursorDelegate(); + void cursorVisible(); void navigation(); void copyAndPaste(); void readOnly(); @@ -1316,6 +1317,75 @@ void tst_qdeclarativetextinput::cursorDelegate() delete view; } +void tst_qdeclarativetextinput::cursorVisible() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&view)); + + QDeclarativeTextInput input; + QSignalSpy spy(&input, SIGNAL(cursorVisibleChanged(bool))); + + QCOMPARE(input.isCursorVisible(), false); + + input.setCursorVisible(true); + QCOMPARE(input.isCursorVisible(), true); + QCOMPARE(spy.count(), 1); + + input.setCursorVisible(false); + QCOMPARE(input.isCursorVisible(), false); + QCOMPARE(spy.count(), 2); + + input.setFocus(true); + QCOMPARE(input.isCursorVisible(), false); + QCOMPARE(spy.count(), 2); + + scene.addItem(&input); + QCOMPARE(input.isCursorVisible(), true); + QCOMPARE(spy.count(), 3); + + input.setFocus(false); + QCOMPARE(input.isCursorVisible(), false); + QCOMPARE(spy.count(), 4); + + input.setFocus(true); + QCOMPARE(input.isCursorVisible(), true); + QCOMPARE(spy.count(), 5); + + scene.clearFocus(); + QCOMPARE(input.isCursorVisible(), false); + QCOMPARE(spy.count(), 6); + + scene.setFocus(); + QCOMPARE(input.isCursorVisible(), true); + QCOMPARE(spy.count(), 7); + + view.clearFocus(); + QCOMPARE(input.isCursorVisible(), false); + QCOMPARE(spy.count(), 8); + + view.setFocus(); + QCOMPARE(input.isCursorVisible(), true); + QCOMPARE(spy.count(), 9); + + // on mac, setActiveWindow(0) on mac does not deactivate the current application + // (you have to switch to a different app or hide the current app to trigger this) +#if !defined(Q_WS_MAC) + QApplication::setActiveWindow(0); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(0)); + QCOMPARE(input.isCursorVisible(), false); + QCOMPARE(spy.count(), 10); + + QApplication::setActiveWindow(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&view)); + QCOMPARE(input.isCursorVisible(), true); + QCOMPARE(spy.count(), 11); +#endif +} + void tst_qdeclarativetextinput::readOnly() { QDeclarativeView *canvas = createView(SRCDIR "/data/readOnly.qml"); -- cgit v0.12 From 8e9c28eaa4d7a3372b9a9a21a984701b62f96456 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Fri, 18 Feb 2011 13:52:10 +1000 Subject: Ensure animations start correctly when running is bound to a value. Animations register to be started when the component is finalized, but in the case of a binding, the registration doesn't happen until we are already working with a copy of the finalization list. With this patch, we no longer work with a copy, but with the actual list. Change-Id: If460c250d2403590907e9ac854d277db68ba8b2a Task-number: QTBUG-14042 Reviewed-by: Aaron Kennedy --- src/declarative/qml/qdeclarativecomponent.cpp | 23 ++++++++++------------ src/declarative/qml/qdeclarativecomponent_p.h | 1 - src/declarative/qml/qdeclarativevme.cpp | 1 - .../data/registrationBug.qml | 18 +++++++++++++++++ .../tst_qdeclarativeanimations.cpp | 12 +++++++++++ 5 files changed, 40 insertions(+), 15 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeanimations/data/registrationBug.qml diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index 5840f70..cf40182 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -870,7 +870,6 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentCon state->bindValues = enginePriv->bindValues; state->parserStatus = enginePriv->parserStatus; - state->finalizedParserStatus = enginePriv->finalizedParserStatus; state->componentAttached = enginePriv->componentAttached; if (state->componentAttached) state->componentAttached->prev = &state->componentAttached; @@ -878,7 +877,6 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentCon enginePriv->componentAttached = 0; enginePriv->bindValues.clear(); enginePriv->parserStatus.clear(); - enginePriv->finalizedParserStatus.clear(); state->completePending = true; enginePriv->inProgressCreations++; } @@ -909,7 +907,6 @@ void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeEnginePrivate *engi state->bindValues = enginePriv->bindValues; state->parserStatus = enginePriv->parserStatus; - state->finalizedParserStatus = enginePriv->finalizedParserStatus; state->componentAttached = enginePriv->componentAttached; if (state->componentAttached) state->componentAttached->prev = &state->componentAttached; @@ -917,7 +914,6 @@ void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeEnginePrivate *engi enginePriv->componentAttached = 0; enginePriv->bindValues.clear(); enginePriv->parserStatus.clear(); - enginePriv->finalizedParserStatus.clear(); state->completePending = true; enginePriv->inProgressCreations++; } @@ -955,14 +951,17 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri QDeclarativeEnginePrivate::clear(ps); } - for (int ii = 0; ii < state->finalizedParserStatus.count(); ++ii) { - QPair, int> status = state->finalizedParserStatus.at(ii); - QObject *obj = status.first; - if (obj) { - void *args[] = { 0 }; - QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, - status.second, args); + if (1 == enginePriv->inProgressCreations) { + for (int ii = 0; ii < enginePriv->finalizedParserStatus.count(); ++ii) { + QPair, int> status = enginePriv->finalizedParserStatus.at(ii); + QObject *obj = status.first; + if (obj) { + void *args[] = { 0 }; + QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, + status.second, args); + } } + enginePriv->finalizedParserStatus.clear(); } while (state->componentAttached) { @@ -977,7 +976,6 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri state->bindValues.clear(); state->parserStatus.clear(); - state->finalizedParserStatus.clear(); state->completePending = false; enginePriv->inProgressCreations--; @@ -987,7 +985,6 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri enginePriv->erroredBindings->removeError(); } } - } } diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h index f8bec2b..020c5e0 100644 --- a/src/declarative/qml/qdeclarativecomponent_p.h +++ b/src/declarative/qml/qdeclarativecomponent_p.h @@ -101,7 +101,6 @@ public: ConstructionState() : componentAttached(0), completePending(false) {} QList > bindValues; QList > parserStatus; - QList, int> > finalizedParserStatus; QDeclarativeComponentAttached *componentAttached; QList errors; bool completePending; diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 366c64b..2d551f2 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -938,7 +938,6 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarativeEnginePrivate::clear(bindValues); QDeclarativeEnginePrivate::clear(parserStatus); - ep->finalizedParserStatus.clear(); return 0; } diff --git a/tests/auto/declarative/qdeclarativeanimations/data/registrationBug.qml b/tests/auto/declarative/qdeclarativeanimations/data/registrationBug.qml new file mode 100644 index 0000000..7dc29f9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeanimations/data/registrationBug.qml @@ -0,0 +1,18 @@ +import QtQuick 1.0 + +Rectangle { + id: rect + width: 200 + height: 200 + + property bool animating: true + property int value: 0 + + NumberAnimation { + target: rect + property: "value" + running: rect.animating + to: 100 + duration: 50 + } +} diff --git a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp index 6f71dec..d1b7c1b 100644 --- a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp +++ b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp @@ -85,6 +85,7 @@ private slots: void rotation(); void runningTrueBug(); void nonTransitionBug(); + void registrationBug(); }; #define QTIMED_COMPARE(lhs, rhs) do { \ @@ -793,6 +794,17 @@ void tst_qdeclarativeanimations::nonTransitionBug() QCOMPARE(mover->x(), qreal(100)); } +//QTBUG-14042 +void tst_qdeclarativeanimations::registrationBug() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, SRCDIR "/data/registrationBug.qml"); + QDeclarativeRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + QTRY_COMPARE(rect->property("value"), QVariant(int(100))); +} + QTEST_MAIN(tst_qdeclarativeanimations) #include "tst_qdeclarativeanimations.moc" -- cgit v0.12 From 1bcddaaf318fc37c71c5191913f3487c49444ec6 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 21 Feb 2011 14:57:08 +1000 Subject: Prevent recursion due to nested Flickables with pressDelay The outermost Flickable handles pressDelay for all descendents, rather than having it cascade up and replayed multiple times. Change-Id: Id294862469f3ce56b0940fbbb0e041d4c9f64f28 Task-number: QTBUG-17361 Reviewed-by: Michael Brasser --- .../graphicsitems/qdeclarativeflickable.cpp | 48 ++++++++++++++++++++-- .../graphicsitems/qdeclarativeflickable_p.h | 1 + .../graphicsitems/qdeclarativeflickable_p_p.h | 1 + .../tst_qdeclarativeflickable.cpp | 29 +++++++++++++ .../tst_qdeclarativemousearea.cpp | 20 +++------ 5 files changed, 80 insertions(+), 19 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 5d5fd0b..a3d9f41 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -845,7 +845,8 @@ void QDeclarativeFlickable::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeFlickable); if (d->interactive) { - d->handleMousePressEvent(event); + if (!d->pressed) + d->handleMousePressEvent(event); event->accept(); } else { QDeclarativeItem::mousePressEvent(event); @@ -910,11 +911,27 @@ void QDeclarativeFlickable::wheelEvent(QGraphicsSceneWheelEvent *event) } } +bool QDeclarativeFlickablePrivate::isOutermostPressDelay() const +{ + Q_Q(const QDeclarativeFlickable); + QDeclarativeItem *item = q->parentItem(); + while (item) { + QDeclarativeFlickable *flick = qobject_cast(item); + if (flick && flick->pressDelay() > 0 && flick->isInteractive()) + return false; + item = item->parentItem(); + } + + return true; +} + void QDeclarativeFlickablePrivate::captureDelayedPress(QGraphicsSceneMouseEvent *event) { Q_Q(QDeclarativeFlickable); if (!q->scene() || pressDelay <= 0) return; + if (!isOutermostPressDelay()) + return; delayedPressTarget = q->scene()->mouseGrabberItem(); delayedPressEvent = new QGraphicsSceneMouseEvent(event->type()); delayedPressEvent->setAccepted(false); @@ -970,9 +987,10 @@ void QDeclarativeFlickable::timerEvent(QTimerEvent *event) if (scene()->mouseGrabberItem() == d->delayedPressTarget) d->delayedPressTarget->ungrabMouse(); //Use the event handler that will take care of finding the proper item to propagate the event - QApplication::sendEvent(scene(), d->delayedPressEvent); + QApplication::postEvent(scene(), d->delayedPressEvent); + } else { + delete d->delayedPressEvent; } - delete d->delayedPressEvent; d->delayedPressEvent = 0; } } @@ -1364,6 +1382,22 @@ bool QDeclarativeFlickable::yflick() const return d->flickableDirection & QDeclarativeFlickable::VerticalFlick; } +bool QDeclarativeFlickable::sceneEvent(QEvent *event) +{ + bool rv = QDeclarativeItem::sceneEvent(event); + if (event->type() == QEvent::UngrabMouse) { + Q_D(QDeclarativeFlickable); + if (d->pressed) { + // if our mouse grab has been removed (probably by another Flickable), + // fix our state + d->pressed = false; + d->stealMouse = false; + setKeepMouseGrab(false); + } + } + return rv; +} + bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeFlickable); @@ -1391,7 +1425,7 @@ bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) d->handleMouseMoveEvent(&mouseEvent); break; case QEvent::GraphicsSceneMousePress: - if (d->delayedPressEvent) + if (d->pressed) // we are already pressed - this is a delayed replay return false; d->handleMousePressEvent(&mouseEvent); @@ -1410,6 +1444,8 @@ bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) // We send the release scene()->sendEvent(s->mouseGrabberItem(), event); // And the event has been consumed + d->stealMouse = false; + d->pressed = false; return true; } d->handleMouseReleaseEvent(&mouseEvent); @@ -1432,6 +1468,7 @@ bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) d->stealMouse = false; d->pressed = false; } + return false; } @@ -1530,6 +1567,9 @@ bool QDeclarativeFlickable::isFlickingVertically() const If the flickable is dragged/flicked before the delay times out the press event will not be delivered. If the button is released within the timeout, both the press and release will be delivered. + + Note that for nested Flickables with pressDelay set, the pressDelay of + inner Flickables is overridden by the outermost Flickable. */ int QDeclarativeFlickable::pressDelay() const { diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p.h index 4fde1d5..a14cc1c 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable_p.h +++ b/src/declarative/graphicsitems/qdeclarativeflickable_p.h @@ -204,6 +204,7 @@ protected: virtual void viewportMoved(); virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); + bool sceneEvent(QEvent *event); bool sendMouseEvent(QGraphicsSceneMouseEvent *event); bool xflick() const; diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h index 5ad6ff6..1b6081c 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h @@ -118,6 +118,7 @@ public: void updateBeginningEnd(); + bool isOutermostPressDelay() const; void captureDelayedPress(QGraphicsSceneMouseEvent *event); void clearDelayedPress(); diff --git a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp index f4bec8f..736f8f4 100644 --- a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp +++ b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp @@ -69,6 +69,7 @@ private slots: void maximumFlickVelocity(); void flickDeceleration(); void pressDelay(); + void nestedPressDelay(); void flickableDirection(); void qgraphicswidget(); void resizeContent(); @@ -246,6 +247,34 @@ void tst_qdeclarativeflickable::pressDelay() QCOMPARE(spy.count(),1); } +// QTBUG-17361 +void tst_qdeclarativeflickable::nestedPressDelay() +{ + QDeclarativeView *canvas = new QDeclarativeView; + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/nestedPressDelay.qml")); + canvas->show(); + canvas->setFocus(); + QVERIFY(canvas->rootObject() != 0); + + QDeclarativeFlickable *outer = qobject_cast(canvas->rootObject()); + QVERIFY(outer != 0); + + QDeclarativeFlickable *inner = canvas->rootObject()->findChild("innerFlickable"); + QVERIFY(inner != 0); + + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(150, 150))); + // the MouseArea is not pressed immediately + QVERIFY(outer->property("pressed").toBool() == false); + + // The outer pressDelay will prevail (50ms, vs. 10sec) + QTest::qWait(300); + QVERIFY(outer->property("pressed").toBool() == true); + + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(150, 150))); + + delete canvas; +} + void tst_qdeclarativeflickable::flickableDirection() { QDeclarativeComponent component(&engine); diff --git a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp index 60d51c6..e1c34fc 100644 --- a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp +++ b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp @@ -541,15 +541,11 @@ void tst_QDeclarativeMouseArea::preventStealing() QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QDeclarativeMouseEvent*))); - QGraphicsScene *scene = canvas->scene(); - QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress); - pressEvent.setScenePos(QPointF(80, 80)); - pressEvent.setButton(Qt::LeftButton); - pressEvent.setButtons(Qt::LeftButton); - QApplication::sendEvent(scene, &pressEvent); + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(80, 80))); // Without preventStealing, mouse movement over MouseArea would // cause the Flickable to steal mouse and trigger content movement. + QGraphicsScene *scene = canvas->scene(); QGraphicsSceneMouseEvent moveEvent(QEvent::GraphicsSceneMouseMove); moveEvent.setScenePos(QPointF(70, 70)); moveEvent.setButton(Qt::LeftButton); @@ -574,17 +570,12 @@ void tst_QDeclarativeMouseArea::preventStealing() QCOMPARE(flickable->contentX(), 0.); QCOMPARE(flickable->contentY(), 0.); - QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease); - releaseEvent.setScenePos(QPointF(50, 50)); - releaseEvent.setButton(Qt::LeftButton); - releaseEvent.setButtons(Qt::LeftButton); - QApplication::sendEvent(scene, &releaseEvent); + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(50, 50))); // Now allow stealing and confirm Flickable does its thing. canvas->rootObject()->setProperty("stealing", false); - pressEvent.setScenePos(QPointF(80, 80)); - QApplication::sendEvent(scene, &pressEvent); + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(80, 80))); // Without preventStealing, mouse movement over MouseArea would // cause the Flickable to steal mouse and trigger content movement. @@ -606,8 +597,7 @@ void tst_QDeclarativeMouseArea::preventStealing() QCOMPARE(flickable->contentX(), 10.); QCOMPARE(flickable->contentY(), 10.); - releaseEvent.setScenePos(QPointF(50, 50)); - QApplication::sendEvent(scene, &releaseEvent); + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(50, 50))); delete canvas; } -- cgit v0.12 From 0c24787a2f35a7b0585c9dfb3bf0a8cb34ce867f Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 22 Feb 2011 10:03:14 +1000 Subject: Add missing test file. Missed in 1bcddaaf318fc37c71c5191913f3487c49444ec6 Change-Id: I4f71e5fb2b0e67a6e64ee64ae03b9d9cfc7a244f Task-number: QTBUG-17361 --- .../data/nestedPressDelay.qml | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/auto/declarative/qdeclarativeflickable/data/nestedPressDelay.qml diff --git a/tests/auto/declarative/qdeclarativeflickable/data/nestedPressDelay.qml b/tests/auto/declarative/qdeclarativeflickable/data/nestedPressDelay.qml new file mode 100644 index 0000000..d0ee545 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeflickable/data/nestedPressDelay.qml @@ -0,0 +1,33 @@ +import QtQuick 1.0 + +Flickable { + property bool pressed: ma.pressed + width: 240 + height: 320 + contentWidth: 480 + contentHeight: 320 + flickableDirection: Flickable.HorizontalFlick + pressDelay: 50 + Flickable { + objectName: "innerFlickable" + flickableDirection: Flickable.VerticalFlick + width: 480 + height: 320 + contentWidth: 480 + contentHeight: 400 + pressDelay: 10000 + Rectangle { + y: 100 + anchors.horizontalCenter: parent.horizontalCenter + width: 240 + height: 100 + color: ma.pressed ? 'blue' : 'green' + MouseArea { + id: ma + objectName: "mouseArea" + anchors.fill: parent + } + } + } +} + -- cgit v0.12 From 5fa90e4bc83541dc23db150166157e2a3f04a668 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 21 Feb 2011 16:11:50 +1000 Subject: Prevent an animation from being registered to run twice. This could cause animations to start running that could not later be stopped. Change-Id: I320f50121f3566619f08181664d049b02e2848e5 Reviewed-by: Martin Jones --- src/declarative/util/qdeclarativeanimation.cpp | 5 ++--- src/declarative/util/qdeclarativeanimation_p_p.h | 3 ++- .../declarative/qdeclarativeanimations/data/Double.qml | 14 ++++++++++++++ .../qdeclarativeanimations/data/doubleRegistrationBug.qml | 8 ++++++++ .../qdeclarativeanimations/tst_qdeclarativeanimations.cpp | 14 ++++++++++++++ 5 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeanimations/data/Double.qml create mode 100644 tests/auto/declarative/qdeclarativeanimations/data/doubleRegistrationBug.qml diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index f22b9dd..014d368 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -182,12 +182,11 @@ void QDeclarativeAbstractAnimation::setRunning(bool r) { Q_D(QDeclarativeAbstractAnimation); if (!d->componentComplete) { - if (d->running && r == d->running) //don't re-register - return; d->running = r; if (r == false) d->avoidPropertyValueSourceStart = true; - else { + else if (!d->registered) { + d->registered = true; QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this)); engPriv->registerFinalizedParserStatusObject(this, this->metaObject()->indexOfSlot("componentFinalized()")); } diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h index 84bc0ef..3c41565 100644 --- a/src/declarative/util/qdeclarativeanimation_p_p.h +++ b/src/declarative/util/qdeclarativeanimation_p_p.h @@ -210,7 +210,7 @@ public: : running(false), paused(false), alwaysRunToEnd(false), connectedTimeLine(false), componentComplete(true), avoidPropertyValueSourceStart(false), disableUserControl(false), - loopCount(1), group(0) {} + registered(false), loopCount(1), group(0) {} bool running:1; bool paused:1; @@ -219,6 +219,7 @@ public: bool componentComplete:1; bool avoidPropertyValueSourceStart:1; bool disableUserControl:1; + bool registered:1; int loopCount; diff --git a/tests/auto/declarative/qdeclarativeanimations/data/Double.qml b/tests/auto/declarative/qdeclarativeanimations/data/Double.qml new file mode 100644 index 0000000..b247fce --- /dev/null +++ b/tests/auto/declarative/qdeclarativeanimations/data/Double.qml @@ -0,0 +1,14 @@ +import QtQuick 1.0 + +Rectangle { + id: container + property bool on: false + border.color: "#ffffff" + color: "green" + width: 50 + height: 50 + NumberAnimation on x { + objectName: "animation" + running: container.on; from: 0; to: 600; loops: Animation.Infinite; duration: 2000 + } +} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/doubleRegistrationBug.qml b/tests/auto/declarative/qdeclarativeanimations/data/doubleRegistrationBug.qml new file mode 100644 index 0000000..f0fdf9c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeanimations/data/doubleRegistrationBug.qml @@ -0,0 +1,8 @@ +import QtQuick 1.0 + +Rectangle { + width: 400; height: 400 + + Double { id: dub; on: parent.width < 800 } + Component.onCompleted: dub.on = false +} diff --git a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp index d1b7c1b..f7fee3b 100644 --- a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp +++ b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp @@ -86,6 +86,7 @@ private slots: void runningTrueBug(); void nonTransitionBug(); void registrationBug(); + void doubleRegistrationBug(); }; #define QTIMED_COMPARE(lhs, rhs) do { \ @@ -805,6 +806,19 @@ void tst_qdeclarativeanimations::registrationBug() QTRY_COMPARE(rect->property("value"), QVariant(int(100))); } +void tst_qdeclarativeanimations::doubleRegistrationBug() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, SRCDIR "/data/doubleRegistrationBug.qml"); + QDeclarativeRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + + QDeclarativeAbstractAnimation *anim = rect->findChild("animation"); + QVERIFY(anim != 0); + QTRY_COMPARE(anim->qtAnimation()->state(), QAbstractAnimation::Stopped); +} + QTEST_MAIN(tst_qdeclarativeanimations) #include "tst_qdeclarativeanimations.moc" -- cgit v0.12 From 15ebe8a375542826278aac2b920f0e3dac3ffaea Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Mon, 21 Feb 2011 14:41:38 +1000 Subject: Another stab at fixing compilation on old Symbian platforms Task-number: QTBUG-17472 Reviewed-by: Martin Jones --- tools/qml/qml.pri | 6 ++---- tools/qml/qmlruntime.cpp | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/qml/qml.pri b/tools/qml/qml.pri index 08cd506..5397384 100644 --- a/tools/qml/qml.pri +++ b/tools/qml/qml.pri @@ -25,12 +25,10 @@ symbian: { } !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) { LIBS += -lsensrvclient -lsensrvutil - } - !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2): { SOURCES += $$PWD/deviceorientation_symbian.cpp - FORMS = $$PWD/recopts.ui \ - $$PWD/proxysettings.ui } + FORMS += $$PWD/recopts.ui \ + $$PWD/proxysettings.ui } else:maemo5 { QT += dbus HEADERS += $$PWD/texteditautoresizer_maemo5.h diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index c746d8e..36915d1 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -50,7 +50,7 @@ # include # include # include "ui_recopts_maemo5.h" -#elif !defined(__SERIES60_31__) && !defined(__S60_32__) +#else # include "ui_recopts.h" #endif -- cgit v0.12 From ceecec1083bac96bdb600020b01c299c389eaa8c Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Tue, 22 Feb 2011 11:39:56 +1000 Subject: Update QtGui def files Task-number: Reviewed-by: Martin Jones --- src/s60installs/bwins/QtGuiu.def | 2 ++ src/s60installs/eabi/QtGuiu.def | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index adf2b3c..a41f784 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -12950,4 +12950,6 @@ EXPORTS ?dynamicPageCount@QTextDocumentLayout@@QBEHXZ @ 12949 NONAME ; int QTextDocumentLayout::dynamicPageCount(void) const ?setWordSelectionEnabled@QTextControl@@QAEX_N@Z @ 12950 NONAME ; void QTextControl::setWordSelectionEnabled(bool) ?isWordSelectionEnabled@QTextControl@@QBE_NXZ @ 12951 NONAME ; bool QTextControl::isWordSelectionEnabled(void) const + ?assignedInputContext@QWidgetPrivate@@QBEPAVQInputContext@@XZ @ 12952 NONAME ; class QInputContext * QWidgetPrivate::assignedInputContext(void) const + ?updateMicroFocus@QLineControl@@IAEXXZ @ 12953 NONAME ; void QLineControl::updateMicroFocus(void) diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 564f530..2de88f2 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -12145,4 +12145,6 @@ EXPORTS _ZTV19QTextDocumentLayout @ 12144 NONAME _ZN12QTextControl23setWordSelectionEnabledEb @ 12145 NONAME _ZNK12QTextControl22isWordSelectionEnabledEv @ 12146 NONAME + _ZN12QLineControl16updateMicroFocusEv @ 12147 NONAME + _ZNK14QWidgetPrivate20assignedInputContextEv @ 12148 NONAME -- cgit v0.12 From 2dad737a8cef6191a46eead8ea9940034d083884 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Tue, 22 Feb 2011 10:51:18 +1000 Subject: Fix auto test failure on mac. Allow for some error in the cursor position due to plaform specific offsets and the like. Change-Id: I2bef793596ab2a5e38cf77aee624bd9fdd5ca38c --- .../tst_qdeclarativetextedit.cpp | 60 ++++++++++----------- .../tst_qdeclarativetextinput.cpp | 61 +++++++++++----------- 2 files changed, 60 insertions(+), 61 deletions(-) diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index ba410ce..2c3ec7c 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -1970,9 +1970,9 @@ void tst_qdeclarativetextedit::inputContextMouseHandler() QDeclarativeTextEdit edit; edit.setPos(0, 0); edit.setWidth(200); - edit.setText(text.mid(0, 5)); + edit.setText(text.mid(0, 12)); edit.setPos(0, 0); - edit.setCursorPosition(5); + edit.setCursorPosition(12); edit.setFocus(true); scene.addItem(&edit); view.show(); @@ -1985,15 +1985,15 @@ void tst_qdeclarativetextedit::inputContextMouseHandler() const qreal y = fm.height() / 2; QPoint position2 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 2)), y))); - QPoint position4 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 4)), y))); - QPoint position7 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 7)), y))); - QPoint position12 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 12)), y))); + QPoint position8 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 8)), y))); + QPoint position20 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 20)), y))); + QPoint position27 = view.mapFromScene(edit.mapToScene(QPointF(fm.width(text.mid(0, 27)), y))); QPoint globalPosition2 = view.viewport()->mapToGlobal(position2); - QPoint globalPosition4 = view.viewport()->mapToGlobal(position4); - QPoint globalPosition7 = view.viewport()->mapToGlobal(position7); - QPoint globalPosition12 = view.viewport()->mapToGlobal(position12); + QPoint globalposition8 = view.viewport()->mapToGlobal(position8); + QPoint globalposition20 = view.viewport()->mapToGlobal(position20); + QPoint globalposition27 = view.viewport()->mapToGlobal(position27); - ic.sendEvent(QInputMethodEvent(text.mid(5), QList())); + ic.sendEvent(QInputMethodEvent(text.mid(12), QList())); QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2); QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick); @@ -2013,56 +2013,56 @@ void tst_qdeclarativetextedit::inputContextMouseHandler() QVERIFY(ic.cursor < 0); ic.eventType = QEvent::None; - { QMouseEvent mv(QEvent::MouseMove, position4, globalPosition4, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + { QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); QApplication::sendEvent(view.viewport(), &mv); } QCOMPARE(ic.eventType, QEvent::None); - { QMouseEvent mv(QEvent::MouseMove, position12, globalPosition12, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + { QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); QApplication::sendEvent(view.viewport(), &mv); } QCOMPARE(ic.eventType, QEvent::MouseMove); - QCOMPARE(ic.eventPosition, position12); - QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventPosition, position27); + QCOMPARE(ic.eventGlobalPosition, globalposition27); QCOMPARE(ic.eventButton, Qt::LeftButton); QCOMPARE(ic.eventModifiers, Qt::NoModifier); - QCOMPARE(ic.cursor, 7); + QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); // 15 is expected but some platforms may be off by one. ic.eventType = QEvent::None; - QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position12); + QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position27); QCOMPARE(ic.eventType, QEvent::MouseButtonRelease); - QCOMPARE(ic.eventPosition, position12); - QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventPosition, position27); + QCOMPARE(ic.eventGlobalPosition, globalposition27); QCOMPARE(ic.eventButton, Qt::LeftButton); QCOMPARE(ic.eventModifiers, Qt::NoModifier); - QCOMPARE(ic.cursor, 7); + QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); ic.eventType = QEvent::None; // And in the other direction. - QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position12); + QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position27); QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick); - QCOMPARE(ic.eventPosition, position12); - QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventPosition, position27); + QCOMPARE(ic.eventGlobalPosition, globalposition27); QCOMPARE(ic.eventButton, Qt::LeftButton); QCOMPARE(ic.eventModifiers, Qt::ControlModifier); - QCOMPARE(ic.cursor, 7); + QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); ic.eventType = QEvent::None; - QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position12); + QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position27); QCOMPARE(ic.eventType, QEvent::MouseButtonPress); - QCOMPARE(ic.eventPosition, position12); - QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventPosition, position27); + QCOMPARE(ic.eventGlobalPosition, globalposition27); QCOMPARE(ic.eventButton, Qt::RightButton); QCOMPARE(ic.eventModifiers, Qt::ControlModifier); - QCOMPARE(ic.cursor, 7); + QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); ic.eventType = QEvent::None; - { QMouseEvent mv(QEvent::MouseMove, position7, globalPosition7, Qt::RightButton, Qt::RightButton,Qt::ControlModifier); + { QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier); QApplication::sendEvent(view.viewport(), &mv); } QCOMPARE(ic.eventType, QEvent::MouseMove); - QCOMPARE(ic.eventPosition, position7); - QCOMPARE(ic.eventGlobalPosition, globalPosition7); + QCOMPARE(ic.eventPosition, position20); + QCOMPARE(ic.eventGlobalPosition, globalposition20); QCOMPARE(ic.eventButton, Qt::RightButton); QCOMPARE(ic.eventModifiers, Qt::ControlModifier); - QCOMPARE(ic.cursor, 2); + QVERIFY(ic.cursor >= 7 && ic.cursor <= 9); ic.eventType = QEvent::None; { QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier); diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp index b8f73bd..49a05a3 100644 --- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp +++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp @@ -1958,7 +1958,8 @@ void tst_qdeclarativetextinput::inputContextMouseHandler() view.setInputContext(&ic); QDeclarativeTextInput input; input.setWidth(200); - input.setText(text.mid(0, 5)); + input.setText(text.mid(0, 12)); + input.setCursorPosition(12); input.setPos(0, 0); input.setFocus(true); scene.addItem(&input); @@ -1967,21 +1968,19 @@ void tst_qdeclarativetextinput::inputContextMouseHandler() QTest::qWaitForWindowShown(&view); QTRY_COMPARE(QApplication::activeWindow(), static_cast(&view)); - ic.sendEvent(QInputMethodEvent(text.mid(5), QList())); - QFontMetricsF fm(input.font()); const qreal y = fm.height() / 2; QPoint position2 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 2)), y))); - QPoint position4 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 4)), y))); - QPoint position7 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 7)), y))); - QPoint position12 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 12)), y))); + QPoint position8 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 8)), y))); + QPoint position20 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 20)), y))); + QPoint position27 = view.mapFromScene(input.mapToScene(QPointF(fm.width(text.mid(0, 27)), y))); QPoint globalPosition2 = view.viewport()->mapToGlobal(position2); - QPoint globalPosition4 = view.viewport()->mapToGlobal(position4); - QPoint globalPosition7 = view.viewport()->mapToGlobal(position7); - QPoint globalPosition12 = view.viewport()->mapToGlobal(position12); + QPoint globalposition8 = view.viewport()->mapToGlobal(position8); + QPoint globalposition20 = view.viewport()->mapToGlobal(position20); + QPoint globalposition27 = view.viewport()->mapToGlobal(position27); - ic.sendEvent(QInputMethodEvent(text.mid(5), QList())); + ic.sendEvent(QInputMethodEvent(text.mid(12), QList())); QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, position2); QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick); @@ -2001,56 +2000,56 @@ void tst_qdeclarativetextinput::inputContextMouseHandler() QVERIFY(ic.cursor < 0); ic.eventType = QEvent::None; - { QMouseEvent mv(QEvent::MouseMove, position4, globalPosition4, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + { QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); QApplication::sendEvent(view.viewport(), &mv); } QCOMPARE(ic.eventType, QEvent::None); - { QMouseEvent mv(QEvent::MouseMove, position12, globalPosition12, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + { QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); QApplication::sendEvent(view.viewport(), &mv); } QCOMPARE(ic.eventType, QEvent::MouseMove); - QCOMPARE(ic.eventPosition, position12); - QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventPosition, position27); + QCOMPARE(ic.eventGlobalPosition, globalposition27); QCOMPARE(ic.eventButton, Qt::LeftButton); QCOMPARE(ic.eventModifiers, Qt::NoModifier); - QCOMPARE(ic.cursor, 7); + QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); // 15 is expected but some platforms may be off by one. ic.eventType = QEvent::None; - QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position12); + QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, position27); QCOMPARE(ic.eventType, QEvent::MouseButtonRelease); - QCOMPARE(ic.eventPosition, position12); - QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventPosition, position27); + QCOMPARE(ic.eventGlobalPosition, globalposition27); QCOMPARE(ic.eventButton, Qt::LeftButton); QCOMPARE(ic.eventModifiers, Qt::NoModifier); - QCOMPARE(ic.cursor, 7); + QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); ic.eventType = QEvent::None; // And in the other direction. - QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position12); + QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, position27); QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick); - QCOMPARE(ic.eventPosition, position12); - QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventPosition, position27); + QCOMPARE(ic.eventGlobalPosition, globalposition27); QCOMPARE(ic.eventButton, Qt::LeftButton); QCOMPARE(ic.eventModifiers, Qt::ControlModifier); - QCOMPARE(ic.cursor, 7); + QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); ic.eventType = QEvent::None; - QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position12); + QTest::mousePress(view.viewport(), Qt::RightButton, Qt::ControlModifier, position27); QCOMPARE(ic.eventType, QEvent::MouseButtonPress); - QCOMPARE(ic.eventPosition, position12); - QCOMPARE(ic.eventGlobalPosition, globalPosition12); + QCOMPARE(ic.eventPosition, position27); + QCOMPARE(ic.eventGlobalPosition, globalposition27); QCOMPARE(ic.eventButton, Qt::RightButton); QCOMPARE(ic.eventModifiers, Qt::ControlModifier); - QCOMPARE(ic.cursor, 7); + QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); ic.eventType = QEvent::None; - { QMouseEvent mv(QEvent::MouseMove, position7, globalPosition7, Qt::RightButton, Qt::RightButton,Qt::ControlModifier); + { QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier); QApplication::sendEvent(view.viewport(), &mv); } QCOMPARE(ic.eventType, QEvent::MouseMove); - QCOMPARE(ic.eventPosition, position7); - QCOMPARE(ic.eventGlobalPosition, globalPosition7); + QCOMPARE(ic.eventPosition, position20); + QCOMPARE(ic.eventGlobalPosition, globalposition20); QCOMPARE(ic.eventButton, Qt::RightButton); QCOMPARE(ic.eventModifiers, Qt::ControlModifier); - QCOMPARE(ic.cursor, 2); + QVERIFY(ic.cursor >= 7 && ic.cursor <= 9); ic.eventType = QEvent::None; { QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier); -- cgit v0.12 From b254be20c03d4dbfc1803cd40dc95d52115b955c Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 22 Feb 2011 13:33:12 +1000 Subject: Fix animations with alwaysRunToEnd that are frequently stopped/started. A previous refactoring of the animation logic introduced a regression -- 'restart' rather than 'continue' behavior. Change-Id: I8ade2286298fad48f5e268793a0b2571884bc5d0 Task-number: QTBUG-16736 Reviewed-by: Martin Jones --- src/declarative/util/qdeclarativeanimation.cpp | 5 ++++- .../tst_qdeclarativeanimations.cpp | 25 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index 014d368..58c346c 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -203,6 +203,7 @@ void QDeclarativeAbstractAnimation::setRunning(bool r) d->running = r; if (d->running) { + bool supressStart = false; if (d->alwaysRunToEnd && d->loopCount != 1 && qtAnimation()->state() == QAbstractAnimation::Running) { //we've restarted before the final loop finished; restore proper loop count @@ -210,6 +211,7 @@ void QDeclarativeAbstractAnimation::setRunning(bool r) qtAnimation()->setLoopCount(d->loopCount); else qtAnimation()->setLoopCount(qtAnimation()->currentLoop() + d->loopCount); + supressStart = true; //we want the animation to continue, rather than restart } if (!d->connectedTimeLine) { @@ -217,7 +219,8 @@ void QDeclarativeAbstractAnimation::setRunning(bool r) this, SLOT(timelineComplete())); d->connectedTimeLine = true; } - d->commence(); + if (!supressStart) + d->commence(); emit started(); } else { if (d->alwaysRunToEnd) { diff --git a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp index f7fee3b..e2a54c0 100644 --- a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp +++ b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp @@ -87,6 +87,7 @@ private slots: void nonTransitionBug(); void registrationBug(); void doubleRegistrationBug(); + void alwaysRunToEndRestartBug(); }; #define QTIMED_COMPARE(lhs, rhs) do { \ @@ -819,6 +820,30 @@ void tst_qdeclarativeanimations::doubleRegistrationBug() QTRY_COMPARE(anim->qtAnimation()->state(), QAbstractAnimation::Stopped); } +//QTBUG-16736 +void tst_qdeclarativeanimations::alwaysRunToEndRestartBug() +{ + QDeclarativeRectangle rect; + QDeclarativePropertyAnimation animation; + animation.setTarget(&rect); + animation.setProperty("x"); + animation.setTo(200); + animation.setDuration(1000); + animation.setLoops(-1); + animation.setAlwaysRunToEnd(true); + QVERIFY(animation.loops() == -1); + QVERIFY(animation.alwaysRunToEnd() == true); + animation.start(); + animation.stop(); + animation.start(); + animation.stop(); + QTest::qWait(500); + QVERIFY(rect.x() != qreal(200)); + QTest::qWait(800); + QTIMED_COMPARE(rect.x(), qreal(200)); + QCOMPARE(static_cast(&animation)->qtAnimation()->state(), QAbstractAnimation::Stopped); +} + QTEST_MAIN(tst_qdeclarativeanimations) #include "tst_qdeclarativeanimations.moc" -- cgit v0.12