| 1 | /**************************************************************************** | 
| 2 | ** | 
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | 
| 4 | ** Contact: https://www.qt.io/licensing/ | 
| 5 | ** | 
| 6 | ** This file is part of the test suite of the Qt Toolkit. | 
| 7 | ** | 
| 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ | 
| 9 | ** Commercial License Usage | 
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | 
| 11 | ** accordance with the commercial license agreement provided with the | 
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | 
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | 
| 16 | ** | 
| 17 | ** GNU General Public License Usage | 
| 18 | ** Alternatively, this file may be used under the terms of the GNU | 
| 19 | ** General Public License version 3 as published by the Free Software | 
| 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT | 
| 21 | ** included in the packaging of this file. Please review the following | 
| 22 | ** information to ensure the GNU General Public License requirements will | 
| 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. | 
| 24 | ** | 
| 25 | ** $QT_END_LICENSE$ | 
| 26 | ** | 
| 27 | ****************************************************************************/ | 
| 28 | #include <qtest.h> | 
| 29 | #include <QtTest/QSignalSpy> | 
| 30 | #include <QtQml/qqmlengine.h> | 
| 31 | #include <QtQml/qqmlcomponent.h> | 
| 32 | #include <QtQml/qqmlcontext.h> | 
| 33 | #include <QtQuick/qquickitemgrabresult.h> | 
| 34 | #include <QtQuick/qquickview.h> | 
| 35 | #include <QtGui/private/qinputmethod_p.h> | 
| 36 | #include <QtQuick/private/qquickloader_p.h> | 
| 37 | #include <QtQuick/private/qquickrectangle_p.h> | 
| 38 | #include <QtQuick/private/qquicktextinput_p.h> | 
| 39 | #include <QtQuick/private/qquickitemchangelistener_p.h> | 
| 40 | #include <QtGui/qstylehints.h> | 
| 41 | #include <private/qquickitem_p.h> | 
| 42 | #include "../../shared/util.h" | 
| 43 | #include "../shared/visualtestutil.h" | 
| 44 | #include "../../shared/platforminputcontext.h" | 
| 45 |  | 
| 46 | using namespace QQuickVisualTestUtil; | 
| 47 |  | 
| 48 | class tst_QQuickItem : public QQmlDataTest | 
| 49 | { | 
| 50 |     Q_OBJECT | 
| 51 | public: | 
| 52 |     tst_QQuickItem(); | 
| 53 |  | 
| 54 | private slots: | 
| 55 |     void initTestCase(); | 
| 56 |     void cleanup(); | 
| 57 |  | 
| 58 |     void activeFocusOnTab(); | 
| 59 |     void activeFocusOnTab2(); | 
| 60 |     void activeFocusOnTab3(); | 
| 61 |     void activeFocusOnTab4(); | 
| 62 |     void activeFocusOnTab5(); | 
| 63 |     void activeFocusOnTab6(); | 
| 64 |     void activeFocusOnTab7(); | 
| 65 |     void activeFocusOnTab8(); | 
| 66 |     void activeFocusOnTab9(); | 
| 67 |     void activeFocusOnTab10(); | 
| 68 |     void activeFocusOnTab_infiniteLoop_data(); | 
| 69 |     void activeFocusOnTab_infiniteLoop(); | 
| 70 |  | 
| 71 |     void nextItemInFocusChain(); | 
| 72 |     void nextItemInFocusChain2(); | 
| 73 |     void nextItemInFocusChain3(); | 
| 74 |  | 
| 75 |     void tabFence(); | 
| 76 |     void qtbug_50516(); | 
| 77 |     void qtbug_50516_2_data(); | 
| 78 |     void qtbug_50516_2(); | 
| 79 |     void focusableItemReparentedToLoadedComponent(); | 
| 80 |  | 
| 81 |     void keys(); | 
| 82 | #if QT_CONFIG(shortcut) | 
| 83 |     void standardKeys_data(); | 
| 84 |     void standardKeys(); | 
| 85 | #endif | 
| 86 |     void keysProcessingOrder(); | 
| 87 |     void keysim(); | 
| 88 |     void keysForward(); | 
| 89 |     void keyNavigation_data(); | 
| 90 |     void keyNavigation(); | 
| 91 |     void keyNavigation_RightToLeft(); | 
| 92 |     void keyNavigation_skipNotVisible(); | 
| 93 |     void keyNavigation_implicitSetting(); | 
| 94 |     void keyNavigation_implicitDestroy(); | 
| 95 |     void keyNavigation_focusReason(); | 
| 96 |     void keyNavigation_loop(); | 
| 97 |     void keyNavigation_repeater(); | 
| 98 |     void layoutMirroring(); | 
| 99 |     void layoutMirroringWindow(); | 
| 100 |     void layoutMirroringIllegalParent(); | 
| 101 |     void smooth(); | 
| 102 |     void antialiasing(); | 
| 103 |     void clip(); | 
| 104 |     void mapCoordinates(); | 
| 105 |     void mapCoordinates_data(); | 
| 106 |     void mapCoordinatesRect(); | 
| 107 |     void mapCoordinatesRect_data(); | 
| 108 |     void propertyChanges(); | 
| 109 |     void nonexistentPropertyConnection(); | 
| 110 |     void transforms(); | 
| 111 |     void transforms_data(); | 
| 112 |     void childrenRect(); | 
| 113 |     void childrenRectBug(); | 
| 114 |     void childrenRectBug2(); | 
| 115 |     void childrenRectBug3(); | 
| 116 |     void childrenRectBottomRightCorner(); | 
| 117 |  | 
| 118 |     void childrenProperty(); | 
| 119 |     void resourcesProperty(); | 
| 120 |  | 
| 121 |     void changeListener(); | 
| 122 |     void transformCrash(); | 
| 123 |     void implicitSize(); | 
| 124 |     void qtbug_16871(); | 
| 125 |     void visibleChildren(); | 
| 126 |     void parentLoop(); | 
| 127 |     void contains_data(); | 
| 128 |     void contains(); | 
| 129 |     void childAt(); | 
| 130 |     void isAncestorOf(); | 
| 131 |  | 
| 132 |     void grab(); | 
| 133 |  | 
| 134 | private: | 
| 135 |     QQmlEngine engine; | 
| 136 |     bool qt_tab_all_widgets() { | 
| 137 |         return QGuiApplication::styleHints()->tabFocusBehavior() == Qt::TabFocusAllControls; | 
| 138 |     } | 
| 139 | }; | 
| 140 |  | 
| 141 | class KeysTestObject : public QObject | 
| 142 | { | 
| 143 |     Q_OBJECT | 
| 144 |  | 
| 145 |     Q_PROPERTY(bool processLast READ processLast NOTIFY processLastChanged) | 
| 146 |  | 
| 147 | public: | 
| 148 |     KeysTestObject() : mKey(0), mModifiers(0), mForwardedKey(0), mLast(false), mNativeScanCode(0) {} | 
| 149 |  | 
| 150 |     void reset() { | 
| 151 |         mKey = 0; | 
| 152 |         mText = QString(); | 
| 153 |         mModifiers = 0; | 
| 154 |         mForwardedKey = 0; | 
| 155 |         mNativeScanCode = 0; | 
| 156 |     } | 
| 157 |  | 
| 158 |     bool processLast() const { return mLast; } | 
| 159 |     void setProcessLast(bool b) { | 
| 160 |         if (b != mLast) { | 
| 161 |             mLast = b; | 
| 162 |             emit processLastChanged(); | 
| 163 |         } | 
| 164 |     } | 
| 165 |  | 
| 166 | public slots: | 
| 167 |     void keyPress(int key, QString text, int modifiers) { | 
| 168 |         mKey = key; | 
| 169 |         mText = text; | 
| 170 |         mModifiers = modifiers; | 
| 171 |     } | 
| 172 |     void keyRelease(int key, QString text, int modifiers) { | 
| 173 |         mKey = key; | 
| 174 |         mText = text; | 
| 175 |         mModifiers = modifiers; | 
| 176 |     } | 
| 177 |     void forwardedKey(int key) { | 
| 178 |         mForwardedKey = key; | 
| 179 |     } | 
| 180 |     void specialKey(int key, QString text, quint32 nativeScanCode) { | 
| 181 |         mKey = key; | 
| 182 |         mText = text; | 
| 183 |         mNativeScanCode = nativeScanCode; | 
| 184 |     } | 
| 185 |  | 
| 186 | signals: | 
| 187 |     void processLastChanged(); | 
| 188 |  | 
| 189 | public: | 
| 190 |     int mKey; | 
| 191 |     QString mText; | 
| 192 |     int mModifiers; | 
| 193 |     int mForwardedKey; | 
| 194 |     bool mLast; | 
| 195 |     quint32 mNativeScanCode; | 
| 196 |  | 
| 197 | private: | 
| 198 | }; | 
| 199 |  | 
| 200 | class KeyTestItem : public QQuickItem | 
| 201 | { | 
| 202 |     Q_OBJECT | 
| 203 | public: | 
| 204 |     KeyTestItem(QQuickItem *parent=nullptr) : QQuickItem(parent), mKey(0) {} | 
| 205 |  | 
| 206 | protected: | 
| 207 |     void keyPressEvent(QKeyEvent *e) { | 
| 208 |         mKey = e->key(); | 
| 209 |  | 
| 210 |         if (e->key() == Qt::Key_A) | 
| 211 |             e->accept(); | 
| 212 |         else | 
| 213 |             e->ignore(); | 
| 214 |     } | 
| 215 |  | 
| 216 |     void keyReleaseEvent(QKeyEvent *e) { | 
| 217 |         if (e->key() == Qt::Key_B) | 
| 218 |             e->accept(); | 
| 219 |         else | 
| 220 |             e->ignore(); | 
| 221 |     } | 
| 222 |  | 
| 223 | public: | 
| 224 |     int mKey; | 
| 225 | }; | 
| 226 |  | 
| 227 | class FocusEventFilter : public QObject | 
| 228 | { | 
| 229 | protected: | 
| 230 |     bool eventFilter(QObject *watched, QEvent *event) { | 
| 231 |         if ((event->type() == QEvent::FocusIn) ||  (event->type() == QEvent::FocusOut)) { | 
| 232 |             QFocusEvent *focusEvent = static_cast<QFocusEvent *>(event); | 
| 233 |             lastFocusReason = focusEvent->reason(); | 
| 234 |             return false; | 
| 235 |         } else | 
| 236 |             return QObject::eventFilter(watched, event); | 
| 237 |     } | 
| 238 | public: | 
| 239 |     Qt::FocusReason lastFocusReason; | 
| 240 | }; | 
| 241 |  | 
| 242 | QML_DECLARE_TYPE(KeyTestItem); | 
| 243 |  | 
| 244 | class HollowTestItem : public QQuickItem | 
| 245 | { | 
| 246 |     Q_OBJECT | 
| 247 |     Q_PROPERTY(bool circle READ isCircle WRITE setCircle) | 
| 248 |     Q_PROPERTY(qreal holeRadius READ holeRadius WRITE setHoleRadius) | 
| 249 |  | 
| 250 | public: | 
| 251 |     HollowTestItem(QQuickItem *parent = nullptr) | 
| 252 |         : QQuickItem(parent), | 
| 253 |           m_isPressed(false), | 
| 254 |           m_isHovered(false), | 
| 255 |           m_isCircle(false), | 
| 256 |           m_holeRadius(50) | 
| 257 |     { | 
| 258 |         setAcceptHoverEvents(true); | 
| 259 |         setAcceptedMouseButtons(Qt::LeftButton); | 
| 260 |     } | 
| 261 |  | 
| 262 |     bool isPressed() const { return m_isPressed; } | 
| 263 |     bool isHovered() const { return m_isHovered; } | 
| 264 |  | 
| 265 |     bool isCircle() const { return m_isCircle; } | 
| 266 |     void setCircle(bool circle) { m_isCircle = circle; } | 
| 267 |  | 
| 268 |     qreal holeRadius() const { return m_holeRadius; } | 
| 269 |     void setHoleRadius(qreal radius) { m_holeRadius = radius; } | 
| 270 |  | 
| 271 |     bool contains(const QPointF &point) const { | 
| 272 |         const qreal w = width(); | 
| 273 |         const qreal h = height(); | 
| 274 |         const qreal r = m_holeRadius; | 
| 275 |  | 
| 276 |         // check boundaries | 
| 277 |         if (!QRectF(0, 0, w, h).contains(p: point)) | 
| 278 |             return false; | 
| 279 |  | 
| 280 |         // square shape | 
| 281 |         if (!m_isCircle) | 
| 282 |             return !QRectF(w / 2 - r, h / 2 - r, r * 2, r * 2).contains(p: point); | 
| 283 |  | 
| 284 |         // circle shape | 
| 285 |         const qreal dx = point.x() - (w / 2); | 
| 286 |         const qreal dy = point.y() - (h / 2); | 
| 287 |         const qreal dd = (dx * dx) + (dy * dy); | 
| 288 |         const qreal outerRadius = qMin<qreal>(a: w / 2, b: h / 2); | 
| 289 |         return dd > (r * r) && dd <= outerRadius * outerRadius; | 
| 290 |     } | 
| 291 |  | 
| 292 | protected: | 
| 293 |     void hoverEnterEvent(QHoverEvent *) { m_isHovered = true; } | 
| 294 |     void hoverLeaveEvent(QHoverEvent *) { m_isHovered = false; } | 
| 295 |     void mousePressEvent(QMouseEvent *) { m_isPressed = true; } | 
| 296 |     void mouseReleaseEvent(QMouseEvent *) { m_isPressed = false; } | 
| 297 |  | 
| 298 | private: | 
| 299 |     bool m_isPressed; | 
| 300 |     bool m_isHovered; | 
| 301 |     bool m_isCircle; | 
| 302 |     qreal m_holeRadius; | 
| 303 | }; | 
| 304 |  | 
| 305 | QML_DECLARE_TYPE(HollowTestItem); | 
| 306 |  | 
| 307 | class TabFenceItem : public QQuickItem | 
| 308 | { | 
| 309 |     Q_OBJECT | 
| 310 |  | 
| 311 | public: | 
| 312 |     TabFenceItem(QQuickItem *parent = nullptr) | 
| 313 |         : QQuickItem(parent) | 
| 314 |     { | 
| 315 |         QQuickItemPrivate *d = QQuickItemPrivate::get(item: this); | 
| 316 |         d->isTabFence = true; | 
| 317 |     } | 
| 318 | }; | 
| 319 |  | 
| 320 | QML_DECLARE_TYPE(TabFenceItem); | 
| 321 |  | 
| 322 | class TabFenceItem2 : public QQuickItem | 
| 323 | { | 
| 324 |     Q_OBJECT | 
| 325 |  | 
| 326 | public: | 
| 327 |     TabFenceItem2(QQuickItem *parent = nullptr) | 
| 328 |         : QQuickItem(parent) | 
| 329 |     { | 
| 330 |         QQuickItemPrivate *d = QQuickItemPrivate::get(item: this); | 
| 331 |         d->isTabFence = true; | 
| 332 |         setFlag(flag: ItemIsFocusScope); | 
| 333 |     } | 
| 334 | }; | 
| 335 |  | 
| 336 | QML_DECLARE_TYPE(TabFenceItem2); | 
| 337 |  | 
| 338 | tst_QQuickItem::tst_QQuickItem() | 
| 339 | { | 
| 340 | } | 
| 341 |  | 
| 342 | void tst_QQuickItem::initTestCase() | 
| 343 | { | 
| 344 |     QQmlDataTest::initTestCase(); | 
| 345 |     qmlRegisterType<KeyTestItem>(uri: "Test" ,versionMajor: 1,versionMinor: 0,qmlName: "KeyTestItem" ); | 
| 346 |     qmlRegisterType<HollowTestItem>(uri: "Test" , versionMajor: 1, versionMinor: 0, qmlName: "HollowTestItem" ); | 
| 347 |     qmlRegisterType<TabFenceItem>(uri: "Test" , versionMajor: 1, versionMinor: 0, qmlName: "TabFence" ); | 
| 348 |     qmlRegisterType<TabFenceItem2>(uri: "Test" , versionMajor: 1, versionMinor: 0, qmlName: "TabFence2" ); | 
| 349 | } | 
| 350 |  | 
| 351 | void tst_QQuickItem::cleanup() | 
| 352 | { | 
| 353 |     QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); | 
| 354 |     inputMethodPrivate->testContext = nullptr; | 
| 355 | } | 
| 356 |  | 
| 357 | void tst_QQuickItem::activeFocusOnTab() | 
| 358 | { | 
| 359 |     if (!qt_tab_all_widgets()) | 
| 360 |         QSKIP("This function doesn't support NOT iterating all." ); | 
| 361 |  | 
| 362 |     QQuickView *window = new QQuickView(nullptr); | 
| 363 |     window->setBaseSize(QSize(800,600)); | 
| 364 |  | 
| 365 |     window->setSource(testFileUrl(fileName: "activeFocusOnTab.qml" )); | 
| 366 |     window->show(); | 
| 367 |     window->requestActivate(); | 
| 368 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 369 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 370 |  | 
| 371 |     // original: button12 | 
| 372 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button12" ); | 
| 373 |     QVERIFY(item); | 
| 374 |     QVERIFY(item->hasActiveFocus()); | 
| 375 |  | 
| 376 |     // Tab: button12->sub2 | 
| 377 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 378 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 379 |     QVERIFY(key.isAccepted()); | 
| 380 |  | 
| 381 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "sub2" ); | 
| 382 |     QVERIFY(item); | 
| 383 |     QVERIFY(item->hasActiveFocus()); | 
| 384 |  | 
| 385 |     // Tab: sub2->button21 | 
| 386 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 387 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 388 |     QVERIFY(key.isAccepted()); | 
| 389 |  | 
| 390 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button21" ); | 
| 391 |     QVERIFY(item); | 
| 392 |     QVERIFY(item->hasActiveFocus()); | 
| 393 |  | 
| 394 |     // Tab: button21->button22 | 
| 395 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 396 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 397 |     QVERIFY(key.isAccepted()); | 
| 398 |  | 
| 399 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button22" ); | 
| 400 |     QVERIFY(item); | 
| 401 |     QVERIFY(item->hasActiveFocus()); | 
| 402 |  | 
| 403 |     // Tab: button22->edit | 
| 404 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 405 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 406 |     QVERIFY(key.isAccepted()); | 
| 407 |  | 
| 408 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "edit" ); | 
| 409 |     QVERIFY(item); | 
| 410 |     QVERIFY(item->hasActiveFocus()); | 
| 411 |  | 
| 412 |     // BackTab: edit->button22 | 
| 413 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 414 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 415 |     QVERIFY(key.isAccepted()); | 
| 416 |  | 
| 417 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button22" ); | 
| 418 |     QVERIFY(item); | 
| 419 |     QVERIFY(item->hasActiveFocus()); | 
| 420 |  | 
| 421 |     // BackTab: button22->button21 | 
| 422 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 423 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 424 |     QVERIFY(key.isAccepted()); | 
| 425 |  | 
| 426 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button21" ); | 
| 427 |     QVERIFY(item); | 
| 428 |     QVERIFY(item->hasActiveFocus()); | 
| 429 |  | 
| 430 |     // BackTab: button21->sub2 | 
| 431 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 432 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 433 |     QVERIFY(key.isAccepted()); | 
| 434 |  | 
| 435 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "sub2" ); | 
| 436 |     QVERIFY(item); | 
| 437 |     QVERIFY(item->hasActiveFocus()); | 
| 438 |  | 
| 439 |     // BackTab: sub2->button12 | 
| 440 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 441 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 442 |     QVERIFY(key.isAccepted()); | 
| 443 |  | 
| 444 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button12" ); | 
| 445 |     QVERIFY(item); | 
| 446 |     QVERIFY(item->hasActiveFocus()); | 
| 447 |  | 
| 448 |     // BackTab: button12->button11 | 
| 449 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 450 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 451 |     QVERIFY(key.isAccepted()); | 
| 452 |  | 
| 453 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button11" ); | 
| 454 |     QVERIFY(item); | 
| 455 |     QVERIFY(item->hasActiveFocus()); | 
| 456 |  | 
| 457 |     // BackTab: button11->edit | 
| 458 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 459 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 460 |     QVERIFY(key.isAccepted()); | 
| 461 |  | 
| 462 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "edit" ); | 
| 463 |     QVERIFY(item); | 
| 464 |     QVERIFY(item->hasActiveFocus()); | 
| 465 |  | 
| 466 |     delete window; | 
| 467 | } | 
| 468 |  | 
| 469 | void tst_QQuickItem::activeFocusOnTab2() | 
| 470 | { | 
| 471 |     if (!qt_tab_all_widgets()) | 
| 472 |         QSKIP("This function doesn't support NOT iterating all." ); | 
| 473 |  | 
| 474 |     QQuickView *window = new QQuickView(nullptr); | 
| 475 |     window->setBaseSize(QSize(800,600)); | 
| 476 |  | 
| 477 |     window->setSource(testFileUrl(fileName: "activeFocusOnTab.qml" )); | 
| 478 |     window->show(); | 
| 479 |     window->requestActivate(); | 
| 480 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 481 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 482 |  | 
| 483 |     // original: button12 | 
| 484 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button12" ); | 
| 485 |     QVERIFY(item); | 
| 486 |     QVERIFY(item->hasActiveFocus()); | 
| 487 |  | 
| 488 |     // BackTab: button12->button11 | 
| 489 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 490 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 491 |     QVERIFY(key.isAccepted()); | 
| 492 |  | 
| 493 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button11" ); | 
| 494 |     QVERIFY(item); | 
| 495 |     QVERIFY(item->hasActiveFocus()); | 
| 496 |  | 
| 497 |     // BackTab: button11->edit | 
| 498 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 499 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 500 |     QVERIFY(key.isAccepted()); | 
| 501 |  | 
| 502 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "edit" ); | 
| 503 |     QVERIFY(item); | 
| 504 |     QVERIFY(item->hasActiveFocus()); | 
| 505 |  | 
| 506 |     delete window; | 
| 507 | } | 
| 508 |  | 
| 509 | void tst_QQuickItem::activeFocusOnTab3() | 
| 510 | { | 
| 511 |     if (!qt_tab_all_widgets()) | 
| 512 |         QSKIP("This function doesn't support NOT iterating all." ); | 
| 513 |  | 
| 514 |     QQuickView *window = new QQuickView(nullptr); | 
| 515 |     window->setBaseSize(QSize(800,600)); | 
| 516 |  | 
| 517 |     window->setSource(testFileUrl(fileName: "activeFocusOnTab3.qml" )); | 
| 518 |     window->show(); | 
| 519 |     window->requestActivate(); | 
| 520 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 521 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 522 |  | 
| 523 |     // original: button1 | 
| 524 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button1" ); | 
| 525 |     QVERIFY(item); | 
| 526 |     QVERIFY(item->hasActiveFocus()); | 
| 527 |  | 
| 528 |     // 4 Tabs: button1->button2, through a repeater | 
| 529 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1);; | 
| 530 |     for (int i = 0; i < 4; ++i) { | 
| 531 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 532 |         QVERIFY(key.isAccepted()); | 
| 533 |     } | 
| 534 |  | 
| 535 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button2" ); | 
| 536 |     QVERIFY(item); | 
| 537 |     QVERIFY(item->hasActiveFocus()); | 
| 538 |  | 
| 539 |     // 4 Tabs: button2->button3, through a row | 
| 540 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1);; | 
| 541 |     for (int i = 0; i < 4; ++i) { | 
| 542 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 543 |         QVERIFY(key.isAccepted()); | 
| 544 |     } | 
| 545 |  | 
| 546 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button3" ); | 
| 547 |     QVERIFY(item); | 
| 548 |     QVERIFY(item->hasActiveFocus()); | 
| 549 |  | 
| 550 |     // 4 Tabs: button3->button4, through a flow | 
| 551 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1);; | 
| 552 |     for (int i = 0; i < 4; ++i) { | 
| 553 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 554 |         QVERIFY(key.isAccepted()); | 
| 555 |     } | 
| 556 |  | 
| 557 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button4" ); | 
| 558 |     QVERIFY(item); | 
| 559 |     QVERIFY(item->hasActiveFocus()); | 
| 560 |  | 
| 561 |     // 4 Tabs: button4->button5, through a focusscope | 
| 562 |     // parent is activeFocusOnTab:false, one of children is focus:true | 
| 563 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1);; | 
| 564 |     for (int i = 0; i < 4; ++i) { | 
| 565 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 566 |         QVERIFY(key.isAccepted()); | 
| 567 |     } | 
| 568 |  | 
| 569 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button5" ); | 
| 570 |     QVERIFY(item); | 
| 571 |     QVERIFY(item->hasActiveFocus()); | 
| 572 |  | 
| 573 |     // 4 Tabs: button5->button6, through a focusscope | 
| 574 |     // parent is activeFocusOnTab:true, one of children is focus:true | 
| 575 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1);; | 
| 576 |     for (int i = 0; i < 4; ++i) { | 
| 577 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 578 |         QVERIFY(key.isAccepted()); | 
| 579 |     } | 
| 580 |  | 
| 581 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button6" ); | 
| 582 |     QVERIFY(item); | 
| 583 |     QVERIFY(item->hasActiveFocus()); | 
| 584 |  | 
| 585 |     // 5 Tabs: button6->button7, through a focusscope | 
| 586 |     // parent is activeFocusOnTab:true, none of children is focus:true | 
| 587 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1);; | 
| 588 |     for (int i = 0; i < 5; ++i) { | 
| 589 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 590 |         QVERIFY(key.isAccepted()); | 
| 591 |     } | 
| 592 |  | 
| 593 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button7" ); | 
| 594 |     QVERIFY(item); | 
| 595 |     QVERIFY(item->hasActiveFocus()); | 
| 596 |  | 
| 597 |     // 4 BackTabs: button7->button6, through a focusscope | 
| 598 |     // parent is activeFocusOnTab:true, one of children got focus:true in previous code | 
| 599 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 600 |     for (int i = 0; i < 4; ++i) { | 
| 601 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 602 |         QVERIFY(key.isAccepted()); | 
| 603 |     } | 
| 604 |  | 
| 605 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button6" ); | 
| 606 |     QVERIFY(item); | 
| 607 |     QVERIFY(item->hasActiveFocus()); | 
| 608 |  | 
| 609 |     // 4 Tabs: button6->button7, through a focusscope | 
| 610 |     // parent is activeFocusOnTab:true, one of children got focus:true in previous code | 
| 611 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1);; | 
| 612 |     for (int i = 0; i < 4; ++i) { | 
| 613 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 614 |         QVERIFY(key.isAccepted()); | 
| 615 |     } | 
| 616 |  | 
| 617 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button7" ); | 
| 618 |     QVERIFY(item); | 
| 619 |     QVERIFY(item->hasActiveFocus()); | 
| 620 |  | 
| 621 |     // 4 BackTabs: button7->button6, through a focusscope | 
| 622 |     // parent is activeFocusOnTab:true, one of children got focus:true in previous code | 
| 623 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 624 |     for (int i = 0; i < 4; ++i) { | 
| 625 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 626 |         QVERIFY(key.isAccepted()); | 
| 627 |     } | 
| 628 |  | 
| 629 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button6" ); | 
| 630 |     QVERIFY(item); | 
| 631 |     QVERIFY(item->hasActiveFocus()); | 
| 632 |  | 
| 633 |     // 4 BackTabs: button6->button5, through a focusscope(parent is activeFocusOnTab: false) | 
| 634 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 635 |     for (int i = 0; i < 4; ++i) { | 
| 636 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 637 |         QVERIFY(key.isAccepted()); | 
| 638 |     } | 
| 639 |  | 
| 640 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button5" ); | 
| 641 |     QVERIFY(item); | 
| 642 |     QVERIFY(item->hasActiveFocus()); | 
| 643 |  | 
| 644 |     // 4 BackTabs: button5->button4, through a focusscope(parent is activeFocusOnTab: false) | 
| 645 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 646 |     for (int i = 0; i < 4; ++i) { | 
| 647 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 648 |         QVERIFY(key.isAccepted()); | 
| 649 |     } | 
| 650 |  | 
| 651 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button4" ); | 
| 652 |     QVERIFY(item); | 
| 653 |     QVERIFY(item->hasActiveFocus()); | 
| 654 |  | 
| 655 |     // 4 BackTabs: button4->button3, through a flow | 
| 656 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 657 |     for (int i = 0; i < 4; ++i) { | 
| 658 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 659 |         QVERIFY(key.isAccepted()); | 
| 660 |     } | 
| 661 |  | 
| 662 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button3" ); | 
| 663 |     QVERIFY(item); | 
| 664 |     QVERIFY(item->hasActiveFocus()); | 
| 665 |  | 
| 666 |     // 4 BackTabs: button3->button2, through a row | 
| 667 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 668 |     for (int i = 0; i < 4; ++i) { | 
| 669 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 670 |         QVERIFY(key.isAccepted()); | 
| 671 |     } | 
| 672 |  | 
| 673 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button2" ); | 
| 674 |     QVERIFY(item); | 
| 675 |     QVERIFY(item->hasActiveFocus()); | 
| 676 |  | 
| 677 |     // 4 BackTabs: button2->button1, through a repeater | 
| 678 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 679 |     for (int i = 0; i < 4; ++i) { | 
| 680 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 681 |         QVERIFY(key.isAccepted()); | 
| 682 |     } | 
| 683 |  | 
| 684 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button1" ); | 
| 685 |     QVERIFY(item); | 
| 686 |     QVERIFY(item->hasActiveFocus()); | 
| 687 |  | 
| 688 |     delete window; | 
| 689 | } | 
| 690 |  | 
| 691 | void tst_QQuickItem::activeFocusOnTab4() | 
| 692 | { | 
| 693 |     if (!qt_tab_all_widgets()) | 
| 694 |         QSKIP("This function doesn't support NOT iterating all." ); | 
| 695 |  | 
| 696 |     QQuickView *window = new QQuickView(nullptr); | 
| 697 |     window->setBaseSize(QSize(800,600)); | 
| 698 |  | 
| 699 |     window->setSource(testFileUrl(fileName: "activeFocusOnTab4.qml" )); | 
| 700 |     window->show(); | 
| 701 |     window->requestActivate(); | 
| 702 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 703 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 704 |  | 
| 705 |     // original: button11 | 
| 706 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button11" ); | 
| 707 |     item->setActiveFocusOnTab(true); | 
| 708 |     QVERIFY(item); | 
| 709 |     QVERIFY(item->hasActiveFocus()); | 
| 710 |  | 
| 711 |     // Tab: button11->button21 | 
| 712 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 713 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 714 |     QVERIFY(key.isAccepted()); | 
| 715 |  | 
| 716 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button21" ); | 
| 717 |     QVERIFY(item); | 
| 718 |     QVERIFY(item->hasActiveFocus()); | 
| 719 |  | 
| 720 |     delete window; | 
| 721 | } | 
| 722 |  | 
| 723 | void tst_QQuickItem::activeFocusOnTab5() | 
| 724 | { | 
| 725 |     if (!qt_tab_all_widgets()) | 
| 726 |         QSKIP("This function doesn't support NOT iterating all." ); | 
| 727 |  | 
| 728 |     QQuickView *window = new QQuickView(nullptr); | 
| 729 |     window->setBaseSize(QSize(800,600)); | 
| 730 |  | 
| 731 |     window->setSource(testFileUrl(fileName: "activeFocusOnTab4.qml" )); | 
| 732 |     window->show(); | 
| 733 |     window->requestActivate(); | 
| 734 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 735 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 736 |  | 
| 737 |     // original: button11 in sub1 | 
| 738 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button11" ); | 
| 739 |     QVERIFY(item); | 
| 740 |     QVERIFY(item->hasActiveFocus()); | 
| 741 |  | 
| 742 |     QQuickItem *item2 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "sub1" ); | 
| 743 |     item2->setActiveFocusOnTab(true); | 
| 744 |  | 
| 745 |     // Tab: button11->button21 | 
| 746 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 747 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 748 |     QVERIFY(key.isAccepted()); | 
| 749 |  | 
| 750 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button21" ); | 
| 751 |     QVERIFY(item); | 
| 752 |     QVERIFY(item->hasActiveFocus()); | 
| 753 |  | 
| 754 |     delete window; | 
| 755 | } | 
| 756 |  | 
| 757 | void tst_QQuickItem::activeFocusOnTab6() | 
| 758 | { | 
| 759 |     if (qt_tab_all_widgets()) | 
| 760 |         QSKIP("This function doesn't support iterating all." ); | 
| 761 |  | 
| 762 |     QQuickView *window = new QQuickView(nullptr); | 
| 763 |     window->setBaseSize(QSize(800,600)); | 
| 764 |  | 
| 765 |     window->setSource(testFileUrl(fileName: "activeFocusOnTab6.qml" )); | 
| 766 |     window->show(); | 
| 767 |     window->requestActivate(); | 
| 768 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 769 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 770 |  | 
| 771 |     // original: button12 | 
| 772 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button12" ); | 
| 773 |     QVERIFY(item); | 
| 774 |     QVERIFY(item->hasActiveFocus()); | 
| 775 |  | 
| 776 |     // Tab: button12->edit | 
| 777 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 778 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 779 |     QVERIFY(key.isAccepted()); | 
| 780 |  | 
| 781 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "edit" ); | 
| 782 |     QVERIFY(item); | 
| 783 |     QVERIFY(item->hasActiveFocus()); | 
| 784 |  | 
| 785 |     // BackTab: edit->button12 | 
| 786 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 787 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 788 |     QVERIFY(key.isAccepted()); | 
| 789 |  | 
| 790 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button12" ); | 
| 791 |     QVERIFY(item); | 
| 792 |     QVERIFY(item->hasActiveFocus()); | 
| 793 |  | 
| 794 |     // BackTab: button12->button11 | 
| 795 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 796 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 797 |     QVERIFY(key.isAccepted()); | 
| 798 |  | 
| 799 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button11" ); | 
| 800 |     QVERIFY(item); | 
| 801 |     QVERIFY(item->hasActiveFocus()); | 
| 802 |  | 
| 803 |     // BackTab: button11->edit | 
| 804 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 805 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 806 |     QVERIFY(key.isAccepted()); | 
| 807 |  | 
| 808 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "edit" ); | 
| 809 |     QVERIFY(item); | 
| 810 |     QVERIFY(item->hasActiveFocus()); | 
| 811 |  | 
| 812 |     delete window; | 
| 813 | } | 
| 814 |  | 
| 815 | void tst_QQuickItem::activeFocusOnTab7() | 
| 816 | { | 
| 817 |     if (qt_tab_all_widgets()) | 
| 818 |         QSKIP("This function doesn't support iterating all." ); | 
| 819 |  | 
| 820 |     QQuickView *window = new QQuickView(nullptr); | 
| 821 |     window->setBaseSize(QSize(300,300)); | 
| 822 |  | 
| 823 |     window->setSource(testFileUrl(fileName: "activeFocusOnTab7.qml" )); | 
| 824 |     window->show(); | 
| 825 |     window->requestActivate(); | 
| 826 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 827 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 828 |  | 
| 829 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button1" ); | 
| 830 |     QVERIFY(item); | 
| 831 |     item->forceActiveFocus(); | 
| 832 |     QVERIFY(item->hasActiveFocus()); | 
| 833 |  | 
| 834 |     // Tab: button1->button1 | 
| 835 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 836 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 837 |     QVERIFY(!key.isAccepted()); | 
| 838 |  | 
| 839 |     QVERIFY(item->hasActiveFocus()); | 
| 840 |  | 
| 841 |     // BackTab: button1->button1 | 
| 842 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 843 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 844 |     QVERIFY(!key.isAccepted()); | 
| 845 |  | 
| 846 |     QVERIFY(item->hasActiveFocus()); | 
| 847 |  | 
| 848 |     delete window; | 
| 849 | } | 
| 850 |  | 
| 851 | void tst_QQuickItem::activeFocusOnTab8() | 
| 852 | { | 
| 853 |     QQuickView *window = new QQuickView(nullptr); | 
| 854 |     window->setBaseSize(QSize(300,300)); | 
| 855 |  | 
| 856 |     window->setSource(testFileUrl(fileName: "activeFocusOnTab8.qml" )); | 
| 857 |     window->show(); | 
| 858 |     window->requestActivate(); | 
| 859 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 860 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 861 |  | 
| 862 |     QQuickItem *content = window->contentItem(); | 
| 863 |     QVERIFY(content); | 
| 864 |     QVERIFY(content->hasActiveFocus()); | 
| 865 |  | 
| 866 |     QQuickItem *button1 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button1" ); | 
| 867 |     QVERIFY(button1); | 
| 868 |     QVERIFY(!button1->hasActiveFocus()); | 
| 869 |  | 
| 870 |     QQuickItem *button2 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button2" ); | 
| 871 |     QVERIFY(button2); | 
| 872 |     QVERIFY(!button2->hasActiveFocus()); | 
| 873 |  | 
| 874 |     // Tab: contentItem->button1 | 
| 875 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 876 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 877 |     QVERIFY(key.isAccepted()); | 
| 878 |  | 
| 879 |     QVERIFY(button1->hasActiveFocus()); | 
| 880 |  | 
| 881 |     // Tab: button1->button2 | 
| 882 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 883 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 884 |     QVERIFY(key.isAccepted()); | 
| 885 |  | 
| 886 |     QVERIFY(button2->hasActiveFocus()); | 
| 887 |     QVERIFY(!button1->hasActiveFocus()); | 
| 888 |  | 
| 889 |     // BackTab: button2->button1 | 
| 890 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 891 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 892 |     QVERIFY(key.isAccepted()); | 
| 893 |  | 
| 894 |     QVERIFY(button1->hasActiveFocus()); | 
| 895 |     QVERIFY(!button2->hasActiveFocus()); | 
| 896 |  | 
| 897 |     delete window; | 
| 898 | } | 
| 899 |  | 
| 900 | void tst_QQuickItem::activeFocusOnTab9() | 
| 901 | { | 
| 902 |     if (qt_tab_all_widgets()) | 
| 903 |         QSKIP("This function doesn't support iterating all." ); | 
| 904 |  | 
| 905 |     QQuickView *window = new QQuickView(nullptr); | 
| 906 |     window->setBaseSize(QSize(300,300)); | 
| 907 |  | 
| 908 |     window->setSource(testFileUrl(fileName: "activeFocusOnTab9.qml" )); | 
| 909 |     window->show(); | 
| 910 |     window->requestActivate(); | 
| 911 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 912 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 913 |  | 
| 914 |     QQuickItem *content = window->contentItem(); | 
| 915 |     QVERIFY(content); | 
| 916 |     QVERIFY(content->hasActiveFocus()); | 
| 917 |  | 
| 918 |     QQuickItem *textinput1 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "textinput1" ); | 
| 919 |     QVERIFY(textinput1); | 
| 920 |     QQuickItem *textedit1 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "textedit1" ); | 
| 921 |     QVERIFY(textedit1); | 
| 922 |  | 
| 923 |     QVERIFY(!textinput1->hasActiveFocus()); | 
| 924 |     textinput1->forceActiveFocus(); | 
| 925 |     QVERIFY(textinput1->hasActiveFocus()); | 
| 926 |  | 
| 927 |     // Tab: textinput1->textedit1 | 
| 928 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 929 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 930 |     QVERIFY(key.isAccepted()); | 
| 931 |  | 
| 932 |     QVERIFY(textedit1->hasActiveFocus()); | 
| 933 |  | 
| 934 |     // BackTab: textedit1->textinput1 | 
| 935 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 936 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 937 |     QVERIFY(key.isAccepted()); | 
| 938 |  | 
| 939 |     QVERIFY(textinput1->hasActiveFocus()); | 
| 940 |  | 
| 941 |     // BackTab: textinput1->textedit1 | 
| 942 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 943 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 944 |     QVERIFY(key.isAccepted()); | 
| 945 |  | 
| 946 |     QVERIFY(textedit1->hasActiveFocus()); | 
| 947 |  | 
| 948 |     delete window; | 
| 949 | } | 
| 950 |  | 
| 951 | void tst_QQuickItem::activeFocusOnTab10() | 
| 952 | { | 
| 953 |     if (!qt_tab_all_widgets()) | 
| 954 |         QSKIP("This function doesn't support NOT iterating all." ); | 
| 955 |  | 
| 956 |     QQuickView *window = new QQuickView(nullptr); | 
| 957 |     window->setBaseSize(QSize(300,300)); | 
| 958 |  | 
| 959 |     window->setSource(testFileUrl(fileName: "activeFocusOnTab9.qml" )); | 
| 960 |     window->show(); | 
| 961 |     window->requestActivate(); | 
| 962 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 963 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 964 |  | 
| 965 |     QQuickItem *content = window->contentItem(); | 
| 966 |     QVERIFY(content); | 
| 967 |     QVERIFY(content->hasActiveFocus()); | 
| 968 |  | 
| 969 |     QQuickItem *textinput1 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "textinput1" ); | 
| 970 |     QVERIFY(textinput1); | 
| 971 |     QQuickItem *textedit1 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "textedit1" ); | 
| 972 |     QVERIFY(textedit1); | 
| 973 |     QQuickItem *textinput2 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "textinput2" ); | 
| 974 |     QVERIFY(textinput2); | 
| 975 |     QQuickItem *textedit2 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "textedit2" ); | 
| 976 |     QVERIFY(textedit2); | 
| 977 |  | 
| 978 |     QVERIFY(!textinput1->hasActiveFocus()); | 
| 979 |     textinput1->forceActiveFocus(); | 
| 980 |     QVERIFY(textinput1->hasActiveFocus()); | 
| 981 |  | 
| 982 |     // Tab: textinput1->textinput2 | 
| 983 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 984 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 985 |     QVERIFY(key.isAccepted()); | 
| 986 |  | 
| 987 |     QVERIFY(textinput2->hasActiveFocus()); | 
| 988 |  | 
| 989 |     // Tab: textinput2->textedit1 | 
| 990 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 991 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 992 |     QVERIFY(key.isAccepted()); | 
| 993 |  | 
| 994 |     QVERIFY(textedit1->hasActiveFocus()); | 
| 995 |  | 
| 996 |     // BackTab: textedit1->textinput2 | 
| 997 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 998 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 999 |     QVERIFY(key.isAccepted()); | 
| 1000 |  | 
| 1001 |     QVERIFY(textinput2->hasActiveFocus()); | 
| 1002 |  | 
| 1003 |     // BackTab: textinput2->textinput1 | 
| 1004 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 1005 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1006 |     QVERIFY(key.isAccepted()); | 
| 1007 |  | 
| 1008 |     QVERIFY(textinput1->hasActiveFocus()); | 
| 1009 |  | 
| 1010 |     // BackTab: textinput1->textedit2 | 
| 1011 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 1012 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1013 |     QVERIFY(key.isAccepted()); | 
| 1014 |  | 
| 1015 |     QVERIFY(textedit2->hasActiveFocus()); | 
| 1016 |  | 
| 1017 |     // BackTab: textedit2->textedit1 | 
| 1018 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 1019 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1020 |     QVERIFY(key.isAccepted()); | 
| 1021 |  | 
| 1022 |     QVERIFY(textedit1->hasActiveFocus()); | 
| 1023 |  | 
| 1024 |     // BackTab: textedit1->textinput2 | 
| 1025 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "" , false, 1); | 
| 1026 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1027 |     QVERIFY(key.isAccepted()); | 
| 1028 |  | 
| 1029 |     QVERIFY(textinput2->hasActiveFocus()); | 
| 1030 |  | 
| 1031 |     delete window; | 
| 1032 | } | 
| 1033 |  | 
| 1034 | void tst_QQuickItem::activeFocusOnTab_infiniteLoop_data() | 
| 1035 | { | 
| 1036 |     QTest::addColumn<QUrl>(name: "source" ); | 
| 1037 |     QTest::newRow(dataTag: "infiniteLoop" ) << testFileUrl(fileName: "activeFocusOnTab_infiniteLoop.qml" );  // QTBUG-68271 | 
| 1038 |     QTest::newRow(dataTag: "infiniteLoop2" ) << testFileUrl(fileName: "activeFocusOnTab_infiniteLoop2.qml" );// QTBUG-81510 | 
| 1039 | } | 
| 1040 |  | 
| 1041 | void tst_QQuickItem::activeFocusOnTab_infiniteLoop() | 
| 1042 | { | 
| 1043 |     QFETCH(QUrl, source); | 
| 1044 |  | 
| 1045 |     // create a window where the currently focused item is not visible | 
| 1046 |     QScopedPointer<QQuickView>window(new QQuickView()); | 
| 1047 |     window->setSource(source); | 
| 1048 |     window->show(); | 
| 1049 |     auto *hiddenChild = findItem<QQuickItem>(parent: window->rootObject(), objectName: "hiddenChild" ); | 
| 1050 |     QVERIFY(hiddenChild); | 
| 1051 |  | 
| 1052 |     // move the focus - this used to result in an infinite loop | 
| 1053 |     auto *item = hiddenChild->nextItemInFocusChain(); | 
| 1054 |     // focus is moved to the root object since there is no other candidate | 
| 1055 |     QCOMPARE(item, window->rootObject()); | 
| 1056 |     item = hiddenChild->nextItemInFocusChain(forward: false); | 
| 1057 |     QCOMPARE(item, window->rootObject()); | 
| 1058 | } | 
| 1059 |  | 
| 1060 | void tst_QQuickItem::nextItemInFocusChain() | 
| 1061 | { | 
| 1062 |     if (!qt_tab_all_widgets()) | 
| 1063 |         QSKIP("This function doesn't support NOT iterating all." ); | 
| 1064 |  | 
| 1065 |     QQuickView *window = new QQuickView(nullptr); | 
| 1066 |     window->setBaseSize(QSize(800,600)); | 
| 1067 |  | 
| 1068 |     window->setSource(testFileUrl(fileName: "activeFocusOnTab.qml" )); | 
| 1069 |     window->show(); | 
| 1070 |     window->requestActivate(); | 
| 1071 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 1072 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 1073 |  | 
| 1074 |     QQuickItem *button11 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button11" ); | 
| 1075 |     QVERIFY(button11); | 
| 1076 |     QQuickItem *button12 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button12" ); | 
| 1077 |     QVERIFY(button12); | 
| 1078 |  | 
| 1079 |     QQuickItem *sub2 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "sub2" ); | 
| 1080 |     QVERIFY(sub2); | 
| 1081 |     QQuickItem *button21 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button21" ); | 
| 1082 |     QVERIFY(button21); | 
| 1083 |     QQuickItem *button22 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button22" ); | 
| 1084 |     QVERIFY(button22); | 
| 1085 |  | 
| 1086 |     QQuickItem *edit = findItem<QQuickItem>(parent: window->rootObject(), objectName: "edit" ); | 
| 1087 |     QVERIFY(edit); | 
| 1088 |  | 
| 1089 |     QQuickItem *next, *prev; | 
| 1090 |  | 
| 1091 |     next = button11->nextItemInFocusChain(forward: true); | 
| 1092 |     QVERIFY(next); | 
| 1093 |     QCOMPARE(next, button12); | 
| 1094 |     prev = button11->nextItemInFocusChain(forward: false); | 
| 1095 |     QVERIFY(prev); | 
| 1096 |     QCOMPARE(prev, edit); | 
| 1097 |  | 
| 1098 |     next = button12->nextItemInFocusChain(); | 
| 1099 |     QVERIFY(next); | 
| 1100 |     QCOMPARE(next, sub2); | 
| 1101 |     prev = button12->nextItemInFocusChain(forward: false); | 
| 1102 |     QVERIFY(prev); | 
| 1103 |     QCOMPARE(prev, button11); | 
| 1104 |  | 
| 1105 |     next = sub2->nextItemInFocusChain(forward: true); | 
| 1106 |     QVERIFY(next); | 
| 1107 |     QCOMPARE(next, button21); | 
| 1108 |     prev = sub2->nextItemInFocusChain(forward: false); | 
| 1109 |     QVERIFY(prev); | 
| 1110 |     QCOMPARE(prev, button12); | 
| 1111 |  | 
| 1112 |     next = button21->nextItemInFocusChain(); | 
| 1113 |     QVERIFY(next); | 
| 1114 |     QCOMPARE(next, button22); | 
| 1115 |     prev = button21->nextItemInFocusChain(forward: false); | 
| 1116 |     QVERIFY(prev); | 
| 1117 |     QCOMPARE(prev, sub2); | 
| 1118 |  | 
| 1119 |     next = button22->nextItemInFocusChain(forward: true); | 
| 1120 |     QVERIFY(next); | 
| 1121 |     QCOMPARE(next, edit); | 
| 1122 |     prev = button22->nextItemInFocusChain(forward: false); | 
| 1123 |     QVERIFY(prev); | 
| 1124 |     QCOMPARE(prev, button21); | 
| 1125 |  | 
| 1126 |     next = edit->nextItemInFocusChain(); | 
| 1127 |     QVERIFY(next); | 
| 1128 |     QCOMPARE(next, button11); | 
| 1129 |     prev = edit->nextItemInFocusChain(forward: false); | 
| 1130 |     QVERIFY(prev); | 
| 1131 |     QCOMPARE(prev, button22); | 
| 1132 |  | 
| 1133 |     delete window; | 
| 1134 | } | 
| 1135 |  | 
| 1136 | void tst_QQuickItem::nextItemInFocusChain2() | 
| 1137 | { | 
| 1138 |     if (qt_tab_all_widgets()) | 
| 1139 |         QSKIP("This function doesn't support iterating all." ); | 
| 1140 |  | 
| 1141 |     QQuickView *window = new QQuickView(nullptr); | 
| 1142 |     window->setBaseSize(QSize(800,600)); | 
| 1143 |  | 
| 1144 |     window->setSource(testFileUrl(fileName: "activeFocusOnTab6.qml" )); | 
| 1145 |     window->show(); | 
| 1146 |     window->requestActivate(); | 
| 1147 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 1148 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 1149 |  | 
| 1150 |     QQuickItem *button11 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button11" ); | 
| 1151 |     QVERIFY(button11); | 
| 1152 |     QQuickItem *button12 = findItem<QQuickItem>(parent: window->rootObject(), objectName: "button12" ); | 
| 1153 |     QVERIFY(button12); | 
| 1154 |  | 
| 1155 |     QQuickItem *edit = findItem<QQuickItem>(parent: window->rootObject(), objectName: "edit" ); | 
| 1156 |     QVERIFY(edit); | 
| 1157 |  | 
| 1158 |     QQuickItem *next, *prev; | 
| 1159 |  | 
| 1160 |     next = button11->nextItemInFocusChain(forward: true); | 
| 1161 |     QVERIFY(next); | 
| 1162 |     QCOMPARE(next, button12); | 
| 1163 |     prev = button11->nextItemInFocusChain(forward: false); | 
| 1164 |     QVERIFY(prev); | 
| 1165 |     QCOMPARE(prev, edit); | 
| 1166 |  | 
| 1167 |     next = button12->nextItemInFocusChain(); | 
| 1168 |     QVERIFY(next); | 
| 1169 |     QCOMPARE(next, edit); | 
| 1170 |     prev = button12->nextItemInFocusChain(forward: false); | 
| 1171 |     QVERIFY(prev); | 
| 1172 |     QCOMPARE(prev, button11); | 
| 1173 |  | 
| 1174 |     next = edit->nextItemInFocusChain(); | 
| 1175 |     QVERIFY(next); | 
| 1176 |     QCOMPARE(next, button11); | 
| 1177 |     prev = edit->nextItemInFocusChain(forward: false); | 
| 1178 |     QVERIFY(prev); | 
| 1179 |     QCOMPARE(prev, button12); | 
| 1180 |  | 
| 1181 |     delete window; | 
| 1182 | } | 
| 1183 |  | 
| 1184 | void tst_QQuickItem::nextItemInFocusChain3() | 
| 1185 | { | 
| 1186 |     QQuickView *window = new QQuickView(nullptr); | 
| 1187 |     window->setBaseSize(QSize(800,600)); | 
| 1188 |  | 
| 1189 |     window->setSource(testFileUrl(fileName: "nextItemInFocusChain3.qml" )); | 
| 1190 |     window->show(); | 
| 1191 |     window->requestActivate(); | 
| 1192 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 1193 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 1194 | } | 
| 1195 |  | 
| 1196 | void verifyTabFocusChain(QQuickView *window, const char **focusChain, bool forward) | 
| 1197 | { | 
| 1198 |     int idx = 0; | 
| 1199 |     for (const char **objectName = focusChain; *objectName; ++objectName, ++idx) { | 
| 1200 |         const QString &descrStr = QString("idx=%1 objectName=\"%2\"" ).arg(a: idx).arg(a: *objectName); | 
| 1201 |         const char *descr = descrStr.toLocal8Bit().data(); | 
| 1202 |         QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, forward ? Qt::NoModifier : Qt::ShiftModifier); | 
| 1203 |         QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1204 |         QVERIFY2(key.isAccepted(), descr); | 
| 1205 |  | 
| 1206 |         QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: *objectName); | 
| 1207 |         QVERIFY2(item, descr); | 
| 1208 |         QVERIFY2(item->hasActiveFocus(), descr); | 
| 1209 |     } | 
| 1210 | } | 
| 1211 |  | 
| 1212 | void tst_QQuickItem::tabFence() | 
| 1213 | { | 
| 1214 |     QQuickView *window = new QQuickView(nullptr); | 
| 1215 |     window->setBaseSize(QSize(800,600)); | 
| 1216 |  | 
| 1217 |     window->setSource(testFileUrl(fileName: "tabFence.qml" )); | 
| 1218 |     window->show(); | 
| 1219 |     window->requestActivate(); | 
| 1220 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 1221 |     QVERIFY(QGuiApplication::focusWindow() == window); | 
| 1222 |     QVERIFY(window->rootObject()->hasActiveFocus()); | 
| 1223 |  | 
| 1224 |     const char *rootTabFocusChain[] = { | 
| 1225 |           "input1" , "input2" , "input3" , "input1" , nullptr | 
| 1226 |     }; | 
| 1227 |     verifyTabFocusChain(window, focusChain: rootTabFocusChain, forward: true /* forward */); | 
| 1228 |  | 
| 1229 |     const char *rootBacktabFocusChain[] = { | 
| 1230 |           "input3" , "input2" , "input1" , "input3" , nullptr | 
| 1231 |     }; | 
| 1232 |     verifyTabFocusChain(window, focusChain: rootBacktabFocusChain, forward: false /* forward */); | 
| 1233 |  | 
| 1234 |     // Give focus to input11 in fence1 | 
| 1235 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "input11" ); | 
| 1236 |     item->setFocus(true); | 
| 1237 |     QVERIFY(item); | 
| 1238 |     QVERIFY(item->hasActiveFocus()); | 
| 1239 |  | 
| 1240 |     const char *fence1TabFocusChain[] = { | 
| 1241 |           "input12" , "input13" , "input11" , "input12" , nullptr | 
| 1242 |     }; | 
| 1243 |     verifyTabFocusChain(window, focusChain: fence1TabFocusChain, forward: true /* forward */); | 
| 1244 |  | 
| 1245 |     const char *fence1BacktabFocusChain[] = { | 
| 1246 |           "input11" , "input13" , "input12" , "input11" , nullptr | 
| 1247 |     }; | 
| 1248 |     verifyTabFocusChain(window, focusChain: fence1BacktabFocusChain, forward: false /* forward */); | 
| 1249 | } | 
| 1250 |  | 
| 1251 | void tst_QQuickItem::qtbug_50516() | 
| 1252 | { | 
| 1253 |     QQuickView *window = new QQuickView(nullptr); | 
| 1254 |     window->setBaseSize(QSize(800,600)); | 
| 1255 |  | 
| 1256 |     window->setSource(testFileUrl(fileName: "qtbug_50516.qml" )); | 
| 1257 |     window->show(); | 
| 1258 |     window->requestActivate(); | 
| 1259 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 1260 |     QVERIFY(QGuiApplication::focusWindow() == window); | 
| 1261 |     QVERIFY(window->rootObject()->hasActiveFocus()); | 
| 1262 |  | 
| 1263 |     QQuickItem *contentItem = window->rootObject(); | 
| 1264 |     QQuickItem *next = contentItem->nextItemInFocusChain(forward: true); | 
| 1265 |     QCOMPARE(next, contentItem); | 
| 1266 |     next = contentItem->nextItemInFocusChain(forward: false); | 
| 1267 |     QCOMPARE(next, contentItem); | 
| 1268 |  | 
| 1269 |     delete window; | 
| 1270 | } | 
| 1271 |  | 
| 1272 | void tst_QQuickItem::qtbug_50516_2_data() | 
| 1273 | { | 
| 1274 |     QTest::addColumn<QString>(name: "filename" ); | 
| 1275 |     QTest::addColumn<QString>(name: "item1" ); | 
| 1276 |     QTest::addColumn<QString>(name: "item2" ); | 
| 1277 |  | 
| 1278 |     QTest::newRow(dataTag: "FocusScope TabFence with one Item(focused)" ) | 
| 1279 |             << QStringLiteral("qtbug_50516_2_1.qml" ) << QStringLiteral("root" ) << QStringLiteral("root" ); | 
| 1280 |     QTest::newRow(dataTag: "FocusScope TabFence with one Item(unfocused)" ) | 
| 1281 |             << QStringLiteral("qtbug_50516_2_2.qml" ) << QStringLiteral("root" ) << QStringLiteral("root" ); | 
| 1282 |     QTest::newRow(dataTag: "FocusScope TabFence with two Items(focused)" ) | 
| 1283 |             << QStringLiteral("qtbug_50516_2_3.qml" ) << QStringLiteral("root" ) << QStringLiteral("root" ); | 
| 1284 |     QTest::newRow(dataTag: "FocusScope TabFence with two Items(unfocused)" ) | 
| 1285 |             << QStringLiteral("qtbug_50516_2_4.qml" ) << QStringLiteral("root" ) << QStringLiteral("root" ); | 
| 1286 |     QTest::newRow(dataTag: "FocusScope TabFence with one Item and one TextInput(unfocused)" ) | 
| 1287 |             << QStringLiteral("qtbug_50516_2_5.qml" ) << QStringLiteral("item1" ) << QStringLiteral("item1" ); | 
| 1288 |     QTest::newRow(dataTag: "FocusScope TabFence with two TextInputs(unfocused)" ) | 
| 1289 |             << QStringLiteral("qtbug_50516_2_6.qml" ) << QStringLiteral("item1" ) << QStringLiteral("item2" ); | 
| 1290 | } | 
| 1291 |  | 
| 1292 | void tst_QQuickItem::qtbug_50516_2() | 
| 1293 | { | 
| 1294 |     QFETCH(QString, filename); | 
| 1295 |     QFETCH(QString, item1); | 
| 1296 |     QFETCH(QString, item2); | 
| 1297 |  | 
| 1298 |     QQuickView *window = new QQuickView(nullptr); | 
| 1299 |     window->setBaseSize(QSize(800,600)); | 
| 1300 |  | 
| 1301 |     window->setSource(testFileUrl(fileName: filename)); | 
| 1302 |     window->show(); | 
| 1303 |     window->requestActivate(); | 
| 1304 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 1305 |     QVERIFY(QGuiApplication::focusWindow() == window); | 
| 1306 |     QVERIFY(window->rootObject()->hasActiveFocus()); | 
| 1307 |  | 
| 1308 |     QQuickItem *contentItem = window->rootObject(); | 
| 1309 |     QQuickItem *next = contentItem->nextItemInFocusChain(forward: true); | 
| 1310 |     QCOMPARE(next->objectName(), item1); | 
| 1311 |     next = contentItem->nextItemInFocusChain(forward: false); | 
| 1312 |     QCOMPARE(next->objectName(), item2); | 
| 1313 |  | 
| 1314 |     delete window; | 
| 1315 | } | 
| 1316 |  | 
| 1317 | void tst_QQuickItem::focusableItemReparentedToLoadedComponent() // QTBUG-89736 | 
| 1318 | { | 
| 1319 |     QQuickView window; | 
| 1320 |     window.setSource(testFileUrl(fileName: "focusableItemReparentedToLoadedComponent.qml" )); | 
| 1321 |     window.show(); | 
| 1322 |     QVERIFY(QTest::qWaitForWindowActive(&window)); | 
| 1323 |     QCOMPARE(QGuiApplication::focusWindow(), &window); | 
| 1324 |     QQuickLoader *loader = window.rootObject()->findChild<QQuickLoader *>(); | 
| 1325 |     QVERIFY(loader); | 
| 1326 |     QTRY_VERIFY(loader->status() == QQuickLoader::Ready); | 
| 1327 |     QQuickTextInput *textInput = window.rootObject()->findChild<QQuickTextInput *>(); | 
| 1328 |     QVERIFY(textInput); | 
| 1329 |  | 
| 1330 |     // click to focus | 
| 1331 |     QTest::mouseClick(window: &window, button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: {10, 10}); | 
| 1332 |     QTRY_VERIFY(textInput->hasActiveFocus()); | 
| 1333 |  | 
| 1334 |     // unload and reload | 
| 1335 |     auto component = loader->sourceComponent(); | 
| 1336 |     loader->resetSourceComponent(); | 
| 1337 |     QTRY_VERIFY(loader->status() == QQuickLoader::Null); | 
| 1338 |     loader->setSourceComponent(component); | 
| 1339 |     QTRY_VERIFY(loader->status() == QQuickLoader::Ready); | 
| 1340 |  | 
| 1341 |     // click to focus again | 
| 1342 |     QTest::mouseClick(window: &window, button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: {10, 10}); | 
| 1343 |     QTRY_VERIFY(textInput->hasActiveFocus()); | 
| 1344 | } | 
| 1345 |  | 
| 1346 | void tst_QQuickItem::keys() | 
| 1347 | { | 
| 1348 |     QQuickView *window = new QQuickView(nullptr); | 
| 1349 |     window->setBaseSize(QSize(240,320)); | 
| 1350 |  | 
| 1351 |     KeysTestObject *testObject = new KeysTestObject; | 
| 1352 |     window->rootContext()->setContextProperty("keysTestObject" , testObject); | 
| 1353 |  | 
| 1354 |     window->rootContext()->setContextProperty("enableKeyHanding" , QVariant(true)); | 
| 1355 |     window->rootContext()->setContextProperty("forwardeeVisible" , QVariant(true)); | 
| 1356 |  | 
| 1357 |     window->setSource(testFileUrl(fileName: "keystest.qml" )); | 
| 1358 |     window->show(); | 
| 1359 |     window->requestActivate(); | 
| 1360 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 1361 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 1362 |  | 
| 1363 |     QVERIFY(window->rootObject()); | 
| 1364 |     QCOMPARE(window->rootObject()->property("isEnabled" ).toBool(), true); | 
| 1365 |  | 
| 1366 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A" , false, 1); | 
| 1367 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1368 |     QCOMPARE(testObject->mKey, int(Qt::Key_A)); | 
| 1369 |     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A)); | 
| 1370 |     QCOMPARE(testObject->mText, QLatin1String("A" )); | 
| 1371 |     QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); | 
| 1372 |     QVERIFY(!key.isAccepted()); | 
| 1373 |  | 
| 1374 |     testObject->reset(); | 
| 1375 |  | 
| 1376 |     key = QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::ShiftModifier, "A" , false, 1); | 
| 1377 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1378 |     QCOMPARE(testObject->mKey, int(Qt::Key_A)); | 
| 1379 |     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A)); | 
| 1380 |     QCOMPARE(testObject->mText, QLatin1String("A" )); | 
| 1381 |     QCOMPARE(testObject->mModifiers, int(Qt::ShiftModifier)); | 
| 1382 |     QVERIFY(key.isAccepted()); | 
| 1383 |  | 
| 1384 |     testObject->reset(); | 
| 1385 |  | 
| 1386 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "" , false, 1); | 
| 1387 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1388 |     QCOMPARE(testObject->mKey, int(Qt::Key_Return)); | 
| 1389 |     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Return)); | 
| 1390 |     QCOMPARE(testObject->mText, QLatin1String("Return" )); | 
| 1391 |     QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); | 
| 1392 |     QVERIFY(key.isAccepted()); | 
| 1393 |  | 
| 1394 |     testObject->reset(); | 
| 1395 |  | 
| 1396 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, "0" , false, 1); | 
| 1397 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1398 |     QCOMPARE(testObject->mKey, int(Qt::Key_0)); | 
| 1399 |     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_0)); | 
| 1400 |     QCOMPARE(testObject->mText, QLatin1String("0" )); | 
| 1401 |     QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); | 
| 1402 |     QVERIFY(key.isAccepted()); | 
| 1403 |  | 
| 1404 |     testObject->reset(); | 
| 1405 |  | 
| 1406 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_9, Qt::NoModifier, "9" , false, 1); | 
| 1407 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1408 |     QCOMPARE(testObject->mKey, int(Qt::Key_9)); | 
| 1409 |     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_9)); | 
| 1410 |     QCOMPARE(testObject->mText, QLatin1String("9" )); | 
| 1411 |     QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); | 
| 1412 |     QVERIFY(!key.isAccepted()); | 
| 1413 |  | 
| 1414 |     testObject->reset(); | 
| 1415 |  | 
| 1416 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 1417 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1418 |     QCOMPARE(testObject->mKey, int(Qt::Key_Tab)); | 
| 1419 |     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Tab)); | 
| 1420 |     QCOMPARE(testObject->mText, QLatin1String("Tab" )); | 
| 1421 |     QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); | 
| 1422 |     QVERIFY(key.isAccepted()); | 
| 1423 |  | 
| 1424 |     testObject->reset(); | 
| 1425 |  | 
| 1426 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "" , false, 1); | 
| 1427 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1428 |     QCOMPARE(testObject->mKey, int(Qt::Key_Backtab)); | 
| 1429 |     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Backtab)); | 
| 1430 |     QCOMPARE(testObject->mText, QLatin1String("Backtab" )); | 
| 1431 |     QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); | 
| 1432 |     QVERIFY(key.isAccepted()); | 
| 1433 |  | 
| 1434 |     testObject->reset(); | 
| 1435 |  | 
| 1436 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_VolumeUp, Qt::NoModifier, 1234, 0, 0); | 
| 1437 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1438 |     QCOMPARE(testObject->mKey, int(Qt::Key_VolumeUp)); | 
| 1439 |     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_VolumeUp)); | 
| 1440 |     QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); | 
| 1441 |     QCOMPARE(testObject->mNativeScanCode, quint32(1234)); | 
| 1442 |     QVERIFY(key.isAccepted()); | 
| 1443 |  | 
| 1444 |     testObject->reset(); | 
| 1445 |  | 
| 1446 |     window->rootContext()->setContextProperty("forwardeeVisible" , QVariant(false)); | 
| 1447 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A" , false, 1); | 
| 1448 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1449 |     QCOMPARE(testObject->mKey, int(Qt::Key_A)); | 
| 1450 |     QCOMPARE(testObject->mForwardedKey, 0); | 
| 1451 |     QCOMPARE(testObject->mText, QLatin1String("A" )); | 
| 1452 |     QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); | 
| 1453 |     QVERIFY(!key.isAccepted()); | 
| 1454 |  | 
| 1455 |     testObject->reset(); | 
| 1456 |  | 
| 1457 |     window->rootContext()->setContextProperty("enableKeyHanding" , QVariant(false)); | 
| 1458 |     QCOMPARE(window->rootObject()->property("isEnabled" ).toBool(), false); | 
| 1459 |  | 
| 1460 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "" , false, 1); | 
| 1461 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1462 |     QCOMPARE(testObject->mKey, 0); | 
| 1463 |     QVERIFY(!key.isAccepted()); | 
| 1464 |  | 
| 1465 |     window->rootContext()->setContextProperty("enableKeyHanding" , QVariant(true)); | 
| 1466 |     QCOMPARE(window->rootObject()->property("isEnabled" ).toBool(), true); | 
| 1467 |  | 
| 1468 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "" , false, 1); | 
| 1469 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1470 |     QCOMPARE(testObject->mKey, int(Qt::Key_Return)); | 
| 1471 |     QVERIFY(key.isAccepted()); | 
| 1472 |  | 
| 1473 |     delete window; | 
| 1474 |     delete testObject; | 
| 1475 | } | 
| 1476 |  | 
| 1477 | #if QT_CONFIG(shortcut) | 
| 1478 |  | 
| 1479 | Q_DECLARE_METATYPE(QEvent::Type); | 
| 1480 | Q_DECLARE_METATYPE(QKeySequence::StandardKey); | 
| 1481 |  | 
| 1482 | void tst_QQuickItem::standardKeys_data() | 
| 1483 | { | 
| 1484 |     QTest::addColumn<QKeySequence::StandardKey>(name: "standardKey" ); | 
| 1485 |     QTest::addColumn<QKeySequence::StandardKey>(name: "contextProperty" ); | 
| 1486 |     QTest::addColumn<QEvent::Type>(name: "eventType" ); | 
| 1487 |     QTest::addColumn<bool>(name: "pressed" ); | 
| 1488 |     QTest::addColumn<bool>(name: "released" ); | 
| 1489 |  | 
| 1490 |     QTest::newRow(dataTag: "Press: Open" ) << QKeySequence::Open << QKeySequence::Open << QEvent::KeyPress << true << false; | 
| 1491 |     QTest::newRow(dataTag: "Press: Close" ) << QKeySequence::Close << QKeySequence::Close << QEvent::KeyPress << true << false; | 
| 1492 |     QTest::newRow(dataTag: "Press: Save" ) << QKeySequence::Save << QKeySequence::Save << QEvent::KeyPress << true << false; | 
| 1493 |     QTest::newRow(dataTag: "Press: Quit" ) << QKeySequence::Quit << QKeySequence::Quit << QEvent::KeyPress << true << false; | 
| 1494 |  | 
| 1495 |     QTest::newRow(dataTag: "Release: New" ) << QKeySequence::New << QKeySequence::New << QEvent::KeyRelease << false << true; | 
| 1496 |     QTest::newRow(dataTag: "Release: Delete" ) << QKeySequence::Delete << QKeySequence::Delete << QEvent::KeyRelease << false << true; | 
| 1497 |     QTest::newRow(dataTag: "Release: Undo" ) << QKeySequence::Undo << QKeySequence::Undo << QEvent::KeyRelease << false << true; | 
| 1498 |     QTest::newRow(dataTag: "Release: Redo" ) << QKeySequence::Redo << QKeySequence::Redo << QEvent::KeyRelease << false << true; | 
| 1499 |  | 
| 1500 |     QTest::newRow(dataTag: "Mismatch: Cut" ) << QKeySequence::Cut << QKeySequence::Copy << QEvent::KeyPress << false << false; | 
| 1501 |     QTest::newRow(dataTag: "Mismatch: Copy" ) << QKeySequence::Copy << QKeySequence::Paste << QEvent::KeyPress << false << false; | 
| 1502 |     QTest::newRow(dataTag: "Mismatch: Paste" ) << QKeySequence::Paste << QKeySequence::Cut << QEvent::KeyRelease << false << false; | 
| 1503 |     QTest::newRow(dataTag: "Mismatch: Quit" ) << QKeySequence::Quit << QKeySequence::New << QEvent::KeyRelease << false << false; | 
| 1504 | } | 
| 1505 |  | 
| 1506 | void tst_QQuickItem::standardKeys() | 
| 1507 | { | 
| 1508 |     QFETCH(QKeySequence::StandardKey, standardKey); | 
| 1509 |     QFETCH(QKeySequence::StandardKey, contextProperty); | 
| 1510 |     QFETCH(QEvent::Type, eventType); | 
| 1511 |     QFETCH(bool, pressed); | 
| 1512 |     QFETCH(bool, released); | 
| 1513 |  | 
| 1514 |     QKeySequence keySequence(standardKey); | 
| 1515 |     if (keySequence.isEmpty()) | 
| 1516 |         QSKIP("Undefined key sequence." ); | 
| 1517 |  | 
| 1518 |     QQuickView view; | 
| 1519 |     view.rootContext()->setContextProperty("standardKey" , contextProperty); | 
| 1520 |     view.setSource(testFileUrl(fileName: "standardkeys.qml" )); | 
| 1521 |     view.show(); | 
| 1522 |     view.requestActivate(); | 
| 1523 |     QVERIFY(QTest::qWaitForWindowActive(&view)); | 
| 1524 |  | 
| 1525 |     QQuickItem *item = qobject_cast<QQuickItem*>(object: view.rootObject()); | 
| 1526 |     QVERIFY(item); | 
| 1527 |  | 
| 1528 |     const int key = keySequence[0] & Qt::Key_unknown; | 
| 1529 |     const int modifiers = keySequence[0] & Qt::KeyboardModifierMask; | 
| 1530 |     QKeyEvent keyEvent(eventType, key, static_cast<Qt::KeyboardModifiers>(modifiers)); | 
| 1531 |     QGuiApplication::sendEvent(receiver: &view, event: &keyEvent); | 
| 1532 |  | 
| 1533 |     QCOMPARE(item->property("pressed" ).toBool(), pressed); | 
| 1534 |     QCOMPARE(item->property("released" ).toBool(), released); | 
| 1535 | } | 
| 1536 |  | 
| 1537 | #endif // QT_CONFIG(shortcut) | 
| 1538 |  | 
| 1539 | void tst_QQuickItem::keysProcessingOrder() | 
| 1540 | { | 
| 1541 |     QQuickView *window = new QQuickView(nullptr); | 
| 1542 |     window->setBaseSize(QSize(240,320)); | 
| 1543 |  | 
| 1544 |     KeysTestObject *testObject = new KeysTestObject; | 
| 1545 |     window->rootContext()->setContextProperty("keysTestObject" , testObject); | 
| 1546 |  | 
| 1547 |     window->setSource(testFileUrl(fileName: "keyspriority.qml" )); | 
| 1548 |     window->show(); | 
| 1549 |     window->requestActivate(); | 
| 1550 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 1551 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 1552 |  | 
| 1553 |     KeyTestItem *testItem = qobject_cast<KeyTestItem*>(object: window->rootObject()); | 
| 1554 |     QVERIFY(testItem); | 
| 1555 |  | 
| 1556 |     QCOMPARE(testItem->property("priorityTest" ).toInt(), 0); | 
| 1557 |  | 
| 1558 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A" , false, 1); | 
| 1559 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1560 |     QCOMPARE(testObject->mKey, int(Qt::Key_A)); | 
| 1561 |     QCOMPARE(testObject->mText, QLatin1String("A" )); | 
| 1562 |     QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); | 
| 1563 |     QVERIFY(key.isAccepted()); | 
| 1564 |  | 
| 1565 |     testObject->reset(); | 
| 1566 |  | 
| 1567 |     testObject->setProcessLast(true); | 
| 1568 |  | 
| 1569 |     QCOMPARE(testItem->property("priorityTest" ).toInt(), 1); | 
| 1570 |  | 
| 1571 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A" , false, 1); | 
| 1572 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1573 |     QCOMPARE(testObject->mKey, 0); | 
| 1574 |     QVERIFY(key.isAccepted()); | 
| 1575 |  | 
| 1576 |     testObject->reset(); | 
| 1577 |  | 
| 1578 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_B, Qt::NoModifier, "B" , false, 1); | 
| 1579 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1580 |     QCOMPARE(testObject->mKey, int(Qt::Key_B)); | 
| 1581 |     QCOMPARE(testObject->mText, QLatin1String("B" )); | 
| 1582 |     QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); | 
| 1583 |     QVERIFY(!key.isAccepted()); | 
| 1584 |  | 
| 1585 |     testObject->reset(); | 
| 1586 |  | 
| 1587 |     key = QKeyEvent(QEvent::KeyRelease, Qt::Key_B, Qt::NoModifier, "B" , false, 1); | 
| 1588 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1589 |     QCOMPARE(testObject->mKey, 0); | 
| 1590 |     QVERIFY(key.isAccepted()); | 
| 1591 |  | 
| 1592 |     delete window; | 
| 1593 |     delete testObject; | 
| 1594 | } | 
| 1595 |  | 
| 1596 | void tst_QQuickItem::keysim() | 
| 1597 | { | 
| 1598 |     PlatformInputContext platformInputContext; | 
| 1599 |     QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); | 
| 1600 |     inputMethodPrivate->testContext = &platformInputContext; | 
| 1601 |  | 
| 1602 |     QQuickView *window = new QQuickView(nullptr); | 
| 1603 |     window->setBaseSize(QSize(240,320)); | 
| 1604 |  | 
| 1605 |     window->setSource(testFileUrl(fileName: "keysim.qml" )); | 
| 1606 |     window->show(); | 
| 1607 |     window->requestActivate(); | 
| 1608 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 1609 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 1610 |  | 
| 1611 |     QVERIFY(window->rootObject()); | 
| 1612 |     QVERIFY(window->rootObject()->hasFocus() && window->rootObject()->hasActiveFocus()); | 
| 1613 |  | 
| 1614 |     QQuickTextInput *input = window->rootObject()->findChild<QQuickTextInput*>(); | 
| 1615 |     QVERIFY(input); | 
| 1616 |  | 
| 1617 |     QInputMethodEvent ev("Hello world!" , QList<QInputMethodEvent::Attribute>()); | 
| 1618 |     QGuiApplication::sendEvent(qGuiApp->focusObject(), event: &ev); | 
| 1619 |  | 
| 1620 |     QEXPECT_FAIL("" , "QTBUG-24280" , Continue); | 
| 1621 |     QCOMPARE(input->text(), QLatin1String("Hello world!" )); | 
| 1622 |  | 
| 1623 |     delete window; | 
| 1624 | } | 
| 1625 |  | 
| 1626 | void tst_QQuickItem::keysForward() | 
| 1627 | { | 
| 1628 |     QQuickView window; | 
| 1629 |     window.setBaseSize(QSize(240,320)); | 
| 1630 |  | 
| 1631 |     window.setSource(testFileUrl(fileName: "keysforward.qml" )); | 
| 1632 |     window.show(); | 
| 1633 |     window.requestActivate(); | 
| 1634 |     QVERIFY(QTest::qWaitForWindowActive(&window)); | 
| 1635 |     QCOMPARE(QGuiApplication::focusWindow(), &window); | 
| 1636 |  | 
| 1637 |     QQuickItem *rootItem = qobject_cast<QQuickItem *>(object: window.rootObject()); | 
| 1638 |     QVERIFY(rootItem); | 
| 1639 |     QQuickItem *sourceItem = rootItem->property(name: "source" ).value<QQuickItem *>(); | 
| 1640 |     QVERIFY(sourceItem); | 
| 1641 |     QQuickItem *primaryTarget = rootItem->property(name: "primaryTarget" ).value<QQuickItem *>(); | 
| 1642 |     QVERIFY(primaryTarget); | 
| 1643 |     QQuickItem *secondaryTarget = rootItem->property(name: "secondaryTarget" ).value<QQuickItem *>(); | 
| 1644 |     QVERIFY(secondaryTarget); | 
| 1645 |  | 
| 1646 |     // primary target accepts/consumes Key_P | 
| 1647 |     QKeyEvent pressKeyP(QEvent::KeyPress, Qt::Key_P, Qt::NoModifier, "P" ); | 
| 1648 |     QCoreApplication::sendEvent(receiver: sourceItem, event: &pressKeyP); | 
| 1649 |     QCOMPARE(rootItem->property("pressedKeys" ).toList(), QVariantList()); | 
| 1650 |     QCOMPARE(sourceItem->property("pressedKeys" ).toList(), QVariantList()); | 
| 1651 |     QCOMPARE(primaryTarget->property("pressedKeys" ).toList(), QVariantList() << Qt::Key_P); | 
| 1652 |     QCOMPARE(secondaryTarget->property("pressedKeys" ).toList(), QVariantList() << Qt::Key_P); | 
| 1653 |     QVERIFY(pressKeyP.isAccepted()); | 
| 1654 |  | 
| 1655 |     QKeyEvent releaseKeyP(QEvent::KeyRelease, Qt::Key_P, Qt::NoModifier, "P" ); | 
| 1656 |     QCoreApplication::sendEvent(receiver: sourceItem, event: &releaseKeyP); | 
| 1657 |     QCOMPARE(rootItem->property("releasedKeys" ).toList(), QVariantList()); | 
| 1658 |     QCOMPARE(sourceItem->property("releasedKeys" ).toList(), QVariantList()); | 
| 1659 |     QCOMPARE(primaryTarget->property("releasedKeys" ).toList(), QVariantList() << Qt::Key_P); | 
| 1660 |     QCOMPARE(secondaryTarget->property("releasedKeys" ).toList(), QVariantList() << Qt::Key_P); | 
| 1661 |     QVERIFY(releaseKeyP.isAccepted()); | 
| 1662 |  | 
| 1663 |     // secondary target accepts/consumes Key_S | 
| 1664 |     QKeyEvent pressKeyS(QEvent::KeyPress, Qt::Key_S, Qt::NoModifier, "S" ); | 
| 1665 |     QCoreApplication::sendEvent(receiver: sourceItem, event: &pressKeyS); | 
| 1666 |     QCOMPARE(rootItem->property("pressedKeys" ).toList(), QVariantList()); | 
| 1667 |     QCOMPARE(sourceItem->property("pressedKeys" ).toList(), QVariantList()); | 
| 1668 |     QCOMPARE(primaryTarget->property("pressedKeys" ).toList(), QVariantList() << Qt::Key_P); | 
| 1669 |     QCOMPARE(secondaryTarget->property("pressedKeys" ).toList(), QVariantList() << Qt::Key_P << Qt::Key_S); | 
| 1670 |     QVERIFY(pressKeyS.isAccepted()); | 
| 1671 |  | 
| 1672 |     QKeyEvent releaseKeyS(QEvent::KeyRelease, Qt::Key_S, Qt::NoModifier, "S" ); | 
| 1673 |     QCoreApplication::sendEvent(receiver: sourceItem, event: &releaseKeyS); | 
| 1674 |     QCOMPARE(rootItem->property("releasedKeys" ).toList(), QVariantList()); | 
| 1675 |     QCOMPARE(sourceItem->property("releasedKeys" ).toList(), QVariantList()); | 
| 1676 |     QCOMPARE(primaryTarget->property("releasedKeys" ).toList(), QVariantList() << Qt::Key_P); | 
| 1677 |     QCOMPARE(secondaryTarget->property("releasedKeys" ).toList(), QVariantList() << Qt::Key_P << Qt::Key_S); | 
| 1678 |     QVERIFY(releaseKeyS.isAccepted()); | 
| 1679 |  | 
| 1680 |     // neither target accepts/consumes Key_Q | 
| 1681 |     QKeyEvent pressKeyQ(QEvent::KeyPress, Qt::Key_Q, Qt::NoModifier, "Q" ); | 
| 1682 |     QCoreApplication::sendEvent(receiver: sourceItem, event: &pressKeyQ); | 
| 1683 |     QCOMPARE(rootItem->property("pressedKeys" ).toList(), QVariantList()); | 
| 1684 |     QCOMPARE(sourceItem->property("pressedKeys" ).toList(), QVariantList() << Qt::Key_Q); | 
| 1685 |     QCOMPARE(primaryTarget->property("pressedKeys" ).toList(), QVariantList() << Qt::Key_P << Qt::Key_Q); | 
| 1686 |     QCOMPARE(secondaryTarget->property("pressedKeys" ).toList(), QVariantList() << Qt::Key_P << Qt::Key_S << Qt::Key_Q); | 
| 1687 |     QVERIFY(!pressKeyQ.isAccepted()); | 
| 1688 |  | 
| 1689 |     QKeyEvent releaseKeyQ(QEvent::KeyRelease, Qt::Key_Q, Qt::NoModifier, "Q" ); | 
| 1690 |     QCoreApplication::sendEvent(receiver: sourceItem, event: &releaseKeyQ); | 
| 1691 |     QCOMPARE(rootItem->property("releasedKeys" ).toList(), QVariantList()); | 
| 1692 |     QCOMPARE(sourceItem->property("releasedKeys" ).toList(), QVariantList() << Qt::Key_Q); | 
| 1693 |     QCOMPARE(primaryTarget->property("releasedKeys" ).toList(), QVariantList() << Qt::Key_P << Qt::Key_Q); | 
| 1694 |     QCOMPARE(secondaryTarget->property("releasedKeys" ).toList(), QVariantList() << Qt::Key_P << Qt::Key_S << Qt::Key_Q); | 
| 1695 |     QVERIFY(!releaseKeyQ.isAccepted()); | 
| 1696 | } | 
| 1697 |  | 
| 1698 | QQuickItemPrivate *childPrivate(QQuickItem *rootItem, const char * itemString) | 
| 1699 | { | 
| 1700 |     QQuickItem *item = findItem<QQuickItem>(parent: rootItem, objectName: QString(QLatin1String(itemString))); | 
| 1701 |     QQuickItemPrivate* itemPrivate = QQuickItemPrivate::get(item); | 
| 1702 |     return itemPrivate; | 
| 1703 | } | 
| 1704 |  | 
| 1705 | QVariant childProperty(QQuickItem *rootItem, const char * itemString, const char * property) | 
| 1706 | { | 
| 1707 |     QQuickItem *item = findItem<QQuickItem>(parent: rootItem, objectName: QString(QLatin1String(itemString))); | 
| 1708 |     return item->property(name: property); | 
| 1709 | } | 
| 1710 |  | 
| 1711 | bool anchorsMirrored(QQuickItem *rootItem, const char * itemString) | 
| 1712 | { | 
| 1713 |     QQuickItem *item = findItem<QQuickItem>(parent: rootItem, objectName: QString(QLatin1String(itemString))); | 
| 1714 |     QQuickItemPrivate* itemPrivate = QQuickItemPrivate::get(item); | 
| 1715 |     return itemPrivate->anchors()->mirrored(); | 
| 1716 | } | 
| 1717 |  | 
| 1718 | void tst_QQuickItem::layoutMirroring() | 
| 1719 | { | 
| 1720 |     QQuickView *window = new QQuickView(nullptr); | 
| 1721 |     window->setSource(testFileUrl(fileName: "layoutmirroring.qml" )); | 
| 1722 |     window->show(); | 
| 1723 |  | 
| 1724 |     QQuickItem *rootItem = qobject_cast<QQuickItem*>(object: window->rootObject()); | 
| 1725 |     QVERIFY(rootItem); | 
| 1726 |     QQuickItemPrivate *rootPrivate = QQuickItemPrivate::get(item: rootItem); | 
| 1727 |     QVERIFY(rootPrivate); | 
| 1728 |  | 
| 1729 |     QCOMPARE(childPrivate(rootItem, "mirrored1" )->effectiveLayoutMirror, true); | 
| 1730 |     QCOMPARE(childPrivate(rootItem, "mirrored2" )->effectiveLayoutMirror, true); | 
| 1731 |     QCOMPARE(childPrivate(rootItem, "notMirrored1" )->effectiveLayoutMirror, false); | 
| 1732 |     QCOMPARE(childPrivate(rootItem, "notMirrored2" )->effectiveLayoutMirror, false); | 
| 1733 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror1" )->effectiveLayoutMirror, true); | 
| 1734 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror2" )->effectiveLayoutMirror, true); | 
| 1735 |  | 
| 1736 |     QCOMPARE(anchorsMirrored(rootItem, "mirrored1" ), true); | 
| 1737 |     QCOMPARE(anchorsMirrored(rootItem, "mirrored2" ), true); | 
| 1738 |     QCOMPARE(anchorsMirrored(rootItem, "notMirrored1" ), false); | 
| 1739 |     QCOMPARE(anchorsMirrored(rootItem, "notMirrored2" ), false); | 
| 1740 |     QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror1" ), true); | 
| 1741 |     QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror2" ), true); | 
| 1742 |  | 
| 1743 |     QCOMPARE(childPrivate(rootItem, "mirrored1" )->inheritedLayoutMirror, true); | 
| 1744 |     QCOMPARE(childPrivate(rootItem, "mirrored2" )->inheritedLayoutMirror, false); | 
| 1745 |     QCOMPARE(childPrivate(rootItem, "notMirrored1" )->inheritedLayoutMirror, true); | 
| 1746 |     QCOMPARE(childPrivate(rootItem, "notMirrored2" )->inheritedLayoutMirror, false); | 
| 1747 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror1" )->inheritedLayoutMirror, true); | 
| 1748 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror2" )->inheritedLayoutMirror, true); | 
| 1749 |  | 
| 1750 |     QCOMPARE(childPrivate(rootItem, "mirrored1" )->isMirrorImplicit, false); | 
| 1751 |     QCOMPARE(childPrivate(rootItem, "mirrored2" )->isMirrorImplicit, false); | 
| 1752 |     QCOMPARE(childPrivate(rootItem, "notMirrored1" )->isMirrorImplicit, false); | 
| 1753 |     QCOMPARE(childPrivate(rootItem, "notMirrored2" )->isMirrorImplicit, true); | 
| 1754 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror1" )->isMirrorImplicit, true); | 
| 1755 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror2" )->isMirrorImplicit, true); | 
| 1756 |  | 
| 1757 |     QCOMPARE(childPrivate(rootItem, "mirrored1" )->inheritMirrorFromParent, true); | 
| 1758 |     QCOMPARE(childPrivate(rootItem, "mirrored2" )->inheritMirrorFromParent, false); | 
| 1759 |     QCOMPARE(childPrivate(rootItem, "notMirrored1" )->inheritMirrorFromParent, true); | 
| 1760 |     QCOMPARE(childPrivate(rootItem, "notMirrored2" )->inheritMirrorFromParent, false); | 
| 1761 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror1" )->inheritMirrorFromParent, true); | 
| 1762 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror2" )->inheritMirrorFromParent, true); | 
| 1763 |  | 
| 1764 |     QCOMPARE(childPrivate(rootItem, "mirrored1" )->inheritMirrorFromItem, true); | 
| 1765 |     QCOMPARE(childPrivate(rootItem, "mirrored2" )->inheritMirrorFromItem, false); | 
| 1766 |     QCOMPARE(childPrivate(rootItem, "notMirrored1" )->inheritMirrorFromItem, false); | 
| 1767 |     QCOMPARE(childPrivate(rootItem, "notMirrored2" )->inheritMirrorFromItem, false); | 
| 1768 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror1" )->inheritMirrorFromItem, false); | 
| 1769 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror2" )->inheritMirrorFromItem, false); | 
| 1770 |  | 
| 1771 |     // load dynamic content using Loader that needs to inherit mirroring | 
| 1772 |     rootItem->setProperty(name: "state" , value: "newContent" ); | 
| 1773 |     QCOMPARE(childPrivate(rootItem, "notMirrored3" )->effectiveLayoutMirror, false); | 
| 1774 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror3" )->effectiveLayoutMirror, true); | 
| 1775 |  | 
| 1776 |     QCOMPARE(childPrivate(rootItem, "notMirrored3" )->inheritedLayoutMirror, true); | 
| 1777 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror3" )->inheritedLayoutMirror, true); | 
| 1778 |  | 
| 1779 |     QCOMPARE(childPrivate(rootItem, "notMirrored3" )->isMirrorImplicit, false); | 
| 1780 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror3" )->isMirrorImplicit, true); | 
| 1781 |  | 
| 1782 |     QCOMPARE(childPrivate(rootItem, "notMirrored3" )->inheritMirrorFromParent, true); | 
| 1783 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror3" )->inheritMirrorFromParent, true); | 
| 1784 |  | 
| 1785 |     QCOMPARE(childPrivate(rootItem, "notMirrored3" )->inheritMirrorFromItem, false); | 
| 1786 |     QCOMPARE(childPrivate(rootItem, "notMirrored3" )->inheritMirrorFromItem, false); | 
| 1787 |  | 
| 1788 |     // disable inheritance | 
| 1789 |     rootItem->setProperty(name: "childrenInherit" , value: false); | 
| 1790 |  | 
| 1791 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror1" )->effectiveLayoutMirror, false); | 
| 1792 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror2" )->effectiveLayoutMirror, false); | 
| 1793 |     QCOMPARE(childPrivate(rootItem, "mirrored1" )->effectiveLayoutMirror, true); | 
| 1794 |     QCOMPARE(childPrivate(rootItem, "notMirrored1" )->effectiveLayoutMirror, false); | 
| 1795 |  | 
| 1796 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror1" )->inheritedLayoutMirror, false); | 
| 1797 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror2" )->inheritedLayoutMirror, false); | 
| 1798 |     QCOMPARE(childPrivate(rootItem, "mirrored1" )->inheritedLayoutMirror, false); | 
| 1799 |     QCOMPARE(childPrivate(rootItem, "notMirrored1" )->inheritedLayoutMirror, false); | 
| 1800 |  | 
| 1801 |     // re-enable inheritance | 
| 1802 |     rootItem->setProperty(name: "childrenInherit" , value: true); | 
| 1803 |  | 
| 1804 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror1" )->effectiveLayoutMirror, true); | 
| 1805 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror2" )->effectiveLayoutMirror, true); | 
| 1806 |     QCOMPARE(childPrivate(rootItem, "mirrored1" )->effectiveLayoutMirror, true); | 
| 1807 |     QCOMPARE(childPrivate(rootItem, "notMirrored1" )->effectiveLayoutMirror, false); | 
| 1808 |  | 
| 1809 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror1" )->inheritedLayoutMirror, true); | 
| 1810 |     QCOMPARE(childPrivate(rootItem, "inheritedMirror2" )->inheritedLayoutMirror, true); | 
| 1811 |     QCOMPARE(childPrivate(rootItem, "mirrored1" )->inheritedLayoutMirror, true); | 
| 1812 |     QCOMPARE(childPrivate(rootItem, "notMirrored1" )->inheritedLayoutMirror, true); | 
| 1813 |  | 
| 1814 |     // | 
| 1815 |     // dynamic parenting | 
| 1816 |     // | 
| 1817 |     QQuickItem *parentItem1 = new QQuickItem(); | 
| 1818 |     QQuickItemPrivate::get(item: parentItem1)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true | 
| 1819 |     QQuickItemPrivate::get(item: parentItem1)->isMirrorImplicit = false; | 
| 1820 |     QQuickItemPrivate::get(item: parentItem1)->inheritMirrorFromItem = true; // LayoutMirroring.childrenInherit: true | 
| 1821 |     QQuickItemPrivate::get(item: parentItem1)->resolveLayoutMirror(); | 
| 1822 |  | 
| 1823 |     // inherit in constructor | 
| 1824 |     QQuickItem *childItem1 = new QQuickItem(parentItem1); | 
| 1825 |     QCOMPARE(QQuickItemPrivate::get(childItem1)->effectiveLayoutMirror, true); | 
| 1826 |     QCOMPARE(QQuickItemPrivate::get(childItem1)->inheritMirrorFromParent, true); | 
| 1827 |  | 
| 1828 |     // inherit through a parent change | 
| 1829 |     QQuickItem *childItem2 = new QQuickItem(); | 
| 1830 |     QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, false); | 
| 1831 |     QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, false); | 
| 1832 |     childItem2->setParentItem(parentItem1); | 
| 1833 |     QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, true); | 
| 1834 |     QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, true); | 
| 1835 |  | 
| 1836 |     // stop inherting through a parent change | 
| 1837 |     QQuickItem *parentItem2 = new QQuickItem(); | 
| 1838 |     QQuickItemPrivate::get(item: parentItem2)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true | 
| 1839 |     QQuickItemPrivate::get(item: parentItem2)->resolveLayoutMirror(); | 
| 1840 |     childItem2->setParentItem(parentItem2); | 
| 1841 |     QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, false); | 
| 1842 |     QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, false); | 
| 1843 |  | 
| 1844 |     delete parentItem1; | 
| 1845 |     delete parentItem2; | 
| 1846 | } | 
| 1847 |  | 
| 1848 | void tst_QQuickItem::layoutMirroringWindow() | 
| 1849 | { | 
| 1850 |     QQmlComponent component(&engine); | 
| 1851 |     component.loadUrl(url: testFileUrl(fileName: "layoutmirroring_window.qml" )); | 
| 1852 |     QScopedPointer<QObject> object(component.create()); | 
| 1853 |     QQuickWindow *window = qobject_cast<QQuickWindow *>(object: object.data()); | 
| 1854 |     QVERIFY(window); | 
| 1855 |     window->show(); | 
| 1856 |  | 
| 1857 |     QQuickItemPrivate *content = QQuickItemPrivate::get(item: window->contentItem()); | 
| 1858 |     QCOMPARE(content->effectiveLayoutMirror, true); | 
| 1859 |     QCOMPARE(content->inheritedLayoutMirror, true); | 
| 1860 |     QCOMPARE(content->isMirrorImplicit, false); | 
| 1861 |     QCOMPARE(content->inheritMirrorFromParent, true); | 
| 1862 |     QCOMPARE(content->inheritMirrorFromItem, true); | 
| 1863 | } | 
| 1864 |  | 
| 1865 | void tst_QQuickItem::layoutMirroringIllegalParent() | 
| 1866 | { | 
| 1867 |     QQmlComponent component(&engine); | 
| 1868 |     component.setData("import QtQuick 2.0; QtObject { LayoutMirroring.enabled: true; LayoutMirroring.childrenInherit: true }" , baseUrl: QUrl::fromLocalFile(localfile: "" )); | 
| 1869 |     QTest::ignoreMessage(type: QtWarningMsg, message: "<Unknown File>:1:21: QML QtObject: LayoutDirection attached property only works with Items and Windows" ); | 
| 1870 |     QObject *object = component.create(); | 
| 1871 |     QVERIFY(object != nullptr); | 
| 1872 | } | 
| 1873 |  | 
| 1874 | void tst_QQuickItem::keyNavigation_data() | 
| 1875 | { | 
| 1876 |     QTest::addColumn<QString>(name: "source" ); | 
| 1877 |     QTest::newRow(dataTag: "KeyNavigation" ) << QStringLiteral("keynavigationtest.qml" ); | 
| 1878 |     QTest::newRow(dataTag: "KeyNavigation_FocusScope" ) << QStringLiteral("keynavigationtest_focusscope.qml" ); | 
| 1879 | } | 
| 1880 |  | 
| 1881 | void tst_QQuickItem::keyNavigation() | 
| 1882 | { | 
| 1883 |     QFETCH(QString, source); | 
| 1884 |  | 
| 1885 |     QQuickView *window = new QQuickView(nullptr); | 
| 1886 |     window->setBaseSize(QSize(240,320)); | 
| 1887 |  | 
| 1888 |     window->setSource(testFileUrl(fileName: source)); | 
| 1889 |     window->show(); | 
| 1890 |     window->requestActivate(); | 
| 1891 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 1892 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 1893 |  | 
| 1894 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item1" ); | 
| 1895 |     QVERIFY(item); | 
| 1896 |     QVERIFY(item->hasActiveFocus()); | 
| 1897 |  | 
| 1898 |     QVariant result; | 
| 1899 |     QVERIFY(QMetaObject::invokeMethod(window->rootObject(), "verify" , | 
| 1900 |             Q_RETURN_ARG(QVariant, result))); | 
| 1901 |     QVERIFY(result.toBool()); | 
| 1902 |  | 
| 1903 |     // right | 
| 1904 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "" , false, 1); | 
| 1905 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1906 |     QVERIFY(key.isAccepted()); | 
| 1907 |  | 
| 1908 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item2" ); | 
| 1909 |     QVERIFY(item); | 
| 1910 |     QVERIFY(item->hasActiveFocus()); | 
| 1911 |  | 
| 1912 |     // down | 
| 1913 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "" , false, 1); | 
| 1914 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1915 |     QVERIFY(key.isAccepted()); | 
| 1916 |  | 
| 1917 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item4" ); | 
| 1918 |     QVERIFY(item); | 
| 1919 |     QVERIFY(item->hasActiveFocus()); | 
| 1920 |  | 
| 1921 |     // left | 
| 1922 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "" , false, 1); | 
| 1923 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1924 |     QVERIFY(key.isAccepted()); | 
| 1925 |  | 
| 1926 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item3" ); | 
| 1927 |     QVERIFY(item); | 
| 1928 |     QVERIFY(item->hasActiveFocus()); | 
| 1929 |  | 
| 1930 |     // up | 
| 1931 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "" , false, 1); | 
| 1932 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1933 |     QVERIFY(key.isAccepted()); | 
| 1934 |  | 
| 1935 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item1" ); | 
| 1936 |     QVERIFY(item); | 
| 1937 |     QVERIFY(item->hasActiveFocus()); | 
| 1938 |  | 
| 1939 |     // tab | 
| 1940 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 1941 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1942 |     QVERIFY(key.isAccepted()); | 
| 1943 |  | 
| 1944 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item2" ); | 
| 1945 |     QVERIFY(item); | 
| 1946 |     QVERIFY(item->hasActiveFocus()); | 
| 1947 |  | 
| 1948 |     // backtab | 
| 1949 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "" , false, 1); | 
| 1950 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1951 |     QVERIFY(key.isAccepted()); | 
| 1952 |  | 
| 1953 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item1" ); | 
| 1954 |     QVERIFY(item); | 
| 1955 |     QVERIFY(item->hasActiveFocus()); | 
| 1956 |  | 
| 1957 |     delete window; | 
| 1958 | } | 
| 1959 |  | 
| 1960 | void tst_QQuickItem::keyNavigation_RightToLeft() | 
| 1961 | { | 
| 1962 |     QQuickView *window = new QQuickView(nullptr); | 
| 1963 |     window->setBaseSize(QSize(240,320)); | 
| 1964 |  | 
| 1965 |     window->setSource(testFileUrl(fileName: "keynavigationtest.qml" )); | 
| 1966 |     window->show(); | 
| 1967 |     window->requestActivate(); | 
| 1968 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 1969 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 1970 |  | 
| 1971 |     QQuickItem *rootItem = qobject_cast<QQuickItem*>(object: window->rootObject()); | 
| 1972 |     QVERIFY(rootItem); | 
| 1973 |     QQuickItemPrivate* rootItemPrivate = QQuickItemPrivate::get(item: rootItem); | 
| 1974 |  | 
| 1975 |     rootItemPrivate->effectiveLayoutMirror = true; // LayoutMirroring.mirror: true | 
| 1976 |     rootItemPrivate->isMirrorImplicit = false; | 
| 1977 |     rootItemPrivate->inheritMirrorFromItem = true; // LayoutMirroring.inherit: true | 
| 1978 |     rootItemPrivate->resolveLayoutMirror(); | 
| 1979 |  | 
| 1980 |     QEvent wa(QEvent::WindowActivate); | 
| 1981 |     QGuiApplication::sendEvent(receiver: window, event: &wa); | 
| 1982 |     QFocusEvent fe(QEvent::FocusIn); | 
| 1983 |     QGuiApplication::sendEvent(receiver: window, event: &fe); | 
| 1984 |  | 
| 1985 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item1" ); | 
| 1986 |     QVERIFY(item); | 
| 1987 |     QVERIFY(item->hasActiveFocus()); | 
| 1988 |  | 
| 1989 |     QVariant result; | 
| 1990 |     QVERIFY(QMetaObject::invokeMethod(window->rootObject(), "verify" , | 
| 1991 |             Q_RETURN_ARG(QVariant, result))); | 
| 1992 |     QVERIFY(result.toBool()); | 
| 1993 |  | 
| 1994 |     // right | 
| 1995 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "" , false, 1); | 
| 1996 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 1997 |     QVERIFY(key.isAccepted()); | 
| 1998 |  | 
| 1999 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item2" ); | 
| 2000 |     QVERIFY(item); | 
| 2001 |     QVERIFY(item->hasActiveFocus()); | 
| 2002 |  | 
| 2003 |     // left | 
| 2004 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "" , false, 1); | 
| 2005 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2006 |     QVERIFY(key.isAccepted()); | 
| 2007 |  | 
| 2008 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item1" ); | 
| 2009 |     QVERIFY(item); | 
| 2010 |     QVERIFY(item->hasActiveFocus()); | 
| 2011 |  | 
| 2012 |     delete window; | 
| 2013 | } | 
| 2014 |  | 
| 2015 | void tst_QQuickItem::keyNavigation_skipNotVisible() | 
| 2016 | { | 
| 2017 |     QQuickView *window = new QQuickView(nullptr); | 
| 2018 |     window->setBaseSize(QSize(240,320)); | 
| 2019 |  | 
| 2020 |     window->setSource(testFileUrl(fileName: "keynavigationtest.qml" )); | 
| 2021 |     window->show(); | 
| 2022 |     window->requestActivate(); | 
| 2023 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 2024 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 2025 |  | 
| 2026 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item1" ); | 
| 2027 |     QVERIFY(item); | 
| 2028 |     QVERIFY(item->hasActiveFocus()); | 
| 2029 |  | 
| 2030 |     // Set item 2 to not visible | 
| 2031 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item2" ); | 
| 2032 |     QVERIFY(item); | 
| 2033 |     item->setVisible(false); | 
| 2034 |     QVERIFY(!item->isVisible()); | 
| 2035 |  | 
| 2036 |     // right | 
| 2037 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "" , false, 1); | 
| 2038 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2039 |     QVERIFY(key.isAccepted()); | 
| 2040 |  | 
| 2041 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item1" ); | 
| 2042 |     QVERIFY(item); | 
| 2043 |     QVERIFY(item->hasActiveFocus()); | 
| 2044 |  | 
| 2045 |     // tab | 
| 2046 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 2047 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2048 |     QVERIFY(key.isAccepted()); | 
| 2049 |  | 
| 2050 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item3" ); | 
| 2051 |     QVERIFY(item); | 
| 2052 |     QVERIFY(item->hasActiveFocus()); | 
| 2053 |  | 
| 2054 |     // backtab | 
| 2055 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "" , false, 1); | 
| 2056 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2057 |     QVERIFY(key.isAccepted()); | 
| 2058 |  | 
| 2059 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item1" ); | 
| 2060 |     QVERIFY(item); | 
| 2061 |     QVERIFY(item->hasActiveFocus()); | 
| 2062 |  | 
| 2063 |     //Set item 3 to not visible | 
| 2064 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item3" ); | 
| 2065 |     QVERIFY(item); | 
| 2066 |     item->setVisible(false); | 
| 2067 |     QVERIFY(!item->isVisible()); | 
| 2068 |  | 
| 2069 |     // tab | 
| 2070 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 2071 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2072 |     QVERIFY(key.isAccepted()); | 
| 2073 |  | 
| 2074 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item4" ); | 
| 2075 |     QVERIFY(item); | 
| 2076 |     QVERIFY(item->hasActiveFocus()); | 
| 2077 |  | 
| 2078 |     // backtab | 
| 2079 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "" , false, 1); | 
| 2080 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2081 |     QVERIFY(key.isAccepted()); | 
| 2082 |  | 
| 2083 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item1" ); | 
| 2084 |     QVERIFY(item); | 
| 2085 |     QVERIFY(item->hasActiveFocus()); | 
| 2086 |  | 
| 2087 |     delete window; | 
| 2088 | } | 
| 2089 |  | 
| 2090 | void tst_QQuickItem::keyNavigation_implicitSetting() | 
| 2091 | { | 
| 2092 |     QQuickView *window = new QQuickView(nullptr); | 
| 2093 |     window->setBaseSize(QSize(240,320)); | 
| 2094 |  | 
| 2095 |     window->setSource(testFileUrl(fileName: "keynavigationtest_implicit.qml" )); | 
| 2096 |     window->show(); | 
| 2097 |     window->requestActivate(); | 
| 2098 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 2099 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 2100 |  | 
| 2101 |     QEvent wa(QEvent::WindowActivate); | 
| 2102 |     QGuiApplication::sendEvent(receiver: window, event: &wa); | 
| 2103 |     QFocusEvent fe(QEvent::FocusIn); | 
| 2104 |     QGuiApplication::sendEvent(receiver: window, event: &fe); | 
| 2105 |  | 
| 2106 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item1" ); | 
| 2107 |     QVERIFY(item); | 
| 2108 |     QVERIFY(item->hasActiveFocus()); | 
| 2109 |  | 
| 2110 |     QVariant result; | 
| 2111 |     QVERIFY(QMetaObject::invokeMethod(window->rootObject(), "verify" , | 
| 2112 |             Q_RETURN_ARG(QVariant, result))); | 
| 2113 |     QVERIFY(result.toBool()); | 
| 2114 |  | 
| 2115 |     // right | 
| 2116 |     QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "" , false, 1); | 
| 2117 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2118 |     QVERIFY(key.isAccepted()); | 
| 2119 |  | 
| 2120 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item2" ); | 
| 2121 |     QVERIFY(item); | 
| 2122 |     QVERIFY(item->hasActiveFocus()); | 
| 2123 |  | 
| 2124 |     // back to item1 | 
| 2125 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "" , false, 1); | 
| 2126 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2127 |     QVERIFY(key.isAccepted()); | 
| 2128 |  | 
| 2129 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item1" ); | 
| 2130 |     QVERIFY(item); | 
| 2131 |     QVERIFY(item->hasActiveFocus()); | 
| 2132 |  | 
| 2133 |     // down | 
| 2134 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "" , false, 1); | 
| 2135 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2136 |     QVERIFY(key.isAccepted()); | 
| 2137 |  | 
| 2138 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item3" ); | 
| 2139 |     QVERIFY(item); | 
| 2140 |     QVERIFY(item->hasActiveFocus()); | 
| 2141 |  | 
| 2142 |     // move to item4 | 
| 2143 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "" , false, 1); | 
| 2144 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2145 |     QVERIFY(key.isAccepted()); | 
| 2146 |  | 
| 2147 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item4" ); | 
| 2148 |     QVERIFY(item); | 
| 2149 |     QVERIFY(item->hasActiveFocus()); | 
| 2150 |  | 
| 2151 |     // left | 
| 2152 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "" , false, 1); | 
| 2153 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2154 |     QVERIFY(key.isAccepted()); | 
| 2155 |  | 
| 2156 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item3" ); | 
| 2157 |     QVERIFY(item); | 
| 2158 |     QVERIFY(item->hasActiveFocus()); | 
| 2159 |  | 
| 2160 |     // back to item4 | 
| 2161 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "" , false, 1); | 
| 2162 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2163 |     QVERIFY(key.isAccepted()); | 
| 2164 |  | 
| 2165 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item4" ); | 
| 2166 |     QVERIFY(item); | 
| 2167 |     QVERIFY(item->hasActiveFocus()); | 
| 2168 |  | 
| 2169 |     // up | 
| 2170 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "" , false, 1); | 
| 2171 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2172 |     QVERIFY(key.isAccepted()); | 
| 2173 |  | 
| 2174 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item2" ); | 
| 2175 |     QVERIFY(item); | 
| 2176 |     QVERIFY(item->hasActiveFocus()); | 
| 2177 |  | 
| 2178 |     // back to item4 | 
| 2179 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "" , false, 1); | 
| 2180 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2181 |     QVERIFY(key.isAccepted()); | 
| 2182 |  | 
| 2183 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item4" ); | 
| 2184 |     QVERIFY(item); | 
| 2185 |     QVERIFY(item->hasActiveFocus()); | 
| 2186 |  | 
| 2187 |     // tab | 
| 2188 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 2189 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2190 |     QVERIFY(key.isAccepted()); | 
| 2191 |  | 
| 2192 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item1" ); | 
| 2193 |     QVERIFY(item); | 
| 2194 |     QVERIFY(item->hasActiveFocus()); | 
| 2195 |  | 
| 2196 |     // back to item4 | 
| 2197 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "" , false, 1); | 
| 2198 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2199 |     QVERIFY(key.isAccepted()); | 
| 2200 |  | 
| 2201 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item4" ); | 
| 2202 |     QVERIFY(item); | 
| 2203 |     QVERIFY(item->hasActiveFocus()); | 
| 2204 |  | 
| 2205 |     // backtab | 
| 2206 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "" , false, 1); | 
| 2207 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2208 |     QVERIFY(key.isAccepted()); | 
| 2209 |  | 
| 2210 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item3" ); | 
| 2211 |     QVERIFY(item); | 
| 2212 |     QVERIFY(item->hasActiveFocus()); | 
| 2213 |  | 
| 2214 |     delete window; | 
| 2215 | } | 
| 2216 |  | 
| 2217 | // QTBUG-75399 | 
| 2218 | void tst_QQuickItem::keyNavigation_implicitDestroy() | 
| 2219 | { | 
| 2220 |     QQuickView view; | 
| 2221 |     view.setSource(testFileUrl(fileName: "keynavigationtest_implicitDestroy.qml" )); | 
| 2222 |     view.show(); | 
| 2223 |  | 
| 2224 |     QVERIFY(QTest::qWaitForWindowActive(&view)); | 
| 2225 |  | 
| 2226 |     QQuickItem *root = view.rootObject(); | 
| 2227 |     QVERIFY(QMetaObject::invokeMethod(root, "createImplicitKeyNavigation" )); | 
| 2228 |  | 
| 2229 |     // process events is necessary to trigger upcoming memory access violation | 
| 2230 |     QTest::qWait(ms: 0); | 
| 2231 |  | 
| 2232 |     QVERIFY(root->hasActiveFocus()); | 
| 2233 |  | 
| 2234 |     QKeyEvent keyPress = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "" , false, 1); | 
| 2235 |     QGuiApplication::sendEvent(receiver: &view, event: &keyPress); // <-- access violation happens here | 
| 2236 |     // this should fail the test, even if the access violation does not occur | 
| 2237 |     QVERIFY(!keyPress.isAccepted()); | 
| 2238 | } | 
| 2239 |  | 
| 2240 | void tst_QQuickItem::keyNavigation_focusReason() | 
| 2241 | { | 
| 2242 |     QQuickView *window = new QQuickView(nullptr); | 
| 2243 |     window->setBaseSize(QSize(240,320)); | 
| 2244 |  | 
| 2245 |     FocusEventFilter focusEventFilter; | 
| 2246 |  | 
| 2247 |     window->setSource(testFileUrl(fileName: "keynavigationtest.qml" )); | 
| 2248 |     window->show(); | 
| 2249 |     window->requestActivate(); | 
| 2250 |  | 
| 2251 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 2252 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 2253 |  | 
| 2254 |     // install event filter on first item | 
| 2255 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item1" ); | 
| 2256 |     QVERIFY(item); | 
| 2257 |     QVERIFY(item->hasActiveFocus()); | 
| 2258 |     item->installEventFilter(filterObj: &focusEventFilter); | 
| 2259 |  | 
| 2260 |     //install event filter on second item | 
| 2261 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item2" ); | 
| 2262 |     QVERIFY(item); | 
| 2263 |     item->installEventFilter(filterObj: &focusEventFilter); | 
| 2264 |  | 
| 2265 |     //install event filter on third item | 
| 2266 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item3" ); | 
| 2267 |     QVERIFY(item); | 
| 2268 |     item->installEventFilter(filterObj: &focusEventFilter); | 
| 2269 |  | 
| 2270 |     //install event filter on last item | 
| 2271 |     item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item4" ); | 
| 2272 |     QVERIFY(item); | 
| 2273 |     item->installEventFilter(filterObj: &focusEventFilter); | 
| 2274 |  | 
| 2275 |     // tab | 
| 2276 |     QKeyEvent key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "" , false, 1); | 
| 2277 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2278 |     QVERIFY(key.isAccepted()); | 
| 2279 |     QCOMPARE(focusEventFilter.lastFocusReason, Qt::TabFocusReason); | 
| 2280 |  | 
| 2281 |     // backtab | 
| 2282 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "" , false, 1); | 
| 2283 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2284 |     QVERIFY(key.isAccepted()); | 
| 2285 |     QCOMPARE(focusEventFilter.lastFocusReason, Qt::BacktabFocusReason); | 
| 2286 |  | 
| 2287 |     // right - it's also one kind of key navigation | 
| 2288 |     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "" , false, 1); | 
| 2289 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2290 |     QVERIFY(key.isAccepted()); | 
| 2291 |     QCOMPARE(focusEventFilter.lastFocusReason, Qt::TabFocusReason); | 
| 2292 |  | 
| 2293 |     item->setFocus(focus: true, reason: Qt::OtherFocusReason); | 
| 2294 |     QVERIFY(item->hasActiveFocus()); | 
| 2295 |     QCOMPARE(focusEventFilter.lastFocusReason, Qt::OtherFocusReason); | 
| 2296 |  | 
| 2297 |     delete window; | 
| 2298 | } | 
| 2299 |  | 
| 2300 | void tst_QQuickItem::keyNavigation_loop() | 
| 2301 | { | 
| 2302 |     // QTBUG-47229 | 
| 2303 |     QQuickView *window = new QQuickView(nullptr); | 
| 2304 |     window->setBaseSize(QSize(240,320)); | 
| 2305 |  | 
| 2306 |     window->setSource(testFileUrl(fileName: "keynavigationtest_loop.qml" )); | 
| 2307 |     window->show(); | 
| 2308 |     window->requestActivate(); | 
| 2309 |  | 
| 2310 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 2311 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 2312 |  | 
| 2313 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item1" ); | 
| 2314 |     QVERIFY(item); | 
| 2315 |     QVERIFY(item->hasActiveFocus()); | 
| 2316 |  | 
| 2317 |     QKeyEvent key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "" , false, 1); | 
| 2318 |     QGuiApplication::sendEvent(receiver: window, event: &key); | 
| 2319 |     QVERIFY(key.isAccepted()); | 
| 2320 |     QVERIFY(item->hasActiveFocus()); | 
| 2321 |  | 
| 2322 |     delete window; | 
| 2323 | } | 
| 2324 |  | 
| 2325 | void tst_QQuickItem::keyNavigation_repeater() | 
| 2326 | { | 
| 2327 |     // QTBUG-83356 | 
| 2328 |     QScopedPointer<QQuickView> window(new QQuickView()); | 
| 2329 |     window->setBaseSize(QSize(240,320)); | 
| 2330 |  | 
| 2331 |     window->setSource(testFileUrl(fileName: "keynavigationtest_repeater.qml" )); | 
| 2332 |     window->show(); | 
| 2333 |     window->requestActivate(); | 
| 2334 |  | 
| 2335 |     QVariant result; | 
| 2336 |     QVERIFY(QMetaObject::invokeMethod(window->rootObject(), "verify" , | 
| 2337 |             Q_RETURN_ARG(QVariant, result))); | 
| 2338 |     QVERIFY(result.toBool()); | 
| 2339 | } | 
| 2340 |  | 
| 2341 | void tst_QQuickItem::smooth() | 
| 2342 | { | 
| 2343 |     QQmlComponent component(&engine); | 
| 2344 |     component.setData("import QtQuick 2.0; Item { smooth: false; }" , baseUrl: QUrl::fromLocalFile(localfile: "" )); | 
| 2345 |     QQuickItem *item = qobject_cast<QQuickItem*>(object: component.create()); | 
| 2346 |     QSignalSpy spy(item, SIGNAL(smoothChanged(bool))); | 
| 2347 |  | 
| 2348 |     QVERIFY(item); | 
| 2349 |     QVERIFY(!item->smooth()); | 
| 2350 |  | 
| 2351 |     item->setSmooth(true); | 
| 2352 |     QVERIFY(item->smooth()); | 
| 2353 |     QCOMPARE(spy.count(),1); | 
| 2354 |     QList<QVariant> arguments = spy.first(); | 
| 2355 |     QCOMPARE(arguments.count(), 1); | 
| 2356 |     QVERIFY(arguments.at(0).toBool()); | 
| 2357 |  | 
| 2358 |     item->setSmooth(true); | 
| 2359 |     QCOMPARE(spy.count(),1); | 
| 2360 |  | 
| 2361 |     item->setSmooth(false); | 
| 2362 |     QVERIFY(!item->smooth()); | 
| 2363 |     QCOMPARE(spy.count(),2); | 
| 2364 |     item->setSmooth(false); | 
| 2365 |     QCOMPARE(spy.count(),2); | 
| 2366 |  | 
| 2367 |     delete item; | 
| 2368 | } | 
| 2369 |  | 
| 2370 | void tst_QQuickItem::antialiasing() | 
| 2371 | { | 
| 2372 |     QQmlComponent component(&engine); | 
| 2373 |     component.setData("import QtQuick 2.0; Item { antialiasing: false; }" , baseUrl: QUrl::fromLocalFile(localfile: "" )); | 
| 2374 |     QQuickItem *item = qobject_cast<QQuickItem*>(object: component.create()); | 
| 2375 |     QSignalSpy spy(item, SIGNAL(antialiasingChanged(bool))); | 
| 2376 |  | 
| 2377 |     QVERIFY(item); | 
| 2378 |     QVERIFY(!item->antialiasing()); | 
| 2379 |  | 
| 2380 |     item->setAntialiasing(true); | 
| 2381 |     QVERIFY(item->antialiasing()); | 
| 2382 |     QCOMPARE(spy.count(),1); | 
| 2383 |     QList<QVariant> arguments = spy.first(); | 
| 2384 |     QCOMPARE(arguments.count(), 1); | 
| 2385 |     QVERIFY(arguments.at(0).toBool()); | 
| 2386 |  | 
| 2387 |     item->setAntialiasing(true); | 
| 2388 |     QCOMPARE(spy.count(),1); | 
| 2389 |  | 
| 2390 |     item->setAntialiasing(false); | 
| 2391 |     QVERIFY(!item->antialiasing()); | 
| 2392 |     QCOMPARE(spy.count(),2); | 
| 2393 |     item->setAntialiasing(false); | 
| 2394 |     QCOMPARE(spy.count(),2); | 
| 2395 |  | 
| 2396 |     delete item; | 
| 2397 | } | 
| 2398 |  | 
| 2399 | void tst_QQuickItem::clip() | 
| 2400 | { | 
| 2401 |     QQmlComponent component(&engine); | 
| 2402 |     component.setData("import QtQuick 2.0\nItem { clip: false\n }" , baseUrl: QUrl::fromLocalFile(localfile: "" )); | 
| 2403 |     QQuickItem *item = qobject_cast<QQuickItem*>(object: component.create()); | 
| 2404 |     QSignalSpy spy(item, SIGNAL(clipChanged(bool))); | 
| 2405 |  | 
| 2406 |     QVERIFY(item); | 
| 2407 |     QVERIFY(!item->clip()); | 
| 2408 |  | 
| 2409 |     item->setClip(true); | 
| 2410 |     QVERIFY(item->clip()); | 
| 2411 |  | 
| 2412 |     QList<QVariant> arguments = spy.first(); | 
| 2413 |     QCOMPARE(arguments.count(), 1); | 
| 2414 |     QVERIFY(arguments.at(0).toBool()); | 
| 2415 |  | 
| 2416 |     QCOMPARE(spy.count(),1); | 
| 2417 |     item->setClip(true); | 
| 2418 |     QCOMPARE(spy.count(),1); | 
| 2419 |  | 
| 2420 |     item->setClip(false); | 
| 2421 |     QVERIFY(!item->clip()); | 
| 2422 |     QCOMPARE(spy.count(),2); | 
| 2423 |     item->setClip(false); | 
| 2424 |     QCOMPARE(spy.count(),2); | 
| 2425 |  | 
| 2426 |     delete item; | 
| 2427 | } | 
| 2428 |  | 
| 2429 | void tst_QQuickItem::mapCoordinates() | 
| 2430 | { | 
| 2431 |     QFETCH(int, x); | 
| 2432 |     QFETCH(int, y); | 
| 2433 |  | 
| 2434 |     QQuickView *window = new QQuickView(nullptr); | 
| 2435 |     window->setBaseSize(QSize(300, 300)); | 
| 2436 |     window->setSource(testFileUrl(fileName: "mapCoordinates.qml" )); | 
| 2437 |     window->show(); | 
| 2438 |     qApp->processEvents(); | 
| 2439 |  | 
| 2440 |     QQuickItem *root = qobject_cast<QQuickItem*>(object: window->rootObject()); | 
| 2441 |     QVERIFY(root != nullptr); | 
| 2442 |     QQuickItem *a = findItem<QQuickItem>(parent: window->rootObject(), objectName: "itemA" ); | 
| 2443 |     QVERIFY(a != nullptr); | 
| 2444 |     QQuickItem *b = findItem<QQuickItem>(parent: window->rootObject(), objectName: "itemB" ); | 
| 2445 |     QVERIFY(b != nullptr); | 
| 2446 |  | 
| 2447 |     QVariant result; | 
| 2448 |  | 
| 2449 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAToB" , | 
| 2450 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); | 
| 2451 |     QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapToItem(b, QPointF(x, y))); | 
| 2452 |  | 
| 2453 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAToBPoint" , | 
| 2454 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); | 
| 2455 |     QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapToItem(b, QPointF(x, y))); | 
| 2456 |  | 
| 2457 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAFromB" , | 
| 2458 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); | 
| 2459 |     QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapFromItem(b, QPointF(x, y))); | 
| 2460 |  | 
| 2461 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAFromBPoint" , | 
| 2462 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); | 
| 2463 |     QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapFromItem(b, QPointF(x, y))); | 
| 2464 |  | 
| 2465 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAToNull" , | 
| 2466 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); | 
| 2467 |     QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapToScene(QPointF(x, y))); | 
| 2468 |  | 
| 2469 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAFromNull" , | 
| 2470 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); | 
| 2471 |     QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapFromScene(QPointF(x, y))); | 
| 2472 |  | 
| 2473 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAToGlobal" , | 
| 2474 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); | 
| 2475 |     QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapToGlobal(QPointF(x, y))); | 
| 2476 |  | 
| 2477 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAToGlobalPoint" , | 
| 2478 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); | 
| 2479 |     QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapToGlobal(QPointF(x, y))); | 
| 2480 |  | 
| 2481 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAFromGlobal" , | 
| 2482 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); | 
| 2483 |     QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapFromGlobal(QPointF(x, y))); | 
| 2484 |  | 
| 2485 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAFromGlobalPoint" , | 
| 2486 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); | 
| 2487 |     QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapFromGlobal(QPointF(x, y))); | 
| 2488 |  | 
| 2489 |     // for orphans we are primarily testing that we don't crash. | 
| 2490 |     // when orphaned the final position is the original position of the item translated by x,y | 
| 2491 |     QVERIFY(QMetaObject::invokeMethod(root, "mapOrphanToGlobal" , | 
| 2492 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); | 
| 2493 |     QCOMPARE(result.value<QPointF>(), QPointF(150,150) + QPointF(x, y)); | 
| 2494 |  | 
| 2495 |     QVERIFY(QMetaObject::invokeMethod(root, "mapOrphanFromGlobal" , | 
| 2496 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); | 
| 2497 |     QCOMPARE(result.value<QPointF>(), -QPointF(150,150) + QPointF(x, y)); | 
| 2498 |  | 
| 2499 |     QString warning1 = testFileUrl(fileName: "mapCoordinates.qml" ).toString() + ":35:5: QML Item: mapToItem() given argument \"1122\" which is neither null nor an Item" ; | 
| 2500 |     QString warning2 = testFileUrl(fileName: "mapCoordinates.qml" ).toString() + ":35:5: QML Item: mapFromItem() given argument \"1122\" which is neither null nor an Item" ; | 
| 2501 |  | 
| 2502 |     QTest::ignoreMessage(type: QtWarningMsg, qPrintable(warning1)); | 
| 2503 |     QVERIFY(QMetaObject::invokeMethod(root, "checkMapAToInvalid" , | 
| 2504 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); | 
| 2505 |     QVERIFY(result.toBool()); | 
| 2506 |  | 
| 2507 |     QTest::ignoreMessage(type: QtWarningMsg, qPrintable(warning2)); | 
| 2508 |     QVERIFY(QMetaObject::invokeMethod(root, "checkMapAFromInvalid" , | 
| 2509 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); | 
| 2510 |     QVERIFY(result.toBool()); | 
| 2511 |  | 
| 2512 |     delete window; | 
| 2513 | } | 
| 2514 |  | 
| 2515 | void tst_QQuickItem::mapCoordinates_data() | 
| 2516 | { | 
| 2517 |     QTest::addColumn<int>(name: "x" ); | 
| 2518 |     QTest::addColumn<int>(name: "y" ); | 
| 2519 |  | 
| 2520 |     for (int i=-20; i<=20; i+=10) | 
| 2521 |         QTest::newRow(dataTag: QTest::toString(i)) << i << i; | 
| 2522 | } | 
| 2523 |  | 
| 2524 | void tst_QQuickItem::mapCoordinatesRect() | 
| 2525 | { | 
| 2526 |     QFETCH(int, x); | 
| 2527 |     QFETCH(int, y); | 
| 2528 |     QFETCH(int, width); | 
| 2529 |     QFETCH(int, height); | 
| 2530 |  | 
| 2531 |     QQuickView *window = new QQuickView(nullptr); | 
| 2532 |     window->setBaseSize(QSize(300, 300)); | 
| 2533 |     window->setSource(testFileUrl(fileName: "mapCoordinatesRect.qml" )); | 
| 2534 |     window->show(); | 
| 2535 |     qApp->processEvents(); | 
| 2536 |  | 
| 2537 |     QQuickItem *root = qobject_cast<QQuickItem*>(object: window->rootObject()); | 
| 2538 |     QVERIFY(root != nullptr); | 
| 2539 |     QQuickItem *a = findItem<QQuickItem>(parent: window->rootObject(), objectName: "itemA" ); | 
| 2540 |     QVERIFY(a != nullptr); | 
| 2541 |     QQuickItem *b = findItem<QQuickItem>(parent: window->rootObject(), objectName: "itemB" ); | 
| 2542 |     QVERIFY(b != nullptr); | 
| 2543 |  | 
| 2544 |     QVariant result; | 
| 2545 |  | 
| 2546 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAToB" , | 
| 2547 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height))); | 
| 2548 |     QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectToItem(b, QRectF(x, y, width, height))); | 
| 2549 |  | 
| 2550 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAToBRect" , | 
| 2551 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height))); | 
| 2552 |     QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectToItem(b, QRectF(x, y, width, height))); | 
| 2553 |  | 
| 2554 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAFromB" , | 
| 2555 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height))); | 
| 2556 |     QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectFromItem(b, QRectF(x, y, width, height))); | 
| 2557 |  | 
| 2558 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAFromBRect" , | 
| 2559 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height))); | 
| 2560 |     QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectFromItem(b, QRectF(x, y, width, height))); | 
| 2561 |  | 
| 2562 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAToNull" , | 
| 2563 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height))); | 
| 2564 |     QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectToScene(QRectF(x, y, width, height))); | 
| 2565 |  | 
| 2566 |     QVERIFY(QMetaObject::invokeMethod(root, "mapAFromNull" , | 
| 2567 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height))); | 
| 2568 |     QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectFromScene(QRectF(x, y, width, height))); | 
| 2569 |  | 
| 2570 |     QString warning1 = testFileUrl(fileName: "mapCoordinatesRect.qml" ).toString() + ":35:5: QML Item: mapToItem() given argument \"1122\" which is neither null nor an Item" ; | 
| 2571 |     QString warning2 = testFileUrl(fileName: "mapCoordinatesRect.qml" ).toString() + ":35:5: QML Item: mapFromItem() given argument \"1122\" which is neither null nor an Item" ; | 
| 2572 |  | 
| 2573 |     QTest::ignoreMessage(type: QtWarningMsg, qPrintable(warning1)); | 
| 2574 |     QVERIFY(QMetaObject::invokeMethod(root, "checkMapAToInvalid" , | 
| 2575 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height))); | 
| 2576 |     QVERIFY(result.toBool()); | 
| 2577 |  | 
| 2578 |     QTest::ignoreMessage(type: QtWarningMsg, qPrintable(warning2)); | 
| 2579 |     QVERIFY(QMetaObject::invokeMethod(root, "checkMapAFromInvalid" , | 
| 2580 |             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height))); | 
| 2581 |     QVERIFY(result.toBool()); | 
| 2582 |  | 
| 2583 |     delete window; | 
| 2584 | } | 
| 2585 |  | 
| 2586 | void tst_QQuickItem::mapCoordinatesRect_data() | 
| 2587 | { | 
| 2588 |     QTest::addColumn<int>(name: "x" ); | 
| 2589 |     QTest::addColumn<int>(name: "y" ); | 
| 2590 |     QTest::addColumn<int>(name: "width" ); | 
| 2591 |     QTest::addColumn<int>(name: "height" ); | 
| 2592 |  | 
| 2593 |     for (int i=-20; i<=20; i+=5) | 
| 2594 |         QTest::newRow(dataTag: QTest::toString(i)) << i << i << i << i; | 
| 2595 | } | 
| 2596 |  | 
| 2597 | void tst_QQuickItem::transforms_data() | 
| 2598 | { | 
| 2599 |     QTest::addColumn<QByteArray>(name: "qml" ); | 
| 2600 |     QTest::addColumn<QTransform>(name: "transform" ); | 
| 2601 |     QTest::newRow(dataTag: "translate" ) << QByteArray("Translate { x: 10; y: 20 }" ) | 
| 2602 |         << QTransform(1,0,0,0,1,0,10,20,1); | 
| 2603 |     QTest::newRow(dataTag: "matrix4x4" ) << QByteArray("Matrix4x4 { matrix: Qt.matrix4x4(1,0,0,10, 0,1,0,15, 0,0,1,0, 0,0,0,1) }" ) | 
| 2604 |         << QTransform(1,0,0,0,1,0,10,15,1); | 
| 2605 |     QTest::newRow(dataTag: "rotation" ) << QByteArray("Rotation { angle: 90 }" ) | 
| 2606 |         << QTransform(0,1,0,-1,0,0,0,0,1); | 
| 2607 |     QTest::newRow(dataTag: "scale" ) << QByteArray("Scale { xScale: 1.5; yScale: -2  }" ) | 
| 2608 |         << QTransform(1.5,0,0,0,-2,0,0,0,1); | 
| 2609 |     QTest::newRow(dataTag: "sequence" ) << QByteArray("[ Translate { x: 10; y: 20 }, Scale { xScale: 1.5; yScale: -2  } ]" ) | 
| 2610 |         << QTransform(1,0,0,0,1,0,10,20,1) * QTransform(1.5,0,0,0,-2,0,0,0,1); | 
| 2611 | } | 
| 2612 |  | 
| 2613 | void tst_QQuickItem::transforms() | 
| 2614 | { | 
| 2615 |     QFETCH(QByteArray, qml); | 
| 2616 |     QFETCH(QTransform, transform); | 
| 2617 |     QQmlComponent component(&engine); | 
| 2618 |     component.setData("import QtQuick 2.3\nItem { transform: " +qml+"}" , baseUrl: QUrl::fromLocalFile(localfile: "" )); | 
| 2619 |     QQuickItem *item = qobject_cast<QQuickItem*>(object: component.create()); | 
| 2620 |     QVERIFY(item); | 
| 2621 |     QCOMPARE(item->itemTransform(nullptr,nullptr), transform); | 
| 2622 | } | 
| 2623 |  | 
| 2624 | void tst_QQuickItem::childrenProperty() | 
| 2625 | { | 
| 2626 |     QQmlComponent component(&engine, testFileUrl(fileName: "childrenProperty.qml" )); | 
| 2627 |  | 
| 2628 |     QObject *o = component.create(); | 
| 2629 |     QVERIFY(o != nullptr); | 
| 2630 |  | 
| 2631 |     QCOMPARE(o->property("test1" ).toBool(), true); | 
| 2632 |     QCOMPARE(o->property("test2" ).toBool(), true); | 
| 2633 |     QCOMPARE(o->property("test3" ).toBool(), true); | 
| 2634 |     QCOMPARE(o->property("test4" ).toBool(), true); | 
| 2635 |     QCOMPARE(o->property("test5" ).toBool(), true); | 
| 2636 |     delete o; | 
| 2637 | } | 
| 2638 |  | 
| 2639 | void tst_QQuickItem::resourcesProperty() | 
| 2640 | { | 
| 2641 |     QQmlComponent component(&engine, testFileUrl(fileName: "resourcesProperty.qml" )); | 
| 2642 |  | 
| 2643 |     QObject *object = component.create(); | 
| 2644 |     QVERIFY(object != nullptr); | 
| 2645 |  | 
| 2646 |     QQmlProperty property(object, "resources" , component.creationContext()); | 
| 2647 |  | 
| 2648 |     QVERIFY(property.isValid()); | 
| 2649 |     QQmlListReference list = qvariant_cast<QQmlListReference>(v: property.read()); | 
| 2650 |     QVERIFY(list.isValid()); | 
| 2651 |  | 
| 2652 |     QCOMPARE(list.count(), 4); | 
| 2653 |  | 
| 2654 |     QCOMPARE(object->property("test1" ).toBool(), true); | 
| 2655 |     QCOMPARE(object->property("test2" ).toBool(), true); | 
| 2656 |     QCOMPARE(object->property("test3" ).toBool(), true); | 
| 2657 |     QCOMPARE(object->property("test4" ).toBool(), true); | 
| 2658 |     QCOMPARE(object->property("test5" ).toBool(), true); | 
| 2659 |     QCOMPARE(object->property("test6" ).toBool(), true); | 
| 2660 |  | 
| 2661 |     QObject *subObject = object->findChild<QObject *>(aName: "subObject" ); | 
| 2662 |  | 
| 2663 |     QVERIFY(subObject); | 
| 2664 |  | 
| 2665 |     QCOMPARE(object, subObject->parent()); | 
| 2666 |  | 
| 2667 |     delete subObject; | 
| 2668 |  | 
| 2669 |     QCOMPARE(list.count(), 3); | 
| 2670 |  | 
| 2671 |     delete object; | 
| 2672 | } | 
| 2673 |  | 
| 2674 | void tst_QQuickItem::propertyChanges() | 
| 2675 | { | 
| 2676 |     QQuickView *window = new QQuickView(nullptr); | 
| 2677 |     window->setBaseSize(QSize(300, 300)); | 
| 2678 |     window->setSource(testFileUrl(fileName: "propertychanges.qml" )); | 
| 2679 |     window->show(); | 
| 2680 |     window->requestActivate(); | 
| 2681 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 2682 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 2683 |  | 
| 2684 |     QQuickItem *item = findItem<QQuickItem>(parent: window->rootObject(), objectName: "item" ); | 
| 2685 |     QQuickItem *parentItem = findItem<QQuickItem>(parent: window->rootObject(), objectName: "parentItem" ); | 
| 2686 |  | 
| 2687 |     QVERIFY(item); | 
| 2688 |     QVERIFY(parentItem); | 
| 2689 |  | 
| 2690 |     QSignalSpy parentSpy(item, SIGNAL(parentChanged(QQuickItem*))); | 
| 2691 |     QSignalSpy widthSpy(item, SIGNAL(widthChanged())); | 
| 2692 |     QSignalSpy heightSpy(item, SIGNAL(heightChanged())); | 
| 2693 |     QSignalSpy baselineOffsetSpy(item, SIGNAL(baselineOffsetChanged(qreal))); | 
| 2694 |     QSignalSpy childrenRectSpy(parentItem, SIGNAL(childrenRectChanged(QRectF))); | 
| 2695 |     QSignalSpy focusSpy(item, SIGNAL(focusChanged(bool))); | 
| 2696 |     QSignalSpy wantsFocusSpy(parentItem, SIGNAL(activeFocusChanged(bool))); | 
| 2697 |     QSignalSpy childrenChangedSpy(parentItem, SIGNAL(childrenChanged())); | 
| 2698 |     QSignalSpy xSpy(item, SIGNAL(xChanged())); | 
| 2699 |     QSignalSpy ySpy(item, SIGNAL(yChanged())); | 
| 2700 |  | 
| 2701 |     item->setParentItem(parentItem); | 
| 2702 |     item->setWidth(100.0); | 
| 2703 |     item->setHeight(200.0); | 
| 2704 |     item->setFocus(true); | 
| 2705 |     item->setBaselineOffset(10.0); | 
| 2706 |  | 
| 2707 |     QCOMPARE(item->parentItem(), parentItem); | 
| 2708 |     QCOMPARE(parentSpy.count(),1); | 
| 2709 |     QList<QVariant> parentArguments = parentSpy.first(); | 
| 2710 |     QCOMPARE(parentArguments.count(), 1); | 
| 2711 |     QCOMPARE(item->parentItem(), qvariant_cast<QQuickItem *>(parentArguments.at(0))); | 
| 2712 |     QCOMPARE(childrenChangedSpy.count(),1); | 
| 2713 |  | 
| 2714 |     item->setParentItem(parentItem); | 
| 2715 |     QCOMPARE(childrenChangedSpy.count(),1); | 
| 2716 |  | 
| 2717 |     QCOMPARE(item->width(), 100.0); | 
| 2718 |     QCOMPARE(widthSpy.count(),1); | 
| 2719 |  | 
| 2720 |     QCOMPARE(item->height(), 200.0); | 
| 2721 |     QCOMPARE(heightSpy.count(),1); | 
| 2722 |  | 
| 2723 |     QCOMPARE(item->baselineOffset(), 10.0); | 
| 2724 |     QCOMPARE(baselineOffsetSpy.count(),1); | 
| 2725 |     QList<QVariant> baselineOffsetArguments = baselineOffsetSpy.first(); | 
| 2726 |     QCOMPARE(baselineOffsetArguments.count(), 1); | 
| 2727 |     QCOMPARE(item->baselineOffset(), baselineOffsetArguments.at(0).toReal()); | 
| 2728 |  | 
| 2729 |     QCOMPARE(parentItem->childrenRect(), QRectF(0.0,0.0,100.0,200.0)); | 
| 2730 |     QCOMPARE(childrenRectSpy.count(),1); | 
| 2731 |     QList<QVariant> childrenRectArguments = childrenRectSpy.at(i: 0); | 
| 2732 |     QCOMPARE(childrenRectArguments.count(), 1); | 
| 2733 |     QCOMPARE(parentItem->childrenRect(), childrenRectArguments.at(0).toRectF()); | 
| 2734 |  | 
| 2735 |     QCOMPARE(item->hasActiveFocus(), true); | 
| 2736 |     QCOMPARE(focusSpy.count(),1); | 
| 2737 |     QList<QVariant> focusArguments = focusSpy.first(); | 
| 2738 |     QCOMPARE(focusArguments.count(), 1); | 
| 2739 |     QCOMPARE(focusArguments.at(0).toBool(), true); | 
| 2740 |  | 
| 2741 |     QCOMPARE(parentItem->hasActiveFocus(), false); | 
| 2742 |     QCOMPARE(parentItem->hasFocus(), false); | 
| 2743 |     QCOMPARE(wantsFocusSpy.count(),0); | 
| 2744 |  | 
| 2745 |     item->setX(10.0); | 
| 2746 |     QCOMPARE(item->x(), 10.0); | 
| 2747 |     QCOMPARE(xSpy.count(), 1); | 
| 2748 |  | 
| 2749 |     item->setY(10.0); | 
| 2750 |     QCOMPARE(item->y(), 10.0); | 
| 2751 |     QCOMPARE(ySpy.count(), 1); | 
| 2752 |  | 
| 2753 |     delete window; | 
| 2754 | } | 
| 2755 |  | 
| 2756 | void tst_QQuickItem::nonexistentPropertyConnection() | 
| 2757 | { | 
| 2758 |     // QTBUG-56551: don't crash | 
| 2759 |     QQmlComponent component(&engine, testFileUrl(fileName: "nonexistentPropertyConnection.qml" )); | 
| 2760 |     QObject *o = component.create(); | 
| 2761 |     QVERIFY(o); | 
| 2762 |     delete o; | 
| 2763 | } | 
| 2764 |  | 
| 2765 | void tst_QQuickItem::childrenRect() | 
| 2766 | { | 
| 2767 |     QQuickView *window = new QQuickView(nullptr); | 
| 2768 |     window->setSource(testFileUrl(fileName: "childrenRect.qml" )); | 
| 2769 |     window->setBaseSize(QSize(240,320)); | 
| 2770 |     window->show(); | 
| 2771 |  | 
| 2772 |     QQuickItem *o = window->rootObject(); | 
| 2773 |     QQuickItem *item = o->findChild<QQuickItem*>(aName: "testItem" ); | 
| 2774 |     QCOMPARE(item->width(), qreal(0)); | 
| 2775 |     QCOMPARE(item->height(), qreal(0)); | 
| 2776 |  | 
| 2777 |     o->setProperty(name: "childCount" , value: 1); | 
| 2778 |     QCOMPARE(item->width(), qreal(10)); | 
| 2779 |     QCOMPARE(item->height(), qreal(20)); | 
| 2780 |  | 
| 2781 |     o->setProperty(name: "childCount" , value: 5); | 
| 2782 |     QCOMPARE(item->width(), qreal(50)); | 
| 2783 |     QCOMPARE(item->height(), qreal(100)); | 
| 2784 |  | 
| 2785 |     o->setProperty(name: "childCount" , value: 0); | 
| 2786 |     QCOMPARE(item->width(), qreal(0)); | 
| 2787 |     QCOMPARE(item->height(), qreal(0)); | 
| 2788 |  | 
| 2789 |     delete o; | 
| 2790 |     delete window; | 
| 2791 | } | 
| 2792 |  | 
| 2793 | // QTBUG-11383 | 
| 2794 | void tst_QQuickItem::childrenRectBug() | 
| 2795 | { | 
| 2796 |     QQuickView *window = new QQuickView(nullptr); | 
| 2797 |  | 
| 2798 |     QString warning = testFileUrl(fileName: "childrenRectBug.qml" ).toString() + ":7:5: QML Item: Binding loop detected for property \"height\"" ; | 
| 2799 |     QTest::ignoreMessage(type: QtWarningMsg, qPrintable(warning)); | 
| 2800 |     QTest::ignoreMessage(type: QtWarningMsg, qPrintable(warning)); | 
| 2801 |  | 
| 2802 |     window->setSource(testFileUrl(fileName: "childrenRectBug.qml" )); | 
| 2803 |     window->show(); | 
| 2804 |  | 
| 2805 |     QQuickItem *o = window->rootObject(); | 
| 2806 |     QQuickItem *item = o->findChild<QQuickItem*>(aName: "theItem" ); | 
| 2807 |     QCOMPARE(item->width(), qreal(200)); | 
| 2808 |     QCOMPARE(item->height(), qreal(100)); | 
| 2809 |     QCOMPARE(item->x(), qreal(100)); | 
| 2810 |  | 
| 2811 |     delete window; | 
| 2812 | } | 
| 2813 |  | 
| 2814 | // QTBUG-11465 | 
| 2815 | void tst_QQuickItem::childrenRectBug2() | 
| 2816 | { | 
| 2817 |     QQuickView *window = new QQuickView(nullptr); | 
| 2818 |  | 
| 2819 |     QString warning1 = testFileUrl(fileName: "childrenRectBug2.qml" ).toString() + ":7:5: QML Item: Binding loop detected for property \"width\"" ; | 
| 2820 |     QTest::ignoreMessage(type: QtWarningMsg, qPrintable(warning1)); | 
| 2821 |     QTest::ignoreMessage(type: QtWarningMsg, qPrintable(warning1)); | 
| 2822 |  | 
| 2823 |     QString warning2 = testFileUrl(fileName: "childrenRectBug2.qml" ).toString() + ":7:5: QML Item: Binding loop detected for property \"height\"" ; | 
| 2824 |     QTest::ignoreMessage(type: QtWarningMsg, qPrintable(warning2)); | 
| 2825 |     QTest::ignoreMessage(type: QtWarningMsg, qPrintable(warning2)); | 
| 2826 |     QTest::ignoreMessage(type: QtWarningMsg, qPrintable(warning2)); | 
| 2827 |     QTest::ignoreMessage(type: QtWarningMsg, qPrintable(warning2)); | 
| 2828 |  | 
| 2829 |     window->setSource(testFileUrl(fileName: "childrenRectBug2.qml" )); | 
| 2830 |     window->show(); | 
| 2831 |  | 
| 2832 |     QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(object: window->rootObject()); | 
| 2833 |     QVERIFY(rect); | 
| 2834 |     QQuickItem *item = rect->findChild<QQuickItem*>(aName: "theItem" ); | 
| 2835 |     QCOMPARE(item->width(), qreal(100)); | 
| 2836 |     QCOMPARE(item->height(), qreal(110)); | 
| 2837 |     QCOMPARE(item->x(), qreal(130)); | 
| 2838 |  | 
| 2839 |     QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(item: rect); | 
| 2840 |     rectPrivate->setState("row" ); | 
| 2841 |     QCOMPARE(item->width(), qreal(210)); | 
| 2842 |     QCOMPARE(item->height(), qreal(50)); | 
| 2843 |     QCOMPARE(item->x(), qreal(75)); | 
| 2844 |  | 
| 2845 |     delete window; | 
| 2846 | } | 
| 2847 |  | 
| 2848 | // QTBUG-12722 | 
| 2849 | void tst_QQuickItem::childrenRectBug3() | 
| 2850 | { | 
| 2851 |     QQuickView *window = new QQuickView(nullptr); | 
| 2852 |     window->setSource(testFileUrl(fileName: "childrenRectBug3.qml" )); | 
| 2853 |     window->show(); | 
| 2854 |  | 
| 2855 |     //don't crash on delete | 
| 2856 |     delete window; | 
| 2857 | } | 
| 2858 |  | 
| 2859 | // QTBUG-38732 | 
| 2860 | void tst_QQuickItem::childrenRectBottomRightCorner() | 
| 2861 | { | 
| 2862 |     QQuickView *window = new QQuickView(nullptr); | 
| 2863 |     window->setSource(testFileUrl(fileName: "childrenRectBottomRightCorner.qml" )); | 
| 2864 |     window->show(); | 
| 2865 |  | 
| 2866 |     QQuickItem *rect = window->rootObject()->findChild<QQuickItem*>(aName: "childrenRectProxy" ); | 
| 2867 |     QCOMPARE(rect->x(), qreal(-100)); | 
| 2868 |     QCOMPARE(rect->y(), qreal(-100)); | 
| 2869 |     QCOMPARE(rect->width(), qreal(50)); | 
| 2870 |     QCOMPARE(rect->height(), qreal(50)); | 
| 2871 |  | 
| 2872 |     delete window; | 
| 2873 | } | 
| 2874 |  | 
| 2875 | struct TestListener : public QQuickItemChangeListener | 
| 2876 | { | 
| 2877 |     TestListener(bool remove = false) : remove(remove) { } | 
| 2878 |  | 
| 2879 |     void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange, const QRectF &oldGeometry) override | 
| 2880 |     { | 
| 2881 |         record(item, change: QQuickItemPrivate::Geometry, value: oldGeometry); | 
| 2882 |     } | 
| 2883 |     void itemSiblingOrderChanged(QQuickItem *item) override | 
| 2884 |     { | 
| 2885 |         record(item, change: QQuickItemPrivate::SiblingOrder); | 
| 2886 |     } | 
| 2887 |     void itemVisibilityChanged(QQuickItem *item) override | 
| 2888 |     { | 
| 2889 |         record(item, change: QQuickItemPrivate::Visibility); | 
| 2890 |     } | 
| 2891 |     void itemOpacityChanged(QQuickItem *item) override | 
| 2892 |     { | 
| 2893 |         record(item, change: QQuickItemPrivate::Opacity); | 
| 2894 |     } | 
| 2895 |     void itemRotationChanged(QQuickItem *item) override | 
| 2896 |     { | 
| 2897 |         record(item, change: QQuickItemPrivate::Rotation); | 
| 2898 |     } | 
| 2899 |     void itemImplicitWidthChanged(QQuickItem *item) override | 
| 2900 |     { | 
| 2901 |         record(item, change: QQuickItemPrivate::ImplicitWidth); | 
| 2902 |     } | 
| 2903 |     void itemImplicitHeightChanged(QQuickItem *item) override | 
| 2904 |     { | 
| 2905 |         record(item, change: QQuickItemPrivate::ImplicitHeight); | 
| 2906 |     } | 
| 2907 |     void itemDestroyed(QQuickItem *item) override | 
| 2908 |     { | 
| 2909 |         record(item, change: QQuickItemPrivate::Destroyed); | 
| 2910 |     } | 
| 2911 |     void itemChildAdded(QQuickItem *item, QQuickItem *child) override | 
| 2912 |     { | 
| 2913 |         record(item, change: QQuickItemPrivate::Children, value: QVariant::fromValue(value: child)); | 
| 2914 |     } | 
| 2915 |     void itemChildRemoved(QQuickItem *item, QQuickItem *child) override | 
| 2916 |     { | 
| 2917 |         record(item, change: QQuickItemPrivate::Children, value: QVariant::fromValue(value: child)); | 
| 2918 |     } | 
| 2919 |     void itemParentChanged(QQuickItem *item, QQuickItem *parent) override | 
| 2920 |     { | 
| 2921 |         record(item, change: QQuickItemPrivate::Parent, value: QVariant::fromValue(value: parent)); | 
| 2922 |     } | 
| 2923 |  | 
| 2924 |     QQuickAnchorsPrivate *anchorPrivate() override { return nullptr; } | 
| 2925 |  | 
| 2926 |     void record(QQuickItem *item, QQuickItemPrivate::ChangeType change, const QVariant &value = QVariant()) | 
| 2927 |     { | 
| 2928 |         changes += change; | 
| 2929 |         values[change] = value; | 
| 2930 |         // QTBUG-54732 | 
| 2931 |         if (remove) | 
| 2932 |             QQuickItemPrivate::get(item)->removeItemChangeListener(this, types: change); | 
| 2933 |     } | 
| 2934 |  | 
| 2935 |     int count(QQuickItemPrivate::ChangeType change) const | 
| 2936 |     { | 
| 2937 |         return changes.count(t: change); | 
| 2938 |     } | 
| 2939 |  | 
| 2940 |     QVariant value(QQuickItemPrivate::ChangeType change) const | 
| 2941 |     { | 
| 2942 |         return values.value(key: change); | 
| 2943 |     } | 
| 2944 |  | 
| 2945 |     bool remove; | 
| 2946 |     QList<QQuickItemPrivate::ChangeType> changes; | 
| 2947 |     QHash<QQuickItemPrivate::ChangeType, QVariant> values; | 
| 2948 | }; | 
| 2949 |  | 
| 2950 | void tst_QQuickItem::changeListener() | 
| 2951 | { | 
| 2952 |     QQuickWindow window; | 
| 2953 |     window.show(); | 
| 2954 |     QVERIFY(QTest::qWaitForWindowExposed(&window)); | 
| 2955 |  | 
| 2956 |     QQuickItem *item = new QQuickItem; | 
| 2957 |     TestListener itemListener; | 
| 2958 |     QQuickItemPrivate::get(item)->addItemChangeListener(listener: &itemListener, types: QQuickItemPrivate::ChangeTypes(0xffff)); | 
| 2959 |  | 
| 2960 |     item->setImplicitWidth(10); | 
| 2961 |     QCOMPARE(itemListener.count(QQuickItemPrivate::ImplicitWidth), 1); | 
| 2962 |     QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 1); | 
| 2963 |     QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,0,0))); | 
| 2964 |  | 
| 2965 |     item->setImplicitHeight(20); | 
| 2966 |     QCOMPARE(itemListener.count(QQuickItemPrivate::ImplicitHeight), 1); | 
| 2967 |     QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 2); | 
| 2968 |     QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,10,0))); | 
| 2969 |  | 
| 2970 |     item->setWidth(item->width() + 30); | 
| 2971 |     QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 3); | 
| 2972 |     QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,10,20))); | 
| 2973 |  | 
| 2974 |     item->setHeight(item->height() + 40); | 
| 2975 |     QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 4); | 
| 2976 |     QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,40,20))); | 
| 2977 |  | 
| 2978 |     item->setOpacity(0.5); | 
| 2979 |     QCOMPARE(itemListener.count(QQuickItemPrivate::Opacity), 1); | 
| 2980 |  | 
| 2981 |     item->setRotation(90); | 
| 2982 |     QCOMPARE(itemListener.count(QQuickItemPrivate::Rotation), 1); | 
| 2983 |  | 
| 2984 |     item->setParentItem(window.contentItem()); | 
| 2985 |     QCOMPARE(itemListener.count(QQuickItemPrivate::Parent), 1); | 
| 2986 |  | 
| 2987 |     item->setVisible(false); | 
| 2988 |     QCOMPARE(itemListener.count(QQuickItemPrivate::Visibility), 1); | 
| 2989 |  | 
| 2990 |     QQuickItemPrivate::get(item)->removeItemChangeListener(&itemListener, types: QQuickItemPrivate::ChangeTypes(0xffff)); | 
| 2991 |  | 
| 2992 |     QQuickItem *parent = new QQuickItem(window.contentItem()); | 
| 2993 |     TestListener parentListener; | 
| 2994 |     QQuickItemPrivate::get(item: parent)->addItemChangeListener(listener: &parentListener, types: QQuickItemPrivate::Children); | 
| 2995 |  | 
| 2996 |     QQuickItem *child1 = new QQuickItem; | 
| 2997 |     QQuickItem *child2 = new QQuickItem; | 
| 2998 |     TestListener child1Listener; | 
| 2999 |     TestListener child2Listener; | 
| 3000 |     QQuickItemPrivate::get(item: child1)->addItemChangeListener(listener: &child1Listener, types: QQuickItemPrivate::Parent | QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::Destroyed); | 
| 3001 |     QQuickItemPrivate::get(item: child2)->addItemChangeListener(listener: &child2Listener, types: QQuickItemPrivate::Parent | QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::Destroyed); | 
| 3002 |  | 
| 3003 |     child1->setParentItem(parent); | 
| 3004 |     QCOMPARE(parentListener.count(QQuickItemPrivate::Children), 1); | 
| 3005 |     QCOMPARE(parentListener.value(QQuickItemPrivate::Children), QVariant::fromValue(child1)); | 
| 3006 |     QCOMPARE(child1Listener.count(QQuickItemPrivate::Parent), 1); | 
| 3007 |     QCOMPARE(child1Listener.value(QQuickItemPrivate::Parent), QVariant::fromValue(parent)); | 
| 3008 |  | 
| 3009 |     child2->setParentItem(parent); | 
| 3010 |     QCOMPARE(parentListener.count(QQuickItemPrivate::Children), 2); | 
| 3011 |     QCOMPARE(parentListener.value(QQuickItemPrivate::Children), QVariant::fromValue(child2)); | 
| 3012 |     QCOMPARE(child2Listener.count(QQuickItemPrivate::Parent), 1); | 
| 3013 |     QCOMPARE(child2Listener.value(QQuickItemPrivate::Parent), QVariant::fromValue(parent)); | 
| 3014 |  | 
| 3015 |     child2->stackBefore(child1); | 
| 3016 |     QCOMPARE(child1Listener.count(QQuickItemPrivate::SiblingOrder), 1); | 
| 3017 |     QCOMPARE(child2Listener.count(QQuickItemPrivate::SiblingOrder), 1); | 
| 3018 |  | 
| 3019 |     child1->setParentItem(nullptr); | 
| 3020 |     QCOMPARE(parentListener.count(QQuickItemPrivate::Children), 3); | 
| 3021 |     QCOMPARE(parentListener.value(QQuickItemPrivate::Children), QVariant::fromValue(child1)); | 
| 3022 |     QCOMPARE(child1Listener.count(QQuickItemPrivate::Parent), 2); | 
| 3023 |     QCOMPARE(child1Listener.value(QQuickItemPrivate::Parent), QVariant::fromValue<QQuickItem *>(nullptr)); | 
| 3024 |  | 
| 3025 |     delete child1; | 
| 3026 |     QCOMPARE(child1Listener.count(QQuickItemPrivate::Destroyed), 1); | 
| 3027 |  | 
| 3028 |     delete child2; | 
| 3029 |     QCOMPARE(parentListener.count(QQuickItemPrivate::Children), 4); | 
| 3030 |     QCOMPARE(parentListener.value(QQuickItemPrivate::Children), QVariant::fromValue(child2)); | 
| 3031 |     QCOMPARE(child2Listener.count(QQuickItemPrivate::Parent), 2); | 
| 3032 |     QCOMPARE(child2Listener.value(QQuickItemPrivate::Parent), QVariant::fromValue<QQuickItem *>(nullptr)); | 
| 3033 |     QCOMPARE(child2Listener.count(QQuickItemPrivate::Destroyed), 1); | 
| 3034 |  | 
| 3035 |     QQuickItemPrivate::get(item: parent)->removeItemChangeListener(&parentListener, types: QQuickItemPrivate::Children); | 
| 3036 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); | 
| 3037 |  | 
| 3038 |     // QTBUG-54732: all listeners should get invoked even if they remove themselves while iterating the listeners | 
| 3039 |     QList<TestListener *> listeners; | 
| 3040 |     for (int i = 0; i < 5; ++i) | 
| 3041 |         listeners << new TestListener(true); | 
| 3042 |  | 
| 3043 |     // itemVisibilityChanged x 5 | 
| 3044 |     foreach (TestListener *listener, listeners) | 
| 3045 |         QQuickItemPrivate::get(item: parent)->addItemChangeListener(listener, types: QQuickItemPrivate::Visibility); | 
| 3046 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); | 
| 3047 |     parent->setVisible(false); | 
| 3048 |     foreach (TestListener *listener, listeners) | 
| 3049 |         QCOMPARE(listener->count(QQuickItemPrivate::Visibility), 1); | 
| 3050 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); | 
| 3051 |  | 
| 3052 |     // itemRotationChanged x 5 | 
| 3053 |     foreach (TestListener *listener, listeners) | 
| 3054 |         QQuickItemPrivate::get(item: parent)->addItemChangeListener(listener, types: QQuickItemPrivate::Rotation); | 
| 3055 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); | 
| 3056 |     parent->setRotation(90); | 
| 3057 |     foreach (TestListener *listener, listeners) | 
| 3058 |         QCOMPARE(listener->count(QQuickItemPrivate::Rotation), 1); | 
| 3059 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); | 
| 3060 |  | 
| 3061 |     // itemOpacityChanged x 5 | 
| 3062 |     foreach (TestListener *listener, listeners) | 
| 3063 |         QQuickItemPrivate::get(item: parent)->addItemChangeListener(listener, types: QQuickItemPrivate::Opacity); | 
| 3064 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); | 
| 3065 |     parent->setOpacity(0.5); | 
| 3066 |     foreach (TestListener *listener, listeners) | 
| 3067 |         QCOMPARE(listener->count(QQuickItemPrivate::Opacity), 1); | 
| 3068 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); | 
| 3069 |  | 
| 3070 |     // itemChildAdded() x 5 | 
| 3071 |     foreach (TestListener *listener, listeners) | 
| 3072 |         QQuickItemPrivate::get(item: parent)->addItemChangeListener(listener, types: QQuickItemPrivate::Children); | 
| 3073 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); | 
| 3074 |     child1 = new QQuickItem(parent); | 
| 3075 |     foreach (TestListener *listener, listeners) | 
| 3076 |         QCOMPARE(listener->count(QQuickItemPrivate::Children), 1); | 
| 3077 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); | 
| 3078 |  | 
| 3079 |     // itemParentChanged() x 5 | 
| 3080 |     foreach (TestListener *listener, listeners) | 
| 3081 |         QQuickItemPrivate::get(item: child1)->addItemChangeListener(listener, types: QQuickItemPrivate::Parent); | 
| 3082 |     QCOMPARE(QQuickItemPrivate::get(child1)->changeListeners.count(), listeners.count()); | 
| 3083 |     child1->setParentItem(nullptr); | 
| 3084 |     foreach (TestListener *listener, listeners) | 
| 3085 |         QCOMPARE(listener->count(QQuickItemPrivate::Parent), 1); | 
| 3086 |     QCOMPARE(QQuickItemPrivate::get(child1)->changeListeners.count(), 0); | 
| 3087 |  | 
| 3088 |     // itemImplicitWidthChanged() x 5 | 
| 3089 |     foreach (TestListener *listener, listeners) | 
| 3090 |         QQuickItemPrivate::get(item: parent)->addItemChangeListener(listener, types: QQuickItemPrivate::ImplicitWidth); | 
| 3091 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); | 
| 3092 |     parent->setImplicitWidth(parent->implicitWidth() + 1); | 
| 3093 |     foreach (TestListener *listener, listeners) | 
| 3094 |         QCOMPARE(listener->count(QQuickItemPrivate::ImplicitWidth), 1); | 
| 3095 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); | 
| 3096 |  | 
| 3097 |     // itemImplicitHeightChanged() x 5 | 
| 3098 |     foreach (TestListener *listener, listeners) | 
| 3099 |         QQuickItemPrivate::get(item: parent)->addItemChangeListener(listener, types: QQuickItemPrivate::ImplicitHeight); | 
| 3100 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); | 
| 3101 |     parent->setImplicitHeight(parent->implicitHeight() + 1); | 
| 3102 |     foreach (TestListener *listener, listeners) | 
| 3103 |         QCOMPARE(listener->count(QQuickItemPrivate::ImplicitHeight), 1); | 
| 3104 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); | 
| 3105 |  | 
| 3106 |     // itemGeometryChanged() x 5 | 
| 3107 |     foreach (TestListener *listener, listeners) | 
| 3108 |         QQuickItemPrivate::get(item: parent)->addItemChangeListener(listener, types: QQuickItemPrivate::Geometry); | 
| 3109 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); | 
| 3110 |     parent->setWidth(parent->width() + 1); | 
| 3111 |     foreach (TestListener *listener, listeners) | 
| 3112 |         QCOMPARE(listener->count(QQuickItemPrivate::Geometry), 1); | 
| 3113 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); | 
| 3114 |  | 
| 3115 |     // itemChildRemoved() x 5 | 
| 3116 |     child1->setParentItem(parent); | 
| 3117 |     foreach (TestListener *listener, listeners) | 
| 3118 |         QQuickItemPrivate::get(item: parent)->addItemChangeListener(listener, types: QQuickItemPrivate::Children); | 
| 3119 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); | 
| 3120 |     delete child1; | 
| 3121 |     foreach (TestListener *listener, listeners) | 
| 3122 |         QCOMPARE(listener->count(QQuickItemPrivate::Children), 2); | 
| 3123 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), 0); | 
| 3124 |  | 
| 3125 |     // itemDestroyed() x 5 | 
| 3126 |     foreach (TestListener *listener, listeners) | 
| 3127 |         QQuickItemPrivate::get(item: parent)->addItemChangeListener(listener, types: QQuickItemPrivate::Destroyed); | 
| 3128 |     QCOMPARE(QQuickItemPrivate::get(parent)->changeListeners.count(), listeners.count()); | 
| 3129 |     delete parent; | 
| 3130 |     foreach (TestListener *listener, listeners) | 
| 3131 |         QCOMPARE(listener->count(QQuickItemPrivate::Destroyed), 1); | 
| 3132 | } | 
| 3133 |  | 
| 3134 | // QTBUG-13893 | 
| 3135 | void tst_QQuickItem::transformCrash() | 
| 3136 | { | 
| 3137 |     QQuickView *window = new QQuickView(nullptr); | 
| 3138 |     window->setSource(testFileUrl(fileName: "transformCrash.qml" )); | 
| 3139 |     window->show(); | 
| 3140 |  | 
| 3141 |     delete window; | 
| 3142 | } | 
| 3143 |  | 
| 3144 | void tst_QQuickItem::implicitSize() | 
| 3145 | { | 
| 3146 |     QQuickView *window = new QQuickView(nullptr); | 
| 3147 |     window->setSource(testFileUrl(fileName: "implicitsize.qml" )); | 
| 3148 |     window->show(); | 
| 3149 |  | 
| 3150 |     QQuickItem *item = qobject_cast<QQuickItem*>(object: window->rootObject()); | 
| 3151 |     QVERIFY(item); | 
| 3152 |     QCOMPARE(item->width(), qreal(80)); | 
| 3153 |     QCOMPARE(item->height(), qreal(60)); | 
| 3154 |  | 
| 3155 |     QCOMPARE(item->implicitWidth(), qreal(200)); | 
| 3156 |     QCOMPARE(item->implicitHeight(), qreal(100)); | 
| 3157 |  | 
| 3158 |     QMetaObject::invokeMethod(obj: item, member: "resetSize" ); | 
| 3159 |  | 
| 3160 |     QCOMPARE(item->width(), qreal(200)); | 
| 3161 |     QCOMPARE(item->height(), qreal(100)); | 
| 3162 |  | 
| 3163 |     QMetaObject::invokeMethod(obj: item, member: "changeImplicit" ); | 
| 3164 |  | 
| 3165 |     QCOMPARE(item->implicitWidth(), qreal(150)); | 
| 3166 |     QCOMPARE(item->implicitHeight(), qreal(80)); | 
| 3167 |     QCOMPARE(item->width(), qreal(150)); | 
| 3168 |     QCOMPARE(item->height(), qreal(80)); | 
| 3169 |  | 
| 3170 |     QMetaObject::invokeMethod(obj: item, member: "assignImplicitBinding" ); | 
| 3171 |  | 
| 3172 |     QCOMPARE(item->implicitWidth(), qreal(150)); | 
| 3173 |     QCOMPARE(item->implicitHeight(), qreal(80)); | 
| 3174 |     QCOMPARE(item->width(), qreal(150)); | 
| 3175 |     QCOMPARE(item->height(), qreal(80)); | 
| 3176 |  | 
| 3177 |     QMetaObject::invokeMethod(obj: item, member: "increaseImplicit" ); | 
| 3178 |  | 
| 3179 |     QCOMPARE(item->implicitWidth(), qreal(200)); | 
| 3180 |     QCOMPARE(item->implicitHeight(), qreal(100)); | 
| 3181 |     QCOMPARE(item->width(), qreal(175)); | 
| 3182 |     QCOMPARE(item->height(), qreal(90)); | 
| 3183 |  | 
| 3184 |     QMetaObject::invokeMethod(obj: item, member: "changeImplicit" ); | 
| 3185 |  | 
| 3186 |     QCOMPARE(item->implicitWidth(), qreal(150)); | 
| 3187 |     QCOMPARE(item->implicitHeight(), qreal(80)); | 
| 3188 |     QCOMPARE(item->width(), qreal(150)); | 
| 3189 |     QCOMPARE(item->height(), qreal(80)); | 
| 3190 |  | 
| 3191 |     QMetaObject::invokeMethod(obj: item, member: "assignUndefinedBinding" ); | 
| 3192 |  | 
| 3193 |     QCOMPARE(item->implicitWidth(), qreal(150)); | 
| 3194 |     QCOMPARE(item->implicitHeight(), qreal(80)); | 
| 3195 |     QCOMPARE(item->width(), qreal(150)); | 
| 3196 |     QCOMPARE(item->height(), qreal(80)); | 
| 3197 |  | 
| 3198 |     QMetaObject::invokeMethod(obj: item, member: "increaseImplicit" ); | 
| 3199 |  | 
| 3200 |     QCOMPARE(item->implicitWidth(), qreal(200)); | 
| 3201 |     QCOMPARE(item->implicitHeight(), qreal(100)); | 
| 3202 |     QCOMPARE(item->width(), qreal(175)); | 
| 3203 |     QCOMPARE(item->height(), qreal(90)); | 
| 3204 |  | 
| 3205 |     QMetaObject::invokeMethod(obj: item, member: "changeImplicit" ); | 
| 3206 |  | 
| 3207 |     QCOMPARE(item->implicitWidth(), qreal(150)); | 
| 3208 |     QCOMPARE(item->implicitHeight(), qreal(80)); | 
| 3209 |     QCOMPARE(item->width(), qreal(150)); | 
| 3210 |     QCOMPARE(item->height(), qreal(80)); | 
| 3211 |  | 
| 3212 |     delete window; | 
| 3213 | } | 
| 3214 |  | 
| 3215 | void tst_QQuickItem::qtbug_16871() | 
| 3216 | { | 
| 3217 |     QQmlComponent component(&engine, testFileUrl(fileName: "qtbug_16871.qml" )); | 
| 3218 |     QObject *o = component.create(); | 
| 3219 |     QVERIFY(o != nullptr); | 
| 3220 |     delete o; | 
| 3221 | } | 
| 3222 |  | 
| 3223 |  | 
| 3224 | void tst_QQuickItem::visibleChildren() | 
| 3225 | { | 
| 3226 |     QQuickView *window = new QQuickView(nullptr); | 
| 3227 |     window->setSource(testFileUrl(fileName: "visiblechildren.qml" )); | 
| 3228 |     window->show(); | 
| 3229 |  | 
| 3230 |     QQuickItem *root = qobject_cast<QQuickItem*>(object: window->rootObject()); | 
| 3231 |     QVERIFY(root); | 
| 3232 |  | 
| 3233 |     QCOMPARE(root->property("test1_1" ).toBool(), true); | 
| 3234 |     QCOMPARE(root->property("test1_2" ).toBool(), true); | 
| 3235 |     QCOMPARE(root->property("test1_3" ).toBool(), true); | 
| 3236 |     QCOMPARE(root->property("test1_4" ).toBool(), true); | 
| 3237 |  | 
| 3238 |     QMetaObject::invokeMethod(obj: root, member: "hideFirstAndLastRowChild" ); | 
| 3239 |     QCOMPARE(root->property("test2_1" ).toBool(), true); | 
| 3240 |     QCOMPARE(root->property("test2_2" ).toBool(), true); | 
| 3241 |     QCOMPARE(root->property("test2_3" ).toBool(), true); | 
| 3242 |     QCOMPARE(root->property("test2_4" ).toBool(), true); | 
| 3243 |  | 
| 3244 |     QMetaObject::invokeMethod(obj: root, member: "showLastRowChildsLastChild" ); | 
| 3245 |     QCOMPARE(root->property("test3_1" ).toBool(), true); | 
| 3246 |     QCOMPARE(root->property("test3_2" ).toBool(), true); | 
| 3247 |     QCOMPARE(root->property("test3_3" ).toBool(), true); | 
| 3248 |     QCOMPARE(root->property("test3_4" ).toBool(), true); | 
| 3249 |  | 
| 3250 |     QMetaObject::invokeMethod(obj: root, member: "showLastRowChild" ); | 
| 3251 |     QCOMPARE(root->property("test4_1" ).toBool(), true); | 
| 3252 |     QCOMPARE(root->property("test4_2" ).toBool(), true); | 
| 3253 |     QCOMPARE(root->property("test4_3" ).toBool(), true); | 
| 3254 |     QCOMPARE(root->property("test4_4" ).toBool(), true); | 
| 3255 |  | 
| 3256 |     QString warning1 = testFileUrl(fileName: "visiblechildren.qml" ).toString() + ":87: TypeError: Cannot read property 'visibleChildren' of null" ; | 
| 3257 |     QTest::ignoreMessage(type: QtWarningMsg, qPrintable(warning1)); | 
| 3258 |     QMetaObject::invokeMethod(obj: root, member: "tryWriteToReadonlyVisibleChildren" ); | 
| 3259 |  | 
| 3260 |     QMetaObject::invokeMethod(obj: root, member: "reparentVisibleItem3" ); | 
| 3261 |     QCOMPARE(root->property("test6_1" ).toBool(), true); | 
| 3262 |     QCOMPARE(root->property("test6_2" ).toBool(), true); | 
| 3263 |     QCOMPARE(root->property("test6_3" ).toBool(), true); | 
| 3264 |     QCOMPARE(root->property("test6_4" ).toBool(), true); | 
| 3265 |  | 
| 3266 |     QMetaObject::invokeMethod(obj: root, member: "reparentImlicitlyInvisibleItem4_1" ); | 
| 3267 |     QCOMPARE(root->property("test7_1" ).toBool(), true); | 
| 3268 |     QCOMPARE(root->property("test7_2" ).toBool(), true); | 
| 3269 |     QCOMPARE(root->property("test7_3" ).toBool(), true); | 
| 3270 |     QCOMPARE(root->property("test7_4" ).toBool(), true); | 
| 3271 |  | 
| 3272 |     // FINALLY TEST THAT EVERYTHING IS AS EXPECTED | 
| 3273 |     QCOMPARE(root->property("test8_1" ).toBool(), true); | 
| 3274 |     QCOMPARE(root->property("test8_2" ).toBool(), true); | 
| 3275 |     QCOMPARE(root->property("test8_3" ).toBool(), true); | 
| 3276 |     QCOMPARE(root->property("test8_4" ).toBool(), true); | 
| 3277 |     QCOMPARE(root->property("test8_5" ).toBool(), true); | 
| 3278 |  | 
| 3279 |     delete window; | 
| 3280 | } | 
| 3281 |  | 
| 3282 | void tst_QQuickItem::parentLoop() | 
| 3283 | { | 
| 3284 |     QQuickView *window = new QQuickView(nullptr); | 
| 3285 |  | 
| 3286 | #if QT_CONFIG(regularexpression) | 
| 3287 |     QRegularExpression msgRegexp = QRegularExpression("QQuickItem::setParentItem: Parent QQuickItem\\(.*\\) is already part of the subtree of QQuickItem\\(.*\\)" ); | 
| 3288 |     QTest::ignoreMessage(type: QtWarningMsg, messagePattern: msgRegexp); | 
| 3289 | #endif | 
| 3290 |     window->setSource(testFileUrl(fileName: "parentLoop.qml" )); | 
| 3291 |  | 
| 3292 |     QQuickItem *root = qobject_cast<QQuickItem*>(object: window->rootObject()); | 
| 3293 |     QVERIFY(root); | 
| 3294 |  | 
| 3295 |     QQuickItem *item1 = root->findChild<QQuickItem*>(aName: "item1" ); | 
| 3296 |     QVERIFY(item1); | 
| 3297 |     QCOMPARE(item1->parentItem(), root); | 
| 3298 |  | 
| 3299 |     QQuickItem *item2 = root->findChild<QQuickItem*>(aName: "item2" ); | 
| 3300 |     QVERIFY(item2); | 
| 3301 |     QCOMPARE(item2->parentItem(), item1); | 
| 3302 |  | 
| 3303 |     delete window; | 
| 3304 | } | 
| 3305 |  | 
| 3306 | void tst_QQuickItem::contains_data() | 
| 3307 | { | 
| 3308 |     QTest::addColumn<bool>(name: "circleTest" ); | 
| 3309 |     QTest::addColumn<bool>(name: "insideTarget" ); | 
| 3310 |     QTest::addColumn<QList<QPoint> >(name: "points" ); | 
| 3311 |  | 
| 3312 |     QList<QPoint> points; | 
| 3313 |  | 
| 3314 |     points << QPoint(176, 176) | 
| 3315 |            << QPoint(176, 226) | 
| 3316 |            << QPoint(226, 176) | 
| 3317 |            << QPoint(226, 226) | 
| 3318 |            << QPoint(150, 200) | 
| 3319 |            << QPoint(200, 150) | 
| 3320 |            << QPoint(200, 250) | 
| 3321 |            << QPoint(250, 200); | 
| 3322 |     QTest::newRow(dataTag: "hollow square: testing points inside" ) << false << true << points; | 
| 3323 |  | 
| 3324 |     points.clear(); | 
| 3325 |     points << QPoint(162, 162) | 
| 3326 |            << QPoint(162, 242) | 
| 3327 |            << QPoint(242, 162) | 
| 3328 |            << QPoint(242, 242) | 
| 3329 |            << QPoint(200, 200) | 
| 3330 |            << QPoint(175, 200) | 
| 3331 |            << QPoint(200, 175) | 
| 3332 |            << QPoint(200, 228) | 
| 3333 |            << QPoint(228, 200) | 
| 3334 |            << QPoint(200, 122) | 
| 3335 |            << QPoint(122, 200) | 
| 3336 |            << QPoint(200, 280) | 
| 3337 |            << QPoint(280, 200); | 
| 3338 |     QTest::newRow(dataTag: "hollow square: testing points outside" ) << false << false << points; | 
| 3339 |  | 
| 3340 |     points.clear(); | 
| 3341 |     points << QPoint(174, 174) | 
| 3342 |            << QPoint(174, 225) | 
| 3343 |            << QPoint(225, 174) | 
| 3344 |            << QPoint(225, 225) | 
| 3345 |            << QPoint(165, 200) | 
| 3346 |            << QPoint(200, 165) | 
| 3347 |            << QPoint(200, 235) | 
| 3348 |            << QPoint(235, 200); | 
| 3349 |     QTest::newRow(dataTag: "hollow circle: testing points inside" ) << true << true << points; | 
| 3350 |  | 
| 3351 |     points.clear(); | 
| 3352 |     points << QPoint(160, 160) | 
| 3353 |            << QPoint(160, 240) | 
| 3354 |            << QPoint(240, 160) | 
| 3355 |            << QPoint(240, 240) | 
| 3356 |            << QPoint(200, 200) | 
| 3357 |            << QPoint(185, 185) | 
| 3358 |            << QPoint(185, 216) | 
| 3359 |            << QPoint(216, 185) | 
| 3360 |            << QPoint(216, 216) | 
| 3361 |            << QPoint(145, 200) | 
| 3362 |            << QPoint(200, 145) | 
| 3363 |            << QPoint(255, 200) | 
| 3364 |            << QPoint(200, 255); | 
| 3365 |     QTest::newRow(dataTag: "hollow circle: testing points outside" ) << true << false << points; | 
| 3366 | } | 
| 3367 |  | 
| 3368 | void tst_QQuickItem::contains() | 
| 3369 | { | 
| 3370 |     QFETCH(bool, circleTest); | 
| 3371 |     QFETCH(bool, insideTarget); | 
| 3372 |     QFETCH(QList<QPoint>, points); | 
| 3373 |  | 
| 3374 |     QQuickView *window = new QQuickView(nullptr); | 
| 3375 |     window->rootContext()->setContextProperty("circleShapeTest" , circleTest); | 
| 3376 |     window->setBaseSize(QSize(400, 400)); | 
| 3377 |     window->setSource(testFileUrl(fileName: "hollowTestItem.qml" )); | 
| 3378 |     window->show(); | 
| 3379 |     window->requestActivate(); | 
| 3380 |     QVERIFY(QTest::qWaitForWindowActive(window)); | 
| 3381 |     QCOMPARE(QGuiApplication::focusWindow(), window); | 
| 3382 |  | 
| 3383 |     QQuickItem *root = qobject_cast<QQuickItem *>(object: window->rootObject()); | 
| 3384 |     QVERIFY(root); | 
| 3385 |  | 
| 3386 |     HollowTestItem *hollowItem = root->findChild<HollowTestItem *>(aName: "hollowItem" ); | 
| 3387 |     QVERIFY(hollowItem); | 
| 3388 |  | 
| 3389 |     foreach (const QPoint &point, points) { | 
| 3390 |         // check mouse hover | 
| 3391 |         QTest::mouseMove(window, pos: point); | 
| 3392 |         QTest::qWait(ms: 10); | 
| 3393 |         QCOMPARE(hollowItem->isHovered(), insideTarget); | 
| 3394 |  | 
| 3395 |         // check mouse press | 
| 3396 |         QTest::mousePress(window, button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: point); | 
| 3397 |         QTest::qWait(ms: 10); | 
| 3398 |         QCOMPARE(hollowItem->isPressed(), insideTarget); | 
| 3399 |  | 
| 3400 |         // check mouse release | 
| 3401 |         QTest::mouseRelease(window, button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: point); | 
| 3402 |         QTest::qWait(ms: 10); | 
| 3403 |         QCOMPARE(hollowItem->isPressed(), false); | 
| 3404 |     } | 
| 3405 |  | 
| 3406 |     delete window; | 
| 3407 | } | 
| 3408 |  | 
| 3409 | void tst_QQuickItem::childAt() | 
| 3410 | { | 
| 3411 |     QQuickItem parent; | 
| 3412 |  | 
| 3413 |     QQuickItem child1; | 
| 3414 |     child1.setX(0); | 
| 3415 |     child1.setY(0); | 
| 3416 |     child1.setWidth(100); | 
| 3417 |     child1.setHeight(100); | 
| 3418 |     child1.setParentItem(&parent); | 
| 3419 |  | 
| 3420 |     QQuickItem child2; | 
| 3421 |     child2.setX(50); | 
| 3422 |     child2.setY(50); | 
| 3423 |     child2.setWidth(100); | 
| 3424 |     child2.setHeight(100); | 
| 3425 |     child2.setParentItem(&parent); | 
| 3426 |  | 
| 3427 |     QQuickItem child3; | 
| 3428 |     child3.setX(0); | 
| 3429 |     child3.setY(200); | 
| 3430 |     child3.setWidth(50); | 
| 3431 |     child3.setHeight(50); | 
| 3432 |     child3.setParentItem(&parent); | 
| 3433 |  | 
| 3434 |     QCOMPARE(parent.childAt(0, 0), &child1); | 
| 3435 |     QCOMPARE(parent.childAt(0, 99), &child1); | 
| 3436 |     QCOMPARE(parent.childAt(25, 25), &child1); | 
| 3437 |     QCOMPARE(parent.childAt(25, 75), &child1); | 
| 3438 |     QCOMPARE(parent.childAt(75, 25), &child1); | 
| 3439 |     QCOMPARE(parent.childAt(75, 75), &child2); | 
| 3440 |     QCOMPARE(parent.childAt(149, 149), &child2); | 
| 3441 |     QCOMPARE(parent.childAt(25, 200), &child3); | 
| 3442 |     QCOMPARE(parent.childAt(0, 150), static_cast<QQuickItem *>(nullptr)); | 
| 3443 |     QCOMPARE(parent.childAt(300, 300), static_cast<QQuickItem *>(nullptr)); | 
| 3444 | } | 
| 3445 |  | 
| 3446 | void tst_QQuickItem::grab() | 
| 3447 | { | 
| 3448 |     if ((QGuiApplication::platformName() == QLatin1String("offscreen" )) | 
| 3449 |         || (QGuiApplication::platformName() == QLatin1String("minimal" ))) | 
| 3450 |         QSKIP("Skipping due to grabToImage not functional on offscreen/minimal platforms" ); | 
| 3451 |  | 
| 3452 |     QQuickView view; | 
| 3453 |     view.setSource(testFileUrl(fileName: "grabToImage.qml" )); | 
| 3454 |     view.show(); | 
| 3455 |     QVERIFY(QTest::qWaitForWindowExposed(&view)); | 
| 3456 |  | 
| 3457 |     QQuickItem *root = qobject_cast<QQuickItem *>(object: view.rootObject()); | 
| 3458 |     QVERIFY(root); | 
| 3459 |     QQuickItem *item = root->findChild<QQuickItem *>(aName: "myItem" ); | 
| 3460 |     QVERIFY(item); | 
| 3461 | #if QT_CONFIG(opengl) | 
| 3462 |     { // Default size (item is 100x100) | 
| 3463 |         QSharedPointer<QQuickItemGrabResult> result = item->grabToImage(); | 
| 3464 |         QSignalSpy spy(result.data(), SIGNAL(ready())); | 
| 3465 |         QTRY_VERIFY(spy.size() > 0); | 
| 3466 |         QVERIFY(!result->url().isEmpty()); | 
| 3467 |         QImage image = result->image(); | 
| 3468 |         QCOMPARE(image.pixel(0, 0), qRgb(255, 0, 0)); | 
| 3469 |         QCOMPARE(image.pixel(99, 99), qRgb(0, 0, 255)); | 
| 3470 |     } | 
| 3471 |  | 
| 3472 |     { // Smaller size | 
| 3473 |         QSharedPointer<QQuickItemGrabResult> result = item->grabToImage(targetSize: QSize(50, 50)); | 
| 3474 |         QVERIFY(!result.isNull()); | 
| 3475 |         QSignalSpy spy(result.data(), SIGNAL(ready())); | 
| 3476 |         QTRY_VERIFY(spy.size() > 0); | 
| 3477 |         QVERIFY(!result->url().isEmpty()); | 
| 3478 |         QImage image = result->image(); | 
| 3479 |         QCOMPARE(image.pixel(0, 0), qRgb(255, 0, 0)); | 
| 3480 |         QCOMPARE(image.pixel(49, 49), qRgb(0, 0, 255)); | 
| 3481 |     } | 
| 3482 | #endif | 
| 3483 | } | 
| 3484 |  | 
| 3485 | void tst_QQuickItem::isAncestorOf() | 
| 3486 | { | 
| 3487 |     QQuickItem parent; | 
| 3488 |  | 
| 3489 |     QQuickItem sub1; | 
| 3490 |     sub1.setParentItem(&parent); | 
| 3491 |  | 
| 3492 |     QQuickItem child1; | 
| 3493 |     child1.setParentItem(&sub1); | 
| 3494 |     QQuickItem child2; | 
| 3495 |     child2.setParentItem(&sub1); | 
| 3496 |  | 
| 3497 |     QQuickItem sub2; | 
| 3498 |     sub2.setParentItem(&parent); | 
| 3499 |  | 
| 3500 |     QQuickItem child3; | 
| 3501 |     child3.setParentItem(&sub2); | 
| 3502 |     QQuickItem child4; | 
| 3503 |     child4.setParentItem(&sub2); | 
| 3504 |  | 
| 3505 |     QVERIFY(parent.isAncestorOf(&sub1)); | 
| 3506 |     QVERIFY(parent.isAncestorOf(&sub2)); | 
| 3507 |     QVERIFY(parent.isAncestorOf(&child1)); | 
| 3508 |     QVERIFY(parent.isAncestorOf(&child2)); | 
| 3509 |     QVERIFY(parent.isAncestorOf(&child3)); | 
| 3510 |     QVERIFY(parent.isAncestorOf(&child4)); | 
| 3511 |     QVERIFY(sub1.isAncestorOf(&child1)); | 
| 3512 |     QVERIFY(sub1.isAncestorOf(&child2)); | 
| 3513 |     QVERIFY(!sub1.isAncestorOf(&child3)); | 
| 3514 |     QVERIFY(!sub1.isAncestorOf(&child4)); | 
| 3515 |     QVERIFY(sub2.isAncestorOf(&child3)); | 
| 3516 |     QVERIFY(sub2.isAncestorOf(&child4)); | 
| 3517 |     QVERIFY(!sub2.isAncestorOf(&child1)); | 
| 3518 |     QVERIFY(!sub2.isAncestorOf(&child2)); | 
| 3519 |     QVERIFY(!sub1.isAncestorOf(&sub1)); | 
| 3520 |     QVERIFY(!sub2.isAncestorOf(&sub2)); | 
| 3521 | } | 
| 3522 |  | 
| 3523 | QTEST_MAIN(tst_QQuickItem) | 
| 3524 |  | 
| 3525 | #include "tst_qquickitem.moc" | 
| 3526 |  |