6#include <QtCore/QRandomGenerator>
7#include <QtCore/QTimer>
8#include <QtQuick/QQuickView>
9#include <QtQuick/QQuickView>
10#include <QtGui/QScreen>
11#include <QtGui/qpa/qwindowsysteminterface.h>
12#include <QtGui/private/qhighdpiscaling_p.h>
14#include <QtTest/QTest>
16#include <QtQuick/private/qquickdeliveryagent_p_p.h>
17#if QT_CONFIG(quick_itemview)
18#include <QtQuick/private/qquickitemview_p_p.h>
20#include <QtQuick/private/qquickwindow_p.h>
22#include <QtQuickTestUtils/private/visualtestutils_p.h>
26QQuickView *QQuickViewTestUtils::createView()
28 QQuickView *window =
new QQuickView(0);
29 const QSize size(240, 320);
31 QQuickViewTestUtils::centerOnScreen(window, size);
35void QQuickViewTestUtils::centerOnScreen(QQuickWindow *window,
const QSize &size)
37 const QRect screenGeometry = window->screen()->availableGeometry();
38 const QPoint offset = QPoint(size.width() / 2, size.height() / 2);
39 window->setFramePosition(screenGeometry.center() - offset);
42void QQuickViewTestUtils::centerOnScreen(QQuickWindow *window)
44 QQuickViewTestUtils::centerOnScreen(window, window->size());
47void QQuickViewTestUtils::moveMouseAway(QQuickView *window)
50 QCursor::setPos(window->geometry().topRight() + QPoint(100, 100));
56QList<
int> QQuickViewTestUtils::adjustIndexesForAddDisplaced(
const QList<
int> &indexes,
int index,
int count)
59 for (
int i=0; i<indexes.size(); i++) {
69QList<
int> QQuickViewTestUtils::adjustIndexesForMove(
const QList<
int> &indexes,
int from,
int to,
int count)
72 for (
int i=0; i<indexes.size(); i++) {
75 if (num >= from && num < from + count)
77 else if (num >= from && num < to + count)
79 }
else if (from > to) {
80 if (num >= from && num < from + count)
82 else if (num >= to && num < from + count)
90QList<
int> QQuickViewTestUtils::adjustIndexesForRemoveDisplaced(
const QList<
int> &indexes,
int index,
int count)
93 for (
int i=0; i<indexes.size(); i++) {
102QQuickViewTestUtils::QaimModel::QaimModel(QObject *parent)
103 : QAbstractListModel(parent)
107int QQuickViewTestUtils::QaimModel::rowCount(
const QModelIndex &parent)
const
113int QQuickViewTestUtils::QaimModel::columnCount(
const QModelIndex &parent)
const
119QHash<
int,QByteArray> QQuickViewTestUtils::QaimModel::roleNames()
const
121 QHash<
int,QByteArray> roles = QAbstractListModel::roleNames();
122 roles.insert(Name,
"name");
123 roles.insert(Number,
"number");
127QVariant QQuickViewTestUtils::QaimModel::data(
const QModelIndex &index,
int role)
const
131 rv = list.at(index.row()).first;
132 else if (role == Number)
133 rv = list.at(index.row()).second;
138int QQuickViewTestUtils::QaimModel::count()
const
140 return rowCount() * columnCount();
143QString QQuickViewTestUtils::QaimModel::name(
int index)
const
145 return list.at(index).first;
148QString QQuickViewTestUtils::QaimModel::number(
int index)
const
150 return list.at(index).second;
153void QQuickViewTestUtils::QaimModel::addItem(
const QString &name,
const QString &number)
155 emit beginInsertRows(QModelIndex(), list.size(), list.size());
156 list.append(std::pair<QString,QString>(name, number));
157 emit endInsertRows();
160void QQuickViewTestUtils::QaimModel::addItems(
const QList<std::pair<QString, QString> > &items)
162 emit beginInsertRows(QModelIndex(), list.size(), list.size()+items.size()-1);
163 for (
int i=0; i<items.size(); i++)
164 list.append(std::pair<QString,QString>(items[i].first, items[i].second));
165 emit endInsertRows();
168void QQuickViewTestUtils::QaimModel::insertItem(
int index,
const QString &name,
const QString &number)
170 emit beginInsertRows(QModelIndex(), index, index);
171 list.insert(index, std::pair<QString,QString>(name, number));
172 emit endInsertRows();
175void QQuickViewTestUtils::QaimModel::insertItems(
int index,
const QList<std::pair<QString, QString> > &items)
177 emit beginInsertRows(QModelIndex(), index, index+items.size()-1);
178 for (
int i=0; i<items.size(); i++)
179 list.insert(index + i, std::pair<QString,QString>(items[i].first, items[i].second));
180 emit endInsertRows();
183void QQuickViewTestUtils::QaimModel::removeItem(
int index)
185 emit beginRemoveRows(QModelIndex(), index, index);
186 list.removeAt(index);
187 emit endRemoveRows();
190void QQuickViewTestUtils::QaimModel::removeItems(
int index,
int count)
192 emit beginRemoveRows(QModelIndex(), index, index+count-1);
194 list.removeAt(index);
195 emit endRemoveRows();
198void QQuickViewTestUtils::QaimModel::moveItem(
int from,
int to)
200 emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
205void QQuickViewTestUtils::QaimModel::moveItems(
int from,
int to,
int count)
207 emit beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to > from ? to+count : to);
208 qquickmodelviewstestutil_move(from, to, count, &list);
212void QQuickViewTestUtils::QaimModel::modifyItem(
int idx,
const QString &name,
const QString &number)
214 list[idx] = std::pair<QString,QString>(name, number);
215 emit dataChanged(index(idx,0), index(idx,0));
218void QQuickViewTestUtils::QaimModel::clear()
220 int count = list.size();
222 beginRemoveRows(QModelIndex(), 0, count-1);
228void QQuickViewTestUtils::QaimModel::reset()
230 emit beginResetModel();
231 emit endResetModel();
234void QQuickViewTestUtils::QaimModel::resetItems(
const QList<std::pair<QString, QString> > &items)
243 Q_DISABLE_COPY_MOVE(ScopedPrintable)
246 ScopedPrintable(
const QString &string) : data(QTest::toString(string)) {}
247 ~ScopedPrintable() {
delete[] data; }
249 operator
const char*()
const {
return data; }
256 for (
int i=0; i<other.size(); i++) {
257 QVERIFY2(list.contains(other[i]),
258 ScopedPrintable(other[i].first + QLatin1Char(
' ') + other[i].second + QLatin1Char(
' ') + error1));
260 for (
int i=0; i<list.size(); i++) {
261 QVERIFY2(other.contains(list[i]),
262 ScopedPrintable(list[i].first + QLatin1Char(
' ') + list[i].second + QLatin1Char(
' ') + error2));
276 indexes = other.indexes;
282 for (
int i=start; i<=end; i++)
295 a.indexes.append(other.indexes);
301 return QSet<
int>(indexes.cbegin(), indexes.cend())
302 == QSet<
int>(other.indexes.cbegin(), other.indexes.cend());
307 return !(*
this == other);
317 return indexes.size();
320QList<std::pair<QString,QString> > QQuickViewTestUtils::ListRange::getModelDataValues(
const QaimModel &model)
322 QList<std::pair<QString,QString> > data;
325 for (
int i=0; i<indexes.size(); i++)
326 data.append(std::make_pair(model.name(indexes[i]), model.number(indexes[i])));
331 : QAbstractListModel()
334 QTimer *t =
new QTimer(
this);
338 connect(t, &QTimer::timeout,
this, &StressTestModel::updateModel);
353 if (m_rowCount > 10) {
354 for (
int i = 0; i < 10; ++i) {
355 int rnum = QRandomGenerator::global()->bounded(m_rowCount);
356 beginRemoveRows(QModelIndex(), rnum, rnum);
361 if (m_rowCount < 20) {
362 for (
int i = 0; i < 10; ++i) {
363 int rnum = QRandomGenerator::global()->bounded(m_rowCount);
364 beginInsertRows(QModelIndex(), rnum, rnum);
371#if QT_CONFIG(quick_itemview) && defined(QT_BUILD_INTERNAL)
372bool QQuickViewTestUtils::testVisibleItems(
const QQuickItemViewPrivate *priv,
bool *nonUnique, FxViewItem **failItem,
int *expectedIdx)
374 QHash<QQuickItem*,
int> uniqueItems;
377 for (
int i = 0; i < priv->visibleItems.size(); ++i) {
378 FxViewItem *item = priv->visibleItems.at(i);
384 qDebug() <<
"\t" << item->index
387 << (!item->item || QQuickItemPrivate::get(item->item)->culled ?
"hidden" :
"visible");
389 if (item->index == -1) {
391 }
else if (item->index != priv->visibleIndex + i - skip) {
394 *expectedIdx = priv->visibleIndex + i - skip;
396 }
else if (uniqueItems.contains(item->item)) {
399 *expectedIdx = uniqueItems.find(item->item).value();
403 uniqueItems.insert(item->item, item->index);
413
414
415
416
417
421 QQuickDeliveryAgentPrivate *da = QQuickWindowPrivate::get(window)->deliveryAgentPrivate();
422 if (!da || !da->delayedTouch)
424 da->deliverDelayedTouchEvent();
436
437
438
439
440
441
442
476
477
478
479
480
481
482
483
484
485
496 qCritical() <<
"qWaitForWindowExposed() failed";
500 qCritical() <<
"View has no root object";
510 qCritical() <<
"Position failed to update";
521 void pointerPress(
const QPointingDevice *dev, QQuickWindow *window,
int pointId,
const QPoint &p,
522 Qt::MouseButton button, Qt::KeyboardModifiers modifiers,
int delay)
524 const auto defaultDelay = QTest::defaultMouseDelay();
525 switch (dev->type()) {
526 case QPointingDevice::DeviceType::Mouse:
527 case QPointingDevice::DeviceType::TouchPad:
528 QTest::mousePress(window, button, modifiers, p, delay >= 0 ? delay : defaultDelay ? defaultDelay : 1);
530 case QPointingDevice::DeviceType::TouchScreen:
532 QTest::touchEvent(window,
const_cast<QPointingDevice *>(dev)).press(pointId, p, window);
535 case QPointingDevice::DeviceType::Puck:
536 case QPointingDevice::DeviceType::Stylus:
537 case QPointingDevice::DeviceType::Airbrush:{
538 const QPointF nativeLocal = QHighDpi::toNativeLocalPosition(p, window);
539 const QPointF nativeGlobal = QHighDpi::toNativeGlobalPosition(window->mapToGlobal(p), window);
540 QTest::lastMouseTimestamp += delay >= 0 ? delay : defaultDelay ? defaultDelay : 1;
543 QWindowSystemInterface::handleTabletEvent(window, QTest::lastMouseTimestamp, dev, nativeLocal, nativeGlobal,
544 button, 0.8, 0, 0, 0, 0, 0, modifiers);
548 qWarning() <<
"can't send a press event from" << dev;
553 void pointerMove(
const QPointingDevice *dev, QQuickWindow *window,
int pointId,
const QPoint &p,
int delay)
555 const auto defaultDelay = QTest::defaultMouseDelay();
556 switch (dev->type()) {
557 case QPointingDevice::DeviceType::Mouse:
558 case QPointingDevice::DeviceType::TouchPad:
559 QTest::mouseMove(window, p, delay >= 0 ? delay : defaultDelay ? defaultDelay : 1);
561 case QPointingDevice::DeviceType::TouchScreen:
563 QTest::touchEvent(window,
const_cast<QPointingDevice *>(dev)).move(pointId, p, window);
566 case QPointingDevice::DeviceType::Puck:
567 case QPointingDevice::DeviceType::Stylus:
568 case QPointingDevice::DeviceType::Airbrush: {
569 const QPointF nativeLocal = QHighDpi::toNativeLocalPosition(p, window);
570 const QPointF nativeGlobal = QHighDpi::toNativeGlobalPosition(window->mapToGlobal(p), window);
571 const auto delay = QTest::defaultMouseDelay();
573 QTest::lastMouseTimestamp += delay >= 0 ? delay : defaultDelay ? defaultDelay : 1;
574 QWindowSystemInterface::handleTabletEvent(window, QTest::lastMouseTimestamp, dev, nativeLocal, nativeGlobal,
575 pressedTabletButton, pressedTabletButton == Qt::NoButton ? 0 : 0.75,
576 0, 0, 0, 0, 0, pressedTabletModifiers);
580 qWarning() <<
"can't send a move event from" << dev;
585 void pointerRelease(
const QPointingDevice *dev, QQuickWindow *window,
int pointId,
const QPoint &p,
586 Qt::MouseButton button, Qt::KeyboardModifiers modifiers,
int delay)
588 const auto defaultDelay = QTest::defaultMouseDelay();
589 switch (dev->type()) {
590 case QPointingDevice::DeviceType::Mouse:
591 case QPointingDevice::DeviceType::TouchPad:
592 QTest::mouseRelease(window, button, modifiers, p, delay >= 0 ? delay : defaultDelay ? defaultDelay : 1);
594 case QPointingDevice::DeviceType::TouchScreen:
596 QTest::touchEvent(window,
const_cast<QPointingDevice *>(dev)).release(pointId, p, window);
599 case QPointingDevice::DeviceType::Puck:
600 case QPointingDevice::DeviceType::Stylus:
601 case QPointingDevice::DeviceType::Airbrush: {
602 const QPointF nativeLocal = QHighDpi::toNativeLocalPosition(p, window);
603 const QPointF nativeGlobal = QHighDpi::toNativeGlobalPosition(window->mapToGlobal(p), window);
604 QTest::lastMouseTimestamp += delay >= 0 ? delay : defaultDelay ? defaultDelay : 1;
605 QWindowSystemInterface::handleTabletEvent(window, QTest::lastMouseTimestamp, dev, nativeLocal, nativeGlobal,
606 Qt::NoButton, 0, 0, 0, 0, 0, 0, modifiers);
610 qWarning() <<
"can't send a press event from" << dev;
616 int pointId,
const QPoint &p, Qt::MouseButton button,
617 Qt::KeyboardModifiers modifiers,
int delay)
619 pointerMove(dev, window, pointId, p, delay);
620 pointerPress(dev, window, pointId, p, button, modifiers);
624 int pointId,
const QPoint &p, Qt::MouseButton button,
625 Qt::KeyboardModifiers modifiers,
int delay)
627 pointerMove(dev, window, pointId, p, delay);
628 pointerRelease(dev, window, pointId, p, button, modifiers);
632 int pointId,
const QPoint &from,
const QPoint &to,
int duration,
633 Qt::MouseButton button, Qt::KeyboardModifiers modifiers,
int delay)
635 const int pointCount = 5;
636 const QPoint diff = to - from;
639 pointerMoveAndPress(dev, window, pointId, from, button, modifiers, delay);
641 for (
int i = 0; i < pointCount; ++i)
642 pointerMove(dev, window, pointId, from + (i + 1) * diff / pointCount, duration / pointCount);
644 pointerMoveAndRelease(dev, window, pointId, to, button, modifiers);
650#include "moc_viewtestutils_p.cpp"
bool operator==(const ListRange &other) const
ListRange(const ListRange &other)
bool operator!=(const ListRange &other) const
ListRange operator+(const ListRange &other) const
ListRange(int start, int end)
void matchAgainst(const QList< std::pair< QString, QString > > &other, const QString &error1, const QString &error2)
QVariant data(const QModelIndex &, int) const override
Returns the data stored under the given role for the item referred to by the index.
int rowCount(const QModelIndex &) const override
Returns the number of rows under the given parent.
void pointerPress(const QPointingDevice *dev, QQuickWindow *window, int pointId, const QPoint &p, Qt::MouseButton button, Qt::KeyboardModifiers modifiers, int delay)
void pointerRelease(const QPointingDevice *dev, QQuickWindow *window, int pointId, const QPoint &p, Qt::MouseButton button, Qt::KeyboardModifiers modifiers, int delay)
void pointerMoveAndPress(const QPointingDevice *dev, QQuickWindow *window, int pointId, const QPoint &p, Qt::MouseButton button, Qt::KeyboardModifiers modifiers, int delay)
void pointerFlick(const QPointingDevice *dev, QQuickWindow *window, int pointId, const QPoint &from, const QPoint &to, int duration, Qt::MouseButton button, Qt::KeyboardModifiers modifiers, int delay)
bool initView(QQuickView &view, const QUrl &url, bool moveMouseOut, QByteArray *errorMessage)
void pointerMoveAndRelease(const QPointingDevice *dev, QQuickWindow *window, int pointId, const QPoint &p, Qt::MouseButton button, Qt::KeyboardModifiers modifiers, int delay)
void pointerMove(const QPointingDevice *dev, QQuickWindow *window, int pointId, const QPoint &p, int delay)
bool showView(QQuickView &view, const QUrl &url)
static Qt::KeyboardModifiers pressedTabletModifiers
static Qt::MouseButton pressedTabletButton
void flush(QQuickWindow *window)