mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-03 15:55:27 +08:00
qt 6.5.1 original
This commit is contained in:
20
tests/auto/widgets/itemviews/CMakeLists.txt
Normal file
20
tests/auto/widgets/itemviews/CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
add_subdirectory(qabstractitemview)
|
||||
add_subdirectory(qdatawidgetmapper)
|
||||
add_subdirectory(qfileiconprovider)
|
||||
add_subdirectory(qheaderview)
|
||||
add_subdirectory(qitemdelegate)
|
||||
add_subdirectory(qitemeditorfactory)
|
||||
add_subdirectory(qitemview)
|
||||
add_subdirectory(qlistview)
|
||||
add_subdirectory(qtableview)
|
||||
add_subdirectory(qtablewidget)
|
||||
add_subdirectory(qtreeview)
|
||||
add_subdirectory(qtreewidget)
|
||||
add_subdirectory(qtreewidgetitemiterator)
|
||||
if(QT_FEATURE_private_tests)
|
||||
add_subdirectory(qcolumnview)
|
||||
add_subdirectory(qlistwidget)
|
||||
endif()
|
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qabstractitemview Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qabstractitemview
|
||||
SOURCES
|
||||
tst_qabstractitemview.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::TestPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
BIN
tests/auto/widgets/itemviews/qabstractitemview/qtlogo.png
Normal file
BIN
tests/auto/widgets/itemviews/qabstractitemview/qtlogo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
File diff suppressed because it is too large
Load Diff
3
tests/auto/widgets/itemviews/qcolumnview/BLACKLIST
Normal file
3
tests/auto/widgets/itemviews/qcolumnview/BLACKLIST
Normal file
@ -0,0 +1,3 @@
|
||||
# QTBUG-41341
|
||||
[scrollTo]
|
||||
macos
|
19
tests/auto/widgets/itemviews/qcolumnview/CMakeLists.txt
Normal file
19
tests/auto/widgets/itemviews/qcolumnview/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qcolumnview Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qcolumnview
|
||||
SOURCES
|
||||
../../../../shared/fakedirmodel.h
|
||||
tst_qcolumnview.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::TestPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
966
tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp
Normal file
966
tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp
Normal file
@ -0,0 +1,966 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QColumnView>
|
||||
#include <QScrollBar>
|
||||
#include <QSignalSpy>
|
||||
#include <QStringListModel>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QTest>
|
||||
#include <QtTest/private/qtesthelpers_p.h>
|
||||
#include <QtWidgets/private/qcolumnviewgrip_p.h>
|
||||
#include "../../../../shared/fakedirmodel.h"
|
||||
|
||||
#define ANIMATION_DELAY 300
|
||||
|
||||
class tst_QColumnView : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
tst_QColumnView();
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void init();
|
||||
void rootIndex();
|
||||
void grips();
|
||||
void isIndexHidden();
|
||||
void indexAt();
|
||||
void scrollContentsBy_data();
|
||||
void scrollContentsBy();
|
||||
void scrollTo_data();
|
||||
void scrollTo();
|
||||
void moveCursor_data();
|
||||
void moveCursor();
|
||||
void selectAll();
|
||||
void clicked();
|
||||
void selectedColumns();
|
||||
void setSelection();
|
||||
void setSelectionModel();
|
||||
void visualRegionForSelection();
|
||||
|
||||
void dynamicModelChanges();
|
||||
|
||||
// grip
|
||||
void moveGrip_basic();
|
||||
void moveGrip_data();
|
||||
void moveGrip();
|
||||
void doubleClick();
|
||||
void gripMoved();
|
||||
|
||||
void preview();
|
||||
void swapPreview();
|
||||
void sizes();
|
||||
void rowDelegate();
|
||||
void resize();
|
||||
void changeSameColumn();
|
||||
void parentCurrentIndex_data();
|
||||
void parentCurrentIndex();
|
||||
void pullRug_data();
|
||||
void pullRug();
|
||||
|
||||
protected slots:
|
||||
void setPreviewWidget();
|
||||
|
||||
private:
|
||||
QStandardItemModel m_fakeDirModel;
|
||||
QModelIndex m_fakeDirHomeIndex;
|
||||
};
|
||||
|
||||
class TreeModel : public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TreeModel()
|
||||
{
|
||||
for (int j = 0; j < 10; ++j) {
|
||||
QStandardItem *parentItem = invisibleRootItem();
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
const QString iS = QString::number(i);
|
||||
const QString itemText = QLatin1String("item ") + iS;
|
||||
QStandardItem *item = new QStandardItem(itemText);
|
||||
parentItem->appendRow(item);
|
||||
QStandardItem *item2 = new QStandardItem(itemText);
|
||||
parentItem->appendRow(item2);
|
||||
item2->appendRow(new QStandardItem(itemText));
|
||||
parentItem->appendRow(new QStandardItem(QLatin1String("file ") + iS));
|
||||
parentItem = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline QModelIndex firstLevel() { return index(0, 0, QModelIndex()); }
|
||||
inline QModelIndex secondLevel() { return index(0, 0, firstLevel()); }
|
||||
inline QModelIndex thirdLevel() { return index(0, 0, secondLevel()); }
|
||||
};
|
||||
|
||||
class ColumnView : public QColumnView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QColumnView::QColumnView;
|
||||
using QColumnView::horizontalOffset;
|
||||
using QColumnView::clicked;
|
||||
using QColumnView::isIndexHidden;
|
||||
using QColumnView::moveCursor;
|
||||
using QColumnView::scrollContentsBy;
|
||||
using QColumnView::setSelection;
|
||||
using QColumnView::visualRegionForSelection;
|
||||
|
||||
friend class tst_QColumnView;
|
||||
|
||||
QList<QPointer<QAbstractItemView>> createdColumns;
|
||||
|
||||
protected:
|
||||
QAbstractItemView *createColumn(const QModelIndex &index) override
|
||||
{
|
||||
QAbstractItemView *view = QColumnView::createColumn(index);
|
||||
QPointer<QAbstractItemView> savedView = view;
|
||||
createdColumns.append(savedView);
|
||||
return view;
|
||||
}
|
||||
};
|
||||
|
||||
tst_QColumnView::tst_QColumnView()
|
||||
{
|
||||
QStandardItem *homeItem = populateFakeDirModel(&m_fakeDirModel);
|
||||
m_fakeDirHomeIndex = m_fakeDirModel.indexFromItem(homeItem);
|
||||
}
|
||||
|
||||
void tst_QColumnView::initTestCase()
|
||||
{
|
||||
QVERIFY(m_fakeDirHomeIndex.isValid());
|
||||
QVERIFY(m_fakeDirModel.rowCount(m_fakeDirHomeIndex) > 1); // Needs some entries in 'home'.
|
||||
}
|
||||
|
||||
void tst_QColumnView::init()
|
||||
{
|
||||
QGuiApplication::setLayoutDirection(Qt::LeftToRight);
|
||||
}
|
||||
|
||||
void tst_QColumnView::rootIndex()
|
||||
{
|
||||
ColumnView view;
|
||||
// no model
|
||||
view.setRootIndex(QModelIndex());
|
||||
|
||||
TreeModel model;
|
||||
view.setModel(&model);
|
||||
|
||||
// A top level index
|
||||
QModelIndex drive = model.firstLevel();
|
||||
QVERIFY(view.visualRect(drive).isValid());
|
||||
view.setRootIndex(QModelIndex());
|
||||
QCOMPARE(view.horizontalOffset(), 0);
|
||||
QCOMPARE(view.rootIndex(), QModelIndex());
|
||||
QVERIFY(view.visualRect(drive).isValid());
|
||||
|
||||
// A item under the rootIndex exists
|
||||
QModelIndex home = model.thirdLevel();
|
||||
QModelIndex homeFile = model.index(0, 0, home);
|
||||
int i = 0;
|
||||
while (i < model.rowCount(home) - 1 && !model.hasChildren(homeFile))
|
||||
homeFile = model.index(++i, 0, home);
|
||||
view.setRootIndex(home);
|
||||
QCOMPARE(view.horizontalOffset(), 0);
|
||||
QCOMPARE(view.rootIndex(), home);
|
||||
QVERIFY(!view.visualRect(drive).isValid());
|
||||
QVERIFY(!view.visualRect(home).isValid());
|
||||
if (homeFile.isValid())
|
||||
QVERIFY(view.visualRect(homeFile).isValid());
|
||||
|
||||
// set root when there already is one and everything should still be ok
|
||||
view.setRootIndex(home);
|
||||
view.setCurrentIndex(homeFile);
|
||||
view.scrollTo(model.index(0,0, homeFile));
|
||||
QCOMPARE(view.horizontalOffset(), 0);
|
||||
QCOMPARE(view.rootIndex(), home);
|
||||
QVERIFY(!view.visualRect(drive).isValid());
|
||||
QVERIFY(!view.visualRect(home).isValid());
|
||||
if (homeFile.isValid())
|
||||
QVERIFY(view.visualRect(homeFile).isValid());
|
||||
|
||||
//
|
||||
homeFile = model.thirdLevel();
|
||||
home = homeFile.parent();
|
||||
view.setRootIndex(home);
|
||||
view.setCurrentIndex(homeFile);
|
||||
view.show();
|
||||
i = 0;
|
||||
QModelIndex two = model.index(0, 0, homeFile);
|
||||
while (i < model.rowCount(homeFile) - 1 && !model.hasChildren(two))
|
||||
two = model.index(++i, 0, homeFile);
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
view.setCurrentIndex(two);
|
||||
view.scrollTo(two);
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
QVERIFY(two.isValid());
|
||||
QVERIFY(view.horizontalOffset() != 0);
|
||||
|
||||
view.setRootIndex(homeFile);
|
||||
QCOMPARE(view.horizontalOffset(), 0);
|
||||
}
|
||||
|
||||
void tst_QColumnView::grips()
|
||||
{
|
||||
QColumnView view;
|
||||
view.setModel(&m_fakeDirModel);
|
||||
QCOMPARE(view.resizeGripsVisible(), true);
|
||||
|
||||
view.setResizeGripsVisible(true);
|
||||
QCOMPARE(view.resizeGripsVisible(), true);
|
||||
|
||||
{
|
||||
const QObjectList list = view.viewport()->children();
|
||||
for (QObject *obj : list) {
|
||||
if (QAbstractItemView *view = qobject_cast<QAbstractItemView*>(obj))
|
||||
QVERIFY(view->cornerWidget() != nullptr);
|
||||
}
|
||||
}
|
||||
view.setResizeGripsVisible(false);
|
||||
QCOMPARE(view.resizeGripsVisible(), false);
|
||||
|
||||
{
|
||||
const QObjectList list = view.viewport()->children();
|
||||
for (QObject *obj : list) {
|
||||
if (QAbstractItemView *view = qobject_cast<QAbstractItemView*>(obj)) {
|
||||
if (view->isVisible())
|
||||
QVERIFY(!view->cornerWidget());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view.setResizeGripsVisible(true);
|
||||
QCOMPARE(view.resizeGripsVisible(), true);
|
||||
}
|
||||
|
||||
void tst_QColumnView::isIndexHidden()
|
||||
{
|
||||
ColumnView view;
|
||||
QModelIndex idx;
|
||||
QCOMPARE(view.isIndexHidden(idx), false);
|
||||
view.setModel(&m_fakeDirModel);
|
||||
QCOMPARE(view.isIndexHidden(idx), false);
|
||||
}
|
||||
|
||||
void tst_QColumnView::indexAt()
|
||||
{
|
||||
QColumnView view;
|
||||
QCOMPARE(view.indexAt(QPoint(0,0)), QModelIndex());
|
||||
view.setModel(&m_fakeDirModel);
|
||||
|
||||
QModelIndex homeFile = m_fakeDirModel.index(0, 0, m_fakeDirHomeIndex);
|
||||
if (!homeFile.isValid())
|
||||
return;
|
||||
view.setRootIndex(m_fakeDirHomeIndex);
|
||||
QRect rect = view.visualRect(QModelIndex());
|
||||
QVERIFY(!rect.isValid());
|
||||
rect = view.visualRect(homeFile);
|
||||
QVERIFY(rect.isValid());
|
||||
|
||||
QModelIndex child;
|
||||
for (int i = 0; i < m_fakeDirModel.rowCount(m_fakeDirHomeIndex); ++i) {
|
||||
child = m_fakeDirModel.index(i, 0, m_fakeDirHomeIndex);
|
||||
rect = view.visualRect(child);
|
||||
QVERIFY(rect.isValid());
|
||||
if (i > 0)
|
||||
QVERIFY(rect.top() > 0);
|
||||
QCOMPARE(view.indexAt(rect.center()), child);
|
||||
|
||||
view.selectionModel()->select(child, QItemSelectionModel::SelectCurrent);
|
||||
view.setCurrentIndex(child);
|
||||
QTest::qWait(200);
|
||||
|
||||
// test that the second row doesn't start at 0
|
||||
if (m_fakeDirModel.rowCount(child) > 0) {
|
||||
child = m_fakeDirModel.index(0, 0, child);
|
||||
QVERIFY(child.isValid());
|
||||
rect = view.visualRect(child);
|
||||
QVERIFY(rect.isValid());
|
||||
QVERIFY(rect.left() > 0);
|
||||
QCOMPARE(view.indexAt(rect.center()), child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QColumnView::scrollContentsBy_data()
|
||||
{
|
||||
QTest::addColumn<bool>("reverse");
|
||||
QTest::newRow("normal") << false;
|
||||
QTest::newRow("reverse") << true;
|
||||
}
|
||||
|
||||
void tst_QColumnView::scrollContentsBy()
|
||||
{
|
||||
QFETCH(bool, reverse);
|
||||
ColumnView view;
|
||||
if (reverse)
|
||||
view.setLayoutDirection(Qt::RightToLeft);
|
||||
view.scrollContentsBy(-1, -1);
|
||||
view.scrollContentsBy(0, 0);
|
||||
|
||||
TreeModel model;
|
||||
view.setModel(&model);
|
||||
view.scrollContentsBy(0, 0);
|
||||
|
||||
QModelIndex home = model.thirdLevel();
|
||||
view.setCurrentIndex(home);
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
view.scrollContentsBy(0, 0);
|
||||
}
|
||||
|
||||
void tst_QColumnView::scrollTo_data()
|
||||
{
|
||||
QTest::addColumn<bool>("reverse");
|
||||
QTest::addColumn<bool>("giveFocus");
|
||||
/// ### add test later for giveFocus == true
|
||||
QTest::newRow("normal") << false << false;
|
||||
QTest::newRow("reverse") << true << false;
|
||||
}
|
||||
|
||||
void tst_QColumnView::scrollTo()
|
||||
{
|
||||
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
|
||||
QSKIP("Wayland: This fails. Figure out why.");
|
||||
|
||||
QFETCH(bool, reverse);
|
||||
QFETCH(bool, giveFocus);
|
||||
QWidget topLevel;
|
||||
if (reverse)
|
||||
topLevel.setLayoutDirection(Qt::RightToLeft);
|
||||
ColumnView view(&topLevel);
|
||||
view.resize(200, 200);
|
||||
topLevel.show();
|
||||
topLevel.activateWindow();
|
||||
QTestPrivate::centerOnScreen(&topLevel);
|
||||
QVERIFY(QTest::qWaitForWindowActive(&topLevel));
|
||||
|
||||
view.scrollTo(QModelIndex(), QAbstractItemView::EnsureVisible);
|
||||
QCOMPARE(view.horizontalOffset(), 0);
|
||||
|
||||
TreeModel model;
|
||||
view.setModel(&model);
|
||||
view.scrollTo(QModelIndex(), QAbstractItemView::EnsureVisible);
|
||||
|
||||
QModelIndex home;
|
||||
home = model.index(0, 0, home);
|
||||
home = model.index(0, 0, home);
|
||||
home = model.index(0, 0, home);
|
||||
view.scrollTo(home, QAbstractItemView::EnsureVisible);
|
||||
view.setRootIndex(home);
|
||||
|
||||
QModelIndex index = model.index(0, 0, home);
|
||||
view.scrollTo(index, QAbstractItemView::EnsureVisible);
|
||||
QCOMPARE(view.horizontalOffset(), 0);
|
||||
|
||||
// Embedded requires that at least one widget have focus
|
||||
QWidget w;
|
||||
w.show();
|
||||
|
||||
QCOMPARE(view.horizontalOffset(), 0);
|
||||
if (giveFocus)
|
||||
view.setFocus(Qt::OtherFocusReason);
|
||||
else
|
||||
view.clearFocus();
|
||||
|
||||
QCOMPARE(view.horizontalOffset(), 0);
|
||||
QCoreApplication::processEvents();
|
||||
QCOMPARE(view.horizontalOffset(), 0);
|
||||
QTRY_COMPARE(view.hasFocus(), giveFocus);
|
||||
// scroll to the right
|
||||
int level = 0;
|
||||
int last = view.horizontalOffset();
|
||||
while (model.hasChildren(index) && level < 5) {
|
||||
view.setCurrentIndex(index);
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
view.scrollTo(index, QAbstractItemView::EnsureVisible);
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
index = model.index(0, 0, index);
|
||||
level++;
|
||||
if (level >= 2) {
|
||||
if (!reverse) {
|
||||
QTRY_VERIFY(view.horizontalOffset() < 0);
|
||||
qDebug() << "last=" << last
|
||||
<< " ; horizontalOffset= " << view.horizontalOffset();
|
||||
QTRY_VERIFY(last > view.horizontalOffset());
|
||||
} else {
|
||||
QTRY_VERIFY(view.horizontalOffset() > 0);
|
||||
QTRY_VERIFY(last < view.horizontalOffset());
|
||||
}
|
||||
}
|
||||
last = view.horizontalOffset();
|
||||
}
|
||||
|
||||
// scroll to the left
|
||||
int start = level;
|
||||
while(index.parent().isValid() && index != view.rootIndex()) {
|
||||
view.setCurrentIndex(index);
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
view.scrollTo(index, QAbstractItemView::EnsureVisible);
|
||||
index = index.parent();
|
||||
if (start != level) {
|
||||
if (!reverse) {
|
||||
QTRY_VERIFY(last < view.horizontalOffset());
|
||||
} else {
|
||||
if (last <= view.horizontalOffset()) {
|
||||
qDebug() << "Test failure. last=" << last
|
||||
<< " ; horizontalOffset= " << view.horizontalOffset();
|
||||
}
|
||||
QTRY_VERIFY(last > view.horizontalOffset());
|
||||
}
|
||||
}
|
||||
level--;
|
||||
last = view.horizontalOffset();
|
||||
}
|
||||
// It shouldn't automatically steal focus if it doesn't have it
|
||||
QTRY_COMPARE(view.hasFocus(), giveFocus);
|
||||
|
||||
// Try scrolling to something that is above the root index
|
||||
home = model.index(0, 0, QModelIndex());
|
||||
QModelIndex temp = model.index(1, 0, home);
|
||||
home = model.index(0, 0, home);
|
||||
home = model.index(0, 0, home);
|
||||
view.setRootIndex(home);
|
||||
view.scrollTo(model.index(0, 0, home));
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
view.scrollTo(temp);
|
||||
}
|
||||
|
||||
void tst_QColumnView::moveCursor_data()
|
||||
{
|
||||
QTest::addColumn<bool>("reverse");
|
||||
QTest::newRow("normal") << false;
|
||||
QTest::newRow("reverse") << true;
|
||||
}
|
||||
|
||||
void tst_QColumnView::moveCursor()
|
||||
{
|
||||
QFETCH(bool, reverse);
|
||||
ColumnView view;
|
||||
if (reverse)
|
||||
view.setLayoutDirection(Qt::RightToLeft);
|
||||
// don't crash
|
||||
view.moveCursor(ColumnView::MoveUp, Qt::NoModifier);
|
||||
|
||||
// don't do anything
|
||||
QCOMPARE(view.moveCursor(ColumnView::MoveEnd, Qt::NoModifier), QModelIndex());
|
||||
|
||||
view.setModel(&m_fakeDirModel);
|
||||
QModelIndex ci = view.currentIndex();
|
||||
QCOMPARE(view.moveCursor(ColumnView::MoveUp, Qt::NoModifier), QModelIndex());
|
||||
QCOMPARE(view.moveCursor(ColumnView::MoveDown, Qt::NoModifier), QModelIndex());
|
||||
|
||||
// left at root
|
||||
view.setCurrentIndex(m_fakeDirModel.index(0,0));
|
||||
ColumnView::CursorAction action = reverse ? ColumnView::MoveRight : ColumnView::MoveLeft;
|
||||
QCOMPARE(view.moveCursor(action, Qt::NoModifier), m_fakeDirModel.index(0,0));
|
||||
|
||||
// left shouldn't move up
|
||||
int i = 0;
|
||||
ci = m_fakeDirModel.index(0, 0);
|
||||
while (i < m_fakeDirModel.rowCount() - 1 && !m_fakeDirModel.hasChildren(ci))
|
||||
ci = m_fakeDirModel.index(++i, 0);
|
||||
QVERIFY(m_fakeDirModel.hasChildren(ci));
|
||||
view.setCurrentIndex(ci);
|
||||
action = reverse ? ColumnView::MoveRight : ColumnView::MoveLeft;
|
||||
QCOMPARE(view.moveCursor(action, Qt::NoModifier), ci);
|
||||
|
||||
// now move to the left (i.e. move over one column)
|
||||
view.setCurrentIndex(m_fakeDirHomeIndex);
|
||||
QCOMPARE(view.moveCursor(action, Qt::NoModifier), m_fakeDirHomeIndex.parent());
|
||||
|
||||
// right
|
||||
action = reverse ? ColumnView::MoveLeft : ColumnView::MoveRight;
|
||||
view.setCurrentIndex(ci);
|
||||
QModelIndex mc = view.moveCursor(action, Qt::NoModifier);
|
||||
QCOMPARE(mc, m_fakeDirModel.index(0,0, ci));
|
||||
|
||||
// for empty directories (no way to go 'right'), next one should move down
|
||||
QModelIndex idx = m_fakeDirModel.index(0, 0, ci);
|
||||
const int rowCount = m_fakeDirModel.rowCount(ci);
|
||||
while (m_fakeDirModel.hasChildren(idx) && rowCount > idx.row() + 1)
|
||||
idx = idx.sibling(idx.row() + 1, idx.column());
|
||||
static const char error[] = "This test requires an empty directory followed by another directory.";
|
||||
QVERIFY2(idx.isValid(), error);
|
||||
QVERIFY2(!m_fakeDirModel.hasChildren(idx), error);
|
||||
QVERIFY2(idx.row() + 1 < rowCount, error);
|
||||
view.setCurrentIndex(idx);
|
||||
mc = view.moveCursor(action, Qt::NoModifier);
|
||||
QCOMPARE(mc, idx.sibling(idx.row() + 1, idx.column()));
|
||||
}
|
||||
|
||||
void tst_QColumnView::selectAll()
|
||||
{
|
||||
ColumnView view;
|
||||
view.selectAll();
|
||||
|
||||
view.setModel(&m_fakeDirModel);
|
||||
view.selectAll();
|
||||
QVERIFY(view.selectionModel()->selectedIndexes().size() >= 0);
|
||||
|
||||
view.setCurrentIndex(m_fakeDirHomeIndex);
|
||||
view.selectAll();
|
||||
QVERIFY(view.selectionModel()->selectedIndexes().size() > 0);
|
||||
|
||||
QModelIndex file;
|
||||
for (int i = 0; i < m_fakeDirModel.rowCount(m_fakeDirHomeIndex); ++i) {
|
||||
if (!m_fakeDirModel.hasChildren(m_fakeDirModel.index(i, 0, m_fakeDirHomeIndex))) {
|
||||
file = m_fakeDirModel.index(i, 0, m_fakeDirHomeIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
view.setCurrentIndex(file);
|
||||
view.selectAll();
|
||||
QVERIFY(view.selectionModel()->selectedIndexes().size() > 0);
|
||||
|
||||
view.setCurrentIndex(QModelIndex());
|
||||
QCOMPARE(view.selectionModel()->selectedIndexes().size(), 0);
|
||||
}
|
||||
|
||||
void tst_QColumnView::clicked()
|
||||
{
|
||||
ColumnView view;
|
||||
|
||||
view.setModel(&m_fakeDirModel);
|
||||
view.resize(800, 300);
|
||||
view.show();
|
||||
|
||||
view.setCurrentIndex(m_fakeDirHomeIndex);
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
|
||||
QModelIndex parent = m_fakeDirHomeIndex.parent();
|
||||
QVERIFY(parent.isValid());
|
||||
|
||||
QSignalSpy clickedSpy(&view, &QAbstractItemView::clicked);
|
||||
|
||||
QPoint localPoint = view.visualRect(m_fakeDirHomeIndex).center();
|
||||
QTest::mouseClick(view.viewport(), Qt::LeftButton, {}, localPoint);
|
||||
QCOMPARE(clickedSpy.size(), 1);
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
if (sizeof(qreal) != sizeof(double))
|
||||
QSKIP("Skipped due to rounding errors");
|
||||
|
||||
for (int i = 0; i < view.createdColumns.size(); ++i) {
|
||||
QAbstractItemView *column = view.createdColumns.at(i);
|
||||
if (column && column->selectionModel() && (column->rootIndex() == m_fakeDirHomeIndex))
|
||||
QVERIFY(column->selectionModel()->selectedIndexes().isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QColumnView::selectedColumns()
|
||||
{
|
||||
ColumnView view;
|
||||
view.setModel(&m_fakeDirModel);
|
||||
view.resize(800,300);
|
||||
view.show();
|
||||
|
||||
view.setCurrentIndex(m_fakeDirHomeIndex);
|
||||
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
|
||||
for (int i = 0; i < view.createdColumns.size(); ++i) {
|
||||
QAbstractItemView *column = view.createdColumns.at(i);
|
||||
if (!column)
|
||||
continue;
|
||||
if (!column->rootIndex().isValid() || column->rootIndex() == m_fakeDirHomeIndex)
|
||||
continue;
|
||||
QTRY_VERIFY(column->currentIndex().isValid());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QColumnView::setSelection()
|
||||
{
|
||||
ColumnView view;
|
||||
// shouldn't do anything, it falls to the columns to handle this
|
||||
QRect r;
|
||||
view.setSelection(r, QItemSelectionModel::NoUpdate);
|
||||
}
|
||||
|
||||
void tst_QColumnView::setSelectionModel()
|
||||
{
|
||||
ColumnView view;
|
||||
view.setModel(&m_fakeDirModel);
|
||||
view.show();
|
||||
|
||||
view.setCurrentIndex(m_fakeDirHomeIndex);
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
|
||||
QItemSelectionModel *selectionModel = new QItemSelectionModel(&m_fakeDirModel);
|
||||
view.setSelectionModel(selectionModel);
|
||||
|
||||
bool found = false;
|
||||
for (int i = 0; i < view.createdColumns.size(); ++i) {
|
||||
if (view.createdColumns.at(i)->selectionModel() == selectionModel) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
QVERIFY(found);
|
||||
}
|
||||
|
||||
void tst_QColumnView::visualRegionForSelection()
|
||||
{
|
||||
ColumnView view;
|
||||
QItemSelection emptyItemSelection;
|
||||
QCOMPARE(QRegion(), view.visualRegionForSelection(emptyItemSelection));
|
||||
|
||||
// a region that isn't empty
|
||||
view.setModel(&m_fakeDirModel);
|
||||
|
||||
|
||||
QItemSelection itemSelection(m_fakeDirModel.index(0, 0, m_fakeDirHomeIndex), m_fakeDirModel.index(m_fakeDirModel.rowCount(m_fakeDirHomeIndex) - 1, 0, m_fakeDirHomeIndex));
|
||||
QVERIFY(QRegion() != view.visualRegionForSelection(itemSelection));
|
||||
}
|
||||
|
||||
void tst_QColumnView::moveGrip_basic()
|
||||
{
|
||||
QColumnView view;
|
||||
QColumnViewGrip *grip = new QColumnViewGrip(&view);
|
||||
QSignalSpy spy(grip, &QColumnViewGrip::gripMoved);
|
||||
view.setCornerWidget(grip);
|
||||
int oldX = view.width();
|
||||
grip->moveGrip(10);
|
||||
QCOMPARE(oldX + 10, view.width());
|
||||
grip->moveGrip(-10);
|
||||
QCOMPARE(oldX, view.width());
|
||||
grip->moveGrip(-800);
|
||||
QVERIFY(view.width() == 0 || view.width() == 1);
|
||||
grip->moveGrip(800);
|
||||
view.setMinimumWidth(200);
|
||||
grip->moveGrip(-800);
|
||||
QCOMPARE(view.width(), 200);
|
||||
QCOMPARE(spy.size(), 5);
|
||||
}
|
||||
|
||||
void tst_QColumnView::moveGrip_data()
|
||||
{
|
||||
QTest::addColumn<bool>("reverse");
|
||||
QTest::newRow("normal") << false;
|
||||
QTest::newRow("reverse") << true;
|
||||
}
|
||||
|
||||
void tst_QColumnView::moveGrip()
|
||||
{
|
||||
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
|
||||
QSKIP("Wayland: This fails. Figure out why.");
|
||||
|
||||
QFETCH(bool, reverse);
|
||||
QWidget topLevel;
|
||||
if (reverse)
|
||||
topLevel.setLayoutDirection(Qt::RightToLeft);
|
||||
ColumnView view(&topLevel);
|
||||
TreeModel model;
|
||||
view.setModel(&model);
|
||||
QModelIndex home = model.thirdLevel();
|
||||
view.setCurrentIndex(home);
|
||||
view.resize(640, 200);
|
||||
topLevel.show();
|
||||
QVERIFY(QTest::qWaitForWindowActive(&topLevel));
|
||||
|
||||
int columnNum = view.createdColumns.size() - 2;
|
||||
QVERIFY(columnNum >= 0);
|
||||
const QObjectList list = view.createdColumns[columnNum]->children();
|
||||
QColumnViewGrip *grip = nullptr;
|
||||
for (QObject *obj : list) {
|
||||
if ((grip = qobject_cast<QColumnViewGrip *>(obj)))
|
||||
break;
|
||||
}
|
||||
if (!grip)
|
||||
return;
|
||||
|
||||
QAbstractItemView *column = qobject_cast<QAbstractItemView *>(grip->parent());
|
||||
int oldX = column->width();
|
||||
QCOMPARE(view.columnWidths().value(columnNum), oldX);
|
||||
grip->moveGrip(10);
|
||||
QCOMPARE(view.columnWidths().value(columnNum), (oldX + (reverse ? -10 : 10)));
|
||||
}
|
||||
|
||||
void tst_QColumnView::doubleClick()
|
||||
{
|
||||
QColumnView view;
|
||||
QColumnViewGrip *grip = new QColumnViewGrip(&view);
|
||||
QSignalSpy spy(grip, &QColumnViewGrip::gripMoved);
|
||||
view.setCornerWidget(grip);
|
||||
view.resize(200, 200);
|
||||
QCOMPARE(view.width(), 200);
|
||||
QTest::mouseDClick(grip, Qt::LeftButton);
|
||||
QCOMPARE(view.width(), view.sizeHint().width());
|
||||
QCOMPARE(spy.size(), 1);
|
||||
}
|
||||
|
||||
void tst_QColumnView::gripMoved()
|
||||
{
|
||||
QColumnView view;
|
||||
QColumnViewGrip *grip = new QColumnViewGrip(&view);
|
||||
QSignalSpy spy(grip, &QColumnViewGrip::gripMoved);
|
||||
view.setCornerWidget(grip);
|
||||
view.move(300, 300);
|
||||
view.resize(200, 200);
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
int oldWidth = view.width();
|
||||
|
||||
QTest::mousePress(grip, Qt::LeftButton, {}, QPoint(1, 1));
|
||||
//QTest::mouseMove(grip, QPoint(grip->globalX()+50, y));
|
||||
|
||||
QPoint posNew = QPoint(grip->mapToGlobal(QPoint(1, 1)).x() + 65, 0);
|
||||
QMouseEvent *event = new QMouseEvent(QEvent::MouseMove, posNew, posNew, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
|
||||
QCoreApplication::postEvent(grip, event);
|
||||
QCoreApplication::processEvents();
|
||||
QTest::mouseRelease(grip, Qt::LeftButton);
|
||||
|
||||
QTRY_COMPARE(spy.size(), 1);
|
||||
QCOMPARE(view.width(), oldWidth + 65);
|
||||
}
|
||||
|
||||
void tst_QColumnView::preview()
|
||||
{
|
||||
QColumnView view;
|
||||
QCOMPARE(view.previewWidget(), nullptr);
|
||||
TreeModel model;
|
||||
view.setModel(&model);
|
||||
QCOMPARE(view.previewWidget(), nullptr);
|
||||
QModelIndex home = model.index(0, 0);
|
||||
QVERIFY(home.isValid());
|
||||
QVERIFY(model.hasChildren(home));
|
||||
view.setCurrentIndex(home);
|
||||
QCOMPARE(view.previewWidget(), nullptr);
|
||||
|
||||
QModelIndex file;
|
||||
QVERIFY(model.rowCount(home) > 0);
|
||||
for (int i = 0; i < model.rowCount(home); ++i) {
|
||||
if (!model.hasChildren(model.index(i, 0, home))) {
|
||||
file = model.index(i, 0, home);
|
||||
break;
|
||||
}
|
||||
}
|
||||
QVERIFY(file.isValid());
|
||||
view.setCurrentIndex(file);
|
||||
QVERIFY(view.previewWidget() != nullptr);
|
||||
|
||||
QWidget *previewWidget = new QWidget(&view);
|
||||
view.setPreviewWidget(previewWidget);
|
||||
QCOMPARE(view.previewWidget(), previewWidget);
|
||||
QVERIFY(previewWidget->parent() != &view);
|
||||
view.setCurrentIndex(home);
|
||||
|
||||
// previewWidget should be marked for deletion
|
||||
QWidget *previewWidget2 = new QWidget(&view);
|
||||
view.setPreviewWidget(previewWidget2);
|
||||
QCOMPARE(view.previewWidget(), previewWidget2);
|
||||
}
|
||||
|
||||
void tst_QColumnView::swapPreview()
|
||||
{
|
||||
// swap the preview widget in updatePreviewWidget
|
||||
QColumnView view;
|
||||
QStringListModel model({ QLatin1String("test") });
|
||||
view.setModel(&model);
|
||||
view.setCurrentIndex(view.indexAt(QPoint(1, 1)));
|
||||
connect(&view, &QColumnView::updatePreviewWidget,
|
||||
this, &tst_QColumnView::setPreviewWidget);
|
||||
view.setCurrentIndex(view.indexAt(QPoint(1, 1)));
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
void tst_QColumnView::setPreviewWidget()
|
||||
{
|
||||
auto ptr = qobject_cast<QColumnView *>(sender());
|
||||
QVERIFY(ptr);
|
||||
ptr->setPreviewWidget(new QWidget);
|
||||
}
|
||||
|
||||
void tst_QColumnView::sizes()
|
||||
{
|
||||
QColumnView view;
|
||||
QCOMPARE(view.columnWidths().size(), 0);
|
||||
|
||||
const QList<int> newSizes{ 10, 4, 50, 6 };
|
||||
|
||||
QList<int> visibleSizes;
|
||||
view.setColumnWidths(newSizes);
|
||||
QCOMPARE(view.columnWidths(), visibleSizes);
|
||||
|
||||
view.setModel(&m_fakeDirModel);
|
||||
view.setCurrentIndex(m_fakeDirHomeIndex);
|
||||
|
||||
QList<int> postSizes = view.columnWidths().mid(0, newSizes.size());
|
||||
QCOMPARE(postSizes, newSizes.mid(0, postSizes.size()));
|
||||
|
||||
QVERIFY(view.columnWidths().size() > 1);
|
||||
QList<int> smallerSizes{ 6 };
|
||||
view.setColumnWidths(smallerSizes);
|
||||
QList<int> expectedSizes = newSizes;
|
||||
expectedSizes[0] = 6;
|
||||
postSizes = view.columnWidths().mid(0, newSizes.size());
|
||||
QCOMPARE(postSizes, expectedSizes.mid(0, postSizes.size()));
|
||||
}
|
||||
|
||||
void tst_QColumnView::rowDelegate()
|
||||
{
|
||||
ColumnView view;
|
||||
QStyledItemDelegate *d = new QStyledItemDelegate;
|
||||
view.setItemDelegateForRow(3, d);
|
||||
|
||||
view.setModel(&m_fakeDirModel);
|
||||
for (int i = 0; i < view.createdColumns.size(); ++i) {
|
||||
QAbstractItemView *column = view.createdColumns.at(i);
|
||||
QCOMPARE(column->itemDelegateForRow(3), d);
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
void tst_QColumnView::resize()
|
||||
{
|
||||
QWidget topLevel;
|
||||
ColumnView view(&topLevel);
|
||||
view.setModel(&m_fakeDirModel);
|
||||
view.resize(200, 200);
|
||||
|
||||
topLevel.show();
|
||||
view.setCurrentIndex(m_fakeDirHomeIndex);
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
view.resize(200, 300);
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
|
||||
QVERIFY(view.horizontalScrollBar()->maximum() != 0);
|
||||
view.resize(view.horizontalScrollBar()->maximum() * 10, 300);
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
QVERIFY(view.horizontalScrollBar()->maximum() <= 0);
|
||||
}
|
||||
|
||||
void tst_QColumnView::changeSameColumn()
|
||||
{
|
||||
ColumnView view;
|
||||
TreeModel model;
|
||||
view.setModel(&model);
|
||||
QModelIndex second;
|
||||
|
||||
QModelIndex home = model.secondLevel();
|
||||
//index(QDir::homePath());
|
||||
view.setCurrentIndex(home);
|
||||
for (int i = 0; i < model.rowCount(home.parent()); ++i) {
|
||||
QModelIndex idx = model.index(i, 0, home.parent());
|
||||
if (model.hasChildren(idx) && idx != home) {
|
||||
second = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
QVERIFY(second.isValid());
|
||||
|
||||
const auto old = view.createdColumns;
|
||||
view.setCurrentIndex(second);
|
||||
|
||||
QCOMPARE(old, view.createdColumns);
|
||||
}
|
||||
|
||||
void tst_QColumnView::parentCurrentIndex_data()
|
||||
{
|
||||
QTest::addColumn<int>("firstRow");
|
||||
QTest::addColumn<int>("secondRow");
|
||||
QTest::newRow("down") << 0 << 1;
|
||||
QTest::newRow("up") << 1 << 0;
|
||||
}
|
||||
|
||||
void tst_QColumnView::parentCurrentIndex()
|
||||
{
|
||||
QFETCH(int, firstRow);
|
||||
QFETCH(int, secondRow);
|
||||
|
||||
ColumnView view;
|
||||
TreeModel model;
|
||||
view.setModel(&model);
|
||||
view.show();
|
||||
|
||||
QModelIndex first;
|
||||
QModelIndex second;
|
||||
QModelIndex third;
|
||||
first = model.index(0, 0, QModelIndex());
|
||||
second = model.index(firstRow, 0, first);
|
||||
third = model.index(0, 0, second);
|
||||
QVERIFY(first.isValid());
|
||||
QVERIFY(second.isValid());
|
||||
QVERIFY(third.isValid());
|
||||
view.setCurrentIndex(third);
|
||||
QTRY_COMPARE(view.createdColumns[0]->currentIndex(), first);
|
||||
QTRY_COMPARE(view.createdColumns[1]->currentIndex(), second);
|
||||
QTRY_COMPARE(view.createdColumns[2]->currentIndex(), third);
|
||||
|
||||
first = model.index(0, 0, QModelIndex());
|
||||
second = model.index(secondRow, 0, first);
|
||||
third = model.index(0, 0, second);
|
||||
QVERIFY(first.isValid());
|
||||
QVERIFY(second.isValid());
|
||||
QVERIFY(third.isValid());
|
||||
view.setCurrentIndex(third);
|
||||
QTRY_COMPARE(view.createdColumns[0]->currentIndex(), first);
|
||||
QTRY_COMPARE(view.createdColumns[1]->currentIndex(), second);
|
||||
|
||||
// The next two lines should be removed when QTBUG-22707 is resolved.
|
||||
QEXPECT_FAIL("", "QTBUG-22707", Abort);
|
||||
|
||||
QVERIFY(view.createdColumns[2]);
|
||||
|
||||
QTRY_COMPARE(view.createdColumns[2]->currentIndex(), third);
|
||||
}
|
||||
|
||||
void tst_QColumnView::pullRug_data()
|
||||
{
|
||||
QTest::addColumn<bool>("removeModel");
|
||||
QTest::newRow("model") << true;
|
||||
QTest::newRow("index") << false;
|
||||
}
|
||||
|
||||
void tst_QColumnView::pullRug()
|
||||
{
|
||||
QFETCH(bool, removeModel);
|
||||
ColumnView view;
|
||||
TreeModel model;
|
||||
view.setModel(&model);
|
||||
QModelIndex home = model.thirdLevel();
|
||||
view.setCurrentIndex(home);
|
||||
if (removeModel)
|
||||
view.setModel(nullptr);
|
||||
else
|
||||
view.setCurrentIndex(QModelIndex());
|
||||
QTest::qWait(ANIMATION_DELAY);
|
||||
// don't crash
|
||||
}
|
||||
|
||||
void tst_QColumnView::dynamicModelChanges()
|
||||
{
|
||||
struct MyItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
void paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override
|
||||
{
|
||||
paintedIndexes += index;
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
}
|
||||
|
||||
mutable QSet<QModelIndex> paintedIndexes;
|
||||
|
||||
} delegate;
|
||||
QStandardItemModel model;
|
||||
ColumnView view;
|
||||
view.setModel(&model);
|
||||
view.setItemDelegate(&delegate);
|
||||
QTestPrivate::centerOnScreen(&view);
|
||||
view.show();
|
||||
|
||||
QStandardItem *item = new QStandardItem(QLatin1String("item"));
|
||||
model.appendRow(item);
|
||||
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&view)); //let the time for painting to occur
|
||||
QTRY_COMPARE(delegate.paintedIndexes.size(), 1);
|
||||
QCOMPARE(*delegate.paintedIndexes.begin(), model.index(0,0));
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(tst_QColumnView)
|
||||
#include "tst_qcolumnview.moc"
|
||||
|
@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qdatawidgetmapper Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qdatawidgetmapper
|
||||
SOURCES
|
||||
tst_qdatawidgetmapper.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
@ -0,0 +1,458 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDataWidgetMapper>
|
||||
#include <QLineEdit>
|
||||
#include <QMetaType>
|
||||
#include <QStandardItemModel>
|
||||
#include <QSignalSpy>
|
||||
#include <QTest>
|
||||
#include <QTextEdit>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <QtWidgets/private/qapplication_p.h>
|
||||
|
||||
class tst_QDataWidgetMapper: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void initTestCase();
|
||||
|
||||
void setModel();
|
||||
void navigate();
|
||||
void addMapping();
|
||||
void currentIndexChanged();
|
||||
void changingValues();
|
||||
void setData();
|
||||
void mappedWidgetAt();
|
||||
|
||||
void comboBox();
|
||||
|
||||
void textEditDoesntChangeFocusOnTab_qtbug3305();
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QAbstractItemDelegate::EndEditHint)
|
||||
|
||||
static QStandardItemModel *testModel(QObject *parent)
|
||||
{
|
||||
QStandardItemModel *model = new QStandardItemModel(10, 10, parent);
|
||||
|
||||
for (int row = 0; row < 10; ++row) {
|
||||
const QString prefix = QLatin1String("item ") + QString::number(row)
|
||||
+ QLatin1Char(' ');
|
||||
for (int col = 0; col < 10; ++col)
|
||||
model->setData(model->index(row, col), prefix + QString::number(col));
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
void tst_QDataWidgetMapper::initTestCase()
|
||||
{
|
||||
qRegisterMetaType<QAbstractItemDelegate::EndEditHint>();
|
||||
}
|
||||
|
||||
void tst_QDataWidgetMapper::setModel()
|
||||
{
|
||||
QDataWidgetMapper mapper;
|
||||
|
||||
QCOMPARE(mapper.model(), nullptr);
|
||||
|
||||
{ // let the model go out of scope firstma
|
||||
QStandardItemModel model;
|
||||
mapper.setModel(&model);
|
||||
QCOMPARE(mapper.model(), &model);
|
||||
}
|
||||
|
||||
QCOMPARE(mapper.model(), nullptr);
|
||||
|
||||
{ // let the mapper go out of scope first
|
||||
QStandardItemModel model2;
|
||||
QDataWidgetMapper mapper2;
|
||||
mapper2.setModel(&model2);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QDataWidgetMapper::navigate()
|
||||
{
|
||||
QDataWidgetMapper mapper;
|
||||
QAbstractItemModel *model = testModel(&mapper);
|
||||
mapper.setModel(model);
|
||||
|
||||
QLineEdit edit1;
|
||||
QLineEdit edit2;
|
||||
QLineEdit edit3;
|
||||
|
||||
mapper.addMapping(&edit1, 0);
|
||||
mapper.toFirst();
|
||||
mapper.addMapping(&edit2, 1);
|
||||
mapper.addMapping(&edit3, 2);
|
||||
|
||||
QCOMPARE(edit1.text(), QString("item 0 0"));
|
||||
QVERIFY(edit2.text().isEmpty());
|
||||
QVERIFY(edit3.text().isEmpty());
|
||||
QVERIFY(mapper.submit());
|
||||
edit2.setText(QString("item 0 1"));
|
||||
edit3.setText(QString("item 0 2"));
|
||||
QVERIFY(mapper.submit());
|
||||
|
||||
mapper.toFirst(); //this will repopulate
|
||||
QCOMPARE(edit1.text(), QString("item 0 0"));
|
||||
QCOMPARE(edit2.text(), QString("item 0 1"));
|
||||
QCOMPARE(edit3.text(), QString("item 0 2"));
|
||||
|
||||
|
||||
mapper.toFirst();
|
||||
QCOMPARE(edit1.text(), QString("item 0 0"));
|
||||
QCOMPARE(edit2.text(), QString("item 0 1"));
|
||||
QCOMPARE(edit3.text(), QString("item 0 2"));
|
||||
|
||||
mapper.toPrevious(); // should do nothing
|
||||
QCOMPARE(edit1.text(), QString("item 0 0"));
|
||||
QCOMPARE(edit2.text(), QString("item 0 1"));
|
||||
QCOMPARE(edit3.text(), QString("item 0 2"));
|
||||
|
||||
mapper.toNext();
|
||||
QCOMPARE(edit1.text(), QString("item 1 0"));
|
||||
QCOMPARE(edit2.text(), QString("item 1 1"));
|
||||
QCOMPARE(edit3.text(), QString("item 1 2"));
|
||||
|
||||
mapper.toLast();
|
||||
QCOMPARE(edit1.text(), QString("item 9 0"));
|
||||
QCOMPARE(edit2.text(), QString("item 9 1"));
|
||||
QCOMPARE(edit3.text(), QString("item 9 2"));
|
||||
|
||||
mapper.toNext(); // should do nothing
|
||||
QCOMPARE(edit1.text(), QString("item 9 0"));
|
||||
QCOMPARE(edit2.text(), QString("item 9 1"));
|
||||
QCOMPARE(edit3.text(), QString("item 9 2"));
|
||||
|
||||
mapper.setCurrentIndex(4);
|
||||
QCOMPARE(edit1.text(), QString("item 4 0"));
|
||||
QCOMPARE(edit2.text(), QString("item 4 1"));
|
||||
QCOMPARE(edit3.text(), QString("item 4 2"));
|
||||
|
||||
mapper.setCurrentIndex(-1); // should do nothing
|
||||
QCOMPARE(edit1.text(), QString("item 4 0"));
|
||||
QCOMPARE(edit2.text(), QString("item 4 1"));
|
||||
QCOMPARE(edit3.text(), QString("item 4 2"));
|
||||
|
||||
mapper.setCurrentIndex(10); // should do nothing
|
||||
QCOMPARE(edit1.text(), QString("item 4 0"));
|
||||
QCOMPARE(edit2.text(), QString("item 4 1"));
|
||||
QCOMPARE(edit3.text(), QString("item 4 2"));
|
||||
|
||||
mapper.setCurrentModelIndex(QModelIndex()); // should do nothing
|
||||
QCOMPARE(edit1.text(), QString("item 4 0"));
|
||||
QCOMPARE(edit2.text(), QString("item 4 1"));
|
||||
QCOMPARE(edit3.text(), QString("item 4 2"));
|
||||
|
||||
mapper.setCurrentModelIndex(model->index(6, 0));
|
||||
QCOMPARE(edit1.text(), QString("item 6 0"));
|
||||
QCOMPARE(edit2.text(), QString("item 6 1"));
|
||||
QCOMPARE(edit3.text(), QString("item 6 2"));
|
||||
|
||||
/* now try vertical navigation */
|
||||
|
||||
mapper.setOrientation(Qt::Vertical);
|
||||
|
||||
mapper.addMapping(&edit1, 0);
|
||||
mapper.addMapping(&edit2, 1);
|
||||
mapper.addMapping(&edit3, 2);
|
||||
|
||||
mapper.toFirst();
|
||||
QCOMPARE(edit1.text(), QString("item 0 0"));
|
||||
QCOMPARE(edit2.text(), QString("item 1 0"));
|
||||
QCOMPARE(edit3.text(), QString("item 2 0"));
|
||||
|
||||
mapper.toPrevious(); // should do nothing
|
||||
QCOMPARE(edit1.text(), QString("item 0 0"));
|
||||
QCOMPARE(edit2.text(), QString("item 1 0"));
|
||||
QCOMPARE(edit3.text(), QString("item 2 0"));
|
||||
|
||||
mapper.toNext();
|
||||
QCOMPARE(edit1.text(), QString("item 0 1"));
|
||||
QCOMPARE(edit2.text(), QString("item 1 1"));
|
||||
QCOMPARE(edit3.text(), QString("item 2 1"));
|
||||
|
||||
mapper.toLast();
|
||||
QCOMPARE(edit1.text(), QString("item 0 9"));
|
||||
QCOMPARE(edit2.text(), QString("item 1 9"));
|
||||
QCOMPARE(edit3.text(), QString("item 2 9"));
|
||||
|
||||
mapper.toNext(); // should do nothing
|
||||
QCOMPARE(edit1.text(), QString("item 0 9"));
|
||||
QCOMPARE(edit2.text(), QString("item 1 9"));
|
||||
QCOMPARE(edit3.text(), QString("item 2 9"));
|
||||
|
||||
mapper.setCurrentIndex(4);
|
||||
QCOMPARE(edit1.text(), QString("item 0 4"));
|
||||
QCOMPARE(edit2.text(), QString("item 1 4"));
|
||||
QCOMPARE(edit3.text(), QString("item 2 4"));
|
||||
|
||||
mapper.setCurrentIndex(-1); // should do nothing
|
||||
QCOMPARE(edit1.text(), QString("item 0 4"));
|
||||
QCOMPARE(edit2.text(), QString("item 1 4"));
|
||||
QCOMPARE(edit3.text(), QString("item 2 4"));
|
||||
|
||||
mapper.setCurrentIndex(10); // should do nothing
|
||||
QCOMPARE(edit1.text(), QString("item 0 4"));
|
||||
QCOMPARE(edit2.text(), QString("item 1 4"));
|
||||
QCOMPARE(edit3.text(), QString("item 2 4"));
|
||||
|
||||
mapper.setCurrentModelIndex(QModelIndex()); // should do nothing
|
||||
QCOMPARE(edit1.text(), QString("item 0 4"));
|
||||
QCOMPARE(edit2.text(), QString("item 1 4"));
|
||||
QCOMPARE(edit3.text(), QString("item 2 4"));
|
||||
|
||||
mapper.setCurrentModelIndex(model->index(0, 6));
|
||||
QCOMPARE(edit1.text(), QString("item 0 6"));
|
||||
QCOMPARE(edit2.text(), QString("item 1 6"));
|
||||
QCOMPARE(edit3.text(), QString("item 2 6"));
|
||||
}
|
||||
|
||||
void tst_QDataWidgetMapper::addMapping()
|
||||
{
|
||||
QDataWidgetMapper mapper;
|
||||
QAbstractItemModel *model = testModel(&mapper);
|
||||
mapper.setModel(model);
|
||||
|
||||
QLineEdit edit1;
|
||||
mapper.addMapping(&edit1, 0);
|
||||
mapper.toFirst();
|
||||
QCOMPARE(edit1.text(), QString("item 0 0"));
|
||||
|
||||
mapper.addMapping(&edit1, 1);
|
||||
mapper.toFirst();
|
||||
QCOMPARE(edit1.text(), QString("item 0 1"));
|
||||
|
||||
QCOMPARE(mapper.mappedSection(&edit1), 1);
|
||||
|
||||
edit1.clear();
|
||||
mapper.removeMapping(&edit1);
|
||||
mapper.toFirst();
|
||||
QCOMPARE(edit1.text(), QString());
|
||||
|
||||
{
|
||||
QLineEdit edit2;
|
||||
mapper.addMapping(&edit2, 2);
|
||||
mapper.toFirst();
|
||||
QCOMPARE(edit2.text(), QString("item 0 2"));
|
||||
} // let the edit go out of scope
|
||||
|
||||
QCOMPARE(mapper.mappedWidgetAt(2), nullptr);
|
||||
mapper.toLast();
|
||||
}
|
||||
|
||||
void tst_QDataWidgetMapper::currentIndexChanged()
|
||||
{
|
||||
QDataWidgetMapper mapper;
|
||||
QAbstractItemModel *model = testModel(&mapper);
|
||||
mapper.setModel(model);
|
||||
|
||||
QSignalSpy spy(&mapper, &QDataWidgetMapper::currentIndexChanged);
|
||||
|
||||
mapper.toFirst();
|
||||
QCOMPARE(spy.size(), 1);
|
||||
QCOMPARE(spy.takeFirst().at(0).toInt(), 0);
|
||||
|
||||
mapper.toNext();
|
||||
QCOMPARE(spy.size(), 1);
|
||||
QCOMPARE(spy.takeFirst().at(0).toInt(), 1);
|
||||
|
||||
mapper.setCurrentIndex(7);
|
||||
QCOMPARE(spy.size(), 1);
|
||||
QCOMPARE(spy.takeFirst().at(0).toInt(), 7);
|
||||
|
||||
mapper.setCurrentIndex(-1);
|
||||
QCOMPARE(spy.size(), 0);
|
||||
|
||||
mapper.setCurrentIndex(42);
|
||||
QCOMPARE(spy.size(), 0);
|
||||
}
|
||||
|
||||
void tst_QDataWidgetMapper::changingValues()
|
||||
{
|
||||
QDataWidgetMapper mapper;
|
||||
QAbstractItemModel *model = testModel(&mapper);
|
||||
mapper.setModel(model);
|
||||
|
||||
QLineEdit edit1;
|
||||
mapper.addMapping(&edit1, 0);
|
||||
mapper.toFirst();
|
||||
QCOMPARE(edit1.text(), QString("item 0 0"));
|
||||
|
||||
QLineEdit edit2;
|
||||
mapper.addMapping(&edit2, 0, "text");
|
||||
mapper.toFirst();
|
||||
QCOMPARE(edit2.text(), QString("item 0 0"));
|
||||
|
||||
model->setData(model->index(0, 0), QString("changed"));
|
||||
QCOMPARE(edit1.text(), QString("changed"));
|
||||
QCOMPARE(edit2.text(), QString("changed"));
|
||||
}
|
||||
|
||||
void tst_QDataWidgetMapper::setData()
|
||||
{
|
||||
QDataWidgetMapper mapper;
|
||||
QAbstractItemModel *model = testModel(&mapper);
|
||||
mapper.setModel(model);
|
||||
|
||||
QLineEdit edit1;
|
||||
QLineEdit edit2;
|
||||
QLineEdit edit3;
|
||||
|
||||
mapper.addMapping(&edit1, 0);
|
||||
mapper.addMapping(&edit2, 1);
|
||||
mapper.addMapping(&edit3, 0, "text");
|
||||
mapper.toFirst();
|
||||
QCOMPARE(edit1.text(), QString("item 0 0"));
|
||||
QCOMPARE(edit2.text(), QString("item 0 1"));
|
||||
QCOMPARE(edit3.text(), QString("item 0 0"));
|
||||
|
||||
edit1.setText("new text");
|
||||
|
||||
mapper.submit();
|
||||
QCOMPARE(model->data(model->index(0, 0)).toString(), QString("new text"));
|
||||
|
||||
edit3.setText("more text");
|
||||
|
||||
mapper.submit();
|
||||
QCOMPARE(model->data(model->index(0, 0)).toString(), QString("more text"));
|
||||
}
|
||||
|
||||
void tst_QDataWidgetMapper::comboBox()
|
||||
{
|
||||
QDataWidgetMapper mapper;
|
||||
QAbstractItemModel *model = testModel(&mapper);
|
||||
mapper.setModel(model);
|
||||
mapper.setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
|
||||
|
||||
QComboBox readOnlyBox;
|
||||
readOnlyBox.setEditable(false);
|
||||
readOnlyBox.addItem("read only item 0");
|
||||
readOnlyBox.addItem("read only item 1");
|
||||
readOnlyBox.addItem("read only item 2");
|
||||
|
||||
QComboBox readWriteBox;
|
||||
readWriteBox.setEditable(true);
|
||||
readWriteBox.addItem("read write item 0");
|
||||
readWriteBox.addItem("read write item 1");
|
||||
readWriteBox.addItem("read write item 2");
|
||||
|
||||
// populate the combo boxes with data
|
||||
mapper.addMapping(&readOnlyBox, 0, "currentIndex");
|
||||
mapper.addMapping(&readWriteBox, 1, "currentText");
|
||||
mapper.toFirst();
|
||||
|
||||
// setCurrentIndex caused the value at index 0 to be displayed
|
||||
QCOMPARE(readOnlyBox.currentText(), QString("read only item 0"));
|
||||
// setCurrentText set the value in the line edit since the combobox is editable
|
||||
QCOMPARE(readWriteBox.currentText(), QString("item 0 1"));
|
||||
|
||||
// set some new values on the boxes
|
||||
readOnlyBox.setCurrentIndex(1);
|
||||
readWriteBox.setEditText("read write item y");
|
||||
|
||||
mapper.submit();
|
||||
|
||||
// make sure the new values are in the model
|
||||
QCOMPARE(model->data(model->index(0, 0)).toInt(), 1);
|
||||
QCOMPARE(model->data(model->index(0, 1)).toString(), QString("read write item y"));
|
||||
|
||||
// now test updating of the widgets
|
||||
model->setData(model->index(0, 0), 2, Qt::EditRole);
|
||||
model->setData(model->index(0, 1), QString("read write item z"), Qt::EditRole);
|
||||
|
||||
QCOMPARE(readOnlyBox.currentIndex(), 2);
|
||||
QCOMPARE(readWriteBox.currentText(), QString("read write item z"));
|
||||
}
|
||||
|
||||
void tst_QDataWidgetMapper::mappedWidgetAt()
|
||||
{
|
||||
QDataWidgetMapper mapper;
|
||||
QAbstractItemModel *model = testModel(&mapper);
|
||||
mapper.setModel(model);
|
||||
|
||||
QLineEdit lineEdit1;
|
||||
QLineEdit lineEdit2;
|
||||
|
||||
QCOMPARE(mapper.mappedWidgetAt(432312), nullptr);
|
||||
|
||||
mapper.addMapping(&lineEdit1, 1);
|
||||
mapper.addMapping(&lineEdit2, 2);
|
||||
|
||||
QCOMPARE(mapper.mappedWidgetAt(1), &lineEdit1);
|
||||
QCOMPARE(mapper.mappedWidgetAt(2), &lineEdit2);
|
||||
|
||||
mapper.addMapping(&lineEdit2, 4242);
|
||||
|
||||
QCOMPARE(mapper.mappedWidgetAt(2), nullptr);
|
||||
QCOMPARE(mapper.mappedWidgetAt(4242), &lineEdit2);
|
||||
}
|
||||
|
||||
void tst_QDataWidgetMapper::textEditDoesntChangeFocusOnTab_qtbug3305()
|
||||
{
|
||||
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
|
||||
QSKIP("Wayland: This fails. Figure out why.");
|
||||
|
||||
QDataWidgetMapper mapper;
|
||||
QAbstractItemModel *model = testModel(&mapper);
|
||||
mapper.setModel(model);
|
||||
|
||||
QSignalSpy closeEditorSpy(mapper.itemDelegate(),
|
||||
&QAbstractItemDelegate::closeEditor);
|
||||
QVERIFY(closeEditorSpy.isValid());
|
||||
|
||||
QWidget container;
|
||||
container.setLayout(new QVBoxLayout);
|
||||
|
||||
QLineEdit *lineEdit = new QLineEdit;
|
||||
mapper.addMapping(lineEdit, 0);
|
||||
container.layout()->addWidget(lineEdit);
|
||||
|
||||
QTextEdit *textEdit = new QTextEdit;
|
||||
mapper.addMapping(textEdit, 1);
|
||||
container.layout()->addWidget(textEdit);
|
||||
|
||||
lineEdit->setFocus();
|
||||
|
||||
container.show();
|
||||
|
||||
QApplicationPrivate::setActiveWindow(&container);
|
||||
QVERIFY(QTest::qWaitForWindowActive(&container));
|
||||
|
||||
int closeEditorSpyCount = 0;
|
||||
const QString textEditContents = textEdit->toPlainText();
|
||||
|
||||
QCOMPARE(closeEditorSpy.size(), closeEditorSpyCount);
|
||||
QVERIFY(lineEdit->hasFocus());
|
||||
QVERIFY(!textEdit->hasFocus());
|
||||
|
||||
// this will generate a closeEditor for the tab key, and another for the focus out
|
||||
QTest::keyClick(QApplication::focusWidget(), Qt::Key_Tab);
|
||||
closeEditorSpyCount += 2;
|
||||
QTRY_COMPARE(closeEditorSpy.size(), closeEditorSpyCount);
|
||||
|
||||
QTRY_VERIFY(textEdit->hasFocus());
|
||||
QVERIFY(!lineEdit->hasFocus());
|
||||
|
||||
// now that the text edit is focused, a tab keypress will insert a tab, not change focus
|
||||
QTest::keyClick(QApplication::focusWidget(), Qt::Key_Tab);
|
||||
QTRY_COMPARE(closeEditorSpy.size(), closeEditorSpyCount);
|
||||
|
||||
QVERIFY(!lineEdit->hasFocus());
|
||||
QVERIFY(textEdit->hasFocus());
|
||||
QCOMPARE(textEdit->toPlainText(), QLatin1Char('\t') + textEditContents);
|
||||
|
||||
// now give focus back to the line edit and check closeEditor gets emitted
|
||||
lineEdit->setFocus();
|
||||
QTRY_VERIFY(lineEdit->hasFocus());
|
||||
QVERIFY(!textEdit->hasFocus());
|
||||
++closeEditorSpyCount;
|
||||
QCOMPARE(closeEditorSpy.size(), closeEditorSpyCount);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QDataWidgetMapper)
|
||||
#include "tst_qdatawidgetmapper.moc"
|
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qfileiconprovider Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qfileiconprovider
|
||||
SOURCES
|
||||
tst_qfileiconprovider.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
@ -0,0 +1,119 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QFileIconProvider>
|
||||
#include <QFileInfo>
|
||||
#include <QTest>
|
||||
|
||||
class tst_QFileIconProvider : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void qfileiconprovider();
|
||||
|
||||
void iconType_data();
|
||||
void iconType();
|
||||
|
||||
void iconInfo_data();
|
||||
void iconInfo();
|
||||
|
||||
void type_data();
|
||||
void type();
|
||||
|
||||
void iconPixmaps();
|
||||
};
|
||||
|
||||
void tst_QFileIconProvider::qfileiconprovider()
|
||||
{
|
||||
// don't crash
|
||||
QFileIconProvider provider;
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(QFileIconProvider::IconType)
|
||||
void tst_QFileIconProvider::iconType_data()
|
||||
{
|
||||
QTest::addColumn<QFileIconProvider::IconType>("type");
|
||||
|
||||
QTest::newRow("computer") << QFileIconProvider::Computer;
|
||||
QTest::newRow("desktop") << QFileIconProvider::Desktop;
|
||||
QTest::newRow("trashcan") << QFileIconProvider::Trashcan;
|
||||
QTest::newRow("network") << QFileIconProvider::Network;
|
||||
QTest::newRow("drive") << QFileIconProvider::Drive;
|
||||
QTest::newRow("folder") << QFileIconProvider::Folder;
|
||||
QTest::newRow("file") << QFileIconProvider::File;
|
||||
}
|
||||
|
||||
// public QIcon icon(QFileIconProvider::IconType const& type) const
|
||||
void tst_QFileIconProvider::iconType()
|
||||
{
|
||||
QFETCH(QFileIconProvider::IconType, type);
|
||||
QFileIconProvider provider;
|
||||
QVERIFY(!provider.icon(type).isNull());
|
||||
}
|
||||
|
||||
void tst_QFileIconProvider::iconInfo_data()
|
||||
{
|
||||
QTest::addColumn<QFileInfo>("info");
|
||||
QTest::addColumn<bool>("setPath");
|
||||
|
||||
QTest::newRow("null") << QFileInfo() << false;
|
||||
QTest::newRow("drive") << QFileInfo(QDir::rootPath()) << true;
|
||||
QTest::newRow("home") << QFileInfo(QDir::homePath()) << true;
|
||||
QTest::newRow("current") << QFileInfo(QDir::currentPath()) << true;
|
||||
}
|
||||
|
||||
// public QIcon icon(QFileInfo const& info) const
|
||||
void tst_QFileIconProvider::iconInfo()
|
||||
{
|
||||
QFETCH(QFileInfo, info);
|
||||
QFETCH(bool, setPath);
|
||||
|
||||
if (setPath)
|
||||
QVERIFY(info.exists());
|
||||
QFileIconProvider provider;
|
||||
// we should always get an icon
|
||||
QVERIFY(!provider.icon(info).isNull());
|
||||
}
|
||||
|
||||
void tst_QFileIconProvider::type_data()
|
||||
{
|
||||
QTest::addColumn<QFileInfo>("info");
|
||||
// Return value is _very_ system dependent, hard to test
|
||||
// QTest::addColumn<QString>("type");
|
||||
|
||||
QTest::newRow("null") << QFileInfo();
|
||||
QTest::newRow("drive") << QFileInfo(QDir::rootPath());
|
||||
QTest::newRow("home") << QFileInfo(QDir::homePath());
|
||||
QTest::newRow("current") << QFileInfo(QDir::currentPath());
|
||||
QTest::newRow("exe") << QFileInfo(QCoreApplication::applicationFilePath());
|
||||
}
|
||||
|
||||
// public QString type(QFileInfo const& info) const
|
||||
void tst_QFileIconProvider::type()
|
||||
{
|
||||
QFETCH(QFileInfo, info);
|
||||
QFileIconProvider provider;
|
||||
QVERIFY(!provider.type(info).isEmpty());
|
||||
}
|
||||
|
||||
static QIcon getIcon()
|
||||
{
|
||||
QFileIconProvider fip;
|
||||
return fip.icon(QFileInfo(QDir::currentPath()));
|
||||
}
|
||||
|
||||
void tst_QFileIconProvider::iconPixmaps()
|
||||
{
|
||||
const QIcon &icon = getIcon();
|
||||
const auto sizes = icon.availableSizes();
|
||||
for (const QSize &size : sizes) {
|
||||
QPixmap pixmap = icon.pixmap(size);
|
||||
QVERIFY(!pixmap.isNull());
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QFileIconProvider)
|
||||
#include "tst_qfileiconprovider.moc"
|
||||
|
3
tests/auto/widgets/itemviews/qheaderview/BLACKLIST
Normal file
3
tests/auto/widgets/itemviews/qheaderview/BLACKLIST
Normal file
@ -0,0 +1,3 @@
|
||||
# QTBUG-87406
|
||||
[stretchAndRestoreLastSection]
|
||||
android
|
17
tests/auto/widgets/itemviews/qheaderview/CMakeLists.txt
Normal file
17
tests/auto/widgets/itemviews/qheaderview/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qheaderview Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qheaderview
|
||||
SOURCES
|
||||
tst_qheaderview.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
3654
tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
Normal file
3654
tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2
tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST
Normal file
2
tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST
Normal file
@ -0,0 +1,2 @@
|
||||
[editorKeyPress]
|
||||
ubuntu-20.04
|
23
tests/auto/widgets/itemviews/qitemdelegate/CMakeLists.txt
Normal file
23
tests/auto/widgets/itemviews/qitemdelegate/CMakeLists.txt
Normal file
@ -0,0 +1,23 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qitemdelegate Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qitemdelegate
|
||||
SOURCES
|
||||
tst_qitemdelegate.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_extend_target(tst_qitemdelegate CONDITION WIN32
|
||||
LIBRARIES
|
||||
user32
|
||||
)
|
1712
tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
Normal file
1712
tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qitemeditorfactory Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qitemeditorfactory
|
||||
SOURCES
|
||||
tst_qitemeditorfactory.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
@ -0,0 +1,88 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QItemEditorFactory>
|
||||
#include <QTest>
|
||||
|
||||
class tst_QItemEditorFactory: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void createEditor();
|
||||
void createCustomEditor();
|
||||
void uintValues();
|
||||
};
|
||||
|
||||
void tst_QItemEditorFactory::createEditor()
|
||||
{
|
||||
const QItemEditorFactory *factory = QItemEditorFactory::defaultFactory();
|
||||
|
||||
QWidget parent;
|
||||
|
||||
QWidget *w = factory->createEditor(QMetaType::QString, &parent);
|
||||
QCOMPARE(w->metaObject()->className(), "QExpandingLineEdit");
|
||||
}
|
||||
|
||||
//we make it inherit from QObject so that we can use QPointer
|
||||
class MyEditor : public QObject, public QStandardItemEditorCreator<QDoubleSpinBox>
|
||||
{
|
||||
};
|
||||
|
||||
void tst_QItemEditorFactory::createCustomEditor()
|
||||
{
|
||||
QPointer<MyEditor> creator = new MyEditor;
|
||||
QPointer<MyEditor> creator2 = new MyEditor;
|
||||
|
||||
{
|
||||
QItemEditorFactory editorFactory;
|
||||
|
||||
editorFactory.registerEditor(QMetaType::QRect, creator);
|
||||
editorFactory.registerEditor(QMetaType::QRectF, creator);
|
||||
|
||||
//creator should not be deleted as a result of calling the next line
|
||||
editorFactory.registerEditor(QMetaType::QRect, creator2);
|
||||
QVERIFY(creator);
|
||||
|
||||
//this should erase creator2
|
||||
editorFactory.registerEditor(QMetaType::QRect, creator);
|
||||
QVERIFY(creator2.isNull());
|
||||
|
||||
|
||||
QWidget parent;
|
||||
|
||||
QWidget *w = editorFactory.createEditor(QMetaType::QRect, &parent);
|
||||
QCOMPARE(w->metaObject()->className(), "QDoubleSpinBox");
|
||||
QCOMPARE(w->metaObject()->userProperty().userType(), QMetaType::Double);
|
||||
}
|
||||
|
||||
//editorFactory has been deleted, so should be creator
|
||||
//because editorFActory has the ownership
|
||||
QVERIFY(creator.isNull());
|
||||
QVERIFY(creator2.isNull());
|
||||
|
||||
delete creator;
|
||||
}
|
||||
|
||||
void tst_QItemEditorFactory::uintValues()
|
||||
{
|
||||
QItemEditorFactory editorFactory;
|
||||
|
||||
QWidget parent;
|
||||
|
||||
{
|
||||
QWidget *editor = editorFactory.createEditor(QMetaType::UInt, &parent);
|
||||
QCOMPARE(editor->metaObject()->className(), "QUIntSpinBox");
|
||||
QCOMPARE(editor->metaObject()->userProperty().userType(), QMetaType::UInt);
|
||||
}
|
||||
{
|
||||
QWidget *editor = editorFactory.createEditor(QMetaType::Int, &parent);
|
||||
QCOMPARE(editor->metaObject()->className(), "QSpinBox");
|
||||
QCOMPARE(editor->metaObject()->userProperty().userType(), QMetaType::Int);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QItemEditorFactory)
|
||||
#include "tst_qitemeditorfactory.moc"
|
||||
|
14
tests/auto/widgets/itemviews/qitemview/CMakeLists.txt
Normal file
14
tests/auto/widgets/itemviews/qitemview/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qitemview Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qitemview
|
||||
SOURCES
|
||||
tst_qitemview.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
804
tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp
Normal file
804
tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp
Normal file
@ -0,0 +1,804 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QRandomGenerator>
|
||||
#include <QStack>
|
||||
#include <QStandardItemModel>
|
||||
#include <QTest>
|
||||
#include "viewstotest.cpp"
|
||||
|
||||
/*!
|
||||
See viewstotest.cpp for instructions on how to have your view tested with these tests.
|
||||
|
||||
Each test such as visualRect have a _data() function which populate the QTest data with
|
||||
tests specified by viewstotest.cpp and any extra data needed for that particular test.
|
||||
|
||||
setupWithNoTestData() fills QTest data with only the tests it is used by most tests.
|
||||
|
||||
There are some basic qDebug statements sprikled about that might be helpfull for
|
||||
fixing your issues.
|
||||
*/
|
||||
class tst_QItemView : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
void nonDestructiveBasicTest_data();
|
||||
void nonDestructiveBasicTest();
|
||||
|
||||
void spider_data();
|
||||
void spider();
|
||||
|
||||
void resize_data();
|
||||
void resize();
|
||||
|
||||
void visualRect_data();
|
||||
void visualRect();
|
||||
|
||||
void indexAt_data();
|
||||
void indexAt();
|
||||
|
||||
void scrollTo_data();
|
||||
void scrollTo();
|
||||
|
||||
void moveCursor_data();
|
||||
void moveCursor();
|
||||
|
||||
private:
|
||||
void setupWithNoTestData();
|
||||
void populate();
|
||||
void walkScreen(QAbstractItemView *view);
|
||||
|
||||
QAbstractItemView *view;
|
||||
QAbstractItemModel *treeModel;
|
||||
ViewsToTest *testViews;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Views should not make invalid requests, sense a model might not check all the bad cases.
|
||||
*/
|
||||
class CheckerModel : public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using QStandardItemModel::QStandardItemModel;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
qWarning("%s: index is not valid", Q_FUNC_INFO);
|
||||
return QVariant();
|
||||
}
|
||||
return QStandardItemModel::data(index, role);
|
||||
}
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
qWarning("%s: index is not valid", Q_FUNC_INFO);
|
||||
return Qt::ItemFlags();
|
||||
}
|
||||
if (index.row() == 2 || index.row() == rowCount() - 3
|
||||
|| index.column() == 2 || index.column() == columnCount() - 3) {
|
||||
Qt::ItemFlags f = QStandardItemModel::flags(index);
|
||||
f.setFlag(Qt::ItemIsEnabled, false);
|
||||
return f;
|
||||
}
|
||||
return QStandardItemModel::flags(index);
|
||||
}
|
||||
|
||||
QModelIndex parent(const QModelIndex &child) const override
|
||||
{
|
||||
if (!child.isValid()) {
|
||||
qWarning("%s: child index is not valid", Q_FUNC_INFO);
|
||||
return QModelIndex();
|
||||
}
|
||||
return QStandardItemModel::parent(child);
|
||||
}
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override
|
||||
{
|
||||
if (orientation == Qt::Horizontal
|
||||
&& (section < 0 || section > columnCount())) {
|
||||
qWarning("%s: invalid section %d, must be in range 0..%d",
|
||||
Q_FUNC_INFO, section, columnCount());
|
||||
return QVariant();
|
||||
}
|
||||
if (orientation == Qt::Vertical
|
||||
&& (section < 0 || section > rowCount())) {
|
||||
qWarning("%s: invalid section %d, must be in range 0..%d",
|
||||
Q_FUNC_INFO, section, rowCount());
|
||||
return QVariant();
|
||||
}
|
||||
return QStandardItemModel::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
bool setData(const QModelIndex &index, const QVariant &value,
|
||||
int role = Qt::EditRole) override
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
qWarning("%s: index is not valid", Q_FUNC_INFO);
|
||||
return false;
|
||||
}
|
||||
return QStandardItemModel::setData(index, value, role);
|
||||
}
|
||||
|
||||
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override
|
||||
{
|
||||
if (column < 0 || column > columnCount())
|
||||
qWarning("%s: invalid column %d, must be in range 0..%d",
|
||||
Q_FUNC_INFO, column, columnCount());
|
||||
else
|
||||
QStandardItemModel::sort(column, order);
|
||||
}
|
||||
|
||||
QModelIndexList match(const QModelIndex &start, int role,
|
||||
const QVariant &value, int hits = 1,
|
||||
Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith | Qt::MatchWrap)) const override
|
||||
{
|
||||
if (hits <= 0) {
|
||||
qWarning("%s: hits must be greater than zero", Q_FUNC_INFO);
|
||||
return QModelIndexList();
|
||||
}
|
||||
if (!value.isValid()) {
|
||||
qWarning("%s: value is not valid", Q_FUNC_INFO);
|
||||
return QModelIndexList();
|
||||
}
|
||||
return QAbstractItemModel::match(start, role, value, hits, flags);
|
||||
}
|
||||
|
||||
bool setHeaderData(int section, Qt::Orientation orientation,
|
||||
const QVariant &value, int role = Qt::EditRole) override
|
||||
{
|
||||
if (orientation == Qt::Horizontal
|
||||
&& (section < 0 || section > columnCount())) {
|
||||
qWarning("%s: invalid section %d, must be in range 0..%d",
|
||||
Q_FUNC_INFO, section, columnCount());
|
||||
return false;
|
||||
}
|
||||
if (orientation == Qt::Vertical
|
||||
&& (section < 0 || section > rowCount())) {
|
||||
qWarning("%s: invalid section %d, must be in range 0..%d",
|
||||
Q_FUNC_INFO, section, rowCount());
|
||||
return false;
|
||||
}
|
||||
return QAbstractItemModel::setHeaderData(section, orientation, value, role);
|
||||
}
|
||||
};
|
||||
|
||||
void tst_QItemView::init()
|
||||
{
|
||||
testViews = new ViewsToTest();
|
||||
populate();
|
||||
}
|
||||
|
||||
void tst_QItemView::cleanup()
|
||||
{
|
||||
delete testViews;
|
||||
delete view;
|
||||
delete treeModel;
|
||||
view = nullptr;
|
||||
testViews = nullptr;
|
||||
treeModel = nullptr;
|
||||
}
|
||||
|
||||
void tst_QItemView::setupWithNoTestData()
|
||||
{
|
||||
ViewsToTest testViews;
|
||||
QTest::addColumn<QString>("viewType");
|
||||
QTest::addColumn<bool>("displays");
|
||||
QTest::addColumn<QAbstractItemView::ScrollMode>("vscroll");
|
||||
QTest::addColumn<QAbstractItemView::ScrollMode>("hscroll");
|
||||
for (int i = 0; i < testViews.tests.size(); ++i) {
|
||||
QString view = testViews.tests.at(i).viewType;
|
||||
QString test = view + " ScrollPerPixel";
|
||||
bool displayIndexes = (testViews.tests.at(i).display == ViewsToTest::DisplayRoot);
|
||||
QTest::newRow(test.toLatin1().data()) << view << displayIndexes
|
||||
<< QAbstractItemView::ScrollPerPixel
|
||||
<< QAbstractItemView::ScrollPerPixel
|
||||
;
|
||||
}
|
||||
for (int i = 0; i < testViews.tests.size(); ++i) {
|
||||
QString view = testViews.tests.at(i).viewType;
|
||||
QString test = view + " ScrollPerItem";
|
||||
bool displayIndexes = (testViews.tests.at(i).display == ViewsToTest::DisplayRoot);
|
||||
QTest::newRow(test.toLatin1().data()) << view << displayIndexes
|
||||
<< QAbstractItemView::ScrollPerItem
|
||||
<< QAbstractItemView::ScrollPerItem
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QItemView::populate()
|
||||
{
|
||||
treeModel = new CheckerModel;
|
||||
QModelIndex parent;
|
||||
#if defined(Q_PROCESSOR_ARM)
|
||||
const int baseInsert = 4;
|
||||
#else
|
||||
const int baseInsert = 26;
|
||||
#endif
|
||||
for (int i = 0; i < 40; ++i) {
|
||||
const QString iS = QString::number(i);
|
||||
parent = treeModel->index(0, 0, parent);
|
||||
treeModel->insertRows(0, baseInsert + i, parent);
|
||||
treeModel->insertColumns(0, baseInsert + i, parent);
|
||||
// Fill in some values to make it easier to debug
|
||||
for (int x = 0; x < treeModel->rowCount(); ++x) {
|
||||
const QString xS = QString::number(x);
|
||||
for (int y = 0; y < treeModel->columnCount(); ++y) {
|
||||
QModelIndex index = treeModel->index(x, y, parent);
|
||||
treeModel->setData(index, xS + QLatin1Char('_') + QString::number(y) + QLatin1Char('_') + iS);
|
||||
treeModel->setData(index, QVariant(QColor(Qt::blue)), Qt::ForegroundRole);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QItemView::nonDestructiveBasicTest_data()
|
||||
{
|
||||
setupWithNoTestData();
|
||||
}
|
||||
|
||||
/*!
|
||||
nonDestructiveBasicTest tries to call a number of the basic functions (not all)
|
||||
to make sure the view doesn't segfault, testing the functions that makes sense.
|
||||
*/
|
||||
void tst_QItemView::nonDestructiveBasicTest()
|
||||
{
|
||||
QFETCH(QString, viewType);
|
||||
QFETCH(QAbstractItemView::ScrollMode, vscroll);
|
||||
QFETCH(QAbstractItemView::ScrollMode, hscroll);
|
||||
|
||||
view = testViews->createView(viewType);
|
||||
QVERIFY(view);
|
||||
view->setVerticalScrollMode(vscroll);
|
||||
view->setHorizontalScrollMode(hscroll);
|
||||
|
||||
// setSelectionModel() will assert
|
||||
//view->setSelectionModel(0);
|
||||
// setItemDelegate() will assert
|
||||
//view->setItemDelegate(0);
|
||||
|
||||
// setSelectionMode
|
||||
view->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
QCOMPARE(view->selectionMode(), QAbstractItemView::SingleSelection);
|
||||
view->setSelectionMode(QAbstractItemView::ContiguousSelection);
|
||||
QCOMPARE(view->selectionMode(), QAbstractItemView::ContiguousSelection);
|
||||
view->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
QCOMPARE(view->selectionMode(), QAbstractItemView::ExtendedSelection);
|
||||
view->setSelectionMode(QAbstractItemView::MultiSelection);
|
||||
QCOMPARE(view->selectionMode(), QAbstractItemView::MultiSelection);
|
||||
view->setSelectionMode(QAbstractItemView::NoSelection);
|
||||
QCOMPARE(view->selectionMode(), QAbstractItemView::NoSelection);
|
||||
|
||||
// setSelectionBehavior
|
||||
view->setSelectionBehavior(QAbstractItemView::SelectItems);
|
||||
QCOMPARE(view->selectionBehavior(), QAbstractItemView::SelectItems);
|
||||
view->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
QCOMPARE(view->selectionBehavior(), QAbstractItemView::SelectRows);
|
||||
view->setSelectionBehavior(QAbstractItemView::SelectColumns);
|
||||
QCOMPARE(view->selectionBehavior(), QAbstractItemView::SelectColumns);
|
||||
|
||||
// setEditTriggers
|
||||
view->setEditTriggers(QAbstractItemView::EditKeyPressed);
|
||||
QCOMPARE(view->editTriggers(), QAbstractItemView::EditKeyPressed);
|
||||
view->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
QCOMPARE(view->editTriggers(), QAbstractItemView::NoEditTriggers);
|
||||
view->setEditTriggers(QAbstractItemView::CurrentChanged);
|
||||
QCOMPARE(view->editTriggers(), QAbstractItemView::CurrentChanged);
|
||||
view->setEditTriggers(QAbstractItemView::DoubleClicked);
|
||||
QCOMPARE(view->editTriggers(), QAbstractItemView::DoubleClicked);
|
||||
view->setEditTriggers(QAbstractItemView::SelectedClicked);
|
||||
QCOMPARE(view->editTriggers(), QAbstractItemView::SelectedClicked);
|
||||
view->setEditTriggers(QAbstractItemView::AnyKeyPressed);
|
||||
QCOMPARE(view->editTriggers(), QAbstractItemView::AnyKeyPressed);
|
||||
view->setEditTriggers(QAbstractItemView::AllEditTriggers);
|
||||
QCOMPARE(view->editTriggers(), QAbstractItemView::AllEditTriggers);
|
||||
|
||||
// setAutoScroll
|
||||
view->setAutoScroll(false);
|
||||
QCOMPARE(view->hasAutoScroll(), false);
|
||||
view->setAutoScroll(true);
|
||||
QCOMPARE(view->hasAutoScroll(), true);
|
||||
|
||||
// setTabKeyNavigation
|
||||
view->setTabKeyNavigation(false);
|
||||
QCOMPARE(view->tabKeyNavigation(), false);
|
||||
view->setTabKeyNavigation(true);
|
||||
QCOMPARE(view->tabKeyNavigation(), true);
|
||||
#if QT_CONFIG(draganddrop)
|
||||
// setDropIndicatorShown
|
||||
view->setDropIndicatorShown(false);
|
||||
QCOMPARE(view->showDropIndicator(), false);
|
||||
view->setDropIndicatorShown(true);
|
||||
QCOMPARE(view->showDropIndicator(), true);
|
||||
|
||||
// setDragEnabled
|
||||
view->setDragEnabled(false);
|
||||
QCOMPARE(view->dragEnabled(), false);
|
||||
view->setDragEnabled(true);
|
||||
QCOMPARE(view->dragEnabled(), true);
|
||||
#endif
|
||||
|
||||
// setAlternatingRowColors
|
||||
view->setAlternatingRowColors(false);
|
||||
QCOMPARE(view->alternatingRowColors(), false);
|
||||
view->setAlternatingRowColors(true);
|
||||
QCOMPARE(view->alternatingRowColors(), true);
|
||||
|
||||
// setIconSize
|
||||
view->setIconSize(QSize(16, 16));
|
||||
QCOMPARE(view->iconSize(), QSize(16, 16));
|
||||
view->setIconSize(QSize(32, 32));
|
||||
QCOMPARE(view->iconSize(), QSize(32, 32));
|
||||
// Should this happen?
|
||||
view->setIconSize(QSize(-1, -1));
|
||||
QCOMPARE(view->iconSize(), QSize(-1, -1));
|
||||
|
||||
QCOMPARE(view->currentIndex(), QModelIndex());
|
||||
QCOMPARE(view->rootIndex(), QModelIndex());
|
||||
|
||||
view->keyboardSearch("");
|
||||
view->keyboardSearch("foo");
|
||||
view->keyboardSearch("1");
|
||||
|
||||
QCOMPARE(view->visualRect(QModelIndex()), QRect());
|
||||
|
||||
view->scrollTo(QModelIndex());
|
||||
|
||||
QCOMPARE(view->sizeHintForIndex(QModelIndex()), QSize());
|
||||
QCOMPARE(view->indexAt(QPoint(-1, -1)), QModelIndex());
|
||||
|
||||
if (!view->model()){
|
||||
QCOMPARE(view->indexAt(QPoint(10, 10)), QModelIndex());
|
||||
QCOMPARE(view->sizeHintForRow(0), -1);
|
||||
QCOMPARE(view->sizeHintForColumn(0), -1);
|
||||
} else if (view->itemDelegate()){
|
||||
view->sizeHintForRow(0);
|
||||
view->sizeHintForColumn(0);
|
||||
}
|
||||
view->openPersistentEditor(QModelIndex());
|
||||
view->closePersistentEditor(QModelIndex());
|
||||
|
||||
view->reset();
|
||||
view->setRootIndex(QModelIndex());
|
||||
view->doItemsLayout();
|
||||
view->selectAll();
|
||||
// edit() causes warning by default
|
||||
//view->edit(QModelIndex());
|
||||
view->clearSelection();
|
||||
view->setCurrentIndex(QModelIndex());
|
||||
}
|
||||
|
||||
void tst_QItemView::spider_data()
|
||||
{
|
||||
setupWithNoTestData();
|
||||
}
|
||||
|
||||
void touch(QWidget *widget, Qt::KeyboardModifier modifier, Qt::Key keyPress)
|
||||
{
|
||||
int width = widget->width();
|
||||
int height = widget->height();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
QTest::mouseClick(widget, Qt::LeftButton, modifier,
|
||||
QPoint(QRandomGenerator::global()->bounded(width), QRandomGenerator::global()->bounded(height)));
|
||||
QTest::mouseDClick(widget, Qt::LeftButton, modifier,
|
||||
QPoint(QRandomGenerator::global()->bounded(width), QRandomGenerator::global()->bounded(height)));
|
||||
QPoint press(QRandomGenerator::global()->bounded(width), QRandomGenerator::global()->bounded(height));
|
||||
QPoint releasePoint(QRandomGenerator::global()->bounded(width), QRandomGenerator::global()->bounded(height));
|
||||
QTest::mousePress(widget, Qt::LeftButton, modifier, press);
|
||||
QTest::mouseMove(widget, releasePoint);
|
||||
if (QRandomGenerator::global()->bounded(1) == 0)
|
||||
QTest::mouseRelease(widget, Qt::LeftButton, {}, releasePoint);
|
||||
else
|
||||
QTest::mouseRelease(widget, Qt::LeftButton, modifier, releasePoint);
|
||||
QTest::keyClick(widget, keyPress);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
This is a basic stress testing application that tries a few basics such as clicking around
|
||||
the screen, and key presses.
|
||||
|
||||
The main goal is to catch any easy segfaults, not to test every case.
|
||||
*/
|
||||
void tst_QItemView::spider()
|
||||
{
|
||||
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
|
||||
QSKIP("Wayland: This fails. Figure out why.");
|
||||
|
||||
QFETCH(QString, viewType);
|
||||
QFETCH(QAbstractItemView::ScrollMode, vscroll);
|
||||
QFETCH(QAbstractItemView::ScrollMode, hscroll);
|
||||
|
||||
view = testViews->createView(viewType);
|
||||
QVERIFY(view);
|
||||
view->setVerticalScrollMode(vscroll);
|
||||
view->setHorizontalScrollMode(hscroll);
|
||||
view->setModel(treeModel);
|
||||
view->show();
|
||||
QVERIFY(QTest::qWaitForWindowActive(view));
|
||||
touch(view->viewport(), Qt::NoModifier, Qt::Key_Left);
|
||||
touch(view->viewport(), Qt::ShiftModifier, Qt::Key_Enter);
|
||||
touch(view->viewport(), Qt::ControlModifier, Qt::Key_Backspace);
|
||||
touch(view->viewport(), Qt::AltModifier, Qt::Key_Up);
|
||||
}
|
||||
|
||||
void tst_QItemView::resize_data()
|
||||
{
|
||||
setupWithNoTestData();
|
||||
}
|
||||
|
||||
/*!
|
||||
The main goal is to catch any infinite loops from layouting
|
||||
*/
|
||||
void tst_QItemView::resize()
|
||||
{
|
||||
QSKIP("This test needs to be re-thought out, it takes too long and doesn't really catch the problem.");
|
||||
|
||||
QFETCH(QString, viewType);
|
||||
QFETCH(QAbstractItemView::ScrollMode, vscroll);
|
||||
QFETCH(QAbstractItemView::ScrollMode, hscroll);
|
||||
|
||||
view = testViews->createView(viewType);
|
||||
QVERIFY(view);
|
||||
view->setVerticalScrollMode(vscroll);
|
||||
view->setHorizontalScrollMode(hscroll);
|
||||
view->setModel(treeModel);
|
||||
view->show();
|
||||
|
||||
for (int w = 100; w < 400; w += 10) {
|
||||
for (int h = 100; h < 400; h += 10) {
|
||||
view->resize(w, h);
|
||||
QTest::qWait(1);
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QItemView::visualRect_data()
|
||||
{
|
||||
setupWithNoTestData();
|
||||
}
|
||||
|
||||
void tst_QItemView::visualRect()
|
||||
{
|
||||
QFETCH(QString, viewType);
|
||||
QFETCH(QAbstractItemView::ScrollMode, vscroll);
|
||||
QFETCH(QAbstractItemView::ScrollMode, hscroll);
|
||||
|
||||
view = testViews->createView(viewType);
|
||||
QVERIFY(view);
|
||||
view->setVerticalScrollMode(vscroll);
|
||||
view->setHorizontalScrollMode(hscroll);
|
||||
QCOMPARE(view->visualRect(QModelIndex()), QRect());
|
||||
|
||||
// Add model
|
||||
view->setModel(treeModel);
|
||||
QCOMPARE(view->visualRect(QModelIndex()), QRect());
|
||||
|
||||
QModelIndex topIndex = treeModel->index(0,0);
|
||||
|
||||
QFETCH(bool, displays);
|
||||
if (!displays){
|
||||
QCOMPARE(view->visualRect(topIndex), QRect());
|
||||
return;
|
||||
}
|
||||
|
||||
QVERIFY(view->visualRect(topIndex) != QRect());
|
||||
view->show();
|
||||
QVERIFY(view->visualRect(topIndex) != QRect());
|
||||
|
||||
QCOMPARE(topIndex, view->indexAt(view->visualRect(topIndex).center()));
|
||||
QCOMPARE(topIndex, view->indexAt(view->visualRect(topIndex).bottomLeft()));
|
||||
QCOMPARE(topIndex, view->indexAt(view->visualRect(topIndex).bottomRight()));
|
||||
QCOMPARE(topIndex, view->indexAt(view->visualRect(topIndex).topLeft()));
|
||||
QCOMPARE(topIndex, view->indexAt(view->visualRect(topIndex).topRight()));
|
||||
|
||||
testViews->hideIndexes(view);
|
||||
QModelIndex hiddenIndex = treeModel->index(1, 0);
|
||||
QCOMPARE(view->visualRect(hiddenIndex), QRect());
|
||||
}
|
||||
|
||||
void tst_QItemView::walkScreen(QAbstractItemView *view)
|
||||
{
|
||||
QModelIndex hiddenIndex = view->model() ? view->model()->index(1, 0) : QModelIndex();
|
||||
int width = view->width();
|
||||
int height = view->height();
|
||||
for (int w = 0; w < width; ++w)
|
||||
{
|
||||
for (int h = 0; h < height; ++h)
|
||||
{
|
||||
QPoint point(w, h);
|
||||
QModelIndex index = view->indexAt(point);
|
||||
|
||||
// If we have no model then we should *never* get a valid index
|
||||
if (!view->model() || !view->isVisible())
|
||||
QVERIFY(!index.isValid());
|
||||
// index should not be the hidden one
|
||||
if (hiddenIndex.isValid())
|
||||
QVERIFY(hiddenIndex != index);
|
||||
// If we are valid then check the visualRect for that index
|
||||
if (index.isValid()){
|
||||
QRect visualRect = view->visualRect(index);
|
||||
if (!visualRect.contains(point))
|
||||
qDebug() << point << visualRect;
|
||||
QVERIFY(visualRect.contains(point));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void walkIndex(const QModelIndex &index, const QAbstractItemView *view)
|
||||
{
|
||||
const QRect visualRect = view->visualRect(index);
|
||||
const int width = visualRect.width();
|
||||
const int height = visualRect.height();
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
const auto widths = (width < 2) ? QList<int>({ 0, 1 })
|
||||
: QList<int>({ 0, 1, width / 2, width - 2, width - 1 });
|
||||
const auto heights = (height < 2) ? QList<int>({ 0, 1 })
|
||||
: QList<int>({ 0, 1, height / 2, height - 2, height - 1 });
|
||||
for (int w : widths)
|
||||
{
|
||||
for (int h : heights)
|
||||
{
|
||||
const QPoint point(visualRect.x() + w, visualRect.y() + h);
|
||||
const auto idxAt = view->indexAt(point);
|
||||
if (idxAt != index)
|
||||
qDebug() << "index" << index << "visualRect" << visualRect << point << view->indexAt(point);
|
||||
QCOMPARE(idxAt, index);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
A model that returns an index of parent X should also return X when asking
|
||||
for the parent of the index.
|
||||
|
||||
This recursive function does pretty extensive testing on the whole model in an
|
||||
effort to catch edge cases.
|
||||
|
||||
This function assumes that rowCount(), columnCount() and index() work. If they have
|
||||
a bug it will point it out, but the above tests should have already found the basic bugs
|
||||
because it is easier to figure out the problem in those tests then this one.
|
||||
*/
|
||||
void checkChildren(const QAbstractItemView *currentView, const QModelIndex &parent = QModelIndex(), int currentDepth = 0)
|
||||
{
|
||||
QAbstractItemModel *currentModel = currentView->model();
|
||||
|
||||
int rows = currentModel->rowCount(parent);
|
||||
int columns = currentModel->columnCount(parent);
|
||||
|
||||
for (int r = 0; r < rows; ++r) {
|
||||
for (int c = 0; c < columns; ++c) {
|
||||
QModelIndex index = currentModel->index(r, c, parent);
|
||||
walkIndex(index, currentView);
|
||||
if (QTest::currentTestFailed())
|
||||
return;
|
||||
|
||||
// recursivly go down
|
||||
if (currentModel->hasChildren(index) && currentDepth < 2) {
|
||||
checkChildren(currentView, index, ++currentDepth);
|
||||
// Because this is recursive we will return at the first failure rather then
|
||||
// reporting it over and over
|
||||
if (QTest::currentTestFailed())
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void tst_QItemView::indexAt_data()
|
||||
{
|
||||
setupWithNoTestData();
|
||||
}
|
||||
|
||||
void tst_QItemView::indexAt()
|
||||
{
|
||||
QFETCH(QString, viewType);
|
||||
QFETCH(QAbstractItemView::ScrollMode, vscroll);
|
||||
QFETCH(QAbstractItemView::ScrollMode, hscroll);
|
||||
|
||||
view = testViews->createView(viewType);
|
||||
QVERIFY(view);
|
||||
view->setVerticalScrollMode(vscroll);
|
||||
view->setHorizontalScrollMode(hscroll);
|
||||
view->show();
|
||||
view->setModel(treeModel);
|
||||
checkChildren(view);
|
||||
|
||||
QModelIndex index = view->model()->index(0, 0);
|
||||
while (view->model()->hasChildren(index))
|
||||
index = view->model()->index(0, 0, index);
|
||||
QCOMPARE(view->model()->hasChildren(index), false);
|
||||
QVERIFY(index.isValid());
|
||||
view->setRootIndex(index);
|
||||
//qDebug() << view->indexAt(QPoint(view->width()/2, view->height()/2)) << view->rootIndex();
|
||||
QPoint p(1, view->height()/2);
|
||||
QModelIndex idx = view->indexAt(p);
|
||||
QCOMPARE(idx, QModelIndex());
|
||||
}
|
||||
|
||||
void tst_QItemView::scrollTo_data()
|
||||
{
|
||||
setupWithNoTestData();
|
||||
}
|
||||
|
||||
void tst_QItemView::scrollTo()
|
||||
{
|
||||
QFETCH(QString, viewType);
|
||||
QFETCH(QAbstractItemView::ScrollMode, vscroll);
|
||||
QFETCH(QAbstractItemView::ScrollMode, hscroll);
|
||||
|
||||
view = testViews->createView(viewType);
|
||||
QVERIFY(view);
|
||||
view->setVerticalScrollMode(vscroll);
|
||||
view->setHorizontalScrollMode(hscroll);
|
||||
view->setModel(treeModel);
|
||||
view->show();
|
||||
|
||||
QModelIndex parent;
|
||||
for (int row = 0; row < treeModel->rowCount(parent); ++row) {
|
||||
for (int column = 0; column < treeModel->columnCount(parent); ++column) {
|
||||
QModelIndex idx = treeModel->index(row, column, parent);
|
||||
view->scrollTo(idx);
|
||||
QRect rect = view->visualRect(idx);
|
||||
view->scrollTo(idx);
|
||||
QCOMPARE(rect, view->visualRect(idx));
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex idx = treeModel->index(0, 0, parent);
|
||||
view->scrollTo(idx);
|
||||
QRect rect = view->visualRect(idx);
|
||||
view->scrollToBottom();
|
||||
view->scrollTo(idx);
|
||||
QCOMPARE(rect, view->visualRect(idx));
|
||||
}
|
||||
|
||||
void tst_QItemView::moveCursor_data()
|
||||
{
|
||||
setupWithNoTestData();
|
||||
}
|
||||
|
||||
struct Event
|
||||
{
|
||||
Event(Qt::Key k, const QModelIndex &s, const QModelIndex &e, const QString &n)
|
||||
: key(k), start(s), end(e), name(n){}
|
||||
Qt::Key key;
|
||||
QModelIndex start;
|
||||
QModelIndex end;
|
||||
QString name;
|
||||
};
|
||||
|
||||
|
||||
void tst_QItemView::moveCursor()
|
||||
{
|
||||
QFETCH(QString, viewType);
|
||||
view = testViews->createView(viewType);
|
||||
QVERIFY(view);
|
||||
if (view->objectName() == "QHeaderView")
|
||||
return;
|
||||
|
||||
view->setModel(treeModel);
|
||||
testViews->hideIndexes(view);
|
||||
view->resize(100, 100);
|
||||
|
||||
QModelIndex invalidIndex = QModelIndex();
|
||||
QModelIndex firstRow = treeModel->index(0, 0);
|
||||
QModelIndex hiddenRowT = treeModel->index(1, 0);
|
||||
QModelIndex disabledRowT = treeModel->index(2, 0);
|
||||
QModelIndex secondRow = treeModel->index(3, 0);
|
||||
|
||||
QModelIndex secondToLastRow = treeModel->index(treeModel->rowCount() - 4, 0);
|
||||
QModelIndex disabledRowB = treeModel->index(treeModel->rowCount() - 3, 0);
|
||||
QModelIndex hiddenRowB = treeModel->index(treeModel->rowCount() - 2, 0);
|
||||
QModelIndex lastRow = treeModel->index(treeModel->rowCount() - 1, 0);
|
||||
|
||||
QStack<Event> events;
|
||||
|
||||
events.push(Event(Qt::Key_Up, invalidIndex, firstRow, "inv, first"));
|
||||
events.push(Event(Qt::Key_Up, hiddenRowT, firstRow, "hid, first"));
|
||||
events.push(Event(Qt::Key_Up, disabledRowT, firstRow, "dis, first"));
|
||||
events.push(Event(Qt::Key_Up, firstRow, firstRow, "first, first"));
|
||||
events.push(Event(Qt::Key_Up, secondRow, firstRow, "sec, first"));
|
||||
events.push(Event(Qt::Key_Up, hiddenRowB, firstRow, "hidB, first"));
|
||||
events.push(Event(Qt::Key_Up, disabledRowB, secondToLastRow, "disB, secLast"));
|
||||
events.push(Event(Qt::Key_Up, lastRow, secondToLastRow, "last, secLast"));
|
||||
|
||||
events.push(Event(Qt::Key_Down, invalidIndex, firstRow, "inv, first"));
|
||||
events.push(Event(Qt::Key_Down, hiddenRowT, firstRow, "hid, first"));
|
||||
events.push(Event(Qt::Key_Down, disabledRowT, secondRow, "dis, sec"));
|
||||
events.push(Event(Qt::Key_Down, firstRow, secondRow, "first, sec"));
|
||||
events.push(Event(Qt::Key_Down, secondToLastRow, lastRow, "secLast, last" ));
|
||||
events.push(Event(Qt::Key_Down, disabledRowB, lastRow, "disB, last"));
|
||||
events.push(Event(Qt::Key_Down, hiddenRowB, firstRow, "hidB, first"));
|
||||
events.push(Event(Qt::Key_Down, lastRow, lastRow, "last, last"));
|
||||
|
||||
events.push(Event(Qt::Key_Home, invalidIndex, firstRow, "inv, first"));
|
||||
events.push(Event(Qt::Key_End, invalidIndex, firstRow, "inv, first"));
|
||||
|
||||
if (view->objectName() == "QTableView") {
|
||||
// In a table we move to the first/last column
|
||||
events.push(Event(Qt::Key_Home, hiddenRowT, firstRow, "hid, first"));
|
||||
events.push(Event(Qt::Key_Home, disabledRowT, disabledRowT, "dis, dis"));
|
||||
events.push(Event(Qt::Key_Home, firstRow, firstRow, "first, first"));
|
||||
events.push(Event(Qt::Key_Home, secondRow, secondRow, "sec, sec"));
|
||||
events.push(Event(Qt::Key_Home, disabledRowB, disabledRowB, "disB, disB"));
|
||||
events.push(Event(Qt::Key_Home, hiddenRowB, firstRow, "hidB, first"));
|
||||
events.push(Event(Qt::Key_Home, secondToLastRow, secondToLastRow, "secLast, secLast"));
|
||||
events.push(Event(Qt::Key_Home, lastRow, lastRow, "last, last"));
|
||||
|
||||
int col = treeModel->columnCount() - 1;
|
||||
events.push(Event(Qt::Key_End, hiddenRowT, firstRow, "hidT, hidT"));
|
||||
events.push(Event(Qt::Key_End, disabledRowT, disabledRowT, "disT, disT"));
|
||||
events.push(Event(Qt::Key_End, firstRow, firstRow.sibling(firstRow.row(), col), "first, first_C"));
|
||||
events.push(Event(Qt::Key_End, secondRow, secondRow.sibling(secondRow.row(), col), "sec, sec_C"));
|
||||
events.push(Event(Qt::Key_End, disabledRowB, disabledRowB, "disB, disB"));
|
||||
events.push(Event(Qt::Key_End, hiddenRowB, firstRow, "hidB, hidB"));
|
||||
events.push(Event(Qt::Key_End, secondToLastRow, secondToLastRow.sibling(secondToLastRow.row(), col), "secLast, secLast_C"));
|
||||
events.push(Event(Qt::Key_End, lastRow, lastRow.sibling(lastRow.row(), col), "last, last_C"));
|
||||
} else {
|
||||
events.push(Event(Qt::Key_Home, hiddenRowT, firstRow, "hid, first"));
|
||||
events.push(Event(Qt::Key_Home, disabledRowT, firstRow, "dis, first"));
|
||||
events.push(Event(Qt::Key_Home, firstRow, firstRow, "first, first"));
|
||||
events.push(Event(Qt::Key_Home, secondRow, firstRow, "sec, first"));
|
||||
events.push(Event(Qt::Key_Home, disabledRowB, firstRow, "disB, first"));
|
||||
events.push(Event(Qt::Key_Home, hiddenRowB, firstRow, "hidB, first"));
|
||||
events.push(Event(Qt::Key_Home, secondToLastRow, firstRow, "sec, first"));
|
||||
events.push(Event(Qt::Key_Home, lastRow, firstRow, "last, first"));
|
||||
|
||||
events.push(Event(Qt::Key_End, hiddenRowT, firstRow, "hid, last"));
|
||||
events.push(Event(Qt::Key_End, disabledRowT, lastRow, "dis, last"));
|
||||
events.push(Event(Qt::Key_End, firstRow, lastRow, "first, last"));
|
||||
events.push(Event(Qt::Key_End, secondRow, lastRow, "sec, last"));
|
||||
events.push(Event(Qt::Key_End, disabledRowB, lastRow, "disB, last"));
|
||||
events.push(Event(Qt::Key_End, hiddenRowB, firstRow, "hidB, last"));
|
||||
events.push(Event(Qt::Key_End, secondToLastRow, lastRow, "sec, last"));
|
||||
events.push(Event(Qt::Key_End, lastRow, lastRow, "last, last"));
|
||||
}
|
||||
|
||||
events.push(Event(Qt::Key_PageDown, invalidIndex, firstRow, "inv, first"));
|
||||
events.push(Event(Qt::Key_PageDown, firstRow, QModelIndex(), "first, x"));
|
||||
events.push(Event(Qt::Key_PageDown, secondRow, QModelIndex(), "sec, x"));
|
||||
events.push(Event(Qt::Key_PageDown, hiddenRowT, QModelIndex(), "hid, x"));
|
||||
events.push(Event(Qt::Key_PageDown, disabledRowT, QModelIndex(), "dis, x"));
|
||||
events.push(Event(Qt::Key_PageDown, disabledRowB, lastRow, "disB, last"));
|
||||
events.push(Event(Qt::Key_PageDown, hiddenRowB, lastRow, "hidB, last"));
|
||||
events.push(Event(Qt::Key_PageDown, secondToLastRow, lastRow, "secLast, last"));
|
||||
events.push(Event(Qt::Key_PageDown, lastRow, lastRow, "last, last"));
|
||||
|
||||
events.push(Event(Qt::Key_PageUp, invalidIndex, firstRow, "inv, first"));
|
||||
events.push(Event(Qt::Key_PageUp, firstRow, firstRow, "first, first"));
|
||||
events.push(Event(Qt::Key_PageUp, secondRow, firstRow, "sec, first"));
|
||||
events.push(Event(Qt::Key_PageUp, secondToLastRow, QModelIndex(), "secLast, x"));
|
||||
events.push(Event(Qt::Key_PageUp, lastRow, QModelIndex(), "last, x"));
|
||||
|
||||
if (view->objectName() == "QTableView") {
|
||||
events.push(Event(Qt::Key_Left, firstRow, firstRow, "first_0, first"));
|
||||
events.push(Event(Qt::Key_Left, firstRow.sibling(0, 1), firstRow, "first_1, first"));
|
||||
events.push(Event(Qt::Key_Left, firstRow.sibling(0, 2), firstRow, "first_2, first"));
|
||||
events.push(Event(Qt::Key_Left, firstRow.sibling(0, 3), firstRow, "first_3, first"));
|
||||
events.push(Event(Qt::Key_Left, secondRow, secondRow, "sec, sec"));
|
||||
|
||||
events.push(Event(Qt::Key_Right, firstRow, firstRow.sibling(0, 3), "first, first_3"));
|
||||
events.push(Event(Qt::Key_Right, firstRow.sibling(0, 1), firstRow, "first_1, first"));
|
||||
events.push(Event(Qt::Key_Right, firstRow.sibling(0, 2), firstRow.sibling(0, 3), "first_2, first_3"));
|
||||
events.push(Event(Qt::Key_Right, firstRow.sibling(0, treeModel->columnCount()-1), firstRow.sibling(0, treeModel->columnCount()-1), "first_3, sec"));
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QItemView)
|
||||
#include "tst_qitemview.moc"
|
126
tests/auto/widgets/itemviews/qitemview/viewstotest.cpp
Normal file
126
tests/auto/widgets/itemviews/qitemview/viewstotest.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QListView>
|
||||
#include <QTableView>
|
||||
#include <QTreeView>
|
||||
|
||||
/*
|
||||
To add a view to be tested add the header file to the includes
|
||||
and impliment what is needed in the functions below.
|
||||
|
||||
You can add more then one view, several Qt views are included as examples.
|
||||
|
||||
In tst_qitemview.cpp a new ViewsToTest object is created for each test.
|
||||
|
||||
When you have errors fix the first ones first. Later tests depend upon them working
|
||||
*/
|
||||
|
||||
class ViewsToTest
|
||||
{
|
||||
public:
|
||||
ViewsToTest();
|
||||
|
||||
QAbstractItemView *createView(const QString &viewType);
|
||||
void hideIndexes(QAbstractItemView *view);
|
||||
|
||||
enum Display { DisplayNone, DisplayRoot };
|
||||
|
||||
struct test {
|
||||
test(const QString &m, Display d) : viewType(m), display(d) {}
|
||||
QString viewType;
|
||||
Display display;
|
||||
};
|
||||
|
||||
QList<test> tests;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
Add new tests, they can be the same view, but in a different state.
|
||||
*/
|
||||
ViewsToTest::ViewsToTest()
|
||||
{
|
||||
tests.append(test("QTreeView_ScrollPerItem", DisplayRoot));
|
||||
tests.append(test("QTreeView_ScrollPerPixel", DisplayRoot));
|
||||
tests.append(test("QListView_ScrollPerItem", DisplayRoot));
|
||||
tests.append(test("QListView_ScrollPerPixel", DisplayRoot));
|
||||
tests.append(test("QHeaderViewHorizontal", DisplayNone));
|
||||
tests.append(test("QHeaderViewVertical", DisplayNone));
|
||||
tests.append(test("QTableView_ScrollPerItem", DisplayRoot));
|
||||
tests.append(test("QTableView_ScrollPerPixel", DisplayRoot));
|
||||
tests.append(test("QTableViewNoGrid", DisplayRoot));
|
||||
}
|
||||
|
||||
/*!
|
||||
Return a new viewType.
|
||||
*/
|
||||
QAbstractItemView *ViewsToTest::createView(const QString &viewType)
|
||||
{
|
||||
QAbstractItemView *view = nullptr;
|
||||
if (viewType == "QListView_ScrollPerItem") {
|
||||
view = new QListView();
|
||||
view->setObjectName("QListView");
|
||||
view->setHorizontalScrollMode(QAbstractItemView::ScrollPerItem);
|
||||
view->setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
|
||||
} else if (viewType == "QListView_ScrollPerPixel") {
|
||||
view = new QListView();
|
||||
view->setObjectName("QListView");
|
||||
view->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
} else if (viewType == "QHeaderViewHorizontal") {
|
||||
view = new QHeaderView(Qt::Horizontal);
|
||||
view->setObjectName("QHeaderView");
|
||||
} else if (viewType == "QHeaderViewVertical") {
|
||||
view = new QHeaderView(Qt::Vertical);
|
||||
view->setObjectName("QHeaderView");
|
||||
} else if (viewType == "QTableView_ScrollPerItem") {
|
||||
view = new QTableView();
|
||||
view->setObjectName("QTableView");
|
||||
view->setHorizontalScrollMode(QAbstractItemView::ScrollPerItem);
|
||||
view->setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
|
||||
} else if (viewType == "QTableView_ScrollPerPixel") {
|
||||
view = new QTableView();
|
||||
view->setObjectName("QTableView");
|
||||
view->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
} else if (viewType == "QTableViewNoGrid") {
|
||||
QTableView *table = new QTableView();
|
||||
table->setObjectName("QTableView");
|
||||
table->setShowGrid(false);
|
||||
view = table;
|
||||
} else if (viewType == "QTreeView_ScrollPerItem") {
|
||||
view = new QTreeView();
|
||||
view->setObjectName("QTreeView");
|
||||
view->setHorizontalScrollMode(QAbstractItemView::ScrollPerItem);
|
||||
view->setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
|
||||
view->setSelectionBehavior(QAbstractItemView::SelectItems);
|
||||
} else if (viewType == "QTreeView_ScrollPerPixel") {
|
||||
view = new QTreeView();
|
||||
view->setObjectName("QTreeView");
|
||||
view->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
view->setSelectionBehavior(QAbstractItemView::SelectItems);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
void ViewsToTest::hideIndexes(QAbstractItemView *view)
|
||||
{
|
||||
if (QTableView *tableView = qobject_cast<QTableView *>(view)) {
|
||||
tableView->setColumnHidden(1, true);
|
||||
tableView->setRowHidden(1, true);
|
||||
tableView->setRowHidden(tableView->model()->rowCount() - 2, true);
|
||||
}
|
||||
if (QTreeView *treeView = qobject_cast<QTreeView *>(view)) {
|
||||
treeView->setColumnHidden(1, true);
|
||||
treeView->setRowHidden(1, QModelIndex(), true);
|
||||
treeView->setRowHidden(treeView->model()->rowCount() - 2, QModelIndex(), true);
|
||||
}
|
||||
if (QListView *listView = qobject_cast<QListView *>(view)) {
|
||||
listView->setRowHidden(1, true);
|
||||
listView->setRowHidden(listView->model()->rowCount() - 2, true);
|
||||
}
|
||||
}
|
||||
|
3
tests/auto/widgets/itemviews/qlistview/BLACKLIST
Normal file
3
tests/auto/widgets/itemviews/qlistview/BLACKLIST
Normal file
@ -0,0 +1,3 @@
|
||||
# QTBUG-94250
|
||||
[internalDragDropMove]
|
||||
opensuse-leap
|
26
tests/auto/widgets/itemviews/qlistview/CMakeLists.txt
Normal file
26
tests/auto/widgets/itemviews/qlistview/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qlistview Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qlistview
|
||||
SOURCES
|
||||
tst_qlistview.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::TestPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_extend_target(tst_qlistview CONDITION WIN32
|
||||
LIBRARIES
|
||||
user32
|
||||
)
|
3201
tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
Normal file
3201
tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
Normal file
File diff suppressed because it is too large
Load Diff
17
tests/auto/widgets/itemviews/qlistwidget/CMakeLists.txt
Normal file
17
tests/auto/widgets/itemviews/qlistwidget/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qlistwidget Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qlistwidget
|
||||
SOURCES
|
||||
tst_qlistwidget.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
1969
tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
Normal file
1969
tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
Normal file
File diff suppressed because it is too large
Load Diff
5
tests/auto/widgets/itemviews/qtableview/BLACKLIST
Normal file
5
tests/auto/widgets/itemviews/qtableview/BLACKLIST
Normal file
@ -0,0 +1,5 @@
|
||||
[moveCursorBiggerJump]
|
||||
osx
|
||||
[mouseWheel:scroll down per pixel]
|
||||
macos
|
||||
|
18
tests/auto/widgets/itemviews/qtableview/CMakeLists.txt
Normal file
18
tests/auto/widgets/itemviews/qtableview/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qtableview Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qtableview
|
||||
SOURCES
|
||||
tst_qtableview.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::TestPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
4933
tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
Normal file
4933
tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
Normal file
File diff suppressed because it is too large
Load Diff
14
tests/auto/widgets/itemviews/qtablewidget/CMakeLists.txt
Normal file
14
tests/auto/widgets/itemviews/qtablewidget/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qtablewidget Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qtablewidget
|
||||
SOURCES
|
||||
tst_qtablewidget.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
1911
tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp
Normal file
1911
tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp
Normal file
File diff suppressed because it is too large
Load Diff
0
tests/auto/widgets/itemviews/qtreeview/BLACKLIST
Normal file
0
tests/auto/widgets/itemviews/qtreeview/BLACKLIST
Normal file
19
tests/auto/widgets/itemviews/qtreeview/CMakeLists.txt
Normal file
19
tests/auto/widgets/itemviews/qtreeview/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qtreeview Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qtreeview
|
||||
SOURCES
|
||||
../../../../shared/fakedirmodel.h
|
||||
tst_qtreeview.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::TestPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
5258
tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
Normal file
5258
tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
Normal file
File diff suppressed because it is too large
Load Diff
14
tests/auto/widgets/itemviews/qtreewidget/CMakeLists.txt
Normal file
14
tests/auto/widgets/itemviews/qtreewidget/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qtreewidget Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qtreewidget
|
||||
SOURCES
|
||||
tst_qtreewidget.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
3691
tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
Normal file
3691
tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qtreewidgetitemiterator Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qtreewidgetitemiterator
|
||||
SOURCES
|
||||
tst_qtreewidgetitemiterator.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user