diff -r 000000000000 -r 1918ee327afb tests/auto/qtableview/tst_qtableview.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/auto/qtableview/tst_qtableview.cpp Mon Jan 11 14:00:40 2010 +0000 @@ -0,0 +1,3848 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include +#include "../../shared/util.h" +#include "private/qapplication_p.h" + +//TESTED_CLASS= +//TESTED_FILES= + +// Will try to wait for the condition while allowing event processing +// for a maximum of 2 seconds. +#define WAIT_FOR_CONDITION(expr, expected) \ + do { \ + const int step = 100; \ + for (int i = 0; i < 2000 && expr != expected; i+=step) { \ + QTest::qWait(step); \ + } \ + } while(0) + +typedef QList IntList; +Q_DECLARE_METATYPE(IntList) + +typedef QList BoolList; +Q_DECLARE_METATYPE(BoolList) + +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 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(); + + // task-specific tests: + void task173773_updateVerticalHeader(); + void task227953_setRootIndex(); + void task240266_veryBigColumn(); + void task248688_autoScrollNavigation(); + void task259308_scrollVerticalHeaderSwappedSections(); + void task191545_dragSelectRows(); + + void mouseWheel_data(); + void mouseWheel(); + + void addColumnWhileEditing(); + void task234926_setHeaderSorting(); +}; + +// 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: + QtTestTableModel(int rows = 0, int columns = 0, QObject *parent = 0) + : QAbstractTableModel(parent), + row_count(rows), + column_count(columns), + 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; + bool can_fetch_more; + int fetch_more_count; + QSet disabled_rows; + QSet 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 { + 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 moveCursor(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(); + } + + 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("rowCount"); + QTest::addColumn("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("rowCount"); + QTest::addColumn("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("rowCount"); + QTest::addColumn("columnCount"); + QTest::addColumn("tabKeyNavigation"); + QTest::addColumn("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(); + QTest::qWaitForWindowShown(&view); + qApp->setActiveWindow(&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("rowCount"); + QTest::addColumn("columnCount"); + QTest::addColumn("row"); + QTest::addColumn("column"); + QTest::addColumn("rowHeight"); + QTest::addColumn("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 IntPair; +Q_DECLARE_METATYPE(IntPair) + +void tst_QTableView::moveCursor_data() +{ + QTest::addColumn("rowCount"); + QTest::addColumn("columnCount"); + QTest::addColumn("hideRow"); + QTest::addColumn("hideColumn"); + + QTest::addColumn("startRow"); + QTest::addColumn("startColumn"); + + QTest::addColumn("cursorMoveAction"); + QTest::addColumn("modifier"); + + QTest::addColumn("expectedRow"); + QTest::addColumn("expectedColumn"); + QTest::addColumn("moveRow"); + QTest::addColumn("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.moveCursor((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("hideRow"); + QTest::addColumn("hideColumn"); + QTest::addColumn("disableRows"); + QTest::addColumn("disableColumns"); + QTest::addColumn("span"); + + QTest::addColumn("startRow"); + QTest::addColumn("startColumn"); + QTest::addColumn("cursorMoveActions"); + QTest::addColumn("expectedRow"); + QTest::addColumn("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. 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.moveCursor((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::hideRows_data() +{ + QTest::addColumn("rowCount"); + QTest::addColumn("columnCount"); + QTest::addColumn("showRow"); // hide, then show + QTest::addColumn("hideRow"); // hide only + QTest::addColumn("row"); + QTest::addColumn("column"); + QTest::addColumn("rowSpan"); + QTest::addColumn("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("rowCount"); + QTest::addColumn("columnCount"); + QTest::addColumn("showColumn"); // hide, then show + QTest::addColumn("hideColumn"); // hide only + QTest::addColumn("row"); + QTest::addColumn("column"); + QTest::addColumn("rowSpan"); + QTest::addColumn("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("rowCount"); + QTest::addColumn("columnCount"); + QTest::addColumn("row"); + QTest::addColumn("column"); + QTest::addColumn("rowSpan"); + QTest::addColumn("columnSpan"); + QTest::addColumn("hideRow"); + QTest::addColumn("hideColumn"); + QTest::addColumn("moveRowFrom"); + QTest::addColumn("moveRowTo"); + QTest::addColumn("moveColumnFrom"); + QTest::addColumn("moveColumnTo"); + QTest::addColumn("rowHeight"); + QTest::addColumn("columnWidth"); + QTest::addColumn("x"); + QTest::addColumn("y"); + QTest::addColumn("width"); + QTest::addColumn("height"); + QTest::addColumn("command"); + QTest::addColumn("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("rowCount"); + QTest::addColumn("columnCount"); + QTest::addColumn("row"); + QTest::addColumn("mode"); + QTest::addColumn("behavior"); + QTest::addColumn("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("rowCount"); + QTest::addColumn("columnCount"); + QTest::addColumn("column"); + QTest::addColumn("mode"); + QTest::addColumn("behavior"); + QTest::addColumn("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); +} + +Q_DECLARE_METATYPE(QRect) +void tst_QTableView::visualRect_data() +{ + QTest::addColumn("rowCount"); + QTest::addColumn("columnCount"); + QTest::addColumn("hideRow"); + QTest::addColumn("hideColumn"); + QTest::addColumn("row"); + QTest::addColumn("column"); + QTest::addColumn("rowHeight"); + QTest::addColumn("columnWidth"); + QTest::addColumn("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("rowCount"); + QTest::addColumn("columnCount"); + QTest::addColumn("showGrid"); + QTest::addColumn("cellWidth"); + QTest::addColumn("cellHeight"); + QTest::addColumn("rowHeight"); + QTest::addColumn("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("rowCount"); + QTest::addColumn("columnCount"); + QTest::addColumn("showGrid"); + QTest::addColumn("cellWidth"); + QTest::addColumn("cellHeight"); + QTest::addColumn("rowHeight"); + QTest::addColumn("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("rowCount"); + QTest::addColumn("rowHeight"); + QTest::addColumn("row"); + QTest::addColumn("verticalScrollMode"); + QTest::addColumn("verticalScrollValue"); + QTest::addColumn("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; + 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("rowCount"); + QTest::addColumn("rowHeight"); + QTest::addColumn("hiddenRows"); + QTest::addColumn("coordinate"); + QTest::addColumn("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("rowCount"); + QTest::addColumn("rowHeights"); + QTest::addColumn("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("columnCount"); + QTest::addColumn("columnWidth"); + QTest::addColumn("column"); + QTest::addColumn("horizontalScrollMode"); + QTest::addColumn("horizontalScrollValue"); + QTest::addColumn("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; + 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("columnCount"); + QTest::addColumn("columnWidth"); + QTest::addColumn("hiddenColumns"); + QTest::addColumn("coordinate"); + QTest::addColumn("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("columnCount"); + QTest::addColumn("columnWidths"); + QTest::addColumn("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("rowCount"); + QTest::addColumn("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("columnCount"); + QTest::addColumn("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("columnCount"); +} + +void tst_QTableView::sortingEnabled() +{ +// QFETCH(int, columnCount); +} + +void tst_QTableView::scrollTo_data() +{ + QTest::addColumn("verticalScrollMode"); + QTest::addColumn("horizontalScrollMode"); + QTest::addColumn("rowCount"); + QTest::addColumn("columnCount"); + QTest::addColumn("rowHeight"); + QTest::addColumn("columnWidth"); + QTest::addColumn("hiddenRow"); + QTest::addColumn("hiddenColumn"); + QTest::addColumn("row"); + QTest::addColumn("column"); + QTest::addColumn("rowSpan"); + QTest::addColumn("columnSpan"); + QTest::addColumn("horizontalScroll"); + QTest::addColumn("verticalScroll"); + QTest::addColumn("scrollHint"); + QTest::addColumn("expectedHorizontalScroll"); + QTest::addColumn("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); + QtTestTableView view; + + view.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); + QTest::qWaitForWindowShown(&view); + QTest::qWait(50); + 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("rowCount"); + QTest::addColumn("columnCount"); + + QTest::addColumn("rowHeight"); + QTest::addColumn("columnWidth"); + + QTest::addColumn("hiddenRow"); + QTest::addColumn("hiddenColumn"); + + QTest::addColumn("row"); + QTest::addColumn("column"); + QTest::addColumn("rowSpan"); + QTest::addColumn("columnSpan"); + QTest::addColumn("horizontalScroll"); + QTest::addColumn("verticalScroll"); + QTest::addColumn("x"); + QTest::addColumn("y"); + QTest::addColumn("expectedRow"); + QTest::addColumn("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)") + << 10 << 10 // 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)") + << 10 << 10 // 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)") + << 10 << 10 // 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); + QtTestTableView view; + + view.show(); + QTest::qWaitForWindowShown(&view); + + //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("rowCount"); + QTest::addColumn("columnCount"); + QTest::addColumn("hiddenRow"); + QTest::addColumn("hiddenColumn"); + QTest::addColumn("row"); + QTest::addColumn("column"); + QTest::addColumn("rowSpan"); + QTest::addColumn("columnSpan"); + QTest::addColumn("expectedRowSpan"); + QTest::addColumn("expectedColumnSpan"); + QTest::addColumn("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); +} + +typedef QVector SpanList; +Q_DECLARE_METATYPE(SpanList) + +void tst_QTableView::spans_data() +{ + QTest::addColumn("rows"); + QTest::addColumn("columns"); + QTest::addColumn("spans"); + QTest::addColumn("hideRowLastRowOfFirstSpan"); + QTest::addColumn("pos"); + QTest::addColumn("expectedRowSpan"); + QTest::addColumn("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; +} + +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); +} + +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); +} + +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); +} + +void tst_QTableView::spansAfterRowRemoval() +{ + QtTestTableModel model(10, 10); + QtTestTableView view; + view.setModel(&model); + + QList 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 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()); + } +} + +void tst_QTableView::spansAfterColumnRemoval() +{ + QtTestTableModel model(10, 10); + QtTestTableView view; + view.setModel(&model); + + // Same set as above just swapping columns and rows. + QList 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 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()); + } +} + +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;iprocessEvents(); + + WAIT_FOR_CONDITION(window.hasFocus(), true); + + qApp->processEvents(); + + // 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(); + QTest::qWaitForWindowShown(&view); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.visualRect(model.index(2, 0)).center()); +} + +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(); + QTest::qWaitForWindowShown(&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() << &item1 << &item2); + + + //setup the first table as a child of the first item + for ( int row = 0; row < 40; ++row ) { + item1.appendRow(QList() << 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() << 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(); + QTest::qWaitForWindowShown(&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("scrollMode"); + QTest::addColumn("delta"); + QTest::addColumn("horizontalPositon"); + QTest::addColumn("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(); +#ifdef Q_WS_MAC + // On Mac, we always scroll one pixel per 120 delta (rather than multiplying with + // singleStep) since wheel events are accelerated by the OS. + QTest::newRow("scroll down per pixel") + << int(QAbstractItemView::ScrollPerPixel) << -120 + << 10 + qApp->wheelScrollLines() << 10 + qApp->wheelScrollLines(); +#else + QTest::newRow("scroll down per pixel") + << int(QAbstractItemView::ScrollPerPixel) << -120 + << 10 + qApp->wheelScrollLines() * 89 << 10 + qApp->wheelScrollLines() * 28; +#endif +} + +void tst_QTableView::mouseWheel() +{ +#ifdef Q_OS_WINCE + QSKIP("Since different Windows CE versions sport different taskbars, we skip this test", SkipAll); +#endif + QFETCH(int, scrollMode); + QFETCH(int, delta); + QFETCH(int, horizontalPositon); + QFETCH(int, verticalPosition); + + QtTestTableModel model(100, 100); + QtTestTableView view; + 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); + view.show(); + QTest::qWaitForWindowShown(&view); + + 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 editor = qFindChild(&view); + 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)); + + QTest::qWaitForWindowShown(&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()); + if (newRow == tv.rowAt(tv.viewport()->height() - 1)) // Overlapping row + newRow++; + 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 +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 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(5, (cellRect.top() + cellRect.bottom()) / 2); + 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); + + 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; + qSort(sortedDataA); + qSort(sortedDataD.begin(), sortedDataD.end(), qGreater()); + 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); +} + +QTEST_MAIN(tst_QTableView) +#include "tst_qtableview.moc"