qt5base-lts/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
Oswald Buddenhagen 30fd22b957 Merge remote-tracking branch 'origin/dev' into stable
Change-Id: Ice524edcc51373509f0023ae7f7c2963f4602f88
2014-02-19 10:06:25 +01:00

4165 lines
124 KiB
C++

/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtGui/QtGui>
#include <QtWidgets/QtWidgets>
#include <private/qtablewidget_p.h>
#include <QtTest/QtTest>
#include "private/qapplication_p.h"
#include <algorithm>
#ifdef QT_BUILD_INTERNAL
#define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) \
QVERIFY(static_cast<QTableViewPrivate*>(QObjectPrivate::get(TEST_VIEW_))->spans.checkConsistency())
#else
#define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) (void)false
#endif
typedef QList<int> IntList;
typedef QList<bool> BoolList;
// Make a widget frameless to prevent size constraints of title bars
// from interfering (Windows).
static inline void setFrameless(QWidget *w)
{
Qt::WindowFlags flags = w->windowFlags();
flags |= Qt::FramelessWindowHint;
flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
w->setWindowFlags(flags);
}
class tst_QTableView : public QObject
{
Q_OBJECT
public:
tst_QTableView();
virtual ~tst_QTableView();
public slots:
void initTestCase();
void cleanupTestCase();
void init();
void cleanup();
private slots:
void getSetCheck();
void noDelegate();
void noModel();
void emptyModel();
void removeRows_data();
void removeRows();
void removeColumns_data();
void removeColumns();
void keyboardNavigation_data();
void keyboardNavigation();
void headerSections_data();
void headerSections();
void moveCursor_data();
void moveCursor();
void moveCursorStrikesBack_data();
void moveCursorStrikesBack();
void moveCursorBiggerJump();
void hideRows_data();
void hideRows();
void hideColumns_data();
void hideColumns();
void selection_data();
void selection();
void selectRow_data();
void selectRow();
void selectColumn_data();
void selectColumn();
void visualRect_data();
void visualRect();
void fetchMore();
void setHeaders();
void resizeRowsToContents_data();
void resizeRowsToContents();
void resizeColumnsToContents_data();
void resizeColumnsToContents();
void rowViewportPosition_data();
void rowViewportPosition();
void rowAt_data();
void rowAt();
void rowHeight_data();
void rowHeight();
void columnViewportPosition_data();
void columnViewportPosition();
void columnAt_data();
void columnAt();
void columnWidth_data();
void columnWidth();
void hiddenRow_data();
void hiddenRow();
void hiddenColumn_data();
void hiddenColumn();
void sortingEnabled_data();
void sortingEnabled();
void scrollTo_data();
void scrollTo();
void indexAt_data();
void indexAt();
void span_data();
void span();
void spans();
void spans_data();
void spansAfterRowInsertion();
void spansAfterColumnInsertion();
void spansAfterRowRemoval();
void spansAfterColumnRemoval();
void checkHeaderReset();
void checkHeaderMinSize();
void resizeToContents();
void tabFocus();
void bigModel();
void selectionSignal();
void setCurrentIndex();
// task-specific tests:
void task173773_updateVerticalHeader();
void task227953_setRootIndex();
void task240266_veryBigColumn();
void task248688_autoScrollNavigation();
void task259308_scrollVerticalHeaderSwappedSections();
void task191545_dragSelectRows();
void taskQTBUG_5062_spansInconsistency();
void taskQTBUG_4516_clickOnRichTextLabel();
void taskQTBUG_5237_wheelEventOnHeader();
void taskQTBUG_8585_crashForNoGoodReason();
void taskQTBUG_7774_RtoLVisualRegionForSelection();
void taskQTBUG_8777_scrollToSpans();
void taskQTBUG_10169_sizeHintForRow();
void taskQTBUG_30653_doItemsLayout();
void mouseWheel_data();
void mouseWheel();
void addColumnWhileEditing();
void task234926_setHeaderSorting();
void changeHeaderData();
void viewOptions();
};
// Testing get/set functions
void tst_QTableView::getSetCheck()
{
QTableView obj1;
obj1.setSortingEnabled(false);
QCOMPARE(false, obj1.isSortingEnabled());
obj1.setSortingEnabled(true);
QCOMPARE(true, obj1.isSortingEnabled());
obj1.setShowGrid(false);
QCOMPARE(false, obj1.showGrid());
obj1.setShowGrid(true);
QCOMPARE(true, obj1.showGrid());
obj1.setGridStyle(Qt::NoPen);
QCOMPARE(Qt::NoPen, obj1.gridStyle());
obj1.setGridStyle(Qt::SolidLine);
QCOMPARE(Qt::SolidLine, obj1.gridStyle());
obj1.setRootIndex(QModelIndex());
QCOMPARE(QModelIndex(), obj1.rootIndex());
QStandardItemModel model(10, 10);
obj1.setModel(&model);
QModelIndex index = model.index(0, 0);
obj1.setRootIndex(index);
QCOMPARE(index, obj1.rootIndex());
QHeaderView *var1 = new QHeaderView(Qt::Horizontal);
obj1.setHorizontalHeader(var1);
QCOMPARE(var1, obj1.horizontalHeader());
obj1.setHorizontalHeader((QHeaderView *)0);
QCOMPARE(var1, obj1.horizontalHeader());
delete var1;
QHeaderView *var2 = new QHeaderView(Qt::Vertical);
obj1.setVerticalHeader(var2);
QCOMPARE(var2, obj1.verticalHeader());
obj1.setVerticalHeader((QHeaderView *)0);
QCOMPARE(var2, obj1.verticalHeader());
delete var2;
QCOMPARE(obj1.isCornerButtonEnabled(), true);
obj1.setCornerButtonEnabled(false);
QCOMPARE(obj1.isCornerButtonEnabled(), false);
}
class QtTestTableModel: public QAbstractTableModel
{
Q_OBJECT
signals:
void invalidIndexEncountered() const;
public slots:
bool submit() { ++submit_count; return QAbstractTableModel::submit(); }
public:
QtTestTableModel(int rows = 0, int columns = 0, QObject *parent = 0)
: QAbstractTableModel(parent),
row_count(rows),
column_count(columns),
submit_count(0),
can_fetch_more(false),
fetch_more_count(0),
disabled_rows(),
disabled_columns() {}
int rowCount(const QModelIndex& = QModelIndex()) const { return row_count; }
int columnCount(const QModelIndex& = QModelIndex()) const { return column_count; }
bool isEditable(const QModelIndex &) const { return true; }
Qt::ItemFlags flags(const QModelIndex &index) const
{
Qt::ItemFlags index_flags = QAbstractTableModel::flags(index);
if (disabled_rows.contains(index.row())
|| disabled_columns.contains(index.column()))
index_flags &= ~Qt::ItemIsEnabled;
return index_flags;
}
void disableRow(int row)
{
disabled_rows.insert(row);
}
void enableRow(int row)
{
disabled_rows.remove(row);
}
void disableColumn(int column)
{
disabled_columns.insert(column);
}
void enableColumn(int column)
{
disabled_columns.remove(column);
}
QVariant data(const QModelIndex &idx, int role) const
{
if (!idx.isValid() || idx.row() >= row_count || idx.column() >= column_count) {
qWarning() << "Invalid modelIndex [%d,%d,%p]" << idx;
emit invalidIndexEncountered();
return QVariant();
}
if (role == Qt::DisplayRole || role == Qt::EditRole)
return QString("[%1,%2,%3]").arg(idx.row()).arg(idx.column()).arg(0);
return QVariant();
}
bool insertRows(int start, int count, const QModelIndex &parent = QModelIndex())
{
if (start < 0 || start > row_count)
return false;
beginInsertRows(parent, start, start + count - 1);
row_count += count;
endInsertRows();
return true;
}
bool removeRows(int start, int count, const QModelIndex &parent = QModelIndex())
{
if (start < 0 || start >= row_count || row_count < count)
return false;
beginRemoveRows(parent, start, start + count - 1);
row_count -= count;
endRemoveRows();
return true;
}
void removeLastRow()
{
beginRemoveRows(QModelIndex(), row_count - 1, row_count - 1);
--row_count;
endRemoveRows();
}
void removeAllRows()
{
beginRemoveRows(QModelIndex(), 0, row_count - 1);
row_count = 0;
endRemoveRows();
}
bool insertColumns(int start, int count, const QModelIndex &parent = QModelIndex())
{
if (start < 0 || start > column_count)
return false;
beginInsertColumns(parent, start, start + count - 1);
column_count += count;
endInsertColumns();
return true;
}
bool removeColumns(int start, int count, const QModelIndex &parent = QModelIndex())
{
if (start < 0 || start >= column_count || column_count < count)
return false;
beginRemoveColumns(parent, start, start + count - 1);
column_count -= count;
endRemoveColumns();
return true;
}
void removeLastColumn()
{
beginRemoveColumns(QModelIndex(), column_count - 1, column_count - 1);
--column_count;
endRemoveColumns();
}
void removeAllColumns()
{
beginRemoveColumns(QModelIndex(), 0, column_count - 1);
column_count = 0;
endRemoveColumns();
}
bool canFetchMore(const QModelIndex &) const
{
return can_fetch_more;
}
void fetchMore(const QModelIndex &)
{
++fetch_more_count;
}
void reset()
{
QAbstractTableModel::reset();
}
int row_count;
int column_count;
int submit_count;
bool can_fetch_more;
int fetch_more_count;
QSet<int> disabled_rows;
QSet<int> disabled_columns;
};
class QtTestTableView : public QTableView
{
Q_OBJECT
public:
QtTestTableView(QWidget *parent = 0) : QTableView(parent), checkSignalOrder(false), hasCurrentChanged(0), hasSelectionChanged(0) {}
void setModel(QAbstractItemModel *model)
{
QTableView::setModel(model);
connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
this, SLOT(currentChanged(QModelIndex,QModelIndex)));
connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this, SLOT(itemSelectionChanged(QItemSelection,QItemSelection)));
}
// enum CursorAction and moveCursor() are protected in QTableView.
enum CursorAction {
MoveUp = QAbstractItemView::MoveUp,
MoveDown = QAbstractItemView::MoveDown,
MoveLeft = QAbstractItemView::MoveLeft,
MoveRight = QAbstractItemView::MoveRight,
MoveHome = QAbstractItemView::MoveHome,
MoveEnd = QAbstractItemView::MoveEnd,
MovePageUp = QAbstractItemView::MovePageUp,
MovePageDown = QAbstractItemView::MovePageDown,
MoveNext = QAbstractItemView::MoveNext,
MovePrevious = QAbstractItemView::MovePrevious
};
QModelIndex doMoveCursor(QtTestTableView::CursorAction cursorAction,
Qt::KeyboardModifiers modifiers)
{
return QTableView::moveCursor((QAbstractItemView::CursorAction)cursorAction, modifiers);
}
int columnWidthHint(int column) const
{
return sizeHintForColumn(column);
}
int rowHeightHint(int row) const
{
return sizeHintForRow(row);
}
bool isIndexHidden(const QModelIndex &index) const
{
return QTableView::isIndexHidden(index);
}
void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
{
QTableView::setSelection(rect, command);
}
QModelIndexList selectedIndexes() const
{
return QTableView::selectedIndexes();
}
int sizeHintForRow(int row) const
{
return QTableView::sizeHintForRow(row);
}
QStyleOptionViewItem viewOptions() const {
return QTableView::viewOptions();
}
bool checkSignalOrder;
public slots:
void currentChanged(QModelIndex , QModelIndex ) {
hasCurrentChanged++;
if (checkSignalOrder)
QVERIFY(hasCurrentChanged > hasSelectionChanged);
}
void itemSelectionChanged(QItemSelection , QItemSelection ) {
hasSelectionChanged++;
if (checkSignalOrder)
QVERIFY(hasCurrentChanged >= hasSelectionChanged);
}
private:
int hasCurrentChanged;
int hasSelectionChanged;
};
class QtTestItemDelegate : public QItemDelegate
{
public:
QSize sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const
{
return hint;
}
QSize hint;
};
tst_QTableView::tst_QTableView()
{
}
tst_QTableView::~tst_QTableView()
{
}
void tst_QTableView::initTestCase()
{
#ifdef Q_OS_WINCE //disable magic for WindowsCE
qApp->setAutoMaximizeThreshold(-1);
#endif
}
void tst_QTableView::cleanupTestCase()
{
}
void tst_QTableView::init()
{
}
void tst_QTableView::cleanup()
{
}
void tst_QTableView::noDelegate()
{
QtTestTableModel model(3, 3);
QTableView view;
view.setModel(&model);
view.setItemDelegate(0);
view.show();
}
void tst_QTableView::noModel()
{
QTableView view;
view.show();
}
void tst_QTableView::emptyModel()
{
QtTestTableModel model;
QTableView view;
QSignalSpy spy(&model, SIGNAL(invalidIndexEncountered()));
view.setModel(&model);
view.show();
QCOMPARE(spy.count(), 0);
}
void tst_QTableView::removeRows_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::newRow("2x2") << 2 << 2;
QTest::newRow("10x10") << 10 << 10;
}
void tst_QTableView::removeRows()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QtTestTableModel model(rowCount, columnCount);
QSignalSpy spy(&model, SIGNAL(invalidIndexEncountered()));
QTableView view;
view.setModel(&model);
view.show();
model.removeLastRow();
QCOMPARE(spy.count(), 0);
model.removeAllRows();
QCOMPARE(spy.count(), 0);
}
void tst_QTableView::removeColumns_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::newRow("2x2") << 2 << 2;
QTest::newRow("10x10") << 10 << 10;
}
void tst_QTableView::removeColumns()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QtTestTableModel model(rowCount, columnCount);
QSignalSpy spy(&model, SIGNAL(invalidIndexEncountered()));
QTableView view;
view.setModel(&model);
view.show();
model.removeLastColumn();
QCOMPARE(spy.count(), 0);
model.removeAllColumns();
QCOMPARE(spy.count(), 0);
}
void tst_QTableView::keyboardNavigation_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::addColumn<bool>("tabKeyNavigation");
QTest::addColumn<IntList>("keyPresses");
QTest::newRow("16x16 model") << 16 << 16 << true
<< (IntList()
<< Qt::Key_Up
<< Qt::Key_Up
<< Qt::Key_Right
<< Qt::Key_Right
<< Qt::Key_Up
<< Qt::Key_Left
<< Qt::Key_Left
<< Qt::Key_Up
<< Qt::Key_Down
<< Qt::Key_Up
<< Qt::Key_Up
<< Qt::Key_Up
<< Qt::Key_Up
<< Qt::Key_Up
<< Qt::Key_Up
<< Qt::Key_Left
<< Qt::Key_Left
<< Qt::Key_Up
<< Qt::Key_Down
<< Qt::Key_Down
<< Qt::Key_Tab
<< Qt::Key_Backtab);
QTest::newRow("no tab") << 8 << 8 << false
<< (IntList()
<< Qt::Key_Up
<< Qt::Key_Up
<< Qt::Key_Right
<< Qt::Key_Right
<< Qt::Key_Up
<< Qt::Key_Left
<< Qt::Key_Left
<< Qt::Key_Up
<< Qt::Key_Down
<< Qt::Key_Up
<< Qt::Key_Up
<< Qt::Key_Up
<< Qt::Key_Up
<< Qt::Key_Up
<< Qt::Key_Up
<< Qt::Key_Left
<< Qt::Key_Left
<< Qt::Key_Up
<< Qt::Key_Down
<< Qt::Key_Down
<< Qt::Key_Tab
<< Qt::Key_Backtab);
}
void tst_QTableView::keyboardNavigation()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QFETCH(bool, tabKeyNavigation);
QFETCH(IntList, keyPresses);
QtTestTableModel model(rowCount, columnCount);
QTableView view;
view.setModel(&model);
view.setTabKeyNavigation(tabKeyNavigation);
QModelIndex index = model.index(rowCount - 1, columnCount - 1);
view.setCurrentIndex(index);
view.show();
qApp->setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
int row = rowCount - 1;
int column = columnCount - 1;
for (int i = 0; i < keyPresses.count(); ++i) {
Qt::Key key = (Qt::Key)keyPresses.at(i);
switch (key) {
case Qt::Key_Up:
row = qMax(0, row - 1);
break;
case Qt::Key_Down:
row = qMin(rowCount - 1, row + 1);
break;
case Qt::Key_Backtab:
if (!tabKeyNavigation)
break;
case Qt::Key_Left:
column = qMax(0, column - 1);
break;
case Qt::Key_Tab:
if (!tabKeyNavigation)
break;
case Qt::Key_Right:
column = qMin(columnCount - 1, column + 1);
break;
default:
break;
}
QTest::keyClick(&view, key);
QApplication::processEvents();
QModelIndex index = model.index(row, column);
QCOMPARE(view.currentIndex(), index);
}
}
void tst_QTableView::headerSections_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::addColumn<int>("row");
QTest::addColumn<int>("column");
QTest::addColumn<int>("rowHeight");
QTest::addColumn<int>("columnWidth");
QTest::newRow("") << 10 << 10 << 5 << 5 << 30 << 30;
}
void tst_QTableView::headerSections()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QFETCH(int, row);
QFETCH(int, column);
QFETCH(int, rowHeight);
QFETCH(int, columnWidth);
QtTestTableModel model(rowCount, columnCount);
QTableView view;
QHeaderView *hheader = view.horizontalHeader();
QHeaderView *vheader = view.verticalHeader();
view.setModel(&model);
view.show();
hheader->doItemsLayout();
vheader->doItemsLayout();
QCOMPARE(hheader->count(), model.columnCount());
QCOMPARE(vheader->count(), model.rowCount());
view.setRowHeight(row, rowHeight);
QCOMPARE(view.rowHeight(row), rowHeight);
view.hideRow(row);
QCOMPARE(view.rowHeight(row), 0);
view.showRow(row);
QCOMPARE(view.rowHeight(row), rowHeight);
view.setColumnWidth(column, columnWidth);
QCOMPARE(view.columnWidth(column), columnWidth);
view.hideColumn(column);
QCOMPARE(view.columnWidth(column), 0);
view.showColumn(column);
QCOMPARE(view.columnWidth(column), columnWidth);
}
typedef QPair<int,int> IntPair;
void tst_QTableView::moveCursor_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::addColumn<int>("hideRow");
QTest::addColumn<int>("hideColumn");
QTest::addColumn<int>("startRow");
QTest::addColumn<int>("startColumn");
QTest::addColumn<int>("cursorMoveAction");
QTest::addColumn<int>("modifier");
QTest::addColumn<int>("expectedRow");
QTest::addColumn<int>("expectedColumn");
QTest::addColumn<IntPair>("moveRow");
QTest::addColumn<IntPair>("moveColumn");
// MoveRight
QTest::newRow("MoveRight (0,0)")
<< 4 << 4 << -1 << -1
<< 0 << 0
<< int(QtTestTableView::MoveRight) << int(Qt::NoModifier)
<< 0 << 1 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveRight (3,0)")
<< 4 << 4 << -1 << -1
<< 3 << 0
<< int(QtTestTableView::MoveRight) << int(Qt::NoModifier)
<< 3 << 1 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveRight (3,3)")
<< 4 << 4 << -1 << -1
<< 3 << 3
<< int(QtTestTableView::MoveRight) << int(Qt::NoModifier)
<< 3 << 3 << IntPair(0,0) << IntPair(0,0); // ###
QTest::newRow("MoveRight, hidden column 1 (0,0)")
<< 4 << 4 << -1 << 1
<< 0 << 0
<< int(QtTestTableView::MoveRight) << int(Qt::NoModifier)
<< 0 << 2 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveRight, hidden column 3 (0,2)")
<< 4 << 4 << -1 << 3
<< 0 << 2
<< int(QtTestTableView::MoveRight) << int(Qt::NoModifier)
<< 0 << 2 << IntPair(0,0) << IntPair(0,0); // ###
// MoveNext should in addition wrap
QTest::newRow("MoveNext (0,0)")
<< 4 << 4 << -1 << -1
<< 0 << 0
<< int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
<< 0 << 1 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveNext (0,2)")
<< 4 << 4 << -1 << -1
<< 0 << 2
<< int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
<< 0 << 3 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveNext, wrap (0,3)")
<< 4 << 4 << -1 << -1
<< 0 << 3
<< int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
<< 1 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveNext, wrap (3,3)")
<< 4 << 4 << -1 << -1
<< 3 << 3
<< int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
<< 0 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveNext, hidden column 1 (0,0)")
<< 4 << 4 << -1 << 1
<< 0 << 0
<< int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
<< 0 << 2 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveNext, wrap, hidden column 3 (0,2)")
<< 4 << 4 << -1 << 3
<< 0 << 2
<< int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
<< 1 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveNext, wrap, hidden column 3 (3,2)")
<< 4 << 4 << -1 << 3
<< 3 << 2
<< int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
<< 0 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveNext, wrapy, wrapx, hidden column 3, hidden row 3 (2,2)")
<< 4 << 4 << 3 << 3
<< 2 << 2
<< int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
<< 0 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveNext, wrap, hidden column 2, moved column from 3 to 0. (0,2)")
<< 4 << 4 << -1 << 2
<< 0 << 2
<< int(QtTestTableView::MoveNext) << int(Qt::NoModifier)
<< 1 << 3 << IntPair(0,0) << IntPair(3,0);
// MoveLeft
QTest::newRow("MoveLeft (0,0)")
<< 4 << 4 << -1 << -1
<< 0 << 0
<< int(QtTestTableView::MoveLeft) << int(Qt::NoModifier)
<< 0 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveLeft (0,3)")
<< 4 << 4 << -1 << -1
<< 0 << 3
<< int(QtTestTableView::MoveLeft) << int(Qt::NoModifier)
<< 0 << 2 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveLeft (1,0)")
<< 4 << 4 << -1 << -1
<< 1 << 0
<< int(QtTestTableView::MoveLeft) << int(Qt::NoModifier)
<< 1 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveLeft, hidden column 0 (0,2)")
<< 4 << 4 << -1 << 1
<< 0 << 2
<< int(QtTestTableView::MoveLeft) << int(Qt::NoModifier)
<< 0 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveLeft, hidden column 0 (0,1)")
<< 4 << 4 << -1 << 0
<< 0 << 1
<< int(QtTestTableView::MoveLeft) << int(Qt::NoModifier)
<< 0 << 1 << IntPair(0,0) << IntPair(0,0);
// MovePrevious should in addition wrap
QTest::newRow("MovePrevious (0,3)")
<< 4 << 4 << -1 << -1
<< 0 << 3
<< int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
<< 0 << 2 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MovePrevious (0,1)")
<< 4 << 4 << -1 << -1
<< 0 << 1
<< int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
<< 0 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MovePrevious, wrap (1,0)")
<< 4 << 4 << -1 << -1
<< 1 << 0
<< int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
<< 0 << 3 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MovePrevious, wrap, (0,0)")
<< 4 << 4 << -1 << -1
<< 0 << 0
<< int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
<< 3 << 3 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MovePrevious, hidden column 1 (0,2)")
<< 4 << 4 << -1 << 1
<< 0 << 2
<< int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
<< 0 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MovePrevious, wrap, hidden column 3 (0,2)")
<< 4 << 4 << -1 << 3
<< 0 << 2
<< int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
<< 0 << 1 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MovePrevious, wrapy, hidden column 0 (0,1)")
<< 4 << 4 << -1 << 0
<< 0 << 1
<< int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
<< 3 << 3 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MovePrevious, wrap, hidden column 0, hidden row 0 (1,1)")
<< 4 << 4 << 0 << 0
<< 1 << 1
<< int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
<< 3 << 3 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MovePrevious, wrap, hidden column 1, moved column from 0 to 3. (1,2)")
<< 4 << 4 << -1 << 1
<< 1 << 2
<< int(QtTestTableView::MovePrevious) << int(Qt::NoModifier)
<< 0 << 0 << IntPair(0,0) << IntPair(0,3);
// MoveDown
QTest::newRow("MoveDown (0,0)")
<< 4 << 4 << -1 << -1
<< 0 << 0
<< int(QtTestTableView::MoveDown) << int(Qt::NoModifier)
<< 1 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveDown (3,0)")
<< 4 << 4 << -1 << -1
<< 3 << 0
<< int(QtTestTableView::MoveDown) << int(Qt::NoModifier)
<< 3 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveDown (3,3)")
<< 4 << 4 << -1 << -1
<< 3 << 3
<< int(QtTestTableView::MoveDown) << int(Qt::NoModifier)
<< 3 << 3 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveDown, hidden row 1 (0,0)")
<< 4 << 4 << 1 << -1
<< 0 << 0
<< int(QtTestTableView::MoveDown) << int(Qt::NoModifier)
<< 2 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveDown, hidden row 3 (2,0)")
<< 4 << 4 << 3 << -1
<< 2 << 0
<< int(QtTestTableView::MoveDown) << int(Qt::NoModifier)
<< 2 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveDown, hidden row 0 hidden column 0 (0,0)")
<< 4 << 4 << 0 << 0
<< 0 << 0
<< int(QtTestTableView::MoveDown) << int(Qt::NoModifier)
<< 1 << 1 << IntPair(0,0) << IntPair(0,0);
// MoveUp
QTest::newRow("MoveUp (0,0)")
<< 4 << 4 << -1 << -1
<< 0 << 0
<< int(QtTestTableView::MoveUp) << int(Qt::NoModifier)
<< 0 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveUp (3, 0)")
<< 4 << 4 << -1 << -1
<< 3 << 0
<< int(QtTestTableView::MoveUp) << int(Qt::NoModifier)
<< 2 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveUp (0,1)")
<< 4 << 4 << -1 << -1
<< 0 << 1
<< int(QtTestTableView::MoveUp) << int(Qt::NoModifier)
<< 0 << 1 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveUp, hidden row 1 (2,0)")
<< 4 << 4 << 1 << -1
<< 2 << 0
<< int(QtTestTableView::MoveUp) << int(Qt::NoModifier)
<< 0 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveUp, hidden row (1,0)")
<< 4 << 4 << 0 << -1
<< 1 << 0
<< int(QtTestTableView::MoveUp) << int(Qt::NoModifier)
<< 1 << 0 << IntPair(0,0) << IntPair(0,0);
// MoveHome
QTest::newRow("MoveHome (0,0)")
<< 4 << 4 << -1 << -1
<< 0 << 0
<< int(QtTestTableView::MoveHome) << int(Qt::NoModifier)
<< 0 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveHome (3,3)")
<< 4 << 4 << -1 << -1
<< 3 << 3
<< int(QtTestTableView::MoveHome) << int(Qt::NoModifier)
<< 3 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveHome, hidden column 0 (3,3)")
<< 4 << 4 << -1 << 0
<< 3 << 3
<< int(QtTestTableView::MoveHome) << int(Qt::NoModifier)
<< 3 << 1 << IntPair(0,0) << IntPair(0,0);
// Use Ctrl modifier
QTest::newRow("MoveHome + Ctrl (0,0)")
<< 4 << 4 << -1 << -1
<< 0 << 0
<< int(QtTestTableView::MoveHome) << int(Qt::ControlModifier)
<< 0 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveHome + Ctrl (3,3)")
<< 4 << 4 << -1 << -1
<< 3 << 3
<< int(QtTestTableView::MoveHome) << int(Qt::ControlModifier)
<< 0 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveHome + Ctrl, hidden column 0, hidden row 0 (3,3)")
<< 4 << 4 << 0 << 0
<< 3 << 3
<< int(QtTestTableView::MoveHome) << int(Qt::ControlModifier)
<< 1 << 1 << IntPair(0,0) << IntPair(0,0);
// MoveEnd
QTest::newRow("MoveEnd (0,0)")
<< 4 << 4 << -1 << -1
<< 0 << 0
<< int(QtTestTableView::MoveEnd) << int(Qt::NoModifier)
<< 0 << 3 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveEnd (3,3)")
<< 4 << 4 << -1 << -1
<< 3 << 3
<< int(QtTestTableView::MoveEnd) << int(Qt::NoModifier)
<< 3 << 3 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveEnd, hidden column (0,0)")
<< 4 << 4 << -1 << 3
<< 0 << 0
<< int(QtTestTableView::MoveEnd) << int(Qt::NoModifier)
<< 0<< 2 << IntPair(0,0) << IntPair(0,0);
// Use Ctrl modifier
QTest::newRow("MoveEnd + Ctrl (0,0)")
<< 4 << 4 << -1 << -1
<< 0 << 0
<< int(QtTestTableView::MoveEnd) << int(Qt::ControlModifier)
<< 3 << 3 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveEnd + Ctrl (3,3)")
<< 4 << 4 << -1 << -1
<< 3 << 3
<< int(QtTestTableView::MoveEnd) << int(Qt::ControlModifier)
<< 3 << 3 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveEnd + Ctrl, hidden column 3 (0,0)")
<< 4 << 4 << -1 << 3
<< 0 << 0
<< int(QtTestTableView::MoveEnd) << int(Qt::ControlModifier)
<< 3 << 2 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MoveEnd + Ctrl, hidden column 3, hidden row 3 (0,0)")
<< 4 << 4 << 3 << 3
<< 0 << 0
<< int(QtTestTableView::MoveEnd) << int(Qt::ControlModifier)
<< 2 << 2 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MovePageUp (0,0)")
<< 4 << 4 << -1 << -1
<< 0 << 0
<< int(QtTestTableView::MovePageUp) << 0
<< 0 << 0 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MovePageUp (3,3)")
<< 4 << 4 << -1 << -1
<< 3 << 3
<< int(QtTestTableView::MovePageUp) << 0
<< 0 << 3 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MovePageDown (3, 3)")
<< 4 << 4 << -1 << -1
<< 3 << 3
<< int(QtTestTableView::MovePageDown) << 0
<< 3 << 3 << IntPair(0,0) << IntPair(0,0);
QTest::newRow("MovePageDown (0, 3)")
<< 4 << 4 << -1 << -1
<< 0 << 3
<< int(QtTestTableView::MovePageDown) << 0
<< 3 << 3 << IntPair(0,0) << IntPair(0,0);
}
void tst_QTableView::moveCursor()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QFETCH(int, hideRow);
QFETCH(int, hideColumn);
QFETCH(int, startRow);
QFETCH(int, startColumn);
QFETCH(int, cursorMoveAction);
QFETCH(int, modifier);
QFETCH(int, expectedRow);
QFETCH(int, expectedColumn);
QFETCH(IntPair, moveRow);
QFETCH(IntPair, moveColumn);
QtTestTableModel model(rowCount, columnCount);
QtTestTableView view;
view.setModel(&model);
view.hideRow(hideRow);
view.hideColumn(hideColumn);
if (moveColumn.first != moveColumn.second)
view.horizontalHeader()->moveSection(moveColumn.first, moveColumn.second);
if (moveRow.first != moveRow.second)
view.verticalHeader()->moveSection(moveRow.first, moveRow.second);
view.show();
QModelIndex index = model.index(startRow, startColumn);
view.setCurrentIndex(index);
QModelIndex newIndex = view.doMoveCursor((QtTestTableView::CursorAction)cursorMoveAction,
(Qt::KeyboardModifiers)modifier);
// expected fails, task 119433
if(newIndex.row() == -1)
return;
QCOMPARE(newIndex.row(), expectedRow);
QCOMPARE(newIndex.column(), expectedColumn);
}
void tst_QTableView::moveCursorStrikesBack_data()
{
QTest::addColumn<int>("hideRow");
QTest::addColumn<int>("hideColumn");
QTest::addColumn<IntList>("disableRows");
QTest::addColumn<IntList>("disableColumns");
QTest::addColumn<QRect>("span");
QTest::addColumn<int>("startRow");
QTest::addColumn<int>("startColumn");
QTest::addColumn<IntList>("cursorMoveActions");
QTest::addColumn<int>("expectedRow");
QTest::addColumn<int>("expectedColumn");
QTest::newRow("Last column disabled. Task QTBUG-3878") << -1 << -1
<< IntList()
<< (IntList() << 6)
<< QRect()
<< 0 << 5 << (IntList() << int(QtTestTableView::MoveNext))
<< 1 << 0;
QTest::newRow("Last column disabled 2. Task QTBUG-3878") << -1 << -1
<< IntList()
<< (IntList() << 6)
<< QRect()
<< 1 << 0 << (IntList() << int(QtTestTableView::MovePrevious))
<< 0 << 5;
QTest::newRow("Span, anchor column hidden") << -1 << 1
<< IntList()
<< IntList()
<< QRect(1, 2, 2, 3)
<< 2 << 0 << (IntList() << int(QtTestTableView::MoveNext))
<< 2 << 2;
QTest::newRow("Span, anchor column disabled") << -1 << -1
<< IntList()
<< (IntList() << 1)
<< QRect(1, 2, 2, 3)
<< 2 << 0 << (IntList() << int(QtTestTableView::MoveNext))
<< 2 << 2;
QTest::newRow("Span, anchor row hidden") << 2 << -1
<< IntList()
<< IntList()
<< QRect(1, 2, 2, 3)
<< 1 << 2 << (IntList() << int(QtTestTableView::MoveDown))
<< 3 << 2;
QTest::newRow("Span, anchor row disabled") << -1 << -1
<< (IntList() << 2)
<< IntList()
<< QRect(1, 2, 2, 3)
<< 1 << 2 << (IntList() << int(QtTestTableView::MoveDown))
<< 3 << 2;
QTest::newRow("Move through span right") << -1 << -1
<< IntList()
<< IntList()
<< QRect(1, 2, 2, 3)
<< 3 << 0 << (IntList() << int(QtTestTableView::MoveRight) << int(QtTestTableView::MoveRight))
<< 3 << 3;
QTest::newRow("Move through span left") << -1 << -1
<< IntList()
<< IntList()
<< QRect(1, 2, 2, 3)
<< 3 << 3 << (IntList() << int(QtTestTableView::MoveLeft) << int(QtTestTableView::MoveLeft))
<< 3 << 0;
QTest::newRow("Move through span down") << -1 << -1
<< IntList()
<< IntList()
<< QRect(1, 2, 2, 3)
<< 1 << 2 << (IntList() << int(QtTestTableView::MoveDown) << int(QtTestTableView::MoveDown))
<< 5 << 2;
QTest::newRow("Move through span up") << -1 << -1
<< IntList()
<< IntList()
<< QRect(1, 2, 2, 3)
<< 5 << 2 << (IntList() << int(QtTestTableView::MoveUp) << int(QtTestTableView::MoveUp))
<< 1 << 2;
IntList fullList;
for (int i = 0; i < 7; ++i)
fullList << i;
QTest::newRow("All disabled, wrap forward. Timeout => FAIL") << -1 << -1
<< fullList
<< fullList
<< QRect()
<< 1 << 0 << (IntList() << int(QtTestTableView::MoveNext))
<< 1 << 0;
QTest::newRow("All disabled, wrap backwards. Timeout => FAIL") << -1 << -1
<< fullList
<< fullList
<< QRect()
<< 1 << 0 << (IntList() << int(QtTestTableView::MovePrevious))
<< 1 << 0;
}
void tst_QTableView::moveCursorStrikesBack()
{
QFETCH(int, hideRow);
QFETCH(int, hideColumn);
QFETCH(IntList, disableRows);
QFETCH(IntList, disableColumns);
QFETCH(QRect, span);
QFETCH(int, startRow);
QFETCH(int, startColumn);
QFETCH(IntList, cursorMoveActions);
QFETCH(int, expectedRow);
QFETCH(int, expectedColumn);
QtTestTableModel model(7, 7);
QtTestTableView view;
view.setModel(&model);
view.hideRow(hideRow);
view.hideColumn(hideColumn);
if (span.height() && span.width())
view.setSpan(span.top(), span.left(), span.height(), span.width());
view.show();
QModelIndex index = model.index(startRow, startColumn);
view.setCurrentIndex(index);
foreach (int row, disableRows)
model.disableRow(row);
foreach (int column, disableColumns)
model.disableColumn(column);
int newRow = -1;
int newColumn = -1;
foreach (int cursorMoveAction, cursorMoveActions) {
QModelIndex newIndex = view.doMoveCursor((QtTestTableView::CursorAction)cursorMoveAction, 0);
view.setCurrentIndex(newIndex);
newRow = newIndex.row();
newColumn = newIndex.column();
}
// expected fails, task 119433
if(newRow == -1)
return;
QCOMPARE(newRow, expectedRow);
QCOMPARE(newColumn, expectedColumn);
}
void tst_QTableView::moveCursorBiggerJump()
{
QtTestTableModel model(50, 7);
QTableView view;
view.setModel(&model);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
int height = view.horizontalHeader()->height();
for (int i=0;i<8;i++)
height += view.verticalHeader()->sectionSize(i);
view.resize(view.width(), height);
view.setCurrentIndex(model.index(0,0));
QTest::keyClick(&view, Qt::Key_PageDown);
QCOMPARE(view.indexAt(QPoint(0,0)), model.index(1,0));
QTest::keyClick(&view, Qt::Key_PageDown);
QCOMPARE(view.indexAt(QPoint(0,0)), model.index(8,0));
QTest::keyClick(&view, Qt::Key_PageDown);
QCOMPARE(view.indexAt(QPoint(0,0)), model.index(15,0));
QTest::keyClick(&view, Qt::Key_PageUp);
QCOMPARE(view.indexAt(QPoint(0,0)), model.index(14,0));
QTest::keyClick(&view, Qt::Key_PageUp);
QCOMPARE(view.indexAt(QPoint(0,0)), model.index(7,0));
QTest::keyClick(&view, Qt::Key_PageUp);
QCOMPARE(view.indexAt(QPoint(0,0)), model.index(0,0));
}
void tst_QTableView::hideRows_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::addColumn<int>("showRow"); // hide, then show
QTest::addColumn<int>("hideRow"); // hide only
QTest::addColumn<int>("row");
QTest::addColumn<int>("column");
QTest::addColumn<int>("rowSpan");
QTest::addColumn<int>("columnSpan");
QTest::newRow("show row 0, hide row 3, no span")
<< 10 << 10
<< 0
<< 3
<< -1 << -1
<< 1 << 1;
QTest::newRow("show row 0, hide row 3, span")
<< 10 << 10
<< 0
<< 3
<< 0 << 0
<< 3 << 2;
}
void tst_QTableView::hideRows()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QFETCH(int, showRow);
QFETCH(int, hideRow);
QFETCH(int, row);
QFETCH(int, column);
QFETCH(int, rowSpan);
QFETCH(int, columnSpan);
QtTestTableModel model(rowCount, columnCount);
QTableView view;
view.setModel(&model);
view.setSpan(row, column, rowSpan, columnSpan);
view.hideRow(showRow);
QVERIFY(view.isRowHidden(showRow));
view.hideRow(hideRow);
QVERIFY(view.isRowHidden(hideRow));
view.showRow(showRow);
QVERIFY(!view.isRowHidden(showRow));
QVERIFY(view.isRowHidden(hideRow));
}
void tst_QTableView::hideColumns_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::addColumn<int>("showColumn"); // hide, then show
QTest::addColumn<int>("hideColumn"); // hide only
QTest::addColumn<int>("row");
QTest::addColumn<int>("column");
QTest::addColumn<int>("rowSpan");
QTest::addColumn<int>("columnSpan");
QTest::newRow("show col 0, hide col 3, no span")
<< 10 << 10
<< 0
<< 3
<< -1 << -1
<< 1 << 1;
QTest::newRow("show col 0, hide col 3, span")
<< 10 << 10
<< 0
<< 3
<< 0 << 0
<< 3 << 2;
}
void tst_QTableView::hideColumns()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QFETCH(int, showColumn);
QFETCH(int, hideColumn);
QFETCH(int, row);
QFETCH(int, column);
QFETCH(int, rowSpan);
QFETCH(int, columnSpan);
QtTestTableModel model(rowCount, columnCount);
QTableView view;
view.setModel(&model);
view.setSpan(row, column, rowSpan, columnSpan);
view.hideColumn(showColumn);
QVERIFY(view.isColumnHidden(showColumn));
view.hideColumn(hideColumn);
QVERIFY(view.isColumnHidden(hideColumn));
view.showColumn(showColumn);
QVERIFY(!view.isColumnHidden(showColumn));
QVERIFY(view.isColumnHidden(hideColumn));
}
void tst_QTableView::selection_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::addColumn<int>("row");
QTest::addColumn<int>("column");
QTest::addColumn<int>("rowSpan");
QTest::addColumn<int>("columnSpan");
QTest::addColumn<int>("hideRow");
QTest::addColumn<int>("hideColumn");
QTest::addColumn<int>("moveRowFrom");
QTest::addColumn<int>("moveRowTo");
QTest::addColumn<int>("moveColumnFrom");
QTest::addColumn<int>("moveColumnTo");
QTest::addColumn<int>("rowHeight");
QTest::addColumn<int>("columnWidth");
QTest::addColumn<int>("x");
QTest::addColumn<int>("y");
QTest::addColumn<int>("width");
QTest::addColumn<int>("height");
QTest::addColumn<int>("command");
QTest::addColumn<int>("selectedCount"); // ### make this more detailed
QTest::newRow("no span, no hidden, no moved, 3x3 select")
<< 10 << 10 // dim
<< -1 << -1 // pos
<< 1 << 1 // span
<< -1 << -1 // hide
<< -1 << -1 // move row
<< -1 << -1 // move col
<< 40 << 40 // cell size
<< 20 << 20 << 80 << 80 // rect
<< int(QItemSelectionModel::Select) // command
<< 9; // selected count
QTest::newRow("row span, no hidden, no moved, 3x3 select")
<< 10 << 10 // dim
<< 1 << 1 // pos
<< 2 << 1 // span
<< -1 << -1 // hide
<< -1 << -1 // move row
<< -1 << -1 // move col
<< 40 << 40 // cell size
<< 20 << 20 << 80 << 80 // rect
<< int(QItemSelectionModel::Select) // command
<< 8; // selected count
QTest::newRow("col span, no hidden, no moved, 3x3 select")
<< 10 << 10 // dim
<< 1 << 1 // pos
<< 1 << 2 // span
<< -1 << -1 // hide
<< -1 << -1 // move row
<< -1 << -1 // move col
<< 40 << 40 // cell size
<< 20 << 20 << 80 << 80 // rect
<< int(QItemSelectionModel::Select) // command
<< 8; // selected count
QTest::newRow("no span, row hidden, no moved, 3x3 select")
<< 10 << 10 // dim
<< -1 << -1 // pos
<< 1 << 1 // span
<< 1 << -1 // hide
<< -1 << -1 // move row
<< -1 << -1 // move col
<< 40 << 40 // cell size
<< 20 << 20 << 80 << 80 // rect
<< int(QItemSelectionModel::Select) // command
<< 9; // selected count
QTest::newRow("no span, col hidden, no moved, 3x3 select")
<< 10 << 10 // dim
<< -1 << -1 // pos
<< 1 << 1 // span
<< -1 << 1 // hide
<< -1 << -1 // move row
<< -1 << -1 // move col
<< 40 << 40 // cell size
<< 20 << 20 << 80 << 80 // rect
<< int(QItemSelectionModel::Select) // command
<< 9; // selected count
QTest::newRow("no span, no hidden, row moved, 3x3 select")
<< 10 << 10 // dim
<< -1 << -1 // pos
<< 1 << 1 // span
<< -1 << -1 // hide
<< 1 << 3 // move row
<< -1 << -1 // move col
<< 40 << 40 // cell size
<< 20 << 20 << 80 << 80 // rect
<< int(QItemSelectionModel::Select) // command
<< 9; // selected count
QTest::newRow("no span, no hidden, col moved, 3x3 select")
<< 10 << 10 // dim
<< -1 << -1 // pos
<< 1 << 1 // span
<< -1 << -1 // hide
<< -1 << -1 // move row
<< 1 << 3 // move col
<< 40 << 40 // cell size
<< 20 << 20 << 80 << 80 // rect
<< int(QItemSelectionModel::Select) // command
<< 9; // selected count
}
void tst_QTableView::selection()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QFETCH(int, row);
QFETCH(int, column);
QFETCH(int, rowSpan);
QFETCH(int, columnSpan);
QFETCH(int, hideRow);
QFETCH(int, hideColumn);
QFETCH(int, moveRowFrom);
QFETCH(int, moveRowTo);
QFETCH(int, moveColumnFrom);
QFETCH(int, moveColumnTo);
QFETCH(int, rowHeight);
QFETCH(int, columnWidth);
QFETCH(int, x);
QFETCH(int, y);
QFETCH(int, width);
QFETCH(int, height);
QFETCH(int, command);
QFETCH(int, selectedCount);
QtTestTableModel model(rowCount, columnCount);
QtTestTableView view;
view.show();
view.setModel(&model);
view.setSpan(row, column, rowSpan, columnSpan);
view.hideRow(hideRow);
view.hideColumn(hideColumn);
view.verticalHeader()->moveSection(moveRowFrom, moveRowTo);
view.horizontalHeader()->moveSection(moveColumnFrom, moveColumnTo);
for (int r = 0; r < rowCount; ++r)
view.setRowHeight(r, rowHeight);
for (int c = 0; c < columnCount; ++c)
view.setColumnWidth(c, columnWidth);
view.setSelection(QRect(x, y, width, height),
QItemSelectionModel::SelectionFlags(command));
QCOMPARE(view.selectedIndexes().count(), selectedCount);
}
void tst_QTableView::selectRow_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::addColumn<int>("row");
QTest::addColumn<int>("mode");
QTest::addColumn<int>("behavior");
QTest::addColumn<int>("selectedItems");
QTest::newRow("SingleSelection and SelectItems")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::SingleSelection
<< (int)QAbstractItemView::SelectItems
<< 0;
QTest::newRow("SingleSelection and SelectRows")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::SingleSelection
<< (int)QAbstractItemView::SelectRows
<< 10;
QTest::newRow("SingleSelection and SelectColumns")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::SingleSelection
<< (int)QAbstractItemView::SelectColumns
<< 0;
QTest::newRow("MultiSelection and SelectItems")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::MultiSelection
<< (int)QAbstractItemView::SelectItems
<< 10;
QTest::newRow("MultiSelection and SelectRows")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::MultiSelection
<< (int)QAbstractItemView::SelectRows
<< 10;
QTest::newRow("MultiSelection and SelectColumns")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::MultiSelection
<< (int)QAbstractItemView::SelectColumns
<< 0;
QTest::newRow("ExtendedSelection and SelectItems")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::ExtendedSelection
<< (int)QAbstractItemView::SelectItems
<< 10;
QTest::newRow("ExtendedSelection and SelectRows")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::ExtendedSelection
<< (int)QAbstractItemView::SelectRows
<< 10;
QTest::newRow("ExtendedSelection and SelectColumns")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::ExtendedSelection
<< (int)QAbstractItemView::SelectColumns
<< 0;
QTest::newRow("ContiguousSelection and SelectItems")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::ContiguousSelection
<< (int)QAbstractItemView::SelectItems
<< 10;
QTest::newRow("ContiguousSelection and SelectRows")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::ContiguousSelection
<< (int)QAbstractItemView::SelectRows
<< 10;
QTest::newRow("ContiguousSelection and SelectColumns")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::ContiguousSelection
<< (int)QAbstractItemView::SelectColumns
<< 0;
}
void tst_QTableView::selectRow()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QFETCH(int, row);
QFETCH(int, mode);
QFETCH(int, behavior);
QFETCH(int, selectedItems);
QtTestTableModel model(rowCount, columnCount);
QTableView view;
view.setModel(&model);
view.setSelectionMode((QAbstractItemView::SelectionMode)mode);
view.setSelectionBehavior((QAbstractItemView::SelectionBehavior)behavior);
QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0);
view.selectRow(row);
//test we have 10 items selected
QCOMPARE(view.selectionModel()->selectedIndexes().count(), selectedItems);
//test that all 10 items are in the same row
for (int i = 0; selectedItems > 0 && i < rowCount; ++i)
QCOMPARE(view.selectionModel()->selectedIndexes().at(i).row(), row);
}
void tst_QTableView::selectColumn_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::addColumn<int>("column");
QTest::addColumn<int>("mode");
QTest::addColumn<int>("behavior");
QTest::addColumn<int>("selectedItems");
QTest::newRow("SingleSelection and SelectItems")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::SingleSelection
<< (int)QAbstractItemView::SelectItems
<< 0;
QTest::newRow("SingleSelection and SelectRows")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::SingleSelection
<< (int)QAbstractItemView::SelectRows
<< 0;
QTest::newRow("SingleSelection and SelectColumns")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::SingleSelection
<< (int)QAbstractItemView::SelectColumns
<< 10;
QTest::newRow("MultiSelection and SelectItems")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::MultiSelection
<< (int)QAbstractItemView::SelectItems
<< 10;
QTest::newRow("MultiSelection and SelectRows")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::MultiSelection
<< (int)QAbstractItemView::SelectRows
<< 0;
QTest::newRow("MultiSelection and SelectColumns")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::MultiSelection
<< (int)QAbstractItemView::SelectColumns
<< 10;
QTest::newRow("ExtendedSelection and SelectItems")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::ExtendedSelection
<< (int)QAbstractItemView::SelectItems
<< 10;
QTest::newRow("ExtendedSelection and SelectRows")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::ExtendedSelection
<< (int)QAbstractItemView::SelectRows
<< 0;
QTest::newRow("ExtendedSelection and SelectColumns")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::ExtendedSelection
<< (int)QAbstractItemView::SelectColumns
<< 10;
QTest::newRow("ContiguousSelection and SelectItems")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::ContiguousSelection
<< (int)QAbstractItemView::SelectItems
<< 10;
QTest::newRow("ContiguousSelection and SelectRows")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::ContiguousSelection
<< (int)QAbstractItemView::SelectRows
<< 0;
QTest::newRow("ContiguousSelection and SelectColumns")
<< 10 << 10
<< 0
<< (int)QAbstractItemView::ContiguousSelection
<< (int)QAbstractItemView::SelectColumns
<< 10;
}
void tst_QTableView::selectColumn()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QFETCH(int, column);
QFETCH(int, mode);
QFETCH(int, behavior);
QFETCH(int, selectedItems);
QtTestTableModel model(rowCount, columnCount);
QTableView view;
view.setModel(&model);
view.setSelectionMode((QAbstractItemView::SelectionMode)mode);
view.setSelectionBehavior((QAbstractItemView::SelectionBehavior)behavior);
QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0);
view.selectColumn(column);
QCOMPARE(view.selectionModel()->selectedIndexes().count(), selectedItems);
for (int i = 0; selectedItems > 0 && i < columnCount; ++i)
QCOMPARE(view.selectionModel()->selectedIndexes().at(i).column(), column);
}
void tst_QTableView::visualRect_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::addColumn<int>("hideRow");
QTest::addColumn<int>("hideColumn");
QTest::addColumn<int>("row");
QTest::addColumn<int>("column");
QTest::addColumn<int>("rowHeight");
QTest::addColumn<int>("columnWidth");
QTest::addColumn<QRect>("expectedRect");
QTest::newRow("(0,0)")
<< 10 << 10
<< -1 << -1
<< 0 << 0
<< 20 << 30
<< QRect(0, 0, 29, 19);
QTest::newRow("(0,0) hidden row")
<< 10 << 10
<< 0 << -1
<< 0 << 0
<< 20 << 30
<< QRect();
QTest::newRow("(0,0) hidden column")
<< 10 << 10
<< -1 << 0
<< 0 << 0
<< 20 << 30
<< QRect();
QTest::newRow("(0,0) hidden row and column")
<< 10 << 10
<< 0 << 0
<< 0 << 0
<< 20 << 30
<< QRect();
QTest::newRow("(0,0) out of bounds")
<< 10 << 10
<< -1 << -1
<< 20 << 20
<< 20 << 30
<< QRect();
QTest::newRow("(5,5), hidden row")
<< 10 << 10
<< 5 << -1
<< 5 << 5
<< 20 << 30
<< QRect();
QTest::newRow("(9,9)")
<< 10 << 10
<< -1 << -1
<< 9 << 9
<< 20 << 30
<< QRect(30*9, 20*9, 29, 19);
}
void tst_QTableView::visualRect()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QFETCH(int, hideRow);
QFETCH(int, hideColumn);
QFETCH(int, row);
QFETCH(int, column);
QFETCH(int, rowHeight);
QFETCH(int, columnWidth);
QFETCH(QRect, expectedRect);
QtTestTableModel model(rowCount, columnCount);
QTableView view;
view.setModel(&model);
// Make sure that it has 1 pixel between each cell.
view.setGridStyle(Qt::SolidLine);
for (int i = 0; i < view.verticalHeader()->count(); ++i)
view.verticalHeader()->resizeSection(i, rowHeight);
for (int i = 0; i < view.horizontalHeader()->count(); ++i)
view.horizontalHeader()->resizeSection(i, columnWidth);
view.hideRow(hideRow);
view.hideColumn(hideColumn);
QRect rect = view.visualRect(model.index(row, column));
QCOMPARE(rect, expectedRect);
}
void tst_QTableView::fetchMore()
{
QtTestTableModel model(64, 64);
model.can_fetch_more = true;
QTableView view;
view.setModel(&model);
view.show();
QCOMPARE(model.fetch_more_count, 0);
view.verticalScrollBar()->setValue(view.verticalScrollBar()->maximum());
QVERIFY(model.fetch_more_count > 0);
model.fetch_more_count = 0; //reset
view.scrollToTop();
QCOMPARE(model.fetch_more_count, 0);
view.scrollToBottom();
QVERIFY(model.fetch_more_count > 0);
model.fetch_more_count = 0; //reset
view.scrollToTop();
view.setCurrentIndex(model.index(0, 0));
QCOMPARE(model.fetch_more_count, 0);
for (int i = 0; i < 64; ++i)
QTest::keyClick(&view, Qt::Key_Down);
QCOMPARE(view.currentIndex(), model.index(63, 0));
QVERIFY(model.fetch_more_count > 0);
}
void tst_QTableView::setHeaders()
{
QTableView view;
// Make sure we don't delete ourselves
view.setVerticalHeader(view.verticalHeader());
view.verticalHeader()->count();
view.setHorizontalHeader(view.horizontalHeader());
view.horizontalHeader()->count();
// Try passing around a header without it being deleted
QTableView view2;
view2.setVerticalHeader(view.verticalHeader());
view2.setHorizontalHeader(view.horizontalHeader());
view.setHorizontalHeader(new QHeaderView(Qt::Horizontal));
view.setVerticalHeader(new QHeaderView(Qt::Vertical));
view2.verticalHeader()->count();
view2.horizontalHeader()->count();
}
void tst_QTableView::resizeRowsToContents_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::addColumn<bool>("showGrid");
QTest::addColumn<int>("cellWidth");
QTest::addColumn<int>("cellHeight");
QTest::addColumn<int>("rowHeight");
QTest::addColumn<int>("columnWidth");
QTest::newRow("10x10 grid shown 40x40")
<< 10 << 10 << false << 40 << 40 << 40 << 40;
QTest::newRow("10x10 grid not shown 40x40")
<< 10 << 10 << true << 40 << 40 << 41 << 41;
}
void tst_QTableView::resizeRowsToContents()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QFETCH(bool, showGrid);
QFETCH(int, cellWidth);
QFETCH(int, cellHeight);
QFETCH(int, rowHeight);
QFETCH(int, columnWidth);
Q_UNUSED(columnWidth);
QtTestTableModel model(rowCount, columnCount);
QtTestTableView view;
QtTestItemDelegate delegate;
view.setModel(&model);
view.setItemDelegate(&delegate);
view.setShowGrid(showGrid); // the grid will add to the row height
delegate.hint = QSize(cellWidth, cellHeight);
QSignalSpy resizedSpy(view.verticalHeader(), SIGNAL(sectionResized(int,int,int)));
view.resizeRowsToContents();
QCOMPARE(resizedSpy.count(), model.rowCount());
for (int r = 0; r < model.rowCount(); ++r) {
QCOMPARE(view.rowHeight(r), rowHeight);
}
}
void tst_QTableView::resizeColumnsToContents_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::addColumn<bool>("showGrid");
QTest::addColumn<int>("cellWidth");
QTest::addColumn<int>("cellHeight");
QTest::addColumn<int>("rowHeight");
QTest::addColumn<int>("columnWidth");
QTest::newRow("10x10 grid shown 40x40")
<< 10 << 10 << false << 40 << 40 << 40 << 40;
QTest::newRow("10x10 grid not shown 40x40")
<< 10 << 10 << true << 40 << 40 << 41 << 41;
}
void tst_QTableView::resizeColumnsToContents()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QFETCH(bool, showGrid);
QFETCH(int, cellWidth);
QFETCH(int, cellHeight);
QFETCH(int, rowHeight);
QFETCH(int, columnWidth);
Q_UNUSED(rowHeight);
QtTestTableModel model(rowCount, columnCount);
QtTestTableView view;
QtTestItemDelegate delegate;
view.setModel(&model);
view.setItemDelegate(&delegate);
view.setShowGrid(showGrid); // the grid will add to the row height
delegate.hint = QSize(cellWidth, cellHeight);
QSignalSpy resizedSpy(view.horizontalHeader(), SIGNAL(sectionResized(int,int,int)));
view.resizeColumnsToContents();
QCOMPARE(resizedSpy.count(), model.columnCount());
for (int c = 0; c < model.columnCount(); ++c)
QCOMPARE(view.columnWidth(c), columnWidth);
}
void tst_QTableView::rowViewportPosition_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("rowHeight");
QTest::addColumn<int>("row");
QTest::addColumn<int>("verticalScrollMode");
QTest::addColumn<int>("verticalScrollValue");
QTest::addColumn<int>("rowViewportPosition");
QTest::newRow("row 0, scroll per item 0")
<< 10 << 40 << 0 << int(QAbstractItemView::ScrollPerItem) << 0 << 0;
QTest::newRow("row 1, scroll per item, 0")
<< 10 << 40 << 1 << int(QAbstractItemView::ScrollPerItem) << 0 << 1 * 40;
QTest::newRow("row 1, scroll per item, 1")
<< 10 << 40 << 1 << int(QAbstractItemView::ScrollPerItem) << 1 << 0;
QTest::newRow("row 5, scroll per item, 0")
<< 10 << 40 << 5 << int(QAbstractItemView::ScrollPerItem) << 0 << 5 * 40;
QTest::newRow("row 5, scroll per item, 5")
<< 10 << 40 << 5 << int(QAbstractItemView::ScrollPerItem) << 5 << 0;
QTest::newRow("row 9, scroll per item, 0")
<< 10 << 40 << 9 << int(QAbstractItemView::ScrollPerItem) << 0 << 9 * 40;
QTest::newRow("row 9, scroll per item, 5")
<< 10 << 40 << 9 << int(QAbstractItemView::ScrollPerItem) << 5 << 4 * 40;
QTest::newRow("row 0, scroll per pixel 0")
<< 10 << 40 << 0 << int(QAbstractItemView::ScrollPerPixel) << 0 << 0;
QTest::newRow("row 1, scroll per pixel, 0")
<< 10 << 40 << 1 << int(QAbstractItemView::ScrollPerPixel) << 0 << 1 * 40;
QTest::newRow("row 1, scroll per pixel, 1")
<< 10 << 40 << 1 << int(QAbstractItemView::ScrollPerPixel) << 1 * 40 << 0;
QTest::newRow("row 5, scroll per pixel, 0")
<< 10 << 40 << 5 << int(QAbstractItemView::ScrollPerPixel) << 0 << 5 * 40;
QTest::newRow("row 5, scroll per pixel, 5")
<< 10 << 40 << 5 << int(QAbstractItemView::ScrollPerPixel) << 5 * 40 << 0;
QTest::newRow("row 9, scroll per pixel, 0")
<< 10 << 40 << 9 << int(QAbstractItemView::ScrollPerPixel) << 0 << 9 * 40;
QTest::newRow("row 9, scroll per pixel, 5")
<< 10 << 40 << 9 << int(QAbstractItemView::ScrollPerPixel) << 5 * 40 << 4 * 40;
}
void tst_QTableView::rowViewportPosition()
{
QFETCH(int, rowCount);
QFETCH(int, rowHeight);
QFETCH(int, row);
QFETCH(int, verticalScrollMode);
QFETCH(int, verticalScrollValue);
QFETCH(int, rowViewportPosition);
QtTestTableModel model(rowCount, 1);
QtTestTableView view;
setFrameless(&view);
view.resize(100, 2 * rowHeight);
view.show();
view.setModel(&model);
for (int r = 0; r < rowCount; ++r)
view.setRowHeight(r, rowHeight);
view.setVerticalScrollMode((QAbstractItemView::ScrollMode)verticalScrollMode);
view.verticalScrollBar()->setValue(verticalScrollValue);
QCOMPARE(view.rowViewportPosition(row), rowViewportPosition);
}
void tst_QTableView::rowAt_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("rowHeight");
QTest::addColumn<IntList>("hiddenRows");
QTest::addColumn<int>("coordinate");
QTest::addColumn<int>("row");
QTest::newRow("row at 100") << 5 << 40 << IntList() << 100 << 2;
QTest::newRow("row at 180") << 5 << 40 << IntList() << 180 << 4;
QTest::newRow("row at 20") << 5 << 40 << IntList() << 20 << 0;
// ### expand the dataset to include hidden rows
}
void tst_QTableView::rowAt()
{
QFETCH(int, rowCount);
QFETCH(int, rowHeight);
QFETCH(IntList, hiddenRows);
QFETCH(int, coordinate);
QFETCH(int, row);
QtTestTableModel model(rowCount, 1);
QtTestTableView view;
view.resize(100, 2 * rowHeight);
view.setModel(&model);
for (int r = 0; r < rowCount; ++r)
view.setRowHeight(r, rowHeight);
for (int i = 0; i < hiddenRows.count(); ++i)
view.hideRow(hiddenRows.at(i));
QCOMPARE(view.rowAt(coordinate), row);
}
void tst_QTableView::rowHeight_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<IntList>("rowHeights");
QTest::addColumn<BoolList>("hiddenRows");
QTest::newRow("increasing")
<< 5
<< (IntList() << 20 << 30 << 40 << 50 << 60)
<< (BoolList() << false << false << false << false << false);
QTest::newRow("decreasing")
<< 5
<< (IntList() << 60 << 50 << 40 << 30 << 20)
<< (BoolList() << false << false << false << false << false);
QTest::newRow("random")
<< 5
<< (IntList() << 87 << 34 << 68 << 91 << 27)
<< (BoolList() << false << false << false << false << false);
// ### expand the dataset to include hidden rows
}
void tst_QTableView::rowHeight()
{
QFETCH(int, rowCount);
QFETCH(IntList, rowHeights);
QFETCH(BoolList, hiddenRows);
QtTestTableModel model(rowCount, 1);
QtTestTableView view;
view.setModel(&model);
for (int r = 0; r < rowCount; ++r) {
view.setRowHeight(r, rowHeights.at(r));
view.setRowHidden(r, hiddenRows.at(r));
}
for (int r = 0; r < rowCount; ++r) {
if (hiddenRows.at(r))
QCOMPARE(view.rowHeight(r), 0);
else
QCOMPARE(view.rowHeight(r), rowHeights.at(r));
}
}
void tst_QTableView::columnViewportPosition_data()
{
QTest::addColumn<int>("columnCount");
QTest::addColumn<int>("columnWidth");
QTest::addColumn<int>("column");
QTest::addColumn<int>("horizontalScrollMode");
QTest::addColumn<int>("horizontalScrollValue");
QTest::addColumn<int>("columnViewportPosition");
QTest::newRow("column 0, scroll per item 0")
<< 10 << 40 << 0 << int(QAbstractItemView::ScrollPerItem) << 0 << 0;
QTest::newRow("column 1, scroll per item, 0")
<< 10 << 40 << 1 << int(QAbstractItemView::ScrollPerItem) << 0 << 1 * 40;
QTest::newRow("column 1, scroll per item, 1")
<< 10 << 40 << 1 << int(QAbstractItemView::ScrollPerItem) << 1 << 0;
QTest::newRow("column 5, scroll per item, 0")
<< 10 << 40 << 5 << int(QAbstractItemView::ScrollPerItem) << 0 << 5 * 40;
QTest::newRow("column 5, scroll per item, 5")
<< 10 << 40 << 5 << int(QAbstractItemView::ScrollPerItem) << 5 << 0;
QTest::newRow("column 9, scroll per item, 0")
<< 10 << 40 << 9 << int(QAbstractItemView::ScrollPerItem) << 0 << 9 * 40;
QTest::newRow("column 9, scroll per item, 5")
<< 10 << 40 << 9 << int(QAbstractItemView::ScrollPerItem) << 5 << 4 * 40;
QTest::newRow("column 0, scroll per pixel 0")
<< 10 << 40 << 0 << int(QAbstractItemView::ScrollPerPixel) << 0 << 0;
QTest::newRow("column 1, scroll per pixel 0")
<< 10 << 40 << 1 << int(QAbstractItemView::ScrollPerPixel) << 0 << 1 * 40;
QTest::newRow("column 1, scroll per pixel 1")
<< 10 << 40 << 1 << int(QAbstractItemView::ScrollPerPixel) << 1 * 40 << 0;
QTest::newRow("column 5, scroll per pixel 0")
<< 10 << 40 << 5 << int(QAbstractItemView::ScrollPerPixel) << 0 << 5 * 40;
QTest::newRow("column 5, scroll per pixel 5")
<< 10 << 40 << 5 << int(QAbstractItemView::ScrollPerPixel) << 5 * 40 << 0;
QTest::newRow("column 9, scroll per pixel 0")
<< 10 << 40 << 9 << int(QAbstractItemView::ScrollPerPixel) << 0 << 9 * 40;
QTest::newRow("column 9, scroll per pixel 5")
<< 10 << 40 << 9 << int(QAbstractItemView::ScrollPerPixel) << 5 * 40 << 4 * 40;
}
void tst_QTableView::columnViewportPosition()
{
QFETCH(int, columnCount);
QFETCH(int, columnWidth);
QFETCH(int, column);
QFETCH(int, horizontalScrollMode);
QFETCH(int, horizontalScrollValue);
QFETCH(int, columnViewportPosition);
QtTestTableModel model(1, columnCount);
QtTestTableView view;
setFrameless(&view);
view.resize(2 * columnWidth, 100);
view.show();
view.setModel(&model);
for (int c = 0; c < columnCount; ++c)
view.setColumnWidth(c, columnWidth);
view.setHorizontalScrollMode((QAbstractItemView::ScrollMode)horizontalScrollMode);
view.horizontalScrollBar()->setValue(horizontalScrollValue);
QCOMPARE(view.columnViewportPosition(column), columnViewportPosition);
}
void tst_QTableView::columnAt_data()
{
QTest::addColumn<int>("columnCount");
QTest::addColumn<int>("columnWidth");
QTest::addColumn<IntList>("hiddenColumns");
QTest::addColumn<int>("coordinate");
QTest::addColumn<int>("column");
QTest::newRow("column at 100") << 5 << 40 << IntList() << 100 << 2;
QTest::newRow("column at 180") << 5 << 40 << IntList() << 180 << 4;
QTest::newRow("column at 20") << 5 << 40 << IntList() << 20 << 0;
// ### expand the dataset to include hidden coumns
}
void tst_QTableView::columnAt()
{
QFETCH(int, columnCount);
QFETCH(int, columnWidth);
QFETCH(IntList, hiddenColumns);
QFETCH(int, coordinate);
QFETCH(int, column);
QtTestTableModel model(1, columnCount);
QtTestTableView view;
view.resize(2 * columnWidth, 100);
view.setModel(&model);
for (int c = 0; c < columnCount; ++c)
view.setColumnWidth(c, columnWidth);
for (int i = 0; i < hiddenColumns.count(); ++i)
view.hideColumn(hiddenColumns.at(i));
QCOMPARE(view.columnAt(coordinate), column);
}
void tst_QTableView::columnWidth_data()
{
QTest::addColumn<int>("columnCount");
QTest::addColumn<IntList>("columnWidths");
QTest::addColumn<BoolList>("hiddenColumns");
QTest::newRow("increasing")
<< 5
<< (IntList() << 20 << 30 << 40 << 50 << 60)
<< (BoolList() << false << false << false << false << false);
QTest::newRow("decreasing")
<< 5
<< (IntList() << 60 << 50 << 40 << 30 << 20)
<< (BoolList() << false << false << false << false << false);
QTest::newRow("random")
<< 5
<< (IntList() << 87 << 34 << 68 << 91 << 27)
<< (BoolList() << false << false << false << false << false);
// ### expand the dataset to include hidden columns
}
void tst_QTableView::columnWidth()
{
QFETCH(int, columnCount);
QFETCH(IntList, columnWidths);
QFETCH(BoolList, hiddenColumns);
QtTestTableModel model(1, columnCount);
QtTestTableView view;
view.setModel(&model);
for (int c = 0; c < columnCount; ++c) {
view.setColumnWidth(c, columnWidths.at(c));
view.setColumnHidden(c, hiddenColumns.at(c));
}
for (int c = 0; c < columnCount; ++c) {
if (hiddenColumns.at(c))
QCOMPARE(view.columnWidth(c), 0);
else
QCOMPARE(view.columnWidth(c), columnWidths.at(c));
}
}
void tst_QTableView::hiddenRow_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<BoolList>("hiddenRows");
QTest::newRow("first hidden")
<< 5 << (BoolList() << true << false << false << false << false);
QTest::newRow("last hidden")
<< 5 << (BoolList() << false << false << false << false << true);
QTest::newRow("none hidden")
<< 5 << (BoolList() << false << false << false << false << false);
QTest::newRow("all hidden")
<< 5 << (BoolList() << true << true << true << true << true);
}
void tst_QTableView::hiddenRow()
{
QFETCH(int, rowCount);
QFETCH(BoolList, hiddenRows);
QtTestTableModel model(rowCount, 1);
QtTestTableView view;
view.setModel(&model);
for (int r = 0; r < rowCount; ++r)
QVERIFY(!view.isRowHidden(r));
for (int r = 0; r < rowCount; ++r)
view.setRowHidden(r, hiddenRows.at(r));
for (int r = 0; r < rowCount; ++r)
QCOMPARE(view.isRowHidden(r), hiddenRows.at(r));
for (int r = 0; r < rowCount; ++r)
view.setRowHidden(r, false);
for (int r = 0; r < rowCount; ++r)
QVERIFY(!view.isRowHidden(r));
}
void tst_QTableView::hiddenColumn_data()
{
QTest::addColumn<int>("columnCount");
QTest::addColumn<BoolList>("hiddenColumns");
QTest::newRow("first hidden")
<< 5 << (BoolList() << true << false << false << false << false);
QTest::newRow("last hidden")
<< 5 << (BoolList() << false << false << false << false << true);
QTest::newRow("none hidden")
<< 5 << (BoolList() << false << false << false << false << false);
QTest::newRow("all hidden")
<< 5 << (BoolList() << true << true << true << true << true);
}
void tst_QTableView::hiddenColumn()
{
QFETCH(int, columnCount);
QFETCH(BoolList, hiddenColumns);
QtTestTableModel model(1, columnCount);
QtTestTableView view;
view.setModel(&model);
for (int c = 0; c < columnCount; ++c)
QVERIFY(!view.isColumnHidden(c));
for (int c = 0; c < columnCount; ++c)
view.setColumnHidden(c, hiddenColumns.at(c));
for (int c = 0; c < columnCount; ++c)
QCOMPARE(view.isColumnHidden(c), hiddenColumns.at(c));
for (int c = 0; c < columnCount; ++c)
view.setColumnHidden(c, false);
for (int c = 0; c < columnCount; ++c)
QVERIFY(!view.isColumnHidden(c));
}
void tst_QTableView::sortingEnabled_data()
{
// QTest::addColumn<int>("columnCount");
}
void tst_QTableView::sortingEnabled()
{
// QFETCH(int, columnCount);
}
void tst_QTableView::scrollTo_data()
{
QTest::addColumn<int>("verticalScrollMode");
QTest::addColumn<int>("horizontalScrollMode");
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::addColumn<int>("rowHeight");
QTest::addColumn<int>("columnWidth");
QTest::addColumn<int>("hiddenRow");
QTest::addColumn<int>("hiddenColumn");
QTest::addColumn<int>("row");
QTest::addColumn<int>("column");
QTest::addColumn<int>("rowSpan");
QTest::addColumn<int>("columnSpan");
QTest::addColumn<int>("horizontalScroll");
QTest::addColumn<int>("verticalScroll");
QTest::addColumn<int>("scrollHint");
QTest::addColumn<int>("expectedHorizontalScroll");
QTest::addColumn<int>("expectedVerticalScroll");
QTest::newRow("no hidden, no span, no scroll, per item")
<< (int)QAbstractItemView::ScrollPerItem
<< (int)QAbstractItemView::ScrollPerItem
<< 10 << 10 // table
<< 80 << 80 // size
<< -1 << -1 // hide
<< 0 << 0 // cell
<< 1 << 1 // span
<< 0 << 0 // scroll
<< (int)QAbstractItemView::PositionAtTop
<< 0 << 0; // expected
QTest::newRow("no hidden, no span, no scroll, per pixel")
<< (int)QAbstractItemView::ScrollPerPixel
<< (int)QAbstractItemView::ScrollPerPixel
<< 10 << 10 // table
<< 80 << 80 // size
<< -1 << -1 // hide
<< 0 << 0 // cell
<< 1 << 1 // span
<< 0 << 0 // scroll
<< (int)QAbstractItemView::PositionAtTop
<< 0 << 0; // expected
QTest::newRow("hidden, no span, no scroll, per item")
<< (int)QAbstractItemView::ScrollPerItem
<< (int)QAbstractItemView::ScrollPerItem
<< 10 << 10 // table
<< 80 << 80 // size
<< 3 << 3 // hide
<< 5 << 5 // cell
<< 1 << 1 // span
<< 0 << 0 // scroll
<< (int)QAbstractItemView::PositionAtTop
<< 4 << 4; // expected
}
void tst_QTableView::scrollTo()
{
QFETCH(int, horizontalScrollMode);
QFETCH(int, verticalScrollMode);
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QFETCH(int, rowHeight);
QFETCH(int, columnWidth);
QFETCH(int, hiddenRow);
QFETCH(int, hiddenColumn);
QFETCH(int, row);
QFETCH(int, column);
QFETCH(int, rowSpan);
QFETCH(int, columnSpan);
QFETCH(int, horizontalScroll);
QFETCH(int, verticalScroll);
QFETCH(int, scrollHint);
QFETCH(int, expectedHorizontalScroll);
QFETCH(int, expectedVerticalScroll);
QtTestTableModel model(rowCount, columnCount);
QWidget toplevel;
setFrameless(&toplevel);
QtTestTableView view(&toplevel);
toplevel.show();
// resizing to this size will ensure that there can ONLY_BE_ONE_CELL inside the view.
QSize forcedSize(columnWidth * 2, rowHeight * 2);
view.resize(forcedSize);
QVERIFY(QTest::qWaitForWindowExposed(&toplevel));
QTRY_COMPARE(view.size(), forcedSize);
view.setModel(&model);
view.setSpan(row, column, rowSpan, columnSpan);
view.hideRow(hiddenRow);
view.hideColumn(hiddenColumn);
view.setHorizontalScrollMode((QAbstractItemView::ScrollMode)horizontalScrollMode);
view.setVerticalScrollMode((QAbstractItemView::ScrollMode)verticalScrollMode);
for (int r = 0; r < rowCount; ++r)
view.setRowHeight(r, rowHeight);
for (int c = 0; c < columnCount; ++c)
view.setColumnWidth(c, columnWidth);
QTest::qWait(150); // ### needed to pass the test
view.horizontalScrollBar()->setValue(horizontalScroll);
view.verticalScrollBar()->setValue(verticalScroll);
QModelIndex index = model.index(row, column);
QVERIFY(index.isValid());
view.scrollTo(index, (QAbstractItemView::ScrollHint)scrollHint);
QCOMPARE(view.verticalScrollBar()->value(), expectedVerticalScroll);
QCOMPARE(view.horizontalScrollBar()->value(), expectedHorizontalScroll);
}
void tst_QTableView::indexAt_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::addColumn<int>("rowHeight");
QTest::addColumn<int>("columnWidth");
QTest::addColumn<int>("hiddenRow");
QTest::addColumn<int>("hiddenColumn");
QTest::addColumn<int>("row");
QTest::addColumn<int>("column");
QTest::addColumn<int>("rowSpan");
QTest::addColumn<int>("columnSpan");
QTest::addColumn<int>("horizontalScroll");
QTest::addColumn<int>("verticalScroll");
QTest::addColumn<int>("x");
QTest::addColumn<int>("y");
QTest::addColumn<int>("expectedRow");
QTest::addColumn<int>("expectedColumn");
QTest::newRow("no hidden, no span, no scroll, (20,20)")
<< 10 << 10 // dim
<< 40 << 40 // size
<< -1 << -1 // hide
<< -1 << -1 // pos
<< 1 << 1 // span
<< 0 << 0 // scroll
<< 20 << 20 // point
<< 0 << 0; // expected
QTest::newRow("row hidden, no span, no scroll, at (20,20)")
<< 10 << 10 // dim
<< 40 << 40 // size
<< 0 << -1 // hide
<< -1 << -1 // pos
<< 1 << 1 // span
<< 0 << 0 // scroll
<< 20 << 20 // point
<< 1 << 0; // expected
QTest::newRow("col hidden, no span, no scroll, at (20,20)")
<< 10 << 10 // dim
<< 40 << 40 // size
<< -1 << 0 // hide
<< -1 << -1 // pos
<< 1 << 1 // span
<< 0 << 0 // scroll
<< 20 << 20 // point
<< 0 << 1; // expected
QTest::newRow("no hidden, row span, no scroll, at (60,20)")
<< 10 << 10 // dim
<< 40 << 40 // size
<< -1 << -1 // hide
<< 0 << 0 // pos
<< 2 << 1 // span
<< 0 << 0 // scroll
<< 20 << 60 // point
<< 0 << 0; // expected
QTest::newRow("no hidden, col span, no scroll, at (60,20)")
<< 10 << 10 // dim
<< 40 << 40 // size
<< -1 << -1 // hide
<< 0 << 0 // pos
<< 1 << 2 // span
<< 0 << 0 // scroll
<< 60 << 20 // point
<< 0 << 0; // expected
QTest::newRow("no hidden, no span, scroll (5,0), at (20,20)")
<< 20 << 20 // dim
<< 40 << 40 // size
<< -1 << -1 // hide
<< -1 << -1 // pos
<< 1 << 1 // span
<< 5 << 0 // scroll
<< 20 << 20 // point
<< 0 << 5; // expected
QTest::newRow("no hidden, no span, scroll (0,5), at (20,20)")
<< 20 << 20 // dim
<< 40 << 40 // size
<< -1 << -1 // hide
<< -1 << -1 // pos
<< 1 << 1 // span
<< 0 << 5 // scroll
<< 20 << 20 // point
<< 5 << 0; // expected
QTest::newRow("no hidden, no span, scroll (5,5), at (20,20)")
<< 20 << 20 // dim
<< 40 << 40 // size
<< -1 << -1 // hide
<< -1 << -1 // pos
<< 1 << 1 // span
<< 5 << 5 // scroll
<< 20 << 20 // point
<< 5 << 5; // expected
}
void tst_QTableView::indexAt()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QFETCH(int, rowHeight);
QFETCH(int, columnWidth);
QFETCH(int, hiddenRow);
QFETCH(int, hiddenColumn);
QFETCH(int, row);
QFETCH(int, column);
QFETCH(int, rowSpan);
QFETCH(int, columnSpan);
QFETCH(int, horizontalScroll);
QFETCH(int, verticalScroll);
QFETCH(int, x);
QFETCH(int, y);
QFETCH(int, expectedRow);
QFETCH(int, expectedColumn);
QtTestTableModel model(rowCount, columnCount);
QWidget toplevel;
QtTestTableView view(&toplevel);
toplevel.show();
QVERIFY(QTest::qWaitForWindowExposed(&toplevel));
//some styles change the scroll mode in their polish
view.setHorizontalScrollMode(QAbstractItemView::ScrollPerItem);
view.setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
view.setModel(&model);
view.setSpan(row, column, rowSpan, columnSpan);
view.hideRow(hiddenRow);
view.hideColumn(hiddenColumn);
for (int r = 0; r < rowCount; ++r)
view.setRowHeight(r, rowHeight);
for (int c = 0; c < columnCount; ++c)
view.setColumnWidth(c, columnWidth);
QTest::qWait(20);
view.horizontalScrollBar()->setValue(horizontalScroll);
view.verticalScrollBar()->setValue(verticalScroll);
QTest::qWait(20);
QModelIndex index = view.indexAt(QPoint(x, y));
QCOMPARE(index.row(), expectedRow);
QCOMPARE(index.column(), expectedColumn);
}
void tst_QTableView::span_data()
{
QTest::addColumn<int>("rowCount");
QTest::addColumn<int>("columnCount");
QTest::addColumn<int>("hiddenRow");
QTest::addColumn<int>("hiddenColumn");
QTest::addColumn<int>("row");
QTest::addColumn<int>("column");
QTest::addColumn<int>("rowSpan");
QTest::addColumn<int>("columnSpan");
QTest::addColumn<int>("expectedRowSpan");
QTest::addColumn<int>("expectedColumnSpan");
QTest::addColumn<bool>("clear");
QTest::newRow("top left 2x2")
<< 10 << 10
<< -1 << -1
<< 0 << 0
<< 2 << 2
<< 2 << 2
<< false;
QTest::newRow("top left 1x2")
<< 10 << 10
<< 3 << 3
<< 0 << 0
<< 1 << 2
<< 1 << 2
<< false;
QTest::newRow("top left 2x1")
<< 10 << 10
<< -1 << -1
<< 0 << 0
<< 2 << 1
<< 2 << 1
<< false;
/* This makes no sens.
QTest::newRow("top left 2x0")
<< 10 << 10
<< -1 << -1
<< 0 << 0
<< 2 << 0
<< 2 << 0
<< false;
QTest::newRow("top left 0x2")
<< 10 << 10
<< -1 << -1
<< 0 << 0
<< 0 << 2
<< 0 << 2
<< false;*/
QTest::newRow("invalid 2x2")
<< 10 << 10
<< -1 << -1
<< -1 << -1
<< 2 << 2
<< 1 << 1
<< false;
QTest::newRow("top left 2x2")
<< 10 << 10
<< -1 << -1
<< 0 << 0
<< 2 << 2
<< 2 << 2
<< false;
QTest::newRow("bottom right 2x2")
<< 10 << 10
<< -1 << -1
<< 8 << 8
<< 2 << 2
<< 2 << 2
<< false;
QTest::newRow("invalid span 2x2")
<< 10 << 10
<< -1 << -1
<< 8 << 8
<< 2 << 2
<< 2 << 2
<< false;
QTest::newRow("invalid span 3x3")
<< 10 << 10
<< -1 << -1
<< 6 << 6
<< 3 << 3
<< 2 << 3
<< true;
}
void tst_QTableView::span()
{
QFETCH(int, rowCount);
QFETCH(int, columnCount);
QFETCH(int, hiddenRow);
QFETCH(int, hiddenColumn);
QFETCH(int, row);
QFETCH(int, column);
QFETCH(int, rowSpan);
QFETCH(int, columnSpan);
QFETCH(int, expectedRowSpan);
QFETCH(int, expectedColumnSpan);
QFETCH(bool, clear);
QtTestTableModel model(rowCount, columnCount);
QtTestTableView view;
view.setModel(&model);
view.show();
view.setSpan(row, column, rowSpan, columnSpan);
if (clear) {
model.removeLastRow();
model.removeLastRow();
view.update();
}
view.hideRow(hiddenRow);
view.hideColumn(hiddenColumn);
view.show();
QCOMPARE(view.rowSpan(row, column), expectedRowSpan);
QCOMPARE(view.columnSpan(row, column), expectedColumnSpan);
if (hiddenRow > -1) {
QModelIndex hidden = model.index(hiddenRow, columnCount - 1);
QVERIFY(view.isIndexHidden(hidden));
}
if (hiddenColumn > -1) {
QModelIndex hidden = model.index(rowCount - 1, hiddenColumn);
QVERIFY(view.isIndexHidden(hidden));
}
view.clearSpans();
QCOMPARE(view.rowSpan(row, column), 1);
QCOMPARE(view.columnSpan(row, column), 1);
VERIFY_SPANS_CONSISTENCY(&view);
}
typedef QVector<QRect> SpanList;
void tst_QTableView::spans_data()
{
QTest::addColumn<int>("rows");
QTest::addColumn<int>("columns");
QTest::addColumn<SpanList>("spans");
QTest::addColumn<bool>("hideRowLastRowOfFirstSpan");
QTest::addColumn<QPoint>("pos");
QTest::addColumn<int>("expectedRowSpan");
QTest::addColumn<int>("expectedColumnSpan");
QTest::newRow("1x3 span, query 3,0")
<< 5 << 5
<< (SpanList() << QRect(3, 0, 1, 3))
<< false //no hidden row
<< QPoint(3, 0)
<< 1
<< 3;
QTest::newRow("1x3 span, query 3,1")
<< 5 << 5
<< (SpanList() << QRect(3, 0, 1, 3))
<< false //no hidden row
<< QPoint(3, 1)
<< 1
<< 3;
QTest::newRow("1x3 span, query 3,2")
<< 5 << 5
<< (SpanList() << QRect(3, 0, 1, 3))
<< false //no hidden row
<< QPoint(3, 2)
<< 1
<< 3;
QTest::newRow("two 1x2 spans at the same column, query at 3,0")
<< 5 << 5
<< (SpanList() << QRect(3, 0, 1, 2) << QRect(4, 0, 1, 2))
<< false //no hidden row
<< QPoint(3, 0)
<< 1
<< 2;
QTest::newRow("two 1x2 spans at the same column, query at 4,0")
<< 5 << 5
<< (SpanList() << QRect(3, 0, 1, 2) << QRect(4, 0, 1, 2))
<< false //no hidden row
<< QPoint(4, 0)
<< 1
<< 2;
QTest::newRow("how to order spans (1,1)")
<< 5 << 5
<< (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1))
<< false //no hidden row
<< QPoint(1, 1)
<< 3
<< 1;
QTest::newRow("how to order spans (2,1)")
<< 5 << 5
<< (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1))
<< false //no hidden row
<< QPoint(2, 1)
<< 3
<< 1;
QTest::newRow("how to order spans (3,1)")
<< 5 << 5
<< (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1))
<< false //no hidden row
<< QPoint(3, 1)
<< 3
<< 1;
QTest::newRow("how to order spans (1,2)")
<< 5 << 5
<< (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1))
<< false //no hidden row
<< QPoint(1, 2)
<< 2
<< 1;
QTest::newRow("how to order spans (2,2)")
<< 5 << 5
<< (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1))
<< false //no hidden row
<< QPoint(2, 2)
<< 2
<< 1;
QTest::newRow("spans with hidden rows")
<< 3 << 2
<< (SpanList() << QRect(0, 0, 2, 2) << QRect(2, 0, 1, 2))
<< true //we hide the last row of the first span
<< QPoint(2, 0)
<< 1
<< 2;
QTest::newRow("QTBUG-6004: No failing assertion, then it passes.")
<< 5 << 5
<< (SpanList() << QRect(0, 0, 2, 2) << QRect(0, 0, 1, 1))
<< false
<< QPoint(0, 0)
<< 1
<< 1;
QTest::newRow("QTBUG-6004 (follow-up): No failing assertion, then it passes.")
<< 10 << 10
<< (SpanList() << QRect(2, 2, 1, 3) << QRect(2, 2, 1, 1))
<< false
<< QPoint(0, 0)
<< 1
<< 1;
QTest::newRow("QTBUG-9631: remove one span")
<< 10 << 10
<< (SpanList() << QRect(1, 1, 2, 1) << QRect(2, 2, 2, 2) << QRect(1, 1, 1, 1))
<< false
<< QPoint(1, 1)
<< 1
<< 1;
}
void tst_QTableView::spans()
{
QFETCH(int, rows);
QFETCH(int, columns);
QFETCH(SpanList, spans);
QFETCH(bool, hideRowLastRowOfFirstSpan);
QFETCH(QPoint, pos);
QFETCH(int, expectedRowSpan);
QFETCH(int, expectedColumnSpan);
QtTestTableModel model(rows, columns);
QtTestTableView view;
view.setModel(&model);
view.show();
for (int i = 0; i < spans.count(); ++i) {
QRect sp = spans.at(i);
view.setSpan(sp.x(), sp.y(), sp.width(), sp.height());
}
if (hideRowLastRowOfFirstSpan) {
view.setRowHidden(spans.at(0).bottom(), true);
//we check that the span didn't break the visual rects of the model indexes
QRect first = view.visualRect( model.index(spans.at(0).top(), 0));
QRect next = view.visualRect( model.index(spans.at(0).bottom() + 1, 0));
QVERIFY(first.intersected(next).isEmpty());
}
QCOMPARE(view.columnSpan(pos.x(), pos.y()), expectedColumnSpan);
QCOMPARE(view.rowSpan(pos.x(), pos.y()), expectedRowSpan);
VERIFY_SPANS_CONSISTENCY(&view);
}
void tst_QTableView::spansAfterRowInsertion()
{
QtTestTableModel model(10, 10);
QtTestTableView view;
view.setModel(&model);
view.setSpan(3, 3, 3, 3);
view.show();
QTest::qWait(50);
// Insertion before the span only shifts the span.
view.model()->insertRows(0, 2);
QCOMPARE(view.rowSpan(3, 3), 1);
QCOMPARE(view.columnSpan(3, 3), 1);
QCOMPARE(view.rowSpan(5, 3), 3);
QCOMPARE(view.columnSpan(5, 3), 3);
// Insertion happens before the given row, so it only shifts the span also.
view.model()->insertRows(5, 2);
QCOMPARE(view.rowSpan(5, 3), 1);
QCOMPARE(view.columnSpan(5, 3), 1);
QCOMPARE(view.rowSpan(7, 3), 3);
QCOMPARE(view.columnSpan(7, 3), 3);
// Insertion inside the span expands it.
view.model()->insertRows(8, 2);
QCOMPARE(view.rowSpan(7, 3), 5);
QCOMPARE(view.columnSpan(7, 3), 3);
// Insertion after the span does nothing to it.
view.model()->insertRows(12, 2);
QCOMPARE(view.rowSpan(7, 3), 5);
QCOMPARE(view.columnSpan(7, 3), 3);
VERIFY_SPANS_CONSISTENCY(&view);
}
void tst_QTableView::spansAfterColumnInsertion()
{
QtTestTableModel model(10, 10);
QtTestTableView view;
view.setModel(&model);
view.setSpan(3, 3, 3, 3);
view.show();
QTest::qWait(50);
// Insertion before the span only shifts the span.
view.model()->insertColumns(0, 2);
QCOMPARE(view.rowSpan(3, 3), 1);
QCOMPARE(view.columnSpan(3, 3), 1);
QCOMPARE(view.rowSpan(3, 5), 3);
QCOMPARE(view.columnSpan(3, 5), 3);
// Insertion happens before the given column, so it only shifts the span also.
view.model()->insertColumns(5, 2);
QCOMPARE(view.rowSpan(3, 5), 1);
QCOMPARE(view.columnSpan(3, 5), 1);
QCOMPARE(view.rowSpan(3, 7), 3);
QCOMPARE(view.columnSpan(3, 7), 3);
// Insertion inside the span expands it.
view.model()->insertColumns(8, 2);
QCOMPARE(view.rowSpan(3, 7), 3);
QCOMPARE(view.columnSpan(3, 7), 5);
// Insertion after the span does nothing to it.
view.model()->insertColumns(12, 2);
QCOMPARE(view.rowSpan(3, 7), 3);
QCOMPARE(view.columnSpan(3, 7), 5);
VERIFY_SPANS_CONSISTENCY(&view);
}
void tst_QTableView::spansAfterRowRemoval()
{
QtTestTableModel model(10, 10);
QtTestTableView view;
view.setModel(&model);
QList<QRect> spans;
spans << QRect(0, 1, 1, 2)
<< QRect(1, 2, 1, 2)
<< QRect(2, 2, 1, 5)
<< QRect(2, 8, 1, 2)
<< QRect(3, 4, 1, 2)
<< QRect(4, 4, 1, 4)
<< QRect(5, 6, 1, 3)
<< QRect(6, 7, 1, 3);
foreach (QRect span, spans)
view.setSpan(span.top(), span.left(), span.height(), span.width());
view.show();
QTest::qWait(100);
view.model()->removeRows(3, 3);
QList<QRect> expectedSpans;
expectedSpans << QRect(0, 1, 1, 2)
<< QRect(1, 2, 1, 1)
<< QRect(2, 2, 1, 2)
<< QRect(2, 5, 1, 2)
<< QRect(3, 4, 1, 1)
<< QRect(4, 3, 1, 2)
<< QRect(5, 3, 1, 3)
<< QRect(6, 4, 1, 3);
foreach (QRect span, expectedSpans) {
QCOMPARE(view.columnSpan(span.top(), span.left()), span.width());
QCOMPARE(view.rowSpan(span.top(), span.left()), span.height());
}
VERIFY_SPANS_CONSISTENCY(&view);
}
void tst_QTableView::spansAfterColumnRemoval()
{
QtTestTableModel model(10, 10);
QtTestTableView view;
view.setModel(&model);
// Same set as above just swapping columns and rows.
QList<QRect> spans;
spans << QRect(0, 1, 1, 2)
<< QRect(1, 2, 1, 2)
<< QRect(2, 2, 1, 5)
<< QRect(2, 8, 1, 2)
<< QRect(3, 4, 1, 2)
<< QRect(4, 4, 1, 4)
<< QRect(5, 6, 1, 3)
<< QRect(6, 7, 1, 3);
foreach (QRect span, spans)
view.setSpan(span.left(), span.top(), span.width(), span.height());
view.show();
QTest::qWait(100);
view.model()->removeColumns(3, 3);
QList<QRect> expectedSpans;
expectedSpans << QRect(0, 1, 1, 2)
<< QRect(1, 2, 1, 1)
<< QRect(2, 2, 1, 2)
<< QRect(2, 5, 1, 2)
<< QRect(3, 4, 1, 1)
<< QRect(4, 3, 1, 2)
<< QRect(5, 3, 1, 3)
<< QRect(6, 4, 1, 3);
foreach (QRect span, expectedSpans) {
QCOMPARE(view.columnSpan(span.left(), span.top()), span.height());
QCOMPARE(view.rowSpan(span.left(), span.top()), span.width());
}
VERIFY_SPANS_CONSISTENCY(&view);
}
class Model : public QAbstractTableModel {
Q_OBJECT
public:
Model(QObject * parent = 0) : QAbstractTableModel(parent) {
}
int rowCount(const QModelIndex &) const {
return rows;
}
int columnCount(const QModelIndex &) const {
return columns;
}
QVariant data(const QModelIndex &, int) const
{
return QVariant();
}
void res() { reset(); }
int rows;
int columns;
};
void tst_QTableView::checkHeaderReset()
{
QTableView view;
Model m;
m.rows = 3;
m.columns = 3;
view.setModel(&m);
m.rows = 4;
m.columns = 4;
m.res();
QCOMPARE(view.horizontalHeader()->count(), 4);
}
void tst_QTableView::checkHeaderMinSize()
{
//tests if the minimumsize is of a header is taken into account
//while computing QTableView geometry. For that we test the position of the
//viewport.
QTableView view;
QStringListModel m;
m.setStringList( QStringList() << QLatin1String("one cell is enough"));
view.setModel(&m);
//setting the minimum height on the horizontal header
//and the minimum width on the vertical header
view.horizontalHeader()->setMinimumHeight(50);
view.verticalHeader()->setMinimumWidth(100);
view.show();
QVERIFY( view.verticalHeader()->y() >= view.horizontalHeader()->minimumHeight());
QVERIFY( view.horizontalHeader()->x() >= view.verticalHeader()->minimumWidth());
}
void tst_QTableView::resizeToContents()
{
//checks that the resize to contents is consistent
QTableWidget table(2,3);
QTableWidget table2(2,3);
QTableWidget table3(2,3);
table.setHorizontalHeaderItem(0, new QTableWidgetItem("A Lot of text here: BLA BLA BLA"));
table2.setHorizontalHeaderItem(0, new QTableWidgetItem("A Lot of text here: BLA BLA BLA"));
table3.setHorizontalHeaderItem(0, new QTableWidgetItem("A Lot of text here: BLA BLA BLA"));
table.horizontalHeader()->setVisible(false);
table2.horizontalHeader()->setVisible(false);
table.verticalHeader()->setVisible(false);
table2.verticalHeader()->setVisible(false);
for(int i = 0;i<table.columnCount();i++) {
table.resizeColumnToContents(i);
}
for(int i = 0;i<table.rowCount();i++) {
table.resizeRowToContents(i);
}
table2.resizeColumnsToContents();
table2.resizeRowsToContents();
table3.resizeColumnsToContents();
table3.resizeRowsToContents();
//now let's check the row/col sizes
for(int i = 0;i<table.columnCount();i++) {
QCOMPARE( table.columnWidth(i), table2.columnWidth(i));
QCOMPARE( table2.columnWidth(i), table3.columnWidth(i));
}
for(int i = 0;i<table.rowCount();i++) {
QCOMPARE( table.rowHeight(i), table2.rowHeight(i));
QCOMPARE( table2.rowHeight(i), table3.rowHeight(i));
}
}
QT_BEGIN_NAMESPACE
extern bool Q_GUI_EXPORT qt_tab_all_widgets(); // qapplication.cpp
QT_END_NAMESPACE
void tst_QTableView::tabFocus()
{
if (!qt_tab_all_widgets())
QSKIP("This test requires full keyboard control to be enabled.");
// QTableView enables tabKeyNavigation by default, but you should be able
// to change focus on an empty table view, or on a table view that doesn't
// have this property set.
QWidget window;
window.resize(200, 200);
QTableView *view = new QTableView(&window);
QLineEdit *edit = new QLineEdit(&window);
window.show();
QApplication::setActiveWindow(&window);
window.setFocus();
window.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&window));
// window
QVERIFY(window.hasFocus());
QVERIFY(!view->hasFocus());
QVERIFY(!edit->hasFocus());
for (int i = 0; i < 2; ++i) {
// tab to view
QTest::keyPress(qApp->focusWidget(), Qt::Key_Tab);
QTRY_VERIFY(!window.hasFocus());
QVERIFY(view->hasFocus());
QVERIFY(!edit->hasFocus());
// tab to edit
QTest::keyPress(qApp->focusWidget(), Qt::Key_Tab);
QTRY_VERIFY(edit->hasFocus());
QVERIFY(!window.hasFocus());
QVERIFY(!view->hasFocus());
}
// backtab to view
QTest::keyPress(qApp->focusWidget(), Qt::Key_Backtab);
QTRY_VERIFY(view->hasFocus());
QVERIFY(!window.hasFocus());
QVERIFY(!edit->hasFocus());
// backtab to edit
QTest::keyPress(qApp->focusWidget(), Qt::Key_Backtab);
QTRY_VERIFY(edit->hasFocus());
QVERIFY(!window.hasFocus());
QVERIFY(!view->hasFocus());
QStandardItemModel *model = new QStandardItemModel;
view->setModel(model);
// backtab to view
QTest::keyPress(qApp->focusWidget(), Qt::Key_Backtab);
QTRY_VERIFY(view->hasFocus());
QVERIFY(!window.hasFocus());
QVERIFY(!edit->hasFocus());
// backtab to edit
QTest::keyPress(qApp->focusWidget(), Qt::Key_Backtab);
QTRY_VERIFY(edit->hasFocus());
QVERIFY(!window.hasFocus());
QVERIFY(!view->hasFocus());
model->insertRow(0, new QStandardItem("Hei"));
model->insertRow(0, new QStandardItem("Hei"));
model->insertRow(0, new QStandardItem("Hei"));
// backtab to view
QTest::keyPress(qApp->focusWidget(), Qt::Key_Backtab);
QTRY_VERIFY(view->hasFocus());
QVERIFY(!window.hasFocus());
QVERIFY(!edit->hasFocus());
// backtab to edit doesn't work
QTest::keyPress(qApp->focusWidget(), Qt::Key_Backtab);
QVERIFY(!window.hasFocus());
QVERIFY(view->hasFocus());
QVERIFY(!edit->hasFocus());
view->setTabKeyNavigation(false);
// backtab to edit
QTest::keyPress(qApp->focusWidget(), Qt::Key_Backtab);
QTRY_VERIFY(edit->hasFocus());
QVERIFY(!window.hasFocus());
QVERIFY(!view->hasFocus());
QTest::keyPress(qApp->focusWidget(), Qt::Key_Tab);
QTRY_VERIFY(view->hasFocus());
QTest::keyPress(qApp->focusWidget(), Qt::Key_Tab);
QTRY_VERIFY(edit->hasFocus());
delete model;
}
class BigModel : public QAbstractTableModel
{
Q_OBJECT
public:
virtual QVariant data(const QModelIndex &index,
int role = Qt::DisplayRole) const
{
if (role == Qt::DisplayRole)
return QString("%1 - %2").arg(index.column()).arg(index.row());
return QVariant();
}
int rowCount(const QModelIndex & parent = QModelIndex()) const
{
Q_UNUSED(parent);
return 10000000;
}
int columnCount(const QModelIndex & parent = QModelIndex()) const
{
Q_UNUSED(parent);
return 20000000;
}
};
void tst_QTableView::bigModel()
{
//should not crash
QTableView view;
BigModel model;
view.setModel(&model);
view.show();
view.setSpan(10002,10002,6,6);
QTest::qWait(100);
view.resize(1000,1000);
QTest::qWait(100);
view.scrollTo(model.index(10010,10010));
QTest::qWait(100);
}
void tst_QTableView::selectionSignal()
{
QtTestTableModel model(10, 10);
QtTestTableView view;
view.checkSignalOrder = true;
view.setModel(&model);
view.resize(200, 200);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.visualRect(model.index(2, 0)).center());
}
void tst_QTableView::setCurrentIndex()
{
QtTestTableModel model(4, 4);
QtTestTableView view;
view.setModel(&model);
// submit() slot should be called in model when current row changes
view.setCurrentIndex(model.index(0,0));
QCOMPARE(model.submit_count, 1);
view.setCurrentIndex(model.index(0,2));
QCOMPARE(model.submit_count, 1);
view.setCurrentIndex(model.index(1,0));
QCOMPARE(model.submit_count, 2);
view.setCurrentIndex(model.index(3,3));
QCOMPARE(model.submit_count, 3);
view.setCurrentIndex(model.index(0,1));
QCOMPARE(model.submit_count, 4);
view.setCurrentIndex(model.index(0,0));
QCOMPARE(model.submit_count, 4);
}
class task173773_EventFilter : public QObject
{
int paintEventCount_;
public:
task173773_EventFilter() : paintEventCount_(0) {}
int paintEventCount() const { return paintEventCount_; }
private:
bool eventFilter(QObject *obj, QEvent *e)
{
Q_UNUSED(obj);
if (e->type() == QEvent::Paint)
++paintEventCount_;
return false;
}
};
void tst_QTableView::task173773_updateVerticalHeader()
{
QStandardItemModel model(2, 1);
model.setData(model.index(0, 0), 0);
model.setData(model.index(1, 0), 1);
QSortFilterProxyModel proxyModel;
proxyModel.setSourceModel(&model);
QTableView view;
view.setModel(&proxyModel);
view.setSortingEnabled(true);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
view.sortByColumn(0, Qt::AscendingOrder);
QTest::qWait(100);
task173773_EventFilter eventFilter;
view.verticalHeader()->viewport()->installEventFilter(&eventFilter);
view.sortByColumn(0, Qt::DescendingOrder);
QTest::qWait(100);
// ### note: this test may occasionally pass even if the bug is present!
QVERIFY(eventFilter.paintEventCount() > 0);
}
void tst_QTableView::task227953_setRootIndex()
{
QTableView tableView;
//model = tree with two items with tables as children
QStandardItemModel model;
QStandardItem item1, item2;
model.appendColumn(QList<QStandardItem*>() << &item1 << &item2);
//setup the first table as a child of the first item
for ( int row = 0; row < 40; ++row ) {
item1.appendRow(QList<QStandardItem*>() << new QStandardItem(QString("row %0").arg(row)));
}
//setup the second table as a child of the second item
for ( int row = 0; row < 10; ++row ) {
item2.appendRow(QList<QStandardItem*>() << new QStandardItem(QString("row %0").arg(row)));
}
tableView.setModel(&model);
//show the first 10 rows of the first table
QModelIndex root = model.indexFromItem(&item1);
tableView.setRootIndex(root);
for (int i = 10; i != 40; ++i) {
tableView.setRowHidden(i, true);
}
QCOMPARE(tableView.verticalHeader()->count(), 40);
QCOMPARE(tableView.verticalHeader()->hiddenSectionCount(), 30);
//show the first 10 rows of the second table
tableView.setRootIndex(model.indexFromItem(&item2));
QCOMPARE(tableView.verticalHeader()->count(), 10);
QCOMPARE(tableView.verticalHeader()->hiddenSectionCount(), 0);
QVERIFY(!tableView.verticalHeader()->isHidden());
}
void tst_QTableView::task240266_veryBigColumn()
{
QTableView table;
table.setFixedSize(500, 300); //just to make sure we have the 2 first columns visible
QStandardItemModel model(1, 3);
table.setModel(&model);
table.setColumnWidth(0, 100); //normal column
table.setColumnWidth(1, 100); //normal column
table.setColumnWidth(2, 9000); //very big column
table.show();
QVERIFY(QTest::qWaitForWindowExposed(&table));
//some styles change the scroll mode in their polish
table.setHorizontalScrollMode(QAbstractItemView::ScrollPerItem);
table.setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
QScrollBar *scroll = table.horizontalScrollBar();
QCOMPARE(scroll->minimum(), 0);
QCOMPARE(scroll->maximum(), model.columnCount() - 1);
QCOMPARE(scroll->singleStep(), 1);
//1 is not always a very correct value for pageStep. Ideally this should be dynamic.
//Maybe something for Qt 5 ;-)
QCOMPARE(scroll->pageStep(), 1);
}
void tst_QTableView::task248688_autoScrollNavigation()
{
//we make sure that when navigating with the keyboard the view is correctly scrolled
//to the current item
QStandardItemModel model(16, 16);
QTableView view;
view.setModel(&model);
view.hideColumn(8);
view.hideRow(8);
view.show();
for (int r = 0; r < model.rowCount(); ++r) {
if (view.isRowHidden(r))
continue;
for (int c = 0; c < model.columnCount(); ++c) {
if (view.isColumnHidden(c))
continue;
QModelIndex index = model.index(r, c);
view.setCurrentIndex(index);
QVERIFY(view.viewport()->rect().contains(view.visualRect(index)));
}
}
}
void tst_QTableView::mouseWheel_data()
{
QTest::addColumn<int>("scrollMode");
QTest::addColumn<int>("delta");
QTest::addColumn<int>("horizontalPositon");
QTest::addColumn<int>("verticalPosition");
QTest::newRow("scroll up per item")
<< int(QAbstractItemView::ScrollPerItem) << 120
<< 10 - qApp->wheelScrollLines() << 10 - qApp->wheelScrollLines();
QTest::newRow("scroll down per item")
<< int(QAbstractItemView::ScrollPerItem) << -120
<< 10 + qApp->wheelScrollLines() << 10 + qApp->wheelScrollLines();
QTest::newRow("scroll down per pixel")
<< int(QAbstractItemView::ScrollPerPixel) << -120
<< 10 + qApp->wheelScrollLines() * 89 << 10 + qApp->wheelScrollLines() * 28;
}
void tst_QTableView::mouseWheel()
{
#ifdef Q_OS_WINCE
QSKIP("Since different Windows CE versions sport different taskbars, we skip this test");
#endif
QFETCH(int, scrollMode);
QFETCH(int, delta);
QFETCH(int, horizontalPositon);
QFETCH(int, verticalPosition);
QtTestTableModel model(100, 100);
QWidget topLevel;
QtTestTableView view(&topLevel);
view.resize(500, 500);
for (int r = 0; r < 100; ++r)
view.setRowHeight(r, 50);
for (int c = 0; c < 100; ++c)
view.setColumnWidth(c, 100);
topLevel.show();
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
view.setModel(&model);
view.setHorizontalScrollMode((QAbstractItemView::ScrollMode)scrollMode);
view.setVerticalScrollMode((QAbstractItemView::ScrollMode)scrollMode);
view.horizontalScrollBar()->setValue(10);
view.verticalScrollBar()->setValue(10);
QPoint pos = view.viewport()->geometry().center();
QWheelEvent verticalEvent(pos, delta, 0, 0, Qt::Vertical);
QWheelEvent horizontalEvent(pos, delta, 0, 0, Qt::Horizontal);
QApplication::sendEvent(view.viewport(), &horizontalEvent);
QVERIFY(qAbs(view.horizontalScrollBar()->value() - horizontalPositon) < 10);
QApplication::sendEvent(view.viewport(), &verticalEvent);
QVERIFY(qAbs(view.verticalScrollBar()->value() - verticalPosition) < 10);
}
void tst_QTableView::addColumnWhileEditing()
{
QTableView view;
QStandardItemModel model(1, 10);
view.setModel(&model);
QModelIndex last = model.index(0,9);
view.show();
view.openPersistentEditor(last);
view.scrollTo(last);
//let's see if the editor is moved to the right location
//after adding a column
model.setColumnCount(model.columnCount() + 1);
QPointer<QLineEdit> editor = view.findChild<QLineEdit*>();
QVERIFY(editor);
QCOMPARE(editor->geometry(), view.visualRect(last));
//let's see if the editor is moved to the right location
//after removing a column
view.scrollTo(model.index(0, model.columnCount()-1));
model.setColumnCount(model.columnCount() - 1);
QVERIFY(editor);
QCOMPARE(editor->geometry(), view.visualRect(last));
}
void tst_QTableView::task259308_scrollVerticalHeaderSwappedSections()
{
QStandardItemModel model;
model.setRowCount(50);
model.setColumnCount(2);
for (int row = 0; row < model.rowCount(); ++row)
for (int col = 0; col < model.columnCount(); ++col) {
const QModelIndex &idx = model.index(row, col);
model.setData(idx, QVariant(row), Qt::EditRole);
}
QTableView tv;
tv.setModel(&model);
tv.show();
tv.verticalHeader()->swapSections(0, model.rowCount() - 1);
tv.setCurrentIndex(model.index(model.rowCount() - 1, 0));
QVERIFY(QTest::qWaitForWindowExposed(&tv));
QTest::keyClick(&tv, Qt::Key_PageUp); // PageUp won't scroll when at top
QTRY_COMPARE(tv.rowAt(0), tv.verticalHeader()->logicalIndex(0));
int newRow = tv.rowAt(tv.viewport()->height());
QTest::keyClick(&tv, Qt::Key_PageDown); // Scroll down and check current
QTRY_COMPARE(tv.currentIndex().row(), newRow);
tv.setCurrentIndex(model.index(0, 0));
QTest::qWait(60);
QTest::keyClick(&tv, Qt::Key_PageDown); // PageDown won't scroll when at the bottom
QTRY_COMPARE(tv.rowAt(tv.viewport()->height() - 1), tv.verticalHeader()->logicalIndex(model.rowCount() - 1));
}
template <typename T>
struct ValueSaver {
T &var, value;
ValueSaver(T &v) : var(v), value(v) { }
~ValueSaver() { var = value; }
};
void tst_QTableView::task191545_dragSelectRows()
{
QStandardItemModel model(10, 10);
QTableView table;
table.setModel(&model);
table.setSelectionBehavior(QAbstractItemView::SelectItems);
table.setSelectionMode(QAbstractItemView::ExtendedSelection);
table.setMinimumSize(1000, 400);
table.show();
QTest::qWait(200);
ValueSaver<Qt::KeyboardModifiers> saver(QApplicationPrivate::modifier_buttons);
QApplicationPrivate::modifier_buttons = Qt::ControlModifier;
{
QRect cellRect = table.visualRect(model.index(3, 0));
QHeaderView *vHeader = table.verticalHeader();
QWidget *vHeaderVp = vHeader->viewport();
QPoint rowPos(cellRect.center());
QMouseEvent rowPressEvent(QEvent::MouseButtonPress, rowPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
qApp->sendEvent(vHeaderVp, &rowPressEvent);
for (int i = 0; i < 4; ++i) {
rowPos.setY(rowPos.y() + cellRect.height());
QMouseEvent moveEvent(QEvent::MouseMove, rowPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
qApp->sendEvent(vHeaderVp, &moveEvent);
}
QMouseEvent rowReleaseEvent(QEvent::MouseButtonRelease, rowPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
qApp->sendEvent(vHeaderVp, &rowReleaseEvent);
for (int i = 0; i < 4; ++i) {
QModelIndex index = model.index(3 + i, 0, table.rootIndex());
QVERIFY(vHeader->selectionModel()->selectedRows().contains(index));
}
}
{
QRect cellRect = table.visualRect(model.index(0, 3));
QHeaderView *hHeader = table.horizontalHeader();
QWidget *hHeaderVp = hHeader->viewport();
QPoint colPos((cellRect.left() + cellRect.right()) / 2, 5);
QMouseEvent colPressEvent(QEvent::MouseButtonPress, colPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
qApp->sendEvent(hHeaderVp, &colPressEvent);
for (int i = 0; i < 4; ++i) {
colPos.setX(colPos.x() + cellRect.width());
QMouseEvent moveEvent(QEvent::MouseMove, colPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
qApp->sendEvent(hHeaderVp, &moveEvent);
}
QMouseEvent colReleaseEvent(QEvent::MouseButtonRelease, colPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
qApp->sendEvent(hHeaderVp, &colReleaseEvent);
for (int i = 0; i < 4; ++i) {
QModelIndex index = model.index(0, 3 + i, table.rootIndex());
QVERIFY(hHeader->selectionModel()->selectedColumns().contains(index));
}
}
{
QRect cellRect = table.visualRect(model.index(2, 2));
QWidget *tableVp = table.viewport();
QPoint cellPos = cellRect.center();
QMouseEvent cellPressEvent(QEvent::MouseButtonPress, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
qApp->sendEvent(tableVp, &cellPressEvent);
for (int i = 0; i < 6; ++i) {
cellPos.setX(cellPos.x() + cellRect.width());
cellPos.setY(cellPos.y() + cellRect.height());
QMouseEvent moveEvent(QEvent::MouseMove, cellPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
qApp->sendEvent(tableVp, &moveEvent);
}
QMouseEvent cellReleaseEvent(QEvent::MouseButtonRelease, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
qApp->sendEvent(tableVp, &cellReleaseEvent);
for (int i = 0; i < 6; ++i)
for (int j = 0; j < 6; ++j) {
QModelIndex index = model.index(2 + i, 2 + j, table.rootIndex());
QVERIFY(table.selectionModel()->isSelected(index));
}
}
{
QRect cellRect = table.visualRect(model.index(3, 3));
QWidget *tableVp = table.viewport();
QPoint cellPos = cellRect.center();
QMouseEvent cellPressEvent(QEvent::MouseButtonPress, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
qApp->sendEvent(tableVp, &cellPressEvent);
for (int i = 0; i < 6; ++i) {
cellPos.setX(cellPos.x() + cellRect.width());
cellPos.setY(cellPos.y() + cellRect.height());
QMouseEvent moveEvent(QEvent::MouseMove, cellPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
qApp->sendEvent(tableVp, &moveEvent);
}
QMouseEvent cellReleaseEvent(QEvent::MouseButtonRelease, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
qApp->sendEvent(tableVp, &cellReleaseEvent);
QTest::qWait(200);
for (int i = 0; i < 6; ++i)
for (int j = 0; j < 6; ++j) {
QModelIndex index = model.index(3 + i, 3 + j, table.rootIndex());
QVERIFY(!table.selectionModel()->isSelected(index));
}
}
}
void tst_QTableView::task234926_setHeaderSorting()
{
QStringListModel model;
QStringList data;
data << "orange" << "apple" << "banana" << "lemon" << "pumpkin";
QStringList sortedDataA = data;
QStringList sortedDataD = data;
std::sort(sortedDataA.begin(), sortedDataA.end());
std::sort(sortedDataD.begin(), sortedDataD.end(), qGreater<QString>());
model.setStringList(data);
QTableView view;
view.setModel(&model);
// view.show();
QTest::qWait(20);
QCOMPARE(model.stringList(), data);
view.setSortingEnabled(true);
view.sortByColumn(0, Qt::AscendingOrder);
QApplication::processEvents();
QCOMPARE(model.stringList() , sortedDataA);
view.horizontalHeader()->setSortIndicator(0, Qt::DescendingOrder);
QApplication::processEvents();
QCOMPARE(model.stringList() , sortedDataD);
QHeaderView *h = new QHeaderView(Qt::Horizontal);
h->setModel(&model);
view.setHorizontalHeader(h);
h->setSortIndicator(0, Qt::AscendingOrder);
QApplication::processEvents();
QCOMPARE(model.stringList() , sortedDataA);
h->setSortIndicator(0, Qt::DescendingOrder);
QApplication::processEvents();
QCOMPARE(model.stringList() , sortedDataD);
}
void tst_QTableView::taskQTBUG_5062_spansInconsistency()
{
const int nRows = 5;
const int nColumns = 5;
QtTestTableModel model(nRows, nColumns);
QtTestTableView view;
view.setModel(&model);
for (int i = 0; i < nRows; ++i)
view.setSpan(i, 0, 1, nColumns);
view.setSpan(2, 0, 1, 1);
view.setSpan(3, 0, 1, 1);
VERIFY_SPANS_CONSISTENCY(&view);
}
void tst_QTableView::taskQTBUG_4516_clickOnRichTextLabel()
{
QTableView view;
QStandardItemModel model(5,5);
view.setModel(&model);
QLabel label("rich text");
label.setTextFormat(Qt::RichText);
view.setIndexWidget(model.index(1,1), &label);
view.setCurrentIndex(model.index(0,0));
QCOMPARE(view.currentIndex(), model.index(0,0));
QTest::mouseClick(&label, Qt::LeftButton);
QCOMPARE(view.currentIndex(), model.index(1,1));
}
void tst_QTableView::changeHeaderData()
{
QTableView view;
QStandardItemModel model(5,5);
view.setModel(&model);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QString text = "long long long text";
const int textWidth = view.verticalHeader()->fontMetrics().width(text);
QVERIFY(view.verticalHeader()->width() < textWidth);
model.setHeaderData(2, Qt::Vertical, text);
QTest::qWait(100); //leave time for layout
QVERIFY(view.verticalHeader()->width() > textWidth);
}
void tst_QTableView::taskQTBUG_5237_wheelEventOnHeader()
{
QTableView view;
QStandardItemModel model(500,5);
view.setModel(&model);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
int sbValueBefore = view.verticalScrollBar()->value();
QHeaderView *header = view.verticalHeader();
QTest::mouseMove(header);
QWheelEvent wheelEvent(header->geometry().center(), -720, 0, 0);
QApplication::sendEvent(header->viewport(), &wheelEvent);
int sbValueAfter = view.verticalScrollBar()->value();
QVERIFY(sbValueBefore != sbValueAfter);
}
class TestTableView : public QTableView {
Q_OBJECT
public:
TestTableView(QWidget *parent = 0) : QTableView(parent)
{
connect(this, SIGNAL(entered(QModelIndex)), this, SLOT(openEditor(QModelIndex)));
}
~TestTableView(){}
public slots:
void onDataChanged()
{
for (int i = 0; i < model()->rowCount(); i++) {
setRowHidden(i, model()->data(model()->index(i, 0)).toBool());
}
}
void openEditor(const QModelIndex& index)
{ openPersistentEditor(index); }
};
void tst_QTableView::taskQTBUG_8585_crashForNoGoodReason()
{
QStandardItemModel model;
model.insertColumn(0, QModelIndex());
for(int i = 0; i < 20; i++)
{
model.insertRow(i);
}
TestTableView w;
w.setMouseTracking(true);
w.setModel(&model);
connect(&model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), &w, SLOT(onDataChanged()));
w.show();
QVERIFY(QTest::qWaitForWindowExposed(&w));
for (int i = 0; i < 10; i++)
{
QTest::mouseMove(w.viewport(), QPoint(50, 20));
w.model()->setData(w.indexAt(QPoint(50, 20)), true);
QTest::mouseMove(w.viewport(), QPoint(50, 25));
}
}
class TableView7774 : public QTableView
{
public:
QRegion visualRegionForSelection(const QItemSelection &selection) const
{
return QTableView::visualRegionForSelection(selection);
}
};
void tst_QTableView::taskQTBUG_7774_RtoLVisualRegionForSelection()
{
TableView7774 view;
QStandardItemModel model(5,5);
view.setModel(&model);
view.setLayoutDirection(Qt::RightToLeft);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QItemSelectionRange range(model.index(2, 0), model.index(2, model.columnCount() - 1));
QItemSelection selection;
selection << range;
QRegion region = view.visualRegionForSelection(selection);
QCOMPARE(region.rects().at(0), view.visualRect(range.topLeft()) | view.visualRect(range.bottomRight()));
}
void tst_QTableView::taskQTBUG_8777_scrollToSpans()
{
QTableWidget table(75,5);
for (int i=0; i<50; i++)
table.setSpan(2+i, 0, 1, 5);
table.setCurrentCell(0,2);
table.show();
for (int i = 0; i < 45; ++i)
QTest::keyClick(&table, Qt::Key_Down);
QVERIFY(table.verticalScrollBar()->value() > 10);
}
void tst_QTableView::taskQTBUG_10169_sizeHintForRow()
{
QtTestTableView tableView;
QStandardItemModel model(1, 3);
model.setData(model.index(0, 0), "Word wrapping text goes here.");
tableView.setModel(&model);
tableView.verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
const int orderedHeight = tableView.sizeHintForRow(0);
tableView.horizontalHeader()->moveSection(2, 0);
const int reorderedHeight = tableView.sizeHintForRow(0);
//the order of the columns shouldn't matter.
QCOMPARE(orderedHeight, reorderedHeight);
}
void tst_QTableView::viewOptions()
{
QtTestTableView view;
QStyleOptionViewItem options = view.viewOptions();
QVERIFY(options.showDecorationSelected);
}
void tst_QTableView::taskQTBUG_30653_doItemsLayout()
{
QWidget topLevel;
QtTestTableView view(&topLevel);
QtTestTableModel model(5, 5);
view.setModel(&model);
QtTestItemDelegate delegate;
delegate.hint = QSize(50, 50);
view.setItemDelegate(&delegate);
view.resizeRowsToContents();
view.resizeColumnsToContents();
// show two and half rows/cols
int extraWidth = view.verticalHeader()->sizeHint().width() + view.verticalScrollBar()->sizeHint().width();
int extraHeight = view.horizontalHeader()->sizeHint().height() + view.horizontalScrollBar()->sizeHint().height();
view.resize(125 + extraWidth, 125 + extraHeight);
topLevel.show();
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
// the offset after scrollToBottom() and doItemsLayout() should not differ
// as the view content should stay aligned to the last section
view.scrollToBottom();
int scrollToBottomOffset = view.verticalHeader()->offset();
view.doItemsLayout();
int doItemsLayoutOffset = view.verticalHeader()->offset();
QCOMPARE(scrollToBottomOffset, doItemsLayoutOffset);
}
QTEST_MAIN(tst_QTableView)
#include "tst_qtableview.moc"